diff --git a/CHANGELOG b/CHANGELOG index b28f47eb5fe..66a4db13a98 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,17 @@ +15.02 + + * Plugins system + + * New core and scalable data structure + + * Using new MongoDB drive + + * Path mounting + + * Accepting bulk requests as post + + * Lots of plugins as Data Populator, Event Logger, DBViewer, etc + 14.08 * Added density reporting for Android diff --git a/Gruntfile.js b/Gruntfile.js index 8f32f5e1052..6718d6906bd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,7 +14,9 @@ module.exports = function(grunt) { node:true, "-W041": true, "-W038": true, - "-W082": true + "-W082": true, + "-W058": true, + "-W030": true }, all: ['Gruntfile.js', 'api/api.js', 'api/lib/*.js', 'api/parts/**/*.js', 'api/utils/common.js', 'frontend/express/app.js'] }, @@ -23,7 +25,7 @@ module.exports = function(grunt) { test: { options: { reporter: 'spec', - timeout: 5000 + timeout: 10000 }, src: ['test/**/*.js'] } diff --git a/api/api.js b/api/api.js index 56f8c52f89b..3ea8d5012cf 100644 --- a/api/api.js +++ b/api/api.js @@ -2,7 +2,10 @@ var http = require('http'), cluster = require('cluster'), os = require('os'), url = require('url'), + querystring = require('querystring'), common = require('./utils/common.js'), + plugins = require('../plugins/pluginManager.js'), + crypto = require('crypto'), countlyApi = { data:{ usage:require('./parts/data/usage.js'), @@ -14,6 +17,9 @@ var http = require('http'), apps:require('./parts/mgmt/apps.js') } }; + +plugins.init(); +plugins.dispatch("/init", {common:common}); http.globalAgent.maxSockets = common.config.api.max_sockets || 1024; @@ -31,12 +37,11 @@ function validateAppForWriteAPI(params) { params.app_id = app['_id']; params.app_cc = app['country']; + params.app_name = app['name']; params.appTimezone = app['timezone']; params.time = common.initTimeObj(params.appTimezone, params.qstring.timestamp); - - var updateSessions = {}; - common.fillTimeObject(params, updateSessions, common.dbMap['events']); - common.db.collection('sessions').update({'_id':params.app_id}, {'$inc':updateSessions}, {'upsert':true}, function(err, res){}); + + plugins.dispatch("/i", {params:params, app:app}); if (params.qstring.events) { countlyApi.data.events.processEvents(params); @@ -45,7 +50,7 @@ function validateAppForWriteAPI(params) { } if (params.qstring.begin_session) { - countlyApi.data.usage.beginUserSession(params); + countlyApi.data.usage.beginUserSession(params); } else if (params.qstring.end_session) { if (params.qstring.session_duration) { countlyApi.data.usage.processSessionDuration(params, function () { @@ -57,6 +62,13 @@ function validateAppForWriteAPI(params) { } else if (params.qstring.session_duration) { countlyApi.data.usage.processSessionDuration(params); } else { + // begin_session, session_duration and end_session handle incrementing request count in usage.js + var dbDateIds = common.getDateIds(params), + updateUsers = {}; + + common.fillTimeObjectMonth(params, updateUsers, common.dbMap['events']); + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.month}, {'$inc': updateUsers}, {'upsert':true}, function(err, res){}); + return false; } }); @@ -68,7 +80,6 @@ function validateUserForWriteAPI(callback, params) { common.returnMessage(params, 401, 'User does not exist'); return false; } - params.member = member; callback(params); }); @@ -95,6 +106,8 @@ function validateUserForDataReadAPI(params, callback, callbackParam) { params.app_id = app['_id']; params.appTimezone = app['timezone']; params.time = common.initTimeObj(params.appTimezone, params.qstring.timestamp); + + plugins.dispatch("/o/validate", {params:params, app:app}); if (callbackParam) { callback(callbackParam, params); @@ -135,19 +148,25 @@ if (cluster.isMaster) { cluster.on('exit', function(worker) { cluster.fork(); }); + + plugins.dispatch("/worker", {}); } else { - http.Server(function (req, res) { - var urlParts = url.parse(req.url, true), queryString = urlParts.query, paths = urlParts.pathname.split("/"), apiPath = "", params = { 'qstring':queryString, - 'res':res + 'res':res, + 'req':req }; + + //remove countly path + if(common.config.path == "/"+paths[1]){ + paths.splice(1, 1); + } if (queryString.app_id && queryString.app_id.length != 24) { common.returnMessage(params, 400, 'Invalid parameter "app_id"'); @@ -166,73 +185,81 @@ if (cluster.isMaster) { apiPath += "/" + paths[i]; } + + plugins.dispatch("/", {params:params, apiPath:apiPath}); switch (apiPath) { case '/i/bulk': - { - - var requests = queryString.requests, - appKey = queryString.app_key; - - if (requests) { - try { - requests = JSON.parse(requests); - } catch (SyntaxError) { - console.log('Parse bulk JSON failed'); - } - } else { - common.returnMessage(params, 400, 'Missing parameter "requests"'); - return false; - } - - for (var i = 0; i < requests.length; i++) { - - if (!requests[i].app_key && !appKey) { - continue; - } - - var tmpParams = { - 'app_id':'', - 'app_cc':'', - 'ip_address':requests[i].ip_address, - 'user':{ - 'country':requests[i].country_code || 'Unknown', - 'city':requests[i].city || 'Unknown' - }, - 'qstring':{ - 'app_key':requests[i].app_key || appKey, - 'device_id':requests[i].device_id, - 'metrics':requests[i].metrics, - 'events':requests[i].events, - 'session_duration':requests[i].session_duration, - 'begin_session':requests[i].begin_session, - 'end_session':requests[i].end_session, - 'timestamp':requests[i].timestamp - } - }; - - if (!tmpParams.qstring.device_id) { - continue; - } else { - tmpParams.app_user_id = common.crypto.createHash('sha1').update(tmpParams.qstring.app_key + tmpParams.qstring.device_id + "").digest('hex'); - } - - if (tmpParams.qstring.metrics) { - if (tmpParams.qstring.metrics["_carrier"]) { - tmpParams.qstring.metrics["_carrier"] = tmpParams.qstring.metrics["_carrier"].replace(/\w\S*/g, function (txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); - } - - if (tmpParams.qstring.metrics["_os"] && tmpParams.qstring.metrics["_os_version"]) { - tmpParams.qstring.metrics["_os_version"] = tmpParams.qstring.metrics["_os"][0].toLowerCase() + tmpParams.qstring.metrics["_os_version"]; - } - } - - validateAppForWriteAPI(tmpParams); - } - - common.returnMessage(params, 200, 'Success'); + { + function processBulk(queryString){ + var requests = queryString.requests, + appKey = queryString.app_key; + + if (requests) { + try { + requests = JSON.parse(requests); + } catch (SyntaxError) { + console.log('Parse bulk JSON failed'); + } + } else { + common.returnMessage(params, 400, 'Missing parameter "requests"'); + return false; + } + for (var i = 0; i < requests.length; i++) { + + if (!requests[i].app_key && !appKey) { + continue; + } + + var tmpParams = { + 'app_id':'', + 'app_cc':'', + 'ip_address':requests[i].ip_address || getIpAddress(req), + 'user':{ + 'country':requests[i].country_code || 'Unknown', + 'city':requests[i].city || 'Unknown' + }, + 'qstring':requests[i] + }; + + tmpParams["qstring"]['app_key'] = requests[i].app_key || appKey; + + if (!tmpParams.qstring.device_id) { + continue; + } else { + tmpParams.app_user_id = common.crypto.createHash('sha1').update(tmpParams.qstring.app_key + tmpParams.qstring.device_id + "").digest('hex'); + } + + if (tmpParams.qstring.metrics) { + if (tmpParams.qstring.metrics["_carrier"]) { + tmpParams.qstring.metrics["_carrier"] = tmpParams.qstring.metrics["_carrier"].replace(/\w\S*/g, function (txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); + } + + if (tmpParams.qstring.metrics["_os"] && tmpParams.qstring.metrics["_os_version"]) { + tmpParams.qstring.metrics["_os_version"] = tmpParams.qstring.metrics["_os"][0].toLowerCase() + tmpParams.qstring.metrics["_os_version"]; + } + } + validateAppForWriteAPI(tmpParams); + } + + common.returnMessage(params, 200, 'Success'); + } + if(req.method.toLowerCase() == 'post'){ + var body = ""; + req.on('data', function(chunk) { + body += chunk.toString(); + }); + + req.on('end', function() { + // parse the received body data + processBulk(querystring.parse(body)); + }); + } + else + //attempt process GET request + processBulk(queryString); break; } case '/i/users': @@ -334,8 +361,6 @@ if (cluster.isMaster) { } catch (SyntaxError) { console.log('Parse metrics JSON failed'); - common.returnMessage(params, 400, 'metrics JSON is not properly formed'); - return false } } @@ -344,8 +369,6 @@ if (cluster.isMaster) { params.qstring.events = JSON.parse(params.qstring.events); } catch (SyntaxError) { console.log('Parse events JSON failed'); - common.returnMessage(params, 400, 'events JSON is not properly formed'); - return false; } } @@ -412,18 +435,25 @@ if (cluster.isMaster) { } switch (params.qstring.method) { + case 'get_period_obj': + validateUserForDataReadAPI(params, countlyApi.data.fetch.getPeriodObj, 'users'); + break; case 'locations': case 'sessions': case 'users': - case 'devices': + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeObj, 'users'); + break; + case 'app_versions': case 'device_details': + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeObj, 'device_details'); + break; + case 'devices': case 'carriers': - case 'app_versions': - validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeData, params.qstring.method); + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeObj, params.qstring.method); break; case 'cities': if (common.config.api.city_data !== false) { - validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeData, params.qstring.method); + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchTimeObj, params.qstring.method); } else { common.returnOutput(params, {}); } @@ -434,8 +464,6 @@ if (cluster.isMaster) { params.qstring.events = JSON.parse(params.qstring.events); } catch (SyntaxError) { console.log('Parse events array failed'); - common.returnMessage(params, 400, 'events JSON is not properly formed'); - break; } validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchMergedEventData); @@ -447,7 +475,8 @@ if (cluster.isMaster) { validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchCollection, 'events'); break; default: - common.returnMessage(params, 400, 'Invalid method'); + if(!plugins.dispatch(apiPath, {params:params, validateUserForDataReadAPI:validateUserForDataReadAPI, validateUserForMgmtReadAPI:validateUserForMgmtReadAPI})) + common.returnMessage(params, 400, 'Invalid method'); break; } @@ -471,15 +500,25 @@ if (cluster.isMaster) { break; case 'countries': validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchCountries); + break; + case 'sessions': + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchSessions); + break; + case 'metric': + validateUserForDataReadAPI(params, countlyApi.data.fetch.fetchMetric); break; default: - common.returnMessage(params, 400, 'Invalid path, must be one of /dashboard or /countries'); + if(!plugins.dispatch(apiPath, {params:params, validateUserForDataReadAPI:validateUserForDataReadAPI, validateUserForMgmtReadAPI:validateUserForMgmtReadAPI, paths:paths})) + common.returnMessage(params, 400, 'Invalid path, must be one of /dashboard or /countries'); break; } break; } + default: + if(!plugins.dispatch(apiPath, {params:params, validateUserForDataReadAPI:validateUserForDataReadAPI, validateUserForMgmtReadAPI:validateUserForMgmtReadAPI, validateUserForWriteAPI:validateUserForWriteAPI, paths:paths})) + common.returnMessage(params, 400, 'Invalid path'); } }).listen(common.config.api.port, common.config.api.host || ''); -} +} \ No newline at end of file diff --git a/api/config.sample.js b/api/config.sample.js index 5f719702a09..575d589f4a8 100644 --- a/api/config.sample.js +++ b/api/config.sample.js @@ -3,35 +3,44 @@ var countlyConfig = { host: "localhost", db: "countly", port: 27017, - max_pool_size: 1000 + max_pool_size: 500, + //username: test, + //password: test }, /* or for a replica set mongodb: { replSetServers : [ - '192.168.3.1:27017/?auto_reconnect=true', - '192.168.3.2:27017/?auto_reconnect=true' + '192.168.3.1:27017', + '192.168.3.2:27017' ], db: "countly", - max_pool_size: 1000 + username: test, + password: test, + max_pool_size: 500 }, */ /* or define as a url - mongodb: "localhost:27017/countly?auto_reconnect=true", + //mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] + mongodb: "localhost:27017/countly", */ api: { - workers: 0, port: 3001, host: "localhost", safe: false, session_duration_limit: 120, max_sockets: 1024, - city_data: true + city_data: true, + event_limit: 500, + event_segmentation_limit: 100, + event_segmentation_value_limit:1000 }, apps: { country: "TR", timezone: "Europe/Istanbul", - category: "6" - } + category: "6", + expire_online_after: 180 + }, + path: "" }; // Set your host IP or domain to be used in the emails sent diff --git a/api/lib/countly.common.js b/api/lib/countly.common.js index 5c79622bda9..3596d72248b 100644 --- a/api/lib/countly.common.js +++ b/api/lib/countly.common.js @@ -504,6 +504,253 @@ var countlyCommon = {}, return formattedDateStart.format(countlyCommon.periodObj.dateString) + " - " + formattedDateEnd.format(countlyCommon.periodObj.dateString); }; + + countlyCommon.extractData = function (db, clearFunction, dataProperties) { + + countlyCommon.periodObj = getPeriodObj(); + + var periodMin = countlyCommon.periodObj.periodMin, + periodMax = (countlyCommon.periodObj.periodMax + 1), + dataObj = {}, + formattedDate = "", + tableData = [], + propertyNames = underscore.pluck(dataProperties, "name"), + propertyFunctions = underscore.pluck(dataProperties, "func"), + currOrPrevious = underscore.pluck(dataProperties, "period"), + activeDate, + activeDateArr; + + for (var j = 0; j < propertyNames.length; j++) { + if (currOrPrevious[j] === "previous") { + if (countlyCommon.periodObj.isSpecialPeriod) { + periodMin = 0; + periodMax = countlyCommon.periodObj.previousPeriodArr.length; + activeDateArr = countlyCommon.periodObj.previousPeriodArr; + } else { + activeDate = countlyCommon.periodObj.previousPeriod; + } + } else { + if (countlyCommon.periodObj.isSpecialPeriod) { + periodMin = 0; + periodMax = countlyCommon.periodObj.currentPeriodArr.length; + activeDateArr = countlyCommon.periodObj.currentPeriodArr; + } else { + activeDate = countlyCommon.periodObj.activePeriod; + } + } + var dateString = ""; + for (var i = periodMin; i < periodMax; i++) { + + if (!countlyCommon.periodObj.isSpecialPeriod) { + + if (countlyCommon.periodObj.periodMin == 0) { + dateString = "YYYY-M-D H:00"; + formattedDate = moment((activeDate + " " + i + ":00:00").replace(/\./g, "/")); + } else if (("" + activeDate).indexOf(".") == -1) { + dateString = "YYYY-M"; + formattedDate = moment((activeDate + "/" + i + "/1").replace(/\./g, "/")); + } else { + dateString = "YYYY-M-D"; + formattedDate = moment((activeDate + "/" + i).replace(/\./g, "/")); + } + + dataObj = countlyCommon.getDescendantProp(db, activeDate + "." + i); + } else { + dateString = "YYYY-M-D"; + formattedDate = moment((activeDateArr[i]).replace(/\./g, "/")); + dataObj = countlyCommon.getDescendantProp(db, activeDateArr[i]); + } + + dataObj = clearFunction(dataObj); + + if (!tableData[i]) { + tableData[i] = {}; + } + + tableData[i]["_id"] = formattedDate.format(dateString); + + if (propertyFunctions[j]) { + propertyValue = propertyFunctions[j](dataObj); + } else { + propertyValue = dataObj[propertyNames[j]]; + } + tableData[i][propertyNames[j]] = propertyValue; + } + } + + return underscore.compact(tableData); + }; + + countlyCommon.extractMetricData = function (db, rangeArray, clearFunction, dataProperties) { + + countlyCommon.periodObj = getPeriodObj(); + + var periodMin = 0, + periodMax = 0, + dataObj = {}, + formattedDate = "", + tableData = [], + chartData = [], + propertyNames = underscore.pluck(dataProperties, "name"), + propertyFunctions = underscore.pluck(dataProperties, "func"), + propertyValue = 0; + + if (!countlyCommon.periodObj.isSpecialPeriod) { + periodMin = countlyCommon.periodObj.periodMin; + periodMax = (countlyCommon.periodObj.periodMax + 1); + } else { + periodMin = 0; + periodMax = countlyCommon.periodObj.currentPeriodArr.length; + } + + var tableCounter = 0; + + if (!countlyCommon.periodObj.isSpecialPeriod) { + for (var j = 0; j < rangeArray.length; j++) { + dataObj = countlyCommon.getDescendantProp(db, countlyCommon.periodObj.activePeriod + "." + rangeArray[j]); + + if (!dataObj) { + continue; + } + + dataObj = clearFunction(dataObj); + + var propertySum = 0, + tmpPropertyObj = {}; + + for (var k = 0; k < propertyNames.length; k++) { + + if (propertyFunctions[k]) { + propertyValue = propertyFunctions[k](rangeArray[j], dataObj); + tmpPropertyObj["_id"] = propertyValue; + } else { + propertyValue = dataObj[propertyNames[k]]; + tmpPropertyObj[propertyNames[k]] = propertyValue; + } + + if (typeof propertyValue !== 'string') { + propertySum += propertyValue; + } + } + + if (propertySum > 0) { + tableData[tableCounter] = {}; + tableData[tableCounter] = tmpPropertyObj; + tableCounter++; + } + } + } else { + + for (var j = 0; j < rangeArray.length; j++) { + + var propertySum = 0, + tmpPropertyObj = {}, + tmp_x = {}, + propertyKey = ""; + + for (var i = periodMin; i < periodMax; i++) { + dataObj = countlyCommon.getDescendantProp(db, countlyCommon.periodObj.currentPeriodArr[i] + "." + rangeArray[j]); + + if (!dataObj) { + continue; + } + + dataObj = clearFunction(dataObj); + + for (var k = 0; k < propertyNames.length; k++) { + + if (propertyNames[k] == "u") { + propertyValue = 0; + } else if (propertyFunctions[k]) { + propertyValue = propertyFunctions[k](rangeArray[j], dataObj); + propertyKey = "_id"; + } else { + propertyValue = dataObj[propertyNames[k]]; + propertyKey = propertyNames[k]; + } + + if (!tmpPropertyObj[propertyKey]) { + tmpPropertyObj[propertyKey] = 0; + } + + if (typeof propertyValue === 'string') { + tmpPropertyObj[propertyKey] = propertyValue; + } else { + propertySum += propertyValue; + tmpPropertyObj[propertyKey] += propertyValue; + } + } + } + + if (propertyNames.indexOf("u") !== -1 && Object.keys(tmpPropertyObj).length) { + var tmpUniqVal = 0, + tmpUniqValCheck = 0, + tmpCheckVal = 0; + + for (var l = 0; l < (countlyCommon.periodObj.uniquePeriodArr.length); l++) { + tmp_x = countlyCommon.getDescendantProp(db, countlyCommon.periodObj.uniquePeriodArr[l] + "." + rangeArray[j]); + if (!tmp_x) { + continue; + } + tmp_x = clearFunction(tmp_x); + propertyValue = tmp_x["u"]; + + if (typeof propertyValue === 'string') { + tmpPropertyObj["u"] = propertyValue; + } else { + propertySum += propertyValue; + tmpUniqVal += propertyValue; + tmpPropertyObj["u"] += propertyValue; + } + } + + for (var l = 0; l < (countlyCommon.periodObj.uniquePeriodCheckArr.length); l++) { + tmp_x = countlyCommon.getDescendantProp(db, countlyCommon.periodObj.uniquePeriodCheckArr[l] + "." + rangeArray[j]); + if (!tmp_x) { + continue; + } + tmp_x = clearFunction(tmp_x); + tmpCheckVal = tmp_x["u"]; + + if (typeof tmpCheckVal !== 'string') { + propertySum += tmpCheckVal; + tmpUniqValCheck += tmpCheckVal; + tmpPropertyObj["u"] += tmpCheckVal; + } + } + + if (tmpUniqVal > tmpUniqValCheck) { + tmpPropertyObj["u"] = tmpUniqValCheck; + } + } + + //if (propertySum > 0) + { + tableData[tableCounter] = {}; + tableData[tableCounter] = tmpPropertyObj; + tableCounter++; + } + } + } + + if (propertyNames.indexOf("t") !== -1) { + tableData = underscore.sortBy(tableData, function (obj) { + return -obj["t"] + }); + } else if (propertyNames.indexOf("c") !== -1) { + tableData = underscore.sortBy(tableData, function (obj) { + return -obj["c"] + }); + } + + for (var i = 0; i < tableData.length; i++) { + if (underscore.isEmpty(tableData[i])) { + tableData[i] = null; + } + } + + return underscore.compact(tableData); + }; // Private Methods @@ -513,143 +760,171 @@ var countlyCommon = {}, // Returns a period object used by all time related data calculation functions. function getPeriodObj() { - var now = _currMoment, - year = now.year(), - month = (now.month() + 1), - day = now.date(), - hour = (now.hours()), - activePeriod, - previousPeriod, - periodMax, - periodMin, - periodObj = {}, + var year = _currMoment.year(), + month = _currMoment.month() + 1, + day = _currMoment.date(), + hour = _currMoment.hours(), + activePeriod = "NA", + previousPeriod = "NA", + periodMax = "NA", + periodMin = "NA", isSpecialPeriod = false, daysInPeriod = 0, rangeEndDay = null, - dateString, - uniquePeriodsCheck = [], - previousUniquePeriodsCheck = []; + dateString = "NA", + currWeeksArr = [], + currWeekCounts = {}, + currMonthsArr = [], + currMonthCounts = {}, + currPeriodArr = [], + prevWeeksArr = [], + prevWeekCounts = {}, + prevMonthsArr = [], + prevMonthCounts = {}, + prevPeriodArr = []; switch (_period) { - case "month": + case "month": { activePeriod = year; previousPeriod = year - 1; periodMax = month; periodMin = 1; dateString = "MMM"; - break; - case "day": - activePeriod = year + "." + month; + daysInPeriod = parseInt(_currMoment.format("DDD"),10); - var previousDate = _currMoment.subtract('days', day), - previousYear = previousDate.year(), - previousMonth = (previousDate.month() + 1), - previousDay = previousDate.date(); + _currMoment.subtract('days', daysInPeriod); + for (var i = 0; i < daysInPeriod; i++) { + _currMoment.add('days', 1); + currPeriodArr.push(_currMoment.format("YYYY.M.D")); + } + + _currMoment.subtract('days', daysInPeriod + 365); + for (var i = 0; i < daysInPeriod; i++) { + prevPeriodArr.push(_currMoment.format("YYYY.M.D")); + _currMoment.add('days', 1); + } + _currMoment.add('days', 365); + break; + } + case "day": { + activePeriod = _currMoment.format("YYYY.M"); + _currMoment.subtract('days', day); + previousPeriod = _currMoment.format("YYYY.M"); _currMoment.add('days', day); - previousPeriod = previousYear + "." + previousMonth; periodMax = day; periodMin = 1; dateString = "D MMM"; - break; - case "hour": - activePeriod = year + "." + month + "." + day; - var previousDate = _currMoment.subtract('days', 1), - previousYear = previousDate.year(), - previousMonth = (previousDate.month() + 1), - previousDay = previousDate.date(); + daysInPeriod = day; + + for (var i = periodMin; i <= periodMax; i++) { + currPeriodArr.push(activePeriod + "." + i); + } + _currMoment.subtract('days', day + 1); + var daysInMonth = _currMoment.daysInMonth(); + _currMoment.subtract('days', daysInMonth - 1); + for (var i = 0; i < day; i++) { + _currMoment.add('days', 1); + prevPeriodArr.push(_currMoment.format("YYYY.M.D")); + } + _currMoment.add('days', daysInMonth); + + break; + } + case "hour": { + activePeriod = _currMoment.format("YYYY.M.D"); + _currMoment.subtract('days', 1); + previousPeriod = _currMoment.format("YYYY.M.D"); _currMoment.add('days', 1); - previousPeriod = previousYear + "." + previousMonth + "." + previousDay; periodMax = hour; periodMin = 0; dateString = "HH:mm"; + daysInPeriod = 1; + + currPeriodArr.push(activePeriod); + prevPeriodArr.push(previousPeriod); break; - case "yesterday": - var yesterday = _currMoment.subtract('days', 1), - year = yesterday.year(), - month = (yesterday.month() + 1), - day = yesterday.date(); - - activePeriod = year + "." + month + "." + day; - var previousDate = _currMoment.subtract('days', 2), - previousYear = previousDate.year(), - previousMonth = (previousDate.month() + 1), - previousDay = previousDate.date(); - - previousPeriod = previousYear + "." + previousMonth + "." + previousDay; + } + case "yesterday": { + _currMoment.subtract('days', 1); + activePeriod = _currMoment.format("YYYY.M.D"); + _currMoment.add('days', 1); + _currMoment.subtract('days', 2); + previousPeriod = _currMoment.format("YYYY.M.D"); + _currMoment.add('days', 2); + periodMax = 23; periodMin = 0; dateString = "D MMM, HH:mm"; + daysInPeriod = 1; + + currPeriodArr.push(activePeriod); + prevPeriodArr.push(previousPeriod); break; - case "7days": + } + case "7days": { daysInPeriod = 7; + isSpecialPeriod = true; break; - case "30days": + } + case "30days": { daysInPeriod = 30; + isSpecialPeriod = true; break; - case "60days": + } + case "60days": { daysInPeriod = 60; + isSpecialPeriod = true; break; - case "90days": + } + case "90days": { daysInPeriod = 90; + isSpecialPeriod = true; break; - default: + } + default: { break; + } } // Check whether period object is array if (Object.prototype.toString.call(_period) === '[object Array]' && _period.length == 2) { + var fromDate = new Date(_period[0]), + toDate = new Date(_period[1]); + + fromDate.setTimezone(_appTimezone); + toDate.setTimezone(_appTimezone); + // One day is selected from the datepicker if (_period[0] == _period[1]) { - var fromDate = new Date(_period[0]); - fromDate.setTimezone(_appTimezone); - var selectedDate = moment(fromDate), - selectedYear = selectedDate.year(), - selectedMonth = (selectedDate.month() + 1), - selectedDay = selectedDate.date(), - selectedHour = (selectedDate.hours()); - - activePeriod = selectedYear + "." + selectedMonth + "." + selectedDay; - - var previousDate = selectedDate.subtract('days', 1), - previousYear = previousDate.year(), - previousMonth = (previousDate.month() + 1), - previousDay = previousDate.date(); - - previousPeriod = previousYear + "." + previousMonth + "." + previousDay; + var selectedDate = moment(fromDate); + + activePeriod = selectedDate.format("YYYY.M.D"); + selectedDate.subtract('days', 1); + previousPeriod = selectedDate.format("YYYY.M.D"); + selectedDate.add('days', 1); + periodMax = 23; periodMin = 0; dateString = "D MMM, HH:mm"; + currPeriodArr.push(activePeriod); + prevPeriodArr.push(previousPeriod); } else { - var fromDate = new Date(_period[0]), - toDate = new Date(_period[1]); - - fromDate.setTimezone(_appTimezone); - toDate.setTimezone(_appTimezone); - var a = moment(fromDate), b = moment(toDate); + daysInPeriod = b.diff(a, 'days') + 1; + isSpecialPeriod = true; rangeEndDay = _period[1]; } } - if (daysInPeriod != 0) { + if (isSpecialPeriod) { var yearChanged = false, - currentYear = 0, - currWeeksArr = [], - currWeekCounts = {}, - currMonthsArr = [], - currMonthCounts = {}, - currPeriodArr = [], - prevWeeksArr = [], - prevWeekCounts = {}, - prevMonthsArr = [], - prevMonthCounts = {}, - prevPeriodArr = []; + currentYear = 0; for (var i = (daysInPeriod - 1); i > -1; i--) { @@ -704,26 +979,41 @@ var countlyCommon = {}, } dateString = (yearChanged) ? "D MMM, YYYY" : "D MMM"; - isSpecialPeriod = true; } - periodObj = { + var requiredDbDateIds = [], + requiredZeroDbDateIds = [], + dateIdSplits; + + for (var i = 0; i < prevPeriodArr.length; i++) { + dateIdSplits = prevPeriodArr[i].split("."); + arrayAddUniq(requiredZeroDbDateIds, dateIdSplits[0] + ":0"); + arrayAddUniq(requiredDbDateIds, dateIdSplits[0] + ":" + dateIdSplits[1]); + } + + for (var i = 0; i < currPeriodArr.length; i++) { + dateIdSplits = currPeriodArr[i].split("."); + arrayAddUniq(requiredZeroDbDateIds, dateIdSplits[0] + ":0"); + arrayAddUniq(requiredDbDateIds, dateIdSplits[0] + ":" + dateIdSplits[1]); + } + + return { "activePeriod":activePeriod, "periodMax":periodMax, "periodMin":periodMin, "previousPeriod":previousPeriod, "currentPeriodArr":currPeriodArr, "previousPeriodArr":prevPeriodArr, - "isSpecialPeriod":isSpecialPeriod, - "dateString":dateString, - "daysInPeriod":daysInPeriod, "uniquePeriodArr":getUniqArray(currWeeksArr, currWeekCounts, currMonthsArr, currMonthCounts, currPeriodArr), "uniquePeriodCheckArr":getUniqCheckArray(currWeeksArr, currWeekCounts, currMonthsArr, currMonthCounts), "previousUniquePeriodArr":getUniqArray(prevWeeksArr, prevWeekCounts, prevMonthsArr, prevMonthCounts, prevPeriodArr), - "previousUniquePeriodCheckArr":getUniqCheckArray(prevWeeksArr, prevWeekCounts, prevMonthsArr, prevMonthCounts) + "previousUniquePeriodCheckArr":getUniqCheckArray(prevWeeksArr, prevWeekCounts, prevMonthsArr, prevMonthCounts), + "dateString":dateString, + "daysInPeriod":daysInPeriod, + "isSpecialPeriod":isSpecialPeriod, + "reqMonthDbDateIds":requiredDbDateIds, + "reqZeroDbDateIds":requiredZeroDbDateIds }; - - return periodObj; } function getUniqArray(weeksArray, weekCounts, monthsArray, monthCounts, periodArr) { @@ -932,6 +1222,24 @@ var countlyCommon = {}, } } + function arrayAddUniq(arr, item) { + if (!arr) { + arr = []; + } + + if (toString.call(item) === "[object Array]") { + for (var i = 0; i < item.length; i++) { + if (arr.indexOf(item[i]) === -1) { + arr[arr.length] = item[i]; + } + } + } else { + if (arr.indexOf(item) === -1) { + arr[arr.length] = item; + } + } + } + }(countlyCommon)); module.exports = countlyCommon; \ No newline at end of file diff --git a/api/lib/countly.session.js b/api/lib/countly.session.js index 588214d0c4e..14af6b27fb8 100644 --- a/api/lib/countly.session.js +++ b/api/lib/countly.session.js @@ -167,6 +167,19 @@ var countlySession = {}, } }; }; + + countlySession.getSubperiodData = function () { + + var dataProps = [ + { name:"t" }, + { name:"n" }, + { name:"u" }, + { name:"d" }, + { name:"e" } + ]; + + return countlyCommon.extractData(_sessionDb, countlySession.clearSessionObject, dataProps); + }; countlySession.clearSessionObject = function (obj) { if (obj) { @@ -175,9 +188,10 @@ var countlySession = {}, if (!obj["u"]) obj["u"] = 0; if (!obj["d"]) obj["d"] = 0; if (!obj["e"]) obj["e"] = 0; + if (!obj["p"]) obj["p"] = 0; } else { - obj = {"t":0, "n":0, "u":0, "d":0, "e":0}; + obj = {"t":0, "n":0, "u":0, "d":0, "e":0, "p":0}; } return obj; diff --git a/api/node_modules/geoip-lite/README.md b/api/node_modules/geoip-lite/README.md deleted file mode 100644 index 209f1315588..00000000000 --- a/api/node_modules/geoip-lite/README.md +++ /dev/null @@ -1,141 +0,0 @@ -GeoIP-lite -========== - -A native NodeJS API for the GeoLite data from MaxMind. - -This product includes GeoLite data created by MaxMind, available from http://maxmind.com/ - -introduction ------------- - -MaxMind provides a set of data files for IP to Geo mapping along with opensource libraries to parse and lookup these data files. -One would typically write a wrapper around their C API to get access to this data in other languages (like JavaScript). - -GeoIP-lite instead attempts to be a fully native JavaScript library. A converter script converts the CSV files from MaxMind into -an internal binary format (note that this is different from the binary data format provided by MaxMind). The geoip module uses this -binary file to lookup IP addresses and return the country, region and city that it maps to. - -Both IPv4 and IPv6 addresses are supported, however since the GeoLite IPv6 database does not currently contain any city or region -information, city and region lookups are only supported for IPv4. - -philosophy ----------- - -I was really aiming for a fast JavaScript native implementation for geomapping of IPs. My prime motivator was the fact that it was -really hard to get libgeoip built for Mac OSX without using the library from MacPorts. - -why geoip-lite --------------- - -So why are we called geoip-lite? `npm` already has a [geoip package](http://search.npmjs.org/#/geoip) which provides a JavaScript -binding around libgeoip from MaxMind. The `geoip` package is fully featured and supports everything that the MaxMind APIs support, -however, it requires `libgeoip` to be installed on your system. - -`geoip-lite` on the other hand is a fully JavaScript implementation. It is not as fully featured as `geoip` however, by reducing its -scope, it is about 40% faster at doing lookups. On average, an IP to Location lookup should take 20 microseconds on a Macbook Pro. -IPv4 addresses take about 6 microseconds, while IPv6 addresses take about 30 microseconds. - -synopsis --------- - -```javascript -var geoip = require('geoip-lite'); - -var ip = "207.97.227.239"; -var geo = geoip.lookup(ip); - -console.log(geo); -{ range: [ 3479299040, 3479299071 ], - country: 'US', - region: 'CA', - city: 'San Francisco', - ll: [37.7484, -122.4156] } -``` - -installation ------------- -### 1. get the library - - $ npm install geoip-lite - -### 2. get the datafiles - -Then download the city data files from https://github.com/bluesmoon/node-geoip/tree/master/data -You need to get `geoip-city.dat` and `geoip-city-names.dat` and put them into the `data/` directory -of this package. - -API ---- - -geoip-lite is completely synchronous. There are no callbacks involved. All blocking file IO is done at startup time, so all runtime -calls are executed in-memory and are fast. Startup may take up to 200ms while it reads into memory and indexes data files. - -### Looking up an IP address ### - -If you have an IP address in dotted quad notation, IPv6 colon notation, or a 32 bit unsigned integer (treated -as an IPv4 address), pass it to the `lookup` method. Note that you should remove any `[` and `]` around an -IPv6 address before passing it to this method. - -```javascript -var geo = geoip.lookup(ip); -``` - -If the IP address was found, the `lookup` method returns an object with the following structure: - -```javascript -{ - range: [ , ], - country: 'XX', // 2 letter ISO-3166-1 country code - region: 'RR', // 2 character region code. For US states this is the 2 letter - // ISO-3166-2 subcountry code for other countries, this is the - // FIPS 10-4 subcountry code - city: "City Name", // This is the full city name - ll: [, ] // The latitude and longitude of the city -} -``` - -The actual values for the `range` array depend on whether the IP is IPv4 or IPv6 and should be -considered internal to `geoip-lite`. To get a human readable format, pass them to `geoip.pretty()` - -If the IP address was not found, the `lookup` returns `null` - -### Pretty printing an IP address ### - -If you have a 32 bit unsigned integer, or a number returned as part of the `range` array from the `lookup` method, -the `pretty` method can be used to turn it into a human readable string. - -```javascript - console.log("The IP is %s", geoip.pretty(ip)); -``` - -This method returns a string if the input was in a format that `geoip-lite` can recognise, else it returns the -input itself. - -Caveats -------- - -This package includes the GeoLite database from MaxMind. This database is not the most accurate database available, -however it is the best available for free. You can use the commercial GeoIP database from MaxMind with better -accuracy by buying a license from MaxMind, and then using the conversion utility to convert it to a format that -geoip-lite understands. You will need to use the `.csv` files from MaxMind for conversion. - -Also note that on occassion, the library may take up to 5 seconds to load into memory. This is largely dependent on -how busy your disk is at that time. It can take as little as 200ms on a lightly loaded disk. This is a one time -cost though, and you make it up at run time with very fast lookups. - -References ----------- - - Documentation from MaxMind - - ISO 3166 (1 & 2) codes - - FIPS region codes - -Copyright ---------- - -`geoip-lite` is Copyright 2011-2012 Philip Tellis and the latest version of the code is -available at https://github.com/bluesmoon/node-geoip - -License -------- - -There are two licenses for the code and data. See the [LICENSE](https://github.com/bluesmoon/node-geoip/blob/master/LICENSE) file for details. diff --git a/api/node_modules/geoip-lite/data/geoip-city-names.dat b/api/node_modules/geoip-lite/data/geoip-city-names.dat deleted file mode 100644 index 2569044c1d9..00000000000 Binary files a/api/node_modules/geoip-lite/data/geoip-city-names.dat and /dev/null differ diff --git a/api/node_modules/geoip-lite/data/geoip-city.dat b/api/node_modules/geoip-lite/data/geoip-city.dat deleted file mode 100644 index 0abac64c8e9..00000000000 Binary files a/api/node_modules/geoip-lite/data/geoip-city.dat and /dev/null differ diff --git a/api/node_modules/geoip-lite/data/geoip-country.dat b/api/node_modules/geoip-lite/data/geoip-country.dat deleted file mode 100644 index 560db741e0b..00000000000 Binary files a/api/node_modules/geoip-lite/data/geoip-country.dat and /dev/null differ diff --git a/api/node_modules/geoip-lite/data/geoip-country6.dat b/api/node_modules/geoip-lite/data/geoip-country6.dat deleted file mode 100644 index c2347fc805c..00000000000 Binary files a/api/node_modules/geoip-lite/data/geoip-country6.dat and /dev/null differ diff --git a/api/node_modules/geoip-lite/lib/city-converter.js b/api/node_modules/geoip-lite/lib/city-converter.js deleted file mode 100644 index b70fff8cf2f..00000000000 --- a/api/node_modules/geoip-lite/lib/city-converter.js +++ /dev/null @@ -1,73 +0,0 @@ -var fs = require('fs'), - LineInputStream = require('line-input-stream'); - -var bfile = process.argv[2]; -var ofile = process.argv[3]; -var lfile = bfile.replace(/-Blocks.csv/, '-Location.csv'); - -if(!bfile || !ofile) { - console.warn("Usage: %s ", require('path').basename(process.argv[1])); - process.exit(); -} - -var lastline = {'location': "", 'block': ""}; -var process_data = {}; - -var locations = []; - -process_data['block'] = function(line, i, a) { - if(line.match(/^Copyright/) || !line.match(/\d/)) { - return; - } - var fields = line.replace(/"/g, '').split(/, */); - var sip, eip, locId, b, bsz, vsz=4, i=0; - - // IPv4 - bsz = 8; - - sip = parseInt(fields[0], 10); - eip = parseInt(fields[1], 10); - locId = parseInt(fields[2], 10); - - b = new Buffer(bsz+vsz); - b.fill(0); - b.writeUInt32BE(sip>>>0, 0); - b.writeUInt32BE(eip>>>0, 4); - b.writeUInt32BE(locId>>>0, 8); - - fs.writeSync(ofd, b, 0, b.length, null); -}; - -process_data['location'] = function(line, i, a) { - if(line.match(/^Copyright/) || !line.match(/\d/)) { - return; - } - var fields = line.replace(/"/g, '').split(/, */); - var cc, rg, city, lat, lon, b, sz=32; - cc = fields[1]; - rg = fields[2]; - city = fields[3]; - lat = Math.round(parseFloat(fields[5])*10000); - lon = Math.round(parseFloat(fields[6])*10000); - - b = new Buffer(sz); - b.fill(0); - b.write(cc, 0); - b.write(rg, 2); - b.writeInt32BE(lat, 4); - b.writeInt32BE(lon, 8); - b.write(city, 12); - - fs.writeSync(lfd, b, 0, b.length, null); -}; - -var ofd = fs.openSync(ofile, "w"); -var lfd = fs.openSync(ofile.replace(/\.dat/, '-names.dat'), "w"); -var lstream = LineInputStream(fs.createReadStream(lfile), /[\r\n]+/); -lstream.setEncoding('utf8'); -var bstream = LineInputStream(fs.createReadStream(bfile), /[\r\n]+/); -bstream.setEncoding('utf8'); -lstream.on('line', process_data['location']); -bstream.on('line', process_data['block']); - - diff --git a/api/node_modules/geoip-lite/lib/country-converter.js b/api/node_modules/geoip-lite/lib/country-converter.js deleted file mode 100644 index fc7a1acaa7c..00000000000 --- a/api/node_modules/geoip-lite/lib/country-converter.js +++ /dev/null @@ -1,85 +0,0 @@ -var fs = require('fs'), - LineInputStream = require('line-input-stream'); - -var ifile = process.argv[2]; -var ofile = process.argv[3]; - -if(!ifile || !ofile) { - console.warn("Usage: %s ", require('path').basename(process.argv[1])); - process.exit(); -} - -function process_line(line) { - var fields = line.split(/, */); - if(fields.length < 6) { - console.log("weird line: %s::", line); - return; - } - var sip, eip, cc, b, bsz, i; - cc = fields[4].replace(/"/g, ''); - - if(fields[0].match(/:/)) { - // IPv6 - bsz = 34; - sip = aton6(fields[0]); - eip = aton6(fields[1]); - - b = new Buffer(bsz); - for(i=0; i=0 && ip[i] !== ""; i--) { - ip[7-l+i] = ip[i]; - } - } - for(i=0; i<8; i++) { - if(!ip[i]) - ip[i]=0; - else - ip[i] = parseInt(ip[i], 16); - } - - var r = []; - for(i=0; i<4; i++) { - r.push(((ip[2*i]<<16)+ip[2*i+1])>>>0); - } - - return r; -} - -var ofd = fs.openSync(ofile, "w"); -var istream = LineInputStream(fs.createReadStream(ifile), /[\r\n]+/); -istream.setEncoding('utf8'); -istream.on('line', process_line); - - - - diff --git a/api/node_modules/geoip-lite/lib/geoip.js b/api/node_modules/geoip-lite/lib/geoip.js deleted file mode 100644 index 7a2c4b159a5..00000000000 --- a/api/node_modules/geoip-lite/lib/geoip.js +++ /dev/null @@ -1,269 +0,0 @@ -var fs = require('fs'), - path = require('path'), - net = require('net'); - -var lookup4, lookup6, geodatadir; - -if (typeof global.geodatadir === 'undefined'){ - geodatadir = path.join(__dirname, '/../data/'); -} else { - geodatadir = global.geodatadir; -} - -(function() { -var ifile, ifd, sz, recsz, buff, lrecsz, lbuff; - -try { - ifile = path.join(geodatadir, 'geoip-city-names.dat'); - ifd = fs.openSync(ifile, "r"); - sz = fs.fstatSync(ifd).size; - lrecsz = 32; - - lbuff = new Buffer(sz); - fs.readSync(ifd, lbuff, 0, sz, 0); - fs.closeSync(ifd); - - ifile = path.join(geodatadir, 'geoip-city.dat'); - ifd = fs.openSync(ifile, "r"); - sz = fs.fstatSync(ifd).size; - recsz = 12; -} -catch(err) { - if(err.code != 'ENOENT' && err.code != 'EBADF') { - throw err; - } - ifile = path.join(geodatadir, 'geoip-country.dat'); - ifd = fs.openSync(ifile, "r"); - sz = fs.fstatSync(ifd).size; - recsz = 10; -} - -buff = new Buffer(sz); -fs.readSync(ifd, buff, 0, sz, 0); -fs.closeSync(ifd); - -var lastline = sz/recsz-1; -var lastip = buff.readUInt32BE(lastline*recsz+4); -var firstip = buff.readUInt32BE(0); - -var private_ranges = [ - [aton4("10.0.0.0"), aton4("10.255.255.255")], - [aton4("172.16.0.0"), aton4("172.31.255.255")], - [aton4("192.168.0.0"), aton4("192.168.255.255")] - ]; - -lookup4 = function(ip) { - var fline=0, floor=lastip, cline=lastline, ceil=firstip, line, locId, cc, rg, city, lat, lon, i; - - // outside IPv4 range - if(ip > lastip || ip < firstip) { - return null; - } - - // private IP - for(i=0; i= private_ranges[i][0] && ip <= private_ranges[i][1]) { - return null; - } - } - - do { - line = Math.round((cline-fline)/2)+fline; - floor = buff.readUInt32BE(line*recsz); - ceil = buff.readUInt32BE(line*recsz+4); - - if(floor <= ip && ceil >= ip) { - if(recsz == 10) { - cc = buff.toString('utf8', line*recsz+8, line*recsz+10); - rg = city = ""; - lat = lon = 0; - } - else { - locId = buff.readUInt32BE(line*recsz+8)-1; - cc = lbuff.toString('utf8', locId*lrecsz+0, locId*lrecsz+2).replace(/\u0000.*/, ''); - rg = lbuff.toString('utf8', locId*lrecsz+2, locId*lrecsz+4).replace(/\u0000.*/, ''); - lat = lbuff.readInt32BE(locId*lrecsz+4)/10000; - lon = lbuff.readInt32BE(locId*lrecsz+8)/10000; - city = lbuff.toString('utf8', locId*lrecsz+12, locId*lrecsz+lrecsz).replace(/\u0000.*/, ''); - } - - return { - range: [floor, ceil], - country: cc, - region: rg, - city: city, - ll: [ lat, lon ] - }; - } - else if(fline == cline) { - return null; - } - else if(fline == cline-1) { - if(line == fline) - fline = cline; - else - cline = fline; - } - else if(floor > ip) { - cline = line; - } - else if(ceil < ip) { - fline = line; - } - } while(1); -} - -})(); - -function aton4(a) { - a = a.split(/\./); - return ((parseInt(a[0], 10)<<24)>>>0) + ((parseInt(a[1], 10)<<16)>>>0) + ((parseInt(a[2], 10)<<8)>>>0) + (parseInt(a[3], 10)>>>0); -} - -function ntoa4(n) { - n = "" + (n>>>24&0xff) + "." + (n>>>16&0xff) + "." + (n>>>8&0xff) + "." + (n&0xff); - return n; -} - -(function() { - var ifile = path.join(geodatadir, 'geoip-country6.dat'); - var ifd = fs.openSync(ifile, "r"); - var sz = fs.fstatSync(ifd).size; - var recsz = 34; - - var buff = new Buffer(sz); - fs.readSync(ifd, buff, 0, sz, 0); - fs.closeSync(ifd); - - var lastline = sz/recsz-1; - // XXX We only use the first 8 bytes of an IPv6 address - // This identifies the network, but not the host within - // the network. Unless at some point of time we have a - // global peace treaty and single subnets span multiple - // countries, this should not be a problem. - function readip(line, offset) { - var ii=0, ip=[]; - for(ii=0; ii<2; ii++) - ip.push(buff.readUInt32BE(line*recsz+offset*16+ii*4)); - return ip; - } - - var lastip=readip(lastline, 1), firstip=readip(0, 0); - - lookup6 = function(ip) { - var fline=0, floor=lastip, cline=lastline, ceil=firstip, line; - - if(cmp6(ip, lastip) > 0 || cmp6(ip, firstip) < 0) { - return null; - } - - do { - line = Math.round((cline-fline)/2)+fline; - floor = readip(line, 0); - ceil = readip(line, 1); - - if(cmp6(floor, ip) <= 0 && cmp6(ceil, ip) >= 0) { - var cc = buff.toString('utf8', line*recsz+32, line*recsz+34); - return { range: [floor, ceil], country: cc, region: "", city: "", ll: [0, 0] }; // We do not currently have region/city info for IPv6 - } - else if(fline == cline) { - return null; - } - else if(fline == cline-1) { - if(line == fline) - fline = cline; - else - cline = fline; - } - else if(cmp6(floor, ip) > 0) { - cline = line; - } - else if(cmp6(ceil, ip) < 0) { - fline = line; - } - } while(1); - }; - -})(); - -//lookup4 = gen_lookup('geoip-country.dat', 4); -//lookup6 = gen_lookup('geoip-country6.dat', 16); - -function cmp6(a, b) { - for(var ii=0; ii<2; ii++) { - if(a[ii] < b[ii]) return -1; - if(a[ii] > b[ii]) return 1; - } - return 0; -} - -function aton6(a) { - var l, i; - a = a.replace(/"/g, '').split(/:/); - l = a.length-1; - if(a[l] === "") - a[l] = 0; - if(l < 7) { - a.length=8; - for(i=l; i>=0 && a[i] !== ""; i--) { - a[7-l+i] = a[i]; - } - } - for(i=0; i<8; i++) { - if(!a[i]) - a[i]=0; - else - a[i] = parseInt(a[i], 16); - } - - var r = []; - for(i=0; i<4; i++) { - r.push(((a[2*i]<<16)+a[2*i+1])>>>0); - } - - return r; -} - -function ntoa6(n) { - var a = "["; - for(var i=0; i>>16).toString(16) + ":"; - a+=(n[i]&0xffff).toString(16) + ":"; - } - a=a.replace(/:$/, ']').replace(/:0+/g, ':').replace(/::+/, '::'); - - return a; -} - - -exports.lookup = function(ip) { - if(!ip) - return null; - if(typeof ip == 'number') - return lookup4(ip); - if(net.isIP(ip) === 4) - return lookup4(aton4(ip)); - if(net.isIP(ip) === 6) - return lookup6(aton6(ip)); - return null; -}; - -exports.pretty = function(n) { - if(typeof n == 'string') - return n; - if(typeof n == 'number') - return ntoa4(n); - if(n instanceof Array) - return ntoa6(n); - - return n; -} - -exports.cmp = function(a, b) { - if(typeof a == 'number' && typeof b == 'number') - return (ab?1:0)); - if(a instanceof Array && b instanceof Array) - return cmp6(a, b); - return null; -} - diff --git a/api/node_modules/geoip-lite/node_modules/line-input-stream/README.md b/api/node_modules/geoip-lite/node_modules/line-input-stream/README.md deleted file mode 100644 index 7013de80710..00000000000 --- a/api/node_modules/geoip-lite/node_modules/line-input-stream/README.md +++ /dev/null @@ -1,78 +0,0 @@ -node-line-input-stream -====================== - -Convert a Node.JS Readable Stream into a Line Buffered Input Stream - -Install ---- - -``` -npm install line-input-stream -``` - -Usage ---- - -Like [Readable Stream](http://nodejs.org/api/stream.html#stream_readable_stream) with a `line` event. - -```javascript -var LineInputStream = require('line-input-stream'), - fs = require('fs'); - -var stream = LineInputStream(fs.createReadStream("foo.txt", { flags: "r" })); -stream.setEncoding("utf8"); -stream.setDelimiter("\n"); // optional string, defaults to "\n" - -stream.on("error", function(err) { - console.log(err); - }); - -stream.on("data", function(chunk) { - // You don't need to use this event - }); - -stream.on("line", function(line) { - // Sends you lines from the stream delimited by delimiter - }); - -stream.on("end", function() { - // No more data, all line events emitted before this event - }); - -stream.on("close", function() { - // Same as ReadableStream's close event - }); - -if(stream.readable) { - console.log("stream is readable"); -} - -// Also available: pause(), resume(), destroy(), pipe() -``` - -You can also attach listeners to any event specific to the underlying stream, ie, -you can listen to the `open` event for streams created by [`fs.createReadStream()`](http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options) -or the `connect` event for [Net](http://nodejs.org/api/net.html) streams. - -A side effect of this is that you can add a listener for any junk string and `LineInputStream` will -pretend that it worked. The event listener may never be called though. - -Caveats & Notes ---- -- Calling `pause()` might not stop `line` events from firing immediately. It will stop reading of data - from the underlying stream, but any data that has already been read will still be split into lines and - a `line` event will be fired for each of them. -- The delimiter is not included in the line passed to the `line` handler -- Even though this is called `line-input-stream`, you can delimit by anything, so for example, - setting delimiter to `"\n\n"` will read by paragraph (sort of). -- You can set the delimiter to a regular expression, which let's you do cool things like drop multiple blank lines: `/[\r\n]+/` -- All methods return `this`, so can be chained - - -Copyright ---- -Philip Tellis [@bluesmoon](https://twitter.com/bluesmoon) - -License ---- -(Apache License)[LICENSE.md] diff --git a/api/node_modules/geoip-lite/node_modules/line-input-stream/lib/line-input-stream.js b/api/node_modules/geoip-lite/node_modules/line-input-stream/lib/line-input-stream.js deleted file mode 100644 index fcd1d39cdda..00000000000 --- a/api/node_modules/geoip-lite/node_modules/line-input-stream/lib/line-input-stream.js +++ /dev/null @@ -1,137 +0,0 @@ -var EventEmitter = require('events').EventEmitter, - Stream = require('stream'), - util = require('util'); - - -var _events = { - "line": function(line) { - this.emit("line", line); - }, - "end": function() { - this.emit("end"); - } -}; - -function LineInputStream(underlyingStream, delimiter) -{ - if(!(this instanceof LineInputStream)) { - return new LineInputStream(underlyingStream); - } - if(!underlyingStream) { - throw new Error("LineInputStream requires an underlying stream"); - } - - Stream.call(this); - - this.underlyingStream = underlyingStream; - this.delimiter = delimiter? delimiter: "\n"; - - var self = this, - data = ""; - - this.underlyingStream.on("data", function(chunk) { - data += chunk; - var lines = data.split(self.delimiter); - data = lines.pop(); - lines.forEach(_events.line, self); - }); - this.underlyingStream.on("end", function() { - if(data.length > 0) { - var lines = data.split(self.delimiter); - lines.forEach(_events.line, self); - } - _events.end.call(self); - }); - - Object.defineProperty(this, "readable", { - get: function() { - return self.underlyingStream.readable; - }, - enumerable: true, - - }); - - Object.defineProperty(this, "paused", { - get: function() { - return self.underlyingStream.paused; - }, - enumerable: true, - - }); -} - -util.inherits(LineInputStream, Stream); - -// Start overriding EventEmitter methods so we can pass through to underlyingStream -// If we get a request for an event we don't know about, pass it to the underlyingStream - -LineInputStream.prototype.addListener = function(type, listener) { - if(!(type in _events)) { - this.underlyingStream.on(type, listener); - } - EventEmitter.prototype.on.call(this, type, listener); - - return this; -}; - -LineInputStream.prototype.on = LineInputStream.prototype.addListener; - -LineInputStream.prototype.removeListener = function(type, listener) { - if(!(type in _events)) { - this.underlyingStream.removeListener(type, listener); - } - EventEmitter.prototype.removeListener.call(this, type, listener); - - return this; -}; - -LineInputStream.prototype.removeAllListeners = function(type) { - if(!(type in _events)) { - this.underlyingStream.removeAllListeners(type); - } - EventEmitter.prototype.removeAllListeners.call(this, type); - - return this; -}; - -// End overriding EventEmitter methods - -// Start passthrough of Readable Stream methods for underlying stream -LineInputStream.prototype.pause = function() { - if(this.underlyingStream.pause) - this.underlyingStream.pause(); - - return this; -}; - -LineInputStream.prototype.resume = function() { - if(this.underlyingStream.resume) - this.underlyingStream.resume(); - - return this; -}; - -LineInputStream.prototype.destroy = function() { - if(this.underlyingStream.destroy) - this.underlyingStream.destroy(); - - return this; -}; - -LineInputStream.prototype.setEncoding = function(encoding) { - if(this.underlyingStream.setEncoding) - this.underlyingStream.setEncoding(encoding); - - return this; -}; - -// End passthrough of Readable Stream methods - -LineInputStream.prototype.setDelimiter = function(delimiter) { - this.delimiter = delimiter; - - return this; -}; - -module.exports = LineInputStream; - diff --git a/api/node_modules/geoip-lite/node_modules/line-input-stream/package.json b/api/node_modules/geoip-lite/node_modules/line-input-stream/package.json deleted file mode 100644 index 95bd82818d7..00000000000 --- a/api/node_modules/geoip-lite/node_modules/line-input-stream/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "line-input-stream", - "version": "1.0.1", - "description": "Convert a Node.JS Readable Stream into a Line Buffered Input Stream", - "keywords": [ - "stream", - "input", - "line", - "line-buffered", - "readable stream" - ], - "homepage": "https://github.com/bluesmoon/node-line-input-stream", - "author": { - "name": "Philip Tellis", - "email": "philip@bluesmoon.info", - "url": "http://bluesmoon.info/" - }, - "files": [ - "lib/" - ], - "main": "lib/line-input-stream.js", - "repository": { - "type": "git", - "url": "git://github.com/bluesmoon/node-line-input-stream.git" - }, - "engines": { - "node": ">=0.8.8" - }, - "readme": "node-line-input-stream\n======================\n\nConvert a Node.JS Readable Stream into a Line Buffered Input Stream\n\nInstall\n---\n\n```\nnpm install line-input-stream\n```\n\nUsage\n---\n\nLike [Readable Stream](http://nodejs.org/api/stream.html#stream_readable_stream) with a `line` event.\n\n```javascript\nvar LineInputStream = require('line-input-stream'),\n fs = require('fs');\n\nvar stream = LineInputStream(fs.createReadStream(\"foo.txt\", { flags: \"r\" }));\nstream.setEncoding(\"utf8\");\nstream.setDelimiter(\"\\n\");\t// optional string, defaults to \"\\n\"\n\nstream.on(\"error\", function(err) {\n\t\tconsole.log(err);\n\t});\n\nstream.on(\"data\", function(chunk) {\n\t\t// You don't need to use this event\n\t});\n\nstream.on(\"line\", function(line) {\n\t\t// Sends you lines from the stream delimited by delimiter\n\t});\n\nstream.on(\"end\", function() {\n\t\t// No more data, all line events emitted before this event\n\t});\n\nstream.on(\"close\", function() {\n\t\t// Same as ReadableStream's close event\n\t});\n\nif(stream.readable) {\n\tconsole.log(\"stream is readable\");\n}\n\n// Also available: pause(), resume(), destroy(), pipe()\n```\n\nYou can also attach listeners to any event specific to the underlying stream, ie,\nyou can listen to the `open` event for streams created by [`fs.createReadStream()`](http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options)\nor the `connect` event for [Net](http://nodejs.org/api/net.html) streams.\n\nA side effect of this is that you can add a listener for any junk string and `LineInputStream` will\npretend that it worked. The event listener may never be called though.\n\nCaveats & Notes\n---\n- Calling `pause()` might not stop `line` events from firing immediately. It will stop reading of data\n from the underlying stream, but any data that has already been read will still be split into lines and\n a `line` event will be fired for each of them.\n- The delimiter is not included in the line passed to the `line` handler\n- Even though this is called `line-input-stream`, you can delimit by anything, so for example,\n setting delimiter to `\"\\n\\n\"` will read by paragraph (sort of).\n- You can set the delimiter to a regular expression, which let's you do cool things like drop multiple blank lines: `/[\\r\\n]+/`\n- All methods return `this`, so can be chained\n\n\nCopyright\n---\nPhilip Tellis [@bluesmoon](https://twitter.com/bluesmoon) \n\nLicense\n---\n(Apache License)[LICENSE.md]\n", - "readmeFilename": "README.md", - "_id": "line-input-stream@1.0.1", - "dist": { - "shasum": "2c9072b35ac73eab5be5d5ab25ac233fb3679897" - }, - "_from": "line-input-stream" -} diff --git a/api/node_modules/geoip-lite/package.json b/api/node_modules/geoip-lite/package.json deleted file mode 100644 index 640b707a2f5..00000000000 --- a/api/node_modules/geoip-lite/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "geoip-lite", - "version": "1.0.10", - "description": "A light weight native JavaScript implementation of GeoIP API from MaxMind", - "keywords": [ - "geo", - "geoip", - "ip", - "ipv4", - "ipv6", - "geolookup", - "maxmind", - "geolite" - ], - "homepage": "https://github.com/bluesmoon/node-geoip", - "author": { - "name": "Philip Tellis", - "email": "philip@bluesmoon.info", - "url": "http://bluesmoon.info/" - }, - "files": [ - "lib/", - "data/geoip-country.dat", - "data/geoip-country6.dat", - "test/" - ], - "main": "lib/geoip.js", - "repository": { - "type": "git", - "url": "git://github.com/bluesmoon/node-geoip.git" - }, - "engines": { - "node": ">=0.5.7" - }, - "scripts": { - "test": "mocha test/geo-lookup.test.js" - }, - "devDependencies": { - "mocha": "~1.0.3", - "line-input-stream": "~1.0.0" - }, - "readme": "GeoIP-lite\n==========\n\nA native NodeJS API for the GeoLite data from MaxMind.\n\nThis product includes GeoLite data created by MaxMind, available from http://maxmind.com/\n\nintroduction\n------------\n\nMaxMind provides a set of data files for IP to Geo mapping along with opensource libraries to parse and lookup these data files.\nOne would typically write a wrapper around their C API to get access to this data in other languages (like JavaScript).\n\nGeoIP-lite instead attempts to be a fully native JavaScript library. A converter script converts the CSV files from MaxMind into\nan internal binary format (note that this is different from the binary data format provided by MaxMind). The geoip module uses this\nbinary file to lookup IP addresses and return the country, region and city that it maps to.\n\nBoth IPv4 and IPv6 addresses are supported, however since the GeoLite IPv6 database does not currently contain any city or region\ninformation, city and region lookups are only supported for IPv4.\n\nphilosophy\n----------\n\nI was really aiming for a fast JavaScript native implementation for geomapping of IPs. My prime motivator was the fact that it was\nreally hard to get libgeoip built for Mac OSX without using the library from MacPorts.\n\nwhy geoip-lite\n--------------\n\nSo why are we called geoip-lite? `npm` already has a [geoip package](http://search.npmjs.org/#/geoip) which provides a JavaScript\nbinding around libgeoip from MaxMind. The `geoip` package is fully featured and supports everything that the MaxMind APIs support,\nhowever, it requires `libgeoip` to be installed on your system.\n\n`geoip-lite` on the other hand is a fully JavaScript implementation. It is not as fully featured as `geoip` however, by reducing its\nscope, it is about 40% faster at doing lookups. On average, an IP to Location lookup should take 20 microseconds on a Macbook Pro.\nIPv4 addresses take about 6 microseconds, while IPv6 addresses take about 30 microseconds.\n\nsynopsis\n--------\n\n```javascript\nvar geoip = require('geoip-lite');\n\nvar ip = \"207.97.227.239\";\nvar geo = geoip.lookup(ip);\n\nconsole.log(geo);\n{ range: [ 3479299040, 3479299071 ],\n country: 'US',\n region: 'CA',\n city: 'San Francisco',\n ll: [37.7484, -122.4156] }\n```\n\ninstallation\n------------\n### 1. get the library\n\n $ npm install geoip-lite\n\n### 2. get the datafiles\n\nThen download the city data files from https://github.com/bluesmoon/node-geoip/tree/master/data\nYou need to get `geoip-city.dat` and `geoip-city-names.dat` and put them into the `data/` directory\nof this package.\n\nAPI\n---\n\ngeoip-lite is completely synchronous. There are no callbacks involved. All blocking file IO is done at startup time, so all runtime\ncalls are executed in-memory and are fast. Startup may take up to 200ms while it reads into memory and indexes data files.\n\n### Looking up an IP address ###\n\nIf you have an IP address in dotted quad notation, IPv6 colon notation, or a 32 bit unsigned integer (treated\nas an IPv4 address), pass it to the `lookup` method. Note that you should remove any `[` and `]` around an\nIPv6 address before passing it to this method.\n\n```javascript\nvar geo = geoip.lookup(ip);\n```\n\nIf the IP address was found, the `lookup` method returns an object with the following structure:\n\n```javascript\n{\n range: [ , ],\n country: 'XX', // 2 letter ISO-3166-1 country code\n region: 'RR', // 2 character region code. For US states this is the 2 letter\n // ISO-3166-2 subcountry code for other countries, this is the\n // FIPS 10-4 subcountry code\n city: \"City Name\", // This is the full city name\n ll: [, ] // The latitude and longitude of the city\n}\n```\n\nThe actual values for the `range` array depend on whether the IP is IPv4 or IPv6 and should be\nconsidered internal to `geoip-lite`. To get a human readable format, pass them to `geoip.pretty()`\n\nIf the IP address was not found, the `lookup` returns `null`\n\n### Pretty printing an IP address ###\n\nIf you have a 32 bit unsigned integer, or a number returned as part of the `range` array from the `lookup` method,\nthe `pretty` method can be used to turn it into a human readable string.\n\n```javascript\n console.log(\"The IP is %s\", geoip.pretty(ip));\n```\n\nThis method returns a string if the input was in a format that `geoip-lite` can recognise, else it returns the\ninput itself.\n\nCaveats\n-------\n\nThis package includes the GeoLite database from MaxMind. This database is not the most accurate database available,\nhowever it is the best available for free. You can use the commercial GeoIP database from MaxMind with better\naccuracy by buying a license from MaxMind, and then using the conversion utility to convert it to a format that\ngeoip-lite understands. You will need to use the `.csv` files from MaxMind for conversion.\n\nAlso note that on occassion, the library may take up to 5 seconds to load into memory. This is largely dependent on\nhow busy your disk is at that time. It can take as little as 200ms on a lightly loaded disk. This is a one time\ncost though, and you make it up at run time with very fast lookups.\n\nReferences\n----------\n - Documentation from MaxMind\n - ISO 3166 (1 & 2) codes\n - FIPS region codes\n\nCopyright\n---------\n\n`geoip-lite` is Copyright 2011-2012 Philip Tellis and the latest version of the code is\navailable at https://github.com/bluesmoon/node-geoip\n\nLicense\n-------\n\nThere are two licenses for the code and data. See the [LICENSE](https://github.com/bluesmoon/node-geoip/blob/master/LICENSE) file for details.\n", - "readmeFilename": "README.md", - "_id": "geoip-lite@1.0.10", - "_from": "geoip-lite" -} diff --git a/api/node_modules/geoip-lite/test/geo-lookup.js b/api/node_modules/geoip-lite/test/geo-lookup.js deleted file mode 100644 index c3a5e4ddcde..00000000000 --- a/api/node_modules/geoip-lite/test/geo-lookup.js +++ /dev/null @@ -1,49 +0,0 @@ -var assert = require('assert'); -var t1=+new Date; -var geoip = require('../lib/geoip'); -var t2=+new Date; - -if(process.argv.length > 2) { - console.dir(geoip.lookup(process.argv[2])); - var t3 = +new Date; - console.log("Startup: %dms, exec: %dms", t2-t1, t3-t2); - process.exit(); -} - -var n=30000; - -var f=[], nf=[]; -var ts = +new Date(); -for(var i=0; i= 0 , "Problem with " + geoip.pretty(ip) + " < " + geoip.pretty(r.range[0])); - assert.ok(geoip.cmp(ip, r.range[1]) <= 0 , "Problem with " + geoip.pretty(ip) + " > " + geoip.pretty(r.range[1])); -} -var te = +new Date(); - -/* -f.forEach(function(ip) { - console.log("%s bw %s & %s is %s", geoip.pretty(ip[0]), geoip.pretty(ip[1].range[0]), geoip.pretty(ip[1].range[1]), ip[1].country); -}); -*/ - -console.log("Found %d (%d/%d) ips in %dms (%s ip/s) (%sμs/ip)", n, f.length, nf.length, te-ts, (n*1000/(te-ts)).toFixed(3), ((te-ts)*1000/n).toFixed(0)); -console.log("Took %d ms to startup", t2-t1); - - diff --git a/api/node_modules/geoip-lite/test/geo-lookup.test.js b/api/node_modules/geoip-lite/test/geo-lookup.test.js deleted file mode 100644 index 303258712af..00000000000 --- a/api/node_modules/geoip-lite/test/geo-lookup.test.js +++ /dev/null @@ -1,10 +0,0 @@ -describe('Global leak test', function() { - - it('no global leaks should exist', function() { - - var geoip = require('../lib/geoip'); - - geoip.lookup('127.0.0.1'); - - }); -}); \ No newline at end of file diff --git a/api/node_modules/moment/.jshintrc b/api/node_modules/moment/.jshintrc deleted file mode 100644 index 27ae76d2d00..00000000000 --- a/api/node_modules/moment/.jshintrc +++ /dev/null @@ -1,26 +0,0 @@ -{ - "node" : true, - "es5" : true, - "browser" : true, - "boss" : false, - "curly": true, - "debug": false, - "devel": false, - "eqeqeq": true, - "eqnull": true, - "evil": false, - "forin": false, - "immed": false, - "laxbreak": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": false, - "onevar": true, - "plusplus": false, - "regexp": false, - "undef": true, - "sub": true, - "strict": false, - "white": true -} diff --git a/api/node_modules/moment/.npmignore b/api/node_modules/moment/.npmignore deleted file mode 100644 index 12ac6472027..00000000000 --- a/api/node_modules/moment/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -.DS_Store \ No newline at end of file diff --git a/api/node_modules/moment/.travis.yml b/api/node_modules/moment/.travis.yml deleted file mode 100644 index 54dbb953f5a..00000000000 --- a/api/node_modules/moment/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.6 - - 0.8 \ No newline at end of file diff --git a/api/node_modules/moment/CONTRIBUTING.md b/api/node_modules/moment/CONTRIBUTING.md deleted file mode 100644 index b0305761456..00000000000 --- a/api/node_modules/moment/CONTRIBUTING.md +++ /dev/null @@ -1,34 +0,0 @@ -Submitting Issues -================= - -If you are submitting a bug with moment, please create a [jsfiddle](http://jsfiddle.net/) demonstrating the issue. - -Contributing -============ - -To contribute, fork the library and install these npm packages. - - npm install jshint uglify-js nodeunit - -You can add tests to the files in `/test/moment` or add a new test file if you are adding a new feature. - -To run the tests, do `make test` to run all tests, `make test-moment` to test the core library, and `make test-lang` to test all the languages. - -To check the filesize, you can use `make size`. - -To minify all the files, use `make moment` to minify moment, `make langs` to minify all the lang files, or just `make` to minfy everything. - -If your code passes the unit tests (including the ones you wrote), submit a pull request. - -Submitting pull requests -======================== - -Moment.js now uses [git-flow](https://github.com/nvie/gitflow). If you're not familiar with git-flow, please read up on it, you'll be glad you did. - -When submitting new features, please create a new feature branch using `git flow feature start ` and submit the pull request to the `develop` branch. - -Pull requests for enhancements for features should be submitted to the `develop` branch as well. - -When submitting a bugfix, please check if there is an existing bugfix branch. If the latest stable version is `1.5.0`, the bugfix branch would be `hotfix/1.5.1`. All pull requests for bug fixes should be on a `hotfix` branch, unless the bug fix depends on a new feature. - -The `master` branch should always have the latest stable version. When bugfix or minor releases are needed, the develop/hotfix branch will be merged into master and released. diff --git a/api/node_modules/moment/LICENSE b/api/node_modules/moment/LICENSE deleted file mode 100644 index 8beeefc3bff..00000000000 --- a/api/node_modules/moment/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2011-2012 Tim Wood - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/moment/Makefile b/api/node_modules/moment/Makefile deleted file mode 100644 index 5f617c201e5..00000000000 --- a/api/node_modules/moment/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -LANG_ALL = $(wildcard lang/*.js) -MIN_LANG_ALL = $(addprefix min/,$(LANG_ALL)) - - -.PHONY: all -all: moment langs - -min/: - mkdir min/ - -min/lang/: - mkdir -p min/lang/ - -.PHONY: moment pretty -moment: min/ min/moment.min.js pretty - -pretty: min/ min/moment.min.pretty.js - -min/moment.min.js: moment.js - node_modules/.bin/uglifyjs -o $@ $< - -min/moment.min.pretty.js: moment.js - node_modules/.bin/uglifyjs -b -o $@ $< - -min/lang/%: lang/% - node_modules/.bin/uglifyjs --ascii -o $@ $< - -min/lang-all.min.js: $(LANG_ALL) - cat $^ | node_modules/.bin/uglifyjs --ascii -o $@ - -.PHONY: langs -langs: min/lang/ $(MIN_LANG_ALL) min/lang-all.min.js - -.PHONY: size -size: moment langs - # FILESIZE FOR ALL LANGS - cp min/lang-all.min.js min/lang-all.min.gzip.js - gzip min/lang-all.min.gzip.js - gzip -l min/lang-all.min.gzip.js.gz - rm min/lang-all.min.gzip.js.gz - # FILESIZE FOR LIBRARY - cp min/moment.min.js min/moment.min.gzip.js - gzip min/moment.min.gzip.js - gzip -l min/moment.min.gzip.js.gz - rm min/moment.min.gzip.js.gz - -.PHONY: size-history -size-history: moment - node test/filesize-history.js - -size-diff: moment - node test/filesize-diff.js - - -.PHONY: test hint test-moment test-lang -test: hint test-moment test-lang -test-zone: - node test/zone - -hint: - node_modules/.bin/jshint moment.js - -test-moment: - node_modules/.bin/nodeunit ./test/moment - -test-lang: - node_modules/.bin/nodeunit ./test/lang - -.PHONY: clean -clean: - rm -rf min/ diff --git a/api/node_modules/moment/README.markdown b/api/node_modules/moment/README.markdown deleted file mode 100644 index b91dc21b6b4..00000000000 --- a/api/node_modules/moment/README.markdown +++ /dev/null @@ -1,210 +0,0 @@ -[Moment.js](http://momentjs.com) -================================ - -A lightweight javascript date library for parsing, manipulating, and formatting dates. - -### [Check out the website](http://momentjs.com) - -### [Read the documentation](http://momentjs.com/docs/) - -### [Run the unit tests](http://momentjs.com/test/) - - -Upgrading to 1.6.0 -================== - -There are a few things being deprecated in the 1.6.0 release. - -1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background. - -2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances. - -3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222). - - -Contributing -============ - -To contribute, fork the library and install these npm packages. - - npm install jshint uglify-js nodeunit - -You can add tests to the files in `/test/moment` or add a new test file if you are adding a new feature. - -To run the tests, do `make test` to run all tests, `make test-moment` to test the core library, and `make test-lang` to test all the languages. - -To check the filesize, you can use `make size`. - -To minify all the files, use `make moment` to minify moment, `make langs` to minify all the lang files, or just `make` to minfy everything. - -If your code passes the unit tests (including the ones you wrote), submit a pull request. - -Submitting pull requests -======================== - -Moment.js now uses [git-flow](https://github.com/nvie/gitflow). If you're not familiar with git-flow, please read up on it, you'll be glad you did. - -When submitting new features, please create a new feature branch using `git flow feature start ` and submit the pull request to the `develop` branch. - -Pull requests for enhancements for features should be submitted to the `develop` branch as well. - -When submitting a bugfix, please check if there is an existing bugfix branch. If the latest stable version is `1.5.0`, the bugfix branch would be `hotfix/1.5.1`. All pull requests for bug fixes should be on a `hotfix` branch, unless the bug fix depends on a new feature. - -The `master` branch should always have the latest stable version. When bugfix or minor releases are needed, the develop/hotfix branch will be merged into master and released. - -Changelog -========= - - -### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268) - -Added Durations. - -Revamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD). - -Added support for millisecond parsing and formatting tokens (S SS SSS) - -Added a getter for `moment.lang()` - -Various bugfixes. - -### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed) - -Added UTC mode. - -Added automatic ISO8601 parsing. - -Various bugfixes. - -### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed) - -Added `moment.fn.toDate` as a replacement for `moment.fn.native`. - -Added `moment.fn.sod` and `moment.fn.eod` to get the start and end of day. - -Various bugfixes. - -### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed) - -Added support for parsing month names in the current language. - -Added escape blocks for parsing tokens. - -Added `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'. - -Added `moment.fn.day` as a setter. - -Various bugfixes - -### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed) - -Added timezones to parser and formatter. - -Added `moment.fn.isDST`. - -Added `moment.fn.zone` to get the timezone offset in minutes. - -### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed) - -Various bugfixes - -### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed) - -Added time specific diffs (months, days, hours, etc) - -### 1.1.0 - -Added `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29) - -Fixed [issue 31](https://github.com/timrwood/moment/pull/31). - -### 1.0.1 - -Added `moment.version` to get the current version. - -Removed `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25) - -### 1.0.0 - -Added convenience methods for getting and setting date parts. - -Added better support for `moment.add()`. - -Added better lang support in NodeJS. - -Renamed library from underscore.date to Moment.js - -### 0.6.1 - -Added Portuguese, Italian, and French language support - -### 0.6.0 - -Added _date.lang() support. -Added support for passing multiple formats to try to parse a date. _date("07-10-1986", ["MM-DD-YYYY", "YYYY-MM-DD"]); -Made parse from string and single format 25% faster. - -### 0.5.2 - -Buxfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9). - -### 0.5.1 - -Buxfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5). - -### 0.5.0 - -Dropped the redundant `_date.date()` in favor of `_date()`. -Removed `_date.now()`, as it is a duplicate of `_date()` with no parameters. -Removed `_date.isLeapYear(yearNuumber)`. Use `_date([yearNumber]).isLeapYear()` instead. -Exposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function. - -### 0.4.1 - -Added date input formats for input strings. - -### 0.4.0 - -Added underscore.date to npm. Removed dependancies on underscore. - -### 0.3.2 - -Added `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes. - -### 0.3.1 - -Cleaned up the namespace. Moved all date manipulation and display functions to the _.date() object. - -### 0.3.0 - -Switched to the Underscore methodology of not mucking with the native objects' prototypes. -Made chaining possible. - -### 0.2.1 - -Changed date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'. -Added `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`. - -### 0.2.0 - -Changed function names to be more concise. -Changed date format from php date format to custom format. - -### 0.1.0 - -Initial release - -License -======= - -Moment.js is freely distributable under the terms of the MIT license. - -Copyright (c) 2011-2012 Tim Wood - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/moment/ender.js b/api/node_modules/moment/ender.js deleted file mode 100644 index 71462a77080..00000000000 --- a/api/node_modules/moment/ender.js +++ /dev/null @@ -1 +0,0 @@ -$.ender({ moment: require('moment') }) diff --git a/api/node_modules/moment/lang/bg.js b/api/node_modules/moment/lang/bg.js deleted file mode 100644 index dc13ac9636a..00000000000 --- a/api/node_modules/moment/lang/bg.js +++ /dev/null @@ -1,66 +0,0 @@ -// moment.js language configuration -// language : bulgarian (bg) -// author : Krasen Borisov : https://github.com/kraz -(function () { - var lang = { - months : "Ñнуари_февруари_март_април_май_юни_юли_авгуÑÑ‚_Ñептември_октомври_ноември_декември".split("_"), - monthsShort : "Ñнр_фев_мар_апр_май_юни_юли_авг_Ñеп_окт_ное_дек".split("_"), - weekdays : "неделÑ_понеделник_вторник_ÑÑ€Ñда_четвъртък_петък_Ñъбота".split("_"), - weekdaysShort : "нед_пон_вто_ÑÑ€Ñ_чет_пет_Ñъб".split("_"), - weekdaysMin : "нд_пн_вт_ÑÑ€_чт_пт_Ñб".split("_"), - longDateFormat : { - LT : "h:mm", - L : "D.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" - }, - calendar : { - sameDay : '[Ð”Ð½ÐµÑ Ð²] LT', - nextDay : '[Утре в] LT', - nextWeek : 'dddd [в] LT', - lastDay : '[Вчера в] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[Ð’ изминалата] dddd [в] LT'; - case 1: - case 2: - case 4: - case 5: - return '[Ð’ изминалиÑ] dddd [в] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : "Ñлед %s", - past : "преди %s", - s : "нÑколко Ñекунди", - m : "минута", - mm : "%d минути", - h : "чаÑ", - hh : "%d чаÑа", - d : "ден", - dd : "%d дни", - M : "меÑец", - MM : "%d меÑеца", - y : "година", - yy : "%d години" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined') { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('bg', lang); - } -}()); diff --git a/api/node_modules/moment/lang/ca.js b/api/node_modules/moment/lang/ca.js deleted file mode 100644 index 5eae6e789c4..00000000000 --- a/api/node_modules/moment/lang/ca.js +++ /dev/null @@ -1,64 +0,0 @@ -// moment.js language configuration -// language : catalan (ca) -// author : Juan G. Hurtado : https://github.com/juanghurtado -(function () { - var lang = { - months : "Gener_Febrer_Març_Abril_Maig_Juny_Juliol_Agost_Setembre_Octubre_Novembre_Desembre".split("_"), - monthsShort : "Gen._Febr._Mar._Abr._Mai._Jun._Jul._Ag._Set._Oct._Nov._Des.".split("_"), - weekdays : "Diumenge_Dilluns_Dimarts_Dimecres_Dijous_Divendres_Dissabte".split("_"), - weekdaysShort : "Dg._Dl._Dt._Dc._Dj._Dv._Ds.".split("_"), - weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay : function () { - return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextDay : function () { - return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastDay : function () { - return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : "en %s", - past : "fa %s", - s : "uns segons", - m : "un minut", - mm : "%d minuts", - h : "una hora", - hh : "%d hores", - d : "un dia", - dd : "%d dies", - M : "un mes", - MM : "%d mesos", - y : "un any", - yy : "%d anys" - }, - ordinal : function (number) { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('ca', lang); - } -}()); diff --git a/api/node_modules/moment/lang/cv.js b/api/node_modules/moment/lang/cv.js deleted file mode 100644 index a27789cf957..00000000000 --- a/api/node_modules/moment/lang/cv.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : chuvash (cv) -// author : Anatoly Mironov : https://github.com/mirontoli -(function () { - var lang = { - months : "кăрлач_нарăÑ_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"), - monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"), - weekdays : "вырÑарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_Ñрнекун_шăматкун".split("_"), - weekdaysShort : "выр_тун_ытл_юн_кĕç_Ñрн_шăм".split("_"), - weekdaysMin : "вр_тн_Ñ‹Ñ‚_юн_кç_ÑÑ€_шм".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD-MM-YYYY", - LL : "YYYY çулхи MMMM уйăхĕн D-мĕшĕ", - LLL : "YYYY çулхи MMMM уйăхĕн D-мĕшĕ, LT", - LLLL : "dddd, YYYY çулхи MMMM уйăхĕн D-мĕшĕ, LT" - }, - calendar : { - sameDay: '[ПаÑн] LT [Ñехетре]', - nextDay: '[Ыран] LT [Ñехетре]', - lastDay: '[Ĕнер] LT [Ñехетре]', - nextWeek: '[ÇитеÑ] dddd LT [Ñехетре]', - lastWeek: '[Иртнĕ] dddd LT [Ñехетре]', - sameElse: 'L' - }, - relativeTime : { - future : function(output) { - var affix = /Ñехет$/i.exec(output) - ? "рен" : /çул$/i.exec(output) ? "тан" : "ран"; - return output + affix; - }, - past : "%s каÑлла", - s : "пĕр-ик çеккунт", - m : "пĕр минут", - mm : "%d минут", - h : "пĕр Ñехет", - hh : "%d Ñехет", - d : "пĕр кун", - dd : "%d кун", - M : "пĕр уйăх", - MM : "%d уйăх", - y : "пĕр çул", - yy : "%d çул" - }, - ordinal : function (number) { - return '-мĕш'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('cv', lang); - } -}()); diff --git a/api/node_modules/moment/lang/da.js b/api/node_modules/moment/lang/da.js deleted file mode 100644 index 0c3c36c097c..00000000000 --- a/api/node_modules/moment/lang/da.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : danish (da) -// author : Ulrik Nielsen : https://github.com/mrbase -(function () { - var lang = { - months : "Januar_Februar_Marts_April_Maj_Juni_Juli_August_September_Oktober_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec".split("_"), - weekdays : "Søndag_Mandag_Tirsdag_Onsdag_Torsdag_Fredag_Lørdag".split("_"), - weekdaysShort : "Søn_Man_Tir_Ons_Tor_Fre_Lør".split("_"), - weekdaysMin : "Sø_Ma_Ti_On_To_Fr_Lø".split("_"), - longDateFormat : { - LT : "h:mm A", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY h:mm A", - LLLL : "dddd D. MMMM, YYYY h:mm A" - }, - calendar : { - sameDay : '[I dag kl.] LT', - nextDay : '[I morgen kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[I gÃ¥r kl.] LT', - lastWeek : '[sidste] dddd [kl] LT', - sameElse : 'L' - }, - relativeTime : { - future : "om %s", - past : "%s siden", - s : "fÃ¥ sekunder", - m : "minut", - mm : "%d minutter", - h : "time", - hh : "%d timer", - d : "dag", - dd : "%d dage", - M : "mÃ¥nede", - MM : "%d mÃ¥neder", - y : "Ã¥r", - yy : "%d Ã¥r" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('da', lang); - } -}()); diff --git a/api/node_modules/moment/lang/de.js b/api/node_modules/moment/lang/de.js deleted file mode 100644 index bbe4e13d50b..00000000000 --- a/api/node_modules/moment/lang/de.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : german (de) -// author : lluchs : https://github.com/lluchs -(function () { - var lang = { - months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), - monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), - weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), - weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), - weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), - longDateFormat : { - LT: "H:mm U\\hr", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" - }, - calendar : { - sameDay: "[Heute um] LT", - sameElse: "L", - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' - }, - relativeTime : { - future : "in %s", - past : "vor %s", - s : "ein paar Sekunden", - m : "einer Minute", - mm : "%d Minuten", - h : "einer Stunde", - hh : "%d Stunden", - d : "einem Tag", - dd : "%d Tagen", - M : "einem Monat", - MM : "%d Monaten", - y : "einem Jahr", - yy : "%d Jahren" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('de', lang); - } -}()); diff --git a/api/node_modules/moment/lang/en-ca.js b/api/node_modules/moment/lang/en-ca.js deleted file mode 100644 index 47dcc5a5096..00000000000 --- a/api/node_modules/moment/lang/en-ca.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : canadian english (en-ca) -// author : Jonathan Abourbih : https://github.com/jonbca -(function () { - var lang = { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), - longDateFormat : { - LT : "h:mm A", - L : "YYYY-MM-DD", - LL : "D MMMM, YYYY", - LLL : "D MMMM, YYYY LT", - LLLL : "dddd, D MMMM, YYYY LT" - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" - }, - ordinal : function (number) { - var b = number % 10; - return (~~ (number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('en-ca', lang); - } -}()); diff --git a/api/node_modules/moment/lang/en-gb.js b/api/node_modules/moment/lang/en-gb.js deleted file mode 100644 index a01a7d04ce2..00000000000 --- a/api/node_modules/moment/lang/en-gb.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : great britain english (en-gb) -// author : Chris Gedrim : https://github.com/chrisgedrim -(function () { - var lang = { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), - longDateFormat : { - LT : "h:mm A", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" - }, - ordinal : function (number) { - var b = number % 10; - return (~~ (number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('en-gb', lang); - } -}()); diff --git a/api/node_modules/moment/lang/es.js b/api/node_modules/moment/lang/es.js deleted file mode 100644 index f093d1a96e3..00000000000 --- a/api/node_modules/moment/lang/es.js +++ /dev/null @@ -1,64 +0,0 @@ -// moment.js language configuration -// language : spanish (es) -// author : Julio Napurí : https://github.com/julionc -(function () { - var lang = { - months : "Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre".split("_"), - monthsShort : "Ene._Feb._Mar._Abr._May._Jun._Jul._Ago._Sep._Oct._Nov._Dic.".split("_"), - weekdays : "Domingo_Lunes_Martes_Miércoles_Jueves_Viernes_Sábado".split("_"), - weekdaysShort : "Dom._Lun._Mar._Mié._Jue._Vie._Sáb.".split("_"), - weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : "en %s", - past : "hace %s", - s : "unos segundos", - m : "un minuto", - mm : "%d minutos", - h : "una hora", - hh : "%d horas", - d : "un día", - dd : "%d días", - M : "un mes", - MM : "%d meses", - y : "un año", - yy : "%d años" - }, - ordinal : function (number) { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('es', lang); - } -}()); diff --git a/api/node_modules/moment/lang/et.js b/api/node_modules/moment/lang/et.js deleted file mode 100644 index 5fb560274e1..00000000000 --- a/api/node_modules/moment/lang/et.js +++ /dev/null @@ -1,67 +0,0 @@ -// moment.js language configuration -// language : estonian (et) -// author : Henry Kehlmann : https://github.com/madhenry -(function () { - - function translate(number, withoutSuffix, key, isFuture) { - var num = number; - - switch (key) { - case 's': - return (isFuture || withoutSuffix) ? 'paari sekundi' : 'paar sekundit'; - default: - } - - return ''; - } - - var lang = { - months : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"), - monthsShort : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"), - weekdays : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"), - weekdaysShort : "P_E_T_K_N_R_L".split("_"), - weekdaysMin : "P_E_T_K_N_R_L".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" - }, - calendar : { - sameDay : '[Täna,] LT', - nextDay : '[Homme,] LT', - nextWeek : '[Järgmine] dddd LT', - lastDay : '[Eile,] LT', - lastWeek : '[Eelmine] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s pärast", - past : "%s tagasi", - s : translate, - m : "minut", - mm : "%d minutit", - h : "tund", - hh : "%d tundi", - d : "päev", - dd : "%d päeva", - M : "kuu", - MM : "%d kuud", - y : "aasta", - yy : "%d aastat" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('et', lang); - } -}()); diff --git a/api/node_modules/moment/lang/eu.js b/api/node_modules/moment/lang/eu.js deleted file mode 100644 index 79e224e4238..00000000000 --- a/api/node_modules/moment/lang/eu.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : euskara (eu) -// author : Eneko Illarramendi : https://github.com/eillarra -(function () { - var lang = { - months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"), - monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"), - weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"), - weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"), - weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "YYYYko MMMMren D[a]", - LLL : "YYYYko MMMMren D[a] LT", - LLLL : "dddd, YYYYko MMMMren D[a] LT" - }, - calendar : { - sameDay : '[gaur] LT[etan]', - nextDay : '[bihar] LT[etan]', - nextWeek : 'dddd LT[etan]', - lastDay : '[atzo] LT[etan]', - lastWeek : '[aurreko] dddd LT[etan]', - sameElse : 'L' - }, - relativeTime : { - future : "%s barru", - past : "duela %s", - s : "segundo batzuk", - m : "minutu bat", - mm : "%d minutu", - h : "ordu bat", - hh : "%d ordu", - d : "egun bat", - dd : "%d egun", - M : "hilabete bat", - MM : "%d hilabete", - y : "urte bat", - yy : "%d urte" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('eu', lang); - } -}()); diff --git a/api/node_modules/moment/lang/fi.js b/api/node_modules/moment/lang/fi.js deleted file mode 100644 index 826259b3f28..00000000000 --- a/api/node_modules/moment/lang/fi.js +++ /dev/null @@ -1,98 +0,0 @@ -// moment.js language configuration -// language : finnish (fi) -// author : Tarmo Aidantausta : https://github.com/bleadof -(function () { - var numbers_past = ['nolla', 'yksi', 'kaksi', 'kolme', 'neljä', 'viisi', - 'kuusi', 'seitsemän', 'kahdeksan', 'yhdeksän']; - var numbers_future = ['nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', - 'kuuden', numbers_past[7], numbers_past[8], numbers_past[9]]; - - function translate(number, withoutSuffix, key, isFuture) { - var result = ""; - switch (key) { - case 's': - return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; - case 'm': - return isFuture ? 'minuutin' : 'minuutti'; - case 'mm': - result = isFuture ? 'minuutin' : 'minuuttia'; - break; - case 'h': - return isFuture ? 'tunnin' : 'tunti'; - case 'hh': - result = isFuture ? 'tunnin' : 'tuntia'; - break; - case 'd': - return isFuture ? 'päivän' : 'päivä'; - case 'dd': - result = isFuture ? 'päivän' : 'päivää'; - break; - case 'M': - return isFuture ? 'kuukauden' : 'kuukausi'; - case 'MM': - result = isFuture ? 'kuukauden' : 'kuukautta'; - break; - case 'y': - return isFuture ? 'vuoden' : 'vuosi'; - case 'yy': - result = isFuture ? 'vuoden' : 'vuotta'; - break; - } - result = verbal_number(number, isFuture) + " " + result; - return result; - } - - function verbal_number(number, isFuture) { - return number < 10 ? (isFuture ? numbers_future[number] : numbers_past[number]) : number; - } - - var lang = { - months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"), - monthsShort : "tam_hel_maa_huh_tou_kes_hei_elo_syy_lok_mar_jou".split("_"), - weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"), - weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"), - weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"), - longDateFormat : { - LT : "HH.mm", - L : "DD.MM.YYYY", - LL : "Do MMMMt\\a YYYY", - LLL : "Do MMMMt\\a YYYY, klo LT", - LLLL : "dddd, Do MMMMt\\a YYYY, klo LT" - }, - calendar : { - sameDay : '[tänään] [klo] LT', - nextDay : '[huomenna] [klo] LT', - nextWeek : 'dddd [klo] LT', - lastDay : '[eilen] [klo] LT', - lastWeek : '[viime] dddd[na] [klo] LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s päästä", - past : "%s sitten", - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : function (number) { - return "."; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('fi', lang); - } -}()); diff --git a/api/node_modules/moment/lang/fr-ca.js b/api/node_modules/moment/lang/fr-ca.js deleted file mode 100644 index 887be220dc4..00000000000 --- a/api/node_modules/moment/lang/fr-ca.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : canadian french (fr-ca) -// author : Jonathan Abourbih : https://github.com/jonbca -(function () { - var lang = { - months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), - monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), - weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"), - weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"), - weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: "[Aujourd'hui à] LT", - nextDay: '[Demain à] LT', - nextWeek: 'dddd [à] LT', - lastDay: '[Hier à] LT', - lastWeek: 'dddd [dernier à] LT', - sameElse: 'L' - }, - relativeTime : { - future : "dans %s", - past : "il y a %s", - s : "quelques secondes", - m : "une minute", - mm : "%d minutes", - h : "une heure", - hh : "%d heures", - d : "un jour", - dd : "%d jours", - M : "un mois", - MM : "%d mois", - y : "une année", - yy : "%d années" - }, - ordinal : function (number) { - return number === 1 ? 'er' : 'ème'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('fr-ca', lang); - } -}()); diff --git a/api/node_modules/moment/lang/fr.js b/api/node_modules/moment/lang/fr.js deleted file mode 100644 index 819f48cd251..00000000000 --- a/api/node_modules/moment/lang/fr.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : french (fr) -// author : John Fischer : https://github.com/jfroffice -(function () { - var lang = { - months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"), - monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"), - weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"), - weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"), - weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: "[Aujourd'hui à] LT", - nextDay: '[Demain à] LT', - nextWeek: 'dddd [à] LT', - lastDay: '[Hier à] LT', - lastWeek: 'dddd [dernier à] LT', - sameElse: 'L' - }, - relativeTime : { - future : "dans %s", - past : "il y a %s", - s : "quelques secondes", - m : "une minute", - mm : "%d minutes", - h : "une heure", - hh : "%d heures", - d : "un jour", - dd : "%d jours", - M : "un mois", - MM : "%d mois", - y : "une année", - yy : "%d années" - }, - ordinal : function (number) { - return number === 1 ? 'er' : 'ème'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('fr', lang); - } -}()); diff --git a/api/node_modules/moment/lang/gl.js b/api/node_modules/moment/lang/gl.js deleted file mode 100644 index 51c8569fb86..00000000000 --- a/api/node_modules/moment/lang/gl.js +++ /dev/null @@ -1,64 +0,0 @@ -// moment.js language configuration -// language : galician (gl) -// author : Juan G. Hurtado : https://github.com/juanghurtado -(function () { - var lang = { - months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Octubro_Novembro_Decembro".split("_"), - monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"), - weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"), - weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"), - weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay : function () { - return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - nextDay : function () { - return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - nextWeek : function () { - return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - lastDay : function () { - return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; - }, - lastWeek : function () { - return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : "en %s", - past : "fai %s", - s : "uns segundo", - m : "un minuto", - mm : "%d minutos", - h : "unha hora", - hh : "%d horas", - d : "un día", - dd : "%d días", - M : "un mes", - MM : "%d meses", - y : "un ano", - yy : "%d anos" - }, - ordinal : function (number) { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('gl', lang); - } -}()); diff --git a/api/node_modules/moment/lang/hu.js b/api/node_modules/moment/lang/hu.js deleted file mode 100644 index 4745cbb5986..00000000000 --- a/api/node_modules/moment/lang/hu.js +++ /dev/null @@ -1,108 +0,0 @@ -// moment.js language configuration -// language : hungarian (hu) -// author : Adam Brunner : https://github.com/adambrunner -(function() -{ - function translate(number, withoutSuffix, key, isFuture) { - var num = number; - - switch (key) { - case 's': - return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; - - case 'm': - num = 'egy'; - case 'mm': - return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); - break; - - case 'h': - num = 'egy'; - case 'hh': - return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); - - case 'd': - num = 'egy'; - case 'dd': - return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); - - case 'M': - num = 'egy'; - case 'MM': - return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - - case 'y': - num = 'egy'; - case 'yy': - return num + (isFuture || withoutSuffix ? ' év' : ' éve'); - - default: - } - - return ''; - } - - function week(isFuture) { - var ending = ''; - switch (this.day()) { - case 0: ending = 'vasárnap'; break; - case 1: ending = 'hétfÅ‘n'; break; - case 2: ending = 'kedden'; break; - case 3: ending = 'szerdán'; break; - case 4: ending = 'csütörtökön'; break; - case 5: ending = 'pénteken'; break; - case 6: ending = 'szombaton'; break; - } - return (isFuture ? '' : 'múlt ')+'['+ending+'] LT[-kor]'; - } - - var lang = { - months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"), - monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"), - weekdays : "vasárnap_hétfÅ‘_kedd_szerda_csütörtök_péntek_szombat".split("_"), - weekdaysShort : "v_h_k_sze_cs_p_szo".split("_"), - longDateFormat : { - LT : "H:mm", - L : "YYYY.MM.DD.", - LL : "YYYY. MMMM D.", - LLL : "YYYY. MMMM D., LT", - LLLL : "YYYY. MMMM D., dddd LT" - }, - calendar : { - sameDay : '[ma] LT[-kor]', - nextDay : '[holnap] LT[-kor]', - nextWeek : function(){return week.call(this, true);}, - lastDay : '[tegnap] LT[-kor]', - lastWeek : function(){return week.call(this, false);}, - sameElse : 'L' - }, - relativeTime : { - future : "%s múlva", - past : "%s", - s : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - ordinal : function(number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('hu', lang); - } -}()); diff --git a/api/node_modules/moment/lang/is.js b/api/node_modules/moment/lang/is.js deleted file mode 100644 index c845665ad58..00000000000 --- a/api/node_modules/moment/lang/is.js +++ /dev/null @@ -1,132 +0,0 @@ -// moment.js language configuration -// language : icelandic (is) -// author : Hinrik Örn Sigurðsson : https://github.com/hinrik -(function () { - var plural = function (n) { - if (n % 100 == 11) { - return true; - } else if (n % 10 == 1) { - return false; - } else { - return true; - } - }, - - translate = function (number, withoutSuffix, key, isFuture) { - var result = number + " "; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; - case 'm': - return withoutSuffix ? 'mínúta' : 'mínútu'; - case 'mm': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); - } else if (withoutSuffix) { - return result + 'mínúta'; - } else { - return result + 'mínútu'; - } - case 'hh': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); - } else { - return result + 'klukkustund'; - } - case 'd': - if (withoutSuffix) { - return 'dagur' - } else { - return isFuture ? 'dag' : 'degi'; - } - case 'dd': - if (plural(number)) { - if (withoutSuffix) { - return result + 'dagar' - } else { - return result + (isFuture ? 'daga' : 'dögum'); - } - } else if (withoutSuffix) { - return result + 'dagur' - } else { - return result + (isFuture ? 'dag' : 'degi'); - } - case 'M': - if (withoutSuffix) { - return 'mánuður' - } else { - return isFuture ? 'mánuð' : 'mánuði'; - } - case 'MM': - if (plural(number)) { - if (withoutSuffix) { - return result + 'mánuðir' - } else { - return result + (isFuture ? 'mánuði' : 'mánuðum'); - } - } else if (withoutSuffix) { - return result + 'mánuður'; - } else { - return result + (isFuture ? 'mánuð' : 'mánuði'); - } - case 'y': - return withoutSuffix || isFuture ? 'ár' : 'ári'; - case 'yy': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); - } else { - return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); - } - } - }, - - lang = { - months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"), - monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"), - weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"), - weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"), - weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY kl. LT", - LLLL : "dddd, D. MMMM YYYY kl. LT" - }, - calendar : { - sameDay : '[í dag kl.] LT', - nextDay : '[á morgun kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[í gær kl.] LT', - lastWeek : '[síðasta] dddd [kl.] LT', - sameElse : 'L' - }, - relativeTime : { - future : "eftir %s", - past : "fyrir %s síðan", - s : translate, - m : translate, - mm : translate, - h : "klukkustund", - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate, - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('is', lang); - } -}()); diff --git a/api/node_modules/moment/lang/it.js b/api/node_modules/moment/lang/it.js deleted file mode 100644 index 6d3b7381e82..00000000000 --- a/api/node_modules/moment/lang/it.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : italian (it) -// author : Lorenzo : https://github.com/aliem -(function () { - var lang = { - months : "Gennaio_Febbraio_Marzo_Aprile_Maggio_Giugno_Luglio_Agosto_Settembre_Ottobre_Novembre_Dicembre".split("_"), - monthsShort : "Gen_Feb_Mar_Apr_Mag_Giu_Lug_Ago_Set_Ott_Nov_Dic".split("_"), - weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"), - weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"), - weekdaysMin : "D_L_Ma_Me_G_V_S".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" - }, - calendar : { - sameDay: '[Oggi alle] LT', - nextDay: '[Domani alle] LT', - nextWeek: 'dddd [alle] LT', - lastDay: '[Ieri alle] LT', - lastWeek: '[lo scorso] dddd [alle] LT', - sameElse: 'L' - }, - relativeTime : { - future : "in %s", - past : "%s fa", - s : "secondi", - m : "un minuto", - mm : "%d minuti", - h : "un'ora", - hh : "%d ore", - d : "un giorno", - dd : "%d giorni", - M : "un mese", - MM : "%d mesi", - y : "un anno", - yy : "%d anni" - }, - ordinal: function () { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('it', lang); - } -}()); diff --git a/api/node_modules/moment/lang/ja.js b/api/node_modules/moment/lang/ja.js deleted file mode 100644 index 0a830276889..00000000000 --- a/api/node_modules/moment/lang/ja.js +++ /dev/null @@ -1,61 +0,0 @@ -// moment.js language configuration -// language : japanese (ja) -// author : LI Long : https://github.com/baryon -(function () { - var lang = { - months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "日曜日_月曜日_ç«æ›œæ—¥_水曜日_木曜日_金曜日_土曜日".split("_"), - weekdaysShort : "æ—¥_月_ç«_æ°´_木_金_土".split("_"), - weekdaysMin : "æ—¥_月_ç«_æ°´_木_金_土".split("_"), - longDateFormat : { - LT : "Ah時m分", - L : "YYYY/MM/DD", - LL : "YYYYå¹´M月Dæ—¥", - LLL : "YYYYå¹´M月Dæ—¥LT", - LLLL : "YYYYå¹´M月Dæ—¥LT dddd" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return "åˆå‰"; - } else { - return "åˆå¾Œ"; - } - }, - calendar : { - sameDay : '[今日] LT', - nextDay : '[明日] LT', - nextWeek : '[æ¥é€±]dddd LT', - lastDay : '[昨日] LT', - lastWeek : '[å‰é€±]dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s後", - past : "%så‰", - s : "数秒", - m : "1分", - mm : "%d分", - h : "1時間", - hh : "%d時間", - d : "1æ—¥", - dd : "%dæ—¥", - M : "1ヶ月", - MM : "%dヶ月", - y : "1å¹´", - yy : "%då¹´" - }, - ordinal : function (number) { - return ''; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('ja', lang); - } -}()); diff --git a/api/node_modules/moment/lang/jp.js b/api/node_modules/moment/lang/jp.js deleted file mode 100644 index 53a85e547c6..00000000000 --- a/api/node_modules/moment/lang/jp.js +++ /dev/null @@ -1,64 +0,0 @@ -// moment.js language configuration -// language : japanese (jp) -// author : LI Long : https://github.com/baryon - -// This language config was incorrectly named 'jp' instead of 'ja'. -// In version 2.0.0, this will be deprecated and you should use 'ja' instead. -(function () { - var lang = { - months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "日曜日_月曜日_ç«æ›œæ—¥_水曜日_木曜日_金曜日_土曜日".split("_"), - weekdaysShort : "æ—¥_月_ç«_æ°´_木_金_土".split("_"), - weekdaysMin : "æ—¥_月_ç«_æ°´_木_金_土".split("_"), - longDateFormat : { - LT : "Ah時m分", - L : "YYYY/MM/DD", - LL : "YYYYå¹´M月Dæ—¥", - LLL : "YYYYå¹´M月Dæ—¥LT", - LLLL : "YYYYå¹´M月Dæ—¥LT dddd" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return "åˆå‰"; - } else { - return "åˆå¾Œ"; - } - }, - calendar : { - sameDay : '[今日] LT', - nextDay : '[明日] LT', - nextWeek : '[æ¥é€±]dddd LT', - lastDay : '[昨日] LT', - lastWeek : '[å‰é€±]dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s後", - past : "%så‰", - s : "数秒", - m : "1分", - mm : "%d分", - h : "1時間", - hh : "%d時間", - d : "1æ—¥", - dd : "%dæ—¥", - M : "1ヶ月", - MM : "%dヶ月", - y : "1å¹´", - yy : "%då¹´" - }, - ordinal : function (number) { - return ''; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('jp', lang); - } -}()); diff --git a/api/node_modules/moment/lang/ko.js b/api/node_modules/moment/lang/ko.js deleted file mode 100644 index 74fcefe6ca9..00000000000 --- a/api/node_modules/moment/lang/ko.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : korean (ko) -// author : Kyungwook, Park : https://github.com/kyungw00k -(function () { - var lang = { - months : "1ì›”_2ì›”_3ì›”_4ì›”_5ì›”_6ì›”_7ì›”_8ì›”_9ì›”_10ì›”_11ì›”_12ì›”".split("_"), - monthsShort : "1ì›”_2ì›”_3ì›”_4ì›”_5ì›”_6ì›”_7ì›”_8ì›”_9ì›”_10ì›”_11ì›”_12ì›”".split("_"), - weekdays : "ì¼ìš”ì¼_월요ì¼_화요ì¼_수요ì¼_목요ì¼_금요ì¼_토요ì¼".split("_"), - weekdaysShort : "ì¼_ì›”_í™”_수_목_금_토".split("_"), - weekdaysMin : "ì¼_ì›”_í™”_수_목_금_토".split("_"), - longDateFormat : { - LT : "A hì‹œ mm분", - L : "YYYY.MM.DD", - LL : "YYYYë…„ MMMM Dì¼", - LLL : "YYYYë…„ MMMM Dì¼ LT", - LLLL : "YYYYë…„ MMMM Dì¼ dddd LT" - }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; - }, - calendar : { - sameDay : '오늘 LT', - nextDay : 'ë‚´ì¼ LT', - nextWeek : 'dddd LT', - lastDay : 'ì–´ì œ LT', - lastWeek : '지난주 dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s 후", - past : "%s ì „", - s : "몇초", - ss : "%dì´ˆ", - m : "ì¼ë¶„", - mm : "%d분", - h : "한시간", - hh : "%d시간", - d : "하루", - dd : "%dì¼", - M : "한달", - MM : "%d달", - y : "ì¼ë…„", - yy : "%dë…„" - }, - ordinal : function (number) { - return 'ì¼'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('ko', lang); - } -}()); diff --git a/api/node_modules/moment/lang/kr.js b/api/node_modules/moment/lang/kr.js deleted file mode 100644 index 5b932e2c7c9..00000000000 --- a/api/node_modules/moment/lang/kr.js +++ /dev/null @@ -1,61 +0,0 @@ -// moment.js language configuration -// language : korean (kr) -// author : Kyungwook, Park : https://github.com/kyungw00k - -// This language config was incorrectly named 'kr' instead of 'ko'. -// In version 2.0.0, this will be deprecated and you should use 'ko' instead. -(function () { - var lang = { - months : "1ì›”_2ì›”_3ì›”_4ì›”_5ì›”_6ì›”_7ì›”_8ì›”_9ì›”_10ì›”_11ì›”_12ì›”".split("_"), - monthsShort : "1ì›”_2ì›”_3ì›”_4ì›”_5ì›”_6ì›”_7ì›”_8ì›”_9ì›”_10ì›”_11ì›”_12ì›”".split("_"), - weekdays : "ì¼ìš”ì¼_월요ì¼_화요ì¼_수요ì¼_목요ì¼_금요ì¼_토요ì¼".split("_"), - weekdaysShort : "ì¼_ì›”_í™”_수_목_금_토".split("_"), - weekdaysMin : "ì¼_ì›”_í™”_수_목_금_토".split("_"), - longDateFormat : { - LT : "A hì‹œ mm분", - L : "YYYY.MM.DD", - LL : "YYYYë…„ MMMM Dì¼", - LLL : "YYYYë…„ MMMM Dì¼ LT", - LLLL : "YYYYë…„ MMMM Dì¼ dddd LT" - }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; - }, - calendar : { - sameDay : '오늘 LT', - nextDay : 'ë‚´ì¼ LT', - nextWeek : 'dddd LT', - lastDay : 'ì–´ì œ LT', - lastWeek : '지난주 dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s 후", - past : "%s ì „", - s : "몇초", - ss : "%dì´ˆ", - m : "ì¼ë¶„", - mm : "%d분", - h : "한시간", - hh : "%d시간", - d : "하루", - dd : "%dì¼", - M : "한달", - MM : "%d달", - y : "ì¼ë…„", - yy : "%dë…„" - }, - ordinal : function (number) { - return 'ì¼'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('kr', lang); - } -}()); diff --git a/api/node_modules/moment/lang/nb.js b/api/node_modules/moment/lang/nb.js deleted file mode 100644 index dd0a266f823..00000000000 --- a/api/node_modules/moment/lang/nb.js +++ /dev/null @@ -1,54 +0,0 @@ -// moment.js language configuration -// language : norwegian bokmÃ¥l (nb) -// author : Espen Hovlandsdal : https://github.com/rexxars -(function () { - var lang = { - months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"), - monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"), - weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"), - weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"), - weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: '[I dag klokken] LT', - nextDay: '[I morgen klokken] LT', - nextWeek: 'dddd [klokken] LT', - lastDay: '[I gÃ¥r klokken] LT', - lastWeek: '[Forrige] dddd [klokken] LT', - sameElse: 'L' - }, - relativeTime : { - future : "om %s", - past : "for %s siden", - s : "noen sekunder", - m : "ett minutt", - mm : "%d minutter", - h : "en time", - hh : "%d timer", - d : "en dag", - dd : "%d dager", - M : "en mÃ¥ned", - MM : "%d mÃ¥neder", - y : "ett Ã¥r", - yy : "%d Ã¥r" - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('nb', lang); - } -}()); diff --git a/api/node_modules/moment/lang/nl.js b/api/node_modules/moment/lang/nl.js deleted file mode 100644 index 53deafb8088..00000000000 --- a/api/node_modules/moment/lang/nl.js +++ /dev/null @@ -1,62 +0,0 @@ -// moment.js language configuration -// language : dutch (nl) -// author : Joris Röling : https://github.com/jjupiter -(function () { - var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"); - var monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"); - var lang = { - months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"), - monthsShort : function (m, format) { - if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"), - weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"), - weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD-MM-YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: '[Vandaag om] LT', - nextDay: '[Morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[Gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : "over %s", - past : "%s geleden", - s : "een paar seconden", - m : "één minuut", - mm : "%d minuten", - h : "één uur", - hh : "%d uur", - d : "één dag", - dd : "%d dagen", - M : "één maand", - MM : "%d maanden", - y : "één jaar", - yy : "%d jaar" - }, - ordinal : function (number) { - return (number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('nl', lang); - } -}()); diff --git a/api/node_modules/moment/lang/pl.js b/api/node_modules/moment/lang/pl.js deleted file mode 100644 index 5c4193c57a5..00000000000 --- a/api/node_modules/moment/lang/pl.js +++ /dev/null @@ -1,76 +0,0 @@ -// moment.js language configuration -// language : polish (pl) -// author : Rafal Hirsz : https://github.com/evoL -(function () { - var plural = function (n) { - return (n % 10 < 5) && (n % 10 > 1) && (~~(n / 10) !== 1); - }, - - translate = function (number, withoutSuffix, key) { - var result = number + " "; - switch (key) { - case 'm': - return withoutSuffix ? 'minuta' : 'minutÄ™'; - case 'mm': - return result + (plural(number) ? 'minuty' : 'minut'); - case 'h': - return withoutSuffix ? 'godzina' : 'godzinÄ™'; - case 'hh': - return result + (plural(number) ? 'godziny' : 'godzin'); - case 'MM': - return result + (plural(number) ? 'miesiÄ…ce' : 'miesiÄ™cy'); - case 'yy': - return result + (plural(number) ? 'lata' : 'lat'); - } - }, - - lang = { - months : "styczeÅ„_luty_marzec_kwiecieÅ„_maj_czerwiec_lipiec_sierpieÅ„_wrzesieÅ„_październik_listopad_grudzieÅ„".split("_"), - monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"), - weekdays : "niedziela_poniedziaÅ‚ek_wtorek_Å›roda_czwartek_piÄ…tek_sobota".split("_"), - weekdaysShort : "nie_pon_wt_Å›r_czw_pt_sb".split("_"), - weekdaysMin : "N_Pn_Wt_Åšr_Cz_Pt_So".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD-MM-YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" - }, - calendar : { - sameDay: '[DziÅ› o] LT', - nextDay: '[Jutro o] LT', - nextWeek: '[W] dddd [o] LT', - lastDay: '[Wczoraj o] LT', - lastWeek: '[W zeszÅ‚y/Å‚Ä…] dddd [o] LT', - sameElse: 'L' - }, - relativeTime : { - future : "za %s", - past : "%s temu", - s : "kilka sekund", - m : translate, - mm : translate, - h : translate, - hh : translate, - d : "1 dzieÅ„", - dd : '%d dni', - M : "miesiÄ…c", - MM : translate, - y : "rok", - yy : translate - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('pl', lang); - } -}()); diff --git a/api/node_modules/moment/lang/pt-br.js b/api/node_modules/moment/lang/pt-br.js deleted file mode 100644 index c83d4acc268..00000000000 --- a/api/node_modules/moment/lang/pt-br.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : brazilian portuguese (pt-br) -// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira -(function () { - var lang = { - months : "Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"), - monthsShort : "Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"), - weekdays : "Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"), - weekdaysShort : "Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"), - weekdaysMin : "Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D \\de MMMM \\de YYYY", - LLL : "D \\de MMMM \\de YYYY LT", - LLLL : "dddd, D \\de MMMM \\de YYYY LT" - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : "em %s", - past : "%s atrás", - s : "segundos", - m : "um minuto", - mm : "%d minutos", - h : "uma hora", - hh : "%d horas", - d : "um dia", - dd : "%d dias", - M : "um mês", - MM : "%d meses", - y : "um ano", - yy : "%d anos" - }, - ordinal : function (number) { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('pt-br', lang); - } -}()); diff --git a/api/node_modules/moment/lang/pt.js b/api/node_modules/moment/lang/pt.js deleted file mode 100644 index 55eb54063b9..00000000000 --- a/api/node_modules/moment/lang/pt.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : portuguese (pt) -// author : Jefferson : https://github.com/jalex79 -(function () { - var lang = { - months : "Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"), - monthsShort : "Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"), - weekdays : "Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"), - weekdaysShort : "Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"), - weekdaysMin : "Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD/MM/YYYY", - LL : "D \\de MMMM \\de YYYY", - LLL : "D \\de MMMM \\de YYYY LT", - LLLL : "dddd, D \\de MMMM \\de YYYY LT" - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : "em %s", - past : "%s atrás", - s : "segundos", - m : "um minuto", - mm : "%d minutos", - h : "uma hora", - hh : "%d horas", - d : "um dia", - dd : "%d dias", - M : "um mês", - MM : "%d meses", - y : "um ano", - yy : "%d anos" - }, - ordinal : function (number) { - return 'º'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('pt', lang); - } -}()); diff --git a/api/node_modules/moment/lang/ro.js b/api/node_modules/moment/lang/ro.js deleted file mode 100644 index 0856b395d49..00000000000 --- a/api/node_modules/moment/lang/ro.js +++ /dev/null @@ -1,55 +0,0 @@ -// moment.js language configuration -// language : romanian (ro) -// author : Vlad Gurdiga : https://github.com/gurdiga -// author : Valentin Agachi : https://github.com/avaly -(function () { - var lang = { - months : "Ianuarie_Februarie_Martie_Aprilie_Mai_Iunie_Iulie_August_Septembrie_Octombrie_Noiembrie_Decembrie".split("_"), - monthsShort : "Ian_Feb_Mar_Apr_Mai_Iun_Iul_Aug_Sep_Oct_Noi_Dec".split("_"), - weekdays : "Duminică_Luni_MarÅ£i_Miercuri_Joi_Vineri_Sâmbătă".split("_"), - weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"), - weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"), - longDateFormat : { - LT : "H:mm", - L : "DD/MM/YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY H:mm", - LLLL : "dddd, D MMMM YYYY H:mm" - }, - calendar : { - sameDay: "[azi la] LT", - nextDay: '[mâine la] LT', - nextWeek: 'dddd [la] LT', - lastDay: '[ieri la] LT', - lastWeek: '[fosta] dddd [la] LT', - sameElse: 'L' - }, - relativeTime : { - future : "peste %s", - past : "%s în urmă", - s : "câteva secunde", - m : "un minut", - mm : "%d minute", - h : "o oră", - hh : "%d ore", - d : "o zi", - dd : "%d zile", - M : "o lună", - MM : "%d luni", - y : "un an", - yy : "%d ani" - }, - ordinal : function (number) { - return ''; - } - }; - - // Node - if (typeof module !== 'undefined') { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('ro', lang); - } -}()); diff --git a/api/node_modules/moment/lang/ru.js b/api/node_modules/moment/lang/ru.js deleted file mode 100644 index 6ed2133a450..00000000000 --- a/api/node_modules/moment/lang/ru.js +++ /dev/null @@ -1,133 +0,0 @@ -// moment.js language configuration -// language : russian (ru) -// author : Viktorminator : https://github.com/Viktorminator -(function () { - - var pluralRules = [ - function (n) { return ((n % 10 === 1) && (n % 100 !== 11)); }, - function (n) { return ((n % 10) >= 2 && (n % 10) <= 4 && ((n % 10) % 1) === 0) && ((n % 100) < 12 || (n % 100) > 14); }, - function (n) { return ((n % 10) === 0 || ((n % 10) >= 5 && (n % 10) <= 9 && ((n % 10) % 1) === 0) || ((n % 100) >= 11 && (n % 100) <= 14 && ((n % 100) % 1) === 0)); }, - function (n) { return true; } - ], - - plural = function (word, num) { - var forms = word.split('_'), - minCount = Math.min(pluralRules.length, forms.length), - i = -1; - - while (++i < minCount) { - if (pluralRules[i](num)) { - return forms[i]; - } - } - return forms[minCount - 1]; - }, - - relativeTimeWithPlural = function (number, withoutSuffix, key) { - var format = { - 'mm': 'минута_минуты_минут_минуты', - 'hh': 'чаÑ_чаÑа_чаÑов_чаÑа', - 'dd': 'день_днÑ_дней_днÑ', - 'MM': 'меÑÑц_меÑÑца_меÑÑцев_меÑÑца', - 'yy': 'год_года_лет_года' - }; - if (key === 'm') { - return withoutSuffix ? 'минута' : 'минуту'; - } - else { - return number + ' ' + plural(format[key], +number); - } - }, - - monthsCaseReplace = function (m, format) { - var months = { - 'nominative': 'Ñнварь_февраль_март_апрель_май_июнь_июль_авгуÑÑ‚_ÑентÑбрь_октÑбрь_ноÑбрь_декабрь'.split('_'), - 'accusative': 'ÑнварÑ_февралÑ_марта_апрелÑ_маÑ_июнÑ_июлÑ_авгуÑта_ÑентÑбрÑ_октÑбрÑ_ноÑбрÑ_декабрÑ'.split('_') - }, - - nounCase = (/D[oD]? *MMMM?/).test(format) ? - 'accusative' : - 'nominative'; - - return months[nounCase][m.month()]; - }, - - weekdaysCaseReplace = function (m, format) { - var weekdays = { - 'nominative': 'воÑкреÑенье_понедельник_вторник_Ñреда_четверг_пÑтница_Ñуббота'.split('_'), - 'accusative': 'воÑкреÑенье_понедельник_вторник_Ñреду_четверг_пÑтницу_Ñубботу'.split('_') - }, - - nounCase = (/\[ ?[Вв] ?(?:прошлую|Ñледующую)? ?\] ?dddd/).test(format) ? - 'accusative' : - 'nominative'; - - return weekdays[nounCase][m.day()]; - }, - - lang = { - months : monthsCaseReplace, - monthsShort : "Ñнв_фев_мар_апр_май_июн_июл_авг_Ñен_окт_ноÑ_дек".split("_"), - weekdays : weekdaysCaseReplace, - weekdaysShort : "вÑк_пнд_втр_Ñрд_чтв_птн_Ñбт".split("_"), - weekdaysMin : "вÑ_пн_вт_ÑÑ€_чт_пт_Ñб".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY г.", - LLL : "D MMMM YYYY г., LT", - LLLL : "dddd, D MMMM YYYY г., LT" - }, - calendar : { - sameDay: '[Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð²] LT', - nextDay: '[Завтра в] LT', - lastDay: '[Вчера в] LT', - nextWeek: function () { - return this.day() === 2 ? '[Во] dddd [в] LT' : '[Ð’] dddd [в] LT'; - }, - lastWeek: function () { - switch (this.day()) { - case 0: - return '[Ð’ прошлое] dddd [в] LT'; - case 1: - case 2: - case 4: - return '[Ð’ прошлый] dddd [в] LT'; - case 3: - case 5: - case 6: - return '[Ð’ прошлую] dddd [в] LT'; - } - }, - sameElse: 'L' - }, - // It needs checking (adding) russian plurals and cases. - relativeTime : { - future : "через %s", - past : "%s назад", - s : "неÑколько Ñекунд", - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : "чаÑ", - hh : relativeTimeWithPlural, - d : "день", - dd : relativeTimeWithPlural, - M : "меÑÑц", - MM : relativeTimeWithPlural, - y : "год", - yy : relativeTimeWithPlural - }, - ordinal : function (number) { - return '.'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('ru', lang); - } -}()); diff --git a/api/node_modules/moment/lang/sv.js b/api/node_modules/moment/lang/sv.js deleted file mode 100644 index cb32ae8fdad..00000000000 --- a/api/node_modules/moment/lang/sv.js +++ /dev/null @@ -1,58 +0,0 @@ -// moment.js language configuration -// language : swedish (sv) -// author : Jens Alm : https://github.com/ulmus -(function () { - var lang = { - months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"), - monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"), - weekdays : "söndag_mÃ¥ndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"), - weekdaysShort : "sön_mÃ¥n_tis_ons_tor_fre_lör".split("_"), - weekdaysMin : "sö_mÃ¥_ti_on_to_fr_lö".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "YYYY-MM-DD", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd D MMMM YYYY LT" - }, - calendar : { - sameDay: '[Idag klockan] LT', - nextDay: '[Imorgon klockan] LT', - lastDay: '[IgÃ¥r klockan] LT', - nextWeek: 'dddd [klockan] LT', - lastWeek: '[Förra] dddd[en klockan] LT', - sameElse: 'L' - }, - relativeTime : { - future : "om %s", - past : "för %s sen", - s : "nÃ¥gra sekunder", - m : "en minut", - mm : "%d minuter", - h : "en timme", - hh : "%d timmar", - d : "en dag", - dd : "%d dagar", - M : "en mÃ¥nad", - MM : "%d mÃ¥nader", - y : "ett Ã¥r", - yy : "%d Ã¥r" - }, - ordinal : function (number) { - var b = number % 10; - return (~~ (number % 100 / 10) === 1) ? 'e' : - (b === 1) ? 'a' : - (b === 2) ? 'a' : - (b === 3) ? 'e' : 'e'; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('sv', lang); - } -}()); diff --git a/api/node_modules/moment/lang/tr.js b/api/node_modules/moment/lang/tr.js deleted file mode 100644 index 746899e73ee..00000000000 --- a/api/node_modules/moment/lang/tr.js +++ /dev/null @@ -1,88 +0,0 @@ -// moment.js language configuration -// language : turkish (tr) -// authors : Erhan Gundogan : https://github.com/erhangundogan, -// Burak YiÄŸit Kaya: https://github.com/BYK -(function () { - var suffixes = { - 1: "'inci", - 5: "'inci", - 8: "'inci", - 70: "'inci", - 80: "'inci", - - 2: "'nci", - 7: "'nci", - 20: "'nci", - 50: "'nci", - - 3: "'üncü", - 4: "'üncü", - 100: "'üncü", - - 6: "'ncı", - - 9: "'uncu", - 10: "'uncu", - 30: "'uncu", - - 60: "'ıncı", - 90: "'ıncı" - }; - var lang = { - months : "Ocak_Åžubat_Mart_Nisan_Mayıs_Haziran_Temmuz_AÄŸustos_Eylül_Ekim_Kasım_Aralık".split("_"), - monthsShort : "Oca_Åžub_Mar_Nis_May_Haz_Tem_AÄŸu_Eyl_Eki_Kas_Ara".split("_"), - weekdays : "Pazar_Pazartesi_Salı_ÇarÅŸamba_PerÅŸembe_Cuma_Cumartesi".split("_"), - weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"), - weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"), - longDateFormat : { - LT : "HH:mm", - L : "DD.MM.YYYY", - LL : "D MMMM YYYY", - LLL : "D MMMM YYYY LT", - LLLL : "dddd, D MMMM YYYY LT" - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[yarın saat] LT', - nextWeek : '[haftaya] dddd [saat] LT', - lastDay : '[dün] LT', - lastWeek : '[geçen hafta] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : "%s sonra", - past : "%s önce", - s : "birkaç saniye", - m : "bir dakika", - mm : "%d dakika", - h : "bir saat", - hh : "%d saat", - d : "bir gün", - dd : "%d gün", - M : "bir ay", - MM : "%d ay", - y : "bir yıl", - yy : "%d yıl" - }, - ordinal : function (number) { - if (number === 0) { // special case for zero - return "'ıncı"; - } - - var a = number % 10; - var b = number % 100 - a; - var c = number >= 100 ? 100 : null; - - return suffixes[a] || suffixes[b] || suffixes[c]; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('tr', lang); - } -}()); diff --git a/api/node_modules/moment/lang/zh-cn.js b/api/node_modules/moment/lang/zh-cn.js deleted file mode 100644 index 0dd1ebb2b8f..00000000000 --- a/api/node_modules/moment/lang/zh-cn.js +++ /dev/null @@ -1,67 +0,0 @@ -// moment.js language configuration -// language : chinese -// author : suupic : https://github.com/suupic -(function () { - var lang = { - months : "一月_二月_三月_四月_五月_六月_七月_八月_ä¹æœˆ_å月_å一月_å二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"), - weekdaysMin : "æ—¥_一_二_三_å››_五_å…­".split("_"), - longDateFormat : { - LT : "Ah点mm", - L : "YYYYå¹´MMMDæ—¥", - LL : "YYYYå¹´MMMDæ—¥", - LLL : "YYYYå¹´MMMDæ—¥LT", - LLLL : "YYYYå¹´MMMDæ—¥ddddLT" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 9) { - return "早上"; - } else if (hour < 11 && minute < 30) { - return "上åˆ"; - } else if (hour < 13 && minute < 30) { - return "中åˆ"; - } else if (hour < 18) { - return "下åˆ"; - } else { - return "晚上"; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - relativeTime : { - future : "%s内", - past : "%så‰", - s : "几秒", - m : "1分钟", - mm : "%d分钟", - h : "1å°æ—¶", - hh : "%då°æ—¶", - d : "1天", - dd : "%d天", - M : "1个月", - MM : "%d个月", - y : "1å¹´", - yy : "%då¹´" - }, - ordinal : function (number) { - return ''; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('zh-cn', lang); - } -}()); diff --git a/api/node_modules/moment/lang/zh-tw.js b/api/node_modules/moment/lang/zh-tw.js deleted file mode 100644 index 0938718aa21..00000000000 --- a/api/node_modules/moment/lang/zh-tw.js +++ /dev/null @@ -1,67 +0,0 @@ -// moment.js language configuration -// language : traditional chinese (zh-tw) -// author : Ben : https://github.com/ben-lin -(function () { - var lang = { - months : "一月_二月_三月_四月_五月_六月_七月_八月_ä¹æœˆ_å月_å一月_å二月".split("_"), - monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), - weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"), - weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"), - weekdaysMin : "æ—¥_一_二_三_å››_五_å…­".split("_"), - longDateFormat : { - LT : "Ah點mm", - L : "YYYYå¹´MMMDæ—¥", - LL : "YYYYå¹´MMMDæ—¥", - LLL : "YYYYå¹´MMMDæ—¥LT", - LLLL : "YYYYå¹´MMMDæ—¥ddddLT" - }, - meridiem : function (hour, minute, isLower) { - if (hour < 9) { - return "早上"; - } else if (hour < 11 && minute < 30) { - return "上åˆ"; - } else if (hour < 13 && minute < 30) { - return "中åˆ"; - } else if (hour < 18) { - return "下åˆ"; - } else { - return "晚上"; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - relativeTime : { - future : "%så…§", - past : "%så‰", - s : "幾秒", - m : "一分é˜", - mm : "%d分é˜", - h : "一å°æ™‚", - hh : "%då°æ™‚", - d : "一天", - dd : "%d天", - M : "一個月", - MM : "%d個月", - y : "一年", - yy : "%då¹´" - }, - ordinal : function (number) { - return ''; - } - }; - - // Node - if (typeof module !== 'undefined' && module.exports) { - module.exports = lang; - } - // Browser - if (typeof window !== 'undefined' && this.moment && this.moment.lang) { - this.moment.lang('zh-tw', lang); - } -}()); diff --git a/api/node_modules/moment/min/lang-all.min.js b/api/node_modules/moment/min/lang-all.min.js deleted file mode 100644 index a33e5781659..00000000000 --- a/api/node_modules/moment/min/lang-all.min.js +++ /dev/null @@ -1,5 +0,0 @@ -// moment.js language configuration -// language : bulgarian (bg) -// author : Krasen Borisov : https://github.com/kraz -(function(){var a={months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0440_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"h:mm",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u043d\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},ordinal:function(a){return"."}};typeof module!="undefined"&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("bg",a)})(),function(){var a={months:"Gener_Febrer_Mar\u00e7_Abril_Maig_Juny_Juliol_Agost_Setembre_Octubre_Novembre_Desembre".split("_"),monthsShort:"Gen._Febr._Mar._Abr._Mai._Jun._Jul._Ag._Set._Oct._Nov._Des.".split("_"),weekdays:"Diumenge_Dilluns_Dimarts_Dimecres_Dijous_Divendres_Dissabte".split("_"),weekdaysShort:"Dg._Dl._Dt._Dc._Dj._Dv._Ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[avui a "+(this.hours()!==1?"les":"la")+"] LT"},nextDay:function(){return"[dem\u00e0 a "+(this.hours()!==1?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(this.hours()!==1?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(this.hours()!==1?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(this.hours()!==1?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ca",a)}(),function(){var a={months:"\u043a\u0103\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u0103\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u00e7\u0115\u0440\u0442\u043c\u0435_\u0443\u0442\u0103_\u00e7\u0443\u0440\u043b\u0430_\u0430\u0432\u0103\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u0103\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u00e7\u0115\u0440_\u0443\u0442\u0103_\u00e7\u0443\u0440_\u0430\u0432_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u0115\u00e7\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u0103\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u0115\u00e7_\u044d\u0440\u043d_\u0448\u0103\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u00e7_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115",LLL:"YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115, LT",LLLL:"dddd, YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115, LT"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u0114\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u00c7\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u0115] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(a){var b=/Ñехет$/i.exec(a)?"\u0440\u0435\u043d":/çул$/i.exec(a)?"\u0442\u0430\u043d":"\u0440\u0430\u043d";return a+b},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u0115\u0440-\u0438\u043a \u00e7\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u0115\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u0115\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u0115\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u0115\u0440 \u0443\u0439\u0103\u0445",MM:"%d \u0443\u0439\u0103\u0445",y:"\u043f\u0115\u0440 \u00e7\u0443\u043b",yy:"%d \u00e7\u0443\u043b"},ordinal:function(a){return"-\u043c\u0115\u0448"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("cv",a)}(),function(){var a={months:"Januar_Februar_Marts_April_Maj_Juni_Juli_August_September_Oktober_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec".split("_"),weekdays:"S\u00f8ndag_Mandag_Tirsdag_Onsdag_Torsdag_Fredag_L\u00f8rdag".split("_"),weekdaysShort:"S\u00f8n_Man_Tir_Ons_Tor_Fre_L\u00f8r".split("_"),weekdaysMin:"S\u00f8_Ma_Ti_On_To_Fr_L\u00f8".split("_"),longDateFormat:{LT:"h:mm A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd D. MMMM, YYYY h:mm A"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I g\u00e5r kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"f\u00e5 sekunder",m:"minut",mm:"%d minutter",h:"time",hh:"%d timer",d:"dag",dd:"%d dage",M:"m\u00e5nede",MM:"%d m\u00e5neder",y:"\u00e5r",yy:"%d \u00e5r"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("da",a)}(),function(){var a={months:"Januar_Februar_M\u00e4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"H:mm U\\hr",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT",sameElse:"L",nextDay:"[Morgen um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gestern um] LT",lastWeek:"[letzten] dddd [um] LT"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:"einer Minute",mm:"%d Minuten",h:"einer Stunde",hh:"%d Stunden",d:"einem Tag",dd:"%d Tagen",M:"einem Monat",MM:"%d Monaten",y:"einem Jahr",yy:"%d Jahren"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("de",a)}(),function(){var a={months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"YYYY-MM-DD",LL:"D MMMM, YYYY",LLL:"D MMMM, YYYY LT",LLLL:"dddd, D MMMM, YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("en-ca",a)}(),function(){var a={months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("en-gb",a)}(),function(){var a={months:"Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre".split("_"),monthsShort:"Ene._Feb._Mar._Abr._May._Jun._Jul._Ago._Sep._Oct._Nov._Dic.".split("_"),weekdays:"Domingo_Lunes_Martes_Mi\u00e9rcoles_Jueves_Viernes_S\u00e1bado".split("_"),weekdaysShort:"Dom._Lun._Mar._Mi\u00e9._Jue._Vie._S\u00e1b.".split("_"),weekdaysMin:"Do_Lu_Ma_Mi_Ju_Vi_S\u00e1".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[ma\u00f1ana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\u00eda",dd:"%d d\u00edas",M:"un mes",MM:"%d meses",y:"un a\u00f1o",yy:"%d a\u00f1os"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("es",a)}(),function(){function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"paari sekundi":"paar sekundit";default:}return""}var b={months:"jaanuar_veebruar_m\u00e4rts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_m\u00e4rts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"p\u00fchap\u00e4ev_esmasp\u00e4ev_teisip\u00e4ev_kolmap\u00e4ev_neljap\u00e4ev_reede_laup\u00e4ev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[T\u00e4na,] LT",nextDay:"[Homme,] LT",nextWeek:"[J\u00e4rgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s p\u00e4rast",past:"%s tagasi",s:a,m:"minut",mm:"%d minutit",h:"tund",hh:"%d tundi",d:"p\u00e4ev",dd:"%d p\u00e4eva",M:"kuu",MM:"%d kuud",y:"aasta",yy:"%d aastat"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=b),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("et",b)}(),function(){var a={months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"YYYYko MMMMren D[a]",LLL:"YYYYko MMMMren D[a] LT",LLLL:"dddd, YYYYko MMMMren D[a] LT"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("eu",a)}(),function(){function c(a,b,c,e){var f="";switch(c){case"s":return e?"muutaman sekunnin":"muutama sekunti";case"m":return e?"minuutin":"minuutti";case"mm":f=e?"minuutin":"minuuttia";break;case"h":return e?"tunnin":"tunti";case"hh":f=e?"tunnin":"tuntia";break;case"d":return e?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4";case"dd":f=e?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4\u00e4";break;case"M":return e?"kuukauden":"kuukausi";case"MM":f=e?"kuukauden":"kuukautta";break;case"y":return e?"vuoden":"vuosi";case"yy":f=e?"vuoden":"vuotta"}return f=d(a,e)+" "+f,f}function d(c,d){return c<10?d?b[c]:a[c]:c}var a=["nolla","yksi","kaksi","kolme","nelj\u00e4","viisi","kuusi","seitsem\u00e4n","kahdeksan","yhdeks\u00e4n"],b=["nolla","yhden","kahden","kolmen","nelj\u00e4n","viiden","kuuden",a[7],a[8],a[9]],e={months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\u00e4kuu_hein\u00e4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tam_hel_maa_huh_tou_kes_hei_elo_syy_lok_mar_jou".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",L:"DD.MM.YYYY",LL:"Do MMMMt\\a YYYY",LLL:"Do MMMMt\\a YYYY, klo LT",LLLL:"dddd, Do MMMMt\\a YYYY, klo LT"},calendar:{sameDay:"[t\u00e4n\u00e4\u00e4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\u00e4\u00e4st\u00e4",past:"%s sitten",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=e),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fi",e)}(),function(){var a={months:"janvier_f\u00e9vrier_mars_avril_mai_juin_juillet_ao\u00fbt_septembre_octobre_novembre_d\u00e9cembre".split("_"),monthsShort:"janv._f\u00e9vr._mars_avr._mai_juin_juil._ao\u00fbt_sept._oct._nov._d\u00e9c.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui \u00e0] LT",nextDay:"[Demain \u00e0] LT",nextWeek:"dddd [\u00e0] LT",lastDay:"[Hier \u00e0] LT",lastWeek:"dddd [dernier \u00e0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"une ann\u00e9e",yy:"%d ann\u00e9es"},ordinal:function(a){return a===1?"er":"\u00e8me"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fr-ca",a)}(),function(){var a={months:"janvier_f\u00e9vrier_mars_avril_mai_juin_juillet_ao\u00fbt_septembre_octobre_novembre_d\u00e9cembre".split("_"),monthsShort:"janv._f\u00e9vr._mars_avr._mai_juin_juil._ao\u00fbt_sept._oct._nov._d\u00e9c.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui \u00e0] LT",nextDay:"[Demain \u00e0] LT",nextWeek:"dddd [\u00e0] LT",lastDay:"[Hier \u00e0] LT",lastWeek:"dddd [dernier \u00e0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"une ann\u00e9e",yy:"%d ann\u00e9es"},ordinal:function(a){return a===1?"er":"\u00e8me"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fr",a)}(),function(){var a={months:"Xaneiro_Febreiro_Marzo_Abril_Maio_Xu\u00f1o_Xullo_Agosto_Setembro_Octubro_Novembro_Decembro".split("_"),monthsShort:"Xan._Feb._Mar._Abr._Mai._Xu\u00f1._Xul._Ago._Set._Out._Nov._Dec.".split("_"),weekdays:"Domingo_Luns_Martes_M\u00e9rcores_Xoves_Venres_S\u00e1bado".split("_"),weekdaysShort:"Dom._Lun._Mar._M\u00e9r._Xov._Ven._S\u00e1b.".split("_"),weekdaysMin:"Do_Lu_Ma_M\u00e9_Xo_Ve_S\u00e1".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoxe "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},nextDay:function(){return"[ma\u00f1\u00e1 "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},nextWeek:function(){return"dddd ["+(this.hours()!==1?"\u00e1s":"a")+"] LT"},lastDay:function(){return"[onte "+(this.hours()!==1?"\u00e1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fai %s",s:"uns segundo",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\u00eda",dd:"%d d\u00edas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("gl",a)}(),function(){function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"n\u00e9h\u00e1ny m\u00e1sodperc":"n\u00e9h\u00e1ny m\u00e1sodperce";case"m":e="egy";case"mm":return e+(d||b?" perc":" perce");case"h":e="egy";case"hh":return e+(d||b?" \u00f3ra":" \u00f3r\u00e1ja");case"d":e="egy";case"dd":return e+(d||b?" nap":" napja");case"M":e="egy";case"MM":return e+(d||b?" h\u00f3nap":" h\u00f3napja");case"y":e="egy";case"yy":return e+(d||b?" \u00e9v":" \u00e9ve");default:}return""}function b(a){var b="";switch(this.day()){case 0:b="vas\u00e1rnap";break;case 1:b="h\u00e9tf\u0151n";break;case 2:b="kedden";break;case 3:b="szerd\u00e1n";break;case 4:b="cs\u00fct\u00f6rt\u00f6k\u00f6n";break;case 5:b="p\u00e9nteken";break;case 6:b="szombaton"}return(a?"":"m\u00falt ")+"["+b+"] LT[-kor]"}var c={months:"janu\u00e1r_febru\u00e1r_m\u00e1rcius_\u00e1prilis_m\u00e1jus_j\u00fanius_j\u00falius_augusztus_szeptember_okt\u00f3ber_november_december".split("_"),monthsShort:"jan_feb_m\u00e1rc_\u00e1pr_m\u00e1j_j\u00fan_j\u00fal_aug_szept_okt_nov_dec".split("_"),weekdays:"vas\u00e1rnap_h\u00e9tf\u0151_kedd_szerda_cs\u00fct\u00f6rt\u00f6k_p\u00e9ntek_szombat".split("_"),weekdaysShort:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return b.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return b.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\u00falva",past:"%s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("hu",c)}(),function(){var a=function(a){return a%100==11?!0:a%10==1?!1:!0},b=function(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"nokkrar sek\u00fandur":"nokkrum sek\u00fandum";case"m":return c?"m\u00edn\u00fata":"m\u00edn\u00fatu";case"mm":return a(b)?f+(c||e?"m\u00edn\u00fatur":"m\u00edn\u00fatum"):c?f+"m\u00edn\u00fata":f+"m\u00edn\u00fatu";case"hh":return a(b)?f+(c||e?"klukkustundir":"klukkustundum"):f+"klukkustund";case"d":return c?"dagur":e?"dag":"degi";case"dd":return a(b)?c?f+"dagar":f+(e?"daga":"d\u00f6gum"):c?f+"dagur":f+(e?"dag":"degi");case"M":return c?"m\u00e1nu\u00f0ur":e?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i";case"MM":return a(b)?c?f+"m\u00e1nu\u00f0ir":f+(e?"m\u00e1nu\u00f0i":"m\u00e1nu\u00f0um"):c?f+"m\u00e1nu\u00f0ur":f+(e?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i");case"y":return c||e?"\u00e1r":"\u00e1ri";case"yy":return a(b)?f+(c||e?"\u00e1r":"\u00e1rum"):f+(c||e?"\u00e1r":"\u00e1ri")}},c={months:"jan\u00faar_febr\u00faar_mars_apr\u00edl_ma\u00ed_j\u00fan\u00ed_j\u00fal\u00ed_\u00e1g\u00fast_september_okt\u00f3ber_n\u00f3vember_desember".split("_"),monthsShort:"jan_feb_mar_apr_ma\u00ed_j\u00fan_j\u00fal_\u00e1g\u00fa_sep_okt_n\u00f3v_des".split("_"),weekdays:"sunnudagur_m\u00e1nudagur_\u00feri\u00f0judagur_mi\u00f0vikudagur_fimmtudagur_f\u00f6studagur_laugardagur".split("_"),weekdaysShort:"sun_m\u00e1n_\u00feri_mi\u00f0_fim_f\u00f6s_lau".split("_"),weekdaysMin:"Su_M\u00e1_\u00der_Mi_Fi_F\u00f6_La".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY kl. LT",LLLL:"dddd, D. MMMM YYYY kl. LT"},calendar:{sameDay:"[\u00ed dag kl.] LT",nextDay:"[\u00e1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\u00ed g\u00e6r kl.] LT",lastWeek:"[s\u00ed\u00f0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\u00ed\u00f0an",s:b,m:b,mm:b,h:"klukkustund",hh:b,d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("is",c)}(),function(){var a={months:"Gennaio_Febbraio_Marzo_Aprile_Maggio_Giugno_Luglio_Agosto_Settembre_Ottobre_Novembre_Dicembre".split("_"),monthsShort:"Gen_Feb_Mar_Apr_Mag_Giu_Lug_Ago_Set_Ott_Nov_Dic".split("_"),weekdays:"Domenica_Luned\u00ec_Marted\u00ec_Mercoled\u00ec_Gioved\u00ec_Venerd\u00ec_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"D_L_Ma_Me_G_V_S".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:"[lo scorso] dddd [alle] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s fa",s:"secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinal:function(){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("it",a)}(),function(){var a={months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"Ah\u6642m\u5206",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5LT",LLLL:"YYYY\u5e74M\u6708D\u65e5LT dddd"},meridiem:function(a,b,c){return a<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ja",a)}(),function(){var a={months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"Ah\u6642m\u5206",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5LT",LLLL:"YYYY\u5e74M\u6708D\u65e5LT dddd"},meridiem:function(a,b,c){return a<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("jp",a)}(),function(){var a={months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h\uc2dc mm\ubd84",L:"YYYY.MM.DD",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c LT",LLLL:"YYYY\ub144 MMMM D\uc77c dddd LT"},meridiem:function(a,b,c){return a<12?"\uc624\uc804":"\uc624\ud6c4"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87\ucd08",ss:"%d\ucd08",m:"\uc77c\ubd84",mm:"%d\ubd84",h:"\ud55c\uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c\ub2ec",MM:"%d\ub2ec",y:"\uc77c\ub144",yy:"%d\ub144"},ordinal:function(a){return"\uc77c"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ko",a)}(),function(){var a={months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h\uc2dc mm\ubd84",L:"YYYY.MM.DD",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c LT",LLLL:"YYYY\ub144 MMMM D\uc77c dddd LT"},meridiem:function(a,b,c){return a<12?"\uc624\uc804":"\uc624\ud6c4"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87\ucd08",ss:"%d\ucd08",m:"\uc77c\ubd84",mm:"%d\ubd84",h:"\ud55c\uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c\ub2ec",MM:"%d\ub2ec",y:"\uc77c\ub144",yy:"%d\ub144"},ordinal:function(a){return"\uc77c"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("kr",a)}(),function(){var a={months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"s\u00f8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\u00f8rdag".split("_"),weekdaysShort:"s\u00f8n_man_tir_ons_tor_fre_l\u00f8r".split("_"),weekdaysMin:"s\u00f8_ma_ti_on_to_fr_l\u00f8".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[I dag klokken] LT",nextDay:"[I morgen klokken] LT",nextWeek:"dddd [klokken] LT",lastDay:"[I g\u00e5r klokken] LT",lastWeek:"[Forrige] dddd [klokken] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"for %s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en m\u00e5ned",MM:"%d m\u00e5neder",y:"ett \u00e5r",yy:"%d \u00e5r"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("nb",a)}(),function(){var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),b="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),c={months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(c,d){return/-MMM-/.test(d)?b[c.month()]:a[c.month()]},weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Vandaag om] LT",nextDay:"[Morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"\u00e9\u00e9n minuut",mm:"%d minuten",h:"\u00e9\u00e9n uur",hh:"%d uur",d:"\u00e9\u00e9n dag" -,dd:"%d dagen",M:"\u00e9\u00e9n maand",MM:"%d maanden",y:"\u00e9\u00e9n jaar",yy:"%d jaar"},ordinal:function(a){return a===1||a===8||a>=20?"ste":"de"}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("nl",c)}(),function(){var a=function(a){return a%10<5&&a%10>1&&~~(a/10)!==1},b=function(b,c,d){var e=b+" ";switch(d){case"m":return c?"minuta":"minut\u0119";case"mm":return e+(a(b)?"minuty":"minut");case"h":return c?"godzina":"godzin\u0119";case"hh":return e+(a(b)?"godziny":"godzin");case"MM":return e+(a(b)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return e+(a(b)?"lata":"lat")}},c={months:"stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"nie_pon_wt_\u015br_czw_pt_sb".split("_"),weekdaysMin:"N_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:"[W zesz\u0142y/\u0142\u0105] dddd [o] LT",sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:b,mm:b,h:b,hh:b,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:b,y:"rok",yy:b},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pl",c)}(),function(){var a={months:"Janeiro_Fevereiro_Mar\u00e7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\u00e7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\u00e1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\u00e1b".split("_"),weekdaysMin:"Dom_2\u00aa_3\u00aa_4\u00aa_5\u00aa_6\u00aa_S\u00e1b".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D \\de MMMM \\de YYYY",LLL:"D \\de MMMM \\de YYYY LT",LLLL:"dddd, D \\de MMMM \\de YYYY LT"},calendar:{sameDay:"[Hoje \u00e0s] LT",nextDay:"[Amanh\u00e3 \u00e0s] LT",nextWeek:"dddd [\u00e0s] LT",lastDay:"[Ontem \u00e0s] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[\u00daltimo] dddd [\u00e0s] LT":"[\u00daltima] dddd [\u00e0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atr\u00e1s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\u00eas",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pt-br",a)}(),function(){var a={months:"Janeiro_Fevereiro_Mar\u00e7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\u00e7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\u00e1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\u00e1b".split("_"),weekdaysMin:"Dom_2\u00aa_3\u00aa_4\u00aa_5\u00aa_6\u00aa_S\u00e1b".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D \\de MMMM \\de YYYY",LLL:"D \\de MMMM \\de YYYY LT",LLLL:"dddd, D \\de MMMM \\de YYYY LT"},calendar:{sameDay:"[Hoje \u00e0s] LT",nextDay:"[Amanh\u00e3 \u00e0s] LT",nextWeek:"dddd [\u00e0s] LT",lastDay:"[Ontem \u00e0s] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[\u00daltimo] dddd [\u00e0s] LT":"[\u00daltima] dddd [\u00e0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atr\u00e1s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\u00eas",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pt",a)}(),function(){var a={months:"Ianuarie_Februarie_Martie_Aprilie_Mai_Iunie_Iulie_August_Septembrie_Octombrie_Noiembrie_Decembrie".split("_"),monthsShort:"Ian_Feb_Mar_Apr_Mai_Iun_Iul_Aug_Sep_Oct_Noi_Dec".split("_"),weekdays:"Duminic\u0103_Luni_Mar\u0163i_Miercuri_Joi_Vineri_S\u00e2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\u00e2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\u00e2".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\u00e2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \u00een urm\u0103",s:"c\u00e2teva secunde",m:"un minut",mm:"%d minute",h:"o or\u0103",hh:"%d ore",d:"o zi",dd:"%d zile",M:"o lun\u0103",MM:"%d luni",y:"un an",yy:"%d ani"},ordinal:function(a){return""}};typeof module!="undefined"&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ro",a)}(),function(){var a=[function(a){return a%10===1&&a%100!==11},function(a){return a%10>=2&&a%10<=4&&a%10%1===0&&(a%100<12||a%100>14)},function(a){return a%10===0||a%10>=5&&a%10<=9&&a%10%1===0||a%100>=11&&a%100<=14&&a%100%1===0},function(a){return!0}],b=function(b,c){var d=b.split("_"),e=Math.min(a.length,d.length),f=-1;while(++f=100?100:null;return a[c]||a[d]||a[e]}};typeof module!="undefined"&&module.exports&&(module.exports=b),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("tr",b)}(),function(){var a={months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"Ah\u70b9mm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,b,c){return a<9?"\u65e9\u4e0a":a<11&&b<30?"\u4e0a\u5348":a<13&&b<30?"\u4e2d\u5348":a<18?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",m:"1\u5206\u949f",mm:"%d\u5206\u949f",h:"1\u5c0f\u65f6",hh:"%d\u5c0f\u65f6",d:"1\u5929",dd:"%d\u5929",M:"1\u4e2a\u6708",MM:"%d\u4e2a\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("zh-cn",a)}(),function(){var a={months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"Ah\u9edemm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,b,c){return a<9?"\u65e9\u4e0a":a<11&&b<30?"\u4e0a\u5348":a<13&&b<30?"\u4e2d\u5348":a<18?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",m:"\u4e00\u5206\u9418",mm:"%d\u5206\u9418",h:"\u4e00\u5c0f\u6642",hh:"%d\u5c0f\u6642",d:"\u4e00\u5929",dd:"%d\u5929",M:"\u4e00\u500b\u6708",MM:"%d\u500b\u6708",y:"\u4e00\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("zh-tw",a)}(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/bg.js b/api/node_modules/moment/min/lang/bg.js deleted file mode 100644 index a5223d410e2..00000000000 --- a/api/node_modules/moment/min/lang/bg.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : bulgarian (bg) -// author : Krasen Borisov : https://github.com/kraz -(function(){var a={months:"\u044f\u043d\u0443\u0430\u0440\u0438_\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438_\u043c\u0430\u0440\u0442_\u0430\u043f\u0440\u0438\u043b_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433\u0443\u0441\u0442_\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438_\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438_\u043d\u043e\u0435\u043c\u0432\u0440\u0438_\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438".split("_"),monthsShort:"\u044f\u043d\u0440_\u0444\u0435\u0432_\u043c\u0430\u0440_\u0430\u043f\u0440_\u043c\u0430\u0439_\u044e\u043d\u0438_\u044e\u043b\u0438_\u0430\u0432\u0433_\u0441\u0435\u043f_\u043e\u043a\u0442_\u043d\u043e\u0435_\u0434\u0435\u043a".split("_"),weekdays:"\u043d\u0435\u0434\u0435\u043b\u044f_\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a_\u0432\u0442\u043e\u0440\u043d\u0438\u043a_\u0441\u0440\u044f\u0434\u0430_\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a_\u043f\u0435\u0442\u044a\u043a_\u0441\u044a\u0431\u043e\u0442\u0430".split("_"),weekdaysShort:"\u043d\u0435\u0434_\u043f\u043e\u043d_\u0432\u0442\u043e_\u0441\u0440\u044f_\u0447\u0435\u0442_\u043f\u0435\u0442_\u0441\u044a\u0431".split("_"),weekdaysMin:"\u043d\u0434_\u043f\u043d_\u0432\u0442_\u0441\u0440_\u0447\u0442_\u043f\u0442_\u0441\u0431".split("_"),longDateFormat:{LT:"h:mm",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[\u0414\u043d\u0435\u0441 \u0432] LT",nextDay:"[\u0423\u0442\u0440\u0435 \u0432] LT",nextWeek:"dddd [\u0432] LT",lastDay:"[\u0412\u0447\u0435\u0440\u0430 \u0432] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0430\u0442\u0430] dddd [\u0432] LT";case 1:case 2:case 4:case 5:return"[\u0412 \u0438\u0437\u043c\u0438\u043d\u0430\u043b\u0438\u044f] dddd [\u0432] LT"}},sameElse:"L"},relativeTime:{future:"\u0441\u043b\u0435\u0434 %s",past:"\u043f\u0440\u0435\u0434\u0438 %s",s:"\u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434\u0438",m:"\u043c\u0438\u043d\u0443\u0442\u0430",mm:"%d \u043c\u0438\u043d\u0443\u0442\u0438",h:"\u0447\u0430\u0441",hh:"%d \u0447\u0430\u0441\u0430",d:"\u0434\u0435\u043d",dd:"%d \u0434\u043d\u0438",M:"\u043c\u0435\u0441\u0435\u0446",MM:"%d \u043c\u0435\u0441\u0435\u0446\u0430",y:"\u0433\u043e\u0434\u0438\u043d\u0430",yy:"%d \u0433\u043e\u0434\u0438\u043d\u0438"},ordinal:function(a){return"."}};typeof module!="undefined"&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("bg",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/ca.js b/api/node_modules/moment/min/lang/ca.js deleted file mode 100644 index ad5906696d1..00000000000 --- a/api/node_modules/moment/min/lang/ca.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : catalan (ca) -// author : Juan G. Hurtado : https://github.com/juanghurtado -(function(){var a={months:"Gener_Febrer_Mar\u00e7_Abril_Maig_Juny_Juliol_Agost_Setembre_Octubre_Novembre_Desembre".split("_"),monthsShort:"Gen._Febr._Mar._Abr._Mai._Jun._Jul._Ag._Set._Oct._Nov._Des.".split("_"),weekdays:"Diumenge_Dilluns_Dimarts_Dimecres_Dijous_Divendres_Dissabte".split("_"),weekdaysShort:"Dg._Dl._Dt._Dc._Dj._Dv._Ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[avui a "+(this.hours()!==1?"les":"la")+"] LT"},nextDay:function(){return"[dem\u00e0 a "+(this.hours()!==1?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(this.hours()!==1?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(this.hours()!==1?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(this.hours()!==1?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ca",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/cv.js b/api/node_modules/moment/min/lang/cv.js deleted file mode 100644 index 9c72500161d..00000000000 --- a/api/node_modules/moment/min/lang/cv.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : chuvash (cv) -// author : Anatoly Mironov : https://github.com/mirontoli -(function(){var a={months:"\u043a\u0103\u0440\u043b\u0430\u0447_\u043d\u0430\u0440\u0103\u0441_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u00e7\u0115\u0440\u0442\u043c\u0435_\u0443\u0442\u0103_\u00e7\u0443\u0440\u043b\u0430_\u0430\u0432\u0103\u043d_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448\u0442\u0430\u0432".split("_"),monthsShort:"\u043a\u0103\u0440_\u043d\u0430\u0440_\u043f\u0443\u0448_\u0430\u043a\u0430_\u043c\u0430\u0439_\u00e7\u0115\u0440_\u0443\u0442\u0103_\u00e7\u0443\u0440_\u0430\u0432_\u044e\u043f\u0430_\u0447\u04f3\u043a_\u0440\u0430\u0448".split("_"),weekdays:"\u0432\u044b\u0440\u0441\u0430\u0440\u043d\u0438\u043a\u0443\u043d_\u0442\u0443\u043d\u0442\u0438\u043a\u0443\u043d_\u044b\u0442\u043b\u0430\u0440\u0438\u043a\u0443\u043d_\u044e\u043d\u043a\u0443\u043d_\u043a\u0115\u00e7\u043d\u0435\u0440\u043d\u0438\u043a\u0443\u043d_\u044d\u0440\u043d\u0435\u043a\u0443\u043d_\u0448\u0103\u043c\u0430\u0442\u043a\u0443\u043d".split("_"),weekdaysShort:"\u0432\u044b\u0440_\u0442\u0443\u043d_\u044b\u0442\u043b_\u044e\u043d_\u043a\u0115\u00e7_\u044d\u0440\u043d_\u0448\u0103\u043c".split("_"),weekdaysMin:"\u0432\u0440_\u0442\u043d_\u044b\u0442_\u044e\u043d_\u043a\u00e7_\u044d\u0440_\u0448\u043c".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115",LLL:"YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115, LT",LLLL:"dddd, YYYY \u00e7\u0443\u043b\u0445\u0438 MMMM \u0443\u0439\u0103\u0445\u0115\u043d D-\u043c\u0115\u0448\u0115, LT"},calendar:{sameDay:"[\u041f\u0430\u044f\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextDay:"[\u042b\u0440\u0430\u043d] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastDay:"[\u0114\u043d\u0435\u0440] LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",nextWeek:"[\u00c7\u0438\u0442\u0435\u0441] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",lastWeek:"[\u0418\u0440\u0442\u043d\u0115] dddd LT [\u0441\u0435\u0445\u0435\u0442\u0440\u0435]",sameElse:"L"},relativeTime:{future:function(a){var b=/Ñехет$/i.exec(a)?"\u0440\u0435\u043d":/çул$/i.exec(a)?"\u0442\u0430\u043d":"\u0440\u0430\u043d";return a+b},past:"%s \u043a\u0430\u044f\u043b\u043b\u0430",s:"\u043f\u0115\u0440-\u0438\u043a \u00e7\u0435\u043a\u043a\u0443\u043d\u0442",m:"\u043f\u0115\u0440 \u043c\u0438\u043d\u0443\u0442",mm:"%d \u043c\u0438\u043d\u0443\u0442",h:"\u043f\u0115\u0440 \u0441\u0435\u0445\u0435\u0442",hh:"%d \u0441\u0435\u0445\u0435\u0442",d:"\u043f\u0115\u0440 \u043a\u0443\u043d",dd:"%d \u043a\u0443\u043d",M:"\u043f\u0115\u0440 \u0443\u0439\u0103\u0445",MM:"%d \u0443\u0439\u0103\u0445",y:"\u043f\u0115\u0440 \u00e7\u0443\u043b",yy:"%d \u00e7\u0443\u043b"},ordinal:function(a){return"-\u043c\u0115\u0448"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("cv",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/da.js b/api/node_modules/moment/min/lang/da.js deleted file mode 100644 index 63997fa9d1b..00000000000 --- a/api/node_modules/moment/min/lang/da.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : danish (da) -// author : Ulrik Nielsen : https://github.com/mrbase -(function(){var a={months:"Januar_Februar_Marts_April_Maj_Juni_Juli_August_September_Oktober_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec".split("_"),weekdays:"S\u00f8ndag_Mandag_Tirsdag_Onsdag_Torsdag_Fredag_L\u00f8rdag".split("_"),weekdaysShort:"S\u00f8n_Man_Tir_Ons_Tor_Fre_L\u00f8r".split("_"),weekdaysMin:"S\u00f8_Ma_Ti_On_To_Fr_L\u00f8".split("_"),longDateFormat:{LT:"h:mm A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd D. MMMM, YYYY h:mm A"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I g\u00e5r kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"f\u00e5 sekunder",m:"minut",mm:"%d minutter",h:"time",hh:"%d timer",d:"dag",dd:"%d dage",M:"m\u00e5nede",MM:"%d m\u00e5neder",y:"\u00e5r",yy:"%d \u00e5r"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("da",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/de.js b/api/node_modules/moment/min/lang/de.js deleted file mode 100644 index 6acd6428596..00000000000 --- a/api/node_modules/moment/min/lang/de.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : german (de) -// author : lluchs : https://github.com/lluchs -(function(){var a={months:"Januar_Februar_M\u00e4rz_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"H:mm U\\hr",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT",sameElse:"L",nextDay:"[Morgen um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gestern um] LT",lastWeek:"[letzten] dddd [um] LT"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:"einer Minute",mm:"%d Minuten",h:"einer Stunde",hh:"%d Stunden",d:"einem Tag",dd:"%d Tagen",M:"einem Monat",MM:"%d Monaten",y:"einem Jahr",yy:"%d Jahren"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("de",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/en-ca.js b/api/node_modules/moment/min/lang/en-ca.js deleted file mode 100644 index b9b32479ef5..00000000000 --- a/api/node_modules/moment/min/lang/en-ca.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : canadian english (en-ca) -// author : Jonathan Abourbih : https://github.com/jonbca -(function(){var a={months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"YYYY-MM-DD",LL:"D MMMM, YYYY",LLL:"D MMMM, YYYY LT",LLLL:"dddd, D MMMM, YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("en-ca",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/en-gb.js b/api/node_modules/moment/min/lang/en-gb.js deleted file mode 100644 index f86fa439191..00000000000 --- a/api/node_modules/moment/min/lang/en-gb.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : great britain english (en-gb) -// author : Chris Gedrim : https://github.com/chrisgedrim -(function(){var a={months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("en-gb",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/es.js b/api/node_modules/moment/min/lang/es.js deleted file mode 100644 index ce389c0910b..00000000000 --- a/api/node_modules/moment/min/lang/es.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : spanish (es) -// author : Julio Napurí : https://github.com/julionc -(function(){var a={months:"Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre".split("_"),monthsShort:"Ene._Feb._Mar._Abr._May._Jun._Jul._Ago._Sep._Oct._Nov._Dic.".split("_"),weekdays:"Domingo_Lunes_Martes_Mi\u00e9rcoles_Jueves_Viernes_S\u00e1bado".split("_"),weekdaysShort:"Dom._Lun._Mar._Mi\u00e9._Jue._Vie._S\u00e1b.".split("_"),weekdaysMin:"Do_Lu_Ma_Mi_Ju_Vi_S\u00e1".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[ma\u00f1ana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un d\u00eda",dd:"%d d\u00edas",M:"un mes",MM:"%d meses",y:"un a\u00f1o",yy:"%d a\u00f1os"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("es",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/et.js b/api/node_modules/moment/min/lang/et.js deleted file mode 100644 index dac6e1e0c15..00000000000 --- a/api/node_modules/moment/min/lang/et.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : estonian (et) -// author : Henry Kehlmann : https://github.com/madhenry -(function(){function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"paari sekundi":"paar sekundit";default:}return""}var b={months:"jaanuar_veebruar_m\u00e4rts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_m\u00e4rts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"p\u00fchap\u00e4ev_esmasp\u00e4ev_teisip\u00e4ev_kolmap\u00e4ev_neljap\u00e4ev_reede_laup\u00e4ev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[T\u00e4na,] LT",nextDay:"[Homme,] LT",nextWeek:"[J\u00e4rgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s p\u00e4rast",past:"%s tagasi",s:a,m:"minut",mm:"%d minutit",h:"tund",hh:"%d tundi",d:"p\u00e4ev",dd:"%d p\u00e4eva",M:"kuu",MM:"%d kuud",y:"aasta",yy:"%d aastat"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=b),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("et",b)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/eu.js b/api/node_modules/moment/min/lang/eu.js deleted file mode 100644 index 453d5122870..00000000000 --- a/api/node_modules/moment/min/lang/eu.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : euskara (eu) -// author : Eneko Illarramendi : https://github.com/eillarra -(function(){var a={months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"YYYYko MMMMren D[a]",LLL:"YYYYko MMMMren D[a] LT",LLLL:"dddd, YYYYko MMMMren D[a] LT"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("eu",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/fi.js b/api/node_modules/moment/min/lang/fi.js deleted file mode 100644 index d088338b382..00000000000 --- a/api/node_modules/moment/min/lang/fi.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : finnish (fi) -// author : Tarmo Aidantausta : https://github.com/bleadof -(function(){function c(a,b,c,e){var f="";switch(c){case"s":return e?"muutaman sekunnin":"muutama sekunti";case"m":return e?"minuutin":"minuutti";case"mm":f=e?"minuutin":"minuuttia";break;case"h":return e?"tunnin":"tunti";case"hh":f=e?"tunnin":"tuntia";break;case"d":return e?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4";case"dd":f=e?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4\u00e4";break;case"M":return e?"kuukauden":"kuukausi";case"MM":f=e?"kuukauden":"kuukautta";break;case"y":return e?"vuoden":"vuosi";case"yy":f=e?"vuoden":"vuotta"}return f=d(a,e)+" "+f,f}function d(c,d){return c<10?d?b[c]:a[c]:c}var a=["nolla","yksi","kaksi","kolme","nelj\u00e4","viisi","kuusi","seitsem\u00e4n","kahdeksan","yhdeks\u00e4n"],b=["nolla","yhden","kahden","kolmen","nelj\u00e4n","viiden","kuuden",a[7],a[8],a[9]],e={months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kes\u00e4kuu_hein\u00e4kuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tam_hel_maa_huh_tou_kes_hei_elo_syy_lok_mar_jou".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",L:"DD.MM.YYYY",LL:"Do MMMMt\\a YYYY",LLL:"Do MMMMt\\a YYYY, klo LT",LLLL:"dddd, Do MMMMt\\a YYYY, klo LT"},calendar:{sameDay:"[t\u00e4n\u00e4\u00e4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\u00e4\u00e4st\u00e4",past:"%s sitten",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=e),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fi",e)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/fr-ca.js b/api/node_modules/moment/min/lang/fr-ca.js deleted file mode 100644 index 695c24159f0..00000000000 --- a/api/node_modules/moment/min/lang/fr-ca.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : canadian french (fr-ca) -// author : Jonathan Abourbih : https://github.com/jonbca -(function(){var a={months:"janvier_f\u00e9vrier_mars_avril_mai_juin_juillet_ao\u00fbt_septembre_octobre_novembre_d\u00e9cembre".split("_"),monthsShort:"janv._f\u00e9vr._mars_avr._mai_juin_juil._ao\u00fbt_sept._oct._nov._d\u00e9c.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui \u00e0] LT",nextDay:"[Demain \u00e0] LT",nextWeek:"dddd [\u00e0] LT",lastDay:"[Hier \u00e0] LT",lastWeek:"dddd [dernier \u00e0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"une ann\u00e9e",yy:"%d ann\u00e9es"},ordinal:function(a){return a===1?"er":"\u00e8me"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fr-ca",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/fr.js b/api/node_modules/moment/min/lang/fr.js deleted file mode 100644 index f1dddc73a3c..00000000000 --- a/api/node_modules/moment/min/lang/fr.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : french (fr) -// author : John Fischer : https://github.com/jfroffice -(function(){var a={months:"janvier_f\u00e9vrier_mars_avril_mai_juin_juillet_ao\u00fbt_septembre_octobre_novembre_d\u00e9cembre".split("_"),monthsShort:"janv._f\u00e9vr._mars_avr._mai_juin_juil._ao\u00fbt_sept._oct._nov._d\u00e9c.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui \u00e0] LT",nextDay:"[Demain \u00e0] LT",nextWeek:"dddd [\u00e0] LT",lastDay:"[Hier \u00e0] LT",lastWeek:"dddd [dernier \u00e0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"une ann\u00e9e",yy:"%d ann\u00e9es"},ordinal:function(a){return a===1?"er":"\u00e8me"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("fr",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/gl.js b/api/node_modules/moment/min/lang/gl.js deleted file mode 100644 index 00ffbc17668..00000000000 --- a/api/node_modules/moment/min/lang/gl.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : galician (gl) -// author : Juan G. Hurtado : https://github.com/juanghurtado -(function(){var a={months:"Xaneiro_Febreiro_Marzo_Abril_Maio_Xu\u00f1o_Xullo_Agosto_Setembro_Octubro_Novembro_Decembro".split("_"),monthsShort:"Xan._Feb._Mar._Abr._Mai._Xu\u00f1._Xul._Ago._Set._Out._Nov._Dec.".split("_"),weekdays:"Domingo_Luns_Martes_M\u00e9rcores_Xoves_Venres_S\u00e1bado".split("_"),weekdaysShort:"Dom._Lun._Mar._M\u00e9r._Xov._Ven._S\u00e1b.".split("_"),weekdaysMin:"Do_Lu_Ma_M\u00e9_Xo_Ve_S\u00e1".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoxe "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},nextDay:function(){return"[ma\u00f1\u00e1 "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},nextWeek:function(){return"dddd ["+(this.hours()!==1?"\u00e1s":"a")+"] LT"},lastDay:function(){return"[onte "+(this.hours()!==1?"\u00e1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(this.hours()!==1?"\u00e1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fai %s",s:"uns segundo",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\u00eda",dd:"%d d\u00edas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("gl",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/hu.js b/api/node_modules/moment/min/lang/hu.js deleted file mode 100644 index 7782baefd8b..00000000000 --- a/api/node_modules/moment/min/lang/hu.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : hungarian (hu) -// author : Adam Brunner : https://github.com/adambrunner -(function(){function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"n\u00e9h\u00e1ny m\u00e1sodperc":"n\u00e9h\u00e1ny m\u00e1sodperce";case"m":e="egy";case"mm":return e+(d||b?" perc":" perce");case"h":e="egy";case"hh":return e+(d||b?" \u00f3ra":" \u00f3r\u00e1ja");case"d":e="egy";case"dd":return e+(d||b?" nap":" napja");case"M":e="egy";case"MM":return e+(d||b?" h\u00f3nap":" h\u00f3napja");case"y":e="egy";case"yy":return e+(d||b?" \u00e9v":" \u00e9ve");default:}return""}function b(a){var b="";switch(this.day()){case 0:b="vas\u00e1rnap";break;case 1:b="h\u00e9tf\u0151n";break;case 2:b="kedden";break;case 3:b="szerd\u00e1n";break;case 4:b="cs\u00fct\u00f6rt\u00f6k\u00f6n";break;case 5:b="p\u00e9nteken";break;case 6:b="szombaton"}return(a?"":"m\u00falt ")+"["+b+"] LT[-kor]"}var c={months:"janu\u00e1r_febru\u00e1r_m\u00e1rcius_\u00e1prilis_m\u00e1jus_j\u00fanius_j\u00falius_augusztus_szeptember_okt\u00f3ber_november_december".split("_"),monthsShort:"jan_feb_m\u00e1rc_\u00e1pr_m\u00e1j_j\u00fan_j\u00fal_aug_szept_okt_nov_dec".split("_"),weekdays:"vas\u00e1rnap_h\u00e9tf\u0151_kedd_szerda_cs\u00fct\u00f6rt\u00f6k_p\u00e9ntek_szombat".split("_"),weekdaysShort:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return b.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return b.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\u00falva",past:"%s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("hu",c)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/is.js b/api/node_modules/moment/min/lang/is.js deleted file mode 100644 index 76ee4a6c1e4..00000000000 --- a/api/node_modules/moment/min/lang/is.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : icelandic (is) -// author : Hinrik Örn Sigurðsson : https://github.com/hinrik -(function(){var a=function(a){return a%100==11?!0:a%10==1?!1:!0},b=function(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"nokkrar sek\u00fandur":"nokkrum sek\u00fandum";case"m":return c?"m\u00edn\u00fata":"m\u00edn\u00fatu";case"mm":return a(b)?f+(c||e?"m\u00edn\u00fatur":"m\u00edn\u00fatum"):c?f+"m\u00edn\u00fata":f+"m\u00edn\u00fatu";case"hh":return a(b)?f+(c||e?"klukkustundir":"klukkustundum"):f+"klukkustund";case"d":return c?"dagur":e?"dag":"degi";case"dd":return a(b)?c?f+"dagar":f+(e?"daga":"d\u00f6gum"):c?f+"dagur":f+(e?"dag":"degi");case"M":return c?"m\u00e1nu\u00f0ur":e?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i";case"MM":return a(b)?c?f+"m\u00e1nu\u00f0ir":f+(e?"m\u00e1nu\u00f0i":"m\u00e1nu\u00f0um"):c?f+"m\u00e1nu\u00f0ur":f+(e?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i");case"y":return c||e?"\u00e1r":"\u00e1ri";case"yy":return a(b)?f+(c||e?"\u00e1r":"\u00e1rum"):f+(c||e?"\u00e1r":"\u00e1ri")}},c={months:"jan\u00faar_febr\u00faar_mars_apr\u00edl_ma\u00ed_j\u00fan\u00ed_j\u00fal\u00ed_\u00e1g\u00fast_september_okt\u00f3ber_n\u00f3vember_desember".split("_"),monthsShort:"jan_feb_mar_apr_ma\u00ed_j\u00fan_j\u00fal_\u00e1g\u00fa_sep_okt_n\u00f3v_des".split("_"),weekdays:"sunnudagur_m\u00e1nudagur_\u00feri\u00f0judagur_mi\u00f0vikudagur_fimmtudagur_f\u00f6studagur_laugardagur".split("_"),weekdaysShort:"sun_m\u00e1n_\u00feri_mi\u00f0_fim_f\u00f6s_lau".split("_"),weekdaysMin:"Su_M\u00e1_\u00der_Mi_Fi_F\u00f6_La".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY kl. LT",LLLL:"dddd, D. MMMM YYYY kl. LT"},calendar:{sameDay:"[\u00ed dag kl.] LT",nextDay:"[\u00e1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\u00ed g\u00e6r kl.] LT",lastWeek:"[s\u00ed\u00f0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\u00ed\u00f0an",s:b,m:b,mm:b,h:"klukkustund",hh:b,d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("is",c)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/it.js b/api/node_modules/moment/min/lang/it.js deleted file mode 100644 index 0463a300074..00000000000 --- a/api/node_modules/moment/min/lang/it.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : italian (it) -// author : Lorenzo : https://github.com/aliem -(function(){var a={months:"Gennaio_Febbraio_Marzo_Aprile_Maggio_Giugno_Luglio_Agosto_Settembre_Ottobre_Novembre_Dicembre".split("_"),monthsShort:"Gen_Feb_Mar_Apr_Mag_Giu_Lug_Ago_Set_Ott_Nov_Dic".split("_"),weekdays:"Domenica_Luned\u00ec_Marted\u00ec_Mercoled\u00ec_Gioved\u00ec_Venerd\u00ec_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"D_L_Ma_Me_G_V_S".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:"[lo scorso] dddd [alle] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s fa",s:"secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinal:function(){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("it",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/ja.js b/api/node_modules/moment/min/lang/ja.js deleted file mode 100644 index 0d060cdd832..00000000000 --- a/api/node_modules/moment/min/lang/ja.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : japanese (ja) -// author : LI Long : https://github.com/baryon -(function(){var a={months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"Ah\u6642m\u5206",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5LT",LLLL:"YYYY\u5e74M\u6708D\u65e5LT dddd"},meridiem:function(a,b,c){return a<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ja",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/jp.js b/api/node_modules/moment/min/lang/jp.js deleted file mode 100644 index 4aa32e860e1..00000000000 --- a/api/node_modules/moment/min/lang/jp.js +++ /dev/null @@ -1,6 +0,0 @@ -// moment.js language configuration -// language : japanese (jp) -// author : LI Long : https://github.com/baryon -// This language config was incorrectly named 'jp' instead of 'ja'. -// In version 2.0.0, this will be deprecated and you should use 'ja' instead. -(function(){var a={months:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u65e5\u66dc\u65e5_\u6708\u66dc\u65e5_\u706b\u66dc\u65e5_\u6c34\u66dc\u65e5_\u6728\u66dc\u65e5_\u91d1\u66dc\u65e5_\u571f\u66dc\u65e5".split("_"),weekdaysShort:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),weekdaysMin:"\u65e5_\u6708_\u706b_\u6c34_\u6728_\u91d1_\u571f".split("_"),longDateFormat:{LT:"Ah\u6642m\u5206",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5LT",LLLL:"YYYY\u5e74M\u6708D\u65e5LT dddd"},meridiem:function(a,b,c){return a<12?"\u5348\u524d":"\u5348\u5f8c"},calendar:{sameDay:"[\u4eca\u65e5] LT",nextDay:"[\u660e\u65e5] LT",nextWeek:"[\u6765\u9031]dddd LT",lastDay:"[\u6628\u65e5] LT",lastWeek:"[\u524d\u9031]dddd LT",sameElse:"L"},relativeTime:{future:"%s\u5f8c",past:"%s\u524d",s:"\u6570\u79d2",m:"1\u5206",mm:"%d\u5206",h:"1\u6642\u9593",hh:"%d\u6642\u9593",d:"1\u65e5",dd:"%d\u65e5",M:"1\u30f6\u6708",MM:"%d\u30f6\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("jp",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/ko.js b/api/node_modules/moment/min/lang/ko.js deleted file mode 100644 index d65a241445d..00000000000 --- a/api/node_modules/moment/min/lang/ko.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : korean (ko) -// author : Kyungwook, Park : https://github.com/kyungw00k -(function(){var a={months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h\uc2dc mm\ubd84",L:"YYYY.MM.DD",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c LT",LLLL:"YYYY\ub144 MMMM D\uc77c dddd LT"},meridiem:function(a,b,c){return a<12?"\uc624\uc804":"\uc624\ud6c4"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87\ucd08",ss:"%d\ucd08",m:"\uc77c\ubd84",mm:"%d\ubd84",h:"\ud55c\uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c\ub2ec",MM:"%d\ub2ec",y:"\uc77c\ub144",yy:"%d\ub144"},ordinal:function(a){return"\uc77c"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ko",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/kr.js b/api/node_modules/moment/min/lang/kr.js deleted file mode 100644 index 9cca2c5194e..00000000000 --- a/api/node_modules/moment/min/lang/kr.js +++ /dev/null @@ -1,6 +0,0 @@ -// moment.js language configuration -// language : korean (kr) -// author : Kyungwook, Park : https://github.com/kyungw00k -// This language config was incorrectly named 'kr' instead of 'ko'. -// In version 2.0.0, this will be deprecated and you should use 'ko' instead. -(function(){var a={months:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),monthsShort:"1\uc6d4_2\uc6d4_3\uc6d4_4\uc6d4_5\uc6d4_6\uc6d4_7\uc6d4_8\uc6d4_9\uc6d4_10\uc6d4_11\uc6d4_12\uc6d4".split("_"),weekdays:"\uc77c\uc694\uc77c_\uc6d4\uc694\uc77c_\ud654\uc694\uc77c_\uc218\uc694\uc77c_\ubaa9\uc694\uc77c_\uae08\uc694\uc77c_\ud1a0\uc694\uc77c".split("_"),weekdaysShort:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),weekdaysMin:"\uc77c_\uc6d4_\ud654_\uc218_\ubaa9_\uae08_\ud1a0".split("_"),longDateFormat:{LT:"A h\uc2dc mm\ubd84",L:"YYYY.MM.DD",LL:"YYYY\ub144 MMMM D\uc77c",LLL:"YYYY\ub144 MMMM D\uc77c LT",LLLL:"YYYY\ub144 MMMM D\uc77c dddd LT"},meridiem:function(a,b,c){return a<12?"\uc624\uc804":"\uc624\ud6c4"},calendar:{sameDay:"\uc624\ub298 LT",nextDay:"\ub0b4\uc77c LT",nextWeek:"dddd LT",lastDay:"\uc5b4\uc81c LT",lastWeek:"\uc9c0\ub09c\uc8fc dddd LT",sameElse:"L"},relativeTime:{future:"%s \ud6c4",past:"%s \uc804",s:"\uba87\ucd08",ss:"%d\ucd08",m:"\uc77c\ubd84",mm:"%d\ubd84",h:"\ud55c\uc2dc\uac04",hh:"%d\uc2dc\uac04",d:"\ud558\ub8e8",dd:"%d\uc77c",M:"\ud55c\ub2ec",MM:"%d\ub2ec",y:"\uc77c\ub144",yy:"%d\ub144"},ordinal:function(a){return"\uc77c"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("kr",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/nb.js b/api/node_modules/moment/min/lang/nb.js deleted file mode 100644 index ecb10617b32..00000000000 --- a/api/node_modules/moment/min/lang/nb.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : norwegian bokmÃ¥l (nb) -// author : Espen Hovlandsdal : https://github.com/rexxars -(function(){var a={months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"s\u00f8ndag_mandag_tirsdag_onsdag_torsdag_fredag_l\u00f8rdag".split("_"),weekdaysShort:"s\u00f8n_man_tir_ons_tor_fre_l\u00f8r".split("_"),weekdaysMin:"s\u00f8_ma_ti_on_to_fr_l\u00f8".split("_"),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[I dag klokken] LT",nextDay:"[I morgen klokken] LT",nextWeek:"dddd [klokken] LT",lastDay:"[I g\u00e5r klokken] LT",lastWeek:"[Forrige] dddd [klokken] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"for %s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en m\u00e5ned",MM:"%d m\u00e5neder",y:"ett \u00e5r",yy:"%d \u00e5r"},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("nb",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/nl.js b/api/node_modules/moment/min/lang/nl.js deleted file mode 100644 index f5010440f6e..00000000000 --- a/api/node_modules/moment/min/lang/nl.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : dutch (nl) -// author : Joris Röling : https://github.com/jjupiter -(function(){var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),b="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),c={months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(c,d){return/-MMM-/.test(d)?b[c.month()]:a[c.month()]},weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Vandaag om] LT",nextDay:"[Morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"\u00e9\u00e9n minuut",mm:"%d minuten",h:"\u00e9\u00e9n uur",hh:"%d uur",d:"\u00e9\u00e9n dag",dd:"%d dagen",M:"\u00e9\u00e9n maand",MM:"%d maanden",y:"\u00e9\u00e9n jaar",yy:"%d jaar"},ordinal:function(a){return a===1||a===8||a>=20?"ste":"de"}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("nl",c)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/pl.js b/api/node_modules/moment/min/lang/pl.js deleted file mode 100644 index 6f0cc935d36..00000000000 --- a/api/node_modules/moment/min/lang/pl.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : polish (pl) -// author : Rafal Hirsz : https://github.com/evoL -(function(){var a=function(a){return a%10<5&&a%10>1&&~~(a/10)!==1},b=function(b,c,d){var e=b+" ";switch(d){case"m":return c?"minuta":"minut\u0119";case"mm":return e+(a(b)?"minuty":"minut");case"h":return c?"godzina":"godzin\u0119";case"hh":return e+(a(b)?"godziny":"godzin");case"MM":return e+(a(b)?"miesi\u0105ce":"miesi\u0119cy");case"yy":return e+(a(b)?"lata":"lat")}},c={months:"stycze\u0144_luty_marzec_kwiecie\u0144_maj_czerwiec_lipiec_sierpie\u0144_wrzesie\u0144_pa\u017adziernik_listopad_grudzie\u0144".split("_"),monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_pa\u017a_lis_gru".split("_"),weekdays:"niedziela_poniedzia\u0142ek_wtorek_\u015broda_czwartek_pi\u0105tek_sobota".split("_"),weekdaysShort:"nie_pon_wt_\u015br_czw_pt_sb".split("_"),weekdaysMin:"N_Pn_Wt_\u015ar_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Dzi\u015b o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:"[W zesz\u0142y/\u0142\u0105] dddd [o] LT",sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:b,mm:b,h:b,hh:b,d:"1 dzie\u0144",dd:"%d dni",M:"miesi\u0105c",MM:b,y:"rok",yy:b},ordinal:function(a){return"."}};typeof module!="undefined"&&module.exports&&(module.exports=c),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pl",c)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/pt-br.js b/api/node_modules/moment/min/lang/pt-br.js deleted file mode 100644 index e124c1a627b..00000000000 --- a/api/node_modules/moment/min/lang/pt-br.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : brazilian portuguese (pt-br) -// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira -(function(){var a={months:"Janeiro_Fevereiro_Mar\u00e7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\u00e7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\u00e1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\u00e1b".split("_"),weekdaysMin:"Dom_2\u00aa_3\u00aa_4\u00aa_5\u00aa_6\u00aa_S\u00e1b".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D \\de MMMM \\de YYYY",LLL:"D \\de MMMM \\de YYYY LT",LLLL:"dddd, D \\de MMMM \\de YYYY LT"},calendar:{sameDay:"[Hoje \u00e0s] LT",nextDay:"[Amanh\u00e3 \u00e0s] LT",nextWeek:"dddd [\u00e0s] LT",lastDay:"[Ontem \u00e0s] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[\u00daltimo] dddd [\u00e0s] LT":"[\u00daltima] dddd [\u00e0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atr\u00e1s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\u00eas",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pt-br",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/pt.js b/api/node_modules/moment/min/lang/pt.js deleted file mode 100644 index 1f532cce191..00000000000 --- a/api/node_modules/moment/min/lang/pt.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : portuguese (pt) -// author : Jefferson : https://github.com/jalex79 -(function(){var a={months:"Janeiro_Fevereiro_Mar\u00e7o_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Ter\u00e7a-feira_Quarta-feira_Quinta-feira_Sexta-feira_S\u00e1bado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_S\u00e1b".split("_"),weekdaysMin:"Dom_2\u00aa_3\u00aa_4\u00aa_5\u00aa_6\u00aa_S\u00e1b".split("_"),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D \\de MMMM \\de YYYY",LLL:"D \\de MMMM \\de YYYY LT",LLLL:"dddd, D \\de MMMM \\de YYYY LT"},calendar:{sameDay:"[Hoje \u00e0s] LT",nextDay:"[Amanh\u00e3 \u00e0s] LT",nextWeek:"dddd [\u00e0s] LT",lastDay:"[Ontem \u00e0s] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[\u00daltimo] dddd [\u00e0s] LT":"[\u00daltima] dddd [\u00e0s] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atr\u00e1s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um m\u00eas",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinal:function(a){return"\u00ba"}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("pt",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/ro.js b/api/node_modules/moment/min/lang/ro.js deleted file mode 100644 index 15343dd5e7b..00000000000 --- a/api/node_modules/moment/min/lang/ro.js +++ /dev/null @@ -1,5 +0,0 @@ -// moment.js language configuration -// language : romanian (ro) -// author : Vlad Gurdiga : https://github.com/gurdiga -// author : Valentin Agachi : https://github.com/avaly -(function(){var a={months:"Ianuarie_Februarie_Martie_Aprilie_Mai_Iunie_Iulie_August_Septembrie_Octombrie_Noiembrie_Decembrie".split("_"),monthsShort:"Ian_Feb_Mar_Apr_Mai_Iun_Iul_Aug_Sep_Oct_Noi_Dec".split("_"),weekdays:"Duminic\u0103_Luni_Mar\u0163i_Miercuri_Joi_Vineri_S\u00e2mb\u0103t\u0103".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_S\u00e2m".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_S\u00e2".split("_"),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[m\u00e2ine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s \u00een urm\u0103",s:"c\u00e2teva secunde",m:"un minut",mm:"%d minute",h:"o or\u0103",hh:"%d ore",d:"o zi",dd:"%d zile",M:"o lun\u0103",MM:"%d luni",y:"un an",yy:"%d ani"},ordinal:function(a){return""}};typeof module!="undefined"&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("ro",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/ru.js b/api/node_modules/moment/min/lang/ru.js deleted file mode 100644 index 498f3e8b7cd..00000000000 --- a/api/node_modules/moment/min/lang/ru.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : russian (ru) -// author : Viktorminator : https://github.com/Viktorminator -(function(){var a=[function(a){return a%10===1&&a%100!==11},function(a){return a%10>=2&&a%10<=4&&a%10%1===0&&(a%100<12||a%100>14)},function(a){return a%10===0||a%10>=5&&a%10<=9&&a%10%1===0||a%100>=11&&a%100<=14&&a%100%1===0},function(a){return!0}],b=function(b,c){var d=b.split("_"),e=Math.min(a.length,d.length),f=-1;while(++f=100?100:null;return a[c]||a[d]||a[e]}};typeof module!="undefined"&&module.exports&&(module.exports=b),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("tr",b)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/zh-cn.js b/api/node_modules/moment/min/lang/zh-cn.js deleted file mode 100644 index 4d690f879b1..00000000000 --- a/api/node_modules/moment/min/lang/zh-cn.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : chinese -// author : suupic : https://github.com/suupic -(function(){var a={months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"Ah\u70b9mm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,b,c){return a<9?"\u65e9\u4e0a":a<11&&b<30?"\u4e0a\u5348":a<13&&b<30?"\u4e2d\u5348":a<18?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",m:"1\u5206\u949f",mm:"%d\u5206\u949f",h:"1\u5c0f\u65f6",hh:"%d\u5c0f\u65f6",d:"1\u5929",dd:"%d\u5929",M:"1\u4e2a\u6708",MM:"%d\u4e2a\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("zh-cn",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/lang/zh-tw.js b/api/node_modules/moment/min/lang/zh-tw.js deleted file mode 100644 index 8fc899edb91..00000000000 --- a/api/node_modules/moment/min/lang/zh-tw.js +++ /dev/null @@ -1,4 +0,0 @@ -// moment.js language configuration -// language : traditional chinese (zh-tw) -// author : Ben : https://github.com/ben-lin -(function(){var a={months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u9031\u65e5_\u9031\u4e00_\u9031\u4e8c_\u9031\u4e09_\u9031\u56db_\u9031\u4e94_\u9031\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"Ah\u9edemm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,b,c){return a<9?"\u65e9\u4e0a":a<11&&b<30?"\u4e0a\u5348":a<13&&b<30?"\u4e2d\u5348":a<18?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",m:"\u4e00\u5206\u9418",mm:"%d\u5206\u9418",h:"\u4e00\u5c0f\u6642",hh:"%d\u5c0f\u6642",d:"\u4e00\u5929",dd:"%d\u5929",M:"\u4e00\u500b\u6708",MM:"%d\u500b\u6708",y:"\u4e00\u5e74",yy:"%d\u5e74"},ordinal:function(a){return""}};typeof module!="undefined"&&module.exports&&(module.exports=a),typeof window!="undefined"&&this.moment&&this.moment.lang&&this.moment.lang("zh-tw",a)})(); \ No newline at end of file diff --git a/api/node_modules/moment/min/moment.min.js b/api/node_modules/moment/min/moment.min.js deleted file mode 100644 index 67cb15270b3..00000000000 --- a/api/node_modules/moment/min/moment.min.js +++ /dev/null @@ -1,6 +0,0 @@ -// moment.js -// version : 1.7.2 -// author : Tim Wood -// license : MIT -// momentjs.com -(function(a){function E(a,b,c,d){var e=c.lang();return e[a].call?e[a](c,d):e[a][b]}function F(a,b){return function(c){return K(a.call(this,c),b)}}function G(a){return function(b){var c=a.call(this,b);return c+this.lang().ordinal(c)}}function H(a,b,c){this._d=a,this._isUTC=!!b,this._a=a._a||null,this._lang=c||!1}function I(a){var b=this._data={},c=a.years||a.y||0,d=a.months||a.M||0,e=a.weeks||a.w||0,f=a.days||a.d||0,g=a.hours||a.h||0,h=a.minutes||a.m||0,i=a.seconds||a.s||0,j=a.milliseconds||a.ms||0;this._milliseconds=j+i*1e3+h*6e4+g*36e5,this._days=f+e*7,this._months=d+c*12,b.milliseconds=j%1e3,i+=J(j/1e3),b.seconds=i%60,h+=J(i/60),b.minutes=h%60,g+=J(h/60),b.hours=g%24,f+=J(g/24),f+=e*7,b.days=f%30,d+=J(f/30),b.months=d%12,c+=J(d/12),b.years=c,this._lang=!1}function J(a){return a<0?Math.ceil(a):Math.floor(a)}function K(a,b){var c=a+"";while(c.length70?1900:2e3);break;case"YYYY":c[0]=~~Math.abs(b);break;case"a":case"A":d.isPm=(b+"").toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b;break;case"S":case"SS":case"SSS":c[6]=~~(("0."+b)*1e3);break;case"Z":case"ZZ":d.isUTC=!0,e=(b+"").match(x),e&&e[1]&&(d.tzh=~~e[1]),e&&e[2]&&(d.tzm=~~e[2]),e&&e[0]==="+"&&(d.tzh=-d.tzh,d.tzm=-d.tzm)}b==null&&(c[8]=!1)}function W(a,b){var c=[0,0,1,0,0,0,0],d={tzh:0,tzm:0},e=b.match(k),f,g;for(f=0;f0,j[4]=c,Z.apply({},j)}function _(a,c){b.fn[a]=function(a){var b=this._isUTC?"UTC":"";return a!=null?(this._d["set"+b+c](a),this):this._d["get"+b+c]()}}function ab(a){b.duration.fn[a]=function(){return this._data[a]}}function bb(a,c){b.duration.fn["as"+a]=function(){return+this/c}}var b,c="1.7.2",d=Math.round,e,f={},g="en",h=typeof module!="undefined"&&module.exports,i="months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem".split("|"),j=/^\/?Date\((\-?\d+)/i,k=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g,l=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g,m=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,n=/\d\d?/,o=/\d{1,3}/,p=/\d{3}/,q=/\d{1,4}/,r=/[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i,s=/Z|[\+\-]\d\d:?\d\d/i,t=/T/i,u=/^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,v="YYYY-MM-DDTHH:mm:ssZ",w=[["HH:mm:ss.S",/T\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/T\d\d:\d\d:\d\d/],["HH:mm",/T\d\d:\d\d/],["HH",/T\d\d/]],x=/([\+\-]|\d\d)/gi,y="Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"),z={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},A={},B="DDD w M D d".split(" "),C="M D H h m s w".split(" "),D={M:function(){return this.month()+1},MMM:function(a){return E("monthsShort",this.month(),this,a)},MMMM:function(a){return E("months",this.month(),this,a)},D:function(){return this.date()},DDD:function(){var a=new Date(this.year(),this.month(),this.date()),b=new Date(this.year(),0,1);return~~((a-b)/864e5+1.5)},d:function(){return this.day()},dd:function(a){return E("weekdaysMin",this.day(),this,a)},ddd:function(a){return E("weekdaysShort",this.day(),this,a)},dddd:function(a){return E("weekdays",this.day(),this,a)},w:function(){var a=new Date(this.year(),this.month(),this.date()-this.day()+5),b=new Date(a.getFullYear(),0,4);return~~((a-b)/864e5/7+1.5)},YY:function(){return K(this.year()%100,2)},YYYY:function(){return K(this.year(),4)},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return K(~~(this.milliseconds()/10),2)},SSS:function(){return K(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(a/60),2)+":"+K(~~a%60,2)},ZZ:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(10*a/6),4)}};while(B.length)e=B.pop(),D[e+"o"]=G(D[e]);while(C.length)e=C.pop(),D[e+e]=F(D[e],2);D.DDDD=F(D.DDD,3),b=function(c,d){if(c===null||c==="")return null;var e,f;return b.isMoment(c)?new H(new Date(+c._d),c._isUTC,c._lang):(d?M(d)?e=X(c,d):e=W(c,d):(f=j.exec(c),e=c===a?new Date:f?new Date(+f[1]):c instanceof Date?c:M(c)?O(c):typeof c=="string"?Y(c):new Date(c)),new H(e))},b.utc=function(a,c){return M(a)?new H(O(a,!0),!0):(typeof a=="string"&&!s.exec(a)&&(a+=" +0000",c&&(c+=" Z")),b(a,c).utc())},b.unix=function(a){return b(a*1e3)},b.duration=function(a,c){var d=b.isDuration(a),e=typeof a=="number",f=d?a._data:e?{}:a,g;return e&&(c?f[c]=a:f.milliseconds=a),g=new I(f),d&&(g._lang=a._lang),g},b.humanizeDuration=function(a,c,d){return b.duration(a,c===!0?null:c).humanize(c===!0?!0:d)},b.version=c,b.defaultFormat=v,b.lang=function(a,c){var d;if(!a)return g;(c||!f[a])&&P(a,c);if(f[a]){for(d=0;d11?c?"pm":"PM":c?"am":"AM"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}}),b.fn=H.prototype={clone:function(){return b(this)},valueOf:function(){return+this._d},unix:function(){return Math.floor(+this._d/1e3)},toString:function(){return this._d.toString()},toDate:function(){return this._d},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds(),!!this._isUTC]},isValid:function(){return this._a?this._a[8]!=null?!!this._a[8]:!N(this._a,(this._a[7]?b.utc(this._a):b(this._a)).toArray()):!isNaN(this._d.getTime())},utc:function(){return this._isUTC=!0,this},local:function(){return this._isUTC=!1,this},format:function(a){return T(this,a?a:b.defaultFormat)},add:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,1),this},subtract:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,-1),this},diff:function(a,c,e){var f=this._isUTC?b(a).utc():b(a).local(),g=(this.zone()-f.zone())*6e4,h=this._d-f._d-g,i=this.year()-f.year(),j=this.month()-f.month(),k=this.date()-f.date(),l;return c==="months"?l=i*12+j+k/30:c==="years"?l=i+(j+k/30)/12:l=c==="seconds"?h/1e3:c==="minutes"?h/6e4:c==="hours"?h/36e5:c==="days"?h/864e5:c==="weeks"?h/6048e5:h,e?l:d(l)},from:function(a,c){return b.duration(this.diff(a)).lang(this._lang).humanize(!c)},fromNow:function(a){return this.from(b(),a)},calendar:function(){var a=this.diff(b().sod(),"days",!0),c=this.lang().calendar,d=c.sameElse,e=a<-6?d:a<-1?c.lastWeek:a<0?c.lastDay:a<1?c.sameDay:a<2?c.nextDay:a<7?c.nextWeek:d;return this.format(typeof e=="function"?e.apply(this):e)},isLeapYear:function(){var a=this.year();return a%4===0&&a%100!==0||a%400===0},isDST:function(){return this.zone() 70 ? 1900 : 2e3); - break; - case "YYYY": - c[0] = ~~Math.abs(b); - break; - case "a": - case "A": - d.isPm = (b + "").toLowerCase() === "pm"; - break; - case "H": - case "HH": - case "h": - case "hh": - c[3] = ~~b; - break; - case "m": - case "mm": - c[4] = ~~b; - break; - case "s": - case "ss": - c[5] = ~~b; - break; - case "S": - case "SS": - case "SSS": - c[6] = ~~(("0." + b) * 1e3); - break; - case "Z": - case "ZZ": - d.isUTC = !0, e = (b + "").match(x), e && e[1] && (d.tzh = ~~e[1]), e && e[2] && (d.tzm = ~~e[2]), e && e[0] === "+" && (d.tzh = -d.tzh, d.tzm = -d.tzm); - } - b == null && (c[8] = !1); - } - function W(a, b) { - var c = [ 0, 0, 1, 0, 0, 0, 0 ], d = { - tzh: 0, - tzm: 0 - }, e = b.match(k), f, g; - for (f = 0; f < e.length; f++) g = (U(e[f]).exec(a) || [])[0], g && (a = a.slice(a.indexOf(g) + g.length)), D[e[f]] && V(e[f], g, c, d); - return d.isPm && c[3] < 12 && (c[3] += 12), d.isPm === !1 && c[3] === 12 && (c[3] = 0), O(c, d.isUTC, d.tzh, d.tzm); - } - function X(a, b) { - var c, d = a.match(m) || [], e, f = 99, g, h, i; - for (g = 0; g < b.length; g++) h = W(a, b[g]), e = T(new H(h), b[g]).match(m) || [], i = N(d, e), i < f && (f = i, c = h); - return c; - } - function Y(a) { - var b = "YYYY-MM-DDT", c; - if (u.exec(a)) { - for (c = 0; c < 4; c++) if (w[c][1].exec(a)) { - b += w[c][0]; - break; - } - return s.exec(a) ? W(a, b + " Z") : W(a, b); - } - return new Date(a); - } - function Z(a, b, c, d, e) { - var f = e.relativeTime[a]; - return typeof f == "function" ? f(b || 1, !!c, a, d) : f.replace(/%d/i, b || 1); - } - function $(a, b, c) { - var e = d(Math.abs(a) / 1e3), f = d(e / 60), g = d(f / 60), h = d(g / 24), i = d(h / 365), j = e < 45 && [ "s", e ] || f === 1 && [ "m" ] || f < 45 && [ "mm", f ] || g === 1 && [ "h" ] || g < 22 && [ "hh", g ] || h === 1 && [ "d" ] || h <= 25 && [ "dd", h ] || h <= 45 && [ "M" ] || h < 345 && [ "MM", d(h / 30) ] || i === 1 && [ "y" ] || [ "yy", i ]; - return j[2] = b, j[3] = a > 0, j[4] = c, Z.apply({}, j); - } - function _(a, c) { - b.fn[a] = function(a) { - var b = this._isUTC ? "UTC" : ""; - return a != null ? (this._d["set" + b + c](a), this) : this._d["get" + b + c](); - }; - } - function ab(a) { - b.duration.fn[a] = function() { - return this._data[a]; - }; - } - function bb(a, c) { - b.duration.fn["as" + a] = function() { - return +this / c; - }; - } - var b, c = "1.7.2", d = Math.round, e, f = {}, g = "en", h = typeof module != "undefined" && module.exports, i = "months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem".split("|"), j = /^\/?Date\((\-?\d+)/i, k = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g, l = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g, m = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi, n = /\d\d?/, o = /\d{1,3}/, p = /\d{3}/, q = /\d{1,4}/, r = /[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i, s = /Z|[\+\-]\d\d:?\d\d/i, t = /T/i, u = /^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/, v = "YYYY-MM-DDTHH:mm:ssZ", w = [ [ "HH:mm:ss.S", /T\d\d:\d\d:\d\d\.\d{1,3}/ ], [ "HH:mm:ss", /T\d\d:\d\d:\d\d/ ], [ "HH:mm", /T\d\d:\d\d/ ], [ "HH", /T\d\d/ ] ], x = /([\+\-]|\d\d)/gi, y = "Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"), z = { - Milliseconds: 1, - Seconds: 1e3, - Minutes: 6e4, - Hours: 36e5, - Days: 864e5, - Months: 2592e6, - Years: 31536e6 - }, A = {}, B = "DDD w M D d".split(" "), C = "M D H h m s w".split(" "), D = { - M: function() { - return this.month() + 1; - }, - MMM: function(a) { - return E("monthsShort", this.month(), this, a); - }, - MMMM: function(a) { - return E("months", this.month(), this, a); - }, - D: function() { - return this.date(); - }, - DDD: function() { - var a = new Date(this.year(), this.month(), this.date()), b = new Date(this.year(), 0, 1); - return ~~((a - b) / 864e5 + 1.5); - }, - d: function() { - return this.day(); - }, - dd: function(a) { - return E("weekdaysMin", this.day(), this, a); - }, - ddd: function(a) { - return E("weekdaysShort", this.day(), this, a); - }, - dddd: function(a) { - return E("weekdays", this.day(), this, a); - }, - w: function() { - var a = new Date(this.year(), this.month(), this.date() - this.day() + 5), b = new Date(a.getFullYear(), 0, 4); - return ~~((a - b) / 864e5 / 7 + 1.5); - }, - YY: function() { - return K(this.year() % 100, 2); - }, - YYYY: function() { - return K(this.year(), 4); - }, - a: function() { - return this.lang().meridiem(this.hours(), this.minutes(), !0); - }, - A: function() { - return this.lang().meridiem(this.hours(), this.minutes(), !1); - }, - H: function() { - return this.hours(); - }, - h: function() { - return this.hours() % 12 || 12; - }, - m: function() { - return this.minutes(); - }, - s: function() { - return this.seconds(); - }, - S: function() { - return ~~(this.milliseconds() / 100); - }, - SS: function() { - return K(~~(this.milliseconds() / 10), 2); - }, - SSS: function() { - return K(this.milliseconds(), 3); - }, - Z: function() { - var a = -this.zone(), b = "+"; - return a < 0 && (a = -a, b = "-"), b + K(~~(a / 60), 2) + ":" + K(~~a % 60, 2); - }, - ZZ: function() { - var a = -this.zone(), b = "+"; - return a < 0 && (a = -a, b = "-"), b + K(~~(10 * a / 6), 4); - } - }; - while (B.length) e = B.pop(), D[e + "o"] = G(D[e]); - while (C.length) e = C.pop(), D[e + e] = F(D[e], 2); - D.DDDD = F(D.DDD, 3), b = function(c, d) { - if (c === null || c === "") return null; - var e, f; - return b.isMoment(c) ? new H(new Date(+c._d), c._isUTC, c._lang) : (d ? M(d) ? e = X(c, d) : e = W(c, d) : (f = j.exec(c), e = c === a ? new Date : f ? new Date(+f[1]) : c instanceof Date ? c : M(c) ? O(c) : typeof c == "string" ? Y(c) : new Date(c)), new H(e)); - }, b.utc = function(a, c) { - return M(a) ? new H(O(a, !0), !0) : (typeof a == "string" && !s.exec(a) && (a += " +0000", c && (c += " Z")), b(a, c).utc()); - }, b.unix = function(a) { - return b(a * 1e3); - }, b.duration = function(a, c) { - var d = b.isDuration(a), e = typeof a == "number", f = d ? a._data : e ? {} : a, g; - return e && (c ? f[c] = a : f.milliseconds = a), g = new I(f), d && (g._lang = a._lang), g; - }, b.humanizeDuration = function(a, c, d) { - return b.duration(a, c === !0 ? null : c).humanize(c === !0 ? !0 : d); - }, b.version = c, b.defaultFormat = v, b.lang = function(a, c) { - var d; - if (!a) return g; - (c || !f[a]) && P(a, c); - if (f[a]) { - for (d = 0; d < i.length; d++) b[i[d]] = f[a][i[d]]; - b.monthsParse = f[a].monthsParse, g = a; - } - }, b.langData = Q, b.isMoment = function(a) { - return a instanceof H; - }, b.isDuration = function(a) { - return a instanceof I; - }, b.lang("en", { - months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort: "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin: "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), - longDateFormat: { - LT: "h:mm A", - L: "MM/DD/YYYY", - LL: "MMMM D YYYY", - LLL: "MMMM D YYYY LT", - LLLL: "dddd, MMMM D YYYY LT" - }, - meridiem: function(a, b, c) { - return a > 11 ? c ? "pm" : "PM" : c ? "am" : "AM"; - }, - calendar: { - sameDay: "[Today at] LT", - nextDay: "[Tomorrow at] LT", - nextWeek: "dddd [at] LT", - lastDay: "[Yesterday at] LT", - lastWeek: "[last] dddd [at] LT", - sameElse: "L" - }, - relativeTime: { - future: "in %s", - past: "%s ago", - s: "a few seconds", - m: "a minute", - mm: "%d minutes", - h: "an hour", - hh: "%d hours", - d: "a day", - dd: "%d days", - M: "a month", - MM: "%d months", - y: "a year", - yy: "%d years" - }, - ordinal: function(a) { - var b = a % 10; - return ~~(a % 100 / 10) === 1 ? "th" : b === 1 ? "st" : b === 2 ? "nd" : b === 3 ? "rd" : "th"; - } - }), b.fn = H.prototype = { - clone: function() { - return b(this); - }, - valueOf: function() { - return +this._d; - }, - unix: function() { - return Math.floor(+this._d / 1e3); - }, - toString: function() { - return this._d.toString(); - }, - toDate: function() { - return this._d; - }, - toArray: function() { - var a = this; - return [ a.year(), a.month(), a.date(), a.hours(), a.minutes(), a.seconds(), a.milliseconds(), !!this._isUTC ]; - }, - isValid: function() { - return this._a ? this._a[8] != null ? !!this._a[8] : !N(this._a, (this._a[7] ? b.utc(this._a) : b(this._a)).toArray()) : !isNaN(this._d.getTime()); - }, - utc: function() { - return this._isUTC = !0, this; - }, - local: function() { - return this._isUTC = !1, this; - }, - format: function(a) { - return T(this, a ? a : b.defaultFormat); - }, - add: function(a, c) { - var d = c ? b.duration(+c, a) : b.duration(a); - return L(this, d, 1), this; - }, - subtract: function(a, c) { - var d = c ? b.duration(+c, a) : b.duration(a); - return L(this, d, -1), this; - }, - diff: function(a, c, e) { - var f = this._isUTC ? b(a).utc() : b(a).local(), g = (this.zone() - f.zone()) * 6e4, h = this._d - f._d - g, i = this.year() - f.year(), j = this.month() - f.month(), k = this.date() - f.date(), l; - return c === "months" ? l = i * 12 + j + k / 30 : c === "years" ? l = i + (j + k / 30) / 12 : l = c === "seconds" ? h / 1e3 : c === "minutes" ? h / 6e4 : c === "hours" ? h / 36e5 : c === "days" ? h / 864e5 : c === "weeks" ? h / 6048e5 : h, e ? l : d(l); - }, - from: function(a, c) { - return b.duration(this.diff(a)).lang(this._lang).humanize(!c); - }, - fromNow: function(a) { - return this.from(b(), a); - }, - calendar: function() { - var a = this.diff(b().sod(), "days", !0), c = this.lang().calendar, d = c.sameElse, e = a < -6 ? d : a < -1 ? c.lastWeek : a < 0 ? c.lastDay : a < 1 ? c.sameDay : a < 2 ? c.nextDay : a < 7 ? c.nextWeek : d; - return this.format(typeof e == "function" ? e.apply(this) : e); - }, - isLeapYear: function() { - var a = this.year(); - return a % 4 === 0 && a % 100 !== 0 || a % 400 === 0; - }, - isDST: function() { - return this.zone() < b([ this.year() ]).zone() || this.zone() < b([ this.year(), 5 ]).zone(); - }, - day: function(a) { - var b = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - return a == null ? b : this.add({ - d: a - b - }); - }, - startOf: function(a) { - switch (a.replace(/s$/, "")) { - case "year": - this.month(0); - case "month": - this.date(1); - case "day": - this.hours(0); - case "hour": - this.minutes(0); - case "minute": - this.seconds(0); - case "second": - this.milliseconds(0); - } - return this; - }, - endOf: function(a) { - return this.startOf(a).add(a.replace(/s?$/, "s"), 1).subtract("ms", 1); - }, - sod: function() { - return this.clone().startOf("day"); - }, - eod: function() { - return this.clone().endOf("day"); - }, - zone: function() { - return this._isUTC ? 0 : this._d.getTimezoneOffset(); - }, - daysInMonth: function() { - return b.utc([ this.year(), this.month() + 1, 0 ]).date(); - }, - lang: function(b) { - return b === a ? Q(this) : (this._lang = b, this); - } - }; - for (e = 0; e < y.length; e++) _(y[e].toLowerCase(), y[e]); - _("year", "FullYear"), b.duration.fn = I.prototype = { - weeks: function() { - return J(this.days() / 7); - }, - valueOf: function() { - return this._milliseconds + this._days * 864e5 + this._months * 2592e6; - }, - humanize: function(a) { - var b = +this, c = this.lang().relativeTime, d = $(b, !a, this.lang()), e = b <= 0 ? c.past : c.future; - return a && (typeof e == "function" ? d = e(d) : d = e.replace(/%s/i, d)), d; - }, - lang: b.fn.lang - }; - for (e in z) z.hasOwnProperty(e) && (bb(e, z[e]), ab(e.toLowerCase())); - bb("Weeks", 6048e5), h && (module.exports = b), typeof ender == "undefined" && (this.moment = b), typeof define == "function" && define.amd && define("moment", [], function() { - return b; - }); -}).call(this); \ No newline at end of file diff --git a/api/node_modules/moment/moment.js b/api/node_modules/moment/moment.js deleted file mode 100644 index e6fa145aa43..00000000000 --- a/api/node_modules/moment/moment.js +++ /dev/null @@ -1,1213 +0,0 @@ -// moment.js -// version : 1.7.2 -// author : Tim Wood -// license : MIT -// momentjs.com - -(function (undefined) { - - /************************************ - Constants - ************************************/ - - var moment, - VERSION = "1.7.2", - round = Math.round, i, - // internal storage for language config files - languages = {}, - currentLanguage = 'en', - - // check for nodeJS - hasModule = (typeof module !== 'undefined' && module.exports), - - // Parameters to check for on the lang config. This list of properties - // will be inherited from English if not provided in a language - // definition. monthsParse is also a lang config property, but it - // cannot be inherited and as such cannot be enumerated here. - langConfigProperties = 'months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem'.split('|'), - - // ASP.NET json date format regex - aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, - - // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g, - - // parsing tokens - parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi, - - // parsing token regexes - parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 - parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 - parseTokenThreeDigits = /\d{3}/, // 000 - 999 - parseTokenFourDigits = /\d{1,4}/, // 0 - 9999 - parseTokenWord = /[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i, // any word characters or numbers - parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z - parseTokenT = /T/i, // T (ISO seperator) - - // preliminary iso regex - // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 - isoRegex = /^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/, - isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', - - // iso time formats and regexes - isoTimes = [ - ['HH:mm:ss.S', /T\d\d:\d\d:\d\d\.\d{1,3}/], - ['HH:mm:ss', /T\d\d:\d\d:\d\d/], - ['HH:mm', /T\d\d:\d\d/], - ['HH', /T\d\d/] - ], - - // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] - parseTimezoneChunker = /([\+\-]|\d\d)/gi, - - // getter and setter names - proxyGettersAndSetters = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), - unitMillisecondFactors = { - 'Milliseconds' : 1, - 'Seconds' : 1e3, - 'Minutes' : 6e4, - 'Hours' : 36e5, - 'Days' : 864e5, - 'Months' : 2592e6, - 'Years' : 31536e6 - }, - - // format function strings - formatFunctions = {}, - - // tokens to ordinalize and pad - ordinalizeTokens = 'DDD w M D d'.split(' '), - paddedTokens = 'M D H h m s w'.split(' '), - - /* - * moment.fn.format uses new Function() to create an inlined formatting function. - * Results are a 3x speed boost - * http://jsperf.com/momentjs-cached-format-functions - * - * These strings are appended into a function using replaceFormatTokens and makeFormatFunction - */ - formatTokenFunctions = { - // a = placeholder - // b = placeholder - // t = the current moment being formatted - // v = getValueAtKey function - // o = language.ordinal function - // p = leftZeroFill function - // m = language.meridiem value or function - M : function () { - return this.month() + 1; - }, - MMM : function (format) { - return getValueFromArray("monthsShort", this.month(), this, format); - }, - MMMM : function (format) { - return getValueFromArray("months", this.month(), this, format); - }, - D : function () { - return this.date(); - }, - DDD : function () { - var a = new Date(this.year(), this.month(), this.date()), - b = new Date(this.year(), 0, 1); - return ~~(((a - b) / 864e5) + 1.5); - }, - d : function () { - return this.day(); - }, - dd : function (format) { - return getValueFromArray("weekdaysMin", this.day(), this, format); - }, - ddd : function (format) { - return getValueFromArray("weekdaysShort", this.day(), this, format); - }, - dddd : function (format) { - return getValueFromArray("weekdays", this.day(), this, format); - }, - w : function () { - var a = new Date(this.year(), this.month(), this.date() - this.day() + 5), - b = new Date(a.getFullYear(), 0, 4); - return ~~((a - b) / 864e5 / 7 + 1.5); - }, - YY : function () { - return leftZeroFill(this.year() % 100, 2); - }, - YYYY : function () { - return leftZeroFill(this.year(), 4); - }, - a : function () { - return this.lang().meridiem(this.hours(), this.minutes(), true); - }, - A : function () { - return this.lang().meridiem(this.hours(), this.minutes(), false); - }, - H : function () { - return this.hours(); - }, - h : function () { - return this.hours() % 12 || 12; - }, - m : function () { - return this.minutes(); - }, - s : function () { - return this.seconds(); - }, - S : function () { - return ~~(this.milliseconds() / 100); - }, - SS : function () { - return leftZeroFill(~~(this.milliseconds() / 10), 2); - }, - SSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - Z : function () { - var a = -this.zone(), - b = "+"; - if (a < 0) { - a = -a; - b = "-"; - } - return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2); - }, - ZZ : function () { - var a = -this.zone(), - b = "+"; - if (a < 0) { - a = -a; - b = "-"; - } - return b + leftZeroFill(~~(10 * a / 6), 4); - } - }; - - function getValueFromArray(key, index, m, format) { - var lang = m.lang(); - return lang[key].call ? lang[key](m, format) : lang[key][index]; - } - - function padToken(func, count) { - return function (a) { - return leftZeroFill(func.call(this, a), count); - }; - } - function ordinalizeToken(func) { - return function (a) { - var b = func.call(this, a); - return b + this.lang().ordinal(b); - }; - } - - while (ordinalizeTokens.length) { - i = ordinalizeTokens.pop(); - formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]); - } - while (paddedTokens.length) { - i = paddedTokens.pop(); - formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); - } - formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); - - - /************************************ - Constructors - ************************************/ - - - // Moment prototype object - function Moment(date, isUTC, lang) { - this._d = date; - this._isUTC = !!isUTC; - this._a = date._a || null; - this._lang = lang || false; - } - - // Duration Constructor - function Duration(duration) { - var data = this._data = {}, - years = duration.years || duration.y || 0, - months = duration.months || duration.M || 0, - weeks = duration.weeks || duration.w || 0, - days = duration.days || duration.d || 0, - hours = duration.hours || duration.h || 0, - minutes = duration.minutes || duration.m || 0, - seconds = duration.seconds || duration.s || 0, - milliseconds = duration.milliseconds || duration.ms || 0; - - // representation for dateAddRemove - this._milliseconds = milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 36e5; // 1000 * 60 * 60 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = days + - weeks * 7; - // It is impossible translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = months + - years * 12; - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - seconds += absRound(milliseconds / 1000); - - data.seconds = seconds % 60; - minutes += absRound(seconds / 60); - - data.minutes = minutes % 60; - hours += absRound(minutes / 60); - - data.hours = hours % 24; - days += absRound(hours / 24); - - days += weeks * 7; - data.days = days % 30; - - months += absRound(days / 30); - - data.months = months % 12; - years += absRound(months / 12); - - data.years = years; - - this._lang = false; - } - - - /************************************ - Helpers - ************************************/ - - - function absRound(number) { - if (number < 0) { - return Math.ceil(number); - } else { - return Math.floor(number); - } - } - - // left zero fill a number - // see http://jsperf.com/left-zero-filling for performance comparison - function leftZeroFill(number, targetLength) { - var output = number + ''; - while (output.length < targetLength) { - output = '0' + output; - } - return output; - } - - // helper function for _.addTime and _.subtractTime - function addOrSubtractDurationFromMoment(mom, duration, isAdding) { - var ms = duration._milliseconds, - d = duration._days, - M = duration._months, - currentDate; - - if (ms) { - mom._d.setTime(+mom + ms * isAdding); - } - if (d) { - mom.date(mom.date() + d * isAdding); - } - if (M) { - currentDate = mom.date(); - mom.date(1) - .month(mom.month() + M * isAdding) - .date(Math.min(currentDate, mom.daysInMonth())); - } - } - - // check if is an array - function isArray(input) { - return Object.prototype.toString.call(input) === '[object Array]'; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if (~~array1[i] !== ~~array2[i]) { - diffs++; - } - } - return diffs + lengthDiff; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function dateFromArray(input, asUTC, hoursOffset, minutesOffset) { - var i, date, forValid = []; - for (i = 0; i < 7; i++) { - forValid[i] = input[i] = (input[i] == null) ? (i === 2 ? 1 : 0) : input[i]; - } - // we store whether we used utc or not in the input array - input[7] = forValid[7] = asUTC; - // if the parser flagged the input as invalid, we pass the value along - if (input[8] != null) { - forValid[8] = input[8]; - } - // add the offsets to the time to be parsed so that we can have a clean array - // for checking isValid - input[3] += hoursOffset || 0; - input[4] += minutesOffset || 0; - date = new Date(0); - if (asUTC) { - date.setUTCFullYear(input[0], input[1], input[2]); - date.setUTCHours(input[3], input[4], input[5], input[6]); - } else { - date.setFullYear(input[0], input[1], input[2]); - date.setHours(input[3], input[4], input[5], input[6]); - } - date._a = forValid; - return date; - } - - // Loads a language definition into the `languages` cache. The function - // takes a key and optionally values. If not in the browser and no values - // are provided, it will load the language file module. As a convenience, - // this function also returns the language values. - function loadLang(key, values) { - var i, m, - parse = []; - - if (!values && hasModule) { - values = require('./lang/' + key); - } - - for (i = 0; i < langConfigProperties.length; i++) { - // If a language definition does not provide a value, inherit - // from English - values[langConfigProperties[i]] = values[langConfigProperties[i]] || - languages.en[langConfigProperties[i]]; - } - - for (i = 0; i < 12; i++) { - m = moment([2000, i]); - parse[i] = new RegExp('^' + (values.months[i] || values.months(m, '')) + - '|^' + (values.monthsShort[i] || values.monthsShort(m, '')).replace('.', ''), 'i'); - } - values.monthsParse = values.monthsParse || parse; - - languages[key] = values; - - return values; - } - - // Determines which language definition to use and returns it. - // - // With no parameters, it will return the global language. If you - // pass in a language key, such as 'en', it will return the - // definition for 'en', so long as 'en' has already been loaded using - // moment.lang. If you pass in a moment or duration instance, it - // will decide the language based on that, or default to the global - // language. - function getLangDefinition(m) { - var langKey = (typeof m === 'string') && m || - m && m._lang || - null; - - return langKey ? (languages[langKey] || loadLang(langKey)) : moment; - } - - - /************************************ - Formatting - ************************************/ - - - function removeFormattingTokens(input) { - if (input.match(/\[.*\]/)) { - return input.replace(/^\[|\]$/g, ""); - } - return input.replace(/\\/g, ""); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = ""; - for (i = 0; i < length; i++) { - output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return m.lang().longDateFormat[input] || input; - } - - while (i-- && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - } - - if (!formatFunctions[format]) { - formatFunctions[format] = makeFormatFunction(format); - } - - return formatFunctions[format](m); - } - - - /************************************ - Parsing - ************************************/ - - - // get the regex to find the next token - function getParseRegexForToken(token) { - switch (token) { - case 'DDDD': - return parseTokenThreeDigits; - case 'YYYY': - return parseTokenFourDigits; - case 'S': - case 'SS': - case 'SSS': - case 'DDD': - return parseTokenOneToThreeDigits; - case 'MMM': - case 'MMMM': - case 'dd': - case 'ddd': - case 'dddd': - case 'a': - case 'A': - return parseTokenWord; - case 'Z': - case 'ZZ': - return parseTokenTimezone; - case 'T': - return parseTokenT; - case 'MM': - case 'DD': - case 'YY': - case 'HH': - case 'hh': - case 'mm': - case 'ss': - case 'M': - case 'D': - case 'd': - case 'H': - case 'h': - case 'm': - case 's': - return parseTokenOneOrTwoDigits; - default : - return new RegExp(token.replace('\\', '')); - } - } - - // function to convert string input to date - function addTimeToArrayFromToken(token, input, datePartArray, config) { - var a, b; - - switch (token) { - // MONTH - case 'M' : // fall through to MM - case 'MM' : - datePartArray[1] = (input == null) ? 0 : ~~input - 1; - break; - case 'MMM' : // fall through to MMMM - case 'MMMM' : - for (a = 0; a < 12; a++) { - if (getLangDefinition().monthsParse[a].test(input)) { - datePartArray[1] = a; - b = true; - break; - } - } - // if we didn't find a month name, mark the date as invalid. - if (!b) { - datePartArray[8] = false; - } - break; - // DAY OF MONTH - case 'D' : // fall through to DDDD - case 'DD' : // fall through to DDDD - case 'DDD' : // fall through to DDDD - case 'DDDD' : - if (input != null) { - datePartArray[2] = ~~input; - } - break; - // YEAR - case 'YY' : - datePartArray[0] = ~~input + (~~input > 70 ? 1900 : 2000); - break; - case 'YYYY' : - datePartArray[0] = ~~Math.abs(input); - break; - // AM / PM - case 'a' : // fall through to A - case 'A' : - config.isPm = ((input + '').toLowerCase() === 'pm'); - break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh - case 'h' : // fall through to hh - case 'hh' : - datePartArray[3] = ~~input; - break; - // MINUTE - case 'm' : // fall through to mm - case 'mm' : - datePartArray[4] = ~~input; - break; - // SECOND - case 's' : // fall through to ss - case 'ss' : - datePartArray[5] = ~~input; - break; - // MILLISECOND - case 'S' : - case 'SS' : - case 'SSS' : - datePartArray[6] = ~~ (('0.' + input) * 1000); - break; - // TIMEZONE - case 'Z' : // fall through to ZZ - case 'ZZ' : - config.isUTC = true; - a = (input + '').match(parseTimezoneChunker); - if (a && a[1]) { - config.tzh = ~~a[1]; - } - if (a && a[2]) { - config.tzm = ~~a[2]; - } - // reverse offsets - if (a && a[0] === '+') { - config.tzh = -config.tzh; - config.tzm = -config.tzm; - } - break; - } - - // if the input is null, the date is not valid - if (input == null) { - datePartArray[8] = false; - } - } - - // date from string and format string - function makeDateFromStringAndFormat(string, format) { - // This array is used to make a Date, either with `new Date` or `Date.UTC` - // We store some additional data on the array for validation - // datePartArray[7] is true if the Date was created with `Date.UTC` and false if created with `new Date` - // datePartArray[8] is false if the Date is invalid, and undefined if the validity is unknown. - var datePartArray = [0, 0, 1, 0, 0, 0, 0], - config = { - tzh : 0, // timezone hour offset - tzm : 0 // timezone minute offset - }, - tokens = format.match(formattingTokens), - i, parsedInput; - - for (i = 0; i < tokens.length; i++) { - parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0]; - if (parsedInput) { - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - } - // don't parse if its not a known token - if (formatTokenFunctions[tokens[i]]) { - addTimeToArrayFromToken(tokens[i], parsedInput, datePartArray, config); - } - } - // handle am pm - if (config.isPm && datePartArray[3] < 12) { - datePartArray[3] += 12; - } - // if is 12 am, change hours to 0 - if (config.isPm === false && datePartArray[3] === 12) { - datePartArray[3] = 0; - } - // return - return dateFromArray(datePartArray, config.isUTC, config.tzh, config.tzm); - } - - // date from string and array of format strings - function makeDateFromStringAndArray(string, formats) { - var output, - inputParts = string.match(parseMultipleFormatChunker) || [], - formattedInputParts, - scoreToBeat = 99, - i, - currentDate, - currentScore; - for (i = 0; i < formats.length; i++) { - currentDate = makeDateFromStringAndFormat(string, formats[i]); - formattedInputParts = formatMoment(new Moment(currentDate), formats[i]).match(parseMultipleFormatChunker) || []; - currentScore = compareArrays(inputParts, formattedInputParts); - if (currentScore < scoreToBeat) { - scoreToBeat = currentScore; - output = currentDate; - } - } - return output; - } - - // date from iso format - function makeDateFromString(string) { - var format = 'YYYY-MM-DDT', - i; - if (isoRegex.exec(string)) { - for (i = 0; i < 4; i++) { - if (isoTimes[i][1].exec(string)) { - format += isoTimes[i][0]; - break; - } - } - return parseTokenTimezone.exec(string) ? - makeDateFromStringAndFormat(string, format + ' Z') : - makeDateFromStringAndFormat(string, format); - } - return new Date(string); - } - - - /************************************ - Relative Time - ************************************/ - - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { - var rt = lang.relativeTime[string]; - return (typeof rt === 'function') ? - rt(number || 1, !!withoutSuffix, string, isFuture) : - rt.replace(/%d/i, number || 1); - } - - function relativeTime(milliseconds, withoutSuffix, lang) { - var seconds = round(Math.abs(milliseconds) / 1000), - minutes = round(seconds / 60), - hours = round(minutes / 60), - days = round(hours / 24), - years = round(days / 365), - args = seconds < 45 && ['s', seconds] || - minutes === 1 && ['m'] || - minutes < 45 && ['mm', minutes] || - hours === 1 && ['h'] || - hours < 22 && ['hh', hours] || - days === 1 && ['d'] || - days <= 25 && ['dd', days] || - days <= 45 && ['M'] || - days < 345 && ['MM', round(days / 30)] || - years === 1 && ['y'] || ['yy', years]; - args[2] = withoutSuffix; - args[3] = milliseconds > 0; - args[4] = lang; - return substituteTimeAgo.apply({}, args); - } - - - /************************************ - Top Level Functions - ************************************/ - - - moment = function (input, format) { - if (input === null || input === '') { - return null; - } - var date, - matched; - // parse Moment object - if (moment.isMoment(input)) { - return new Moment(new Date(+input._d), input._isUTC, input._lang); - // parse string and format - } else if (format) { - if (isArray(format)) { - date = makeDateFromStringAndArray(input, format); - } else { - date = makeDateFromStringAndFormat(input, format); - } - // evaluate it as a JSON-encoded date - } else { - matched = aspNetJsonRegex.exec(input); - date = input === undefined ? new Date() : - matched ? new Date(+matched[1]) : - input instanceof Date ? input : - isArray(input) ? dateFromArray(input) : - typeof input === 'string' ? makeDateFromString(input) : - new Date(input); - } - - return new Moment(date); - }; - - // creating with utc - moment.utc = function (input, format) { - if (isArray(input)) { - return new Moment(dateFromArray(input, true), true); - } - // if we don't have a timezone, we need to add one to trigger parsing into utc - if (typeof input === 'string' && !parseTokenTimezone.exec(input)) { - input += ' +0000'; - if (format) { - format += ' Z'; - } - } - return moment(input, format).utc(); - }; - - // creating with unix timestamp (in seconds) - moment.unix = function (input) { - return moment(input * 1000); - }; - - // duration - moment.duration = function (input, key) { - var isDuration = moment.isDuration(input), - isNumber = (typeof input === 'number'), - duration = (isDuration ? input._data : (isNumber ? {} : input)), - ret; - - if (isNumber) { - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } - - ret = new Duration(duration); - - if (isDuration) { - ret._lang = input._lang; - } - - return ret; - }; - - // humanizeDuration - // This method is deprecated in favor of the new Duration object. Please - // see the moment.duration method. - moment.humanizeDuration = function (num, type, withSuffix) { - return moment.duration(num, type === true ? null : type).humanize(type === true ? true : withSuffix); - }; - - // version number - moment.version = VERSION; - - // default format - moment.defaultFormat = isoFormat; - - // This function will load languages and then set the global language. If - // no arguments are passed in, it will simply return the current global - // language key. - moment.lang = function (key, values) { - var i; - - if (!key) { - return currentLanguage; - } - if (values || !languages[key]) { - loadLang(key, values); - } - if (languages[key]) { - // deprecated, to get the language definition variables, use the - // moment.fn.lang method or the getLangDefinition function. - for (i = 0; i < langConfigProperties.length; i++) { - moment[langConfigProperties[i]] = languages[key][langConfigProperties[i]]; - } - moment.monthsParse = languages[key].monthsParse; - currentLanguage = key; - } - }; - - // returns language data - moment.langData = getLangDefinition; - - // compare moment object - moment.isMoment = function (obj) { - return obj instanceof Moment; - }; - - // for typechecking Duration objects - moment.isDuration = function (obj) { - return obj instanceof Duration; - }; - - // Set default language, other languages will inherit from English. - moment.lang('en', { - months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), - longDateFormat : { - LT : "h:mm A", - L : "MM/DD/YYYY", - LL : "MMMM D YYYY", - LLL : "MMMM D YYYY LT", - LLLL : "dddd, MMMM D YYYY LT" - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" - }, - ordinal : function (number) { - var b = number % 10; - return (~~ (number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - } - }); - - - /************************************ - Moment Prototype - ************************************/ - - - moment.fn = Moment.prototype = { - - clone : function () { - return moment(this); - }, - - valueOf : function () { - return +this._d; - }, - - unix : function () { - return Math.floor(+this._d / 1000); - }, - - toString : function () { - return this._d.toString(); - }, - - toDate : function () { - return this._d; - }, - - toArray : function () { - var m = this; - return [ - m.year(), - m.month(), - m.date(), - m.hours(), - m.minutes(), - m.seconds(), - m.milliseconds(), - !!this._isUTC - ]; - }, - - isValid : function () { - if (this._a) { - // if the parser finds that the input is invalid, it sets - // the eighth item in the input array to false. - if (this._a[8] != null) { - return !!this._a[8]; - } - return !compareArrays(this._a, (this._a[7] ? moment.utc(this._a) : moment(this._a)).toArray()); - } - return !isNaN(this._d.getTime()); - }, - - utc : function () { - this._isUTC = true; - return this; - }, - - local : function () { - this._isUTC = false; - return this; - }, - - format : function (inputString) { - return formatMoment(this, inputString ? inputString : moment.defaultFormat); - }, - - add : function (input, val) { - var dur = val ? moment.duration(+val, input) : moment.duration(input); - addOrSubtractDurationFromMoment(this, dur, 1); - return this; - }, - - subtract : function (input, val) { - var dur = val ? moment.duration(+val, input) : moment.duration(input); - addOrSubtractDurationFromMoment(this, dur, -1); - return this; - }, - - diff : function (input, val, asFloat) { - var inputMoment = this._isUTC ? moment(input).utc() : moment(input).local(), - zoneDiff = (this.zone() - inputMoment.zone()) * 6e4, - diff = this._d - inputMoment._d - zoneDiff, - year = this.year() - inputMoment.year(), - month = this.month() - inputMoment.month(), - date = this.date() - inputMoment.date(), - output; - if (val === 'months') { - output = year * 12 + month + date / 30; - } else if (val === 'years') { - output = year + (month + date / 30) / 12; - } else { - output = val === 'seconds' ? diff / 1e3 : // 1000 - val === 'minutes' ? diff / 6e4 : // 1000 * 60 - val === 'hours' ? diff / 36e5 : // 1000 * 60 * 60 - val === 'days' ? diff / 864e5 : // 1000 * 60 * 60 * 24 - val === 'weeks' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7 - diff; - } - return asFloat ? output : round(output); - }, - - from : function (time, withoutSuffix) { - return moment.duration(this.diff(time)).lang(this._lang).humanize(!withoutSuffix); - }, - - fromNow : function (withoutSuffix) { - return this.from(moment(), withoutSuffix); - }, - - calendar : function () { - var diff = this.diff(moment().sod(), 'days', true), - calendar = this.lang().calendar, - allElse = calendar.sameElse, - format = diff < -6 ? allElse : - diff < -1 ? calendar.lastWeek : - diff < 0 ? calendar.lastDay : - diff < 1 ? calendar.sameDay : - diff < 2 ? calendar.nextDay : - diff < 7 ? calendar.nextWeek : allElse; - return this.format(typeof format === 'function' ? format.apply(this) : format); - }, - - isLeapYear : function () { - var year = this.year(); - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - }, - - isDST : function () { - return (this.zone() < moment([this.year()]).zone() || - this.zone() < moment([this.year(), 5]).zone()); - }, - - day : function (input) { - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - return input == null ? day : - this.add({ d : input - day }); - }, - - startOf: function (val) { - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (val.replace(/s$/, '')) { - case 'year': - this.month(0); - /* falls through */ - case 'month': - this.date(1); - /* falls through */ - case 'day': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - /* falls through */ - } - return this; - }, - - endOf: function (val) { - return this.startOf(val).add(val.replace(/s?$/, 's'), 1).subtract('ms', 1); - }, - - sod: function () { - return this.clone().startOf('day'); - }, - - eod: function () { - // end of day = start of day plus 1 day, minus 1 millisecond - return this.clone().endOf('day'); - }, - - zone : function () { - return this._isUTC ? 0 : this._d.getTimezoneOffset(); - }, - - daysInMonth : function () { - return moment.utc([this.year(), this.month() + 1, 0]).date(); - }, - - // If passed a language key, it will set the language for this - // instance. Otherwise, it will return the language configuration - // variables for this instance. - lang : function (lang) { - if (lang === undefined) { - return getLangDefinition(this); - } else { - this._lang = lang; - return this; - } - } - }; - - // helper for adding shortcuts - function makeGetterAndSetter(name, key) { - moment.fn[name] = function (input) { - var utc = this._isUTC ? 'UTC' : ''; - if (input != null) { - this._d['set' + utc + key](input); - return this; - } else { - return this._d['get' + utc + key](); - } - }; - } - - // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) - for (i = 0; i < proxyGettersAndSetters.length; i ++) { - makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase(), proxyGettersAndSetters[i]); - } - - // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') - makeGetterAndSetter('year', 'FullYear'); - - - /************************************ - Duration Prototype - ************************************/ - - - moment.duration.fn = Duration.prototype = { - weeks : function () { - return absRound(this.days() / 7); - }, - - valueOf : function () { - return this._milliseconds + - this._days * 864e5 + - this._months * 2592e6; - }, - - humanize : function (withSuffix) { - var difference = +this, - rel = this.lang().relativeTime, - output = relativeTime(difference, !withSuffix, this.lang()), - fromNow = difference <= 0 ? rel.past : rel.future; - - if (withSuffix) { - if (typeof fromNow === 'function') { - output = fromNow(output); - } else { - output = fromNow.replace(/%s/i, output); - } - } - - return output; - }, - - lang : moment.fn.lang - }; - - function makeDurationGetter(name) { - moment.duration.fn[name] = function () { - return this._data[name]; - }; - } - - function makeDurationAsGetter(name, factor) { - moment.duration.fn['as' + name] = function () { - return +this / factor; - }; - } - - for (i in unitMillisecondFactors) { - if (unitMillisecondFactors.hasOwnProperty(i)) { - makeDurationAsGetter(i, unitMillisecondFactors[i]); - makeDurationGetter(i.toLowerCase()); - } - } - - makeDurationAsGetter('Weeks', 6048e5); - - - /************************************ - Exposing Moment - ************************************/ - - - // CommonJS module is defined - if (hasModule) { - module.exports = moment; - } - /*global ender:false */ - if (typeof ender === 'undefined') { - // here, `this` means `window` in the browser, or `global` on the server - // add `moment` as a global object via a string identifier, - // for Closure Compiler "advanced" mode - this['moment'] = moment; - } - /*global define:false */ - if (typeof define === "function" && define.amd) { - define("moment", [], function () { - return moment; - }); - } -}).call(this); diff --git a/api/node_modules/moment/package.json b/api/node_modules/moment/package.json deleted file mode 100644 index ef4ef10bc73..00000000000 --- a/api/node_modules/moment/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "moment", - "version": "1.7.2", - "description": "Parse, manipulate, and display dates.", - "homepage": "http://momentjs.com", - "author": { - "name": "Tim Wood", - "email": "washwithcare@gmail.com", - "url": "http://timwoodcreates.com/" - }, - "contributors": [ - { - "name": "Rocky Meza", - "url": "http://rockymeza.com" - } - ], - "keywords": [ - "moment", - "date", - "time", - "parse", - "format", - "validate", - "i18n", - "l10n", - "ender" - ], - "main": "./moment.js", - "engines": { - "node": "*" - }, - "repository": { - "type": "git", - "url": "https://github.com/timrwood/moment.git" - }, - "bugs": { - "url": "https://github.com/timrwood/moment/issues" - }, - "licenses": [ - { - "type": "MIT" - } - ], - "devDependencies": { - "jshint": "latest", - "uglify-js": "latest", - "nodeunit": "latest" - }, - "scripts": { - "test": "make test" - }, - "ender": "./ender.js", - "readme": "[Moment.js](http://momentjs.com)\n================================\n\nA lightweight javascript date library for parsing, validating, manipulating, and formatting dates.\n\n### [Check out the website](http://momentjs.com)\n\n### [Read the documentation](http://momentjs.com/docs/)\n\n### [Run the unit tests](http://momentjs.com/test/)\n\n\nUpgrading to 1.6.0\n==================\n\nThere are a few things being deprecated in the 1.6.0 release.\n\n1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.\n\n2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.\n\n3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).\n\n\nChangelog\n=========\n\n\n### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)\n\nAdded `moment.fn.endOf()` and `moment.fn.startOf()`.\n\nAdded validation via `moment.fn.isValid()`.\n\nMade formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions\n\nAdd support for month/weekday callbacks in `moment.fn.format()`\n\nAdded instance specific languages.\n\nAdded two letter weekday abbreviations with the formatting token `dd`.\n\nVarious language updates.\n\nVarious bugfixes.\n\n### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)\n\nAdded Durations.\n\nRevamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).\n\nAdded support for millisecond parsing and formatting tokens (S SS SSS)\n\nAdded a getter for `moment.lang()`\n\nVarious bugfixes.\n\n### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)\n\nAdded UTC mode.\n\nAdded automatic ISO8601 parsing.\n\nVarious bugfixes.\n\n### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)\n\nAdded `moment.fn.toDate` as a replacement for `moment.fn.native`.\n\nAdded `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.\n\nVarious bugfixes.\n\n### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)\n\nAdded support for parsing month names in the current language.\n\nAdded escape blocks for parsing tokens.\n\nAdded `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.\n\nAdded `moment.fn.day` as a setter.\n\nVarious bugfixes\n\n### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)\n\nAdded timezones to parser and formatter.\n\nAdded `moment.fn.isDST`.\n\nAdded `moment.fn.zone` to get the timezone offset in minutes.\n\n### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)\n\nVarious bugfixes\n\n### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)\n\nAdded time specific diffs (months, days, hours, etc)\n\n### 1.1.0\n\nAdded `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)\n\nFixed [issue 31](https://github.com/timrwood/moment/pull/31).\n\n### 1.0.1\n\nAdded `moment.version` to get the current version.\n\nRemoved `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)\n\n### 1.0.0\n\nAdded convenience methods for getting and setting date parts.\n\nAdded better support for `moment.add()`.\n\nAdded better lang support in NodeJS.\n\nRenamed library from underscore.date to Moment.js\n\n### 0.6.1\n\nAdded Portuguese, Italian, and French language support\n\n### 0.6.0\n\nAdded _date.lang() support.\nAdded support for passing multiple formats to try to parse a date. _date(\"07-10-1986\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nMade parse from string and single format 25% faster.\n\n### 0.5.2\n\nBuxfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).\n\n### 0.5.1\n\nBuxfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).\n\n### 0.5.0\n\nDropped the redundant `_date.date()` in favor of `_date()`.\nRemoved `_date.now()`, as it is a duplicate of `_date()` with no parameters.\nRemoved `_date.isLeapYear(yearNuumber)`. Use `_date([yearNumber]).isLeapYear()` instead.\nExposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.\n\n### 0.4.1\n\nAdded date input formats for input strings.\n\n### 0.4.0\n\nAdded underscore.date to npm. Removed dependancies on underscore.\n\n### 0.3.2\n\nAdded `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.\n\n### 0.3.1\n\nCleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.\n\n### 0.3.0\n\nSwitched to the Underscore methodology of not mucking with the native objects' prototypes.\nMade chaining possible.\n\n### 0.2.1\n\nChanged date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.\nAdded `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.\n\n### 0.2.0\n\nChanged function names to be more concise.\nChanged date format from php date format to custom format.\n\n### 0.1.0\n\nInitial release\n\nLicense\n=======\n\nMoment.js is freely distributable under the terms of the MIT license.\n\nCopyright (c) 2011-2012 Tim Wood\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "readme.md", - "_id": "moment@1.7.2", - "_from": "moment" -} diff --git a/api/node_modules/moment/readme.md b/api/node_modules/moment/readme.md deleted file mode 100644 index 4c3b61074fc..00000000000 --- a/api/node_modules/moment/readme.md +++ /dev/null @@ -1,198 +0,0 @@ -[Moment.js](http://momentjs.com) -================================ - -A lightweight javascript date library for parsing, validating, manipulating, and formatting dates. - -### [Check out the website](http://momentjs.com) - -### [Read the documentation](http://momentjs.com/docs/) - -### [Run the unit tests](http://momentjs.com/test/) - - -Upgrading to 1.6.0 -================== - -There are a few things being deprecated in the 1.6.0 release. - -1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background. - -2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances. - -3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222). - - -Changelog -========= - - -### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288) - -Added `moment.fn.endOf()` and `moment.fn.startOf()`. - -Added validation via `moment.fn.isValid()`. - -Made formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions - -Add support for month/weekday callbacks in `moment.fn.format()` - -Added instance specific languages. - -Added two letter weekday abbreviations with the formatting token `dd`. - -Various language updates. - -Various bugfixes. - -### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268) - -Added Durations. - -Revamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD). - -Added support for millisecond parsing and formatting tokens (S SS SSS) - -Added a getter for `moment.lang()` - -Various bugfixes. - -### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed) - -Added UTC mode. - -Added automatic ISO8601 parsing. - -Various bugfixes. - -### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed) - -Added `moment.fn.toDate` as a replacement for `moment.fn.native`. - -Added `moment.fn.sod` and `moment.fn.eod` to get the start and end of day. - -Various bugfixes. - -### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed) - -Added support for parsing month names in the current language. - -Added escape blocks for parsing tokens. - -Added `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'. - -Added `moment.fn.day` as a setter. - -Various bugfixes - -### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed) - -Added timezones to parser and formatter. - -Added `moment.fn.isDST`. - -Added `moment.fn.zone` to get the timezone offset in minutes. - -### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed) - -Various bugfixes - -### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed) - -Added time specific diffs (months, days, hours, etc) - -### 1.1.0 - -Added `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29) - -Fixed [issue 31](https://github.com/timrwood/moment/pull/31). - -### 1.0.1 - -Added `moment.version` to get the current version. - -Removed `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25) - -### 1.0.0 - -Added convenience methods for getting and setting date parts. - -Added better support for `moment.add()`. - -Added better lang support in NodeJS. - -Renamed library from underscore.date to Moment.js - -### 0.6.1 - -Added Portuguese, Italian, and French language support - -### 0.6.0 - -Added _date.lang() support. -Added support for passing multiple formats to try to parse a date. _date("07-10-1986", ["MM-DD-YYYY", "YYYY-MM-DD"]); -Made parse from string and single format 25% faster. - -### 0.5.2 - -Buxfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9). - -### 0.5.1 - -Buxfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5). - -### 0.5.0 - -Dropped the redundant `_date.date()` in favor of `_date()`. -Removed `_date.now()`, as it is a duplicate of `_date()` with no parameters. -Removed `_date.isLeapYear(yearNuumber)`. Use `_date([yearNumber]).isLeapYear()` instead. -Exposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function. - -### 0.4.1 - -Added date input formats for input strings. - -### 0.4.0 - -Added underscore.date to npm. Removed dependancies on underscore. - -### 0.3.2 - -Added `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes. - -### 0.3.1 - -Cleaned up the namespace. Moved all date manipulation and display functions to the _.date() object. - -### 0.3.0 - -Switched to the Underscore methodology of not mucking with the native objects' prototypes. -Made chaining possible. - -### 0.2.1 - -Changed date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'. -Added `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`. - -### 0.2.0 - -Changed function names to be more concise. -Changed date format from php date format to custom format. - -### 0.1.0 - -Initial release - -License -======= - -Moment.js is freely distributable under the terms of the MIT license. - -Copyright (c) 2011-2012 Tim Wood - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/api/node_modules/moment/test/filesize-diff.js b/api/node_modules/moment/test/filesize-diff.js deleted file mode 100644 index 6c18e3ea03c..00000000000 --- a/api/node_modules/moment/test/filesize-diff.js +++ /dev/null @@ -1,55 +0,0 @@ -var https = require("https"), - zlib = require('zlib'), - path = require('path'), - fs = require('fs'); - - -var stable = '1.6.2'; - -function getVersion(path, cb) { - var data = '', - - req = https.request({ - host: 'raw.github.com', - port: 443, - path: '/timrwood/moment/' + path - }, function(res) { - res.setEncoding('utf8'); - res.on('data', function (chunk) { - data += chunk; - }); - res.on('end', function(e) { - zlib.gzip(data, function(error, result) { - cb(data.length, result.length); - }); - }); - }); - req.on('error', function(e) { - console.log('problem with request: ' + e.message); - }); - req.end(); -} - -function printDiffs(stableLen, stableGzip, currentLen, currentGzip) { - var diff = currentLen - stableLen, - gzipDiff = currentGzip - stableGzip; - - console.log("Filesize difference from current branch to " + stable); - console.log(stable + " " + stableLen + ' / ' + stableGzip); - console.log("curr " + currentLen + ' / ' + currentGzip); - console.log("diff " + (diff > 0 ? '+' : '') + diff); - console.log("gzip " + (gzipDiff > 0 ? '+' : '') + gzipDiff); -} - -(function(){ - fs.readFile(path.normalize(__dirname + '/../min/moment.min.js'), 'utf8', function(err, data){ - if (err) { - throw err; - } - zlib.gzip(data, function(error, result) { - getVersion(stable + '/min/moment.min.js', function (stableLength, stableGzipLength) { - printDiffs(stableLength, stableGzipLength, data.length, result.length); - }); - }); - }); -}()); \ No newline at end of file diff --git a/api/node_modules/moment/test/filesize-history.js b/api/node_modules/moment/test/filesize-history.js deleted file mode 100644 index f78f1fb89d2..00000000000 --- a/api/node_modules/moment/test/filesize-history.js +++ /dev/null @@ -1,108 +0,0 @@ -var https = require("https"), - zlib = require('zlib'), - path = require('path'), - fs = require('fs'); - -var count = 0; -var resolved = 0; - -var outputs = []; - -function check() { - if (resolved === count) { - normalize(); - display(); - } -} - -function makeBar(length) { - var i = ''; - while (i.length < length) { - i += '='; - } - return i; -} - -function normalize() { - var i, - max = 0, - max2 = 0; - for (i = 0; i < count; i ++) { - max = Math.max(max, outputs[i].gzip); - max2 = Math.max(max2, outputs[i].original); - } - for (i = 0; i < count; i ++) { - outputs[i].bargraph = makeBar((outputs[i].gzip / max) * 80); - outputs[i].bargraph2 = makeBar((outputs[i].original / max2) * 80); - } -} - -function display() { - var i; - for (i = 0; i < count; i ++) { - console.log(outputs[i].version + ' ' + outputs[i].gzip + ' ' + outputs[i].original); - console.log('gzip ' + outputs[i].bargraph); - console.log('orig ' + outputs[i].bargraph2); - } -} - -function getSizeAtVersion(version, path) { - var data = ''; - var op = {}; - - var req = https.request({ - host: 'raw.github.com', - port: 443, - path: '/timrwood/moment/' + version + path - }, function(res) { - res.setEncoding('utf8'); - res.on('data', function (chunk) { - data += chunk; - }); - res.on('end', function(e) { - zlib.gzip(data, function(error, result) { - op.version = version; - op.gzip = result.length; - op.original = data.length; - resolved ++; - check(); - }); - }); - }); - - req.on('error', function(e) { - console.log('problem with request: ' + e.message); - }); - req.end(); - count++; - outputs.push(op); -} - -(function(){ - var old_versions = '1.0.1 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.4.0'.split(' '); - var new_versions = '1.5.0 1.5.1 1.6.0 1.6.1'.split(' '); - var i; - - for (i = 0; i < old_versions.length; i++) { - getSizeAtVersion(old_versions[i], '/moment.min.js'); - } - for (i = 0; i < new_versions.length; i++) { - getSizeAtVersion(new_versions[i], '/min/moment.min.js'); - } -}()); - -(function(){ - count ++; - var op = {}; - outputs.push(op); - fs.readFile(path.normalize(__dirname + '/../min/moment.min.js'), 'utf8', function(err, data){ - if (err) throw err; - zlib.gzip(data, function(error, result) { - op.version = '.next'; - op.gzip = result.length; - op.original = data.length; - resolved ++; - check(); - }); - }); -}()); \ No newline at end of file diff --git a/api/node_modules/moment/test/lang/bg.js b/api/node_modules/moment/test/lang/bg.js deleted file mode 100644 index 732d84f60f1..00000000000 --- a/api/node_modules/moment/test/lang/bg.js +++ /dev/null @@ -1,265 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Bulgarian - *************************************************/ - -exports["lang:bg"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('bg'); - var tests = 'Ñнуари Ñнр_февруари фев_март мар_април апр_май май_юни юни_юли юли_авгуÑÑ‚ авг_Ñептември Ñеп_октомври окт_ноември ное_декември дек'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('bg'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'неделÑ, февруари 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'нед, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 февруари фев'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. Ð½ÐµÐ´ÐµÐ»Ñ Ð½ÐµÐ´ нд'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '14.02.2010'], - ['LL', '14 февруари 2010'], - ['LLL', '14 февруари 2010 3:25'], - ['LLLL', 'неделÑ, 14 февруари 2010 3:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('bg'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('bg'); - var expected = 'Ñнуари Ñнр_февруари фев_март мар_април апр_май май_юни юни_юли юли_авгуÑÑ‚ авг_Ñептември Ñеп_октомври окт_ноември ное_декември дек'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('bg'); - var expected = 'Ð½ÐµÐ´ÐµÐ»Ñ Ð½ÐµÐ´ нд_понеделник пон пн_вторник вто вт_ÑÑ€Ñда ÑÑ€Ñ ÑÑ€_четвъртък чет чт_петък пет пт_Ñъбота Ñъб Ñб'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('bg'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "нÑколко Ñекунди", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "минута", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "минута", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 минути", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 минути", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "чаÑ", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "чаÑ", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 чаÑа", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 чаÑа", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 чаÑа", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "ден", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "ден", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 дни", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "ден", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 дни", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 дни", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "меÑец", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "меÑец", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "меÑец", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 меÑеца", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 меÑеца", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 меÑеца", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "меÑец", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 меÑеца", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 меÑеца", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "година", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "година", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 години", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "година", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 години", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('bg'); - test.equal(moment(30000).from(0), "Ñлед нÑколко Ñекунди", "prefix"); - test.equal(moment(0).from(30000), "преди нÑколко Ñекунди", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('bg'); - test.equal(moment().fromNow(), "преди нÑколко Ñекунди", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('bg'); - test.equal(moment().add({s:30}).fromNow(), "Ñлед нÑколко Ñекунди", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "Ñлед 5 дни", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('bg'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Ð”Ð½ÐµÑ Ð² 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Ð”Ð½ÐµÑ Ð² 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Ð”Ð½ÐµÑ Ð² 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Утре в 2:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Ð”Ð½ÐµÑ Ð² 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Вчера в 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('bg'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [в] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [в] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [в] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('bg'); - - var i; - var m; - - function makeFormat(d) { - switch (d.day()) { - case 0: - case 3: - case 6: - return '[Ð’ изминалата] dddd [в] LT'; - case 1: - case 2: - case 4: - case 5: - return '[Ð’ изминалиÑ] dddd [в] LT'; - } - } - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('bg'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/ca.js b/api/node_modules/moment/test/lang/ca.js deleted file mode 100644 index ac7377d08e3..00000000000 --- a/api/node_modules/moment/test/lang/ca.js +++ /dev/null @@ -1,221 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Català - *************************************************/ - -exports["lang:ca"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('ca'); - - var tests = "Gener Gen._Febrer Febr._Març Mar._Abril Abr._Maig Mai._Juny Jun._Juliol Jul._Agost Ag._Setembre Set._Octubre Oct._Novembre Nov._Desembre Des.".split("_"); - - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('ca'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('ca'); - var expected = "Gener Gen._Febrer Febr._Març Mar._Abril Abr._Maig Mai._Juny Jun._Juliol Jul._Agost Ag._Setembre Set._Octubre Oct._Novembre Nov._Desembre Des.".split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('ca'); - var expected = "Diumenge Dg. Dg_Dilluns Dl. Dl_Dimarts Dt. Dt_Dimecres Dc. Dc_Dijous Dj. Dj_Divendres Dv. Dv_Dissabte Ds. Ds".split("_"); - - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('ca'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "uns segons", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "un minut", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "un minut", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minuts", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuts", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "una hora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "una hora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 hores", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 hores", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 hores", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un dia", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un dia", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dies", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un dia", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dies", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dies", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mes", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mes", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mes", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mesos", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mesos", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mesos", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mes", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mesos", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mesos", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "un any", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "un any", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 anys", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "un any", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 anys", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('ca'); - test.equal(moment(30000).from(0), "en uns segons", "prefix"); - test.equal(moment(0).from(30000), "fa uns segons", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('ca'); - test.equal(moment().fromNow(), "fa uns segons", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('ca'); - test.equal(moment().add({s:30}).fromNow(), "en uns segons", "en uns segons"); - test.equal(moment().add({d:5}).fromNow(), "en 5 dies", "en 5 dies"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(7); - moment.lang('ca'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "avui a les 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "avui a les 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "avui a les 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "demà a les 2:00", "tomorrow at the same time"); - test.equal(moment(a).add({ d: 1, h : -1 }).calendar(), "demà a la 1:00", "tomorrow minus 1 hour"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "avui a la 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "ahir a les 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('ca'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('ca'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('ca'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/cv.js b/api/node_modules/moment/test/lang/cv.js deleted file mode 100644 index 3de0f3354d3..00000000000 --- a/api/node_modules/moment/test/lang/cv.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Chuvash - *************************************************/ - -exports["lang:cv"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('cv'); - var tests = 'кăрлач кăр_Ð½Ð°Ñ€ÄƒÑ Ð½Ð°Ñ€_пуш пуш_ака ака_май май_çĕртме çĕр_утă утă_çурла çур_авăн ав_юпа юпа_чӳк чӳк_раштав раш'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('cv'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'вырÑарникун, Ð½Ð°Ñ€ÄƒÑ 14-мĕш 2010, 3:25:50 pm'], - ['ddd, hA', 'выр, 3PM'], - ['M Mo MM MMMM MMM', '2 2-мĕш 02 Ð½Ð°Ñ€ÄƒÑ Ð½Ð°Ñ€'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14-мĕш 14'], - ['d do dddd ddd dd', '0 0-мĕш вырÑарникун выр вр'], - ['DDD DDDo DDDD', '45 45-мĕш 045'], - ['w wo ww', '8 8-мĕш 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['Çулăн DDDo кунĕ', 'Çулăн 45-мĕш кунĕ'], - ['L', '14-02-2010'], - ['LL', '2010 çулхи Ð½Ð°Ñ€ÄƒÑ ÑƒÐ¹ÄƒÑ…Ä•Ð½ 14-мĕшĕ'], - ['LLL', '2010 çулхи Ð½Ð°Ñ€ÄƒÑ ÑƒÐ¹ÄƒÑ…Ä•Ð½ 14-мĕшĕ, 15:25'], - ['LLLL', 'вырÑарникун, 2010 çулхи Ð½Ð°Ñ€ÄƒÑ ÑƒÐ¹ÄƒÑ…Ä•Ð½ 14-мĕшĕ, 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('cv'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1-мĕш', '1-мĕш'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2-мĕш', '2-мĕш'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3-мĕш', '3-мĕш'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4-мĕш', '4-мĕш'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5-мĕш', '5-мĕш'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6-мĕш', '6-мĕш'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7-мĕш', '7-мĕш'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8-мĕш', '8-мĕш'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9-мĕш', '9-мĕш'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10-мĕш', '10-мĕш'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11-мĕш', '11-мĕш'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12-мĕш', '12-мĕш'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13-мĕш', '13-мĕш'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14-мĕш', '14-мĕш'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15-мĕш', '15-мĕш'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16-мĕш', '16-мĕш'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17-мĕш', '17-мĕш'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18-мĕш', '18-мĕш'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19-мĕш', '19-мĕш'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20-мĕш', '20-мĕш'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21-мĕш', '21-мĕш'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22-мĕш', '22-мĕш'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23-мĕш', '23-мĕш'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24-мĕш', '24-мĕш'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25-мĕш', '25-мĕш'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26-мĕш', '26-мĕш'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27-мĕш', '27-мĕш'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28-мĕш', '28-мĕш'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29-мĕш', '29-мĕш'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30-мĕш', '30-мĕш'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31-мĕш', '31-мĕш'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('cv'); - var expected = 'кăрлач кăр_Ð½Ð°Ñ€ÄƒÑ Ð½Ð°Ñ€_пуш пуш_ака ака_май май_çĕртме çĕр_утă утă_çурла çур_авăн ав_юпа юпа_чӳк чӳк_раштав раш'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('cv'); - var expected = 'вырÑарникун выр вр_тунтикун тун тн_ытларикун ытл Ñ‹Ñ‚_юнкун юн юн_кĕçнерникун кĕç кç_Ñрнекун Ñрн ÑÑ€_шăматкун шăм шм'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('cv'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "пĕр-ик çеккунт", "44 sekunder = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "пĕр минут", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "пĕр минут", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 минут", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 минут", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "пĕр Ñехет", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "пĕр Ñехет", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 Ñехет", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 Ñехет", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 Ñехет", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "пĕр кун", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "пĕр кун", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 кун", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "пĕр кун", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 кун", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 кун", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "пĕр уйăх", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "пĕр уйăх", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "пĕр уйăх", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 уйăх", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 уйăх", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 уйăх", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "пĕр уйăх", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 уйăх", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 уйăх", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "пĕр çул", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "пĕр çул", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 çул", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "пĕр çул", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 çул", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('cv'); - test.equal(moment(30000).from(0), "пĕр-ик çеккунтран", "prefix"); - test.equal(moment(0).from(30000), "пĕр-ик çеккунт каÑлла", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('cv'); - test.equal(moment().fromNow(), "пĕр-ик çеккунт каÑлла", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(4); - moment.lang('cv'); - test.equal(moment().add({s:30}).fromNow(), "пĕр-ик çеккунтран", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5 кунран", "in 5 days"); - test.equal(moment().add({h:2}).fromNow(), "2 Ñехетрен", "in 2 hours, the right suffix!"); - test.equal(moment().add({y:3}).fromNow(), "3 çултан", "in 3 years, the right suffix!"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('cv'); - var a = moment().hours(2).minutes(0).seconds(0); - test.equal(moment(a).calendar(), "ПаÑн 02:00 Ñехетре", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "ПаÑн 02:25 Ñехетре", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "ПаÑн 03:00 Ñехетре", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Ыран 02:00 Ñехетре", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "ПаÑн 01:00 Ñехетре", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Ĕнер 02:00 Ñехетре", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('cv'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[ÇитеÑ] dddd LT [Ñехетре]'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[ÇитеÑ] dddd LT [Ñехетре]'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[ÇитеÑ] dddd LT [Ñехетре]'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('cv'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[Иртнĕ] dddd LT [Ñехетре]'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[Иртнĕ] dddd LT [Ñехетре]'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[Иртнĕ] dddd LT [Ñехетре]'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('cv'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/da.js b/api/node_modules/moment/test/lang/da.js deleted file mode 100644 index 2bcf26c3e92..00000000000 --- a/api/node_modules/moment/test/lang/da.js +++ /dev/null @@ -1,183 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Danish - *************************************************/ - -exports["lang:da"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('da'); - var tests = 'Januar Jan_Februar Feb_Marts Mar_April Apr_Maj Maj_Juni Jun_Juli Jul_August Aug_September Sep_Oktober Okt_November Nov_December Dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('da'); - var a = [ - ['dddd \\den MMMM Do YYYY, h:mm:ss a', 'Søndag den Februar 14. 2010, 3:25:50 pm'], - ['ddd hA', 'Søn 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 Februar Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. Søndag Søn Sø'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['[den] DDDo \\d\\ag pÃ¥ Ã¥ret', 'den 45. dag pÃ¥ Ã¥ret'], - ['L', '14/02/2010'], - ['LL', '14 Februar 2010'], - ['LLL', '14 Februar 2010 3:25 PM'], - ['LLLL', 'Søndag 14. Februar, 2010 3:25 PM'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('da'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('da'); - var expected = 'Januar Jan_Februar Feb_Marts Mar_April Apr_Maj Maj_Juni Jun_Juli Jul_August Aug_September Sep_Oktober Okt_November Nov_December Dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('da'); - var expected = 'Søndag Søn Sø_Mandag Man Ma_Tirsdag Tir Ti_Onsdag Ons On_Torsdag Tor To_Fredag Fre Fr_Lørdag Lør Lø'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('da'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "fÃ¥ sekunder", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "minut", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "minut", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutter", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutter", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "time", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "time", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 timer", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 timer", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 timer", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "dag", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "dag", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dage", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "dag", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dage", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dage", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "mÃ¥nede", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "mÃ¥nede", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "mÃ¥nede", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mÃ¥neder", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mÃ¥neder", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mÃ¥neder", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "mÃ¥nede", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mÃ¥neder", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mÃ¥neder", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "Ã¥r", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "Ã¥r", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 Ã¥r", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "Ã¥r", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 Ã¥r", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('da'); - test.equal(moment(30000).from(0), "om fÃ¥ sekunder", "prefix"); - test.equal(moment(0).from(30000), "fÃ¥ sekunder siden", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('da'); - test.equal(moment().fromNow(), "fÃ¥ sekunder siden", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('da'); - test.equal(moment().add({s:30}).fromNow(), "om fÃ¥ sekunder", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "om 5 dage", "in 5 days"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/de.js b/api/node_modules/moment/test/lang/de.js deleted file mode 100644 index 59d5358924a..00000000000 --- a/api/node_modules/moment/test/lang/de.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - German - *************************************************/ - -exports["lang:de"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('de'); - var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('de'); - var a = [ - ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'], - ['ddd, hA', 'So., 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. Sonntag So. So'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '14.02.2010'], - ['LL', '14. Februar 2010'], - ['LLL', '14. Februar 2010 15:25 Uhr'], - ['LLLL', 'Sonntag, 14. Februar 2010 15:25 Uhr'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('de'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('de'); - var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('de'); - var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('de'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "ein paar Sekunden", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "einer Minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "einer Minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 Minuten", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 Minuten", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "einer Stunde", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "einer Stunde", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 Stunden", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 Stunden", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 Stunden", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "einem Tag", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "einem Tag", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 Tagen", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "einem Tag", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 Tagen", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 Tagen", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "einem Monat", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "einem Monat", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "einem Monat", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 Monaten", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 Monaten", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 Monaten", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "einem Monat", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 Monaten", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 Monaten", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "einem Jahr", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "einem Jahr", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 Jahren", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "einem Jahr", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 Jahren", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('de'); - test.equal(moment(30000).from(0), "in ein paar Sekunden", "prefix"); - test.equal(moment(0).from(30000), "vor ein paar Sekunden", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('de'); - test.equal(moment().add({s:30}).fromNow(), "in ein paar Sekunden", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "in 5 Tagen", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('de'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Heute um 2:00 Uhr", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Heute um 2:25 Uhr", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Heute um 3:00 Uhr", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Morgen um 2:00 Uhr", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Heute um 1:00 Uhr", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Gestern um 2:00 Uhr", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('de'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [um] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [um] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [um] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('de'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[letzten] dddd [um] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[letzten] dddd [um] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[letzten] dddd [um] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('de'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/en-ca.js b/api/node_modules/moment/test/lang/en-ca.js deleted file mode 100644 index d59de281db3..00000000000 --- a/api/node_modules/moment/test/lang/en-ca.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - English - *************************************************/ - -exports["lang:en-ca"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('en-ca'); - var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('en-ca'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Sunday, February 14th 2010, 3:25:50 pm'], - ['ddd, hA', 'Sun, 3PM'], - ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14th 14'], - ['d do dddd ddd dd', '0 0th Sunday Sun Su'], - ['DDD DDDo DDDD', '45 45th 045'], - ['w wo ww', '8 8th 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45th day of the year'], - ['L', '2010-02-14'], - ['LL', '14 February, 2010'], - ['LLL', '14 February, 2010 3:25 PM'], - ['LLLL', 'Sunday, 14 February, 2010 3:25 PM'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('en-gb'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('en-gb'); - var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('en-gb'); - var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('en-gb'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "a few seconds", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "a minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "a minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutes", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutes", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "an hour", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "an hour", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 hours", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 hours", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 hours", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "a day", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "a day", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 days", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "a day", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 days", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 days", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "a month", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "a month", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "a month", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 months", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 months", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 months", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "a month", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 months", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 months", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "a year", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "a year", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 years", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "a year", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 years", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('en-gb'); - test.equal(moment(30000).from(0), "in a few seconds", "prefix"); - test.equal(moment(0).from(30000), "a few seconds ago", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('en-gb'); - test.equal(moment().fromNow(), "a few seconds ago", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('en-gb'); - test.equal(moment().add({s:30}).fromNow(), "in a few seconds", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "in 5 days", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('en-gb'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Today at 2:00 AM", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Today at 2:25 AM", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Today at 3:00 AM", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Tomorrow at 2:00 AM", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Today at 1:00 AM", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Yesterday at 2:00 AM", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('en-gb'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('en-gb'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('en-gb'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/en-gb.js b/api/node_modules/moment/test/lang/en-gb.js deleted file mode 100644 index 6641b813097..00000000000 --- a/api/node_modules/moment/test/lang/en-gb.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - English - *************************************************/ - -exports["lang:en-gb"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('en-gb'); - var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('en-gb'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Sunday, February 14th 2010, 3:25:50 pm'], - ['ddd, hA', 'Sun, 3PM'], - ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14th 14'], - ['d do dddd ddd dd', '0 0th Sunday Sun Su'], - ['DDD DDDo DDDD', '45 45th 045'], - ['w wo ww', '8 8th 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45th day of the year'], - ['L', '14/02/2010'], - ['LL', '14 February 2010'], - ['LLL', '14 February 2010 3:25 PM'], - ['LLLL', 'Sunday, 14 February 2010 3:25 PM'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('en-gb'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('en-gb'); - var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('en-gb'); - var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('en-gb'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "a few seconds", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "a minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "a minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutes", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutes", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "an hour", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "an hour", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 hours", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 hours", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 hours", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "a day", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "a day", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 days", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "a day", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 days", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 days", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "a month", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "a month", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "a month", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 months", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 months", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 months", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "a month", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 months", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 months", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "a year", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "a year", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 years", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "a year", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 years", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('en-gb'); - test.equal(moment(30000).from(0), "in a few seconds", "prefix"); - test.equal(moment(0).from(30000), "a few seconds ago", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('en-gb'); - test.equal(moment().fromNow(), "a few seconds ago", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('en-gb'); - test.equal(moment().add({s:30}).fromNow(), "in a few seconds", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "in 5 days", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('en-gb'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Today at 2:00 AM", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Today at 2:25 AM", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Today at 3:00 AM", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Tomorrow at 2:00 AM", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Today at 1:00 AM", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Yesterday at 2:00 AM", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('en-gb'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('en-gb'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('en-gb'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/en.js b/api/node_modules/moment/test/lang/en.js deleted file mode 100644 index 5f368b81161..00000000000 --- a/api/node_modules/moment/test/lang/en.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - English - *************************************************/ - -exports["lang:en"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('en'); - var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('en'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Sunday, February 14th 2010, 3:25:50 pm'], - ['ddd, hA', 'Sun, 3PM'], - ['M Mo MM MMMM MMM', '2 2nd 02 February Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14th 14'], - ['d do dddd ddd dd', '0 0th Sunday Sun Su'], - ['DDD DDDo DDDD', '45 45th 045'], - ['w wo ww', '8 8th 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45th day of the year'], - ['L', '02/14/2010'], - ['LL', 'February 14 2010'], - ['LLL', 'February 14 2010 3:25 PM'], - ['LLLL', 'Sunday, February 14 2010 3:25 PM'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('en'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('en'); - var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('en'); - var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('en'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "a few seconds", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "a minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "a minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutes", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutes", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "an hour", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "an hour", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 hours", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 hours", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 hours", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "a day", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "a day", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 days", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "a day", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 days", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 days", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "a month", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "a month", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "a month", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 months", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 months", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 months", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "a month", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 months", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 months", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "a year", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "a year", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 years", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "a year", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 years", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('en'); - test.equal(moment(30000).from(0), "in a few seconds", "prefix"); - test.equal(moment(0).from(30000), "a few seconds ago", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('en'); - test.equal(moment().fromNow(), "a few seconds ago", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('en'); - test.equal(moment().add({s:30}).fromNow(), "in a few seconds", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "in 5 days", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('en'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Today at 2:00 AM", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Today at 2:25 AM", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Today at 3:00 AM", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Tomorrow at 2:00 AM", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Today at 1:00 AM", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Yesterday at 2:00 AM", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('en'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [at] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('en'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[last] dddd [at] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('en'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/es.js b/api/node_modules/moment/test/lang/es.js deleted file mode 100644 index 53095f55a7c..00000000000 --- a/api/node_modules/moment/test/lang/es.js +++ /dev/null @@ -1,218 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Spanish - *************************************************/ - -exports["lang:es"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('es'); - var tests = 'Enero Ene._Febrero Feb._Marzo Mar._Abril Abr._Mayo May._Junio Jun._Julio Jul._Agosto Ago._Septiembre Sep._Octubre Oct._Noviembre Nov._Diciembre Dic.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('es'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('es'); - var expected = 'Enero Ene._Febrero Feb._Marzo Mar._Abril Abr._Mayo May._Junio Jun._Julio Jul._Agosto Ago._Septiembre Sep._Octubre Oct._Noviembre Nov._Diciembre Dic.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('es'); - var expected = 'Domingo Dom. Do_Lunes Lun. Lu_Martes Mar. Ma_Miércoles Mié. Mi_Jueves Jue. Ju_Viernes Vie. Vi_Sábado Sáb. Sá'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('es'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "unos segundos", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "un minuto", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "un minuto", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutos", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutos", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "una hora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "una hora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 horas", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 horas", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 horas", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un día", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un día", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 días", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un día", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 días", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 días", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mes", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mes", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mes", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 meses", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 meses", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 meses", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mes", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 meses", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 meses", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "un año", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "un año", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 años", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "un año", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 años", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('es'); - test.equal(moment(30000).from(0), "en unos segundos", "prefix"); - test.equal(moment(0).from(30000), "hace unos segundos", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('es'); - test.equal(moment().fromNow(), "hace unos segundos", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('es'); - test.equal(moment().add({s:30}).fromNow(), "en unos segundos", "en unos segundos"); - test.equal(moment().add({d:5}).fromNow(), "en 5 días", "en 5 días"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(7); - moment.lang('es'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "hoy a las 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "hoy a las 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "hoy a las 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "mañana a las 2:00", "tomorrow at the same time"); - test.equal(moment(a).add({ d: 1, h : -1 }).calendar(), "mañana a la 1:00", "tomorrow minus 1 hour"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "hoy a la 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "ayer a las 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('es'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('es'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('es'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/et.js b/api/node_modules/moment/test/lang/et.js deleted file mode 100644 index c33a445777a..00000000000 --- a/api/node_modules/moment/test/lang/et.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - English - *************************************************/ - -exports["lang:et"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('et'); - var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('et'); - var a = [ - ['dddd, Do MMMM YYYY, H:mm:ss', 'pühapäev, 14. veebruar 2010, 15:25:50'], - ['ddd, h', 'P, 3'], - ['M Mo MM MMMM MMM', '2 2. 02 veebruar veebr'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. pühapäev P P'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['\\a\\a\\st\\a DDDo päev', 'aasta 45. päev'], - ['L', '14.02.2010'], - ['LL', '14. veebruar 2010'], - ['LLL', '14. veebruar 2010 15:25'], - ['LLLL', 'pühapäev, 14. veebruar 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('et'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('et'); - var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('et'); - var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('et'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "paari sekundi", "44 seconds = paari sekundi"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "minut", "45 seconds = minut"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "minut", "89 seconds = minut"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutit", "90 seconds = 2 minutit"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutit", "44 minutes = 44 minutit"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "tund", "45 minutes = tund"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "tund", "89 minutes = tund"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 tundi", "90 minutes = 2 tundi"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 tundi", "5 hours = 5 tundi"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 tundi", "21 hours = 21 tundi"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "päev", "22 hours = päev"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "päev", "35 hours = päev"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 päeva", "36 hours = 2 päeva"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "päev", "1 day = päev"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 päeva", "5 days = 5 päeva"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 päeva", "25 days = 25 päeva"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "kuu", "26 days = kuu"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "kuu", "30 days = kuu"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "kuu", "45 days = kuu"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 kuud", "46 days = 2 kuud"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 kuud", "75 days = 2 kuud"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 kuud", "76 days = 3 kuud"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "kuu", "1 month = kuu"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 kuud", "5 months = 5 kuud"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 kuud", "344 days = 11 kuud"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "aasta", "345 days = aasta"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "aasta", "547 days = aasta"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 aastat", "548 days = 2 aastat"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "aasta", "1 year = aasta"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 aastat", "5 years = 5 aastat"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('et'); - test.equal(moment(30000).from(0), "paari sekundi pärast", "prefix"); - test.equal(moment(0).from(30000), "paar sekundit tagasi", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('et'); - test.equal(moment().fromNow(), "paar sekundit tagasi", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('et'); - test.equal(moment().add({s:30}).fromNow(), "paari sekundi pärast", "paari sekundi pärast"); - test.equal(moment().add({d:5}).fromNow(), "5 päeva pärast", "5 päeva pärast"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('et'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Täna, 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Täna, 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Täna, 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Homme, 2:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Täna, 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Eile, 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('et'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[Järgmine] dddd LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[Järgmine] dddd LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[Järgmine] dddd LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('et'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[Eelmine] dddd LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[Eelmine] dddd LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[Eelmine] dddd LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('en'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 nädal tagasi"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "1 nädala pärast"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 nädalat tagasi"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "2 nädala pärast"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/eu.js b/api/node_modules/moment/test/lang/eu.js deleted file mode 100644 index b701e46547d..00000000000 --- a/api/node_modules/moment/test/lang/eu.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Euskara - *************************************************/ - -exports["lang:eu"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('eu'); - var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('eu'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'igandea, otsaila 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'ig., 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 otsaila ots.'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. igandea ig. ig'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '2010-02-14'], - ['LL', '2010ko otsailaren 14a'], - ['LLL', '2010ko otsailaren 14a 15:25'], - ['LLLL', 'igandea, 2010ko otsailaren 14a 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('eu'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('eu'); - var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('eu'); - var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('eu'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "segundo batzuk", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "minutu bat", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "minutu bat", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutu", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutu", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "ordu bat", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "ordu bat", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 ordu", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 ordu", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 ordu", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "egun bat", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "egun bat", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 egun", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "egun bat", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 egun", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 egun", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "hilabete bat", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "hilabete bat", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "hilabete bat", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 hilabete", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 hilabete", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 hilabete", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "hilabete bat", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 hilabete", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 hilabete", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "urte bat", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "urte bat", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 urte", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "urte bat", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 urte", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('eu'); - test.equal(moment(30000).from(0), "segundo batzuk barru", "prefix"); - test.equal(moment(0).from(30000), "duela segundo batzuk", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('eu'); - test.equal(moment().fromNow(), "duela segundo batzuk", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('eu'); - test.equal(moment().add({s:30}).fromNow(), "segundo batzuk barru", "in seconds"); - test.equal(moment().add({d:5}).fromNow(), "5 egun barru", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('eu'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "gaur 02:00etan", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "gaur 02:25etan", "now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "gaur 03:00etan", "now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "bihar 02:00etan", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "gaur 01:00etan", "now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "atzo 02:00etan", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('eu'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd LT[etan]'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd LT[etan]'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd LT[etan]'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('eu'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[aurreko] dddd LT[etan]'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[aurreko] dddd LT[etan]'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[aurreko] dddd LT[etan]'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('eu'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/fi.js b/api/node_modules/moment/test/lang/fi.js deleted file mode 100644 index 6c83ff4c8c2..00000000000 --- a/api/node_modules/moment/test/lang/fi.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Finnish - *************************************************/ - -exports["lang:fi"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('fi'); - var tests = 'tammikuu tam_helmikuu hel_maaliskuu maa_huhtikuu huh_toukokuu tou_kesäkuu kes_heinäkuu hei_elokuu elo_syyskuu syys_lokakuu lok_marraskuu mar_joulukuu jou'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('fi'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'su, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 helmikuu hel'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. sunnuntai su su'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['vuo\\den DDDo päivä', 'vuoden 45. päivä'], - ['L', '14.02.2010'], - ['LL', '14. helmikuuta 2010'], - ['LLL', '14. helmikuuta 2010, klo 15.25'], - ['LLLL', 'sunnuntai, 14. helmikuuta 2010, klo 15.25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('fi'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('fi'); - var expected = 'tammikuu tam_helmikuu hel_maaliskuu maa_huhtikuu huh_toukokuu tou_kesäkuu kes_heinäkuu hei_elokuu elo_syyskuu syy_lokakuu lok_marraskuu mar_joulukuu jou'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('fi'); - var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('fi'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "muutama sekunti", "44 seconds = few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "minuutti", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "minuutti", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "kaksi minuuttia", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuuttia", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "tunti", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "tunti", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "kaksi tuntia", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "viisi tuntia", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 tuntia", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "päivä", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "päivä", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "kaksi päivää", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "päivä", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "viisi päivää", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 päivää", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "kuukausi", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "kuukausi", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "kuukausi", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "kaksi kuukautta", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "kaksi kuukautta", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "kolme kuukautta", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "kuukausi", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "viisi kuukautta", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 kuukautta", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "vuosi", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "vuosi", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "kaksi vuotta", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "vuosi", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "viisi vuotta", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('fi'); - test.equal(moment(30000).from(0), "muutaman sekunnin päästä", "prefix"); - test.equal(moment(0).from(30000), "muutama sekunti sitten", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('fi'); - test.equal(moment().fromNow(), "muutama sekunti sitten", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('fi'); - test.equal(moment().add({s:30}).fromNow(), "muutaman sekunnin päästä", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "viiden päivän päästä", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('fi'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "tänään klo 02.00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "tänään klo 02.25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "tänään klo 03.00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "huomenna klo 02.00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "tänään klo 01.00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "eilen klo 02.00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('fi'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [klo] LT'), "today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [klo] LT'), "today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [klo] LT'), "today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('fi'); - - for (var i = 2; i < 7; i++) { - var m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[viime] dddd[na] [klo] LT'), "today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[viime] dddd[na] [klo] LT'), "today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[viime] dddd[na] [klo] LT'), "today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('fi'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "yksi viikko sitten"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "yhden viikon päästä"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "kaksi viikkoa sitten"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "kaden viikon päästä"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/fr-ca.js b/api/node_modules/moment/test/lang/fr-ca.js deleted file mode 100644 index 83c165b8f38..00000000000 --- a/api/node_modules/moment/test/lang/fr-ca.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - French - *************************************************/ - -exports["lang:fr-ca"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('fr-ca'); - var tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('fr-ca'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14ème 2010, 3:25:50 pm'], - ['ddd, hA', 'dim., 3PM'], - ['M Mo MM MMMM MMM', '2 2ème 02 février févr.'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14ème 14'], - ['d do dddd ddd dd', '0 0ème dimanche dim. Di'], - ['DDD DDDo DDDD', '45 45ème 045'], - ['w wo ww', '8 8ème 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45ème day of the year'], - ['L', '2010-02-14'], - ['LL', '14 février 2010'], - ['LLL', '14 février 2010 15:25'], - ['LLLL', 'dimanche 14 février 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('fr'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2ème', '2ème'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3ème', '3ème'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4ème', '4ème'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5ème', '5ème'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6ème', '6ème'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7ème', '7ème'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8ème', '8ème'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9ème', '9ème'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10ème', '10ème'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11ème', '11ème'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12ème', '12ème'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13ème', '13ème'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14ème', '14ème'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15ème', '15ème'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16ème', '16ème'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17ème', '17ème'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18ème', '18ème'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19ème', '19ème'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20ème', '20ème'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21ème', '21ème'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22ème', '22ème'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23ème', '23ème'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24ème', '24ème'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25ème', '25ème'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26ème', '26ème'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27ème', '27ème'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28ème', '28ème'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29ème', '29ème'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30ème', '30ème'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31ème', '31ème'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('fr'); - var expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('fr'); - var expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('fr'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "quelques secondes", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "une minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "une minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutes", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutes", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "une heure", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "une heure", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 heures", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 heures", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 heures", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un jour", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un jour", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 jours", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un jour", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 jours", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 jours", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mois", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mois", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mois", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mois", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mois", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mois", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mois", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mois", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mois", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "une année", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "une année", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 années", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "une année", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 années", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('fr'); - test.equal(moment(30000).from(0), "dans quelques secondes", "prefix"); - test.equal(moment(0).from(30000), "il y a quelques secondes", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('fr'); - test.equal(moment().add({s:30}).fromNow(), "dans quelques secondes", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "dans 5 jours", "in 5 days"); - test.done(); - }, - - "same day" : function(test) { - test.expect(6); - moment.lang('fr'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Aujourd'hui à 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Aujourd'hui à 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Aujourd'hui à 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Demain à 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Aujourd'hui à 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Hier à 02:00", "yesterday at the same time"); - test.done(); - }, - - "same next week" : function(test) { - test.expect(15); - moment.lang('fr'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "same last week" : function(test) { - test.expect(15); - moment.lang('fr'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "same all else" : function(test) { - test.expect(4); - moment.lang('fr'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/fr.js b/api/node_modules/moment/test/lang/fr.js deleted file mode 100644 index 170bdb7a826..00000000000 --- a/api/node_modules/moment/test/lang/fr.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - French - *************************************************/ - -exports["lang:fr"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('fr'); - var tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('fr'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14ème 2010, 3:25:50 pm'], - ['ddd, hA', 'dim., 3PM'], - ['M Mo MM MMMM MMM', '2 2ème 02 février févr.'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14ème 14'], - ['d do dddd ddd dd', '0 0ème dimanche dim. Di'], - ['DDD DDDo DDDD', '45 45ème 045'], - ['w wo ww', '8 8ème 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45ème day of the year'], - ['L', '14/02/2010'], - ['LL', '14 février 2010'], - ['LLL', '14 février 2010 15:25'], - ['LLLL', 'dimanche 14 février 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('fr'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2ème', '2ème'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3ème', '3ème'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4ème', '4ème'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5ème', '5ème'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6ème', '6ème'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7ème', '7ème'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8ème', '8ème'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9ème', '9ème'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10ème', '10ème'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11ème', '11ème'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12ème', '12ème'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13ème', '13ème'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14ème', '14ème'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15ème', '15ème'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16ème', '16ème'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17ème', '17ème'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18ème', '18ème'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19ème', '19ème'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20ème', '20ème'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21ème', '21ème'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22ème', '22ème'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23ème', '23ème'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24ème', '24ème'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25ème', '25ème'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26ème', '26ème'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27ème', '27ème'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28ème', '28ème'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29ème', '29ème'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30ème', '30ème'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31ème', '31ème'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('fr'); - var expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('fr'); - var expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('fr'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "quelques secondes", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "une minute", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "une minute", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutes", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutes", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "une heure", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "une heure", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 heures", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 heures", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 heures", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un jour", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un jour", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 jours", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un jour", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 jours", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 jours", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mois", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mois", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mois", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mois", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mois", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mois", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mois", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mois", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mois", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "une année", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "une année", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 années", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "une année", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 années", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('fr'); - test.equal(moment(30000).from(0), "dans quelques secondes", "prefix"); - test.equal(moment(0).from(30000), "il y a quelques secondes", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('fr'); - test.equal(moment().add({s:30}).fromNow(), "dans quelques secondes", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "dans 5 jours", "in 5 days"); - test.done(); - }, - - "same day" : function(test) { - test.expect(6); - moment.lang('fr'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Aujourd'hui à 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Aujourd'hui à 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Aujourd'hui à 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Demain à 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Aujourd'hui à 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Hier à 02:00", "yesterday at the same time"); - test.done(); - }, - - "same next week" : function(test) { - test.expect(15); - moment.lang('fr'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [à] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "same last week" : function(test) { - test.expect(15); - moment.lang('fr'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [dernier à] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "same all else" : function(test) { - test.expect(4); - moment.lang('fr'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/gl.js b/api/node_modules/moment/test/lang/gl.js deleted file mode 100644 index a4d34b49021..00000000000 --- a/api/node_modules/moment/test/lang/gl.js +++ /dev/null @@ -1,232 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Galego - *************************************************/ - -exports["lang:gl"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('gl'); - var tests = "Xaneiro Xan._Febreiro Feb._Marzo Mar._Abril Abr._Maio Mai._Xuño Xuñ._Xullo Xul._Agosto Ago._Setembro Set._Octubro Out._Novembro Nov._Decembro Dec.".split("_"); - - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('es'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('gl'); - var expected = "Xaneiro Xan._Febreiro Feb._Marzo Mar._Abril Abr._Maio Mai._Xuño Xuñ._Xullo Xul._Agosto Ago._Setembro Set._Octubro Out._Novembro Nov._Decembro Dec.".split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('gl'); - var expected = "Domingo Dom. Do_Luns Lun. Lu_Martes Mar. Ma_Mércores Mér. Mé_Xoves Xov. Xo_Venres Ven. Ve_Sábado Sáb. Sá".split("_"); - - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('gl'); - var start = moment([2007, 1, 28]); - - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "uns segundo", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "un minuto", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "un minuto", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutos", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutos", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "unha hora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "unha hora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 horas", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 horas", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 horas", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un día", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un día", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 días", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un día", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 días", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 días", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mes", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mes", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mes", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 meses", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 meses", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 meses", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mes", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 meses", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 meses", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "un ano", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "un ano", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 anos", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "un ano", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 anos", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('gl'); - test.equal(moment(30000).from(0), "en uns segundo", "prefix"); - test.equal(moment(0).from(30000), "fai uns segundo", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('gl'); - test.equal(moment().fromNow(), "fai uns segundo", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('gl'); - test.equal(moment().add({s:30}).fromNow(), "en uns segundo", "en unos segundos"); - test.equal(moment().add({d:5}).fromNow(), "en 5 días", "en 5 días"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(7); - moment.lang('gl'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "hoxe ás 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "hoxe ás 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "hoxe ás 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "mañá ás 2:00", "tomorrow at the same time"); - test.equal(moment(a).add({ d: 1, h : -1 }).calendar(), "mañá a 1:00", "tomorrow minus 1 hour"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "hoxe a 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "onte á 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('gl'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('gl'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('gl'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - }, - - "regression tests" : function(test) { - test.expect(1); - moment.lang('gl'); - - var lastWeek = moment().subtract({ d: 4 }).hours(1); - test.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), "1 o'clock bug"); - - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/hu.js b/api/node_modules/moment/test/lang/hu.js deleted file mode 100644 index a2ef512512a..00000000000 --- a/api/node_modules/moment/test/lang/hu.js +++ /dev/null @@ -1,250 +0,0 @@ -var moment = require("../../moment"); - - /************************************************** - English - *************************************************/ - -exports["lang:hu"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('hu'); - var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(16); - moment.lang('hu'); - var a = [ - ['dddd, MMMM Do YYYY, HH:mm:ss', 'vasárnap, február 14. 2010, 15:25:50'], - ['ddd, HH', 'v, 15'], - ['M Mo MM MMMM MMM', '2 2. 02 február feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd', '0 0. vasárnap v'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['\\az év DDDo n\\apj\\a', 'az év 45. napja'], - ['L', '2010.02.14.'], - ['LL', '2010. február 14.'], - ['LLL', '2010. február 14., 15:25'], - ['LLLL', '2010. február 14., vasárnap 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('hu'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('hu'); - var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('hu'); - var expected = 'vasárnap v_hétfÅ‘ h_kedd k_szerda sze_csütörtök cs_péntek p_szombat szo'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('hu'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "néhány másodperc", "44 másodperc = néhány másodperc"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "egy perc", "45 másodperc = egy perc"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "egy perc", "89 másodperc = egy perc"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 perc", "90 másodperc = 2 perc"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 perc", "44 perc = 44 perc"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "egy óra", "45 perc = egy óra"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "egy óra", "89 perc = egy óra"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 óra", "90 perc = 2 óra"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 óra", "5 óra = 5 óra"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 óra", "21 óra = 21 óra"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "egy nap", "22 óra = egy nap"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "egy nap", "35 óra = egy nap"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 nap", "36 óra = 2 nap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "egy nap", "1 nap = egy nap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 nap", "5 nap = 5 nap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 nap", "25 nap = 25 nap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "egy hónap", "26 nap = egy hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "egy hónap", "30 nap = egy hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "egy hónap", "45 nap = egy hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 hónap", "46 nap = 2 hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 hónap", "75 nap = 2 hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 hónap", "76 nap = 3 hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "egy hónap", "1 hónap = egy hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 hónap", "5 hónap = 5 hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 hónap", "344 nap = 11 hónap"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "egy év", "345 nap = egy év"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "egy év", "547 nap = egy év"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 év", "548 nap = 2 év"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "egy év", "1 év = egy év"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 év", "5 év = 5 év"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('hu'); - test.equal(moment(30000).from(0), "néhány másodperc múlva", "prefix"); - test.equal(moment(0).from(30000), "néhány másodperce", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('hu'); - test.equal(moment().fromNow(), "néhány másodperce", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('hu'); - test.equal(moment().add({s:30}).fromNow(), "néhány másodperc múlva", "néhány másodperc múlva"); - test.equal(moment().add({d:5}).fromNow(), "5 nap múlva", "5 nap múlva"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('hu'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "ma 2:00-kor", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "ma 2:25-kor", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "ma 3:00-kor", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "holnap 2:00-kor", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "ma 1:00-kor", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "tegnap 2:00-kor", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('hu'); - - var i; - var m; - var days = 'vasárnap_hétfÅ‘n_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_'); - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('['+days[m.day()]+'] LT[-kor]'), "today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('['+days[m.day()]+'] LT[-kor]'), "today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('['+days[m.day()]+'] LT[-kor]'), "today + " + i + " days end of day"); - } - - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('hu'); - - var days = 'vasárnap_hétfÅ‘n_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_'); - - for (var i = 2; i < 7; i++) { - var m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('múlt ['+days[m.day()]+'] LT[-kor]'), "today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('múlt ['+days[m.day()]+'] LT[-kor]'), "today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('múlt ['+days[m.day()]+'] LT[-kor]'), "today - " + i + " days end of day"); - } - - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('hu'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "egy héte"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "egy hét múlva"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 hete"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "2 hét múlva"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/is.js b/api/node_modules/moment/test/lang/is.js deleted file mode 100644 index a59ed447200..00000000000 --- a/api/node_modules/moment/test/lang/is.js +++ /dev/null @@ -1,254 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Icelandic - *************************************************/ - -exports["lang:is"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('is'); - var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('is'); - var a = [ - ['dddd, Do MMMM YYYY, h:mm:ss a', 'sunnudagur, 14. febrúar 2010, 3:25:50 pm'], - ['ddd, hA', 'sun, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 febrúar feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. sunnudagur sun Su'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '14/02/2010'], - ['LL', '14. febrúar 2010'], - ['LLL', '14. febrúar 2010 kl. 15:25'], - ['LLLL', 'sunnudagur, 14. febrúar 2010 kl. 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('is'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('is'); - var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('is'); - var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(34); - moment.lang('is'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "nokkrar sekúndur", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "mínúta", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "mínúta", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 mínútur", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 mínútur", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:21}), true), "21 mínúta", "21 minutes = 21 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "klukkustund", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "klukkustund", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 klukkustundir", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 klukkustundir", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 klukkustund", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "dagur", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "dagur", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dagar", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "dagur", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dagar", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dagar", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:11}), true), "11 dagar", "11 days = 11 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:21}), true), "21 dagur", "21 days = 21 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "mánuður", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "mánuður", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "mánuður", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mánuðir", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mánuðir", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mánuðir", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "mánuður", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mánuðir", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mánuðir", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "ár", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "ár", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 ár", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "ár", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 ár", "5 years = 5 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:21}), true), "21 ár", "21 years = 21 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(3); - moment.lang('is'); - test.equal(moment(30000).from(0), "eftir nokkrar sekúndur", "prefix"); - test.equal(moment(0).from(30000), "fyrir nokkrum sekúndum síðan", "suffix"); - test.equal(moment().subtract({m:1}).fromNow(), "fyrir mínútu síðan", "a minute ago"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('is'); - test.equal(moment().fromNow(), "fyrir nokkrum sekúndum síðan", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(3); - moment.lang('is'); - test.equal(moment().add({s:30}).fromNow(), "eftir nokkrar sekúndur", "in a few seconds"); - test.equal(moment().add({m:1}).fromNow(), "eftir mínútu", "in a minute"); - test.equal(moment().add({d:5}).fromNow(), "eftir 5 daga", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('is'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "í dag kl. 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "í dag kl. 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "í dag kl. 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "á morgun kl. 2:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "í dag kl. 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "í gær kl. 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('is'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [kl.] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [kl.] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [kl.] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('is'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[síðasta] dddd [kl.] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[síðasta] dddd [kl.] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[síðasta] dddd [kl.] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('is'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/it.js b/api/node_modules/moment/test/lang/it.js deleted file mode 100644 index d9716b0e353..00000000000 --- a/api/node_modules/moment/test/lang/it.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Italian - *************************************************/ - -exports["lang:it"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('it'); - var tests = 'Gennaio Gen_Febbraio Feb_Marzo Mar_Aprile Apr_Maggio Mag_Giugno Giu_Luglio Lug_Agosto Ago_Settembre Set_Ottobre Ott_Novembre Nov_Dicembre Dic'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('it'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Domenica, Febbraio 14º 2010, 3:25:50 pm'], - ['ddd, hA', 'Dom, 3PM'], - ['M Mo MM MMMM MMM', '2 2º 02 Febbraio Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14º 14'], - ['d do dddd ddd dd', '0 0º Domenica Dom D'], - ['DDD DDDo DDDD', '45 45º 045'], - ['w wo ww', '8 8º 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45º day of the year'], - ['L', '14/02/2010'], - ['LL', '14 Febbraio 2010'], - ['LLL', '14 Febbraio 2010 15:25'], - ['LLLL', 'Domenica, 14 Febbraio 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('it'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('it'); - var expected = 'Gennaio Gen_Febbraio Feb_Marzo Mar_Aprile Apr_Maggio Mag_Giugno Giu_Luglio Lug_Agosto Ago_Settembre Set_Ottobre Ott_Novembre Nov_Dicembre Dic'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('it'); - var expected = 'Domenica Dom D_Lunedì Lun L_Martedì Mar Ma_Mercoledì Mer Me_Giovedì Gio G_Venerdì Ven V_Sabato Sab S'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('it'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "secondi", "44 seconds = seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "un minuto", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "un minuto", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minuti", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuti", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "un'ora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "un'ora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 ore", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 ore", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 ore", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "un giorno", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "un giorno", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 giorni", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "un giorno", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 giorni", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 giorni", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "un mese", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "un mese", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "un mese", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mesi", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mesi", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mesi", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "un mese", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mesi", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mesi", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "un anno", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "un anno", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 anni", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "un anno", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 anni", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('it'); - test.equal(moment(30000).from(0), "in secondi", "prefix"); - test.equal(moment(0).from(30000), "secondi fa", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('it'); - test.equal(moment().add({s:30}).fromNow(), "in secondi", "in seconds"); - test.equal(moment().add({d:5}).fromNow(), "in 5 giorni", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('it'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Oggi alle 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Oggi alle 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Oggi alle 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Domani alle 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Oggi alle 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Ieri alle 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('it'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [alle] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [alle] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [alle] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('it'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[lo scorso] dddd [alle] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[lo scorso] dddd [alle] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[lo scorso] dddd [alle] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('it'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/ja.js b/api/node_modules/moment/test/lang/ja.js deleted file mode 100644 index 0705ae751dc..00000000000 --- a/api/node_modules/moment/test/lang/ja.js +++ /dev/null @@ -1,208 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Japanese - *************************************************/ - -exports["lang:jp"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('ja'); - var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('ja'); - var a = [ - ['dddd, MMMM Do YYYY, a h:mm:ss', '日曜日, 2月 14 2010, åˆå¾Œ 3:25:50'], - ['ddd, Ah', 'æ—¥, åˆå¾Œ3'], - ['M Mo MM MMMM MMM', '2 2 02 2月 2月'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14 14'], - ['d do dddd ddd dd', '0 0 日曜日 æ—¥ æ—¥'], - ['DDD DDDo DDDD', '45 45 045'], - ['w wo ww', '8 8 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'åˆå¾Œ åˆå¾Œ'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45 day of the year'], - ['L', '2010/02/14'], - ['LL', '2010å¹´2月14æ—¥'], - ['LLL', '2010å¹´2月14æ—¥åˆå¾Œ3時25分'], - ['LLLL', '2010å¹´2月14æ—¥åˆå¾Œ3時25分 日曜日'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('ja'); - var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('ja'); - var expected = '日曜日 æ—¥ æ—¥_月曜日 月 月_ç«æ›œæ—¥ ç« ç«_水曜日 æ°´ æ°´_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('ja'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "数秒", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "1分", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "1分", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2分", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44分", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "1時間", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "1時間", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2時間", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5時間", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21時間", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "1æ—¥", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "1æ—¥", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2æ—¥", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "1æ—¥", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5æ—¥", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25æ—¥", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "1ヶ月", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "1ヶ月", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "1ヶ月", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2ヶ月", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2ヶ月", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3ヶ月", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "1ヶ月", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5ヶ月", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11ヶ月", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "1å¹´", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "1å¹´", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2å¹´", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "1å¹´", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5å¹´", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('ja'); - test.equal(moment(30000).from(0), "数秒後", "prefix"); - test.equal(moment(0).from(30000), "数秒å‰", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('ja'); - test.equal(moment().fromNow(), "数秒å‰", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('ja'); - test.equal(moment().add({s:30}).fromNow(), "数秒後", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5日後", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('ja'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "今日 åˆå‰2時0分", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "今日 åˆå‰2時25分", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "今日 åˆå‰3時0分", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "明日 åˆå‰2時0分", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "今日 åˆå‰1時0分", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "昨日 åˆå‰2時0分", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('ja'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('ja'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('ja'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/jp.js b/api/node_modules/moment/test/lang/jp.js deleted file mode 100644 index 8b47f7a47d1..00000000000 --- a/api/node_modules/moment/test/lang/jp.js +++ /dev/null @@ -1,208 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Japanese - *************************************************/ - -exports["lang:jp"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('jp'); - var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('jp'); - var a = [ - ['dddd, MMMM Do YYYY, a h:mm:ss', '日曜日, 2月 14 2010, åˆå¾Œ 3:25:50'], - ['ddd, Ah', 'æ—¥, åˆå¾Œ3'], - ['M Mo MM MMMM MMM', '2 2 02 2月 2月'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14 14'], - ['d do dddd ddd dd', '0 0 日曜日 æ—¥ æ—¥'], - ['DDD DDDo DDDD', '45 45 045'], - ['w wo ww', '8 8 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'åˆå¾Œ åˆå¾Œ'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45 day of the year'], - ['L', '2010/02/14'], - ['LL', '2010å¹´2月14æ—¥'], - ['LLL', '2010å¹´2月14æ—¥åˆå¾Œ3時25分'], - ['LLLL', '2010å¹´2月14æ—¥åˆå¾Œ3時25分 日曜日'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('jp'); - var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('jp'); - var expected = '日曜日 æ—¥ æ—¥_月曜日 月 月_ç«æ›œæ—¥ ç« ç«_水曜日 æ°´ æ°´_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('jp'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "数秒", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "1分", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "1分", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2分", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44分", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "1時間", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "1時間", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2時間", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5時間", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21時間", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "1æ—¥", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "1æ—¥", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2æ—¥", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "1æ—¥", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5æ—¥", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25æ—¥", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "1ヶ月", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "1ヶ月", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "1ヶ月", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2ヶ月", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2ヶ月", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3ヶ月", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "1ヶ月", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5ヶ月", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11ヶ月", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "1å¹´", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "1å¹´", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2å¹´", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "1å¹´", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5å¹´", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('jp'); - test.equal(moment(30000).from(0), "数秒後", "prefix"); - test.equal(moment(0).from(30000), "数秒å‰", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('jp'); - test.equal(moment().fromNow(), "数秒å‰", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('jp'); - test.equal(moment().add({s:30}).fromNow(), "数秒後", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5日後", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('jp'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "今日 åˆå‰2時0分", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "今日 åˆå‰2時25分", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "今日 åˆå‰3時0分", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "明日 åˆå‰2時0分", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "今日 åˆå‰1時0分", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "昨日 åˆå‰2時0分", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('jp'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[æ¥é€±]dddd LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('jp'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[å‰é€±]dddd LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('jp'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/ko.js b/api/node_modules/moment/test/lang/ko.js deleted file mode 100644 index 8e55ca4ddb9..00000000000 --- a/api/node_modules/moment/test/lang/ko.js +++ /dev/null @@ -1,247 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Korean - *************************************************/ - -exports["lang:kr"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('ko'); - var tests = '1ì›” 1ì›”_2ì›” 2ì›”_3ì›” 3ì›”_4ì›” 4ì›”_5ì›” 5ì›”_6ì›” 6ì›”_7ì›” 7ì›”_8ì›” 8ì›”_9ì›” 9ì›”_10ì›” 10ì›”_11ì›” 11ì›”_12ì›” 12ì›”'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - "format" : function(test) { - test.expect(18); - moment.lang('ko'); - var a = [ - ['YYYYë…„ MMMM Do dddd a h:mm:ss', '2010ë…„ 2ì›” 14ì¼ ì¼ìš”ì¼ ì˜¤í›„ 3:25:50'], - ['ddd A h', 'ì¼ ì˜¤í›„ 3'], - ['M Mo MM MMMM MMM', '2 2ì¼ 02 2ì›” 2ì›”'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14ì¼ 14'], - ['d do dddd ddd dd', '0 0ì¼ ì¼ìš”ì¼ ì¼ ì¼'], - ['DDD DDDo DDDD', '45 45ì¼ 045'], - ['w wo ww', '8 8ì¼ 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', '오후 오후'], - ['ì¼ë…„ 중 DDDo째 ë˜ëŠ” ë‚ ', 'ì¼ë…„ 중 45ì¼ì§¸ ë˜ëŠ” ë‚ '], - ['L', '2010.02.14'], - ['LL', '2010ë…„ 2ì›” 14ì¼'], - ['LLL', '2010ë…„ 2ì›” 14ì¼ ì˜¤í›„ 3ì‹œ 25분'], - ['LLLL', '2010ë…„ 2ì›” 14ì¼ ì¼ìš”ì¼ ì˜¤í›„ 3ì‹œ 25분'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('ko'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1ì¼', '1ì¼'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2ì¼', '2ì¼'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3ì¼', '3ì¼'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4ì¼', '4ì¼'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5ì¼', '5ì¼'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6ì¼', '6ì¼'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7ì¼', '7ì¼'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8ì¼', '8ì¼'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9ì¼', '9ì¼'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10ì¼', '10ì¼'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11ì¼', '11ì¼'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12ì¼', '12ì¼'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13ì¼', '13ì¼'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14ì¼', '14ì¼'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15ì¼', '15ì¼'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16ì¼', '16ì¼'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17ì¼', '17ì¼'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18ì¼', '18ì¼'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19ì¼', '19ì¼'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20ì¼', '20ì¼'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21ì¼', '21ì¼'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22ì¼', '22ì¼'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23ì¼', '23ì¼'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24ì¼', '24ì¼'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25ì¼', '25ì¼'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26ì¼', '26ì¼'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27ì¼', '27ì¼'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28ì¼', '28ì¼'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29ì¼', '29ì¼'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30ì¼', '30ì¼'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31ì¼', '31ì¼'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('ko'); - var expected = '1ì›” 1ì›”_2ì›” 2ì›”_3ì›” 3ì›”_4ì›” 4ì›”_5ì›” 5ì›”_6ì›” 6ì›”_7ì›” 7ì›”_8ì›” 8ì›”_9ì›” 9ì›”_10ì›” 10ì›”_11ì›” 11ì›”_12ì›” 12ì›”'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('ko'); - var expected = 'ì¼ìš”ì¼ ì¼ ì¼_ì›”ìš”ì¼ ì›” ì›”_í™”ìš”ì¼ í™” í™”_ìˆ˜ìš”ì¼ ìˆ˜ 수_ëª©ìš”ì¼ ëª© 목_ê¸ˆìš”ì¼ ê¸ˆ 금_í† ìš”ì¼ í†  토'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('ko'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "몇초", "44ì´ˆ = 몇초"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "ì¼ë¶„", "45ì´ˆ = ì¼ë¶„"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "ì¼ë¶„", "89ì´ˆ = ì¼ë¶„"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2분", "90ì´ˆ = 2분"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44분", "44분 = 44분"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "한시간", "45분 = 한시간"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "한시간", "89분 = 한시간"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2시간", "90분 = 2시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5시간", "5시간 = 5시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21시간", "21시간 = 21시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "하루", "22시간 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "하루", "35시간 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2ì¼", "36시간 = 2ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "하루", "하루 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5ì¼", "5ì¼ = 5ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25ì¼", "25ì¼ = 25ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "한달", "26ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "한달", "30ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "한달", "45ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2달", "46ì¼ = 2달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2달", "75ì¼ = 2달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3달", "76ì¼ = 3달"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "한달", "1달 = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5달", "5달 = 5달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11달", "344ì¼ = 11달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "ì¼ë…„", "345ì¼ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "ì¼ë…„", "547ì¼ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2ë…„", "548ì¼ = 2ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "ì¼ë…„", "ì¼ë…„ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5ë…„", "5ë…„ = 5ë…„"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('ko'); - test.equal(moment(30000).from(0), "몇초 후", "prefix"); - test.equal(moment(0).from(30000), "몇초 ì „", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('ko'); - test.equal(moment().fromNow(), "몇초 ì „", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('ko'); - test.equal(moment().add({s:30}).fromNow(), "몇초 후", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5ì¼ í›„", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('ko'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "오늘 오전 2ì‹œ 00분", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "오늘 오전 2ì‹œ 25분", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "오늘 오전 3ì‹œ 00분", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "ë‚´ì¼ ì˜¤ì „ 2ì‹œ 00분", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "오늘 오전 1ì‹œ 00분", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "ì–´ì œ 오전 2ì‹œ 00분", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('ko'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('ko'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('ko'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/kr.js b/api/node_modules/moment/test/lang/kr.js deleted file mode 100644 index 67314eb8e1c..00000000000 --- a/api/node_modules/moment/test/lang/kr.js +++ /dev/null @@ -1,247 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Korean - *************************************************/ - -exports["lang:kr"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('kr'); - var tests = '1ì›” 1ì›”_2ì›” 2ì›”_3ì›” 3ì›”_4ì›” 4ì›”_5ì›” 5ì›”_6ì›” 6ì›”_7ì›” 7ì›”_8ì›” 8ì›”_9ì›” 9ì›”_10ì›” 10ì›”_11ì›” 11ì›”_12ì›” 12ì›”'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - "format" : function(test) { - test.expect(18); - moment.lang('kr'); - var a = [ - ['YYYYë…„ MMMM Do dddd a h:mm:ss', '2010ë…„ 2ì›” 14ì¼ ì¼ìš”ì¼ ì˜¤í›„ 3:25:50'], - ['ddd A h', 'ì¼ ì˜¤í›„ 3'], - ['M Mo MM MMMM MMM', '2 2ì¼ 02 2ì›” 2ì›”'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14ì¼ 14'], - ['d do dddd ddd dd', '0 0ì¼ ì¼ìš”ì¼ ì¼ ì¼'], - ['DDD DDDo DDDD', '45 45ì¼ 045'], - ['w wo ww', '8 8ì¼ 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', '오후 오후'], - ['ì¼ë…„ 중 DDDo째 ë˜ëŠ” ë‚ ', 'ì¼ë…„ 중 45ì¼ì§¸ ë˜ëŠ” ë‚ '], - ['L', '2010.02.14'], - ['LL', '2010ë…„ 2ì›” 14ì¼'], - ['LLL', '2010ë…„ 2ì›” 14ì¼ ì˜¤í›„ 3ì‹œ 25분'], - ['LLLL', '2010ë…„ 2ì›” 14ì¼ ì¼ìš”ì¼ ì˜¤í›„ 3ì‹œ 25분'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('kr'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1ì¼', '1ì¼'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2ì¼', '2ì¼'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3ì¼', '3ì¼'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4ì¼', '4ì¼'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5ì¼', '5ì¼'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6ì¼', '6ì¼'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7ì¼', '7ì¼'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8ì¼', '8ì¼'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9ì¼', '9ì¼'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10ì¼', '10ì¼'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11ì¼', '11ì¼'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12ì¼', '12ì¼'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13ì¼', '13ì¼'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14ì¼', '14ì¼'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15ì¼', '15ì¼'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16ì¼', '16ì¼'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17ì¼', '17ì¼'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18ì¼', '18ì¼'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19ì¼', '19ì¼'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20ì¼', '20ì¼'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21ì¼', '21ì¼'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22ì¼', '22ì¼'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23ì¼', '23ì¼'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24ì¼', '24ì¼'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25ì¼', '25ì¼'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26ì¼', '26ì¼'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27ì¼', '27ì¼'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28ì¼', '28ì¼'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29ì¼', '29ì¼'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30ì¼', '30ì¼'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31ì¼', '31ì¼'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('kr'); - var expected = '1ì›” 1ì›”_2ì›” 2ì›”_3ì›” 3ì›”_4ì›” 4ì›”_5ì›” 5ì›”_6ì›” 6ì›”_7ì›” 7ì›”_8ì›” 8ì›”_9ì›” 9ì›”_10ì›” 10ì›”_11ì›” 11ì›”_12ì›” 12ì›”'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('kr'); - var expected = 'ì¼ìš”ì¼ ì¼ ì¼_ì›”ìš”ì¼ ì›” ì›”_í™”ìš”ì¼ í™” í™”_ìˆ˜ìš”ì¼ ìˆ˜ 수_ëª©ìš”ì¼ ëª© 목_ê¸ˆìš”ì¼ ê¸ˆ 금_í† ìš”ì¼ í†  토'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('kr'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "몇초", "44ì´ˆ = 몇초"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "ì¼ë¶„", "45ì´ˆ = ì¼ë¶„"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "ì¼ë¶„", "89ì´ˆ = ì¼ë¶„"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2분", "90ì´ˆ = 2분"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44분", "44분 = 44분"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "한시간", "45분 = 한시간"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "한시간", "89분 = 한시간"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2시간", "90분 = 2시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5시간", "5시간 = 5시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21시간", "21시간 = 21시간"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "하루", "22시간 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "하루", "35시간 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2ì¼", "36시간 = 2ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "하루", "하루 = 하루"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5ì¼", "5ì¼ = 5ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25ì¼", "25ì¼ = 25ì¼"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "한달", "26ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "한달", "30ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "한달", "45ì¼ = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2달", "46ì¼ = 2달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2달", "75ì¼ = 2달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3달", "76ì¼ = 3달"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "한달", "1달 = 한달"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5달", "5달 = 5달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11달", "344ì¼ = 11달"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "ì¼ë…„", "345ì¼ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "ì¼ë…„", "547ì¼ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2ë…„", "548ì¼ = 2ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "ì¼ë…„", "ì¼ë…„ = ì¼ë…„"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5ë…„", "5ë…„ = 5ë…„"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('kr'); - test.equal(moment(30000).from(0), "몇초 후", "prefix"); - test.equal(moment(0).from(30000), "몇초 ì „", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('kr'); - test.equal(moment().fromNow(), "몇초 ì „", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('kr'); - test.equal(moment().add({s:30}).fromNow(), "몇초 후", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5ì¼ í›„", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('kr'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "오늘 오전 2ì‹œ 00분", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "오늘 오전 2ì‹œ 25분", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "오늘 오전 3ì‹œ 00분", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "ë‚´ì¼ ì˜¤ì „ 2ì‹œ 00분", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "오늘 오전 1ì‹œ 00분", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "ì–´ì œ 오전 2ì‹œ 00분", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('kr'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('kr'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('지난주 dddd LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('kr'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/nb.js b/api/node_modules/moment/test/lang/nb.js deleted file mode 100644 index 6d0ab02ee2d..00000000000 --- a/api/node_modules/moment/test/lang/nb.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Norwegian bokmÃ¥l - *************************************************/ - -exports["lang:nb"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('nb'); - var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('nb'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'søndag, februar 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'søn, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 februar feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. søndag søn sø'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '2010-02-14'], - ['LL', '14 februar 2010'], - ['LLL', '14 februar 2010 15:25'], - ['LLLL', 'søndag 14 februar 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('nb'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('nb'); - var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('nb'); - var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('nb'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "noen sekunder", "44 sekunder = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "ett minutt", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "ett minutt", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutter", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutter", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "en time", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "en time", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 timer", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 timer", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 timer", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "en dag", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "en dag", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dager", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "en dag", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dager", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dager", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "en mÃ¥ned", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "en mÃ¥ned", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "en mÃ¥ned", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mÃ¥neder", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mÃ¥neder", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mÃ¥neder", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "en mÃ¥ned", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mÃ¥neder", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mÃ¥neder", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "ett Ã¥r", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "ett Ã¥r", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 Ã¥r", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "ett Ã¥r", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 Ã¥r", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('nb'); - test.equal(moment(30000).from(0), "om noen sekunder", "prefix"); - test.equal(moment(0).from(30000), "for noen sekunder siden", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('nb'); - test.equal(moment().fromNow(), "for noen sekunder siden", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('nb'); - test.equal(moment().add({s:30}).fromNow(), "om noen sekunder", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "om 5 dager", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('nb'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "I dag klokken 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "I dag klokken 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "I dag klokken 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "I morgen klokken 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "I dag klokken 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "I gÃ¥r klokken 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('nb'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [klokken] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [klokken] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [klokken] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('nb'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[Forrige] dddd [klokken] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[Forrige] dddd [klokken] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[Forrige] dddd [klokken] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('nb'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/nl.js b/api/node_modules/moment/test/lang/nl.js deleted file mode 100644 index 6d6525501d0..00000000000 --- a/api/node_modules/moment/test/lang/nl.js +++ /dev/null @@ -1,258 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Dutch - *************************************************/ - -exports["lang:nl"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('nl'); - var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('nl'); - var a = [ - ['dddd, MMMM Do YYYY, HH:mm:ss', 'zondag, februari 14de 2010, 15:25:50'], - ['ddd, HH', 'zo., 15'], - ['M Mo MM MMMM MMM', '2 2de 02 februari feb.'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14de 14'], - ['d do dddd ddd dd', '0 0de zondag zo. Zo'], - ['DDD DDDo DDDD', '45 45ste 045'], - ['w wo ww', '8 8ste 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45ste day of the year'], - ['L', '14-02-2010'], - ['LL', '14 februari 2010'], - ['LLL', '14 februari 2010 15:25'], - ['LLLL', 'zondag 14 februari 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('nl'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('nl'); - var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('nl'); - var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('nl'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "een paar seconden", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "één minuut", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "één minuut", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minuten", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuten", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "één uur", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "één uur", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 uur", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 uur", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 uur", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "één dag", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "één dag", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dagen", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "één dag", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dagen", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dagen", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "één maand", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "één maand", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "één maand", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 maanden", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 maanden", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 maanden", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "één maand", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 maanden", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 maanden", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "één jaar", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "één jaar", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 jaar", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "één jaar", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 jaar", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('nl'); - test.equal(moment(30000).from(0), "over een paar seconden", "prefix"); - test.equal(moment(0).from(30000), "een paar seconden geleden", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('nl'); - test.equal(moment().fromNow(), "een paar seconden geleden", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('nl'); - test.equal(moment().add({s:30}).fromNow(), "over een paar seconden", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "over 5 dagen", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('nl'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Vandaag om 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Vandaag om 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Vandaag om 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Morgen om 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Vandaag om 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Gisteren om 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('nl'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [om] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [om] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [om] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('nl'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[afgelopen] dddd [om] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[afgelopen] dddd [om] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[afgelopen] dddd [om] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('nl'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - }, - - "month abbreviation" : function(test) { - test.expect(2); - moment.lang('nl'); - - test.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot'); - test.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot'); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/pl.js b/api/node_modules/moment/test/lang/pl.js deleted file mode 100644 index 9e315f5807a..00000000000 --- a/api/node_modules/moment/test/lang/pl.js +++ /dev/null @@ -1,249 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Polish - *************************************************/ - -exports["lang:pl"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('pl'); - var tests = 'styczeÅ„ sty_luty lut_marzec mar_kwiecieÅ„ kwi_maj maj_czerwiec cze_lipiec lip_sierpieÅ„ sie_wrzesieÅ„ wrz_październik paź_listopad lis_grudzieÅ„ gru'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('pl'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'niedziela, luty 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'nie, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 luty lut'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. niedziela nie N'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '14-02-2010'], - ['LL', '14 luty 2010'], - ['LLL', '14 luty 2010 15:25'], - ['LLLL', 'niedziela, 14 luty 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('pl'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('pl'); - var expected = 'styczeÅ„ sty_luty lut_marzec mar_kwiecieÅ„ kwi_maj maj_czerwiec cze_lipiec lip_sierpieÅ„ sie_wrzesieÅ„ wrz_październik paź_listopad lis_grudzieÅ„ gru'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('pl'); - var expected = 'niedziela nie N_poniedziaÅ‚ek pon Pn_wtorek wt Wt_Å›roda Å›r Åšr_czwartek czw Cz_piÄ…tek pt Pt_sobota sb So'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('pl'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "kilka sekund", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "minuta", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "minuta", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minuty", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuty", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "godzina", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "godzina", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 godziny", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 godzin", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 godzin", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "1 dzieÅ„", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "1 dzieÅ„", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dni", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "1 dzieÅ„", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dni", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dni", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "miesiÄ…c", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "miesiÄ…c", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "miesiÄ…c", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 miesiÄ…ce", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 miesiÄ…ce", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 miesiÄ…ce", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "miesiÄ…c", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 miesiÄ™cy", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 miesiÄ™cy", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "rok", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "rok", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 lata", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "rok", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 lat", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('pl'); - test.equal(moment(30000).from(0), "za kilka sekund", "prefix"); - test.equal(moment(0).from(30000), "kilka sekund temu", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('pl'); - test.equal(moment().fromNow(), "kilka sekund temu", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(3); - moment.lang('pl'); - test.equal(moment().add({s:30}).fromNow(), "za kilka sekund", "in a few seconds"); - test.equal(moment().add({h:1}).fromNow(), "za godzinÄ™", "in an hour"); - test.equal(moment().add({d:5}).fromNow(), "za 5 dni", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('pl'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "DziÅ› o 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "DziÅ› o 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "DziÅ› o 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Jutro o 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "DziÅ› o 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Wczoraj o 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('pl'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[W] dddd [o] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[W] dddd [o] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[W] dddd [o] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('pl'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[W zeszÅ‚y/Å‚Ä…] dddd [o] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[W zeszÅ‚y/Å‚Ä…] dddd [o] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[W zeszÅ‚y/Å‚Ä…] dddd [o] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('pl'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/pt-br.js b/api/node_modules/moment/test/lang/pt-br.js deleted file mode 100644 index 9f6b93582dd..00000000000 --- a/api/node_modules/moment/test/lang/pt-br.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Portuguese - Brazilian - *************************************************/ - -exports["lang:pt-br"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('pt-br'); - var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('pt-br'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Domingo, Fevereiro 14º 2010, 3:25:50 pm'], - ['ddd, hA', 'Dom, 3PM'], - ['M Mo MM MMMM MMM', '2 2º 02 Fevereiro Fev'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14º 14'], - ['d do dddd ddd', '0 0º Domingo Dom'], - ['DDD DDDo DDDD', '45 45º 045'], - ['w wo ww', '8 8º 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45º day of the year'], - ['L', '14/02/2010'], - ['LL', '14 de Fevereiro de 2010'], - ['LLL', '14 de Fevereiro de 2010 15:25'], - ['LLLL', 'Domingo, 14 de Fevereiro de 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('pt-br'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('pt-br'); - var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('pt-br'); - var expected = 'Domingo Dom_Segunda-feira Seg_Terça-feira Ter_Quarta-feira Qua_Quinta-feira Qui_Sexta-feira Sex_Sábado Sáb'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('pt-br'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "segundos", "44 seconds = seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "um minuto", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "um minuto", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutos", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutos", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "uma hora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "uma hora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 horas", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 horas", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 horas", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "um dia", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "um dia", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dias", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "um dia", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dias", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dias", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "um mês", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "um mês", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "um mês", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 meses", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 meses", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 meses", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "um mês", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 meses", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 meses", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "um ano", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "um ano", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 anos", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "um ano", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 anos", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('pt-br'); - test.equal(moment(30000).from(0), "em segundos", "prefix"); - test.equal(moment(0).from(30000), "segundos atrás", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('pt-br'); - test.equal(moment().add({s:30}).fromNow(), "em segundos", "in seconds"); - test.equal(moment().add({d:5}).fromNow(), "em 5 dias", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('pt-br'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Hoje às 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Hoje às 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Hoje às 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Amanhã às 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Hoje às 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Ontem às 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('pt-br'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('pt-br'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('pt-br'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/pt.js b/api/node_modules/moment/test/lang/pt.js deleted file mode 100644 index 27731d8e607..00000000000 --- a/api/node_modules/moment/test/lang/pt.js +++ /dev/null @@ -1,241 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Portuguese - *************************************************/ - -exports["lang:pt"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('pt'); - var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('pt'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Domingo, Fevereiro 14º 2010, 3:25:50 pm'], - ['ddd, hA', 'Dom, 3PM'], - ['M Mo MM MMMM MMM', '2 2º 02 Fevereiro Fev'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14º 14'], - ['d do dddd ddd dd', '0 0º Domingo Dom Dom'], - ['DDD DDDo DDDD', '45 45º 045'], - ['w wo ww', '8 8º 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45º day of the year'], - ['L', '14/02/2010'], - ['LL', '14 de Fevereiro de 2010'], - ['LLL', '14 de Fevereiro de 2010 15:25'], - ['LLLL', 'Domingo, 14 de Fevereiro de 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('pt'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('pt'); - var expected = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('pt'); - var expected = 'Domingo Dom Dom_Segunda-feira Seg 2ª_Terça-feira Ter 3ª_Quarta-feira Qua 4ª_Quinta-feira Qui 5ª_Sexta-feira Sex 6ª_Sábado Sáb Sáb'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('pt'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "segundos", "44 seconds = seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "um minuto", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "um minuto", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minutos", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minutos", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "uma hora", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "uma hora", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 horas", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 horas", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 horas", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "um dia", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "um dia", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dias", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "um dia", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dias", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dias", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "um mês", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "um mês", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "um mês", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 meses", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 meses", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 meses", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "um mês", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 meses", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 meses", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "um ano", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "um ano", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 anos", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "um ano", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 anos", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('pt'); - test.equal(moment(30000).from(0), "em segundos", "prefix"); - test.equal(moment(0).from(30000), "segundos atrás", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('pt'); - test.equal(moment().add({s:30}).fromNow(), "em segundos", "in seconds"); - test.equal(moment().add({d:5}).fromNow(), "em 5 dias", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('pt'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Hoje às 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Hoje às 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Hoje às 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Amanhã às 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Hoje às 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Ontem às 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('pt'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [às] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('pt'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('pt'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/ro.js b/api/node_modules/moment/test/lang/ro.js deleted file mode 100644 index 1773584e339..00000000000 --- a/api/node_modules/moment/test/lang/ro.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Romanian - *************************************************/ - -exports["lang:ro"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('ro'); - var tests = 'Ianuarie Ian_Februarie Feb_Martie Mar_Aprilie Apr_Mai Mai_Iunie Iun_Iulie Iul_August Aug_Septembrie Sep_Octombrie Oct_Noiembrie Noi_Decembrie Dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('ro'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss A', 'Duminică, Februarie 14 2010, 3:25:50 PM'], - ['ddd, hA', 'Dum, 3PM'], - ['M Mo MM MMMM MMM', '2 2 02 Februarie Feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14 14'], - ['d do dddd ddd dd', '0 0 Duminică Dum Du'], - ['DDD DDDo DDDD', '45 45 045'], - ['w wo ww', '8 8 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['\\a DDDo\\a zi \\a \\anului', 'a 45a zi a anului'], - ['L', '14/02/2010'], - ['LL', '14 Februarie 2010'], - ['LLL', '14 Februarie 2010 15:25'], - ['LLLL', 'Duminică, 14 Februarie 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('ro'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('ro'); - var expected = 'Ianuarie Ian_Februarie Feb_Martie Mar_Aprilie Apr_Mai Mai_Iunie Iun_Iulie Iul_August Aug_Septembrie Sep_Octombrie Oct_Noiembrie Noi_Decembrie Dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('ro'); - var expected = 'Duminică Dum Du_Luni Lun Lu_MarÅ£i Mar Ma_Miercuri Mie Mi_Joi Joi Jo_Vineri Vin Vi_Sâmbătă Sâm Sâ'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('ro'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "câteva secunde", "44 secunde = câteva secunde"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "un minut", "45 secunde = un minut"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "un minut", "89 secunde = un minut"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minute", "90 secunde = 2 minute"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minute", "44 minute = 44 minute"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "o oră", "45 minute = o oră"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "o oră", "89 minute = o oră"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 ore", "90 minute = 2 ore"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 ore", "5 ore = 5 ore"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 ore", "21 ore = 21 ore"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "o zi", "22 ore = o zi"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "o zi", "35 ore = o zi"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 zile", "36 ore = 2 zile"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "o zi", "1 zi = o zi"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 zile", "5 zile = 5 zile"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 zile", "25 zile = 25 zile"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "o lună", "26 zile = o lună"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "o lună", "30 zile = o lună"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "o lună", "45 zile = o lună"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 luni", "46 zile = 2 luni"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 luni", "75 zile = 2 luni"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 luni", "76 zile = 3 luni"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "o lună", "1 lună = o lună"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 luni", "5 luni = 5 luni"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 luni", "344 zile = 11 luni"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "un an", "345 zile = un an"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "un an", "547 zile = un an"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 ani", "548 zile = 2 ani"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "un an", "1 an = un an"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 ani", "5 ani = 5 ani"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('ro'); - test.equal(moment(30000).from(0), "peste câteva secunde", "prefix"); - test.equal(moment(0).from(30000), "câteva secunde în urmă", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('ro'); - test.equal(moment().fromNow(), "câteva secunde în urmă", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('ro'); - test.equal(moment().add({s:30}).fromNow(), "peste câteva secunde", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "peste 5 zile", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('ro'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "azi la 2:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "azi la 2:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "azi la 3:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "mâine la 2:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "azi la 1:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "ieri la 2:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('ro'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [la] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [la] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [la] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('ro'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[fosta] dddd [la] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[fosta] dddd [la] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[fosta] dddd [la] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('ro'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/ru.js b/api/node_modules/moment/test/lang/ru.js deleted file mode 100644 index 05af6a0cb78..00000000000 --- a/api/node_modules/moment/test/lang/ru.js +++ /dev/null @@ -1,280 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Russian - *************************************************/ - -exports["lang:ru"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('ru'); - var tests = 'Ñнварь Ñнв_февраль фев_март мар_апрель апр_май май_июнь июн_июль июл_авгуÑÑ‚ авг_ÑентÑбрь Ñен_октÑбрь окт_ноÑбрь ноÑ_декабрь дек'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('ru'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'воÑкреÑенье, февраль 14. 2010, 3:25:50 pm'], - ['ddd, hA', 'вÑк, 3PM'], - ['M Mo MM MMMM MMM', '2 2. 02 февраль фев'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14. 14'], - ['d do dddd ddd dd', '0 0. воÑкреÑенье вÑк вÑ'], - ['DDD DDDo DDDD', '45 45. 045'], - ['w wo ww', '8 8. 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45. day of the year'], - ['L', '14.02.2010'], - ['LL', '14 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ 2010 г.'], - ['LLL', '14 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ 2010 г., 15:25'], - ['LLLL', 'воÑкреÑенье, 14 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ 2010 г., 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('ru'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('ru'); - var expected = 'Ñнварь Ñнв_февраль фев_март мар_апрель апр_май май_июнь июн_июль июл_авгуÑÑ‚ авг_ÑентÑбрь Ñен_октÑбрь окт_ноÑбрь ноÑ_декабрь дек'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format month case" : function(test) { - test.expect(24); - moment.lang('ru'); - var months = { - 'nominative': 'Ñнварь_февраль_март_апрель_май_июнь_июль_авгуÑÑ‚_ÑентÑбрь_октÑбрь_ноÑбрь_декабрь'.split('_'), - 'accusative': 'ÑнварÑ_февралÑ_марта_апрелÑ_маÑ_июнÑ_июлÑ_авгуÑта_ÑентÑбрÑ_октÑбрÑ_ноÑбрÑ_декабрÑ'.split('_') - }; - var i; - for (i = 0; i < 12; i++) { - test.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]); - test.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('ru'); - var expected = 'воÑкреÑенье вÑк вÑ_понедельник пнд пн_вторник втр вт_Ñреда Ñрд ÑÑ€_четверг чтв чт_пÑтница птн пт_Ñуббота Ñбт Ñб'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(32); - moment.lang('ru'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "неÑколько Ñекунд", "44 seconds = seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "минута", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "минута", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 минуты", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 минуты", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "чаÑ", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "чаÑ", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 чаÑа", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 чаÑов", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 чаÑ", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "день", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "день", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 днÑ", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "день", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 дней", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:11}), true), "11 дней", "11 days = 11 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:21}), true), "21 день", "21 days = 21 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 дней", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "меÑÑц", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "меÑÑц", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "меÑÑц", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 меÑÑца", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 меÑÑца", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 меÑÑца", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "меÑÑц", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 меÑÑцев", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 меÑÑцев", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "год", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "год", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 года", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "год", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 лет", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('ru'); - test.equal(moment(30000).from(0), "через неÑколько Ñекунд", "prefix"); - test.equal(moment(0).from(30000), "неÑколько Ñекунд назад", "suffix"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('ru'); - test.equal(moment().add({s:30}).fromNow(), "через неÑколько Ñекунд", "in seconds"); - test.equal(moment().add({d:5}).fromNow(), "через 5 дней", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('ru'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð² 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð² 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð² 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Завтра в 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð² 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "Вчера в 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('ru'); - - var i; - var m; - - function makeFormat(d) { - return d.day() === 2 ? '[Во] dddd [в] LT' : '[Ð’] dddd [в] LT'; - } - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('ru'); - - var i; - var m; - - function makeFormat(d) { - switch (d.day()) { - case 0: - return '[Ð’ прошлое] dddd [в] LT'; - case 1: - case 2: - case 4: - return '[Ð’ прошлый] dddd [в] LT'; - case 3: - case 5: - case 6: - return '[Ð’ прошлую] dddd [в] LT'; - } - } - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format(makeFormat(m)), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('ru'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/sv.js b/api/node_modules/moment/test/lang/sv.js deleted file mode 100644 index 43c7f60f0d2..00000000000 --- a/api/node_modules/moment/test/lang/sv.js +++ /dev/null @@ -1,248 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - English - *************************************************/ - -exports["lang:sv"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('sv'); - var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('sv'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'söndag, februari 14e 2010, 3:25:50 pm'], - ['ddd, hA', 'sön, 3PM'], - ['M Mo MM MMMM MMM', '2 2a 02 februari feb'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14e 14'], - ['d do dddd ddd dd', '0 0e söndag sön sö'], - ['DDD DDDo DDDD', '45 45e 045'], - ['w wo ww', '8 8e 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45e day of the year'], - ['L', '2010-02-14'], - ['LL', '14 februari 2010'], - ['LLL', '14 februari 2010 15:25'], - ['LLLL', 'söndag 14 februari 2010 15:25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('sv'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('sv'); - var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('sv'); - var expected = 'söndag sön sö_mÃ¥ndag mÃ¥n mÃ¥_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('sv'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "nÃ¥gra sekunder", "44 sekunder = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "en minut", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "en minut", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 minuter", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 minuter", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "en timme", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "en timme", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 timmar", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 timmar", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 timmar", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "en dag", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "en dag", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 dagar", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "en dag", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 dagar", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 dagar", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "en mÃ¥nad", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "en mÃ¥nad", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "en mÃ¥nad", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 mÃ¥nader", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 mÃ¥nader", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 mÃ¥nader", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "en mÃ¥nad", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 mÃ¥nader", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 mÃ¥nader", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "ett Ã¥r", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "ett Ã¥r", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 Ã¥r", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "ett Ã¥r", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 Ã¥r", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('sv'); - test.equal(moment(30000).from(0), "om nÃ¥gra sekunder", "prefix"); - test.equal(moment(0).from(30000), "för nÃ¥gra sekunder sen", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('sv'); - test.equal(moment().fromNow(), "för nÃ¥gra sekunder sen", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('sv'); - test.equal(moment().add({s:30}).fromNow(), "om nÃ¥gra sekunder", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "om 5 dagar", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('sv'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "Idag klockan 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "Idag klockan 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "Idag klockan 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "Imorgon klockan 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "Idag klockan 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "IgÃ¥r klockan 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('sv'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('dddd [klockan] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('dddd [klockan] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('dddd [klockan] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('sv'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[Förra] dddd[en klockan] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[Förra] dddd[en klockan] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[Förra] dddd[en klockan] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('sv'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/tr.js b/api/node_modules/moment/test/lang/tr.js deleted file mode 100644 index 2fce8a3a257..00000000000 --- a/api/node_modules/moment/test/lang/tr.js +++ /dev/null @@ -1,259 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Turkish - *************************************************/ - -exports["lang:tr"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('tr'); - var tests = 'Ocak Oca_Åžubat Åžub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_AÄŸustos AÄŸu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - moment.lang('tr'); - var a = [ - ['dddd, MMMM Do YYYY, h:mm:ss a', 'Pazar, Åžubat 14\'üncü 2010, 3:25:50 pm'], - ['ddd, hA', 'Paz, 3PM'], - ['M Mo MM MMMM MMM', '2 2\'nci 02 Åžubat Åžub'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14\'üncü 14'], - ['d do dddd ddd dd', '0 0\'ıncı Pazar Paz Pz'], - ['DDD DDDo DDDD', '45 45\'inci 045'], - ['w wo ww', '8 8\'inci 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'pm PM'], - ['yılın DDDo günü', 'yılın 45\'inci günü'], - ['L', '14.02.2010'], - ['LL', '14 Åžubat 2010'], - ['LLL', '14 Åžubat 2010 15:25'], - ['LLLL', 'Pazar, 14 Åžubat 2010 15:25'] - ], - DDDo = [ - [359, '360\'ıncı'], - [199, '200\'üncü'], - [149, '150\'nci'] - ], - dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - DDDoDt, - i; - test.expect(a.length + DDDo.length); - - for (i = 0; i < a.length; i++) { - test.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - for (i = 0; i < DDDo.length; i++) { - DDDoDt = moment([2010]); - test.equal(DDDoDt.add('days', DDDo[i][0]).format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]); - } - test.done(); - }, - - "format ordinal" : function(test) { - test.expect(31); - moment.lang('tr'); - test.equal(moment([2011, 0, 1]).format('DDDo'), '1\'inci', '1st'); - test.equal(moment([2011, 0, 2]).format('DDDo'), '2\'nci', '2nd'); - test.equal(moment([2011, 0, 3]).format('DDDo'), '3\'üncü', '3rd'); - test.equal(moment([2011, 0, 4]).format('DDDo'), '4\'üncü', '4th'); - test.equal(moment([2011, 0, 5]).format('DDDo'), '5\'inci', '5th'); - test.equal(moment([2011, 0, 6]).format('DDDo'), '6\'ncı', '6th'); - test.equal(moment([2011, 0, 7]).format('DDDo'), '7\'nci', '7th'); - test.equal(moment([2011, 0, 8]).format('DDDo'), '8\'inci', '8th'); - test.equal(moment([2011, 0, 9]).format('DDDo'), '9\'uncu', '9th'); - test.equal(moment([2011, 0, 10]).format('DDDo'), '10\'uncu', '10th'); - - test.equal(moment([2011, 0, 11]).format('DDDo'), '11\'inci', '11th'); - test.equal(moment([2011, 0, 12]).format('DDDo'), '12\'nci', '12th'); - test.equal(moment([2011, 0, 13]).format('DDDo'), '13\'üncü', '13th'); - test.equal(moment([2011, 0, 14]).format('DDDo'), '14\'üncü', '14th'); - test.equal(moment([2011, 0, 15]).format('DDDo'), '15\'inci', '15th'); - test.equal(moment([2011, 0, 16]).format('DDDo'), '16\'ncı', '16th'); - test.equal(moment([2011, 0, 17]).format('DDDo'), '17\'nci', '17th'); - test.equal(moment([2011, 0, 18]).format('DDDo'), '18\'inci', '18th'); - test.equal(moment([2011, 0, 19]).format('DDDo'), '19\'uncu', '19th'); - test.equal(moment([2011, 0, 20]).format('DDDo'), '20\'nci', '20th'); - - test.equal(moment([2011, 0, 21]).format('DDDo'), '21\'inci', '21th'); - test.equal(moment([2011, 0, 22]).format('DDDo'), '22\'nci', '22th'); - test.equal(moment([2011, 0, 23]).format('DDDo'), '23\'üncü', '23th'); - test.equal(moment([2011, 0, 24]).format('DDDo'), '24\'üncü', '24th'); - test.equal(moment([2011, 0, 25]).format('DDDo'), '25\'inci', '25th'); - test.equal(moment([2011, 0, 26]).format('DDDo'), '26\'ncı', '26th'); - test.equal(moment([2011, 0, 27]).format('DDDo'), '27\'nci', '27th'); - test.equal(moment([2011, 0, 28]).format('DDDo'), '28\'inci', '28th'); - test.equal(moment([2011, 0, 29]).format('DDDo'), '29\'uncu', '29th'); - test.equal(moment([2011, 0, 30]).format('DDDo'), '30\'uncu', '30th'); - - test.equal(moment([2011, 0, 31]).format('DDDo'), '31\'inci', '31st'); - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('tr'); - var expected = 'Ocak Oca_Åžubat Åžub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_AÄŸustos AÄŸu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('tr'); - var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_ÇarÅŸamba Çar Ça_PerÅŸembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('tr'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "birkaç saniye", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "bir dakika", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "bir dakika", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2 dakika", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44 dakika", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "bir saat", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "bir saat", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2 saat", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5 saat", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21 saat", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "bir gün", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "bir gün", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2 gün", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "bir gün", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5 gün", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25 gün", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "bir ay", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "bir ay", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "bir ay", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2 ay", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2 ay", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3 ay", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "bir ay", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5 ay", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11 ay", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "bir yıl", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "bir yıl", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2 yıl", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "bir yıl", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5 yıl", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('tr'); - test.equal(moment(30000).from(0), "birkaç saniye sonra", "prefix"); - test.equal(moment(0).from(30000), "birkaç saniye önce", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('tr'); - test.equal(moment().fromNow(), "birkaç saniye önce", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('tr'); - test.equal(moment().add({s:30}).fromNow(), "birkaç saniye sonra", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5 gün sonra", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('tr'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "bugün saat 02:00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "bugün saat 02:25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "bugün saat 03:00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "yarın saat 02:00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "bugün saat 01:00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "dün 02:00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('tr'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[haftaya] dddd [saat] LT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[haftaya] dddd [saat] LT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[haftaya] dddd [saat] LT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('tr'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[geçen hafta] dddd [saat] LT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[geçen hafta] dddd [saat] LT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[geçen hafta] dddd [saat] LT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('tr'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/zh-cn.js b/api/node_modules/moment/test/lang/zh-cn.js deleted file mode 100644 index 7bcfef54c89..00000000000 --- a/api/node_modules/moment/test/lang/zh-cn.js +++ /dev/null @@ -1,227 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Simplified Chinese - *************************************************/ - -exports["lang:zh-cn"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('zh-cn'); - var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_ä¹æœˆ 9月_å月 10月_å一月 11月_å二月 12月'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('zh-cn'); - var a = [ - ['dddd, MMMM Do YYYY, a h:mm:ss', '星期日, 二月 14 2010, ä¸‹åˆ 3:25:50'], - ['ddd, Ah', '周日, 下åˆ3'], - ['M Mo MM MMMM MMM', '2 2 02 二月 2月'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14 14'], - ['d do dddd ddd dd', '0 0 星期日 周日 æ—¥'], - ['DDD DDDo DDDD', '45 45 045'], - ['w wo ww', '8 8 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'ä¸‹åˆ ä¸‹åˆ'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45 day of the year'], - ['L', '2010å¹´2月14æ—¥'], - ['LL', '2010å¹´2月14æ—¥'], - ['LLL', '2010å¹´2月14日下åˆ3点25'], - ['LLLL', '2010å¹´2月14日星期日下åˆ3点25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('zh-cn'); - var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_ä¹æœˆ 9月_å月 10月_å一月 11月_å二月 12月'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('zh-cn'); - var expected = '星期日 周日 æ—¥_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 å››_星期五 周五 五_星期六 周六 å…­'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('zh-cn'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "几秒", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "1分钟", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "1分钟", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2分钟", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44分钟", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "1å°æ—¶", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "1å°æ—¶", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2å°æ—¶", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5å°æ—¶", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21å°æ—¶", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "1天", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "1天", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2天", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "1天", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5天", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25天", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "1个月", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "1个月", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "1个月", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2个月", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2个月", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3个月", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "1个月", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5个月", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11个月", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "1å¹´", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "1å¹´", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2å¹´", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "1å¹´", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5å¹´", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('zh-cn'); - test.equal(moment(30000).from(0), "几秒内", "prefix"); - test.equal(moment(0).from(30000), "几秒å‰", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('zh-cn'); - test.equal(moment().fromNow(), "几秒å‰", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('zh-cn'); - test.equal(moment().add({s:30}).fromNow(), "几秒内", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5天内", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('zh-cn'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "今天早上2点00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "今天早上2点25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "今天早上3点00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "明天早上2点00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "今天早上1点00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "昨天早上2点00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('zh-cn'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('zh-cn'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('zh-cn'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - }, - - "meridiem" : function(test) { - test.expect(10); - moment.lang('zh-cn'); - - test.equal(moment([2011, 2, 23, 0, 0]).format('a'), "早上", "morning"); - test.equal(moment([2011, 2, 23, 9, 0]).format('a'), "上åˆ", "before noon"); - test.equal(moment([2011, 2, 23, 12, 0]).format('a'), "中åˆ", "noon"); - test.equal(moment([2011, 2, 23, 13, 0]).format('a'), "下åˆ", "after noon"); - test.equal(moment([2011, 2, 23, 18, 0]).format('a'), "晚上", "night"); - - test.equal(moment([2011, 2, 23, 0, 0]).format('A'), "早上", "morning"); - test.equal(moment([2011, 2, 23, 9, 0]).format('A'), "上åˆ", "before noon"); - test.equal(moment([2011, 2, 23, 12, 0]).format('A'), "中åˆ", "noon"); - test.equal(moment([2011, 2, 23, 13, 0]).format('A'), "下åˆ", "afternoon"); - test.equal(moment([2011, 2, 23, 18, 0]).format('A'), "晚上", "night"); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/lang/zh-tw.js b/api/node_modules/moment/test/lang/zh-tw.js deleted file mode 100644 index bba8cc4a1b5..00000000000 --- a/api/node_modules/moment/test/lang/zh-tw.js +++ /dev/null @@ -1,227 +0,0 @@ -var moment = require("../../moment"); - - - /************************************************** - Traditional Chinese - *************************************************/ - -exports["lang:zh-tw"] = { - "parse" : function(test) { - test.expect(96); - moment.lang('zh-tw'); - var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_ä¹æœˆ 9月_å月 10月_å一月 11月_å二月 12月'.split("_"); - var i; - function equalTest(input, mmm, i) { - test.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1)); - } - for (i = 0; i < 12; i++) { - tests[i] = tests[i].split(' '); - equalTest(tests[i][0], 'MMM', i); - equalTest(tests[i][1], 'MMM', i); - equalTest(tests[i][0], 'MMMM', i); - equalTest(tests[i][1], 'MMMM', i); - equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i); - equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i); - equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i); - } - test.done(); - }, - - "format" : function(test) { - test.expect(18); - moment.lang('zh-tw'); - var a = [ - ['dddd, MMMM Do YYYY, a h:mm:ss', '星期日, 二月 14 2010, ä¸‹åˆ 3:25:50'], - ['ddd, Ah', '週日, 下åˆ3'], - ['M Mo MM MMMM MMM', '2 2 02 二月 2月'], - ['YYYY YY', '2010 10'], - ['D Do DD', '14 14 14'], - ['d do dddd ddd dd', '0 0 星期日 週日 æ—¥'], - ['DDD DDDo DDDD', '45 45 045'], - ['w wo ww', '8 8 08'], - ['h hh', '3 03'], - ['H HH', '15 15'], - ['m mm', '25 25'], - ['s ss', '50 50'], - ['a A', 'ä¸‹åˆ ä¸‹åˆ'], - ['t\\he DDDo \\d\\ay of t\\he ye\\ar', 'the 45 day of the year'], - ['L', '2010å¹´2月14æ—¥'], - ['LL', '2010å¹´2月14æ—¥'], - ['LLL', '2010å¹´2月14日下åˆ3點25'], - ['LLLL', '2010å¹´2月14日星期日下åˆ3點25'] - ], - b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)), - i; - for (i = 0; i < a.length; i++) { - test.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "format month" : function(test) { - test.expect(12); - moment.lang('zh-tw'); - var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_ä¹æœˆ 9月_å月 10月_å一月 11月_å二月 12月'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]); - } - test.done(); - }, - - "format week" : function(test) { - test.expect(7); - moment.lang('zh-tw'); - var expected = '星期日 週日 æ—¥_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 å››_星期五 週五 五_星期六 週六 å…­'.split("_"); - var i; - for (i = 0; i < expected.length; i++) { - test.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]); - } - test.done(); - }, - - "from" : function(test) { - test.expect(30); - moment.lang('zh-tw'); - var start = moment([2007, 1, 28]); - test.equal(start.from(moment([2007, 1, 28]).add({s:44}), true), "幾秒", "44 seconds = a few seconds"); - test.equal(start.from(moment([2007, 1, 28]).add({s:45}), true), "一分é˜", "45 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:89}), true), "一分é˜", "89 seconds = a minute"); - test.equal(start.from(moment([2007, 1, 28]).add({s:90}), true), "2分é˜", "90 seconds = 2 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:44}), true), "44分é˜", "44 minutes = 44 minutes"); - test.equal(start.from(moment([2007, 1, 28]).add({m:45}), true), "一å°æ™‚", "45 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:89}), true), "一å°æ™‚", "89 minutes = an hour"); - test.equal(start.from(moment([2007, 1, 28]).add({m:90}), true), "2å°æ™‚", "90 minutes = 2 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:5}), true), "5å°æ™‚", "5 hours = 5 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:21}), true), "21å°æ™‚", "21 hours = 21 hours"); - test.equal(start.from(moment([2007, 1, 28]).add({h:22}), true), "一天", "22 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:35}), true), "一天", "35 hours = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({h:36}), true), "2天", "36 hours = 2 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:1}), true), "一天", "1 day = a day"); - test.equal(start.from(moment([2007, 1, 28]).add({d:5}), true), "5天", "5 days = 5 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:25}), true), "25天", "25 days = 25 days"); - test.equal(start.from(moment([2007, 1, 28]).add({d:26}), true), "一個月", "26 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:30}), true), "一個月", "30 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:45}), true), "一個月", "45 days = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({d:46}), true), "2個月", "46 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:74}), true), "2個月", "75 days = 2 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:76}), true), "3個月", "76 days = 3 months"); - test.equal(start.from(moment([2007, 1, 28]).add({M:1}), true), "一個月", "1 month = a month"); - test.equal(start.from(moment([2007, 1, 28]).add({M:5}), true), "5個月", "5 months = 5 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:344}), true), "11個月", "344 days = 11 months"); - test.equal(start.from(moment([2007, 1, 28]).add({d:345}), true), "一年", "345 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:547}), true), "一年", "547 days = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({d:548}), true), "2å¹´", "548 days = 2 years"); - test.equal(start.from(moment([2007, 1, 28]).add({y:1}), true), "一年", "1 year = a year"); - test.equal(start.from(moment([2007, 1, 28]).add({y:5}), true), "5å¹´", "5 years = 5 years"); - test.done(); - }, - - "suffix" : function(test) { - test.expect(2); - moment.lang('zh-tw'); - test.equal(moment(30000).from(0), "幾秒內", "prefix"); - test.equal(moment(0).from(30000), "幾秒å‰", "suffix"); - test.done(); - }, - - "now from now" : function(test) { - test.expect(1); - moment.lang('zh-tw'); - test.equal(moment().fromNow(), "幾秒å‰", "now from now should display as in the past"); - test.done(); - }, - - "fromNow" : function(test) { - test.expect(2); - moment.lang('zh-tw'); - test.equal(moment().add({s:30}).fromNow(), "幾秒內", "in a few seconds"); - test.equal(moment().add({d:5}).fromNow(), "5天內", "in 5 days"); - test.done(); - }, - - "calendar day" : function(test) { - test.expect(6); - moment.lang('zh-tw'); - - var a = moment().hours(2).minutes(0).seconds(0); - - test.equal(moment(a).calendar(), "今天早上2點00", "today at the same time"); - test.equal(moment(a).add({ m: 25 }).calendar(), "今天早上2點25", "Now plus 25 min"); - test.equal(moment(a).add({ h: 1 }).calendar(), "今天早上3點00", "Now plus 1 hour"); - test.equal(moment(a).add({ d: 1 }).calendar(), "明天早上2點00", "tomorrow at the same time"); - test.equal(moment(a).subtract({ h: 1 }).calendar(), "今天早上1點00", "Now minus 1 hour"); - test.equal(moment(a).subtract({ d: 1 }).calendar(), "昨天早上2點00", "yesterday at the same time"); - test.done(); - }, - - "calendar next week" : function(test) { - test.expect(15); - moment.lang('zh-tw'); - - var i; - var m; - - for (i = 2; i < 7; i++) { - m = moment().add({ d: i }); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[下]ddddLT'), "Today + " + i + " days end of day"); - } - test.done(); - }, - - "calendar last week" : function(test) { - test.expect(15); - moment.lang('zh-tw'); - - for (i = 2; i < 7; i++) { - m = moment().subtract({ d: i }); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days current time"); - m.hours(0).minutes(0).seconds(0).milliseconds(0); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days beginning of day"); - m.hours(23).minutes(59).seconds(59).milliseconds(999); - test.equal(m.calendar(), m.format('[上]ddddLT'), "Today - " + i + " days end of day"); - } - test.done(); - }, - - "calendar all else" : function(test) { - test.expect(4); - moment.lang('zh-tw'); - var weeksAgo = moment().subtract({ w: 1 }); - var weeksFromNow = moment().add({ w: 1 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "1 week ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 1 week"); - - weeksAgo = moment().subtract({ w: 2 }); - weeksFromNow = moment().add({ w: 2 }); - - test.equal(weeksAgo.calendar(), weeksAgo.format('L'), "2 weeks ago"); - test.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), "in 2 weeks"); - test.done(); - }, - - "meridiem" : function(test) { - test.expect(10); - moment.lang('zh-cn'); - - test.equal(moment([2011, 2, 23, 0, 0]).format('a'), "早上", "morning"); - test.equal(moment([2011, 2, 23, 9, 0]).format('a'), "上åˆ", "before noon"); - test.equal(moment([2011, 2, 23, 12, 0]).format('a'), "中åˆ", "noon"); - test.equal(moment([2011, 2, 23, 13, 0]).format('a'), "下åˆ", "after noon"); - test.equal(moment([2011, 2, 23, 18, 0]).format('a'), "晚上", "night"); - - test.equal(moment([2011, 2, 23, 0, 0]).format('A'), "早上", "morning"); - test.equal(moment([2011, 2, 23, 9, 0]).format('A'), "上åˆ", "before noon"); - test.equal(moment([2011, 2, 23, 12, 0]).format('A'), "中åˆ", "noon"); - test.equal(moment([2011, 2, 23, 13, 0]).format('A'), "下åˆ", "afternoon"); - test.equal(moment([2011, 2, 23, 18, 0]).format('A'), "晚上", "night"); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/add_subtract.js b/api/node_modules/moment/test/moment/add_subtract.js deleted file mode 100644 index 1241befc71d..00000000000 --- a/api/node_modules/moment/test/moment/add_subtract.js +++ /dev/null @@ -1,128 +0,0 @@ -var moment = require("../../moment"); - -exports.add_subtract = { - "add and subtract short" : function(test) { - test.expect(12); - - var a = moment(); - a.year(2011); - a.month(9); - a.date(12); - a.hours(6); - a.minutes(7); - a.seconds(8); - a.milliseconds(500); - - test.equal(a.add({ms:50}).milliseconds(), 550, 'Add milliseconds'); - test.equal(a.add({s:1}).seconds(), 9, 'Add seconds'); - test.equal(a.add({m:1}).minutes(), 8, 'Add minutes'); - test.equal(a.add({h:1}).hours(), 7, 'Add hours'); - test.equal(a.add({d:1}).date(), 13, 'Add date'); - test.equal(a.add({w:1}).date(), 20, 'Add week'); - test.equal(a.add({M:1}).month(), 10, 'Add month'); - test.equal(a.add({y:1}).year(), 2012, 'Add year'); - - var b = moment([2010, 0, 31]).add({M:1}); - var c = moment([2010, 1, 28]).subtract({M:1}); - - test.equal(b.month(), 1, 'add month, jan 31st to feb 28th'); - test.equal(b.date(), 28, 'add month, jan 31st to feb 28th'); - test.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th'); - test.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th'); - test.done(); - }, - - "add and subtract long" : function(test) { - test.expect(8); - - var a = moment(); - a.year(2011); - a.month(9); - a.date(12); - a.hours(6); - a.minutes(7); - a.seconds(8); - a.milliseconds(500); - - test.equal(a.add({milliseconds:50}).milliseconds(), 550, 'Add milliseconds'); - test.equal(a.add({seconds:1}).seconds(), 9, 'Add seconds'); - test.equal(a.add({minutes:1}).minutes(), 8, 'Add minutes'); - test.equal(a.add({hours:1}).hours(), 7, 'Add hours'); - test.equal(a.add({days:1}).date(), 13, 'Add date'); - test.equal(a.add({weeks:1}).date(), 20, 'Add week'); - test.equal(a.add({months:1}).month(), 10, 'Add month'); - test.equal(a.add({years:1}).year(), 2012, 'Add year'); - test.done(); - }, - - "add and subtract string long" : function(test) { - test.expect(9); - - var a = moment(); - a.year(2011); - a.month(9); - a.date(12); - a.hours(6); - a.minutes(7); - a.seconds(8); - a.milliseconds(500); - - var b = a.clone(); - - test.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds'); - test.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds'); - test.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes'); - test.equal(a.add('hours', 1).hours(), 7, 'Add hours'); - test.equal(a.add('days', 1).date(), 13, 'Add date'); - test.equal(a.add('weeks', 1).date(), 20, 'Add week'); - test.equal(a.add('months', 1).month(), 10, 'Add month'); - test.equal(a.add('years', 1).year(), 2012, 'Add year'); - test.equal(b.add('days', '01').date(), 13, 'Add date'); - test.done(); - }, - - "add and subtract string short" : function(test) { - test.expect(8); - - var a = moment(); - a.year(2011); - a.month(9); - a.date(12); - a.hours(6); - a.minutes(7); - a.seconds(8); - a.milliseconds(500); - - test.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds'); - test.equal(a.add('s', 1).seconds(), 9, 'Add seconds'); - test.equal(a.add('m', 1).minutes(), 8, 'Add minutes'); - test.equal(a.add('h', 1).hours(), 7, 'Add hours'); - test.equal(a.add('d', 1).date(), 13, 'Add date'); - test.equal(a.add('w', 1).date(), 20, 'Add week'); - test.equal(a.add('M', 1).month(), 10, 'Add month'); - test.equal(a.add('y', 1).year(), 2012, 'Add year'); - test.done(); - }, - - "add across DST" : function(test) { - test.expect(3); - - var a = moment(new Date(2011, 2, 12, 5, 0, 0)); - var b = moment(new Date(2011, 2, 12, 5, 0, 0)); - var c = moment(new Date(2011, 2, 12, 5, 0, 0)); - var d = moment(new Date(2011, 2, 12, 5, 0, 0)); - a.add('days', 1); - b.add('hours', 24); - c.add('months', 1); - test.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour'); - if (b.isDST() && !d.isDST()) { - test.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour'); - } else if (!b.isDST() && d.isDST()) { - test.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour'); - } else { - test.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time'); - } - test.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour'); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/create.js b/api/node_modules/moment/test/moment/create.js deleted file mode 100644 index 404c1751d4d..00000000000 --- a/api/node_modules/moment/test/moment/create.js +++ /dev/null @@ -1,327 +0,0 @@ -var moment = require("../../moment"); - -exports.create = { - "array" : function(test) { - test.expect(8); - test.ok(moment([2010]).toDate() instanceof Date, "[2010]"); - test.ok(moment([2010, 1]).toDate() instanceof Date, "[2010, 1]"); - test.ok(moment([2010, 1, 12]).toDate() instanceof Date, "[2010, 1, 12]"); - test.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, "[2010, 1, 12, 1]"); - test.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, "[2010, 1, 12, 1, 1]"); - test.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, "[2010, 1, 12, 1, 1, 1]"); - test.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, "[2010, 1, 12, 1, 1, 1, 1]"); - test.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), "constructing with array === constructing with new Date()"); - test.done(); - }, - - "number" : function(test) { - test.expect(3); - test.ok(moment(1000).toDate() instanceof Date, "1000"); - test.ok((moment(1000).valueOf() === 1000), "testing valueOf"); - test.ok((moment.utc(1000).valueOf() === 1000), "testing valueOf"); - test.done(); - }, - - "unix" : function(test) { - test.expect(8); - test.equal(moment.unix(1).valueOf(), 1000, "1 unix timestamp == 1000 Date.valueOf"); - test.equal(moment(1000).unix(), 1, "1000 Date.valueOf == 1 unix timestamp"); - test.equal(moment.unix(1000).valueOf(), 1000000, "1000 unix timestamp == 1000000 Date.valueOf"); - test.equal(moment(1500).unix(), 1, "1500 Date.valueOf == 1 unix timestamp"); - test.equal(moment(1900).unix(), 1, "1900 Date.valueOf == 1 unix timestamp"); - test.equal(moment(2100).unix(), 2, "2100 Date.valueOf == 2 unix timestamp"); - test.equal(moment(1333129333524).unix(), 1333129333, "1333129333524 Date.valueOf == 1333129333 unix timestamp"); - test.equal(moment(1333129333524000).unix(), 1333129333524, "1333129333524000 Date.valueOf == 1333129333524 unix timestamp"); - test.done(); - }, - - "date" : function(test) { - test.expect(1); - test.ok(moment(new Date()).toDate() instanceof Date, "new Date()"); - test.done(); - }, - - "moment" : function(test) { - test.expect(2); - test.ok(moment(moment()).toDate() instanceof Date, "moment(moment())"); - test.ok(moment(moment(moment())).toDate() instanceof Date, "moment(moment(moment()))"); - test.done(); - }, - - "undefined" : function(test) { - test.expect(1); - test.ok(moment().toDate() instanceof Date, "undefined"); - test.done(); - }, - - "string without format" : function(test) { - test.expect(2); - test.ok(moment("Aug 9, 1995").toDate() instanceof Date, "Aug 9, 1995"); - test.ok(moment("Mon, 25 Dec 1995 13:30:00 GMT").toDate() instanceof Date, "Mon, 25 Dec 1995 13:30:00 GMT"); - test.done(); - }, - - "string from Date.toString" : function(test) { - test.expect(1); - var str = (new Date()).toString(); - test.equal(moment(str).toString(), str, "Parsing a string from Date.prototype.toString should match moment.fn.toString"); - test.done(); - }, - - "string without format - json" : function(test) { - test.expect(5); - test.equal(moment("Date(1325132654000)").valueOf(), 1325132654000, "Date(1325132654000)"); - test.equal(moment("Date(-1325132654000)").valueOf(), -1325132654000, "Date(-1325132654000)"); - test.equal(moment("/Date(1325132654000)/").valueOf(), 1325132654000, "/Date(1325132654000)/"); - test.equal(moment("/Date(1325132654000+0700)/").valueOf(), 1325132654000, "/Date(1325132654000+0700)/"); - test.equal(moment("/Date(1325132654000-0700)/").valueOf(), 1325132654000, "/Date(1325132654000-0700)/"); - test.done(); - }, - - "string with format dropped am/pm bug" : function(test) { - moment.lang('en'); - test.expect(3); - - test.equal(moment('05/1/2012', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens'); - test.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens'); - test.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens'); - - test.done(); - }, - - "empty string with formats" : function(test) { - test.expect(3); - - test.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), '0000-01-01 00:00:00', 'should not break if input is an empty string'); - test.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), '0000-01-01 00:00:00', 'should not break if input is an empty string'); - test.equal(moment(' ', ['MM', "DD"]).format('YYYY-MM-DD HH:mm:ss'), '0000-01-01 00:00:00', 'should not break if input is an empty string'); - - test.done(); - }, - - "matching am/pm" : function(test) { - test.expect(1); - - test.equal(moment('2012-09-03T03:00PM', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly even if the input string contains other letters'); - - test.done(); - }, - - "string with format" : function(test) { - moment.lang('en'); - var a = [ - ['MM-DD-YYYY', '12-02-1999'], - ['DD-MM-YYYY', '12-02-1999'], - ['DD/MM/YYYY', '12/02/1999'], - ['DD_MM_YYYY', '12_02_1999'], - ['DD:MM:YYYY', '12:02:1999'], - ['D-M-YY', '2-2-99'], - ['YY', '99'], - ['DDD-YYYY', '300-1999'], - ['DD-MM-YYYY h:m:s', '12-02-1999 2:45:10'], - ['DD-MM-YYYY h:m:s a', '12-02-1999 2:45:10 am'], - ['DD-MM-YYYY h:m:s a', '12-02-1999 2:45:10 pm'], - ['h:mm a', '12:00 pm'], - ['h:mm a', '12:30 pm'], - ['h:mm a', '12:00 am'], - ['h:mm a', '12:30 am'], - ['HH:mm', '12:00'], - ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'], - ['MM-DD-YYYY \\M', '12-02-1999 M'], - ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'], - ['HH:mm:ss', '12:00:00'], - ['HH:mm:ss', '12:30:00'], - ['HH:mm:ss', '00:00:00'], - ['HH:mm:ss S', '00:30:00 1'], - ['HH:mm:ss SS', '00:30:00 12'], - ['HH:mm:ss SSS', '00:30:00 123'], - ['HH:mm:ss S', '00:30:00 7'], - ['HH:mm:ss SS', '00:30:00 78'], - ['HH:mm:ss SSS', '00:30:00 789'] - ], - i; - - test.expect(a.length); - for (i = 0; i < a.length; i++) { - test.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - test.done(); - }, - - "string with format no separators" : function(test) { - moment.lang('en'); - var a = [ - ['MMDDYYYY', '12021999'], - ['DDMMYYYY', '12021999'], - ['YYYYMMDD', '19991202'] - ],i; - - test.expect(a.length); - - for (i = 0; i < a.length; i++) { - test.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]); - } - - test.done(); - }, - - "string with format (timezone)" : function(test) { - test.expect(8); - test.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours "5 -0700" ---> "H ZZ"'); - test.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours "5 -07:00" ---> "H Z"'); - test.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours "5 -0730" ---> "H ZZ"'); - test.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours "5 -07:30" ---> "H Z"'); - test.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours "5 +0100" ---> "H ZZ"'); - test.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours "5 +01:00" ---> "H Z"'); - test.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours "5 +0130" ---> "H ZZ"'); - test.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours "5 +01:30" ---> "H Z"'); - test.done(); - }, - - "string with format (timezone offset)" : function(test) { - test.expect(4); - var a = new Date(Date.UTC(2011, 0, 1, 1)); - var b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z'); - test.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset'); - test.equal(+a, +b, 'date created with utc == parsed string with timezone offset'); - var c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z'); - var d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z'); - test.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time'); - var e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss'); - var f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ'); - test.equal(e.hours(), f.hours(), 'parse timezone offset in utc'); - test.done(); - }, - - "string with array of formats" : function(test) { - test.expect(3); - test.equal(moment('13-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '02 13 1999', 'switching month and day'); - test.equal(moment('02-13-1999', ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 13 1999', 'year last'); - test.equal(moment('1999-02-13', ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 13 1999', 'year first'); - test.done(); - }, - - "string with format - years" : function(test) { - test.expect(2); - test.equal(moment('71', 'YY').format('YYYY'), '1971', '71 > 1971'); - test.equal(moment('69', 'YY').format('YYYY'), '2069', '69 > 2069'); - test.done(); - }, - - "implicit cloning" : function(test) { - test.expect(2); - var momentA = moment([2011, 10, 10]); - var momentB = moment(momentA); - momentA.month(5); - test.equal(momentB.month(), 10, "Calling moment() on a moment will create a clone"); - test.equal(momentA.month(), 5, "Calling moment() on a moment will create a clone"); - test.done(); - }, - - "explicit cloning" : function(test) { - test.expect(2); - var momentA = moment([2011, 10, 10]); - var momentB = momentA.clone(); - momentA.month(5); - test.equal(momentB.month(), 10, "Calling moment() on a moment will create a clone"); - test.equal(momentA.month(), 5, "Calling moment() on a moment will create a clone"); - test.done(); - }, - - "cloning carrying over utc mode" : function(test) { - test.expect(8); - - test.equal(moment().local().clone()._isUTC, false, "An explicit cloned local moment should have _isUTC == false"); - test.equal(moment().utc().clone()._isUTC, true, "An cloned utc moment should have _isUTC == true"); - test.equal(moment().clone()._isUTC, false, "An explicit cloned local moment should have _isUTC == false"); - test.equal(moment.utc().clone()._isUTC, true, "An explicit cloned utc moment should have _isUTC == true"); - test.equal(moment(moment().local())._isUTC, false, "An implicit cloned local moment should have _isUTC == false"); - test.equal(moment(moment().utc())._isUTC, true, "An implicit cloned utc moment should have _isUTC == true"); - test.equal(moment(moment())._isUTC, false, "An implicit cloned local moment should have _isUTC == false"); - test.equal(moment(moment.utc())._isUTC, true, "An implicit cloned utc moment should have _isUTC == true"); - - test.done(); - }, - - "parsing iso" : function(test) { - var offset = moment([2011, 9, 08]).zone(); - var pad = function(input) { - if (input < 10) { - return '0' + input; - } - return '' + input; - } - var hourOffset = (offset > 0) ? Math.floor(offset / 60) : Math.ceil(offset / 60); - var minOffset = offset - (hourOffset * 60); - var tz = (offset > 0) ? '-' + pad(hourOffset) + ':' + pad(minOffset) : '+' + pad(-hourOffset) + ':' + pad(-minOffset); - var tz2 = tz.replace(':', ''); - var formats = [ - ['2011-10-08', '2011-10-08T00:00:00.000' + tz], - ['2011-10-08T18', '2011-10-08T18:00:00.000' + tz], - ['2011-10-08T18:04', '2011-10-08T18:04:00.000' + tz], - ['2011-10-08T18:04:20', '2011-10-08T18:04:20.000' + tz], - ['2011-10-08T18:04' + tz, '2011-10-08T18:04:00.000' + tz], - ['2011-10-08T18:04:20' + tz, '2011-10-08T18:04:20.000' + tz], - ['2011-10-08T18:04' + tz2, '2011-10-08T18:04:00.000' + tz], - ['2011-10-08T18:04:20' + tz2, '2011-10-08T18:04:20.000' + tz], - ['2011-10-08T18:04:20.1' + tz2, '2011-10-08T18:04:20.100' + tz], - ['2011-10-08T18:04:20.11' + tz2, '2011-10-08T18:04:20.110' + tz], - ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz] - ]; - test.expect(formats.length); - for (var i = 0; i < formats.length; i++) { - test.equal(formats[i][1], moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), "moment should be able to parse ISO " + formats[i][0]); - } - test.done(); - }, - - "parsing iso Z timezone" : function(test) { - var i, - formats = [ - ['2011-10-08T18:04Z', '2011-10-08T18:04:00.000+00:00'], - ['2011-10-08T18:04:20Z', '2011-10-08T18:04:20.000+00:00'], - ['2011-10-08T18:04:20.111Z', '2011-10-08T18:04:20.111+00:00'] - ]; - test.expect(formats.length); - for (i = 0; i < formats.length; i++) { - test.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], "moment should be able to parse ISO " + formats[i][0]); - } - test.done(); - }, - - "parsing iso Z timezone into local" : function(test) { - test.expect(1); - - var m = moment('2011-10-08T18:04:20.111Z'); - - test.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', "moment should be able to parse ISO 2011-10-08T18:04:20.111Z"); - - test.done(); - }, - - "null" : function(test) { - test.expect(3); - test.equal(moment(''), null, "Calling moment('')"); - test.equal(moment(null), null, "Calling moment(null)"); - test.equal(moment('', 'YYYY-MM-DD'), null, "Calling moment('', 'YYYY-MM-DD')"); - test.done(); - }, - - "first century" : function(test) { - test.expect(6); - test.equal(moment([0, 0, 1]).format("YYYY-MM-DD"), "0000-01-01", "Year AD 0"); - test.equal(moment([99, 0, 1]).format("YYYY-MM-DD"), "0099-01-01", "Year AD 99"); - test.equal(moment([999, 0, 1]).format("YYYY-MM-DD"), "0999-01-01", "Year AD 999"); - test.equal(moment('0 1 1', 'YYYY MM DD').format("YYYY-MM-DD"), "0000-01-01", "Year AD 0"); - test.equal(moment('99 1 1', 'YYYY MM DD').format("YYYY-MM-DD"), "0099-01-01", "Year AD 99"); - test.equal(moment('999 1 1', 'YYYY MM DD').format("YYYY-MM-DD"), "0999-01-01", "Year AD 999"); - test.done(); - }, - - "six digit years" : function(test) { - test.expect(2); - test.equal(moment([-270000, 0, 1]).format("YYYY-MM-DD"), "-270000-01-01", "format BC 270,000"); - test.equal(moment([ 270000, 0, 1]).format("YYYY-MM-DD"), "270000-01-01", "format AD 270,000"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/days_in_month.js b/api/node_modules/moment/test/moment/days_in_month.js deleted file mode 100644 index ffa2546731f..00000000000 --- a/api/node_modules/moment/test/moment/days_in_month.js +++ /dev/null @@ -1,28 +0,0 @@ -var moment = require("../../moment"); - -exports.days_in_month = { - "days in month" : function(test) { - test.expect(24); - var months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - for (var i = 0; i < 12; i++) { - test.equal(moment([2012, i]).daysInMonth(), - months[i], - moment([2012, i]).format('L') + " should have " + months[i] + " days. (beginning of month " + i + ')') - } - for (var i = 0; i < 12; i++) { - test.equal(moment([2012, i, months[i]]).daysInMonth(), - months[i], - moment([2012, i, months[i]]).format('L') + " should have " + months[i] + " days. (end of month " + i + ')') - } - test.done(); - }, - - "days in month leap years" : function(test) { - test.expect(4); - test.equal(moment([2010, 1]).daysInMonth(), 28, "Feb 2010 should have 28 days"); - test.equal(moment([2100, 1]).daysInMonth(), 28, "Feb 2100 should have 28 days"); - test.equal(moment([2008, 1]).daysInMonth(), 29, "Feb 2008 should have 29 days"); - test.equal(moment([2000, 1]).daysInMonth(), 29, "Feb 2000 should have 29 days"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/diff.js b/api/node_modules/moment/test/moment/diff.js deleted file mode 100644 index 849c16615f4..00000000000 --- a/api/node_modules/moment/test/moment/diff.js +++ /dev/null @@ -1,94 +0,0 @@ -var moment = require("../../moment"); - -exports.diff = { - "diff" : function(test) { - test.expect(5); - - test.equal(moment(1000).diff(0), 1000, "1 second - 0 = 1000"); - test.equal(moment(1000).diff(500), 500, "1 second - 0.5 seconds = 500"); - test.equal(moment(0).diff(1000), -1000, "0 - 1 second = -1000"); - test.equal(moment(new Date(1000)).diff(1000), 0, "1 second - 1 second = 0"); - var oneHourDate = new Date(), - nowDate = new Date(); - oneHourDate.setHours(oneHourDate.getHours() + 1); - test.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, "1 hour from now = 360000"); - test.done(); - }, - - "diff key after" : function(test) { - test.expect(9); - - test.equal(moment([2010]).diff([2011], 'years'), -1, "year diff"); - test.equal(moment([2010]).diff([2011, 6], 'years', true), -1.5, "year diff, float"); - test.equal(moment([2010]).diff([2010, 2], 'months'), -2, "month diff"); - test.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), -1, "week diff"); - test.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -3, "week diff"); - test.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, "day diff"); - test.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, "hour diff"); - test.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, "minute diff"); - test.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, "second diff"); - test.done(); - }, - - "diff key before" : function(test) { - test.expect(9); - - test.equal(moment([2011]).diff([2010], 'years'), 1, "year diff"); - test.equal(moment([2011, 6]).diff([2010], 'years', true), 1.5, "year diff, float"); - test.equal(moment([2010, 2]).diff([2010], 'months'), 2, "month diff"); - test.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, "day diff"); - test.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 1, "week diff"); - test.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 3, "week diff"); - test.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, "hour diff"); - test.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, "minute diff"); - test.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, "second diff"); - test.done(); - }, - - "diff month" : function(test) { - test.expect(1); - - test.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, "month diff"); - test.done(); - }, - - "diff across DST" : function(test) { - test.expect(2); - - test.equal(moment([2012, 2, 24]).diff([2012, 2, 10], 'weeks', true), 2, "diff weeks across DST"); - test.equal(moment([2012, 2, 24]).diff([2012, 2, 10], 'days', true), 14, "diff weeks across DST"); - test.done(); - }, - - "diff overflow" : function(test) { - test.expect(4); - - test.equal(moment([2011]).diff([2010], 'months'), 12, "month diff"); - test.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, "hour diff"); - test.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, "minute diff"); - test.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, "second diff"); - test.done(); - }, - - "diff between utc and local" : function(test) { - test.expect(7); - - test.equal(moment([2011]).utc().diff([2010], 'years'), 1, "year diff"); - test.equal(moment([2010, 2]).utc().diff([2010], 'months'), 2, "month diff"); - test.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, "day diff"); - test.equal(moment([2010, 0, 21]).utc().diff([2010], 'weeks'), 3, "week diff"); - test.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, "hour diff"); - test.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, "minute diff"); - test.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, "second diff"); - - test.done(); - }, - - "year diffs include dates" : function(test) { - test.expect(1); - - test.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, "year diff should include date of month"); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/duration.js b/api/node_modules/moment/test/moment/duration.js deleted file mode 100644 index 37ac4546b5f..00000000000 --- a/api/node_modules/moment/test/moment/duration.js +++ /dev/null @@ -1,212 +0,0 @@ -var moment = require("../../moment"); - -exports.duration = { - "object instantiation" : function(test) { - var d = moment.duration({ - years: 2, - months: 3, - weeks: 2, - days: 1, - hours: 8, - minutes: 9, - seconds: 20, - milliseconds: 12 - }); - - test.expect(8); - test.equal(d.years(), 2, "years"); - test.equal(d.months(), 3, "months"); - test.equal(d.weeks(), 2, "weeks"); - test.equal(d.days(), 15, "days"); // two weeks + 1 day - test.equal(d.hours(), 8, "hours"); - test.equal(d.minutes(), 9, "minutes"); - test.equal(d.seconds(), 20, "seconds"); - test.equal(d.milliseconds(), 12, "milliseconds"); - test.done(); - }, - - "milliseconds instantiation" : function(test) { - test.expect(1); - test.equal(moment.duration(72).milliseconds(), 72, "milliseconds"); - test.done(); - }, - - "instantiation by type" : function(test) { - test.expect(16); - test.equal(moment.duration(1, "years").years(), 1, "years"); - test.equal(moment.duration(1, "y").years(), 1, "y"); - test.equal(moment.duration(2, "months").months(), 2, "months"); - test.equal(moment.duration(2, "M").months(), 2, "M"); - test.equal(moment.duration(3, "weeks").weeks(), 3, "weeks"); - test.equal(moment.duration(3, "w").weeks(), 3, "weeks"); - test.equal(moment.duration(4, "days").days(), 4, "days"); - test.equal(moment.duration(4, "d").days(), 4, "d"); - test.equal(moment.duration(5, "hours").hours(), 5, "hours"); - test.equal(moment.duration(5, "h").hours(), 5, "h"); - test.equal(moment.duration(6, "minutes").minutes(), 6, "minutes"); - test.equal(moment.duration(6, "m").minutes(), 6, "m"); - test.equal(moment.duration(7, "seconds").seconds(), 7, "seconds"); - test.equal(moment.duration(7, "s").seconds(), 7, "s"); - test.equal(moment.duration(8, "milliseconds").milliseconds(), 8, "milliseconds"); - test.equal(moment.duration(8, "ms").milliseconds(), 8, "ms"); - test.done(); - }, - - "shortcuts" : function(test) { - test.expect(8); - test.equal(moment.duration({y: 1}).years(), 1, "years = y"); - test.equal(moment.duration({M: 2}).months(), 2, "months = M"); - test.equal(moment.duration({w: 3}).weeks(), 3, "weeks = w"); - test.equal(moment.duration({d: 4}).days(), 4, "days = d"); - test.equal(moment.duration({h: 5}).hours(), 5, "hours = h"); - test.equal(moment.duration({m: 6}).minutes(), 6, "minutes = m"); - test.equal(moment.duration({s: 7}).seconds(), 7, "seconds = s"); - test.equal(moment.duration({ms: 8}).milliseconds(), 8, "milliseconds = ms"); - test.done(); - }, - - "instantiation from another duration" : function(test) { - var simple = moment.duration(1234), - complicated = moment.duration({ - years: 2, - months: 3, - weeks: 4, - days: 1, - hours: 8, - minutes: 9, - seconds: 20, - milliseconds: 12 - }); - - test.expect(2); - test.deepEqual(moment.duration(simple), simple, "simple clones are equal"); - test.deepEqual(moment.duration(complicated), complicated, "complicated clones are equal"); - test.done(); - }, - - "humanize" : function(test) { - test.expect(32); - moment.lang('en'); - test.equal(moment.duration({seconds: 44}).humanize(), "a few seconds", "44 seconds = a few seconds"); - test.equal(moment.duration({seconds: 45}).humanize(), "a minute", "45 seconds = a minute"); - test.equal(moment.duration({seconds: 89}).humanize(), "a minute", "89 seconds = a minute"); - test.equal(moment.duration({seconds: 90}).humanize(), "2 minutes", "90 seconds = 2 minutes"); - test.equal(moment.duration({minutes: 44}).humanize(), "44 minutes", "44 minutes = 44 minutes"); - test.equal(moment.duration({minutes: 45}).humanize(), "an hour", "45 minutes = an hour"); - test.equal(moment.duration({minutes: 89}).humanize(), "an hour", "89 minutes = an hour"); - test.equal(moment.duration({minutes: 90}).humanize(), "2 hours", "90 minutes = 2 hours"); - test.equal(moment.duration({hours: 5}).humanize(), "5 hours", "5 hours = 5 hours"); - test.equal(moment.duration({hours: 21}).humanize(), "21 hours", "21 hours = 21 hours"); - test.equal(moment.duration({hours: 22}).humanize(), "a day", "22 hours = a day"); - test.equal(moment.duration({hours: 35}).humanize(), "a day", "35 hours = a day"); - test.equal(moment.duration({hours: 36}).humanize(), "2 days", "36 hours = 2 days"); - test.equal(moment.duration({days: 1}).humanize(), "a day", "1 day = a day"); - test.equal(moment.duration({days: 5}).humanize(), "5 days", "5 days = 5 days"); - test.equal(moment.duration({weeks: 1}).humanize(), "7 days", "1 week = 7 days"); - test.equal(moment.duration({days: 25}).humanize(), "25 days", "25 days = 25 days"); - test.equal(moment.duration({days: 26}).humanize(), "a month", "26 days = a month"); - test.equal(moment.duration({days: 30}).humanize(), "a month", "30 days = a month"); - test.equal(moment.duration({days: 45}).humanize(), "a month", "45 days = a month"); - test.equal(moment.duration({days: 46}).humanize(), "2 months", "46 days = 2 months"); - test.equal(moment.duration({days: 74}).humanize(), "2 months", "75 days = 2 months"); - test.equal(moment.duration({days: 76}).humanize(), "3 months", "76 days = 3 months"); - test.equal(moment.duration({months: 1}).humanize(), "a month", "1 month = a month"); - test.equal(moment.duration({months: 5}).humanize(), "5 months", "5 months = 5 months"); - test.equal(moment.duration({days: 344}).humanize(), "11 months", "344 days = 11 months"); - test.equal(moment.duration({days: 345}).humanize(), "a year", "345 days = a year"); - test.equal(moment.duration({days: 547}).humanize(), "a year", "547 days = a year"); - test.equal(moment.duration({days: 548}).humanize(), "2 years", "548 days = 2 years"); - test.equal(moment.duration({years: 1}).humanize(), "a year", "1 year = a year"); - test.equal(moment.duration({years: 5}).humanize(), "5 years", "5 years = 5 years"); - test.equal(moment.duration(7200000).humanize(), "2 hours", "7200000 = 2 minutes"); - test.done(); - }, - - "humanize duration with suffix" : function(test) { - test.expect(2); - moment.lang('en'); - test.equal(moment.duration({seconds: 44}).humanize(true), "in a few seconds", "44 seconds = a few seconds"); - test.equal(moment.duration({seconds: -44}).humanize(true), "a few seconds ago", "44 seconds = a few seconds"); - test.done(); - }, - - "bubble value up" : function(test) { - test.expect(5); - test.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, "61001 milliseconds has 1 millisecond left over"); - test.equal(moment.duration({milliseconds: 61001}).seconds(), 1, "61001 milliseconds has 1 second left over"); - test.equal(moment.duration({milliseconds: 61001}).minutes(), 1, "61001 milliseconds has 1 minute left over"); - - test.equal(moment.duration({minutes: 350}).minutes(), 50, "350 minutes has 50 minutes left over"); - test.equal(moment.duration({minutes: 350}).hours(), 5, "350 minutes has 5 hours left over"); - test.done(); - }, - - "clipping" : function(test) { - test.expect(18); - test.equal(moment.duration({months: 11}).months(), 11, "11 months is 11 months"); - test.equal(moment.duration({months: 11}).years(), 0, "11 months makes no year"); - test.equal(moment.duration({months: 12}).months(), 0, "12 months is 0 months left over"); - test.equal(moment.duration({months: 12}).years(), 1, "12 months makes 1 year"); - test.equal(moment.duration({months: 13}).months(), 1, "13 months is 1 month left over"); - test.equal(moment.duration({months: 13}).years(), 1, "13 months makes 1 year"); - - test.equal(moment.duration({days: 29}).days(), 29, "29 days is 29 days"); - test.equal(moment.duration({days: 29}).months(), 0, "29 days makes no month"); - test.equal(moment.duration({days: 30}).days(), 0, "30 days is 0 days left over"); - test.equal(moment.duration({days: 30}).months(), 1, "30 days is a month"); - test.equal(moment.duration({days: 31}).days(), 1, "31 days is 1 day left over"); - test.equal(moment.duration({days: 31}).months(), 1, "31 days is a month"); - - test.equal(moment.duration({hours: 23}).hours(), 23, "23 hours is 23 hours"); - test.equal(moment.duration({hours: 23}).days(), 0, "23 hours makes no day"); - test.equal(moment.duration({hours: 24}).hours(), 0, "24 hours is 0 hours left over"); - test.equal(moment.duration({hours: 24}).days(), 1, "24 hours makes 1 day"); - test.equal(moment.duration({hours: 25}).hours(), 1, "25 hours is 1 hour left over"); - test.equal(moment.duration({hours: 25}).days(), 1, "25 hours makes 1 day"); - test.done(); - }, - - "effective equivalency" : function(test) { - test.expect(7); - test.deepEqual(moment.duration({seconds: 1})._data, moment.duration({milliseconds: 1000})._data, "1 second is the same as 1000 milliseconds"); - test.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data, "1 minute is the same as 60 seconds"); - test.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data, "1 hour is the same as 60 minutes"); - test.deepEqual(moment.duration({hours: 24})._data, moment.duration({days: 1})._data, "1 day is the same as 24 hours"); - test.deepEqual(moment.duration({days: 7})._data, moment.duration({weeks: 1})._data, "1 week is the same as 7 days"); - test.deepEqual(moment.duration({days: 30})._data, moment.duration({months: 1})._data, "1 month is the same as 30 days"); - test.deepEqual(moment.duration({months: 12})._data, moment.duration({years: 1})._data, "1 years is the same as 12 months"); - test.done(); - }, - - "asGetters" : function(test) { - var d = moment.duration({ - years: 2, - months: 3, - weeks: 2, - days: 1, - hours: 8, - minutes: 9, - seconds: 20, - milliseconds: 12 - }); - - test.expect(8); - test.equal(Math.round(d.asYears() * 100) / 100, 2.26, "years"); - test.equal(Math.round(d.asMonths() * 100) / 100, 27.51, "months"); - test.equal(Math.round(d.asWeeks() * 100) / 100, 117.91, "weeks"); - test.equal(Math.round(d.asDays() * 100) / 100, 825.34, "days"); - test.equal(Math.round(d.asHours() * 100) / 100, 19808.16, "hours"); - test.equal(Math.round(d.asMinutes() * 100) / 100, 1188489.33, "minutes"); - test.equal(Math.round(d.asSeconds() * 100) / 100, 71309360.01, "seconds"); - test.equal(d.asMilliseconds(), 71309360012, "milliseconds"); - test.done(); - }, - - "isDuration" : function(test) { - test.expect(3); - test.ok(moment.isDuration(moment.duration(12345678)), "correctly says true"); - test.ok(!moment.isDuration(moment()), "moment object is not a duration"); - test.ok(!moment.isDuration({milliseconds: 1}), "plain object is not a duration"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/format.js b/api/node_modules/moment/test/moment/format.js deleted file mode 100644 index 9681a2b8626..00000000000 --- a/api/node_modules/moment/test/moment/format.js +++ /dev/null @@ -1,115 +0,0 @@ -var moment = require("../../moment"); - -exports.format = { - "format YY" : function(test) { - test.expect(1); - - var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125)); - test.equal(b.format('YY'), '09', 'YY ---> 09'); - test.done(); - }, - - "format escape brackets" : function(test) { - test.expect(9); - - var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125)); - test.equal(b.format('[day]'), 'day', 'Single bracket'); - test.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket'); - test.equal(b.format('[YY'), '[09', 'Un-ended bracket'); - test.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets'); - test.equal(b.format('[[]'), '[', 'Escape open bracket'); - test.equal(b.format('[Last]'), 'Last', 'localized tokens'); - test.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens'); - test.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens'); - test.equal(b.format('[LLL] LLL'), 'LLL February 14 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)'); - test.done(); - }, - - "format milliseconds" : function(test) { - test.expect(6); - var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123)); - test.equal(b.format('S'), '1', 'Deciseconds'); - test.equal(b.format('SS'), '12', 'Centiseconds'); - test.equal(b.format('SSS'), '123', 'Milliseconds'); - b.milliseconds(789); - test.equal(b.format('S'), '7', 'Deciseconds'); - test.equal(b.format('SS'), '78', 'Centiseconds'); - test.equal(b.format('SSS'), '789', 'Milliseconds'); - test.done(); - }, - - "format timezone" : function(test) { - test.expect(2); - - var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)); - var explanation = 'moment().format("z") = ' + b.format('z') + ' It should be something like "PST"' - if (moment().zone() === -60) { - explanation += "For UTC+1 this is a known issue, see https://github.com/timrwood/moment/issues/162"; - } - test.ok(b.format('Z').match(/^[\+\-]\d\d:\d\d$/), b.format('Z') + ' should be something like "+07:30"'); - test.ok(b.format('ZZ').match(/^[\+\-]\d{4}$/), b.format('ZZ') + ' should be something like "+0700"'); - test.done(); - }, - - "format multiple with zone" : function(test) { - test.expect(1); - - var b = moment('2012-10-08 -1200', ['YYYY ZZ', 'YYYY-MM-DD ZZ']); - test.equals(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats'); - test.done(); - }, - - "isDST" : function(test) { - test.expect(2); - - var janOffset = new Date(2011, 0, 1).getTimezoneOffset(), - julOffset = new Date(2011, 6, 1).getTimezoneOffset(), - janIsDst = janOffset < julOffset, - julIsDst = julOffset < janOffset, - jan1 = moment([2011]), - jul1 = moment([2011, 6]); - - if (janIsDst && julIsDst) { - test.ok(0, 'January and July cannot both be in DST'); - test.ok(0, 'January and July cannot both be in DST'); - } else if (janIsDst) { - test.ok(jan1.isDST(), 'January 1 is DST'); - test.ok(!jul1.isDST(), 'July 1 is not DST'); - } else if (julIsDst) { - test.ok(!jan1.isDST(), 'January 1 is not DST'); - test.ok(jul1.isDST(), 'July 1 is DST'); - } else { - test.ok(!jan1.isDST(), 'January 1 is not DST'); - test.ok(!jul1.isDST(), 'July 1 is not DST'); - } - test.done(); - }, - - "zone" : function(test) { - test.expect(3); - - if (moment().zone() > 0) { - test.ok(moment().format('ZZ').indexOf('-') > -1, 'When the zone() offset is greater than 0, the ISO offset should be less than zero'); - } - if (moment().zone() < 0) { - test.ok(moment().format('ZZ').indexOf('+') > -1, 'When the zone() offset is less than 0, the ISO offset should be greater than zero'); - } - if (moment().zone() == 0) { - test.ok(moment().format('ZZ').indexOf('+') > -1, 'When the zone() offset is equal to 0, the ISO offset should be positive zero'); - } - if (moment().zone() === 0) { - test.equal(moment().zone(), 0, 'moment.fn.zone should be a multiple of 15 (was ' + moment().zone() + ')'); - } else { - test.equal(moment().zone() % 15, 0, 'moment.fn.zone should be a multiple of 15 (was ' + moment().zone() + ')'); - } - test.equal(moment().zone(), new Date().getTimezoneOffset(), 'zone should equal getTimezoneOffset'); - test.done(); - }, - - "default format" : function(test) { - test.expect(1); - var isoRegex = /\d{4}.\d\d.\d\dT\d\d.\d\d.\d\d[\+\-]\d\d:\d\d/; - test.ok(isoRegex.exec(moment().format()), "default format (" + moment().format() + ") should match ISO"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/getters_setters.js b/api/node_modules/moment/test/moment/getters_setters.js deleted file mode 100644 index dc3d77bcdfd..00000000000 --- a/api/node_modules/moment/test/moment/getters_setters.js +++ /dev/null @@ -1,103 +0,0 @@ -var moment = require("../../moment"); - -exports.getters_setters = { - "getters" : function(test) { - test.expect(8); - - var a = moment([2011, 9, 12, 6, 7, 8, 9]); - test.equal(a.year(), 2011, 'year'); - test.equal(a.month(), 9, 'month'); - test.equal(a.date(), 12, 'date'); - test.equal(a.day(), 3, 'day'); - test.equal(a.hours(), 6, 'hour'); - test.equal(a.minutes(), 7, 'minute'); - test.equal(a.seconds(), 8, 'second'); - test.equal(a.milliseconds(), 9, 'milliseconds'); - test.done(); - }, - - "setters" : function(test) { - test.expect(8); - - var a = moment(); - a.year(2011); - a.month(9); - a.date(12); - a.hours(6); - a.minutes(7); - a.seconds(8); - a.milliseconds(9); - test.equal(a.year(), 2011, 'year'); - test.equal(a.month(), 9, 'month'); - test.equal(a.date(), 12, 'date'); - test.equal(a.day(), 3, 'day'); - test.equal(a.hours(), 6, 'hour'); - test.equal(a.minutes(), 7, 'minute'); - test.equal(a.seconds(), 8, 'second'); - test.equal(a.milliseconds(), 9, 'milliseconds'); - test.done(); - }, - - "setters - falsey values" : function(test) { - test.expect(1); - - var a = moment(); - // ensure minutes wasn't coincidentally 0 already - a.minutes(1); - a.minutes(0); - test.equal(a.minutes(), 0, 'falsey value'); - test.done(); - }, - - "chaining setters" : function(test) { - test.expect(7); - - var a = moment(); - a.year(2011) - .month(9) - .date(12) - .hours(6) - .minutes(7) - .seconds(8); - test.equal(a.year(), 2011, 'year'); - test.equal(a.month(), 9, 'month'); - test.equal(a.date(), 12, 'date'); - test.equal(a.day(), 3, 'day'); - test.equal(a.hours(), 6, 'hour'); - test.equal(a.minutes(), 7, 'minute'); - test.equal(a.seconds(), 8, 'second'); - test.done(); - }, - - "day setter" : function(test) { - test.expect(18); - - var a = moment([2011, 0, 15]); - test.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday'); - test.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday'); - test.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday'); - - a = moment([2011, 0, 9]); - test.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday'); - test.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday'); - test.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday'); - - a = moment([2011, 0, 12]); - test.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday'); - test.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday'); - test.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday'); - - test.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday'); - test.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday'); - test.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday'); - - test.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday'); - test.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday'); - test.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday'); - - test.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday'); - test.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday'); - test.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday'); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/humanize_duration.js b/api/node_modules/moment/test/moment/humanize_duration.js deleted file mode 100644 index b539851f51a..00000000000 --- a/api/node_modules/moment/test/moment/humanize_duration.js +++ /dev/null @@ -1,52 +0,0 @@ -var moment = require("../../moment"); - -exports.humanize_duration = { - "humanize duration" : function(test) { - test.expect(32); - moment.lang('en'); - // this syntax is deprecated. - // see moment.duration instead. - test.equal(moment.humanizeDuration(44, "seconds"), "a few seconds", "44 seconds = a few seconds"); - test.equal(moment.humanizeDuration(45, "seconds"), "a minute", "45 seconds = a minute"); - test.equal(moment.humanizeDuration(89, "seconds"), "a minute", "89 seconds = a minute"); - test.equal(moment.humanizeDuration(90, "seconds"), "2 minutes", "90 seconds = 2 minutes"); - test.equal(moment.humanizeDuration(44, "minutes"), "44 minutes", "44 minutes = 44 minutes"); - test.equal(moment.humanizeDuration(45, "minutes"), "an hour", "45 minutes = an hour"); - test.equal(moment.humanizeDuration(89, "minutes"), "an hour", "89 minutes = an hour"); - test.equal(moment.humanizeDuration(90, "minutes"), "2 hours", "90 minutes = 2 hours"); - test.equal(moment.humanizeDuration(5, "hours"), "5 hours", "5 hours = 5 hours"); - test.equal(moment.humanizeDuration(21, "hours"), "21 hours", "21 hours = 21 hours"); - test.equal(moment.humanizeDuration(22, "hours"), "a day", "22 hours = a day"); - test.equal(moment.humanizeDuration(35, "hours"), "a day", "35 hours = a day"); - test.equal(moment.humanizeDuration(36, "hours"), "2 days", "36 hours = 2 days"); - test.equal(moment.humanizeDuration(1, "days"), "a day", "1 day = a day"); - test.equal(moment.humanizeDuration(5, "days"), "5 days", "5 days = 5 days"); - test.equal(moment.humanizeDuration(1, "weeks"), "7 days", "1 week = 7 days"); - test.equal(moment.humanizeDuration(25, "days"), "25 days", "25 days = 25 days"); - test.equal(moment.humanizeDuration(26, "days"), "a month", "26 days = a month"); - test.equal(moment.humanizeDuration(30, "days"), "a month", "30 days = a month"); - test.equal(moment.humanizeDuration(45, "days"), "a month", "45 days = a month"); - test.equal(moment.humanizeDuration(46, "days"), "2 months", "46 days = 2 months"); - test.equal(moment.humanizeDuration(74, "days"), "2 months", "75 days = 2 months"); - test.equal(moment.humanizeDuration(76, "days"), "3 months", "76 days = 3 months"); - test.equal(moment.humanizeDuration(1, "months"), "a month", "1 month = a month"); - test.equal(moment.humanizeDuration(5, "months"), "5 months", "5 months = 5 months"); - test.equal(moment.humanizeDuration(344, "days"), "11 months", "344 days = 11 months"); - test.equal(moment.humanizeDuration(345, "days"), "a year", "345 days = a year"); - test.equal(moment.humanizeDuration(547, "days"), "a year", "547 days = a year"); - test.equal(moment.humanizeDuration(548, "days"), "2 years", "548 days = 2 years"); - test.equal(moment.humanizeDuration(1, "years"), "a year", "1 year = a year"); - test.equal(moment.humanizeDuration(5, "years"), "5 years", "5 years = 5 years"); - test.equal(moment.humanizeDuration(7200000), "2 hours", "7200000 = 2 minutes"); - test.done(); - }, - - "humanize duration with suffix" : function(test) { - test.expect(3); - moment.lang('en'); - test.equal(moment.humanizeDuration(44, "seconds", true), "in a few seconds", "44 seconds = a few seconds"); - test.equal(moment.humanizeDuration(-44, "seconds", true), "a few seconds ago", "44 seconds = a few seconds"); - test.equal(moment.humanizeDuration(44000, true), "in a few seconds", "44000 milliseconds = a few seconds"); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/is_moment.js b/api/node_modules/moment/test/moment/is_moment.js deleted file mode 100644 index 9b085cc1d46..00000000000 --- a/api/node_modules/moment/test/moment/is_moment.js +++ /dev/null @@ -1,27 +0,0 @@ -var moment = require('../../moment'); - -exports.is_moment = { - "is moment object": function(test) { - test.expect(11); - - var MyObj = function() {}; - MyObj.prototype.toDate = function() { - return new Date(); - } - - test.ok(moment.isMoment(moment()), 'simple moment object'); - test.ok(moment.isMoment(moment('invalid date')), 'invalid moment object'); - - test.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object'); - test.ok(!moment.isMoment(moment), 'moment function is not moment object'); - test.ok(!moment.isMoment(new Date()), 'date object is not moment object'); - test.ok(!moment.isMoment(Object), 'Object is not moment object'); - test.ok(!moment.isMoment('foo'), 'string is not moment object'); - test.ok(!moment.isMoment(1), 'number is not moment object'); - test.ok(!moment.isMoment(NaN), 'NaN is not moment object'); - test.ok(!moment.isMoment(null), 'null is not moment object'); - test.ok(!moment.isMoment(undefined), 'undefined is not moment object'); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/is_valid.js b/api/node_modules/moment/test/moment/is_valid.js deleted file mode 100644 index fe2278c3bd2..00000000000 --- a/api/node_modules/moment/test/moment/is_valid.js +++ /dev/null @@ -1,156 +0,0 @@ -var moment = require("../../moment"); - -exports.is_valid = { - "array bad month" : function (test) { - test.expect(2); - - test.equal(moment([2010, -1]).isValid(), false, 'month -1'); - test.equal(moment([2100, 12]).isValid(), false, 'month 12'); - - test.done(); - }, - - "array good month" : function (test) { - test.expect(24); - - for (var i = 0; i < 12; i++) { - test.equal(moment([2010, i]).isValid(), true, 'month ' + i); - test.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i); - } - - test.done(); - }, - - "array bad date" : function (test) { - test.expect(4); - - test.equal(moment([2010, 0, 0]).isValid(), false, 'date 0'); - test.equal(moment([2100, 0, 32]).isValid(), false, 'date 32'); - - test.equal(moment.utc([2010, 0, 0]).isValid(), false, 'utc date 0'); - test.equal(moment.utc([2100, 0, 32]).isValid(), false, 'utc date 32'); - - test.done(); - }, - - "array bad date leap year" : function (test) { - test.expect(8); - - test.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29'); - test.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29'); - test.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30'); - test.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30'); - - test.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29'); - test.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29'); - test.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30'); - test.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30'); - - test.done(); - }, - - "string + formats bad date" : function (test) { - test.expect(9); - - test.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array'); - test.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array'); - test.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first'); - test.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last'); - test.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both'); - test.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last'); - - test.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover'); - test.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover'); - test.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover'); - - test.done(); - }, - - "string nonsensical" : function (test) { - test.expect(1); - - test.equal(moment('fail').isValid(), false, 'string "fail"'); - test.done(); - }, - - "string nonsensical with format" : function (test) { - test.expect(2); - - test.equal(moment('fail', "MM-DD-YYYY").isValid(), false, 'string "fail" with format "MM-DD-YYYY"'); - test.equal(moment("xx-xx-2001", 'DD-MM-YYY').isValid(), false, 'string "xx-xx-2001" with format "MM-DD-YYYY"'); - test.done(); - }, - - "string with bad month name" : function (test) { - test.expect(2); - - moment.lang('en'); - - test.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '"Nam" is an invalid month'); - test.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '"Aug" is a valid month'); - - test.done(); - }, - - "invalid string iso 8601" : function (test) { - - var tests = [ - '2010-00-00', - '2010-01-00', - '2010-01-40', - '2010-01-01T24', - '2010-01-01T23:60', - '2010-01-01T23:59:60' - ]; - - test.expect(tests.length * 2); - - for (var i = 0; i < tests.length; i++) { - test.equal(moment(tests[i]).isValid(), false, tests[i] + ' should be invalid'); - test.equal(moment.utc(tests[i]).isValid(), false, tests[i] + ' should be invalid'); - } - test.done(); - }, - - "invalid string iso 8601 + timezone" : function (test) { - - var tests = [ - '2010-00-00+00:00', - '2010-01-00+00:00', - '2010-01-40+00:00', - '2010-01-40T24+00:00', - '2010-01-40T23:60+00:00', - '2010-01-40T23:59:60+00:00', - '2010-01-40T23:59:59.9999+00:00' - ]; - - test.expect(tests.length * 2); - - for (var i = 0; i < tests.length; i++) { - test.equal(moment(tests[i]).isValid(), false, tests[i] + ' should be invalid'); - test.equal(moment.utc(tests[i]).isValid(), false, tests[i] + ' should be invalid'); - } - test.done(); - }, - - "valid string iso 8601 + timezone" : function (test) { - var tests = [ - '2010-01-01', - '2010-01-30', - '2010-01-30T23+00:00', - '2010-01-30T23:59+00:00', - '2010-01-30T23:59:59+00:00', - '2010-01-30T23:59:59.999+00:00', - '2010-01-30T23:59:59.999-07:00', - '2010-01-30T00:00:00.000+07:00' - ]; - - test.expect(tests.length * 2); - - for (var i = 0; i < tests.length; i++) { - test.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid'); - test.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid'); - } - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/lang.js b/api/node_modules/moment/test/moment/lang.js deleted file mode 100644 index 2e3ba5da4e4..00000000000 --- a/api/node_modules/moment/test/moment/lang.js +++ /dev/null @@ -1,231 +0,0 @@ -var moment = require("../../moment"); - -exports.lang = { - "library getter" : function (test) { - test.expect(4); - - moment.lang('en'); - test.equal(moment.lang(), 'en', 'Lang should return en by default'); - - moment.lang('fr'); - test.equal(moment.lang(), 'fr', 'Lang should return the changed language'); - - moment.lang('en-gb'); - test.equal(moment.lang(), 'en-gb', 'Lang should return the changed language'); - - moment.lang('en'); - test.equal(moment.lang(), 'en', 'Lang should reset'); - - test.done(); - }, - - "library ensure inheritance" : function (test) { - test.expect(2); - - moment.lang('made-up', { - // I put them out of order - months : "February_March_April_May_June_July_August_September_October_November_December_January".split("_") - // the rest of the properties should be inherited. - }); - - test.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs'); - test.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them'); - - test.done(); - }, - - "library ensure inheritance LT L LL LLL LLLL" : function (test) { - test.expect(5); - - var lang = 'test-inherit-lt'; - - moment.lang(lang, { - longDateFormat : { - LT : "-[LT]-", - L : "-[L]-", - LL : "-[LL]-", - LLL : "-[LLL]-", - LLLL : "-[LLLL]-", - }, - calendar : { - sameDay : '[sameDay] LT', - nextDay : '[nextDay] L', - nextWeek : '[nextWeek] LL', - lastDay : '[lastDay] LLL', - lastWeek : '[lastWeek] LLLL', - sameElse : 'L' - } - }); - - moment.lang('es'); - - test.equal(moment().lang(lang).calendar(), "sameDay -LT-", "Should use instance lang in LT formatting"); - test.equal(moment().add('days', 1).lang(lang).calendar(), "nextDay -L-", "Should use instance lang in L formatting"); - test.equal(moment().add('days', -1).lang(lang).calendar(), "lastDay -LLL-", "Should use instance lang in LL formatting"); - test.equal(moment().add('days', 4).lang(lang).calendar(), "nextWeek -LL-", "Should use instance lang in LLL formatting"); - test.equal(moment().add('days', -4).lang(lang).calendar(), "lastWeek -LLLL-", "Should use instance lang in LLLL formatting"); - - test.done(); - }, - - "library langData" : function (test) { - test.expect(3); - moment.lang('en'); - - test.equal(moment.langData().months[0], 'January', 'no arguments returns global'); - test.equal(moment.langData('zh-cn').months[0], '一月', 'a string returns the language based on key'); - test.equal(moment.langData(moment().lang('es')).months[0], 'Enero', "if you pass in a moment it uses the moment's language"); - - test.done(); - }, - - "instance lang method" : function (test) { - test.expect(3); - moment.lang('en'); - - test.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global'); - test.equal(moment([2012, 5, 6]).lang('es').format('MMMM'), 'Junio', 'Use the instance specific language'); - test.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific language does not affect other moments'); - - test.done(); - }, - - "instance lang persists with manipulation" : function (test) { - test.expect(3); - moment.lang('en'); - - test.equal(moment([2012, 5, 6]).lang('es').add({days: 1}).format('MMMM'), 'Junio', 'With addition'); - test.equal(moment([2012, 5, 6]).lang('es').day(0).format('MMMM'), 'Junio', 'With day getter'); - test.equal(moment([2012, 5, 6]).lang('es').eod().format('MMMM'), 'Junio', 'With eod'); - - test.done(); - }, - - "instance lang persists with cloning" : function (test) { - test.expect(2); - moment.lang('en'); - - var a = moment([2012, 5, 6]).lang('es'), - b = a.clone(), - c = moment(a); - - test.equal(b.format('MMMM'), 'Junio', 'using moment.fn.clone()'); - test.equal(b.format('MMMM'), 'Junio', 'using moment()'); - - test.done(); - }, - - "duration lang method" : function (test) { - test.expect(3); - moment.lang('en'); - - test.equal(moment.duration({seconds: 44}).humanize(), 'a few seconds', 'Normally default to global'); - test.equal(moment.duration({seconds: 44}).lang('es').humanize(), 'unos segundos', 'Use the instance specific language'); - test.equal(moment.duration({seconds: 44}).humanize(), 'a few seconds', 'Using an instance specific language does not affect other durations'); - - test.done(); - }, - - "duration lang persists with cloning" : function (test) { - test.expect(1); - moment.lang('en'); - - var a = moment.duration({seconds: 44}).lang('es'), - b = moment.duration(a); - - test.equal(b.humanize(), 'unos segundos', 'using moment.duration()'); - test.done(); - }, - - "instance lang used with from" : function (test) { - test.expect(2); - moment.lang('en'); - - var a = moment([2012, 5, 6]).lang('es'), - b = moment([2012, 5, 7]); - - test.equal(a.from(b), 'hace un día', 'preserve language of first moment'); - test.equal(b.from(a), 'in a day', 'do not preserve language of second moment'); - - test.done(); - }, - - "month name callback function" : function (test) { - test.expect(3); - - function fakeReplace(m, format) { - if (/test/.test(format)) { - return "test"; - } - if (m.date() === 1) { - return "date"; - } - return 'default'; - } - - moment.lang('made-up', { - months : fakeReplace, - monthsShort : fakeReplace, - weekdays : fakeReplace, - weekdaysShort : fakeReplace, - weekdaysMin : fakeReplace - }); - - test.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string'); - test.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object'); - test.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object'); - - test.done(); - }, - - // the following tests should be removed after the 2.0.0 release as they will be deprecated - "lang accessors on the global object should exist < 2.0.0" : function (test) { - moment.lang('en'); - - var a = 'months|monthsShort|monthsParse|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem'.split('|'); - var i; - - test.expect(a.length); - - for (i = 0; i < a.length; i++) { - test.ok(moment[a[i]], "moment." + a[i] + " should exist"); - } - - test.done(); - }, - - // the following tests should be removed after the 2.0.0 release as they will be deprecated - "lang accessors on the global object should change < 2.0.0" : function (test) { - moment.lang('en'); - - var a = 'months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal'.split('|'); - var i; - var en = {}; - - test.expect(a.length); - - for (i = 0; i < a.length; i++) { - en[a[i]] = moment[a[i]]; - } - - moment.lang('fr'); - - for (i = 0; i < a.length; i++) { - test.notDeepEqual(en[a[i]], moment[a[i]], "the " + a[i] + " lang data should change on the global object"); - } - - test.done(); - }, - - "manip lang accessors on the global object < 2.0.0" : function (test) { - test.expect(1); - moment.lang('en'); - - moment.months = ["test"]; - test.equal(moment([2011, 0]).format('MMMM'), "test", "Should be able to manipulate the objects on the global object"); - - moment.lang('en'); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/leapyear.js b/api/node_modules/moment/test/moment/leapyear.js deleted file mode 100644 index 7a3dd263c43..00000000000 --- a/api/node_modules/moment/test/moment/leapyear.js +++ /dev/null @@ -1,13 +0,0 @@ -var moment = require("../../moment"); - -exports.leapyear = { - "leap year" : function(test) { - test.expect(4); - - test.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010'); - test.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100'); - test.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008'); - test.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000'); - test.done(); - } -}; diff --git a/api/node_modules/moment/test/moment/mutable.js b/api/node_modules/moment/test/moment/mutable.js deleted file mode 100644 index 4d45c94b187..00000000000 --- a/api/node_modules/moment/test/moment/mutable.js +++ /dev/null @@ -1,56 +0,0 @@ -var moment = require("../../moment"); - -exports.mutable = { - "manipulation methods" : function (test) { - - var mutableMethods = { - 'year': function (m){ return m.year(2011); }, - 'month': function (m){ return m.month(1); }, - 'date': function (m){ return m.date(9); }, - 'hours': function (m){ return m.hours(7); }, - 'minutes': function (m){ return m.minutes(33); }, - 'seconds': function (m){ return m.seconds(44); }, - 'milliseconds': function (m){ return m.milliseconds(55); }, - 'day': function (m){ return m.day(2); }, - 'startOf': function (m){ return m.startOf('week') }, - 'endOf': function (m){ return m.endOf('week') }, - 'add': function (m){ return m.add('days', 1) }, - 'subtract': function (m){ return m.subtract('years', 2) }, - 'local': function (m){ return m.local() }, - 'utc': function (m){ return m.utc() } - }; - - test.expect(14); - - for (method in mutableMethods) { - if (mutableMethods.hasOwnProperty(method)) { - var d = new Date(); - var d2 = mutableMethods[method](moment(d)).toDate(); - test.equal(d, d2, method + "() should be mutable"); - } - } - - test.done(); - }, - - "non mutable methods" : function (test) { - - var nonMutableMethods = { - 'sod': function (m){ return m.sod() }, - 'eod': function (m){ return m.eod() } - }; - - test.expect(2); - - for (method in nonMutableMethods){ - if (nonMutableMethods.hasOwnProperty(method)) { - var d = new Date(); - var d2 = nonMutableMethods[method](moment(d)).toDate(); - test.notEqual(d, d2, method + "() should not be mutable"); - } - } - - test.done(); - } - -}; diff --git a/api/node_modules/moment/test/moment/sod_eod.js b/api/node_modules/moment/test/moment/sod_eod.js deleted file mode 100644 index fd3a856889e..00000000000 --- a/api/node_modules/moment/test/moment/sod_eod.js +++ /dev/null @@ -1,232 +0,0 @@ -var moment = require("../../moment"); - -exports.eod_sod = { - "sod" : function(test) { - test.expect(7); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).sod(); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 0, "strip out the hours"); - test.equal(m.minutes(), 0, "strip out the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "eod" : function(test) { - test.expect(7); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).eod(); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 23, "set the hours"); - test.equal(m.minutes(), 59, "set the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "eod utc" : function(test) { - test.expect(1); - - var m2 = moment.utc(new Date(2011, 1, 2, 3, 4, 5, 6)); - test.equal(m2.eod().valueOf(), m2.hours(23).minutes(59).seconds(59).milliseconds(999).valueOf(), "Eod should equal manual hours/mins/seconds"); - - test.done(); - }, - - "start of year" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 0, "strip out the month"); - test.equal(m.date(), 1, "strip out the day"); - test.equal(m.hours(), 0, "strip out the hours"); - test.equal(m.minutes(), 0, "strip out the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of year" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 11, "set the month"); - test.equal(m.date(), 31, "set the day"); - test.equal(m.hours(), 23, "set the hours"); - test.equal(m.minutes(), 59, "set the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "start of month" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 1, "strip out the day"); - test.equal(m.hours(), 0, "strip out the hours"); - test.equal(m.minutes(), 0, "strip out the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of month" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 28, "set the day"); - test.equal(m.hours(), 23, "set the hours"); - test.equal(m.minutes(), 59, "set the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "start of day" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 0, "strip out the hours"); - test.equal(m.minutes(), 0, "strip out the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of day" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 23, "set the hours"); - test.equal(m.minutes(), 59, "set the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "start of hour" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 0, "strip out the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of hour" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 59, "set the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "start of minute" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 4, "keep the minutes"); - test.equal(m.seconds(), 0, "strip out the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of minute" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 4, "keep the minutes"); - test.equal(m.seconds(), 59, "set the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, - - "start of second" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 4, "keep the minutes"); - test.equal(m.seconds(), 5, "keep the the seconds"); - test.equal(m.milliseconds(), 0, "strip out the milliseconds"); - test.done(); - }, - - "end of second" : function(test) { - test.expect(8); - - var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'); - var ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'); - test.equal(+m, +ms, "Plural or singular should work"); - test.equal(m.year(), 2011, "keep the year"); - test.equal(m.month(), 1, "keep the month"); - test.equal(m.date(), 2, "keep the day"); - test.equal(m.hours(), 3, "keep the hours"); - test.equal(m.minutes(), 4, "keep the minutes"); - test.equal(m.seconds(), 5, "keep the seconds"); - test.equal(m.milliseconds(), 999, "set the seconds"); - test.done(); - }, -}; diff --git a/api/node_modules/moment/test/moment/utc.js b/api/node_modules/moment/test/moment/utc.js deleted file mode 100644 index 26a66a28c20..00000000000 --- a/api/node_modules/moment/test/moment/utc.js +++ /dev/null @@ -1,63 +0,0 @@ -var moment = require("../../moment"); - -exports.utc = { - "utc and local" : function(test) { - test.expect(7); - - var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)); - m.utc(); - // utc - test.equal(m.date(), 2, "the day should be correct for utc"); - test.equal(m.day(), 3, "the date should be correct for utc"); - test.equal(m.hours(), 3, "the hours should be correct for utc"); - - // local - m.local(); - if (m.zone() > 180) { - test.equal(m.date(), 1, "the date should be correct for local"); - test.equal(m.day(), 2, "the day should be correct for local"); - } else { - test.equal(m.date(), 2, "the date should be correct for local"); - test.equal(m.day(), 3, "the day should be correct for local"); - } - var zone = Math.ceil(m.zone() / 60); - var expected = (24 + 3 - zone) % 24; - test.equal(m.hours(), expected, "the hours (" + m.hours() + ") should be correct for local"); - test.equal(moment().utc().zone(), 0, "timezone in utc should always be zero"); - test.done(); - }, - - "creating with utc" : function(test) { - test.expect(7); - - test.equal(moment.utc().valueOf(), moment().valueOf(), "Calling moment.utc() should default to the current time"); - - var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]); - test.equal(m.date(), 2, "the day should be correct for utc array"); - test.equal(m.hours(), 3, "the hours should be correct for utc array"); - - m = moment.utc("2011-02-02 3:04:05", "YYYY-MM-DD HH:mm:ss"); - test.equal(m.date(), 2, "the day should be correct for utc parsing format"); - test.equal(m.hours(), 3, "the hours should be correct for utc parsing format"); - - m = moment.utc("2011-02-02T03:04:05+00:00"); - test.equal(m.date(), 2, "the day should be correct for utc parsing iso"); - test.equal(m.hours(), 3, "the hours should be correct for utc parsing iso"); - - test.done(); - }, - - "creating with utc without timezone" : function(test) { - test.expect(4); - - var m = moment.utc("2012-01-02T08:20:00"); - test.equal(m.date(), 2, "the day should be correct for utc parse without timezone"); - test.equal(m.hours(), 8, "the hours should be correct for utc parse without timezone"); - - m = moment.utc("2012-01-02T08:20:00+09:00"); - test.equal(m.date(), 1, "the day should be correct for utc parse with timezone"); - test.equal(m.hours(), 23, "the hours should be correct for utc parse with timezone"); - - test.done(); - } -}; diff --git a/api/node_modules/moment/test/zone.js b/api/node_modules/moment/test/zone.js deleted file mode 100644 index 5813fbc7e51..00000000000 --- a/api/node_modules/moment/test/zone.js +++ /dev/null @@ -1,181 +0,0 @@ -var terminal = require('child_process').spawn('bash'), - path = require('path'), - util = require('util'), - nodeunit = require('nodeunit'); - -var ZONES; - - -/****************************** - Get Timezone -******************************/ - -var currentTimezone = ''; - -function getTimezone() { - var term = require('child_process').spawn('bash'); - - term.stdout.on('data', function (data) { - currentTimezone = data.toString().replace('Time Zone: ', ''); - getTimezoneList(); - }); - - term.stdin.write('systemsetup gettimezone'); - term.stdin.end(); -} - -function getTimezoneList() { - var term = require('child_process').spawn('bash'), - data = ''; - - term.stdout.on('data', function (d) { - data += d; - }); - - term.stdout.on('end', function () { - data = data.replace('Time Zones:', ''); - ZONES = data.match(/\S+/g); - // console.log(ZONES); - startTests(); - }); - - term.stdin.write('systemsetup listtimezones'); - term.stdin.end(); - -} - - - -/****************************** - Set Timezone -******************************/ - -var currentTimezone = ''; - -function setTimezone() { - terminal.stdin.write('systemsetup settimezone ' + currentTimezone); - terminal.stdin.end(); -} - - -/****************************** - Tests -******************************/ - - -var files = ['test/moment'], - paths = files.map(function (p) { - return path.join(process.cwd(), p); - }); - -var globalfailures = ''; - -var f = 0; -var p = 0; - -function errorLog(assertion) { - if (!assertion.error) { - return assertion; - } - - var e = assertion.error; - if (e.actual && e.expected) { - var actual = util.inspect(e.actual, false, 10).replace(/\n$/, ''), - expected = util.inspect(e.expected, false, 10).replace(/\n$/, ''), - multiline = (actual.indexOf('\n') !== -1 || expected.indexOf('\n') !== -1), - spacing = (multiline ? '\n' : ' '); - e._message = e.message; - e.stack = ( - e.name + ':' + spacing + - actual + spacing + e.operator + spacing + - expected + '\n' + - e.stack.split('\n').slice(1).join('\n') - ); - } - return assertion; -} - -var zone = '', - nextZone = ''; - -function runTestIfNeeded() { - if (zone === nextZone) { - return; - } - nextZone = zone; - - console.log("-----------------------"); - console.log(zone + " testing started..."); - nodeunit.runFiles(paths, { - testDone: function (name, assertions) { - if (assertions.failures()) { - console.log('\nFAILURE: ' + name); - assertions.forEach(function (a) { - if (a.failed()) { - a = errorLog(a); - if (a.error && a.message) { - console.log('Assertion Message: ' + a.message); - } - console.log(a.error.stack); - } - }); - } - }, - done: function (assertions) { - if (assertions.failures()) { - console.log('\n' + zone + ' had ' + assertions.failures() + ' failures'); - globalfailures += zone + ' had ' + assertions.failures() + ' failures\n'; - f++; - } else { - console.log(zone + ' passed all tests!'); - p++; - } - console.log("-----------------------"); - nextTest(); - } - }); -} - -function runTest(zoned) { - zone = zoned; - terminal.stdin.write('systemsetup settimezone ' + zone + '\n'); -} - -terminal.stdout.on('data', function(d) { - setTimeout(runTestIfNeeded, 100); -}); - - -var i = 0; - -function startTests() { - nextTest(); - //setTimezone(); -} - -function nextTest() { - if (i < ZONES.length) { - runTest(ZONES[i]); - } else { - console.log("----------------------"); - console.log("----------------------"); - console.log(globalfailures); - console.log("----------------------"); - console.log("----------------------"); - console.log("--- Total Failing " + f); - console.log("----------------------"); - console.log("--- Total Passing " + p); - console.log("----------------------"); - console.log("----------------------"); - setTimezone(); - } - i++; -} - - -/****************************** - Start it off -******************************/ - - -getTimezone(); \ No newline at end of file diff --git a/api/node_modules/mongoskin/.jshintrc b/api/node_modules/mongoskin/.jshintrc deleted file mode 100644 index bbe0a3e8a05..00000000000 --- a/api/node_modules/mongoskin/.jshintrc +++ /dev/null @@ -1,43 +0,0 @@ -{ - "predef": [ - "phantom", - "module", - "require", - "__dirname", - "process", - "console", - "it", - "describe", - "before", - "beforeEach", - "after", - "should", - "rewire", - "$" - ], - - "browser": true, - "node" : true, - "es5": true, - "bitwise": true, - "curly": true, - "eqeqeq": true, - "forin": false, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonew": true, - "plusplus": false, - "undef": true, - "strict": true, - "trailing": false, - "globalstrict": true, - "nonstandard": true, - "white": false, - "indent": 2, - "expr": true, - "multistr": true, - "onevar": false -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/.npmignore b/api/node_modules/mongoskin/.npmignore deleted file mode 100644 index cbd931a5c04..00000000000 --- a/api/node_modules/mongoskin/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -data/ -deps/ -coverage.html -lib-cov -test/ -test_results.md diff --git a/api/node_modules/mongoskin/.travis.yml b/api/node_modules/mongoskin/.travis.yml deleted file mode 100644 index f0afa7e8376..00000000000 --- a/api/node_modules/mongoskin/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 -services: - - mongodb diff --git a/api/node_modules/mongoskin/AUTHORS b/api/node_modules/mongoskin/AUTHORS deleted file mode 100644 index 99e04c19eb9..00000000000 --- a/api/node_modules/mongoskin/AUTHORS +++ /dev/null @@ -1,16 +0,0 @@ -# Total 12 contributors. -# Ordered by date of first contribution. -# Auto-generated (http://github.com/dtrejo/node-authors) on Tue Aug 14 2012 02:58:57 GMT+0800 (CST). - -Gui Lin (https://github.com/guileen) -François de Metz (https://github.com/francois2metz) -fengmk2 (http://fengmk2.github.com) -Quang Van (https://github.com/quangv) -Matt Perpick (https://github.com/clutchski) -humanchimp (https://github.com/humanchimp) -Joe Faber (https://github.com/jlfaber) -Harvey McQueen (https://github.com/hmcqueen) -Paul Gebheim (https://github.com/paulirish) -Aneil Mallavarapu (https://github.com/amallavarapu) -wmertens (https://github.com/wmertens) -Rakshit Menpara (https://github.com/deltasquare4) diff --git a/api/node_modules/mongoskin/History.md b/api/node_modules/mongoskin/History.md deleted file mode 100644 index 25af581994a..00000000000 --- a/api/node_modules/mongoskin/History.md +++ /dev/null @@ -1,61 +0,0 @@ - -0.5.0 / 2012-12-29 -================== - - * fixed unsafe mode warnning log - * Merge pull request #84 from kingpearl/master - * MongoDB 1.2.x support - * Merge pull request #73 from jockster/master - * Merge pull request #75 from voke/patch-1 - * Fix typo - * fixed bind() test cases; - * Minor error in readme. Now updated - * Updated readme according to issue #72 - -0.3.4 / 2011-03-24 - * fix global leaks - -0.3.3 / 2011-03-15 -================== - * Add rootCollection option to SkinGridStore.exist - -0.3.2 / 2011-03-01 -================== - * exports all classes of node-mongodb-native - -0.3.1 / 2011-02-26 -================== - * bug fix #33 - -0.3.0 / 2011-01-19 -================== - * add ReplSet support - * bug fix - -0.2.3 / 2011-01-03 -================== - * add db.toObjectID - * fix #25 for node-mongodb-native update - -0.2.2 / 2011-12-02 -================== - * add bind support for embeded collections, e.g. db.bind('system.js') - * add method `toId` to SkinDB - * add property `ObjectID`, `bson_serializer` to SkinDB. - * SkinCollection.prototype.id is now deprecated. - -0.2.1 / 2011-11-18 -================== - * add ObjectId support for XXXXById - -0.2.0 / 2011-11-06 -================== - * add SkinDB.gridfs - -0.1.3 / 2011-05-24 -================== - * add SkinCollection.removeById - -0.1.2 / 2011-04-30 -================== - * add mongoskin.router diff --git a/api/node_modules/mongoskin/LICENSE b/api/node_modules/mongoskin/LICENSE deleted file mode 100644 index e91ac035ea1..00000000000 --- a/api/node_modules/mongoskin/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/mongoskin/Makefile b/api/node_modules/mongoskin/Makefile deleted file mode 100644 index 94d697ebfc6..00000000000 --- a/api/node_modules/mongoskin/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -TESTS = test/ -TESTTIMEOUT = 60000 -REPORTER = spec -MOCHA_OPTS = -PROJECT_DIR = $(shell pwd) -MONGOSKIN_REPLICASET = false -JSCOVERAGE = ./node_modules/jscover/bin/jscover -SUPPORT_VERSIONS := \ - 1.0.0 1.0.1 1.0.2 \ - 1.1.0-beta 1.1.1 1.1.2 1.1.3 1.1.4 - -test: - @npm install - @if ! test -d deps/mongodb; then \ - git clone git://github.com/mongodb/node-mongodb-native.git deps/mongodb; \ - fi - @cd deps/mongodb && npm install && git pull && cd ../.. - @NODE_ENV=test MONGOSKIN_REPLICASET=$(MONGOSKIN_REPLICASET) \ - ./node_modules/mocha/bin/mocha --recursive \ - --reporter $(REPORTER) --timeout $(TESTTIMEOUT) \ - $(MOCHA_OPTS) $(TESTS) - -test-debug: - @$(MAKE) test MOCHA_OPTS="--debug-brk" - -test-replicaset: - @$(MAKE) test MONGOSKIN_REPLICASET=true - -lib-cov: - @rm -rf $@ - @$(JSCOVERAGE) lib $@ - -test-cov: lib-cov - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=dot - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html - @$(MAKE) test REPORTER=markdown > test_results.md - -test-version: - @for version in $(SUPPORT_VERSIONS); do \ - echo "test with mongodb@$$version"; \ - npm install mongodb@$$version --loglevel=warn; \ - $(MAKE) test REPORTER=dot; \ - done - -.PHONY: test-replicaset test-version test-cov test lib-cov diff --git a/api/node_modules/mongoskin/Readme.md b/api/node_modules/mongoskin/Readme.md deleted file mode 100644 index ba39ce97b91..00000000000 --- a/api/node_modules/mongoskin/Readme.md +++ /dev/null @@ -1,724 +0,0 @@ -# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin) - -![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png) - -This project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native). -The api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first. - -## Test - -* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md) -* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html) - -## Test pass [mongodb] versions - -* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` - when connection open error. -* 1.0.x -* 1.1.x -* 1.2.x - -```bash -$ make test -``` - - - -# Mongoskin document - -* [Nodejs mongodb drivers comparation](#comparation) -* [Install](#install) -* [Quick Start](#quickstart) - * [Connect easier](#quickstart-1) - * [Server options and BSON options](#quickstart-2) - * [Similar API with node-mongodb-native](#quickstart-3) - * [Cursor easier](#quickstart-4) - * [MVC helper](#quickstart-5) -* [Documentation](#documentation) - * [Module](#module) - * [SkinServer](#skinserver) - * [SkinDb](#skindb) - * [SkinCollection](#skincollection) - * [Additional methods](#additional-collection-op) - * [Collection operation](#inherit-collection-op) - * [Indexes](#inherit-indexes) - * [Querying](#inherit-query) - * [Aggregation](#inherit-aggregation) - * [Inserting](#inherit-inserting) - * [Updating](#inherit-updating) - * [Removing](#inherit-removing) - * [SkinCursor](#skincursor) - - - -Nodejs Mongodb Driver Comparison -======== - -node-mongodb-native --------- - -One of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build -on top of it, including mongoskin. Unfortunately, it has an awkward interface with too many -callbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model. - -See [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs) - -mongoose --------- - -Mongoose provides an ORM way to hold Collection instance as Model, - you should define schema first. But why mongodb need schema? - Some guys like me, want to write code from application layer but not database layer, - and we can use any fields without define it before. - - Mongoose provide a DAL that you can do validation, and write your middlewares. - But some guys like me would like to validate manually, I think it is the tao of mongodb. - - If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice. - -mongoskin --------- - -Mongoskin is an easy to use driver of mongodb for nodejs, - it is similar with mongo shell, powerful like node-mongodb-native, - and support additional javascript method binding, which make it can act as a Model(in document way). - -It will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native), - and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29). - -If you need validation, you can use [node-iform](https://github.com/guileen/node-iform). - -[Back to index](#index) - - - -Install -======== - -```bash -$ npm install mongoskin -``` - -[Back to index](#index) - - - - -Quick Start -======== - - **Is mongoskin synchronized?** - -Nope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29). -**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native) - - - -Connect easier --------- -You can connect to mongodb easier now. - -```js -var mongo = require('mongoskin'); -mongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) { - console.dir(items); -}) -``` - - - -Server options and BSON options --------- -You can also set `auto_reconnect` options querystring. -And native_parser options will automatically set if native_parser is available. - -```js -var mongo = require('mongoskin'); -var db = mongo.db('localhost:27017/test?auto_reconnect'); -``` - - - -Similar API with node-mongodb-native --------- -You can do everything that node-mongodb-native can do. - -```js -db.createCollection(...); -db.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {}); -db.collection('posts').hint = 'slug'; -db.collection('posts').findOne({slug: 'whats-up'}, function (err, post) { - // do something -}); -``` - - - -Cursor easier --------- - -```js -db.collection('posts').find().toArray(function (err, posts) { - // do something -}); -``` - - - -MVC helper --------- - -You can bind **additional methods** for collection. -It is very useful if you want to use MVC patterns with nodejs and mongodb. -You can also invoke collection by properties after bind, -it could simplfy your `require`. - -To keep your code in line with DRY principles, it's possible to create your own -data layer by for example, setting up your own validators and/or default values -inside the MVC methods as shown below in the config example - -```js -db.bind('posts', { - findTop10 : function (fn) { - this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn); - }, - removeTagWith : function (tag, fn) { - this.remove({tags:tag},fn); - } - } -}); - -db.bind('settings', { - - getAll: function(user, fn) { - - this.find({user: user}).toArray(function(err, settings) { - - // We want to set a default currency from within our app instead of storing it - // for every user - settings.currency = (typeof settings.currency !== "undefined") ? settings.currency : 'USD'; - - fn(err, settings); - - }); - } -}); - - -db.bind('comments'); - -db.collection('posts').removeTagWith('delete', function (err, replies) { - //do something -}); - -db.posts.findTop10(function (err, topPosts) { - //do something -}); - -db.comments.find().toArray(function (err, comments) { - //do something -}); -``` - -[Back to index](#index) - - - - -Documentation -======== - -for more information, see the source. - -[Back to index](#index) - - - - -Module --------- - -### MongoSkin Url format - -``` -[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]` -``` - -e.g. - -``` -localhost/blog -mongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect -127.0.0.1?auto_reconnect=false -``` - -### db(serverURL[s], dbOptions, replicasetOptions) - -Get or create instance of [SkinDb](#skindb). - -```js -var db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5'); -``` - -for ReplSet server - -```js -var db = mongoskin.db([ - '192.168.0.1:27017/?auto_reconnect=true', - '192.168.0.2:27017/?auto_reconnect=true', - '192.168.0.3:27017/?auto_reconnect=true' -], { - database: 'testdb', - safe: true -}, { - connectArbiter: false, - socketOptions: { - timeout: 2000 - } -}); -``` - -### router(select) - -select is `function(collectionName)` returns a database instance, means router collectionName to that database. - -```js -var db = mongo.router(function (coll_name) { - switch(coll_name) { - case 'user': - case 'message': - return mongo.db('192.168.1.3/auth_db'); - default: - return mongo.db('192.168.1.2/app_db'); - } -}); -db.bind('user', require('./shared-user-methods')); -var users = db.user; //auth_db.user -var messages = db.collection('message'); // auth_db.message -var products = db.collection('product'); //app_db.product -``` - -### classes extends frome node-mongodb-native - -* BSONPure -* BSONNative -* BinaryParser -* Binary -* Code -* DBRef -* Double -* MaxKey -* MinKey -* ObjectID -* Symbol -* Timestamp -* Long -* BaseCommand -* DbCommand -* DeleteCommand -* GetMoreCommand -* InsertCommand -* KillCursorCommand -* QueryCommand -* UpdateCommand -* MongoReply -* Admin -* Collection -* Connection -* Server -* ReplSetServers -* Cursor -* Db -* connect -* Grid -* Chunk -* GridStore -* native -* pure - - -[Back to index](#index) - - - -SkinServer --------- - -### SkinServer(server) - -Construct SkinServer from native Server instance. - -### db(dbname, username=null, password=null) - -Construct [SkinDb](#skindb) from SkinServer. - -[Back to index](#index) - - - -SkinDb --------- - -### SkinDb(db, username=null, password=null) - -Construct SkinDb. - -### open(callback) - -Connect to database, retrieval native -[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) -instance, callback is function(err, db). - -### collection(collectionName) - -Retrieval [SkinCollection](#skincollection) instance of specified collection name. - - - -### bind(collectionName) - -### bind(collectionName, SkinCollection) - -### bind(collectionName, extendObject1, extendObject2 ...) - -Bind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name). -You can also bind additional methods to the SkinCollection, it is useful when -you want to reuse a complex operation. This will also affect -db.collection(name) method. - -e.g. - -```js -db.bind('book', { - firstBook: function (fn) { - this.findOne(fn); - } -}); -db.book.firstBook(function (err, book) {}); -``` - -### all the methods from Db.prototype - -See [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information. - -[Back to index](#index) - - - -SkinCollection --------- - -See [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information. - - -### open(callback) - -Retrieval native -[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) -instance, callback is function(err, collection). - -### id(hex) - -Equivalent to - -```js -db.bson_serializer.ObjectID.createFromHexString(hex); -``` - -See [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548) - - - - -### Collection operation - -```js -checkCollectionName(collectionName) -options(callback) -rename(collectionName, callback) -drop(callback) -``` - - - -### Indexes - -```js -createIndex(fieldOrSpec, unique, callback) -ensureIndex(fieldOrSpec, unique, callback) -indexInformation(callback) -dropIndex(indexName, callback) -dropIndexes(callback) -``` - -See [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md) - - - -### Queries - -See [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md) - -#### findItems(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.toArray(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findEach(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.each(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findById(id, ..., callback) - -Equivalent to - -```js -collection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417) - -#### find(...) - -If the last parameter is function, it is equivalent to native -[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) -method, else it will return a future [SkinCursor](#skincursor). - -e.g. - -```js -// callback -db.book.find({}, function (err, cursor) {/* do something */}); -// future SkinCursor -db.book.find().toArray(function (err, books) {/* do something */}); -``` - -#### normalizeHintField(hint) - -#### find - -```js -/** - * Various argument possibilities - * 1 callback - * 2 selector, callback, - * 2 callback, options // really?! - * 3 selector, fields, callback - * 3 selector, options, callback - * 4,selector, fields, options, callback - * 5 selector, fields, skip, limit, callback - * 6 selector, fields, skip, limit, timeout, callback - * - * Available options: - * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize - */ -``` - -#### findAndModify(query, sort, update, options, callback) - -```js -/** - Fetch and update a collection - query: a filter for the query - sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate - update: an object describing the modifications to the documents selected by the query - options: - remove: set to a true to remove the object before returning - new: set to true if you want to return the modified object rather than the original. Ignored for remove. - upsert: true/false (perform upsert operation) -**/ -``` - -#### findOne(queryObject, options, callback) - - - -### Aggregation - -#### mapReduce(map, reduce, options, callback) - -e.g. - -```js -var map = function () { - emit(test(this.timestamp.getYear()), 1); -} - -var reduce = function (k, v){ - count = 0; - for (i = 0; i < v.length; i++) { - count += v[i]; - } - return count; -} -var options = {scope: {test: new client.bson_serializer.Code(t.toString())}}; -collection.mapReduce(map, reduce, options, function (err, collection) { - collection.find(function (err, cursor) { - cursor.toArray(function (err, results) { - test.equal(2, results[0].value) - finished_test({test_map_reduce_functions_scope:'ok'}); - }) -}) -``` - -#### group(keys, condition, initial, reduce, command, callback) - -e.g. - -```js -collection.group([], {}, {"count":0}, "function (obj, prev) { prev.count++; }", true, function(err, results) {}); -``` - -#### count(query, callback) -#### distinct(key, query, callback) - - - -### Inserting - -#### insert(docs, options, callback) - - - -### Updating - -#### save(doc, options, callback) - -```js -/** - Update a single document in this collection. - spec - a associcated array containing the fields that need to be present in - the document for the update to succeed - - document - an associated array with the fields to be updated or in the case of - a upsert operation the fields to be inserted. - - Options: - upsert - true/false (perform upsert operation) - multi - true/false (update all documents matching spec) - strict - true/false (perform check if the operation failed, required extra call to db) - Deprecated Options: - safe - true/false (perform check if the operation failed, required extra call to db) -**/ -``` - -#### update(spec, document, options, callback) - -#### updateById(_id, ..., callback) - -Equivalent to - -```js -collection.update({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md) - - - -### Removing - -#### remove(selector, options, callback) - -#### removeById(_id, options, callback) - -[Back to index](#index) - - - -SkinCursor ---------- - -See [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1) -of node-mongodb-native for more information. - -All these methods will return the SkinCursor itself. - -```js -sort(keyOrList, [direction], [callback]) -limit(limit, [callback]) -skip(skip, [callback]) -batchSize(skip, [callback]) - -toArray(callback) -each(callback) -count(callback) -nextObject(callback) -getMore(callback) -explain(callback) -``` - -[Back to index](#index) - -## How to validate input? - -I wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) -base on [node-validator](https://github.com/chriso/node-validator) - -## Authors - -Below is the output from `git-summary`. - -``` - project: node-mongoskin - commits: 112 - active : 54 days - files : 39 - authors: - 49 Lin Gui 43.8% - 34 guilin æ¡‚æž— 30.4% - 9 fengmk2 8.0% - 5 guilin 4.5% - 2 François de Metz 1.8% - 2 Paul Gebheim 1.8% - 2 Gui Lin 1.8% - 1 humanchimp 0.9% - 1 Aneil Mallavarapu 0.9% - 1 wmertens 0.9% - 1 Harvey McQueen 0.9% - 1 Joe Faber 0.9% - 1 Matt Perpick 0.9% - 1 Quang Van 0.9% - 1 Rakshit Menpara 0.9% - 1 Wout Mertens 0.9% -``` - -## License - -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/api/node_modules/mongoskin/docs/docco.css b/api/node_modules/mongoskin/docs/docco.css deleted file mode 100644 index 5aa0a8d73f7..00000000000 --- a/api/node_modules/mongoskin/docs/docco.css +++ /dev/null @@ -1,186 +0,0 @@ -/*--------------------- Layout and Typography ----------------------------*/ -body { - font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; - font-size: 15px; - line-height: 22px; - color: #252519; - margin: 0; padding: 0; -} -a { - color: #261a3b; -} - a:visited { - color: #261a3b; - } -p { - margin: 0 0 15px 0; -} -h1, h2, h3, h4, h5, h6 { - margin: 0px 0 15px 0; -} - h1 { - margin-top: 40px; - } -#container { - position: relative; -} -#background { - position: fixed; - top: 0; left: 525px; right: 0; bottom: 0; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - z-index: -1; -} -#jump_to, #jump_page { - background: white; - -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; - -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - font: 10px Arial; - text-transform: uppercase; - cursor: pointer; - text-align: right; -} -#jump_to, #jump_wrapper { - position: fixed; - right: 0; top: 0; - padding: 5px 10px; -} - #jump_wrapper { - padding: 0; - display: none; - } - #jump_to:hover #jump_wrapper { - display: block; - } - #jump_page { - padding: 5px 0 3px; - margin: 0 0 25px 25px; - } - #jump_page .source { - display: block; - padding: 5px 10px; - text-decoration: none; - border-top: 1px solid #eee; - } - #jump_page .source:hover { - background: #f5f5ff; - } - #jump_page .source:first-child { - } -table td { - border: 0; - outline: 0; -} - td.docs, th.docs { - max-width: 450px; - min-width: 450px; - min-height: 5px; - padding: 10px 25px 1px 50px; - overflow-x: hidden; - vertical-align: top; - text-align: left; - } - .docs pre { - margin: 15px 0 15px; - padding-left: 15px; - } - .docs p tt, .docs p code { - background: #f8f8ff; - border: 1px solid #dedede; - font-size: 12px; - padding: 0 0.2em; - } - .pilwrap { - position: relative; - } - .pilcrow { - font: 12px Arial; - text-decoration: none; - color: #454545; - position: absolute; - top: 3px; left: -20px; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; - } - td.docs:hover .pilcrow { - opacity: 1; - } - td.code, th.code { - padding: 14px 15px 16px 25px; - width: 100%; - vertical-align: top; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - } - pre, tt, code { - font-size: 12px; line-height: 18px; - font-family: Monaco, Consolas, "Lucida Console", monospace; - margin: 0; padding: 0; - } - - -/*---------------------- Syntax Highlighting -----------------------------*/ -td.linenos { background-color: #f0f0f0; padding-right: 10px; } -span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } -body .hll { background-color: #ffffcc } -body .c { color: #408080; font-style: italic } /* Comment */ -body .err { border: 1px solid #FF0000 } /* Error */ -body .k { color: #954121 } /* Keyword */ -body .o { color: #666666 } /* Operator */ -body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -body .cp { color: #BC7A00 } /* Comment.Preproc */ -body .c1 { color: #408080; font-style: italic } /* Comment.Single */ -body .cs { color: #408080; font-style: italic } /* Comment.Special */ -body .gd { color: #A00000 } /* Generic.Deleted */ -body .ge { font-style: italic } /* Generic.Emph */ -body .gr { color: #FF0000 } /* Generic.Error */ -body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -body .gi { color: #00A000 } /* Generic.Inserted */ -body .go { color: #808080 } /* Generic.Output */ -body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -body .gs { font-weight: bold } /* Generic.Strong */ -body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -body .gt { color: #0040D0 } /* Generic.Traceback */ -body .kc { color: #954121 } /* Keyword.Constant */ -body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ -body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ -body .kp { color: #954121 } /* Keyword.Pseudo */ -body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ -body .kt { color: #B00040 } /* Keyword.Type */ -body .m { color: #666666 } /* Literal.Number */ -body .s { color: #219161 } /* Literal.String */ -body .na { color: #7D9029 } /* Name.Attribute */ -body .nb { color: #954121 } /* Name.Builtin */ -body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -body .no { color: #880000 } /* Name.Constant */ -body .nd { color: #AA22FF } /* Name.Decorator */ -body .ni { color: #999999; font-weight: bold } /* Name.Entity */ -body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -body .nf { color: #0000FF } /* Name.Function */ -body .nl { color: #A0A000 } /* Name.Label */ -body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -body .nt { color: #954121; font-weight: bold } /* Name.Tag */ -body .nv { color: #19469D } /* Name.Variable */ -body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -body .w { color: #bbbbbb } /* Text.Whitespace */ -body .mf { color: #666666 } /* Literal.Number.Float */ -body .mh { color: #666666 } /* Literal.Number.Hex */ -body .mi { color: #666666 } /* Literal.Number.Integer */ -body .mo { color: #666666 } /* Literal.Number.Oct */ -body .sb { color: #219161 } /* Literal.String.Backtick */ -body .sc { color: #219161 } /* Literal.String.Char */ -body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ -body .s2 { color: #219161 } /* Literal.String.Double */ -body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -body .sh { color: #219161 } /* Literal.String.Heredoc */ -body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -body .sx { color: #954121 } /* Literal.String.Other */ -body .sr { color: #BB6688 } /* Literal.String.Regex */ -body .s1 { color: #219161 } /* Literal.String.Single */ -body .ss { color: #19469D } /* Literal.String.Symbol */ -body .bp { color: #954121 } /* Name.Builtin.Pseudo */ -body .vc { color: #19469D } /* Name.Variable.Class */ -body .vg { color: #19469D } /* Name.Variable.Global */ -body .vi { color: #19469D } /* Name.Variable.Instance */ -body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/api/node_modules/mongoskin/examples/admin.js b/api/node_modules/mongoskin/examples/admin.js deleted file mode 100644 index f32eee53546..00000000000 --- a/api/node_modules/mongoskin/examples/admin.js +++ /dev/null @@ -1,9 +0,0 @@ -var db = require('./config').db; - -db.admin.listDatabases(function(err, result){ - if(err) { - console.traceError(err); - } - console.log(result); - db.close(); -}) diff --git a/api/node_modules/mongoskin/examples/close.js b/api/node_modules/mongoskin/examples/close.js deleted file mode 100644 index 73fafaa1381..00000000000 --- a/api/node_modules/mongoskin/examples/close.js +++ /dev/null @@ -1,15 +0,0 @@ -var db = require('./config').db; - -db.collection('test').findOne({}, function(err, data) { - if(!err) { - console.log('db has open'); - console.log(data); - } -}); - -process.on('SIGINT', function() { - console.log('Recieve SIGINT'); - db.close(function(){ - console.log('database has closed'); - }) -}) diff --git a/api/node_modules/mongoskin/examples/config.js b/api/node_modules/mongoskin/examples/config.js deleted file mode 100644 index 80c9184a9d7..00000000000 --- a/api/node_modules/mongoskin/examples/config.js +++ /dev/null @@ -1,5 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -exports.db = mongoskin.db('localhost/test'); - -mongoskin.db('localhost', { database: 'test' }); diff --git a/api/node_modules/mongoskin/examples/generateId.js b/api/node_modules/mongoskin/examples/generateId.js deleted file mode 100644 index 6acb4bfe4df..00000000000 --- a/api/node_modules/mongoskin/examples/generateId.js +++ /dev/null @@ -1,31 +0,0 @@ -var redis = require('redis').createClient() - , shorten = require('shorten')(redis) - , async = require('async') - , db = require('./config').db - ; - -db.bind('user'); - -function log(err) { - if(err) { - console.log(err.stack); - } -} - -function createUser(user, callback) { - - async.waterfall([ - function(fn) { - shorten.nextId('user', fn); - } - , function(uid, fn) { - user.uid = uid; - db.user.save(user, fn); - } - ], callback); - -} - -for(var i = 0; i<10; i++) { - createUser({name: 'user' + i}, log); -} diff --git a/api/node_modules/mongoskin/examples/gridfs.js b/api/node_modules/mongoskin/examples/gridfs.js deleted file mode 100644 index ce476a3bba0..00000000000 --- a/api/node_modules/mongoskin/examples/gridfs.js +++ /dev/null @@ -1,13 +0,0 @@ -var db = require('./config').db; - -db.gridfs().open('test.txt', 'w', function(err, gs) { - gs.write('blablabla', function(err, reply) { - gs.close(function(err, reply){ - db.gridfs().open('test.txt', 'r' ,function(err, gs) { - gs.read(function(err, reply){ - console.log(reply.toString()); - }); - }); - }); - }); -}); diff --git a/api/node_modules/mongoskin/examples/insert.js b/api/node_modules/mongoskin/examples/insert.js deleted file mode 100644 index bba4c58007f..00000000000 --- a/api/node_modules/mongoskin/examples/insert.js +++ /dev/null @@ -1,8 +0,0 @@ -var db = require('./config').db; - -db.collection('test').insert({foo: 'bar'}, function(err, result) { - console.log(result); - db.collection('test').drop(); - db.close(); - -}); diff --git a/api/node_modules/mongoskin/examples/replSetBenchmark.js b/api/node_modules/mongoskin/examples/replSetBenchmark.js deleted file mode 100644 index bacd59eb3d0..00000000000 --- a/api/node_modules/mongoskin/examples/replSetBenchmark.js +++ /dev/null @@ -1,45 +0,0 @@ - -var mongo = require('../'); - -var conf = { - hosts: [ - '127.0.0.1:27110/?auto_reconnect', - '127.0.0.1:27111/?auto_reconnect' - ], - dataDB: 'test' -}; - -var db = exports.db = mongo.db(conf.hosts, { - database: conf.dataDB -}); - -var noop = function() {}; - -db.bind('user'); -// db.user.ensureIndex({ name: 1 }, { unique: true }, noop); -// db.user.ensureIndex({ enable: 1 }, noop); -// db.user.ensureIndex({ created_at: 1, enable: 1 }, noop); - -var counter = 0; -setInterval(function () { - db.user.findItems({ name: 'name_' + counter }, function (err, items) { - if (err) { - console.error('findItems user error', err); - } - if (items) { - console.log('total: %d users', items.length); - } - }); - db.user.insert({ - name: 'name_' + counter, - createtime: new Date() - }, function(err, user) { - if (err) { - console.error('insert user error', err); - } - if (user && user[0]) { - console.log('new: %d %s', counter, user[0]._id); - } - }); - counter++; -}, 10); diff --git a/api/node_modules/mongoskin/examples/replset.js b/api/node_modules/mongoskin/examples/replset.js deleted file mode 100644 index 4e3dc616ccf..00000000000 --- a/api/node_modules/mongoskin/examples/replset.js +++ /dev/null @@ -1,10 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -var db = mongoskin.db(['127.0.0.1:27017'], { - database: 'test' -}); - -db.open(function(err, data) { - console.log(err && err.stack); - console.log(data); -}); diff --git a/api/node_modules/mongoskin/examples/update.js b/api/node_modules/mongoskin/examples/update.js deleted file mode 100644 index 080d84e3807..00000000000 --- a/api/node_modules/mongoskin/examples/update.js +++ /dev/null @@ -1,19 +0,0 @@ -var db = require('./config').db; -var articles = db.collection('articles'); -articles.insert({foo: 'bar', val: 'val1'}, function(err, result) { - - console.log(result); - articles.update({foo:'bar'}, {foo: 'bar', val:'val2'}, {strict: true}, function(err, result) { - - console.log(result); - articles.find({foo: 'bar'}).toArray(function(err, docs){ - - console.log(docs); - articles.drop(); - db.close(); - - }); - - }) - -}); diff --git a/api/node_modules/mongoskin/index.js b/api/node_modules/mongoskin/index.js deleted file mode 100644 index dd996affa95..00000000000 --- a/api/node_modules/mongoskin/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = process.env.MONGOSKIN_COV ? require('./lib-cov/mongoskin') : require('./lib/mongoskin'); \ No newline at end of file diff --git a/api/node_modules/mongoskin/integration/integration_tests.js b/api/node_modules/mongoskin/integration/integration_tests.js deleted file mode 100644 index 7a34db70fa1..00000000000 --- a/api/node_modules/mongoskin/integration/integration_tests.js +++ /dev/null @@ -1,203 +0,0 @@ -GLOBAL.DEBUG = true; - -var assert = require('assert'), - mongo = require('../lib/mongoskin'); - -console.log('======== test MongoSkin.db ========'); -(function(){ - var username = 'testuser', - password = 'password'; - - db = mongo.db('localhost/test'); - db.open(function(err, db) { - assert.ok(!err); - assert.ok(db, err && err.stack); - db.addUser(username, password, function(err, result){ - var authdb = mongo.db(username + ':' + password +'@localhost/test'); - authdb.open(function(err, db){ - assert.ok(!err, err && err.stack); - }); - var faildb = mongo.db(username + ':wrongpassword@localhost/test'); - faildb.open(function(err, db){ - assert.ok(err, 'should not auth'); - assert.ok(!db, 'should not return db'); - }); - }); - }); -})(); - -(function(){ - db = mongo.db('db://admin:admin@localhost:27017/test?auto_reconnect'); - db.open(function(err, db){ - assert.ok(err instanceof Error); - }) -})(); - -var bindToBlog = { - first: function(fn) { - this.findOne(fn); - } -}; - -console.log('======== test MongoSkin.router ========'); -var testdb1 = mongo.db('localhost/test1'); -var testdb2 = mongo.db('localhost/test2'); -var router = mongo.router(function(name){ - switch(name){ - case 'user': - case 'message': - return testdb1; - default: - return testdb2; - } -}); -assert.equal(router.collection('user'), testdb1.collection('user'), 'user should router to testdb1'); -assert.equal(router.collection('message'), testdb1.collection('message'), 'message should router to testdb1'); -assert.equal(router.collection('others'), testdb2.collection('others'), 'others should router to testdb2'); -router.bind('user'); -router.bind('others'); -assert.equal(router.user, testdb1.user, 'user property should router to testdb1'); -assert.equal(router.others, testdb2.others, 'user property should router to testdb1'); - -console.log('======== test MongoSkin.bind ========'); -var db = mongo.db('localhost/test_mongoskin'); -db.bind('blog', bindToBlog); -db.bind('users'); -assert.equal(db.blog.first, bindToBlog.first); -assert.ok(db.users); - -console.log('======== test SkinDb bson ========'); -assert.ok(db.ObjectID.createFromHexString('a7b79d4dca9d730000000000')); - -console.log('======== test SkinDb.bind ========'); -db.bind('blog2', bindToBlog); -db.bind('user2'); -assert.equal(db.blog2.first, bindToBlog.first); -assert.ok(db.user2); - -console.log('======== test SkinDb.open ========'); -(function(){ - var db1, db2; - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db1 = db; - assert.equal(db1.state, 'connected'); - if (db2) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db2 = db; - assert.equal(db2.state, 'connected'); - if (db1) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - -})() - -console.log('======== test normal method of SkinDb ========'); -db.createCollection('test_createCollection', function(err, collection) { - assert.equal(db.db.state, 'connected'); - assert.ok(collection, err && err.stack); -}); - - -console.log('======== test SkinDb.collection ========'); -assert.equal(db.blog, db.collection('blog')); - -console.log('======== test SkinCollection.open ========'); -var coll1, coll2; -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll1 = coll; - if (coll2) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll2 = coll; - if (coll1) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -console.log('======== test normal method of SkinCollection ========'); -db.collection('test_normal').ensureIndex([['a',1]], function(err, replies){ - assert.ok(replies, err && err.stack); -}); - -console.log('======== test SkinCollection.drop ========'); -db.collection('test_find').drop(function(err, replies){ - assert.ok(!err, err && err.stack); -}); - -console.log('======== test SkinCollection.find ========'); -collection = db.collection('test_find'); -collection.insert([{a:1},{a:2},{a:3},{a:4}], function(err, replies){ - assert.ok(replies, err && err.stack); - console.log('======== test SkinCollection.findById ========'); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.equal(item.a, 1); - console.log('======== test SkinCollection.removeById ========'); - collection.removeById(replies[0]._id.toString(), function(err, reply){ - assert.ok(!err, err && err.stack); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.ok(!err); - assert.ok(!item); - }); - }); - }); -}); - - - collection.findItems(function(err, items){ - assert.ok(items, err && err.stack); - console.log('found '+ items.length + ' items'); - }); - collection.findEach(function(err, item){ - assert.ok(!err, err && err.stack); - }); - collection.find(function(err, cursor){ - assert.ok(cursor, err && err.stack); - }); - - console.log('======== test SkinCursor ========'); - collection.find().toArray(function(err, items){ - console.log('======== test find cursor toArray========'); - assert.ok(items, err && err.stack); - }); - collection.find().each(function(err, item){ - console.log('======== test find cursor each========'); - assert.ok(!err, err && err.stack); - }); - collection.find().sort({a:-1}).limit(2).skip(1).toArray(function(err, items){ - console.log('======== test cursor sort() limit() skip() ========'); - assert.ok(!err, err && err.stack); - console.dir(items); - }); - -console.log('======== deep future test ========'); -(function(){ - var db2 = mongo.db('localhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(!err, err && err.stack); - }) -})(); - -(function(){ - var db2 = mongo.db('unknownhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(err); - }) -})(); -/* -console.log('======== test SkinDb.close ========'); -db.close(); -assert.equal(db.db.state, 'notConnected'); -*/ - diff --git a/api/node_modules/mongoskin/integration/longlive.js b/api/node_modules/mongoskin/integration/longlive.js deleted file mode 100644 index 828f71a1bdb..00000000000 --- a/api/node_modules/mongoskin/integration/longlive.js +++ /dev/null @@ -1,28 +0,0 @@ -var mongo = require('../'); -var db = mongo.db('192.168.0.103/test'); -// var db = mongo.db('127.0.0.1/test'); -var myconsole = require('myconsole'); - -var foo = db.collection('foo'); - -setInterval(function() { - foo.insert({foo:'foo'}, function(err, result){ - if(err) return myconsole.error(err); - foo.count(function(err, count){ - if(err) return myconsole.error(err); - myconsole.log('count: %d', count); - foo.find().limit(10).toArray(function(err, arr) { - if(err) return myconsole.error(err); - myconsole.log('arr: %d', arr.length); - }) - }) - }) -}, 500); - -process.on('SIGINT', function(){ - myconsole.log('SIGINT') - foo.drop(function(err){ - if(err) myconsole.error(err); - process.exit(); - }) -}) diff --git a/api/node_modules/mongoskin/lib/mongoskin/admin.js b/api/node_modules/mongoskin/lib/mongoskin/admin.js deleted file mode 100644 index 035e2087d7b..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/admin.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - admin.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var Admin = require('mongodb').Admin; -var utils = require('./utils'); -var constant = require('./constant'); - -/** - * SkinAdmin - * - * @param {SkinDb} skinDb - * @constructor - * @api public - */ -var SkinAdmin = exports.SkinAdmin = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; - this.admin = null; -}; - -utils.inherits(SkinAdmin, utils.SkinObject); - -/** - * Retrieve mongodb.Admin instance. - * - * @param {Function(err, admin)} callback - * @return {SkinAdmin} this - * @api public - */ -SkinAdmin.prototype.open = function (callback) { - if (this.state === constant.STATE_OPEN) { - callback(null, this.admin); - return this; - } - this.emitter.once('open', callback); - if (this.state === constant.STATE_OPENNING) { - return this; - } - this.state = constant.STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.admin = null; - this.state = constant.STATE_CLOSE; - } else { - this.admin = new Admin(db); - this.state = constant.STATE_OPEN; - } - this.emitter.emit('open', err, this.admin); - }.bind(this)); - return this; -}; - -for (var key in Admin.prototype) { - var method = Admin.prototype[key]; - utils.bindSkin('SkinAdmin', SkinAdmin, 'admin', key, method); -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/lib/mongoskin/collection.js b/api/node_modules/mongoskin/lib/mongoskin/collection.js deleted file mode 100644 index 20302026747..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/collection.js +++ /dev/null @@ -1,300 +0,0 @@ -/*! - * mongoskin - collection.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - bind these methods from Collection.prototype to Provider - - methods: - insert - checkCollectionName - remove - rename - save - update - distinct - count - drop - findAndModify - find - normalizeHintField - findOne - createIndex - ensureIndex - indexInformation - dropIndex - dropIndexes - mapReduce - group - options -*/ -var __slice = Array.prototype.slice; -var events = require('events'); -var Collection = require('mongodb').Collection; -var SkinCursor = require('./cursor').SkinCursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * Construct SkinCollection from SkinDb and collectionName - * use skinDb.collection('name') usually - * - * @param {SkinDb} skinDb - * @param {String} collectionName - * @param {Object} [options] collection options - * @constructor - * @api public - */ -var SkinCollection = exports.SkinCollection = function (skinDb, collectionName, options) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(50); - - this.options = options; - this.skinDb = skinDb; - this.ObjectID = this.skinDb.ObjectID; - this.collectionName = collectionName; - this.collection = null; - this.internalHint = null; - this.__defineGetter__('hint', function () { - return this.internalHint; - }); - this.__defineSetter__('hint', function (value) { - this.internalHint = value; - this.open(function (err, collection) { - collection.hint = value; - this.internalHint = collection.hint; - }.bind(this)); - }); -}; - -utils.inherits(SkinCollection, utils.SkinObject); - -for (var _name in Collection.prototype) { - var method = Collection.prototype[_name]; - utils.bindSkin('SkinCollection', SkinCollection, 'collection', _name, method); -} - -/* - * find is a special method, because it could return a SkinCursor instance - */ -SkinCollection.prototype._find = SkinCollection.prototype.find; - -/** - * Retrieve mongodb.Collection - * - * @param {Function(err, collection)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.collection); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.state = STATE_CLOSE; - return this.emitter.emit('open', err, null); - } - db.collection(this.collectionName, this.options, function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - } else { - this.state = STATE_OPEN; - this.collection = collection; - if (this.hint) { - this.collection.hint = this.hit; - } - } - this.emitter.emit('open', err, collection); - }.bind(this)); - }.bind(this)); - break; - } - return this; -}; - -/** - * Close current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.close = function (callback) { - this.collection = null; - this.state = STATE_CLOSE; - return this; -}; - -/** - * Drop current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.drop = function (callback) { - this.skinDb.dropCollection(this.collectionName, callback); - this.close(); - return this; -}; - -/** - * same args as find, but use Array as callback result but not use Cursor - * - * findItems(args, function (err, items) {}); - * - * same as - * - * find(args).toArray(function (err, items) {}); - * - * or using `mongodb.collection.find()` - * - * find(args, function (err, cursor) { - * cursor.toArray(function (err, items) { - * }); - * }); - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, docs)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findItems = function (query, options, callback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.toArray(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * find and cursor.each(fn). - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, item)} eachCallback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findEach = function (query, options, eachCallback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.each(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * @deprecated use `SkinDb.toId` instead - * - * @param {String} hex - * @return {ObjectID|String} - * @api public - */ -SkinCollection.prototype.id = function (hex) { - return this.skinDb.toId(hex); -}; - -/** - * Operate by object.`_id` - * - * @param {String} methodName - * @param {String|ObjectID|Number} id - * @param {Arguments|Array} args - * @return {SkinCollection} this - * @api private - */ -SkinCollection.prototype._operateById = function (methodName, id, args) { - args = __slice.call(args); - args[0] = {_id: this.skinDb.toId(id)}; - this[methodName].apply(this, args); - return this; -}; - -/** - * Find one object by _id. - * - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err, doc)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findById = function (id, callback) { - return this._operateById('findOne', id, arguments); -}; - -/** - * Update doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Object} doc - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.updateById = function (id, doc, callback) { - return this._operateById('update', id, arguments); -}; - -/** - * Remove doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.removeById = function (id, callback) { - return this._operateById('remove', id, arguments); -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB. - * - * @param {Object} query - * @param {Object} options - * @param {Function(err, docs)} callback - * @return {SkinCursor|SkinCollection} if last argument is not a function, then returns a SkinCursor, - * otherise return this - * @api public - */ -SkinCollection.prototype.find = function (query, options, callback) { - var args = __slice.call(arguments); - if (args.length > 0 && typeof args[args.length - 1] === 'function') { - this._find.apply(this, args); - return this; - } else { - return new SkinCursor(null, this, args); - } -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/lib/mongoskin/constant.js b/api/node_modules/mongoskin/lib/mongoskin/constant.js deleted file mode 100644 index b9fb90704ac..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/constant.js +++ /dev/null @@ -1,15 +0,0 @@ -/*! - * mongoskin - constant.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -exports.DEFAULT_PORT = 27017; - -exports.STATE_CLOSE = 0; -exports.STATE_OPENNING = 1; -exports.STATE_OPEN = 2; \ No newline at end of file diff --git a/api/node_modules/mongoskin/lib/mongoskin/cursor.js b/api/node_modules/mongoskin/lib/mongoskin/cursor.js deleted file mode 100644 index a879d80a473..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/cursor.js +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * mongoskin - cursor.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter; -var Cursor = require('mongodb').Cursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -var SkinCursor = exports.SkinCursor = function (cursor, skinCollection, args) { - utils.SkinObject.call(this); - - this.cursor = cursor; - this.skinCollection = skinCollection; - this.args = args || []; - this.emitter = new EventEmitter(); - if (cursor) { - this.state = STATE_OPEN; - } -}; - -utils.inherits(SkinCursor, utils.SkinObject); - -/** - * Retrieve mongodb.Cursor instance. - * - * @param {Function(err, cursor)} callback - * @return {SkinCursor} this - * @api public - */ -SkinCursor.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.cursor); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinCollection.open(function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - this.emitter.emit('open', err); - return; - } - // copy args - var args = this.args.slice(); - args.push(function (err, cursor) { - if (cursor) { - this.state = STATE_OPEN; - this.cursor = cursor; - } - this.emitter.emit('open', err, cursor); - }.bind(this)); - collection.find.apply(collection, args); - }.bind(this)); - break; - } - return this; -}; - -[ - // callbacks - 'toArray', 'each', 'count', 'nextObject', 'getMore', 'explain', - // self return - 'sort', 'limit', 'skip', 'batchSize', - // unsupported - //'rewind', 'close' ,... -].forEach(function (name) { - var method = Cursor.prototype[name]; - utils.bindSkin('SkinCursor', SkinCursor, 'cursor', name, method); -}); diff --git a/api/node_modules/mongoskin/lib/mongoskin/db.js b/api/node_modules/mongoskin/lib/mongoskin/db.js deleted file mode 100644 index f954a52ff5b..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/db.js +++ /dev/null @@ -1,254 +0,0 @@ -/*! - * mongoskin - db.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var mongodb = require('mongodb'); -var utils = require('./utils'); -var SkinAdmin = require('./admin').SkinAdmin; -var SkinCollection = require('./collection').SkinCollection; -var SkinGridStore = require('./gridfs').SkinGridStore; -var Db = mongodb.Db; -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * SkinDb - * - * @param {Db} dbconn, mongodb.Db instance - * @param {String} [username] - * @param {String} [password] - * @constructor - * @api public - */ -var SkinDb = exports.SkinDb = function (dbconn, username, password) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(100); - - this._dbconn = dbconn; - this.db = null; - this.username = username; - this.password = password; - this.admin = new SkinAdmin(this); - this._collections = {}; - this.bson_serializer = dbconn.bson_serializer; - this.ObjectID = mongodb.ObjectID /* 0.9.7-3-2 */ || dbconn.bson_serializer.ObjectID /* <= 0.9.7 */; -}; - -utils.inherits(SkinDb, utils.SkinObject); - -/** - * Convert to ObjectID. - * - * @param {String} hex - * @return {ObjectID} - */ -SkinDb.prototype.toObjectID = SkinDb.prototype.toId = function (hex) { - if (hex instanceof this.ObjectID) { - return hex; - } - if (!hex || hex.length !== 24) { - return hex; - } - return this.ObjectID.createFromHexString(hex); -}; - - -/** - * Open the database connection. - * - * @param {Function(err, nativeDb)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback && callback(null, this.db); - break; - case STATE_OPENNING: - // if call 'open' method multi times before opened - callback && this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - var onDbOpen = function (err, db) { - if (!err && db) { - this.db = db; - this.state = STATE_OPEN; - } else { - db && db.close(); - // close the openning connection. - this._dbconn.close(); - this.db = null; - this.state = STATE_CLOSE; - } - this.emitter.emit('open', err, this.db); - }.bind(this); - callback && this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this._dbconn.open(function (err, db) { - if (db && this.username) { - // do authenticate - db.authenticate(this.username, this.password, function (err) { - onDbOpen(err, db); - }); - } else { - onDbOpen(err, db); - } - }.bind(this)); - break; - } - return this; -}; - -/** - * Close the database connection. - * - * @param {Function(err)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.close = function (callback) { - if (this.state === STATE_CLOSE) { - callback && callback(); - } else if (this.state === STATE_OPEN) { - this.state = STATE_CLOSE; - this.db.close(callback); - } else if (this.state === STATE_OPENNING) { - var that = this; - this.emitter.once('open', function (err, db) { - that.state = STATE_CLOSE; - db ? db.close(callback) : callback && callback(err); - }); - } - return this; -}; - -/** - * Create or retrieval skin collection - * - * @param {String} name, the collection name. - * @param {Object} [options] collection options. - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.collection = function (name, options) { - var collection = this._collections[name]; - if (!collection) { - this._collections[name] = collection = new SkinCollection(this, name, options); - } - return collection; -}; - -/** - * gridfs - * - * @return {SkinGridStore} - * @api public - */ -SkinDb.prototype.gridfs = function () { - return this.skinGridStore || (this.skinGridStore = new SkinGridStore(this)); -}; - -/** - * bind additional method to SkinCollection - * - * 1. collectionName - * 2. collectionName, extends1, extends2,... extendsn - * 3. collectionName, SkinCollection - * - * @param {String} collectionName - * @param {Object|SkinCollection} [options] - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.bind = function (collectionName, options) { - var args = __slice.call(arguments); - var name = args[0]; - - if (typeof name !== 'string' || !name.trim()) { - throw new Error('Must provide collection name to bind.'); - } - if (args.length === 1) { - return this.bind(name, this.collection(name)); - } - if (args.length === 2 && args[1].constructor === SkinCollection) { - this._collections[name] = args[1]; - Object.defineProperty(this, name, { - value: args[1], - writable: false, - enumerable: true - }); - // support bind for system.js - var names = name.split('.'); - if (names.length > 1){ - var prev = this, next; - for (var i = 0; i < names.length - 1; i++) { - next = prev[names[i]]; - if (!next) { - next = {}; - Object.defineProperty(prev, names[i], { - value: next, - writable: false, - enumerable : true - }); - } - prev = next; - } - Object.defineProperty(prev, names[names.length - 1], { - value: args[1], - writable: false, - enumerable : true - }); - } - return args[1]; - } - - var isOptions = false; - var argsIndex = 1; - if (options && typeof options === 'object') { - isOptions = true; - argsIndex = 2; - for (var k in options) { - if (typeof options[k] === 'function') { - isOptions = false; - argsIndex = 1; - break; - } - } - } - var collection = this.collection(name, isOptions ? options : null); - for (var len = args.length; argsIndex < len; argsIndex++) { - var extend = args[argsIndex]; - if (typeof extend !== 'object') { - throw new Error('the args[' + argsIndex + '] should be object, but is `' + extend + '`'); - } - utils.extend(collection, extend); - } - return this.bind(name, collection); -}; - -var IGNORE_NAMES = [ - 'bind', 'open', 'close', 'collection', 'admin', 'state' -]; -// bind method of mongodb.Db to SkinDb -for (var key in Db.prototype) { - if (!key || key[0] === '_' || IGNORE_NAMES.indexOf(key) >= 0) { - continue; - } - var method = Db.prototype[key]; - utils.bindSkin('SkinDb', SkinDb, 'db', key, method); -} diff --git a/api/node_modules/mongoskin/lib/mongoskin/gridfs.js b/api/node_modules/mongoskin/lib/mongoskin/gridfs.js deleted file mode 100644 index 603e9e9a67c..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/gridfs.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - gridfs.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var GridStore = require('mongodb').GridStore; -var utils = require('./utils'); - -/** - * @param filename: filename or ObjectId - */ -var SkinGridStore = exports.SkinGridStore = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; -}; - -utils.inherits(SkinGridStore, utils.SkinObject); - -/** - * @param id - * @param filename - * @param mode - * @param options - * @param callback - * callback(err, gridStoreObject) - */ -SkinGridStore.prototype.open = function (id, filename, mode, options, callback) { - var args = Array.prototype.slice.call(arguments); - callback = args.pop(); - this.skinDb.open(function (err, db) { - var gs = new GridStore(db, args[0], args[1], args[2], args[3]); - var props = { - length: gs.length, - contentType: gs.contentType, - uploadDate: gs.uploadDate, - metadata: gs.metadata, - chunkSize: gs.chunkSize - }; - - gs.open(function (error, reply) { - callback(error, reply, props); - }); - }); -}; - -/** - * @param filename: filename or ObjectId - */ -SkinGridStore.prototype.unlink = SkinGridStore.prototype.remove = function (filename, callback) { - this.skinDb.open(function (err, db) { - GridStore.unlink(db, filename, callback); - }); -}; - -SkinGridStore.prototype.exist = function (filename, rootCollection, callback) { - this.skinDb.open(function (err, db) { - GridStore.exist(db, filename, rootCollection, callback); - }); -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/lib/mongoskin/index.js b/api/node_modules/mongoskin/lib/mongoskin/index.js deleted file mode 100644 index db051fc3115..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/index.js +++ /dev/null @@ -1,200 +0,0 @@ -/*! - * mongoskin - index.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var url = require('url'); -var Router = require('./router').Router; -var mongo = require('mongodb'); -var SkinServer = require('./server').SkinServer; -var SkinDb =require('./db').SkinDb; -var Db = mongo.Db; -var Server = mongo.Server; -var ReplSetServers = mongo.ReplSetServers; -var BSONNative = mongo.BSONNative; -var constant = require('./constant'); -var DEFAULT_PORT = constant.DEFAULT_PORT; - -function toBool(value) { - return value !== undefined && value !== 'false' && value !== 'no' && value !== 'off'; -} - -/** - * parse the database url to config - * - * [*://]username:password@host[:port]/database?options - * - * @param {String} serverUrl - * @return {Object} config - * - {String} host - * - {Number} port, default is `DEFAULT_PORT`. - * - {String} [database], no database by default. - * - {Object} options - * - {Bool} auto_reconnect, default is `false`. - * - {Number} poolSize, default is `1`. - * - {String} [username], no username by default. - * - {String} [password], no password by default. - * @api private - */ -var parseUrl = function (serverUrl) { - serverUrl = /\w+:\/\//.test(serverUrl) ? serverUrl : 'db://' + serverUrl; - var uri = url.parse(serverUrl, true); - var config = {}; - var serverOptions = uri.query; - - config.host = uri.hostname; - config.port = parseInt(uri.port, 10) || DEFAULT_PORT; - if (uri.pathname) { - config.database = uri.pathname.replace(/\//g, ''); - } - config.options = {}; - config.options.auto_reconnect = toBool(serverOptions.auto_reconnect); - config.options.poolSize = parseInt(serverOptions.poolSize || 1, 10); - if (uri && uri.auth) { - var auth = uri.auth; - var separator = auth.indexOf(':'); - config.username = auth.substr(0, separator); - config.password = auth.substr(separator + 1); - } - return config; -}; - -/** - * constructor Server from url - * - * @param {String} serverUrl - * @return {Server} - * @api private - */ -var parseServer = function (serverUrl) { - var config = parseUrl(serverUrl); - return new Server(config.host, config.port, config.options); -}; - -/* - * exports mongo classes ObjectID Long Code DbRef ... to mongoskin - */ -for (var key in mongo) { - exports[key] = mongo[key]; -} - -/** - * constructor SkinDb from serverURL[s] - * - * ReplicaSet: mongoskin.db(serverURLs, dbOptions, replicasetOptions) - * - * ```js - * mongoskin.db([ - * '192.168.0.1:27017/', - * '192.168.0.2/?auto_reconnect', - * '192.168.0.3' - * ], {database: 'mydb'}, {connectArbiter: false, socketOptions: {timeout: 2000}}); - * ``` - * - * Single Server: mongoskin.db(dbURL, options) - * - * ```js - * mongoskin.db('192.168.0.1:27017/mydb'); - * // or - * mongoskin.db('192.168.0.1:27017', {database: 'mydb'}); - * // set the connection timeout to `2000ms` - * mongoskin.db('192.168.0.1:27017', {database: 'mydb', socketOptions: {timeout: 2000}}); - * ``` - * - * @param {String|Array} serverUrl or server urls. - * @param {Object} [dbOptions] - * - {Object} socketOptions: @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#socket-options - * - the other, @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#db-options - * @param {Object} [replicasetOptions], options for replicaset. - * The detail of this options, please - * @see https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/connection/repl_set.js#L27. - * @return {SkinDb} - * @api public - */ -exports.db = function (serverUrl, dbOptions, replicasetOptions) { - dbOptions = dbOptions || {}; - - var server, database, config; - - if (Array.isArray(serverUrl)) { - if (!dbOptions.database) { - throw new Error('Please provide a database in `dbOptions` to connect.'); - } - database = dbOptions.database; - - var len = serverUrl.length; - var servers = []; - for (var i = 0; i < len; i++) { - config = parseUrl(serverUrl[i]); - if (config.database || config.username) { - console.log('MONGOSKIN:WARN: database or username found in RepliSet server URL, ' + serverUrl[i]); - } - servers.push(new Server(config.host, config.port, config.options)); - } - server = new ReplSetServers(servers, replicasetOptions); - } else { - config = parseUrl(serverUrl); - database = dbOptions.database || config.database; - if (!database) { - throw new Error('Please provide a database to connect to.'); - } - var socketOptions = dbOptions.socketOptions; - if (socketOptions) { - delete dbOptions.socketOptions; - config.options.socketOptions = socketOptions; - } - server = new Server(config.host, config.port, config.options); - - if (dbOptions.username === undefined) { - dbOptions.username = config.username; - dbOptions.password = config.password; - } - } - - var skinServer = new SkinServer(server); - return skinServer.db(database, dbOptions); -}; - -/** - * select different db by collection name - * - * @param select `function(name)` returns SkinDb - * - * ```js - * var router = mongoskin.router(function (name) { - * swhich (name) { - * case 'user': - * case 'group': - * return authDb; - * default: - * return appDb; - * } - * }); - * router.collection('user') - * ``` - * - * @param {Function(name)} select - * @return {Router} - * @api public - */ -exports.router = function (select) { - return new Router(select); -}; - -/* - * export Skin classes from ./db ./collection ./cursor ./admin - */ -['server', 'db', 'collection', 'cursor', 'admin'].forEach(function (path) { - var module = require('./' + path); - for (var name in module) { - exports[name] = module[name]; - } -}); diff --git a/api/node_modules/mongoskin/lib/mongoskin/router.js b/api/node_modules/mongoskin/lib/mongoskin/router.js deleted file mode 100644 index 1e7bf301d98..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/router.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * mongoskin - router.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - * Router - * - * @param {Function(name)} select - * @constructor - * @api public - */ -var Router = exports.Router = function (select) { - this._select = select; - this._collections = {}; -}; - -/** - * Bind custom methods - * - * @param {String} name, collection name. - * @param {Object} [options] - * @return {Router} this - * @api public - */ -Router.prototype.bind = function (name, options) { - var args = Array.prototype.slice.call(arguments); - var database = this._select(name); - var collection = database.bind.apply(database, args); - this._collections[name] = collection; - Object.defineProperty(this, name, { - value: collection, - writable: false, - enumerable: true - }); - return this; -}; - -Router.prototype.collection = function (name) { - return this._collections[name] || (this._collections[name] = this._select(name).collection(name)); -}; diff --git a/api/node_modules/mongoskin/lib/mongoskin/server.js b/api/node_modules/mongoskin/lib/mongoskin/server.js deleted file mode 100644 index 54baaf44dfd..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/server.js +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * mongoskin - server.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var mongodb = require('mongodb'); -var Db = mongodb.Db; -var Server = mongodb.Server; -var SkinDb = require('./db').SkinDb; - -/** - * Construct SkinServer with native Server - * - * @param {Server} server - * @constructor - * @api public - */ -var SkinServer = exports.SkinServer = function (server) { - this.server = server; - this._cache_ = {}; -}; - -/** - * Create SkinDb from a SkinServer - * - * @param {String} name database name - * @param {Object} [options] - * @return {SkinDb} - * @api public - */ -SkinServer.prototype.db = function (name, options) { - options = options || {}; - var username = options.username || ''; - var key = username + '@' + name; - var skinDb = this._cache_[key]; - if (!skinDb || skinDb.fail) { - var password = options.password; - if (!options.native_parser) { - options.native_parser = !! mongodb.BSONNative; - } - var db = new Db(name, this.server, options); - skinDb = new SkinDb(db, username, password); - this._cache_[key] = skinDb; - } - return skinDb; -}; diff --git a/api/node_modules/mongoskin/lib/mongoskin/utils.js b/api/node_modules/mongoskin/lib/mongoskin/utils.js deleted file mode 100644 index 9b98231e607..00000000000 --- a/api/node_modules/mongoskin/lib/mongoskin/utils.js +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * mongoskin - utils.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var EventEmitter = require('events').EventEmitter; -var constant = require('./constant'); -var STATE_OPEN = constant.STATE_OPEN; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_CLOSE = constant.STATE_CLOSE; - -exports.inherits = require('util').inherits; - -exports.error = function (err, args, name) { - var cb = args.pop(); - if (cb && typeof cb === 'function') { - cb(err); - } else { - console.error("Error occured with no callback to handle it while calling " + name, err); - } -}; - -/** - * SkinObject - * - * @constructor - * @api public - */ -exports.SkinObject = function () { - this.emitter = new EventEmitter(); - this.state = STATE_CLOSE; -}; - -/** - * Skin method binding. - * - * @param {String} objName - * @param {Function} obj - * @param {String} nativeObjName - * @param {String} methodName - * @param {Function} method - * @return {Function} - */ -exports.bindSkin = function (objName, obj, nativeObjName, methodName, method) { - if (typeof method !== 'function') { - return; - } - return obj.prototype[methodName] = function () { - var args = __slice.call(arguments); - if (this.state === STATE_OPEN) { - method.apply(this[nativeObjName], args); - return this; - } - this.open(function (err, nativeObj) { - if (err) { - exports.error(err, args, objName + '.' + methodName); - } else { - return method.apply(nativeObj, args); - } - }); - return this; - }; -}; - -exports.extend = function (destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; -}; - -exports.noop = function () {}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/logo.png b/api/node_modules/mongoskin/logo.png deleted file mode 100644 index c8de074af05..00000000000 Binary files a/api/node_modules/mongoskin/logo.png and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/.travis.yml b/api/node_modules/mongoskin/node_modules/mongodb/.travis.yml deleted file mode 100644 index 0140117b64d..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.10 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md b/api/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md deleted file mode 100644 index 2a1c52e2abd..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -## Contributing to the driver - -### Bugfixes - -- Before starting to write code, look for existing [tickets](https://github.com/mongodb/node-mongodb-native/issues) or [create one](https://github.com/mongodb/node-mongodb-native/issues/new) for your specific issue. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch. -- Fork the [repo](https://github.com/mongodb/node-mongodb-native) _or_ for small documentation changes, navigate to the source on github and click the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. -- Follow the general coding style of the rest of the project: - - 2 space tabs - - no trailing whitespace - - comma last - - inline documentation for new methods, class members, etc - - 0 space between conditionals/functions, and their parenthesis and curly braces - - `if(..) {` - - `for(..) {` - - `while(..) {` - - `function(err) {` -- Write tests and make sure they pass (execute `make test` from the cmd line to run the test suite). - -### Documentation - -To contribute to the [API documentation](http://mongodb.github.com/node-mongodb-native/) just make your changes to the inline documentation of the appropriate [source code](https://github.com/mongodb/node-mongodb-native/tree/master/docs) in the master branch and submit a [pull request](https://help.github.com/articles/using-pull-requests/). You might also use the github [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. - -If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make generate_docs`. Make sure you have the python documentation framework sphinx installed `easy_install sphinx`. The docs are generated under `docs/build'. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes. \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/Makefile b/api/node_modules/mongoskin/node_modules/mongodb/Makefile deleted file mode 100644 index 59d2bfeb89e..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit -DOX = node_modules/dox/bin/dox -name = all - -total: build_native - -test_functional: - node test/runner.js -t functional - -test_ssl: - node test/runner.js -t ssl - -test_replicaset: - node test/runner.js -t replicaset - -test_sharded: - node test/runner.js -t sharded - -test_auth: - node test/runner.js -t auth - -generate_docs: - $(NODE) dev/tools/build-docs.js - make --directory=./docs/sphinx-docs --file=Makefile html - -.PHONY: total diff --git a/api/node_modules/mongoskin/node_modules/mongodb/Readme.md b/api/node_modules/mongoskin/node_modules/mongodb/Readme.md deleted file mode 100644 index b81e719bfe4..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/Readme.md +++ /dev/null @@ -1,442 +0,0 @@ -Up to date documentation -======================== - -[Documentation](http://mongodb.github.com/node-mongodb-native/) - -Install -======= - -To install the most recent release from npm, run: - - npm install mongodb - -That may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version) - -To install the latest from the repository, run:: - - npm install path/to/node-mongodb-native - -Community -========= -Check out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver. - -Try it live -============ - - -Introduction -============ - -This is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/. - -A simple example of inserting a document. - -```javascript - var client = new Db('test', new Server("127.0.0.1", 27017, {}), {w: 1}), - test = function (err, collection) { - collection.insert({a:2}, function(err, docs) { - - collection.count(function(err, count) { - test.assertEquals(1, count); - }); - - // Locate all the entries using find - collection.find().toArray(function(err, results) { - test.assertEquals(1, results.length); - test.assertTrue(results[0].a === 2); - - // Let's close the db - client.close(); - }); - }); - }; - - client.open(function(err, p_client) { - client.collection('test_insert', test); - }); -``` - -Data types -========== - -To store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code). - -In particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example: - -```javascript - // Get the objectID type - var ObjectID = require('mongodb').ObjectID; - - var idString = '4e4e1638c85e808431000003'; - collection.findOne({_id: new ObjectID(idString)}, console.log) // ok - collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined -``` - -Here are the constructors the non-Javascript BSON primitive types: - -```javascript - // Fetch the library - var mongo = require('mongodb'); - // Create new instances of BSON types - new mongo.Long(numberString) - new mongo.ObjectID(hexString) - new mongo.Timestamp() // the actual unique number is generated on insert. - new mongo.DBRef(collectionName, id, dbName) - new mongo.Binary(buffer) // takes a string or Buffer - new mongo.Code(code, [context]) - new mongo.Symbol(string) - new mongo.MinKey() - new mongo.MaxKey() - new mongo.Double(number) // Force double storage -``` - -The C/C++ bson parser/serializer --------------------------------- - -If you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below - -```javascript - // using native_parser: - var client = new Db('integration_tests_20', - new Server("127.0.0.1", 27017), - {native_parser:true}); -``` - -The C++ parser uses the js objects both for serialization and deserialization. - -GitHub information -================== - -The source code is available at http://github.com/mongodb/node-mongodb-native. -You can either clone the repository or download a tarball of the latest release. - -Once you have the source you can test the driver by running - - $ make test - -in the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass. - -Examples -======== - -For examples look in the examples/ directory. You can execute the examples using node. - - $ cd examples - $ node queries.js - -GridStore -========= - -The GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition. - -For more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) - -Replicasets -=========== -For more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md) - -Primary Key Factories ---------------------- - -Defining your own primary key factory allows you to generate your own series of id's -(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long "string". - -Simple example below - -```javascript - // Custom factory (need to provide a 12 byte array); - CustomPKFactory = function() {} - CustomPKFactory.prototype = new Object(); - CustomPKFactory.createPk = function() { - return new ObjectID("aaaaaaaaaaaa"); - } - - var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory}); - p_client.open(function(err, p_client) { - p_client.dropDatabase(function(err, done) { - p_client.createCollection('test_custom_key', function(err, collection) { - collection.insert({'a':1}, function(err, docs) { - collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) { - cursor.toArray(function(err, items) { - test.assertEquals(1, items.length); - - // Let's close the db - p_client.close(); - }); - }); - }); - }); - }); - }); -``` - -Strict mode ------------ - -Each database has an optional strict mode. If it is set then asking for a collection -that does not exist will return an Error object in the callback. Similarly if you -attempt to create a collection that already exists. Strict is provided for convenience. - -```javascript - var error_client = new Db('integration_tests_', new Server("127.0.0.1", 27017, {auto_reconnect: false}), {strict:true}); - test.assertEquals(true, error_client.strict); - - error_client.open(function(err, error_client) { - error_client.collection('does-not-exist', function(err, collection) { - test.assertTrue(err instanceof Error); - test.assertEquals("Collection does-not-exist does not exist. Currently in strict mode.", err.message); - }); - - error_client.createCollection('test_strict_access_collection', function(err, collection) { - error_client.collection('test_strict_access_collection', function(err, collection) { - test.assertTrue(collection instanceof Collection); - // Let's close the db - error_client.close(); - }); - }); - }); -``` - -Documentation -============= - -If this document doesn't answer your questions, see the source of -[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js) -or [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js), -or the documentation at MongoDB for query and update formats. - -Find ----- - -The find method is actually a factory method to create -Cursor objects. A Cursor lazily uses the connection the first time -you call `nextObject`, `each`, or `toArray`. - -The basic operation on a cursor is the `nextObject` method -that fetches the next matching document from the database. The convenience -methods `each` and `toArray` call `nextObject` until the cursor is exhausted. - -Signatures: - -```javascript - var cursor = collection.find(query, [fields], options); - cursor.sort(fields).limit(n).skip(m). - - cursor.nextObject(function(err, doc) {}); - cursor.each(function(err, doc) {}); - cursor.toArray(function(err, docs) {}); - - cursor.rewind() // reset the cursor to its initial state. -``` - -Useful chainable methods of cursor. These can optionally be options of `find` instead of method calls: - -* `.limit(n).skip(m)` to control paging. -* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes: - * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2. - * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above - * `.sort([['field1', 'desc'], 'field2'])` same as above - * `.sort('field1')` ascending by field1 - -Other options of `find`: - -* `fields` the fields to fetch (to avoid transferring the entire document) -* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors). -* `batchSize` The number of the subset of results to request the database -to return for every request. This should initially be greater than 1 otherwise -the database will automatically close the cursor. The batch size can be set to 1 -with `batchSize(n, function(err){})` after performing the initial query to the database. -* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint). -* `explain` turns this into an explain query. You can also call -`explain()` on any cursor to fetch the explanation. -* `snapshot` prevents documents that are updated while the query is active -from being returned multiple times. See more -[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database). -* `timeout` if false, asks MongoDb not to time out this cursor after an -inactivity period. - - -For information on how to create queries, see the -[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.find({}, {limit:10}).toArray(function(err, docs) { - console.dir(docs); - }); - }); -``` - -Insert ------- - -Signature: - -```javascript - collection.insert(docs, options, [callback]); -``` - -where `docs` can be a single document or an array of documents. - -Useful options: - -* `safe:true` Should always set if you have a callback. - -See also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.insert({hello: 'world'}, {safe:true}, - function(err, objects) { - if (err) console.warn(err.message); - if (err && err.message.indexOf('E11000 ') !== -1) { - // this _id was already inserted in the database - } - }); - }); -``` - -Note that there's no reason to pass a callback to the insert or update commands -unless you use the `safe:true` option. If you don't specify `safe:true`, then -your callback will be called immediately. - -Update; update and insert (upsert) ----------------------------------- - -The update operation will update the first document that matches your query -(or all documents that match if you use `multi:true`). -If `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated. - -See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for -the modifier (`$inc`, `$set`, `$push`, etc.) formats. - -Signature: - -```javascript - collection.update(criteria, objNew, options, [callback]); -``` - -Useful options: - -* `safe:true` Should always set if you have a callback. -* `multi:true` If set, all matching documents are updated, not just the first. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `update`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true}, - function(err) { - if (err) console.warn(err.message); - else console.log('successfully updated'); - }); - }); -``` - -Find and modify ---------------- - -`findAndModify` is like `update`, but it also gives the updated document to -your callback. But there are a few key differences between findAndModify and -update: - - 1. The signatures differ. - 2. You can only findAndModify a single item, not multiple items. - -Signature: - -```javascript - collection.findAndModify(query, sort, update, options, callback) -``` - -The sort parameter is used to specify which object to operate on, if more than -one document matches. It takes the same format as the cursor sort (see -Connection.find above). - -See the -[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) -for more details. - -Useful options: - -* `remove:true` set to a true to remove the object before returning -* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `findAndModify`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {}, - function(err, object) { - if (err) console.warn(err.message); - else console.dir(object); // undefined if no matching object exists. - }); - }); -``` - -Save ----- - -The `save` method is a shorthand for upsert if the document contains an -`_id`, or an insert if there is no `_id`. - -Sponsors -======== -Just as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB. - -If your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details. - -And I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing. - -Release Notes -============= - -See HISTORY - -Credits -======= - -1. [10gen](http://github.com/mongodb/mongo-ruby-driver/) -2. [Google Closure Library](http://code.google.com/closure/library/) -3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser) - -Contributors -============ - -Aaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy - -License -======= - - Copyright 2009 - 2012 Christian Amor Kvalheim. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile deleted file mode 100644 index ad877d4bd3c..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -test: - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc deleted file mode 100644 index 8906eea9ac6..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc +++ /dev/null @@ -1,2165 +0,0 @@ -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bson.h" - -using namespace v8; -using namespace node; -using namespace std; - -// BSON DATA TYPES -const uint32_t BSON_DATA_NUMBER = 1; -const uint32_t BSON_DATA_STRING = 2; -const uint32_t BSON_DATA_OBJECT = 3; -const uint32_t BSON_DATA_ARRAY = 4; -const uint32_t BSON_DATA_BINARY = 5; -const uint32_t BSON_DATA_OID = 7; -const uint32_t BSON_DATA_BOOLEAN = 8; -const uint32_t BSON_DATA_DATE = 9; -const uint32_t BSON_DATA_NULL = 10; -const uint32_t BSON_DATA_REGEXP = 11; -const uint32_t BSON_DATA_CODE = 13; -const uint32_t BSON_DATA_SYMBOL = 14; -const uint32_t BSON_DATA_CODE_W_SCOPE = 15; -const uint32_t BSON_DATA_INT = 16; -const uint32_t BSON_DATA_TIMESTAMP = 17; -const uint32_t BSON_DATA_LONG = 18; -const uint32_t BSON_DATA_MIN_KEY = 0xff; -const uint32_t BSON_DATA_MAX_KEY = 0x7f; - -const int32_t BSON_INT32_MAX = (int32_t)2147483647L; -const int32_t BSON_INT32_MIN = (int32_t)(-1) * 2147483648L; - -const int64_t BSON_INT64_MAX = ((int64_t)1 << 63) - 1; -const int64_t BSON_INT64_MIN = (int64_t)-1 << 63; - -const int64_t JS_INT_MAX = (int64_t)1 << 53; -const int64_t JS_INT_MIN = (int64_t)-1 << 53; - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); - }; - -Persistent BSON::constructor_template; - -void BSON::Initialize(v8::Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - // Experimental - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize2", CalculateObjectSize2); - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize2", BSONSerialize2); - // NODE_SET_METHOD(constructor_template->GetFunction(), "serialize2", BSONSerialize2); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and assing it the existing context -Handle BSON::New(const Arguments &args) { - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - // Setup pre-allocated comparision objects - bson->_bsontypeString = Persistent::New(String::New("_bsontype")); - bson->_longLowString = Persistent::New(String::New("low_")); - bson->_longHighString = Persistent::New(String::New("high_")); - bson->_objectIDidString = Persistent::New(String::New("id")); - bson->_binaryPositionString = Persistent::New(String::New("position")); - bson->_binarySubTypeString = Persistent::New(String::New("sub_type")); - bson->_binaryBufferString = Persistent::New(String::New("buffer")); - bson->_doubleValueString = Persistent::New(String::New("value")); - bson->_symbolValueString = Persistent::New(String::New("value")); - bson->_dbRefRefString = Persistent::New(String::New("$ref")); - bson->_dbRefIdRefString = Persistent::New(String::New("$id")); - bson->_dbRefDbRefString = Persistent::New(String::New("$db")); - bson->_dbRefNamespaceString = Persistent::New(String::New("namespace")); - bson->_dbRefDbString = Persistent::New(String::New("db")); - bson->_dbRefOidString = Persistent::New(String::New("oid")); - - // total number of found classes - uint32_t numberOfClasses = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(String::New("Long"))) { - bson->longConstructor = Persistent::New(func); - bson->longString = Persistent::New(String::New("Long")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("ObjectID"))) { - bson->objectIDConstructor = Persistent::New(func); - bson->objectIDString = Persistent::New(String::New("ObjectID")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Binary"))) { - bson->binaryConstructor = Persistent::New(func); - bson->binaryString = Persistent::New(String::New("Binary")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Code"))) { - bson->codeConstructor = Persistent::New(func); - bson->codeString = Persistent::New(String::New("Code")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("DBRef"))) { - bson->dbrefConstructor = Persistent::New(func); - bson->dbrefString = Persistent::New(String::New("DBRef")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Symbol"))) { - bson->symbolConstructor = Persistent::New(func); - bson->symbolString = Persistent::New(String::New("Symbol")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Double"))) { - bson->doubleConstructor = Persistent::New(func); - bson->doubleString = Persistent::New(String::New("Double")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Timestamp"))) { - bson->timestampConstructor = Persistent::New(func); - bson->timestampString = Persistent::New(String::New("Timestamp")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MinKey"))) { - bson->minKeyConstructor = Persistent::New(func); - bson->minKeyString = Persistent::New(String::New("MinKey")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MaxKey"))) { - bson->maxKeyConstructor = Persistent::New(func); - bson->maxKeyString = Persistent::New(String::New("MaxKey")); - numberOfClasses = numberOfClasses + 1; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(numberOfClasses != 10) { - // Destroy object - delete(bson); - // Fire exception - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } else { - return VException("No types passed in"); - } - } else { - return VException("Argument passed in must be an array of types"); - } -} - -void BSON::write_int32(char *data, uint32_t value) { - // Write the int to the char* - memcpy(data, &value, 4); -} - -void BSON::write_double(char *data, double value) { - // Write the double to the char* - memcpy(data, &value, 8); -} - -void BSON::write_int64(char *data, int64_t value) { - // Write the int to the char* - memcpy(data, &value, 8); -} - -char *BSON::check_key(Local key) { - // Allocate space for they key string - char *key_str = (char *)malloc(key->Utf8Length() * sizeof(char) + 1); - // Error string - char *error_str = (char *)malloc(256 * sizeof(char)); - // Decode the key - ssize_t len = DecodeBytes(key, BINARY); - DecodeWrite(key_str, len, key, BINARY); - *(key_str + key->Utf8Length()) = '\0'; - // Check if we have a valid key - if(key->Utf8Length() > 0 && *(key_str) == '$') { - // Create the string - sprintf(error_str, "key %s must not start with '$'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } else if(key->Utf8Length() > 0 && strchr(key_str, '.') != NULL) { - // Create the string - sprintf(error_str, "key %s must not contain '.'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } - // Free allocated space - free(key_str); - free(error_str); - // Return No check key error - return NULL; -} - -const char* BSON::ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : ""; -} - -Handle BSON::decodeDBref(BSON *bson, Local ref, Local oid, Local db) { - HandleScope scope; - Local argv[] = {ref, oid, db}; - Handle dbrefObj = bson->dbrefConstructor->NewInstance(3, argv); - return scope.Close(dbrefObj); -} - -Handle BSON::decodeCode(BSON *bson, char *code, Handle scope_object) { - HandleScope scope; - - Local argv[] = {String::New(code), scope_object->ToObject()}; - Handle codeObj = bson->codeConstructor->NewInstance(2, argv); - return scope.Close(codeObj); -} - -Handle BSON::decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data) { - HandleScope scope; - - // Create a buffer object that wraps the raw stream - Buffer *bufferObj = Buffer::New(data, number_of_bytes); - // Arguments to be passed to create the binary - Handle argv[] = {bufferObj->handle_, Uint32::New(sub_type)}; - // Return the buffer handle - Local bufferObjHandle = bson->binaryConstructor->NewInstance(2, argv); - // Close the scope - return scope.Close(bufferObjHandle); -} - -Handle BSON::decodeOid(BSON *bson, char *oid) { - HandleScope scope; - - // Encode the string (string - null termiating character) - Local bin_value = Encode(oid, 12, BINARY)->ToString(); - - // Return the id object - Local argv[] = {bin_value}; - Local oidObj = bson->objectIDConstructor->NewInstance(1, argv); - return scope.Close(oidObj); -} - -Handle BSON::decodeLong(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Decode 64bit value - int64_t value = 0; - memcpy(&value, (data + index), 8); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - int64_t finalValue = 0; - memcpy(&finalValue, (data + index), 8); - return scope.Close(Number::New(finalValue)); - } - - // Instantiate the js object and pass it back - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Local longObject = bson->longConstructor->NewInstance(2, argv); - return scope.Close(longObject); -} - -Handle BSON::decodeTimestamp(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Build timestamp - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Handle timestamp_obj = bson->timestampConstructor->NewInstance(2, argv); - return scope.Close(timestamp_obj); -} - -// Search for 0 terminated C string and return the string -char* BSON::extract_string(char *data, uint32_t offset) { - char *prt = strchr((data + offset), '\0'); - if(prt == NULL) return NULL; - // Figure out the length of the string - uint32_t length = (prt - data) - offset; - // Allocate memory for the new string - char *string_name = (char *)malloc((length * sizeof(char)) + 1); - // Copy the variable into the string_name - strncpy(string_name, (data + offset), length); - // Ensure the string is null terminated - *(string_name + length) = '\0'; - // Return the unpacked string - return string_name; -} - -// Decode a byte -uint16_t BSON::deserialize_int8(char *data, uint32_t offset) { - uint16_t value = 0; - value |= *(data + offset + 0); - return value; -} - -// Requires a 4 byte char array -uint32_t BSON::deserialize_int32(char* data, uint32_t offset) { - uint32_t value = 0; - memcpy(&value, (data + offset), 4); - return value; -} - -//------------------------------------------------------------------------------------------------ -// -// Experimental -// -//------------------------------------------------------------------------------------------------ -Handle BSON::CalculateObjectSize2(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() > 1) return VException("One argument required - [object]"); - // Calculate size of the object - uint32_t object_size = BSON::calculate_object_size2(args[0]); - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size2(Handle value) { - // Final object size - uint32_t object_size = (4 + 1); - uint32_t stackIndex = 0; - // Controls the flow - bool done = false; - bool finished = false; - - // Current object we are processing - Local currentObject = value->ToObject(); - - // Current list of object keys - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local keys = currentObject->GetPropertyNames(); - #else - Local keys = currentObject->GetOwnPropertyNames(); - #endif - - // Contains pointer to keysIndex - uint32_t keysIndex = 0; - uint32_t keysLength = keys->Length(); - - // printf("=================================================================================\n"); - // printf("Start serializing\n"); - - while(!done) { - // If the index is bigger than the number of keys for the object - // we finished up the previous object and are ready for the next one - if(keysIndex >= keysLength) { - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - keys = currentObject->GetPropertyNames(); - #else - keys = currentObject->GetOwnPropertyNames(); - #endif - keysLength = keys->Length(); - } - - // Iterate over all the keys - while(keysIndex < keysLength) { - // Fetch the key name - Local name = keys->Get(keysIndex++)->ToString(); - // Fetch the object related to the key - Local value = currentObject->Get(name); - // Add size of the name, plus zero, plus type - object_size += name->Utf8Length() + 1 + 1; - - // If we have a string - if(value->IsString()) { - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } - // } else if(value->IsNumber()) { - // // Check if we have a float value or a long value - // Local number = value->ToNumber(); - // double d_number = number->NumberValue(); - // int64_t l_number = number->IntegerValue(); - // // Check if we have a double value and not a int64 - // double d_result = d_number - l_number; - // // If we have a value after subtracting the integer value we have a float - // if(d_result > 0 || d_result < 0) { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // object_size = name->Utf8Length() + 1 + object_size + 4 + 1; - // } else { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } - // } else if(value->IsObject()) { - // printf("------------- hello\n"); - // } - } - - // If we have finished all the keys - if(keysIndex == keysLength) { - finished = false; - } - - // Validate the stack - if(stackIndex == 0) { - // printf("======================================================================== 3\n"); - done = true; - } else if(finished || keysIndex == keysLength) { - // Pop off the stack - stackIndex = stackIndex - 1; - // Fetch the current object stack - // vector > currentObjectStored = stack.back(); - // stack.pop_back(); - // // Unroll the current object - // currentObject = currentObjectStored.back()->ToObject(); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keys = Local::Cast(currentObjectStored.back()->ToObject()); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keysIndex = currentObjectStored.back()->ToUint32()->Value(); - // currentObjectStored.pop_back(); - // // Check if we finished up - // if(keysIndex == keys->Length()) { - // finished = true; - // } - } - } - - return object_size; -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -Handle BSON::BSONDeserialize(const Arguments &args) { - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - char *data; - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) { - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - uint32_t length = buffer->length(); - #else - data = Buffer::Data(obj); - uint32_t length = Buffer::Length(obj); - #endif - - // Validate that we have at least 5 bytes - if(length < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Deserialize the data - return BSON::deserialize(bson, data, length, 0, NULL); - } else { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Let's define the buffer size - data = (char *)malloc(len); - // Write the data to the buffer from the string object - ssize_t written = DecodeWrite(data, len, args[0], BINARY); - // Assert that we wrote the same number of bytes as we have length - assert(written == len); - // Get result - Handle result = BSON::deserialize(bson, data, len, 0, NULL); - // Free memory - free(data); - // Deserialize the content - return result; - } -} - -// Deserialize the stream -Handle BSON::deserialize(BSON *bson, char *data, uint32_t inDataLength, uint32_t startIndex, bool is_array_item) { - HandleScope scope; - // Holds references to the objects that are going to be returned - Local return_data = Object::New(); - Local return_array = Array::New(); - // The current index in the char data - uint32_t index = startIndex; - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // If we have an illegal message size - if(size > inDataLength) return VException("corrupt bson message"); - - // Data length - uint32_t dataLength = index + size; - - // Adjust the index to point to next piece - index = index + 4; - - // While we have data left let's decode - while(index < dataLength) { - // Read the first to bytes to indicate the type of object we are decoding - uint8_t type = BSON::deserialize_int8(data, index); - // Adjust index to skip type byte - index = index + 1; - - if(type == BSON_DATA_STRING) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), utf8_encoded_str); - } else { - return_data->ForceSet(String::New(string_name), utf8_encoded_str); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_INT) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - uint32_t value = 0; - memcpy(&value, (data + index), 4); - - // Adjust the index for the size of the value - index = index + 4; - // Add the element to the object - if(is_array_item) { - return_array->Set(Integer::New(insert_index), Integer::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Integer::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_TIMESTAMP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeTimestamp(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeTimestamp(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_LONG) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeLong(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeLong(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NUMBER) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - double value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Number::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Number::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MIN_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local minKey = bson->minKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), minKey); - } else { - return_data->ForceSet(String::New(string_name), minKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MAX_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local maxKey = bson->maxKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), maxKey); - } else { - return_data->ForceSet(String::New(string_name), maxKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NULL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Null()); - } else { - return_data->ForceSet(String::New(string_name), Null()); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_BOOLEAN) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the boolean value - char bool_value = *(data + index); - // Adjust the index for the size of the value - index = index + 1; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } else { - return_data->ForceSet(String::New(string_name), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_DATE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the value 64 bit integer - int64_t value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Date::New((double)value)); - } else { - return_data->ForceSet(String::New(string_name), Date::New((double)value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_REGEXP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Length variable - int32_t length_regexp = 0; - char chr; - - // Locate end of the regexp expression \0 - while((chr = *(data + index + length_regexp)) != '\0') { - length_regexp = length_regexp + 1; - } - - // Contains the reg exp - char *reg_exp = (char *)malloc(length_regexp * sizeof(char) + 2); - // Copy the regexp from the data to the char * - memcpy(reg_exp, (data + index), (length_regexp + 1)); - // Adjust the index to skip the first part of the regular expression - index = index + length_regexp + 1; - - // Reset the length - int32_t options_length = 0; - // Locate the end of the options for the regexp terminated with a '\0' - while((chr = *(data + index + options_length)) != '\0') { - options_length = options_length + 1; - } - - // Contains the reg exp - char *options = (char *)malloc(options_length * sizeof(char) + 1); - // Copy the options from the data to the char * - memcpy(options, (data + index), (options_length + 1)); - // Adjust the index to skip the option part of the regular expression - index = index + options_length + 1; - // ARRRRGH Google does not expose regular expressions through the v8 api - // Have to use Script to instantiate the object (slower) - - // Generate the string for execution in the string context - int flag = 0; - - for(int i = 0; i < options_length; i++) { - // Multiline - if(*(options + i) == 'm') { - flag = flag | 4; - } else if(*(options + i) == 'i') { - flag = flag | 2; - } - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } else { - return_data->ForceSet(String::New(string_name), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } - - // Free memory - free(reg_exp); - free(options); - free(string_name); - } else if(type == BSON_DATA_OID) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // The id string - char *oid_string = (char *)malloc(12 * sizeof(char)); - // Copy the options from the data to the char * - memcpy(oid_string, (data + index), 12); - - // Adjust the index - index = index + 12; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeOid(bson, oid_string)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeOid(bson, oid_string)); - } - - // Free memory - free(oid_string); - free(string_name); - } else if(type == BSON_DATA_BINARY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the binary data size - uint32_t number_of_bytes = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Decode the subtype, ensure it's positive - uint32_t sub_type = (int)*(data + index) & 0xff; - // Adjust the index - index = index + 1; - // Copy the binary data into a buffer - char *buffer = (char *)malloc(number_of_bytes * sizeof(char) + 1); - memcpy(buffer, (data + index), number_of_bytes); - *(buffer + number_of_bytes) = '\0'; - - // Adjust the index - index = index + number_of_bytes; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } - // Free memory - free(buffer); - free(string_name); - } else if(type == BSON_DATA_SYMBOL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - - // Wrap up the string in a Symbol Object - Local argv[] = {utf8_encoded_str}; - Handle symbolObj = bson->symbolConstructor->NewInstance(1, argv); - - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), symbolObj); - } else { - return_data->ForceSet(String::New(string_name), symbolObj); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_CODE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - - // Define empty scope object - Handle scope_object = Object::New(); - - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - free(string_name); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(string_name); - } else if(type == BSON_DATA_CODE_W_SCOPE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Total number of bytes after array index - uint32_t total_code_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - // Adjust the index - index = index + string_size; - // Get the scope object (bson object) - uint32_t bson_object_size = total_code_size - string_size - 8; - // Allocate bson object buffer and copy out the content - char *bson_buffer = (char *)malloc(bson_object_size * sizeof(char)); - memcpy(bson_buffer, (data + index), bson_object_size); - // Adjust the index - index = index + bson_object_size; - // Parse the bson object - Handle scope_object = BSON::deserialize(bson, bson_buffer, inDataLength, 0, false); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Clean up memory allocation - free(string_name); - free(bson_buffer); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(bson_buffer); - free(string_name); - } else if(type == BSON_DATA_OBJECT) { - // If this is the top level object we need to skip the undecoding - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the object size - uint32_t bson_object_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, false); - // Adjust the index - index = index + bson_object_size; - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(string_name); - } else if(type == BSON_DATA_ARRAY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the size - uint32_t array_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, true); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - // Adjust the index for the next value - index = index + array_size; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - // Clean up memory allocation - free(string_name); - } - } - - // Check if we have a db reference - if(!is_array_item && return_data->Has(String::New("$ref")) && return_data->Has(String::New("$id"))) { - Handle dbrefValue = BSON::decodeDBref(bson, return_data->Get(String::New("$ref")), return_data->Get(String::New("$id")), return_data->Get(String::New("$db"))); - return scope.Close(dbrefValue); - } - - // Return the data object to javascript - if(is_array_item) { - return scope.Close(return_array); - } else { - return scope.Close(return_data); - } -} - -Handle BSON::BSONSerialize(const Arguments &args) { - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - if(args.Length() == 4) { - object_size = BSON::calculate_object_size(bson, args[0], args[3]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 3 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - // Check if we have a boolean value - bool serializeFunctions = false; - if(args.Length() == 4 && args[1]->IsBoolean()) { - serializeFunctions = args[3]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - // Write the object size - BSON::write_int32((serialized_object), object_size); - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) { - // Local asBuffer = args[2]->ToBoolean(); - Buffer *buffer = Buffer::New(serialized_object, object_size); - // Release the serialized string - free(serialized_object); - return scope.Close(buffer->handle_); - } else { - // Encode the string (string - null termiating character) - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - // Return the serialized content - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Object size - uint32_t object_size = 0; - // Check if we have our argument, calculate size of the object - if(args.Length() >= 2) { - object_size = BSON::calculate_object_size(bson, args[0], args[1]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size(BSON *bson, Handle value, bool serializeFunctions) { - uint32_t object_size = 0; - - // If we have an object let's unwrap it and calculate the sub sections - if(value->IsString()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Calculate the size of each element - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Add the size of the string length - uint32_t label_length = strlen(length_str) + 1; - // Add the type definition size for each item - object_size = object_size + label_length + 1; - // Add size of the object - uint32_t object_length = BSON::calculate_object_size(bson, array->Get(Integer::New(i)), serializeFunctions); - object_size = object_size + object_length; - } - // Add the object size - object_size = object_size + 4 + 1; - // Free up memory - free(length_str); - } else if(value->IsFunction()) { - if(serializeFunctions) { - object_size += value->ToString()->Utf8Length() + 4 + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - object_size = object_size + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local positionObj = value->ToObject()->Get(String::New("position"))->ToUint32(); - // Adjust the object_size, binary content lengt + total size int32 + binary size int32 + subtype - object_size += positionObj->Value() + 4 + 1; - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Check if the scope has any parameters - // Let's calculate the size the code object adds adds - if(propertyNameLength > 0) { - object_size += function->Utf8Length() + 4 + BSON::calculate_object_size(bson, scope, serializeFunctions) + 4 + 1; - } else { - object_size += function->Utf8Length() + 4 + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - // Calculate size - object_size += BSON::calculate_object_size(bson, obj, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString) || bson->maxKeyString->Equals(constructorString)) { - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Get string - Local str = value->ToObject()->Get(String::New("value"))->ToString(); - // Get the utf8 length - int utf8_length = str->Utf8Length(); - // Check if we have a utf8 encoded string or not - if(utf8_length != str->Length()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += str->Utf8Length() + 1 + 4; - } else { - object_size += str->Length() + 1 + 4; - } - } else if(bson->doubleString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } - } else if(value->IsObject()) { - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Length of the property - uint32_t propertyLength = property_names->Length(); - - // Process all the properties on the object - for(uint32_t index = 0; index < propertyLength; index++) { - // Fetch the property name - Local property_name = property_names->Get(index)->ToString(); - - // Fetch the object for the property - Local property = object->Get(property_name); - // Get size of property (property + property name length + 1 for terminating 0) - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - object_size += BSON::calculate_object_size(bson, property, serializeFunctions) + property_name->Utf8Length() + 1 + 1; - } - } - - object_size = object_size + 4 + 1; - } - - return object_size; -} - -uint32_t BSON::serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions) { - // Scope for method execution - HandleScope scope; - - // If we have a name check that key is valid - if(!name->IsNull() && check_key) { - if(BSON::check_key(name->ToString()) != NULL) return -1; - } - - // If we have an object let's serialize it - if(value->IsString()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_STRING; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Write the actual string into the char array - Local str = value->ToString(); - // Let's fetch the int value - uint32_t utf8_length = str->Utf8Length(); - - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else if(value->IsNumber()) { - uint32_t first_pointer = index; - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_INT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - Local number = value->ToNumber(); - // Get the values - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // Smaller than 32 bit, write as 32 bit value - BSON::write_int32(serialized_object + index, value->ToInt32()->Value()); - // Adjust the size of the index - index = index + 4; - } else if(l_number <= JS_INT_MAX && l_number >= JS_INT_MIN) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else { - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust the size of the index - index = index + 8; - } - } else if(value->IsBoolean()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_BOOLEAN; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Save the boolean value - *(serialized_object + index) = value->BooleanValue() ? '\1' : '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsDate()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_DATE; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the Integer value - int64_t integer_value = value->IntegerValue(); - BSON::write_int64((serialized_object + index), integer_value); - // Adjust the index - index = index + 8; - } else if(value->IsNull() || value->IsUndefined()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_NULL; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_ARRAY; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - // Object size - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size of the object - BSON::write_int32((serialized_object + index), object_size); - // Adjust the index - index = index + 4; - // Write out all the elements - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Encode the values - index = BSON::serialize(bson, serialized_object, index, String::New(length_str), array->Get(Integer::New(i)), check_key, serializeFunctions); - // Write trailing '\0' for object - *(serialized_object + index) = '\0'; - } - - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - // Free up memory - free(length_str); - } else if(value->IsRegExp()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_REGEXP; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - len = DecodeBytes(regExp->GetSource(), UTF8); - written = DecodeWrite((serialized_object + index), len, regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // global - if((flags & (1 << 0)) != 0) { - *(serialized_object + index) = 's'; - index = index + 1; - } - - // ignorecase - if((flags & (1 << 1)) != 0) { - *(serialized_object + index) = 'i'; - index = index + 1; - } - - //multiline - if((flags & (1 << 2)) != 0) { - *(serialized_object + index) = 'm'; - index = index + 1; - } - - // Add null termiation for the string - *(serialized_object + index) = '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsFunction()) { - if(serializeFunctions) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_CODE; - - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Function String - Local function = value->ToString(); - - // Decode the function - len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - written = DecodeWrite((serialized_object + index), len, function, BINARY); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - uint32_t originalIndex = index; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_LONG; - // Object reference - Local longObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = longObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = longObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_TIMESTAMP; - // Object reference - Local timestampObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = timestampObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = timestampObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_OID; - // Convert to object - Local objectIDObject = value->ToObject(); - // Let's grab the id - Local idString = objectIDObject->Get(bson->_objectIDidString)->ToString(); - // Let's decode the raw chars from the string - len = DecodeBytes(idString, BINARY); - written = DecodeWrite((serialized_object + index), len, idString, BINARY); - // Adjust the index - index = index + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_BINARY; - - // Let's get the binary object - Local binaryObject = value->ToObject(); - - // Grab the size(position of the binary) - uint32_t position = value->ToObject()->Get(bson->_binaryPositionString)->ToUint32()->Value(); - // Grab the subtype - uint32_t subType = value->ToObject()->Get(bson->_binarySubTypeString)->ToUint32()->Value(); - // Grab the buffer object - Local bufferObj = value->ToObject()->Get(bson->_binaryBufferString)->ToObject(); - - // Buffer data pointers - char *data; - uint32_t length; - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(bufferObj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(bufferObj); - length = Buffer::Length(bufferObj); - #endif - - // Write the size of the buffer out - BSON::write_int32((serialized_object + index), position); - // Adjust index - index = index + 4; - // Write subtype - *(serialized_object + index) = (char)subType; - // Adjust index - index = index + 1; - // Write binary content - memcpy((serialized_object + index), data, position); - // Adjust index.rar">_ - index = index + position; - } else if(bson->doubleString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_NUMBER; - - // Unpack the double - Local doubleObject = value->ToObject(); - - // Fetch the double value - Local doubleValue = doubleObject->Get(bson->_doubleValueString)->ToNumber(); - // Write the double to the char array - BSON::write_double((serialized_object + index), doubleValue->NumberValue()); - // Adjust index for double - index = index + 8; - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_SYMBOL; - // Unpack symbol object - Local symbolObj = value->ToObject(); - - // Grab the actual string - Local str = symbolObj->Get(bson->_symbolValueString)->ToString(); - // Let's fetch the int value - int utf8_length = str->Utf8Length(); - - // If the Utf8 length is different from the string length then we - // have a UTF8 encoded string, otherwise write it as ascii - if(utf8_length != str->Length()) { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), str->Length() + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - written = DecodeWrite((serialized_object + index), str->Length(), str, BINARY); - // Add the null termination - *(serialized_object + index + str->Length()) = '\0'; - // Adjust the index - index = index + str->Length() + 1; - } - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Set the right type if we have a scope or not - if(propertyNameLength > 0) { - // Set basic data code object with scope object - *(serialized_object + originalIndex) = BSON_DATA_CODE_W_SCOPE; - - // Calculate the size of the whole object - uint32_t scopeSize = BSON::calculate_object_size(bson, scope, false); - // Decode the function length - ssize_t len = DecodeBytes(function, UTF8); - // Calculate total size - uint32_t size = 4 + len + 1 + 4 + scopeSize; - - // Write the total size - BSON::write_int32((serialized_object + index), size); - // Adjust the index - index = index + 4; - - // Write the function size - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, UTF8); - assert(written == len); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index with the length of the function - index = index + len + 1; - // Write the scope object - BSON::serialize(bson, (serialized_object + index), 0, Null(), scope, check_key, serializeFunctions); - // Adjust the index - index = index + scopeSize; - } else { - // Set basic data code object - *(serialized_object + originalIndex) = BSON_DATA_CODE; - // Decode the function - ssize_t len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, BINARY); - assert(written == len); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - - // Encode the variable - index = BSON::serialize(bson, serialized_object, originalIndex, name, obj, false, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_MIN_KEY; - } else if(bson->maxKeyString->StrictEquals(constructorString)) { - *(serialized_object + originalIndex) = BSON_DATA_MAX_KEY; - } - } else if(value->IsObject()) { - if(!name->IsNull()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_OBJECT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } - - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Calculate size of the total object - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size - BSON::write_int32((serialized_object + index), object_size); - // Adjust size - index = index + 4; - - // Process all the properties on the object - for(uint32_t i = 0; i < property_names->Length(); i++) { - // Fetch the property name - Local property_name = property_names->Get(i)->ToString(); - // Fetch the object for the property - Local property = object->Get(property_name); - // Write the next serialized object - // printf("========== !property->IsFunction() || (property->IsFunction() && serializeFunctions) = %d\n", !property->IsFunction() || (property->IsFunction() && serializeFunctions) == true ? 1 : 0); - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - ssize_t len = DecodeBytes(property_name, UTF8); - // char *data = new char[len]; - char *data = (char *)malloc(len + 1); - *(data + len) = '\0'; - ssize_t written = DecodeWrite(data, len, property_name, UTF8); - assert(written == len); - // Serialize the content - index = BSON::serialize(bson, serialized_object, index, property_name, property, check_key, serializeFunctions); - // Free up memory of data - free(data); - } - } - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - - // Null out reminding fields if we have a toplevel object and nested levels - if(name->IsNull()) { - for(uint32_t i = 0; i < (object_size - index); i++) { - *(serialized_object + index + i) = '\0'; - } - } - } - - return index; -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) { - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Define pointer to data - char *data; - uint32_t length; - // Unpack the object - Local obj = args[2]->ToObject(); - - // Unpack the buffer object and get pointers to structures - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - if(args.Length() == 5) { - object_size = BSON::calculate_object_size(bson, args[0], args[4]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Unpack the index variable - Local indexObject = args[3]->ToUint32(); - uint32_t index = indexObject->Value(); - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 4 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - bool serializeFunctions = false; - if(args.Length() == 5) { - serializeFunctions = args[4]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - for(uint32_t i = 0; i < object_size; i++) { - *(data + index + i) = *(serialized_object + i); - } - - return scope.Close(Uint32::New(index + object_size - 1)); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) { - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - char *data; - uint32_t length; - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->ToUint32()->Value(); - uint32_t index = args[1]->ToUint32()->Value(); - uint32_t resultIndex = args[4]->ToUint32()->Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - for(uint32_t i = 0; i < numberOfDocuments; i++) { - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // Get result - Handle result = BSON::deserialize(bson, data, size, index, NULL); - - // Add result to array - documents->Set(i + resultIndex, result); - - // Adjust the index for next pass - index = index + size; - } - - // Return new index of parsing - return scope.Close(Uint32::New(index)); -} - -// Exporting function -extern "C" void init(Handle target) { - HandleScope scope; - BSON::Initialize(target); -} - -// NODE_MODULE(bson, BSON::Initialize); -// NODE_MODULE(l, Long::Initialize); diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h deleted file mode 100644 index dcf21d17af6..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef BSON_H_ -#define BSON_H_ - -#include -#include -#include - -using namespace v8; -using namespace node; - -class BSON : public ObjectWrap { - public: - BSON() : ObjectWrap() {} - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Experimental - static Handle CalculateObjectSize2(const Arguments &args); - static Handle BSONSerialize2(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - - private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - static uint32_t serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions); - - static char* extract_string(char *data, uint32_t offset); - static const char* ToCString(const v8::String::Utf8Value& value); - static uint32_t calculate_object_size(BSON *bson, Handle object, bool serializeFunctions); - - static void write_int32(char *data, uint32_t value); - static void write_int64(char *data, int64_t value); - static void write_double(char *data, double value); - static uint16_t deserialize_int8(char *data, uint32_t offset); - static uint32_t deserialize_int32(char* data, uint32_t offset); - static char *check_key(Local key); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparision objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - // Decode JS function - static Handle decodeLong(BSON *bson, char *data, uint32_t index); - static Handle decodeTimestamp(BSON *bson, char *data, uint32_t index); - static Handle decodeOid(BSON *bson, char *oid); - static Handle decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data); - static Handle decodeCode(BSON *bson, char *code, Handle scope); - static Handle decodeDBref(BSON *bson, Local ref, Local oid, Local db); - - // Experimental - static uint32_t calculate_object_size2(Handle object); - static uint32_t serialize2(char *serialized_object, uint32_t index, Handle name, Handle value, uint32_t object_size, bool check_key); -}; - -#endif // BSON_H_ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js deleted file mode 100644 index 2c66dee6cca..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js +++ /dev/null @@ -1,20 +0,0 @@ -var bson = require('./bson'); -exports.BSON = bson.BSON; -exports.Long = require('../../lib/mongodb/bson/long').Long; -exports.ObjectID = require('../../lib/mongodb/bson/objectid').ObjectID; -exports.DBRef = require('../../lib/mongodb/bson/db_ref').DBRef; -exports.Code = require('../../lib/mongodb/bson/code').Code; -exports.Timestamp = require('../../lib/mongodb/bson/timestamp').Timestamp; -exports.Binary = require('../../lib/mongodb/bson/binary').Binary; -exports.Double = require('../../lib/mongodb/bson/double').Double; -exports.MaxKey = require('../../lib/mongodb/bson/max_key').MaxKey; -exports.MinKey = require('../../lib/mongodb/bson/min_key').MinKey; -exports.Symbol = require('../../lib/mongodb/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js deleted file mode 100644 index 706f1df8cc8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js +++ /dev/null @@ -1,349 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp, - assert = require('assert'); - -if(process.env['npm_package_config_native'] != null) return; - -sys.puts("=== EXECUTING TEST_BSON ==="); - -// Should fail due to illegal key -assert.throws(function() { new ObjectID('foo'); }) -assert.throws(function() { new ObjectID('foo'); }) - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Simple serialization and deserialization of edge value -var doc = {doc:0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// -// Assert correct toJSON -// -var a = Long.fromNumber(10); -assert.equal(10, a); - -var a = Long.fromNumber(9223372036854775807); -assert.equal(9223372036854775807, a); - -// Simple serialization and deserialization test for a Single String value -var doc = {doc:'Serialize'}; -var simple_string_serialized = bsonC.serialize(doc, true, false); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Nested doc -var doc = {a:{b:{c:1}}}; -var simple_string_serialized = bsonC.serialize(doc, false, true); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple integer serialization/deserialization test, including testing boundary conditions -var doc = {doc:-1}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization test for a Long value -var doc = {doc:Long.fromNumber(9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:Long.fromNumber(-9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a Float value -var doc = {doc:2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a null value -var doc = {doc:null}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:true}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a date value -var date = new Date(); -var doc = {doc:date}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:/abcd/mi}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -var doc = {doc:/abcd/}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a objectId value -var doc = {doc:new ObjectID()}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a Binary value -var binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - -var Binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { Binary.put(string.charAt(index)); } - -var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Binary}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - -// Simple serialization and deserialization for a Code value -var code = new Code('this.a > i', {'i': 1}); -var Code = new Code('this.a > i', {'i': 1}); -var simple_string_serialized_2 = bsonJS.serialize({doc:Code}, false, true); -var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - -// Simple serialization and deserialization for an Object -var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for an Array -var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for a DBRef -var oid = new ObjectID() -var oid2 = new ObjectID.createFromHexString(oid.toHexString()) -var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -// Ensure we have the same values for the dbref -var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object_c = bsonC.deserialize(simple_string_serialized); - -assert.equal(object_js.doc.namespace, object_c.doc.namespace); -assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); -assert.equal(object_js.doc.db, object_c.doc.db); - -// Serialized document -var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal('Patty', object.name) -assert.equal(34, object.age) -assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - -// Serialize utf8 -var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.equal(doc.name, object.name) -assert.equal(doc.name1, object.name1) -assert.equal(doc.name2, object.name2) - -// Serialize object with array -var doc = {b:[1, 2, 3]}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc, object) - -// Test equality of an object ID -var object_id = new ObjectID(); -var object_id_2 = new ObjectID(); -assert.ok(object_id.equals(object_id)); -assert.ok(!(object_id.equals(object_id_2))) - -// Test same serialization for Object ID -var object_id = new ObjectID(); -var object_id2 = ObjectID.createFromHexString(object_id.toString()) -var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - -assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object2 = bsonC.deserialize(simple_string_serialized); -assert.equal(object.doc.id, object2.doc.id) - -// JS Object -var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; -var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); - -// C++ Object -var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; -var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) -}; - -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); -} - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc._id.id, doc1._id.id) -assert.equal(doc._id.id, doc2._id.id) -assert.equal(doc1._id.id, doc2._id.id) - -var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.deepEqual(doc2, doc1) -assert.deepEqual(doc, doc2) -assert.deepEqual(doc, doc1) - -// Serialize function -var doc = { - _id: 'testid', - key1: function() {} -} - -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - -var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Should serialize to the same value -assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) -var doc1 = bsonJS.deserialize(simple_string_serialized_2); -var doc2 = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc1, doc2) - -// Hex Id -var hexId = new ObjectID().toString(); -var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docJSBin = bsonJS.serialize(docJS, false, true, true); -var docCBin = bsonC.serialize(docC, false, true, true); -assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - -// // Complex document serialization -// doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} -// var docJSBin = bsonJS.serialize(docJS, false, true, true); -// var docCBin = bsonC.serialize(docC, false, true, true); -// -// - -// // Force garbage collect -// global.gc(); - - - - - - - - - - - - - - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js deleted file mode 100644 index 2a6506c7650..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js +++ /dev/null @@ -1,218 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - assert = require('assert'), - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - -if(process.env['npm_package_config_native'] != null) return; - -sys.puts("=== EXECUTING TEST_FULL_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Should Correctly Deserialize object -var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(serialized_data); -assert.equal("a_1", object.name); -assert.equal(false, object.unique); -assert.equal(1, object.key.a); - -// Should Correctly Deserialize object with all types -var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} - -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal("hello", object.string); -assert.deepEqual([1, 2, 3], object.array); -assert.equal(1, object.hash.a); -assert.equal(2, object.hash.b); -assert.ok(object.date != null); -assert.ok(object.oid != null); -assert.ok(object.binary != null); -assert.equal(42, object.int); -assert.equal(33.3333, object.float); -assert.ok(object.regexp != null); -assert.equal(true, object.boolean); -assert.ok(object.where != null); -assert.ok(object.dbref != null); -assert.ok(object['null'] == null); - -// Should Serialize and Deserialze String -var test_string = {hello: 'world'} -var serialized_data = bsonC.serialize(test_string) -assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_number = {doc: 5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize null value -var test_null = {doc:null} -var serialized_data = bsonC.serialize(test_null) -var object = bsonC.deserialize(serialized_data); -assert.deepEqual(test_null, object); - -// Should Correctly Serialize and Deserialize undefined value -var test_undefined = {doc:undefined} -var serialized_data = bsonC.serialize(test_undefined) -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal(null, object.doc) - -// Should Correctly Serialize and Deserialize Number -var test_number = {doc: 5.5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_int = {doc: 42} -var serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -5600} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: 2147483647} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -2147483648} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Object -var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array with added on functions -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize A Boolean -var doc = {doc: true} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize a Date -var date = new Date() -//(2009, 11, 12, 12, 00, 30) -date.setUTCDate(12) -date.setUTCFullYear(2009) -date.setUTCMonth(11 - 1) -date.setUTCHours(12) -date.setUTCMinutes(0) -date.setUTCSeconds(30) -var doc = {doc: date} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// // Should Correctly Serialize and Deserialize Oid -var doc = {doc: new ObjectID()} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - -// Should Correctly encode Empty Hash -var test_code = {} -var serialized_data = bsonC.serialize(test_code) -assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Ordered Hash -var doc = {doc: {b:1, a:2, c:3, d:4}} -var serialized_data = bsonC.serialize(doc) -var decoded_hash = bsonC.deserialize(serialized_data).doc -var keys = [] -for(name in decoded_hash) keys.push(name) -assert.deepEqual(['b', 'a', 'c', 'd'], keys) - -// Should Correctly Serialize and Deserialize Regular Expression -// Serialize the regular expression -var doc = {doc: /foobar/mi} -var serialized_data = bsonC.serialize(doc) -var doc2 = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.toString(), doc2.doc.toString()) - -// Should Correctly Serialize and Deserialize a Binary object -var bin = new Binary() -var string = 'binstring' -for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) -} -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - -// Should Correctly Serialize and Deserialize a big Binary object -var data = fs.readFileSync("../../test/gridstore/test_gs_weird_bug.png", 'binary'); -var bin = new Binary() -bin.write(data) -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js deleted file mode 100644 index f271caceb82..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js +++ /dev/null @@ -1,132 +0,0 @@ -var Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - assert = require('assert'); - -if(process.env['npm_package_config_native'] != null) return; - -console.log("=== EXECUTING TEST_STACKLESS_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Number of iterations for the benchmark -var COUNT = 10000; -// var COUNT = 1; -// Sample simple doc -var doc = {key:"Hello world", key2:"šđžÄćŠÄŽČĆ", key3:'客家è¯', key4:'how are you doing dog!!'}; -// var doc = {}; -// for(var i = 0; i < 100; i++) { -// doc['string' + i] = "dumdyms fsdfdsfdsfdsfsdfdsfsdfsdfsdfsdfsdfsdfsdffsfsdfs"; -// } - -// // Calculate size -console.log(bsonC.calculateObjectSize2(doc)); -console.log(bsonJS.calculateObjectSize(doc)); -// assert.equal(bsonJS.calculateObjectSize(doc), bsonC.calculateObjectSize2(doc)); - -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// Benchmark calculateObjectSize -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- - -// Benchmark 1 JS BSON -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonJS.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 2 C++ BSON calculateObjectSize -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 3 C++ BSON calculateObjectSize2 -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize2(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize2(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// // Serialize the content -// var _serializedDoc1 = bsonJS.serialize(doc, true, false); -// var _serializedDoc2 = bsonC.serialize2(doc, true, false); -// console.dir(_serializedDoc1); -// console.dir(_serializedDoc2); -// assert.equal(_serializedDoc1.toString('base64'), _serializedDoc2.toString('base64')) -// -// -// // Benchmark 1 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// // var objectBSON = bsonC.serialize2(doc, true, false); -// var objectBSON = bsonJS.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 2 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize2(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 3 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); diff --git a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript b/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/api/node_modules/mongoskin/node_modules/mongodb/index.js b/api/node_modules/mongoskin/node_modules/mongodb/index.js deleted file mode 100644 index 4f59e9d9262..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/mongodb'); diff --git a/api/node_modules/mongoskin/node_modules/mongodb/install.js b/api/node_modules/mongoskin/node_modules/mongodb/install.js deleted file mode 100644 index f9f2a5778eb..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/install.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false'; -build_native = build_native == 'true' ? true : false; -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total']); - } else { - make = spawn('gmake', ['total']); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js deleted file mode 100644 index 6e9cd306cb4..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js +++ /dev/null @@ -1,339 +0,0 @@ -/*! - * Module dependencies. - */ -var Collection = require('./collection').Collection, - Cursor = require('./cursor').Cursor, - DbCommand = require('./commands/db_command').DbCommand, - utils = require('./utils'); - -/** - * Allows the user to access the admin functionality of MongoDB - * - * @class Represents the Admin methods of MongoDB. - * @param {Object} db Current db instance we wish to perform Admin operations on. - * @return {Function} Constructor for Admin type. - */ -function Admin(db) { - if(!(this instanceof Admin)) return new Admin(db); - this.db = db; -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.buildInfo = function(callback) { - this.serverInfo(callback); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured. - * @return {null} Returns no result - * @api private - */ -Admin.prototype.serverInfo = function(callback) { - this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Retrieve this db's server status. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.serverStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) { - callback(null, doc.documents[0]); - } else { - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - } - }); -}; - -/** - * Retrieve the current profiling Level for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingLevel = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({profile:-1}, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) { - var was = doc.was; - if(was == 0) return callback(null, "off"); - if(was == 1) return callback(null, "slow_only"); - if(was == 2) return callback(null, "all"); - return callback(new Error("Error: illegal profiling level value " + was), null); - } else { - err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - } - }); -}; - -/** - * Ping the MongoDB server and retrieve results - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.ping = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - - this.db.executeDbAdminCommand({ping: 1}, callback); -} - -/** - * Authenticate against MongoDB - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.authenticate = function(username, password, callback) { - this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Logout current authenticated user - * - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.logout = function(callback) { - this.db.logout({authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Add a user to the MongoDB server, if the user exists it will - * overwrite the current password - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.addUser = function(username, password, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - options.dbName = 'admin'; - // Add user - this.db.addUser(username, password, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Remove a user from the MongoDB server - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options.dbName = 'admin'; - - this.db.removeUser(username, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Set the current profiling level of MongoDB - * - * @param {String} level The new profiling level (off, slow_only, all) - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.setProfilingLevel = function(level, callback) { - var self = this; - var command = {}; - var profile = 0; - - if(level == "off") { - profile = 0; - } else if(level == "slow_only") { - profile = 1; - } else if(level == "all") { - profile = 2; - } else { - return callback(new Error("Error: illegal profiling level value " + level)); - } - - // Set up the profile number - command['profile'] = profile; - - this.db.executeDbAdminCommand(command, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) - return callback(null, level); - return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - }); -}; - -/** - * Retrive the current profiling information for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingInfo = function(callback) { - try { - new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) { - return callback(err, items); - }); - } catch (err) { - return callback(err, null); - } -}; - -/** - * Execute a db command against the Admin database - * - * @param {Object} command A command object `{ping:1}`. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.command = function(command, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Execute a command - this.db.executeDbAdminCommand(command, options, function(err, doc) { - // Ensure change before event loop executes - return callback != null ? callback(err, doc) : null; - }); -} - -/** - * Validate an existing collection - * - * @param {String} collectionName The name of the collection to validate. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.validateCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - var self = this; - var command = {validate: collectionName}; - var keys = Object.keys(options); - - // Decorate command with extra options - for(var i = 0; i < keys.length; i++) { - if(options.hasOwnProperty(keys[i])) { - command[keys[i]] = options[keys[i]]; - } - } - - this.db.executeDbCommand(command, function(err, doc) { - if(err != null) return callback(err, null); - doc = doc.documents[0]; - - if(doc.ok === 0) - return callback(new Error("Error with validate command"), null); - if(doc.result != null && doc.result.constructor != String) - return callback(new Error("Error with validation data"), null); - if(doc.result != null && doc.result.match(/exception|corrupt/) != null) - return callback(new Error("Error: invalid collection " + collectionName), null); - if(doc.valid != null && !doc.valid) - return callback(new Error("Error: invalid collection " + collectionName), null); - - return callback(null, doc); - }); -}; - -/** - * List the available databases - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.listDatabases = function(callback) { - // Execute the listAllDatabases command - this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Get ReplicaSet status - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.replSetGetStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) - return callback(null, doc.documents[0]); - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - }); -}; - -/** - * @ignore - */ -exports.Admin = Admin; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js deleted file mode 100644 index 9c80d809291..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js +++ /dev/null @@ -1,1762 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var InsertCommand = require('./commands/insert_command').InsertCommand - , QueryCommand = require('./commands/query_command').QueryCommand - , DeleteCommand = require('./commands/delete_command').DeleteCommand - , UpdateCommand = require('./commands/update_command').UpdateCommand - , DbCommand = require('./commands/db_command').DbCommand - , ObjectID = require('bson').ObjectID - , Code = require('bson').Code - , Cursor = require('./cursor').Cursor - , utils = require('./utils'); - -/** - * Precompiled regexes - * @ignore -**/ -const eErrorMessages = /No matching object found/; - -/** - * toString helper. - * @ignore - */ -var toString = Object.prototype.toString; - -/** - * Create a new Collection instance (INTERNAL TYPE) - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **slaveOk** {Boolean, default:false}, Allow reads from secondaries. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - * @class Represents a Collection - * @param {Object} db db instance. - * @param {String} collectionName collection name. - * @param {Object} [pkFactory] alternative primary key factory. - * @param {Object} [options] additional options for the collection. - * @return {Object} a collection instance. - */ -function Collection (db, collectionName, pkFactory, options) { - if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options); - - checkCollectionName(collectionName); - - this.db = db; - this.collectionName = collectionName; - this.internalHint = null; - this.opts = options != null && ('object' === typeof options) ? options : {}; - this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk; - this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions; - this.raw = options == null || options.raw == null ? db.raw : options.raw; - - this.readPreference = options == null || options.readPreference == null ? db.serverConfig.readPreference : options.readPreference; - this.readPreference = this.readPreference == null ? 'primary' : this.readPreference; - - this.pkFactory = pkFactory == null - ? ObjectID - : pkFactory; - - var self = this; -} - -/** - * Inserts a single document or a an array of documents into MongoDB. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Array|Object} docs - * @param {Object} [options] optional options for insert command - * @param {Function} [callback] optional callback for the function, must be provided when using a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.insert = function insert (docs, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - insertAll(self, Array.isArray(docs) ? docs : [docs], options, callback); - return this; -}; - -/** - * @ignore - */ -var checkCollectionName = function checkCollectionName (collectionName) { - if ('string' !== typeof collectionName) { - throw Error("collection name must be a String"); - } - - if (!collectionName || collectionName.indexOf('..') != -1) { - throw Error("collection names cannot be empty"); - } - - if (collectionName.indexOf('$') != -1 && - collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) { - throw Error("collection names must not contain '$'"); - } - - if (collectionName.match(/^\.|\.$/) != null) { - throw Error("collection names must not start or end with '.'"); - } -}; - -/** - * Removes documents specified by `selector` from the db. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **single** {Boolean, default:false}, removes the first document found. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [selector] optional select, no selector is equivalent to removing all documents. - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a remove with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.remove = function remove(selector, options, callback) { - if ('function' === typeof selector) { - callback = selector; - selector = options = {}; - } else if ('function' === typeof options) { - callback = options; - options = {}; - } - - // Ensure options - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Ensure we have at least an empty selector - selector = selector == null ? {} : selector; - // Set up flags for the command, if we have a single document remove - var flags = 0 | (options.single ? 1 : 0); - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Create a delete command - var deleteCommand = new DeleteCommand( - this.db - , dbName + "." + this.collectionName - , selector - , flags); - - var self = this; - var errorOptions = _getWriteConcern(self, options, callback); - // Execute the command, do not add a callback as it's async - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = true; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeRemoveCommand(deleteCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, error[0].n); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - var result = this.db._executeRemoveCommand(deleteCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * Renames the collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} newName the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback the callback accepting the result - * @return {null} - * @api public - */ -Collection.prototype.rename = function rename (newName, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - // Ensure the new name is valid - checkCollectionName(newName); - // Execute the command, return the new renamed collection if successful - self.db._executeQueryCommand(DbCommand.createRenameCollectionCommand(self.db, self.collectionName, newName, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - if(callback != null) { - // Set current object to point to the new name - self.collectionName = newName; - // Return the current collection - callback(null, self); - } - } else if(result.documents[0].errmsg != null) { - if(null != callback) { - if (null == err) { - err = utils.toError(result.documents[0]); - } - callback(err, null); - } - } - }); -}; - -/** - * @ignore - */ -var insertAll = function insertAll (self, docs, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Insert options (flags for insert) - var insertFlags = {}; - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['keepGoing'] != null) { - insertFlags['keepGoing'] = options['keepGoing']; - } - - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['continueOnError'] != null) { - insertFlags['continueOnError'] = options['continueOnError']; - } - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = self.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - insertFlags['serializeFunctions'] = options['serializeFunctions']; - } else { - insertFlags['serializeFunctions'] = self.serializeFunctions; - } - - // Pass in options - var insertCommand = new InsertCommand( - self.db - , dbName + "." + self.collectionName, true, insertFlags); - - // Add the documents and decorate them with id's if they have none - for(var index = 0, len = docs.length; index < len; ++index) { - var doc = docs[index]; - - // Add id to each document if it's not already defined - if (!(Buffer.isBuffer(doc)) && doc['_id'] == null && self.db.forceServerObjectId != true) { - doc['_id'] = self.pkFactory.createPk(); - } - - insertCommand.add(doc); - } - - // Collect errorOptions - var errorOptions = _getWriteConcern(self, options, callback); - // Default command options - var commandOptions = {}; - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - self.db._executeInsertCommand(insertCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if (err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, docs); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute the call without a write concern - var result = self.db._executeInsertCommand(insertCommand, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, docs); - } -}; - -/** - * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic - * operators and update instead for more efficient operations. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [doc] the document to save - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a safe save - * @return {null} - * @api public - */ -Collection.prototype.save = function save(doc, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Extract the id, if we have one we need to do a update command - var id = doc['_id']; - var commandOptions = _getWriteConcern(this, options, callback); - - if(id) { - commandOptions.upsert = true; - this.update({ _id: id }, doc, commandOptions, callback); - } else { - this.insert(doc, commandOptions, callback && function (err, docs) { - if (err) return callback(err, null); - - if (Array.isArray(docs)) { - callback(err, docs[0]); - } else { - callback(err, docs); - } - }); - } -}; - -/** - * Updates documents. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **multi** {Boolean, default:false}, update all documents matching the selector. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} selector the query to select the document/documents to be updated - * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted. - * @param {Object} [options] additional options during update. - * @param {Function} [callback] must be provided if you performing an update with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.update = function update(selector, document, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - var updateCommand = new UpdateCommand( - this.db - , dbName + "." + this.collectionName - , selector - , document - , options); - - var self = this; - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeUpdateCommand(updateCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - // Perform the callback - callback(null, error[0].n, error[0]); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute update - var result = this.db._executeUpdateCommand(updateCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * The distinct command returns returns a list of distinct values for the given key across a collection. - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} key key to run distinct against. - * @param {Object} [query] option query to narrow the returned objects. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from distinct or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.distinct = function distinct(key, query, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - - var mapCommandHash = { - 'distinct': this.collectionName - , 'query': query - , 'key': key - }; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // Create the command - var cmd = DbCommand.createDbSlaveOkCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err) - return callback(err); - if(result.documents[0].ok != 1) - return callback(new Error(result.documents[0].errmsg)); - callback(null, result.documents[0].values); - }); -}; - -/** - * Count number of matching documents in the db to a query. - * - * Options - * - **skip** {Number}, The number of documents to skip for the count. - * - **limit** {Number}, The limit of documents to count. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object} [query] query to filter by before performing count. - * @param {Object} [options] additional options during count. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the count method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.count = function count (query, options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - var skip = options.skip; - var limit = options.limit; - - // Final query - var final_query = { - 'count': this.collectionName - , 'query': query - , 'fields': null - }; - - // Add limit and skip if defined - if(typeof skip == 'number') final_query.skip = skip; - if(typeof limit == 'number') final_query.limit = limit; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Set up query options - var queryOptions = QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - if (this.slaveOk || this.db.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - var queryCommand = new QueryCommand( - this.db - , this.db.databaseName + ".$cmd" - , queryOptions - , 0 - , -1 - , final_query - , null - ); - - var self = this; - this.db._executeQueryCommand(queryCommand, {read:readPreference}, function (err, result) { - result = result && result.documents; - if(!callback) return; - - if(err) return callback(err); - if (result[0].ok != 1 || result[0].errmsg) { - return callback(utils.toError(result[0])); - } - callback(null, result[0].n); - }); -}; - - -/** - * Drop the collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the drop method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.drop = function drop(callback) { - this.db.dropCollection(this.collectionName, callback); -}; - -/** - * Find and update a document. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **remove** {Boolean, default:false}, set to true to remove the object before returning. - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} doc - the fields/vals to be updated - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndModify method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndModify = function findAndModify (query, sort, doc, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - doc = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - var self = this; - - var queryObject = { - 'findandmodify': this.collectionName - , 'query': query - , 'sort': utils.formattedOrderClause(sort) - }; - - queryObject.new = options.new ? 1 : 0; - queryObject.remove = options.remove ? 1 : 0; - queryObject.upsert = options.upsert ? 1 : 0; - - if (options.fields) { - queryObject.fields = options.fields; - } - - if (doc && !options.remove) { - queryObject.update = doc; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - - // If we have j, w or something else do the getLast Error path - if(errorOptions != null && typeof errorOptions == 'object') { - // Commands to send - var commands = []; - // Add the find and modify command - commands.push(DbCommand.createDbCommand(this.db, queryObject, options)); - // If we have safe defined we need to return both call results - var chainedCommands = errorOptions != null ? true : false; - // Add error command if we have one - if(chainedCommands) { - commands.push(DbCommand.createGetLastErrorCommand(errorOptions, this.db)); - } - - // Fire commands and - this.db._executeQueryCommand(commands, {read:false}, function(err, result) { - if(err != null) return callback(err); - result = result && result.documents; - - if(result[0].err != null) { - return callback(utils.toError(result[0]), null); - } - - // Workaround due to 1.8.X returning an error on no matching object - // while 2.0.X does not not, making 2.0.X behaviour standard - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - return callback(null, result[0].value, result[0]); - }); - } else { - // Only run command and rely on getLastError command - var command = DbCommand.createDbCommand(this.db, queryObject, options) - // Execute command - this.db._executeQueryCommand(command, {read:false}, function(err, result) { - if(err != null) return callback(err); - - result = result && result.documents; - - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - // If we have an error return it - if(result[0].lastErrorObject && result[0].lastErrorObject.err != null) { - return callback(utils.toError(result[0].lastErrorObject), null); - } - - return callback(null, result[0].value, result[0]); - }); - } -} - -/** - * Find and remove a document - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndRemove method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndRemove = function(query, sort, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - options = args.length ? args.shift() : {}; - // Add the remove option - options['remove'] = true; - // Execute the callback - this.findAndModify(query, sort, null, options, callback); -} - -var testForFields = { - limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1 - , numberOfRetries: 1, awaitdata: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1 - , comment: 1, raw: 1, readPreference: 1, numberOfRetries: 1, partial: 1, read: 1, dbName: 1 -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **tailableRetryInterval** {Number, default:100}, specify the miliseconds between getMores on tailable cursor. - * - **numberOfRetries** {Number, default:5}, specify the number of times to retry the tailable cursor. - * - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor. - * - **exhaust** {Boolean, default:false} have the server send all the documents at once as getMore packets, not recommended. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **numberOfRetries** {Number, default:5}, if using awaidata specifies the number of times to retry on timeout. - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the find method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.find = function find () { - var options - , args = Array.prototype.slice.call(arguments, 0) - , has_callback = typeof args[args.length - 1] === 'function' - , has_weird_callback = typeof args[0] === 'function' - , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null) - , len = args.length - , selector = len >= 1 ? args[0] : {} - , fields = len >= 2 ? args[1] : undefined; - - if(len === 1 && has_weird_callback) { - // backwards compat for callback?, options case - selector = {}; - options = args[0]; - } - - if(len === 2 && !Array.isArray(fields)) { - var fieldKeys = Object.getOwnPropertyNames(fields); - var is_option = false; - - for(var i = 0; i < fieldKeys.length; i++) { - if(testForFields[fieldKeys[i]] != null) { - is_option = true; - break; - } - } - - if(is_option) { - options = fields; - fields = undefined; - } else { - options = {}; - } - } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) { - var newFields = {}; - // Rewrite the array - for(var i = 0; i < fields.length; i++) { - newFields[fields[i]] = 1; - } - // Set the fields - fields = newFields; - } - - if(3 === len) { - options = args[2]; - } - - // Ensure selector is not null - selector = selector == null ? {} : selector; - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Validate correctness of the field selector - var object = fields; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Check special case where we are using an objectId - if(selector instanceof ObjectID) { - selector = {_id:selector}; - } - - // If it's a serialized fields field we need to just let it through - // user be warned it better be good - if(options && options.fields && !(Buffer.isBuffer(options.fields))) { - fields = {}; - - if(Array.isArray(options.fields)) { - if(!options.fields.length) { - fields['_id'] = 1; - } else { - for (var i = 0, l = options.fields.length; i < l; i++) { - fields[options.fields[i]] = 1; - } - } - } else { - fields = options.fields; - } - } - - if (!options) options = {}; - options.skip = len > 3 ? args[2] : options.skip ? options.skip : 0; - options.limit = len > 3 ? args[3] : options.limit ? options.limit : 0; - options.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw; - options.hint = options.hint != null ? normalizeHintField(options.hint) : this.internalHint; - options.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout; - // If we have overridden slaveOk otherwise use the default db setting - options.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk; - - // Set option - var o = options; - // Support read/readPreference - if(o["read"] != null) o["readPreference"] = o["read"]; - // Set the read preference - o.read = o["readPreference"] ? o.readPreference : this.readPreference; - // Adjust slave ok if read preference is secondary or secondary only - if(o.read == "secondary" || o.read == "secondaryOnly") options.slaveOk = true; - - // callback for backward compatibility - if(callback) { - // TODO refactor Cursor args - callback(null, new Cursor(this.db, this, selector, fields, o)); - } else { - return new Cursor(this.db, this, selector, fields, o); - } -}; - -/** - * Normalizes a `hint` argument. - * - * @param {String|Object|Array} hint - * @return {Object} - * @api private - */ -var normalizeHintField = function normalizeHintField(hint) { - var finalHint = null; - - if (null != hint) { - switch (hint.constructor) { - case String: - finalHint = {}; - finalHint[hint] = 1; - break; - case Object: - finalHint = {}; - for (var name in hint) { - finalHint[name] = hint[name]; - } - break; - case Array: - finalHint = {}; - hint.forEach(function(param) { - finalHint[param] = 1; - }); - break; - } - } - - return finalHint; -}; - -/** - * Finds a single document based on the query - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findOne method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.findOne = function findOne () { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - var callback = args.pop(); - var cursor = this.find.apply(this, args).limit(-1).batchSize(1); - // Return the item - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the createIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.createIndex = function createIndex (fieldOrSpec, options, callback) { - // Clean up call - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Collect errorOptions - var errorOptions = _getWriteConcern(this, options, callback); - // Execute create index - this.db.createIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the ensureIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.ensureIndex = function ensureIndex (fieldOrSpec, options, callback) { - // Clean up call - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Execute create index - this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexInformation method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexInformation = function indexInformation (options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // Call the index information - this.db.indexInformation(this.collectionName, options, callback); -}; - -/** - * Drops an index from this collection. - * - * @param {String} name - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropIndex = function dropIndex (name, callback) { - this.db.dropIndex(this.collectionName, name, callback); -}; - -/** - * Drops all indexes from this collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropAllIndexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropAllIndexes = function dropIndexes (callback) { - this.db.dropIndex(this.collectionName, '*', function (err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Drops all indexes from this collection. - * - * @deprecated - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndexes method or null if an error occured. - * @return {null} - * @api private - */ -Collection.prototype.dropIndexes = Collection.prototype.dropAllIndexes; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the reIndex method or null if an error occured. - * @return {null} - * @api public -**/ -Collection.prototype.reIndex = function(callback) { - this.db.reIndex(this.collectionName, callback); -} - -/** - * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection. - * - * Options - * - **out** {Object, default:*{inline:1}*}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}* - * - **query** {Object}, query filter object. - * - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces. - * - **limit** {Number}, number of objects to return from collection. - * - **keeptemp** {Boolean, default:false}, keep temporary data. - * - **finalize** {Function | String}, finalize function. - * - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize. - * - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X. - * - **verbose** {Boolean, default:false}, provide statistics on job execution time. - * - **readPreference** {String, only for inline results}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Function|String} map the mapping function. - * @param {Function|String} reduce the reduce function. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the mapReduce method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.mapReduce = function mapReduce (map, reduce, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers) - if(null == options.out) { - throw new Error("the out option parameter must be defined, see mongodb docs for possible values"); - } - - if ('function' === typeof map) { - map = map.toString(); - } - - if ('function' === typeof reduce) { - reduce = reduce.toString(); - } - - if ('function' === typeof options.finalize) { - options.finalize = options.finalize.toString(); - } - - var mapCommandHash = { - mapreduce: this.collectionName - , map: map - , reduce: reduce - }; - - // Add any other options passed in - for (var name in options) { - if ('scope' == name) { - mapCommandHash[name] = processScope(options[name]); - } else { - mapCommandHash[name] = options[name]; - } - } - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // If we have a read preference and inline is not set as output fail hard - if(readPreference != false && options['out'] != 'inline') { - throw new Error("a readPreference can only be provided when performing an inline mapReduce"); - } - - // self - var self = this; - var cmd = DbCommand.createDbCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if (err) { - return callback(err); - } - - // - if (1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) { - return callback(utils.toError(result.documents[0])); - } - - // Create statistics value - var stats = {}; - if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis; - if(result.documents[0].counts) stats['counts'] = result.documents[0].counts; - if(result.documents[0].timing) stats['timing'] = result.documents[0].timing; - - // invoked with inline? - if(result.documents[0].results) { - return callback(null, result.documents[0].results, stats); - } - - // The returned collection - var collection = null; - - // If we have an object it's a different db - if(result.documents[0].result != null && typeof result.documents[0].result == 'object') { - var doc = result.documents[0].result; - collection = self.db.db(doc.db).collection(doc.collection); - } else { - // Create a collection object that wraps the result collection - collection = self.db.collection(result.documents[0].result) - } - - // If we wish for no verbosity - if(options['verbose'] == null || !options['verbose']) { - return callback(err, collection); - } - - // Return stats as third set of values - callback(err, collection, stats); - }); -}; - -/** - * Functions that are passed as scope args must - * be converted to Code instances. - * @ignore - */ -function processScope (scope) { - if (!utils.isObject(scope)) { - return scope; - } - - var keys = Object.keys(scope); - var i = keys.length; - var key; - - while (i--) { - key = keys[i]; - if ('function' == typeof scope[key]) { - scope[key] = new Code(String(scope[key])); - } - } - - return scope; -} - -/** - * Group function helper - * @ignore - */ -var groupFunction = function () { - var c = db[ns].find(condition); - var map = new Map(); - var reduce_function = reduce; - - while (c.hasNext()) { - var obj = c.next(); - var key = {}; - - for (var i = 0, len = keys.length; i < len; ++i) { - var k = keys[i]; - key[k] = obj[k]; - } - - var aggObj = map.get(key); - - if (aggObj == null) { - var newObj = Object.extend({}, key); - aggObj = Object.extend(newObj, initial); - map.put(key, aggObj); - } - - reduce_function(obj, aggObj); - } - - return { "result": map.values() }; -}.toString(); - -/** - * Run a group command across a collection - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by. - * @param {Object} condition an optional condition that must be true for a row to be considered. - * @param {Object} initial initial value of the aggregation counter object. - * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated - * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned. - * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the group method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.group = function group(keys, condition, initial, reduce, finalize, command, options, callback) { - var args = Array.prototype.slice.call(arguments, 3); - callback = args.pop(); - // Fetch all commands - reduce = args.length ? args.shift() : null; - finalize = args.length ? args.shift() : null; - command = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Make sure we are backward compatible - if(!(typeof finalize == 'function')) { - command = finalize; - finalize = null; - } - - if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) { - keys = Object.keys(keys); - } - - if(typeof reduce === 'function') { - reduce = reduce.toString(); - } - - if(typeof finalize === 'function') { - finalize = finalize.toString(); - } - - // Set up the command as default - command = command == null ? true : command; - - // Execute using the command - if(command) { - var reduceFunction = reduce instanceof Code - ? reduce - : new Code(reduce); - - var selector = { - group: { - 'ns': this.collectionName - , '$reduce': reduceFunction - , 'cond': condition - , 'initial': initial - , 'out': "inline" - } - }; - - // if finalize is defined - if(finalize != null) selector.group['finalize'] = finalize; - // Set up group selector - if ('function' === typeof keys || keys instanceof Code) { - selector.group.$keyf = keys instanceof Code - ? keys - : new Code(keys); - } else { - var hash = {}; - keys.forEach(function (key) { - hash[key] = 1; - }); - selector.group.key = hash; - } - - var cmd = DbCommand.createDbSlaveOkCommand(this.db, selector); - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err != null) return callback(err); - - var document = result.documents[0]; - if (null == document.retval) { - return callback(new Error("group command failed: " + document.errmsg)); - } - - callback(null, document.retval); - }); - - } else { - // Create execution scope - var scope = reduce != null && reduce instanceof Code - ? reduce.scope - : {}; - - scope.ns = this.collectionName; - scope.keys = keys; - scope.condition = condition; - scope.initial = initial; - - // Pass in the function text to execute within mongodb. - var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';'); - - this.db.eval(new Code(groupfn, scope), function (err, results) { - if (err) return callback(err, null); - callback(null, results.result || results); - }); - } -}; - -/** - * Returns the options of the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the options method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.options = function options(callback) { - this.db.collectionsInfo(this.collectionName, function (err, cursor) { - if (err) return callback(err); - cursor.nextObject(function (err, document) { - callback(err, document && document.options || null); - }); - }); -}; - -/** - * Returns if the collection is a capped collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the isCapped method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.isCapped = function isCapped(callback) { - this.options(function(err, document) { - if(err != null) { - callback(err); - } else { - callback(null, document && document.capped); - } - }); -}; - -/** - * Checks if one or more indexes exist on the collection - * - * @param {String|Array} indexNames check if one or more indexes exist on the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexExists method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexExists = function indexExists(indexes, callback) { - this.indexInformation(function(err, indexInformation) { - // If we have an error return - if(err != null) return callback(err, null); - // Let's check for the index names - if(Array.isArray(indexes)) { - for(var i = 0; i < indexes.length; i++) { - if(indexInformation[indexes[i]] == null) { - return callback(null, false); - } - } - - // All keys found return true - return callback(null, true); - } else { - return callback(null, indexInformation[indexes] != null); - } - }); -} - -/** - * Execute the geoNear command to search for items in the collection - * - * Options - * - **num** {Number}, max number of results to return. - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions. - * - **query** {Object}, filter the results by a query. - * - **spherical** {Boolean, default:false}, perform query using a spherical model. - * - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X. - * - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoNear method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoNear = function geoNear(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoNear:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['num'] != null) commandObject['num'] = options['num']; - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['distanceMultiplier'] != null) commandObject['distanceMultiplier'] = options['distanceMultiplier']; - if(options['query'] != null) commandObject['query'] = options['query']; - if(options['spherical'] != null) commandObject['spherical'] = options['spherical']; - if(options['uniqueDocs'] != null) commandObject['uniqueDocs'] = options['uniqueDocs']; - if(options['includeLocs'] != null) commandObject['includeLocs'] = options['includeLocs']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Execute a geo search using a geo haystack index on a collection. - * - * Options - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **search** {Object}, filter the results by a query. - * - **limit** {Number}, max number of results to return. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoHaystackSearch method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoSearch:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['query'] != null) commandObject['search'] = options['query']; - if(options['search'] != null) commandObject['search'] = options['search']; - if(options['limit'] != null) commandObject['limit'] = options['limit']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Retrieve all the indexes on the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexes = function indexes(callback) { - // Return all the index information - this.db.indexInformation(this.collectionName, {full:true}, callback); -} - -/** - * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.1 - * - * Options - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Array} array containing all the aggregation framework commands for the execution. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the aggregate method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.aggregate = function(pipeline, options, callback) { - // * - **explain** {Boolean}, return the query plan for the aggregation pipeline instead of the results. 2.3, 2.4 - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - var self = this; - - // If we have any of the supported options in the options object - var opts = args[args.length - 1]; - options = opts.readPreference || opts.explain ? args.pop() : {} - - // Convert operations to an array - if(!Array.isArray(args[0])) { - pipeline = []; - // Push all the operations to the pipeline - for(var i = 0; i < args.length; i++) pipeline.push(args[i]); - } - - // Build the command - var command = { aggregate : this.collectionName, pipeline : pipeline}; - // Add all options - var keys = Object.keys(options); - // Add all options - for(var i = 0; i < keys.length; i++) { - command[keys[i]] = options[keys[i]]; - } - - // Execute the command - this.db.command(command, options, function(err, result) { - if(err) { - callback(err); - } else if(result['err'] || result['errmsg']) { - callback(utils.toError(result)); - } else if(typeof result == 'object' && result['serverPipeline']) { - callback(null, result); - } else { - callback(null, result.result); - } - }); -} - -/** - * Get all the collection statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the stats method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - collStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * @ignore - */ -Object.defineProperty(Collection.prototype, "hint", { - enumerable: true - , get: function () { - return this.internalHint; - } - , set: function (v) { - this.internalHint = normalizeHintField(v); - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(self.opts.w != null || typeof self.opts.j == 'boolean' || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.opts); - } else if(typeof self.opts.safe == "boolean") { - finalOptions = {w: (self.opts.safe ? 1 : 0)}; - } else if(self.db.safe.w != null || typeof self.db.safe.j == 'boolean' || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.safe); - } else if(self.db.options.w != null || typeof self.db.options.j == 'boolean' || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.options); - } else if(typeof self.db.safe == "boolean") { - finalOptions = {w: (self.db.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Expose. - */ -exports.Collection = Collection; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js deleted file mode 100644 index 955858283ce..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - Base object used for common functionality -**/ -var BaseCommand = exports.BaseCommand = function BaseCommand() { -}; - -var id = 1; -BaseCommand.prototype.getRequestId = function getRequestId() { - if (!this.requestId) this.requestId = id++; - return this.requestId; -}; - -BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {} - -BaseCommand.prototype.updateRequestId = function() { - this.requestId = id++; - return this.requestId; -}; - -// OpCodes -BaseCommand.OP_REPLY = 1; -BaseCommand.OP_MSG = 1000; -BaseCommand.OP_UPDATE = 2001; -BaseCommand.OP_INSERT = 2002; -BaseCommand.OP_GET_BY_OID = 2003; -BaseCommand.OP_QUERY = 2004; -BaseCommand.OP_GET_MORE = 2005; -BaseCommand.OP_DELETE = 2006; -BaseCommand.OP_KILL_CURSORS = 2007; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js deleted file mode 100644 index 9e85ab02d7b..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js +++ /dev/null @@ -1,241 +0,0 @@ -var QueryCommand = require('./query_command').QueryCommand, - InsertCommand = require('./insert_command').InsertCommand, - inherits = require('util').inherits, - utils = require('../utils'), - crypto = require('crypto'); - -/** - Db Command -**/ -var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - QueryCommand.call(this); - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = dbInstance; - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(DbCommand, QueryCommand); - -// Constants -DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"; -DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes"; -DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile"; -DbCommand.SYSTEM_USER_COLLECTION = "system.users"; -DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd"; -DbCommand.SYSTEM_JS_COLLECTION = "system.js"; - -// New commands -DbCommand.NcreateIsMasterCommand = function(db, databaseName) { - return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -// Provide constructors for different db commands -DbCommand.createIsMasterCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -DbCommand.createCollectionInfoCommand = function(db, selector) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null); -}; - -DbCommand.createGetNonceCommand = function(db, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null); -}; - -DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) { - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var hash_password = md5.digest('hex'); - // Final key - md5 = crypto.createHash('md5'); - md5.update(nonce + username + hash_password); - var key = md5.digest('hex'); - // Creat selector - var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key}; - // Create db command - return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null); -}; - -DbCommand.createLogoutCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null); -}; - -DbCommand.createCreateCollectionCommand = function(db, collectionName, options) { - var selector = {'create':collectionName}; - // Modify the options to ensure correct behaviour - for(var name in options) { - if(options[name] != null && options[name].constructor != Function) selector[name] = options[name]; - } - // Execute the command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null); -}; - -DbCommand.createDropCollectionCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null); -}; - -DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName, options) { - var renameCollection = db.databaseName + "." + fromCollectionName; - var toCollection = db.databaseName + "." + toCollectionName; - var dropTarget = options && options.dropTarget ? options.dropTarget : false; - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget}, null); -}; - -DbCommand.createGetLastErrorCommand = function(options, db) { - - if (typeof db === 'undefined') { - db = options; - options = {}; - } - // Final command - var command = {'getlasterror':1}; - // If we have an options Object let's merge in the fields (fsync/wtimeout/w) - if('object' === typeof options) { - for(var name in options) { - command[name] = options[name] - } - } - - // Special case for w == 1, remove the w - if(1 == command.w) { - delete command.w; - } - - // Execute command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null); -}; - -DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand; - -DbCommand.createGetPreviousErrorsCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null); -}; - -DbCommand.createResetErrorHistoryCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null); -}; - -DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) { - var fieldHash = {}; - var indexes = []; - var keys; - - // Get all the fields accordingly - if('string' == typeof fieldOrSpec) { - // 'type' - indexes.push(fieldOrSpec + '_' + 1); - fieldHash[fieldOrSpec] = 1; - - } else if(utils.isArray(fieldOrSpec)) { - - fieldOrSpec.forEach(function(f) { - if('string' == typeof f) { - // [{location:'2d'}, 'type'] - indexes.push(f + '_' + 1); - fieldHash[f] = 1; - } else if(utils.isArray(f)) { - // [['location', '2d'],['type', 1]] - indexes.push(f[0] + '_' + (f[1] || 1)); - fieldHash[f[0]] = f[1] || 1; - } else if(utils.isObject(f)) { - // [{location:'2d'}, {type:1}] - keys = Object.keys(f); - keys.forEach(function(k) { - indexes.push(k + '_' + f[k]); - fieldHash[k] = f[k]; - }); - } else { - // undefined (ignore) - } - }); - - } else if(utils.isObject(fieldOrSpec)) { - // {location:'2d', type:1} - keys = Object.keys(fieldOrSpec); - keys.forEach(function(key) { - indexes.push(key + '_' + fieldOrSpec[key]); - fieldHash[key] = fieldOrSpec[key]; - }); - } - - // Generate the index name - var indexName = typeof options.name == 'string' - ? options.name - : indexes.join("_"); - - var selector = { - 'ns': db.databaseName + "." + collectionName, - 'key': fieldHash, - 'name': indexName - } - - // Ensure we have a correct finalUnique - var finalUnique = options == null || 'object' === typeof options - ? false - : options; - - // Set up options - options = options == null || typeof options == 'boolean' - ? {} - : options; - - // Add all the options - var keys = Object.keys(options); - for(var i = 0; i < keys.length; i++) { - selector[keys[i]] = options[keys[i]]; - } - - if(selector['unique'] == null) - selector['unique'] = finalUnique; - - var name = db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION; - var cmd = new InsertCommand(db, name, false); - return cmd.add(selector); -}; - -DbCommand.logoutCommand = function(db, command_hash, options) { - var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName; - // Create logout command - return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -} - -DbCommand.createDropIndexCommand = function(db, collectionName, indexName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null); -}; - -DbCommand.createReIndexCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null); -}; - -DbCommand.createDropDatabaseCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null); -}; - -DbCommand.createDbCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options); -}; - -DbCommand.createAdminDbCommand = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -}; - -DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null); -}; - -DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options); -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js deleted file mode 100644 index e6ae20ab6e6..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js +++ /dev/null @@ -1,114 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.flags = flags; - this.collectionName = collectionName; - this.selector = selector; - this.db = db; -}; - -inherits(DeleteCommand, BaseCommand); - -DeleteCommand.OP_DELETE = 2006; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 ZERO; // 0 - reserved for future use - mongo.BSON selector; // query object. See below for details. -} -*/ -DeleteCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff; - _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff; - _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff; - _command[_index] = DeleteCommand.OP_DELETE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(this.selector)) { - documentLength = this.selector.length; - // Copy the data into the current buffer - this.selector.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - return _command; -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js deleted file mode 100644 index d3aac02ef81..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js +++ /dev/null @@ -1,83 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Get More Document Command -**/ -var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.numberToReturn = numberToReturn; - this.cursorId = cursorId; - this.db = db; -}; - -inherits(GetMoreCommand, BaseCommand); - -GetMoreCommand.OP_GET_MORE = 2005; - -GetMoreCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index++] = totalLengthOfCommand & 0xff; - _command[_index++] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 24) & 0xff; - - // Write the request ID - _command[_index++] = this.requestId & 0xff; - _command[_index++] = (this.requestId >> 8) & 0xff; - _command[_index++] = (this.requestId >> 16) & 0xff; - _command[_index++] = (this.requestId >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the op_code for the command - _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Number of documents to return - _command[_index++] = this.numberToReturn & 0xff; - _command[_index++] = (this.numberToReturn >> 8) & 0xff; - _command[_index++] = (this.numberToReturn >> 16) & 0xff; - _command[_index++] = (this.numberToReturn >> 24) & 0xff; - - // Encode the cursor id - var low_bits = this.cursorId.getLowBits(); - // Encode low bits - _command[_index++] = low_bits & 0xff; - _command[_index++] = (low_bits >> 8) & 0xff; - _command[_index++] = (low_bits >> 16) & 0xff; - _command[_index++] = (low_bits >> 24) & 0xff; - - var high_bits = this.cursorId.getHighBits(); - // Encode high bits - _command[_index++] = high_bits & 0xff; - _command[_index++] = (high_bits >> 8) & 0xff; - _command[_index++] = (high_bits >> 16) & 0xff; - _command[_index++] = (high_bits >> 24) & 0xff; - // Return command - return _command; -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js deleted file mode 100644 index d6a210017a5..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js +++ /dev/null @@ -1,147 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.documents = []; - this.checkKeys = checkKeys == null ? true : checkKeys; - this.db = db; - this.flags = 0; - this.serializeFunctions = false; - - // Ensure valid options hash - options = options == null ? {} : options; - - // Check if we have keepGoing set -> set flag if it's the case - if(options['keepGoing'] != null && options['keepGoing']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Check if we have keepGoing set -> set flag if it's the case - if(options['continueOnError'] != null && options['continueOnError']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(InsertCommand, BaseCommand); - -// OpCodes -InsertCommand.OP_INSERT = 2002; - -InsertCommand.prototype.add = function(document) { - if(Buffer.isBuffer(document)) { - var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24; - if(object_size != document.length) { - var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.documents.push(document); - return this; -}; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - BSON[] documents; // one or more documents to insert into the collection -} -*/ -InsertCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4); - // var docLength = 0 - for(var i = 0; i < this.documents.length; i++) { - if(Buffer.isBuffer(this.documents[i])) { - totalLengthOfCommand += this.documents[i].length; - } else { - // Calculate size of document - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true); - } - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff; - _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff; - _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff; - _command[_index] = InsertCommand.OP_INSERT & 0xff; - // Adjust index - _index = _index + 4; - // Write flags if any - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write all the bson documents to the buffer at the index offset - for(var i = 0; i < this.documents.length; i++) { - // Document binary length - var documentLength = 0 - var object = this.documents[i]; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - return _command; -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js deleted file mode 100644 index d8ccb0c3a64..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js +++ /dev/null @@ -1,98 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Insert Document Command -**/ -var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) { - BaseCommand.call(this); - - this.cursorIds = cursorIds; - this.db = db; -}; - -inherits(KillCursorCommand, BaseCommand); - -KillCursorCommand.OP_KILL_CURSORS = 2007; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - int32 numberOfCursorIDs; // number of cursorIDs in message - int64[] cursorIDs; // array of cursorIDs to close -} -*/ -KillCursorCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff; - _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff; - _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff; - _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Number of cursors to kill - var numberOfCursors = this.cursorIds.length; - _command[_index + 3] = (numberOfCursors >> 24) & 0xff; - _command[_index + 2] = (numberOfCursors >> 16) & 0xff; - _command[_index + 1] = (numberOfCursors >> 8) & 0xff; - _command[_index] = numberOfCursors & 0xff; - // Adjust index - _index = _index + 4; - - // Encode all the cursors - for(var i = 0; i < this.cursorIds.length; i++) { - // Encode the cursor id - var low_bits = this.cursorIds[i].getLowBits(); - // Encode low bits - _command[_index + 3] = (low_bits >> 24) & 0xff; - _command[_index + 2] = (low_bits >> 16) & 0xff; - _command[_index + 1] = (low_bits >> 8) & 0xff; - _command[_index] = low_bits & 0xff; - // Adjust index - _index = _index + 4; - - var high_bits = this.cursorIds[i].getHighBits(); - // Encode high bits - _command[_index + 3] = (high_bits >> 24) & 0xff; - _command[_index + 2] = (high_bits >> 16) & 0xff; - _command[_index + 1] = (high_bits >> 8) & 0xff; - _command[_index] = high_bits & 0xff; - // Adjust index - _index = _index + 4; - } - - return _command; -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js deleted file mode 100644 index 76829d9991f..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js +++ /dev/null @@ -1,261 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = query, - object_size; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - object = returnFieldSelector; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Set up options - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - - // Ensure we have no null query - query = query == null ? {} : query; - // Wrap query in the $query parameter so we can add read preferences for mongos - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = db; - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(QueryCommand, BaseCommand); - -QueryCommand.OP_QUERY = 2004; - -/* - * Adds the read prefrence to the current command - */ -QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) { - // If we have readPreference set to true set to secondary prefered - if(readPreference == true) { - readPreference = 'secondaryPreferred'; - } else if(readPreference == 'false') { - readPreference = 'primary'; - } - - // Force the slave ok flag to be set if we are not using primary read preference - if(readPreference != false && readPreference != 'primary') { - this.queryOptions |= QueryCommand.OPTS_SLAVE; - } - - // Backward compatibility, ensure $query only set on read preference so 1.8.X works - if((readPreference != null || tags != null) && this.query['$query'] == null) { - this.query = {'$query': this.query}; - } - - // If we have no readPreference set and no tags, check if the slaveOk bit is set - if(readPreference == null && tags == null) { - // If we have a slaveOk bit set the read preference for MongoS - if(this.queryOptions & QueryCommand.OPTS_SLAVE) { - this.query['$readPreference'] = {mode: 'secondary'} - } else { - this.query['$readPreference'] = {mode: 'primary'} - } - } - - // Build read preference object - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - this.query['$readPreference'] = readPreference.toObject(); - } else if(readPreference != null) { - // Add the read preference - this.query['$readPreference'] = {mode: readPreference}; - - // If we have tags let's add them - if(tags != null) { - this.query['$readPreference']['tags'] = tags; - } - } -} - -/* -struct { - MsgHeader header; // standard message header - int32 opts; // query options. See below for details. - cstring fullCollectionName; // "dbname.collectionname" - int32 numberToSkip; // number of documents to skip when returning results - int32 numberToReturn; // number of documents to return in the first OP_REPLY - BSON query ; // query object. See below for details. - [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details. -} -*/ -QueryCommand.prototype.toBinary = function() { - // Total length of the command - var totalLengthOfCommand = 0; - // Calculate total length of the document - if(Buffer.isBuffer(this.query)) { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4); - } else { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4); - } - - // Calculate extra fields size - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true); - } - } else if(Buffer.isBuffer(this.returnFieldSelector)) { - totalLengthOfCommand += this.returnFieldSelector.length; - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff; - _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff; - _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff; - _command[_index] = QueryCommand.OP_QUERY & 0xff; - // Adjust index - _index = _index + 4; - - // Write the query options - _command[_index + 3] = (this.queryOptions >> 24) & 0xff; - _command[_index + 2] = (this.queryOptions >> 16) & 0xff; - _command[_index + 1] = (this.queryOptions >> 8) & 0xff; - _command[_index] = this.queryOptions & 0xff; - // Adjust index - _index = _index + 4; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the number of documents to skip - _command[_index + 3] = (this.numberToSkip >> 24) & 0xff; - _command[_index + 2] = (this.numberToSkip >> 16) & 0xff; - _command[_index + 1] = (this.numberToSkip >> 8) & 0xff; - _command[_index] = this.numberToSkip & 0xff; - // Adjust index - _index = _index + 4; - - // Write the number of documents to return - _command[_index + 3] = (this.numberToReturn >> 24) & 0xff; - _command[_index + 2] = (this.numberToReturn >> 16) & 0xff; - _command[_index + 1] = (this.numberToReturn >> 8) & 0xff; - _command[_index] = this.numberToReturn & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.query; - - // Serialize the selector - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Push field selector if available - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) { - // Document binary length - var documentLength = 0 - var object = this.returnFieldSelector; - - // Serialize the selector - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - // Return finished command - return _command; -}; - -// Constants -QueryCommand.OPTS_NONE = 0; -QueryCommand.OPTS_TAILABLE_CURSOR = 2; -QueryCommand.OPTS_SLAVE = 4; -QueryCommand.OPTS_OPLOG_REPLY = 8; -QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16; -QueryCommand.OPTS_AWAIT_DATA = 32; -QueryCommand.OPTS_EXHAUST = 64; -QueryCommand.OPTS_PARTIAL = 128; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js deleted file mode 100644 index 9829dea453d..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js +++ /dev/null @@ -1,174 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Update Document Command -**/ -var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) { - BaseCommand.call(this); - - var object = spec; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - var object = document; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.collectionName = collectionName; - this.spec = spec; - this.document = document; - this.db = db; - this.serializeFunctions = false; - - // Generate correct flags - var db_upsert = 0; - var db_multi_update = 0; - db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert; - db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update; - - // Flags - this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2); - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(UpdateCommand, BaseCommand); - -UpdateCommand.OP_UPDATE = 2001; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 flags; // bit vector. see below - BSON spec; // the query to select the document - BSON document; // the document data to update with or insert -} -*/ -UpdateCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) + - this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4); - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff; - _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff; - _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff; - _command[_index] = UpdateCommand.OP_UPDATE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the update flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.spec; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Document binary length - var documentLength = 0 - var object = this.document; - - // Serialize the document - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - return _command; -}; - -// Constants -UpdateCommand.DB_UPSERT = 0; -UpdateCommand.DB_MULTI_UPDATE = 1; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js deleted file mode 100644 index e93463c305f..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js +++ /dev/null @@ -1,169 +0,0 @@ -var EventEmitter = require('events').EventEmitter - , inherits = require('util').inherits; - -/** - * Internal class for callback storage - * @ignore - */ -var CallbackStore = function() { - // Make class an event emitter - EventEmitter.call(this); - // Add a info about call variable - this._notReplied = {}; -} - -/** - * @ignore - */ -inherits(CallbackStore, EventEmitter); - -var Base = function Base() { - EventEmitter.call(this); - - // Callback store is part of connection specification - if(Base._callBackStore == null) { - Base._callBackStore = new CallbackStore(); - } - - // this._callBackStore = Base._callBackStore; - this._callBackStore = new CallbackStore(); -} - -/** - * @ignore - */ -inherits(Base, EventEmitter); - -/** - * Fire all the errors - * @ignore - */ -Base.prototype.__executeAllCallbacksWithError = function(err) { - // Check all callbacks - var keys = Object.keys(this._callBackStore._notReplied); - // For each key check if it's a callback that needs to be returned - for(var j = 0; j < keys.length; j++) { - var info = this._callBackStore._notReplied[keys[j]]; - // Check if we have a chained command (findAndModify) - if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) { - var chained = info['chained']; - // Only callback once and the last one is the right one - var finalCallback = chained.pop(); - // Emit only the last event - this._callBackStore.emit(finalCallback, err, null); - - // Put back the final callback to ensure we don't call all commands in the chain - chained.push(finalCallback); - - // Remove all chained callbacks - for(var i = 0; i < chained.length; i++) { - delete this._callBackStore._notReplied[chained[i]]; - } - } else { - this._callBackStore.emit(keys[j], err, null); - } - } -} - -/** - * Register a handler - * @ignore - * @api private - */ -Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) { - // If we have an array of commands, chain them - var chained = Array.isArray(db_command); - - // Check if we have exhausted - if(typeof exhaust == 'function') { - callback = exhaust; - exhaust = false; - } - - // If they are chained we need to add a special handler situation - if(chained) { - // List off chained id's - var chainedIds = []; - // Add all id's - for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString()); - // Register all the commands together - for(var i = 0; i < db_command.length; i++) { - var command = db_command[i]; - // Add the callback to the store - this._callBackStore.once(command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection, exhaust:false}; - } - } else { - // Add the callback to the list of handlers - this._callBackStore.once(db_command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust}; - } -} - -/** - * Re-Register a handler, on the cursor id f.ex - * @ignore - * @api private - */ -Base.prototype._reRegisterHandler = function(newId, object, callback) { - // Add the callback to the list of handlers - this._callBackStore.once(newId, object.callback.listener); - // Add the information about the reply - this._callBackStore._notReplied[newId] = object.info; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._callHandler = function(id, document, err) { - // If there is a callback peform it - if(this._callBackStore.listeners(id).length >= 1) { - // Get info object - var info = this._callBackStore._notReplied[id]; - // Delete the current object - delete this._callBackStore._notReplied[id]; - // Emit to the callback of the object - this._callBackStore.emit(id, err, document, info.connection); - } -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._hasHandler = function(id) { - // If there is a callback peform it - return this._callBackStore.listeners(id).length >= 1; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._removeHandler = function(id) { - // Remove the information - if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id]; - // Remove the callback if it's registered - this._callBackStore.removeAllListeners(id); - // Force cleanup _events, node.js seems to set it as a null value - if(this._callBackStore._events != null) delete this._callBackStore._events[id]; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._findHandler = function(id) { - var info = this._callBackStore._notReplied[id]; - // Return the callback - return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null} -} - -exports.Base = Base; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js deleted file mode 100644 index 41647a36538..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js +++ /dev/null @@ -1,504 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - binaryutils = require('../utils'), - tls = require('tls'); - -var Connection = exports.Connection = function(id, socketOptions) { - // Set up event emitter - EventEmitter.call(this); - // Store all socket options - this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false}; - // Set keep alive default if not overriden - if(this.socketOptions.keepAlive == null && (process.platform !== "sunos" || process.platform !== "win32")) this.socketOptions.keepAlive = 100; - // Id for the connection - this.id = id; - // State of the connection - this.connected = false; - // Set if this is a domain socket - this.domainSocket = this.socketOptions.domainSocket; - - // - // Connection parsing state - // - this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE; - this.maxMessageSizeBytes = socketOptions.maxMessageSizeBytes ? socketOptions.maxMessageSizeBytes : Connection.DEFAULT_MAX_MESSAGE_SIZE; - // Contains the current message bytes - this.buffer = null; - // Contains the current message size - this.sizeOfMessage = 0; - // Contains the readIndex for the messaage - this.bytesRead = 0; - // Contains spill over bytes from additional messages - this.stubBuffer = 0; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]}; - - // Just keeps list of events we allow - resetHandlers(this, false); -} - -// Set max bson size -Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4; -// Set default to max bson to avoid overflow or bad guesses -Connection.DEFAULT_MAX_MESSAGE_SIZE = Connection.DEFAULT_MAX_BSON_SIZE; - -// Inherit event emitter so we can emit stuff wohoo -inherits(Connection, EventEmitter); - -Connection.prototype.start = function() { - var self = this; - - // If we have a normal connection - if(this.socketOptions.ssl) { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Check if the driver should validate the certificate - var validate_certificates = this.socketOptions.sslValidate == true ? true : false; - - // Create options for the tls connection - var tls_options = { - socket: this.connection - , rejectUnauthorized: false - } - - // If we wish to validate the certificate we have provided a ca store - if(validate_certificates) { - tls_options.ca = this.socketOptions.sslCA; - } - - // If we have a certificate to present - if(this.socketOptions.sslCert) { - tls_options.cert = this.socketOptions.sslCert; - tls_options.key = this.socketOptions.sslKey; - } - - // If the driver has been provided a private key password - if(this.socketOptions.sslPass) { - tls_options.passphrase = this.socketOptions.sslPass; - } - - // Contains the cleartext stream - var cleartext = null; - // Attempt to establish a TLS connection to the server - try { - cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() { - // If we have a ssl certificate validation error return an error - if(cleartext.authorizationError && validate_certificates) { - // Emit an error - return self.emit("error", cleartext.authorizationError, self, {ssl:true}); - } - - // Connect to the server - connectHandler(self)(); - }) - } catch(err) { - return self.emit("error", "SSL connection failed", self, {ssl:true}); - } - - // Save the output stream - this.writeSteam = cleartext; - - // Set up data handler for the clear stream - cleartext.on("data", createDataHandler(this)); - // Do any handling of end event of the stream - cleartext.on("end", endHandler(this)); - cleartext.on("error", errorHandler(this)); - - // Handle any errors - this.connection.on("error", errorHandler(this)); - // Handle timeout - this.connection.on("timeout", timeoutHandler(this)); - // Handle drain event - this.connection.on("drain", drainHandler(this)); - // Handle the close event - this.connection.on("close", closeHandler(this)); - } else { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Set up write stream - this.writeSteam = this.connection; - // Add handlers - this.connection.on("error", errorHandler(this)); - // Add all handlers to the socket to manage it - this.connection.on("connect", connectHandler(this)); - // this.connection.on("end", endHandler(this)); - this.connection.on("data", createDataHandler(this)); - this.connection.on("timeout", timeoutHandler(this)); - this.connection.on("drain", drainHandler(this)); - this.connection.on("close", closeHandler(this)); - } -} - -// Check if the sockets are live -Connection.prototype.isConnected = function() { - return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable; -} - -// Write the data out to the socket -Connection.prototype.write = function(command, callback) { - try { - // If we have a list off commands to be executed on the same socket - if(Array.isArray(command)) { - for(var i = 0; i < command.length; i++) { - var binaryCommand = command[i].toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]}); - - var r = this.writeSteam.write(binaryCommand); - } - } else { - var binaryCommand = command.toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command}); - - var r = this.writeSteam.write(binaryCommand); - } - } catch (err) { - if(typeof callback === 'function') callback(err); - } -} - -// Force the closure of the connection -Connection.prototype.close = function() { - // clear out all the listeners - resetHandlers(this, true); - // Add a dummy error listener to catch any weird last moment errors (and ignore them) - this.connection.on("error", function() {}) - // destroy connection - this.connection.destroy(); - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("closed connection", this.connection); - } -} - -// Reset all handlers -var resetHandlers = function(self, clearListeners) { - self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]}; - - // If we want to clear all the listeners - if(clearListeners && self.connection != null) { - var keys = Object.keys(self.eventHandlers); - // Remove all listeners - for(var i = 0; i < keys.length; i++) { - self.connection.removeAllListeners(keys[i]); - } - } -} - -// -// Handlers -// - -// Connect handler -var connectHandler = function(self) { - return function(data) { - // Set connected - self.connected = true; - // Now that we are connected set the socket timeout - self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout); - // Emit the connect event with no error - self.emit("connect", null, self); - } -} - -var createDataHandler = exports.Connection.createDataHandler = function(self) { - // We need to handle the parsing of the data - // and emit the messages when there is a complete one - return function(data) { - // Parse until we are done with the data - while(data.length > 0) { - // If we still have bytes to read on the current message - if(self.bytesRead > 0 && self.sizeOfMessage > 0) { - // Calculate the amount of remaining bytes - var remainingBytesToRead = self.sizeOfMessage - self.bytesRead; - // Check if the current chunk contains the rest of the message - if(remainingBytesToRead > data.length) { - // Copy the new data into the exiting buffer (should have been allocated when we know the message size) - data.copy(self.buffer, self.bytesRead); - // Adjust the number of bytes read so it point to the correct index in the buffer - self.bytesRead = self.bytesRead + data.length; - - // Reset state of buffer - data = new Buffer(0); - } else { - // Copy the missing part of the data into our current buffer - data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead); - // Slice the overflow into a new buffer that we will then re-parse - data = data.slice(remainingBytesToRead); - - // Emit current complete message - try { - var emitBuffer = self.buffer; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Emit the buffer - self.emit("message", emitBuffer, self); - } catch(err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } - } else { - // Stub buffer is kept in case we don't get enough bytes to determine the - // size of the message (< 4 bytes) - if(self.stubBuffer != null && self.stubBuffer.length > 0) { - - // If we have enough bytes to determine the message size let's do it - if(self.stubBuffer.length + data.length > 4) { - // Prepad the data - var newData = new Buffer(self.stubBuffer.length + data.length); - self.stubBuffer.copy(newData, 0); - data.copy(newData, self.stubBuffer.length); - // Reassign for parsing - data = newData; - - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - - } else { - - // Add the the bytes to the stub buffer - var newStubBuffer = new Buffer(self.stubBuffer.length + data.length); - // Copy existing stub buffer - self.stubBuffer.copy(newStubBuffer, 0); - // Copy missing part of the data - data.copy(newStubBuffer, self.stubBuffer.length); - // Exit parsing loop - data = new Buffer(0); - } - } else { - if(data.length > 4) { - // Retrieve the message size - var sizeOfMessage = binaryutils.decodeUInt32(data, 0); - // If we have a negative sizeOfMessage emit error and return - if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{ - sizeOfMessage: sizeOfMessage, - bytesRead: self.bytesRead, - stubBuffer: self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - return; - } - - // Ensure that the size of message is larger than 0 and less than the max allowed - if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) { - self.buffer = new Buffer(sizeOfMessage); - // Copy all the data into the buffer - data.copy(self.buffer, 0); - // Update bytes read - self.bytesRead = data.length; - // Update sizeOfMessage - self.sizeOfMessage = sizeOfMessage; - // Ensure stub buffer is null - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) { - try { - var emitBuffer = data; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:0, - buffer:null, - stubBuffer:null}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - - // Clear out the state of the parser - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else { - try { - var emitBuffer = data.slice(0, sizeOfMessage); - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Copy rest of message - data = data.slice(sizeOfMessage); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - - } - } else { - // Create a buffer that contains the space for the non-complete message - self.stubBuffer = new Buffer(data.length) - // Copy the data to the stub buffer - data.copy(self.stubBuffer, 0); - // Exit parsing loop - data = new Buffer(0); - } - } - } - } - } -} - -var endHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit end event - self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var timeoutHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit timeout event - self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self); - } -} - -var drainHandler = function(self) { - return function() { - } -} - -var errorHandler = function(self) { - return function(err) { - // Set connected to false - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var closeHandler = function(self) { - return function(hadError) { - // If we have an error during the connection phase - if(hadError && !self.connected) { - // Set disconnected - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } else { - // Set disconnected - self.connected = false; - // Emit close - self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } - } -} - -// Some basic defaults -Connection.DEFAULT_PORT = 27017; - - - - - - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js deleted file mode 100644 index 0ca433f5297..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js +++ /dev/null @@ -1,293 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - timers = require('timers'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - MongoReply = require("../responses/mongo_reply").MongoReply, - Connection = require("./connection").Connection; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) { - if(typeof host !== 'string') { - throw new Error("host must be specified [" + host + "]"); - } - - // Set up event emitter - EventEmitter.call(this); - - // Keep all options for the socket in a specific collection allowing the user to specify the - // Wished upon socket connection parameters - this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {}; - this.socketOptions.host = host; - this.socketOptions.port = port; - this.socketOptions.domainSocket = false; - this.bson = bson; - // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc) - this.poolSize = poolSize; - this.minPoolSize = Math.floor(this.poolSize / 2) + 1; - - // Check if the host is a socket - if(host.match(/^\//)) { - this.socketOptions.domainSocket = true; - } else if(typeof port === 'string') { - try { - port = parseInt(port, 10); - } catch(err) { - new Error("port must be specified or valid integer[" + port + "]"); - } - } else if(typeof port !== 'number') { - throw new Error("port must be specified [" + port + "]"); - } - - // Set default settings for the socket options - utils.setIntegerParameter(this.socketOptions, 'timeout', 0); - // Delay before writing out the data to the server - utils.setBooleanParameter(this.socketOptions, 'noDelay', true); - // Delay before writing out the data to the server - utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0); - // Set the encoding of the data read, default is binary == null - utils.setStringParameter(this.socketOptions, 'encoding', null); - // Allows you to set a throttling bufferSize if you need to stop overflows - utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0); - - // Internal structures - this.openConnections = []; - // Assign connection id's - this.connectionId = 0; - - // Current index for selection of pool connection - this.currentConnectionIndex = 0; - // The pool state - this._poolState = 'disconnected'; - // timeout control - this._timeout = false; - // Time to wait between connections for the pool - this._timeToWait = 10; -} - -inherits(ConnectionPool, EventEmitter); - -ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) { - if(maxBsonSize == null){ - maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxBsonSize = maxBsonSize; - } -} - -ConnectionPool.prototype.setMaxMessageSizeBytes = function(maxMessageSizeBytes) { - if(maxMessageSizeBytes == null){ - maxMessageSizeBytes = Connection.DEFAULT_MAX_MESSAGE_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxMessageSizeBytes = maxMessageSizeBytes; - } -} - -// Start a function -var _connect = function(_self) { - // return new function() { - // Create a new connection instance - var connection = new Connection(_self.connectionId++, _self.socketOptions); - // Set logger on pool - connection.logger = _self.logger; - // Connect handler - connection.on("connect", function(err, connection) { - // Add connection to list of open connections - _self.openConnections.push(connection); - // If the number of open connections is equal to the poolSize signal ready pool - if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') { - // Set connected - _self._poolState = 'connected'; - // Emit pool ready - _self.emit("poolReady"); - } else if(_self.openConnections.length < _self.poolSize) { - // Wait a little bit of time to let the close event happen if the server closes the connection - // so we don't leave hanging connections around - if(typeof _self._timeToWait == 'number') { - setTimeout(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }, _self._timeToWait); - } else { - processor(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }); - } - } - }); - - var numberOfErrors = 0 - - // Error handler - connection.on("error", function(err, connection, error_options) { - numberOfErrors++; - // If we are already disconnected ignore the event - if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) { - _self.emit("error", err, connection, error_options); - } - - // Close the connection - connection.close(); - // Set pool as disconnected - _self._poolState = 'disconnected'; - // Stop the pool - _self.stop(); - }); - - // Close handler - connection.on("close", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) { - _self.emit("close"); - } - - // Set disconnected - _self._poolState = 'disconnected'; - // Stop - _self.stop(); - }); - - // Timeout handler - connection.on("timeout", function(err, connection) { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) { - _self.emit("timeout", err); - } - - // Close the connection - connection.close(); - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - // Parse error, needs a complete shutdown of the pool - connection.on("parseError", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) { - _self.emit("parseError", new Error("parseError occured")); - } - - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - connection.on("message", function(message) { - _self.emit("message", message); - }); - - // Start connection in the next tick - connection.start(); - // }(); -} - - -// Start method, will throw error if no listeners are available -// Pass in an instance of the listener that contains the api for -// finding callbacks for a given message etc. -ConnectionPool.prototype.start = function() { - var markerDate = new Date().getTime(); - var self = this; - - if(this.listeners("poolReady").length == 0) { - throw "pool must have at least one listener ready that responds to the [poolReady] event"; - } - - // Set pool state to connecting - this._poolState = 'connecting'; - this._timeout = false; - - _connect(self); -} - -// Restart a connection pool (on a close the pool might be in a wrong state) -ConnectionPool.prototype.restart = function() { - // Close all connections - this.stop(false); - // Now restart the pool - this.start(); -} - -// Stop the connections in the pool -ConnectionPool.prototype.stop = function(removeListeners) { - removeListeners = removeListeners == null ? true : removeListeners; - // Set disconnected - this._poolState = 'disconnected'; - - // Clear all listeners if specified - if(removeListeners) { - this.removeAllEventListeners(); - } - - // Close all connections - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].close(); - } - - // Clean up - this.openConnections = []; -} - -// Check the status of the connection -ConnectionPool.prototype.isConnected = function() { - return this._poolState === 'connected'; -} - -// Checkout a connection from the pool for usage, or grab a specific pool instance -ConnectionPool.prototype.checkoutConnection = function(id) { - var index = (this.currentConnectionIndex++ % (this.openConnections.length)); - var connection = this.openConnections[index]; - return connection; -} - -ConnectionPool.prototype.getAllConnections = function() { - return this.openConnections; -} - -// Remove all non-needed event listeners -ConnectionPool.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("connect"); - this.removeAllListeners("end"); - this.removeAllListeners("parseError"); - this.removeAllListeners("message"); - this.removeAllListeners("poolReady"); -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js deleted file mode 100644 index 591092495a8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.setIntegerParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) { - throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setBooleanParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "boolean") { - throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setStringParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "string") { - throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js deleted file mode 100644 index 6bd1cdd1158..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js +++ /dev/null @@ -1,357 +0,0 @@ -var ReadPreference = require('./read_preference').ReadPreference - , Base = require('./base').Base - , inherits = require('util').inherits; - -/** - * Mongos constructor provides a connection to a mongos proxy including failover to additional servers - * - * Options - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - * @class Represents a Mongos connection with failover to backup proxies - * @param {Array} list of mongos server objects - * @param {Object} [options] additional options for the mongos connection - */ -var Mongos = function Mongos(servers, options) { - // Set up basic - if(!(this instanceof Mongos)) - return new Mongos(servers, options); - - // Set up event emitter - Base.call(this); - - // Throw error on wrong setup - if(servers == null || !Array.isArray(servers) || servers.length == 0) - throw new Error("At least one mongos proxy must be in the array"); - - // Ensure we have at least an empty options object - this.options = options == null ? {} : options; - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - // How often are we checking for new servers in the replicaset - this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 2000 : this.options['haInterval']; - // Save all the server connections - this.servers = servers; - // Servers we need to attempt reconnect with - this.downServers = []; - // Just contains the current lowest ping time and server - this.lowestPingTimeServer = null; - this.lowestPingTime = 0; - - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - - // Add options to servers - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - server._callBackStore = this._callBackStore; - // Default empty socket options object - var socketOptions = {host: server.host, port: server.port}; - // If a socket option object exists clone it - if(this.socketOptions != null) { - var keys = Object.keys(this.socketOptions); - for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]]; - } - // Set socket options - server.socketOptions = socketOptions; - } -} - -/** - * @ignore - */ -inherits(Mongos, Base); - -/** - * @ignore - */ -Mongos.prototype.isMongos = function() { - return true; -} - -/** - * @ignore - */ -Mongos.prototype.connect = function(db, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - - // Keep reference to parent - this.db = db; - // Set server state to connecting - this._serverState = 'connecting'; - // Number of total servers that need to initialized (known servers) - this._numberOfServersLeftToInitialize = this.servers.length; - // Default to the first proxy server as the first one to use - this._currentMongos = this.servers[0]; - - // Connect handler - var connectHandler = function(_server) { - return function(err, result) { - self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1; - - if(self._numberOfServersLeftToInitialize == 0) { - // Start ha function if it exists - if(self.haEnabled) { - // Setup the ha process - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - - // Set the mongos to connected - self._serverState = "connected"; - // Emit the open event - self.db.emit("open", null, self.db); - // Callback - callback(null, self.db); - } - } - }; - - // Error handler - var errorOrCloseHandler = function(_server) { - return function(err, result) { - // Create current mongos comparision - var currentUrl = self._currentMongos.host + ":" + self._currentMongos.port; - var serverUrl = this.host + ":" + this.port; - // We need to check if the server that closed is the actual current proxy we are using, otherwise - // just ignore - if(currentUrl == serverUrl) { - // Remove the server from the list - if(self.servers.indexOf(_server) != -1) { - self.servers.splice(self.servers.indexOf(_server), 1); - } - - // Pick the next one on the list if there is one - for(var i = 0; i < self.servers.length; i++) { - // Grab the server out of the array (making sure there is no servers in the list if none available) - var server = self.servers[i]; - // Generate url for comparision - var serverUrl = server.host + ":" + server.port; - // It's not the current one and connected set it as the current db - if(currentUrl != serverUrl && server.isConnected()) { - self._currentMongos = server; - break; - } - } - } - - // Ensure we don't store the _server twice - if(self.downServers.indexOf(_server) == -1) { - // Add the server instances - self.downServers.push(_server); - } - } - } - - // Mongo function - this.mongosCheckFunction = function() { - // If we have down servers let's attempt a reconnect - if(self.downServers.length > 0) { - var numberOfServersLeft = self.downServers.length; - // Attempt to reconnect - for(var i = 0; i < self.downServers.length; i++) { - var downServer = self.downServers.pop(); - - // Configuration - var options = { - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - returnIsMasterResults: true - } - - // Attemp to reconnect - downServer.connect(self.db, options, function(_server) { - // Return a function to check for the values - return function(err, result) { - // Adjust the number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - - if(err != null) { - self.downServers.push(_server); - } else { - // Add server event handlers - _server.on("close", errorOrCloseHandler(_server)); - _server.on("error", errorOrCloseHandler(_server)); - // Add to list of servers - self.servers.push(_server); - } - - if(numberOfServersLeft <= 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - }(downServer)); - } - } else if(self.servers.length > 0) { - var numberOfServersLeft = self.servers.length; - var _s = new Date().getTime() - - // Else let's perform a ping command - for(var i = 0; i < self.servers.length; i++) { - var executePing = function(_server) { - // Get a read connection - var _connection = _server.checkoutReader(); - // Execute ping command - self.db.command({ping:1}, {failFast:true, connection:_connection}, function(err, result) { - var pingTime = new Date().getTime() - _s; - // If no server set set the first one, otherwise check - // the lowest ping time and assign the server if it's got a lower ping time - if(self.lowestPingTimeServer == null) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } else if(self.lowestPingTime > pingTime - && (_server.host != self.lowestPingTimeServer.host || _server.port != self.lowestPingTimeServer.port)) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } - - // Number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - // All active mongos's pinged - if(numberOfServersLeft == 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - }) - } - - // Execute the function - executePing(self.servers[i]); - } - } else { - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - - // Connect all the server instances - for(var i = 0; i < this.servers.length; i++) { - // Get the connection - var server = this.servers[i]; - server.mongosInstance = this; - // Add server event handlers - server.on("close", errorOrCloseHandler(server)); - server.on("timeout", errorOrCloseHandler(server)); - server.on("error", errorOrCloseHandler(server)); - // Configuration - var options = { - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - returnIsMasterResults: true - } - - // Connect the instance - server.connect(self.db, options, connectHandler(server)); - } -} - -/** - * @ignore - * Just return the currently picked active connection - */ -Mongos.prototype.allServerInstances = function() { - return this.servers; -} - -/** - * Always ourselves - * @ignore - */ -Mongos.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Mongos.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - // Add all connections - for(var i = 0; i < this.servers.length; i++) { - allConnections = allConnections.concat(this.servers[i].allRawConnections()); - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -Mongos.prototype.isConnected = function() { - return this._serverState == "connected"; -} - -/** - * @ignore - */ -Mongos.prototype.checkoutWriter = function() { - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutWriter(); - } - return this._currentMongos.checkoutWriter(); -} - -/** - * @ignore - */ -Mongos.prototype.checkoutReader = function(read) { - // If we have a read preference object unpack it - if(typeof read == 'object' && read['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode); - } else if(!ReadPreference.isValid(read)) { - throw new Error("Illegal readPreference mode specified, " + read); - } - - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutReader(); - } - return this._currentMongos.checkoutReader(); -} - -/** - * @ignore - */ -Mongos.prototype.close = function(callback) { - var self = this; - // Set server status as disconnected - this._serverState = 'disconnected'; - // Number of connections to close - var numberOfConnectionsToClose = self.servers.length; - // If we have a ha process running kill it - if(self._replicasetTimeoutId != null) clearTimeout(self._replicasetTimeoutId); - // Close all proxy connections - for(var i = 0; i < self.servers.length; i++) { - self.servers[i].close(function(err, result) { - numberOfConnectionsToClose = numberOfConnectionsToClose - 1; - // Callback if we have one defined - if(numberOfConnectionsToClose == 0 && typeof callback == 'function') { - callback(null); - } - }); - } -} - -/** - * @ignore - * Return the used state - */ -Mongos.prototype._isUsed = function() { - return this._used; -} - -exports.Mongos = Mongos; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js deleted file mode 100644 index 4cba58792b1..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * A class representation of the Read Preference. - * - * Read Preferences - * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.). - * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary. - * - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error. - * - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary. - * - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection. - * - * @class Represents a Read Preference. - * @param {String} the read preference type - * @param {Object} tags - * @return {ReadPreference} - */ -var ReadPreference = function(mode, tags) { - if(!(this instanceof ReadPreference)) - return new ReadPreference(mode, tags); - this._type = 'ReadPreference'; - this.mode = mode; - this.tags = tags; -} - -/** - * @ignore - */ -ReadPreference.isValid = function(_mode) { - return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED - || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED - || _mode == ReadPreference.NEAREST); -} - -/** - * @ignore - */ -ReadPreference.prototype.isValid = function(mode) { - var _mode = typeof mode == 'string' ? mode : this.mode; - return ReadPreference.isValid(_mode); -} - -/** - * @ignore - */ -ReadPreference.prototype.toObject = function() { - var object = {mode:this.mode}; - - if(this.tags != null) { - object['tags'] = this.tags; - } - - return object; -} - -/** - * @ignore - */ -ReadPreference.PRIMARY = 'primary'; -ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred'; -ReadPreference.SECONDARY = 'secondary'; -ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred'; -ReadPreference.NEAREST = 'nearest' - -/** - * @ignore - */ -exports.ReadPreference = ReadPreference; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js deleted file mode 100644 index 92171a6e450..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js +++ /dev/null @@ -1,1471 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - debug = require('util').debug, - inherits = require('util').inherits, - inspect = require('util').inspect, - Server = require('./server').Server, - PingStrategy = require('./strategies/ping_strategy').PingStrategy, - StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy, - Base = require('./base').Base; - -const STATE_STARTING_PHASE_1 = 0; -const STATE_PRIMARY = 1; -const STATE_SECONDARY = 2; -const STATE_RECOVERING = 3; -const STATE_FATAL_ERROR = 4; -const STATE_STARTING_PHASE_2 = 5; -const STATE_UNKNOWN = 6; -const STATE_ARBITER = 7; -const STATE_DOWN = 8; -const STATE_ROLLBACK = 9; - -/** - * ReplSet constructor provides replicaset functionality - * - * Options - * - **ha** {Boolean, default:true}, turn on high availability. - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect. - * - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect. - * - **rs_name** {String}, the name of the replicaset to connect to. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strategy** {String, default:'ping'}, selection strategy for reads choose between (ping, statistical and none, default is ping) - * - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms) - * - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - * @class Represents a Replicaset Configuration - * @param {Array} list of server objects participating in the replicaset. - * @param {Object} [options] additional options for the replicaset connection. - */ -var ReplSet = exports.ReplSet = function(servers, options) { - this.count = 0; - - // Set up basic - if(!(this instanceof ReplSet)) - return new ReplSet(servers, options); - - // Set up event emitter - Base.call(this); - - // Ensure no Mongos's - for(var i = 0; i < servers.length; i++) { - if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server"); - } - - // Just reference for simplicity - var self = this; - // Contains the master server entry - this.options = options == null ? {} : options; - this.reconnectWait = this.options["reconnectWait"] != null ? this.options["reconnectWait"] : 1000; - this.retries = this.options["retries"] != null ? this.options["retries"] : 30; - this.replicaSet = this.options["rs_name"]; - - // Are we allowing reads from secondaries ? - this.readSecondary = this.options["read_secondary"]; - this.slaveOk = true; - this.closedConnectionCount = 0; - this._used = false; - - // Connect arbiters ? - this.connectArbiter = this.options.connectArbiter == null ? false : this.options.connectArbiter; - - // Default poolSize for new server instances - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this._currentServerChoice = 0; - - // Set up ssl connections - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Internal state of server connection - this._serverState = 'disconnected'; - // Read preference - this._readPreference = null; - // HA running - this._haRunning = false; - // Do we record server stats or not - this.recordQueryStats = false; - // Update health try server - this.updateHealthServerTry = 0; - - // Get the readPreference - var readPreference = this.options['readPreference']; - - // Validate correctness of Read preferences - if(readPreference != null) { - if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED - && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED - && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("Illegal readPreference mode specified, " + readPreference); - } - - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Ensure read_secondary is set correctly - if(!this.readSecondary) - this.readSecondary = this._readPreference == ReadPreference.PRIMARY - || this._readPreference == false - || this._readPreference == null ? false : true; - - // Ensure correct slave set - if(this.readSecondary) this.slaveOk = true; - - // Strategy for picking a secondary - this.secondaryAcceptableLatencyMS = this.options['secondaryAcceptableLatencyMS'] == null ? 15 : this.options['secondaryAcceptableLatencyMS']; - this.strategy = this.options['strategy']; - // Make sure strategy is one of the two allowed - if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical' && this.strategy != 'none')) - throw new Error("Only ping or statistical strategies allowed"); - if(this.strategy == null) this.strategy = 'ping'; - // Let's set up our strategy object for picking secodaries - if(this.strategy == 'ping') { - // Create a new instance - this.strategyInstance = new PingStrategy(this, this.secondaryAcceptableLatencyMS); - } else if(this.strategy == 'statistical') { - // Set strategy as statistical - this.strategyInstance = new StatisticsStrategy(this); - // Add enable query information - this.enableRecordQueryStats(true); - } - - // Set logger if strategy exists - if(this.strategyInstance) this.strategyInstance.logger = this.logger; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.debug == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Ensure all the instances are of type server and auto_reconnect is false - if(!Array.isArray(servers) || servers.length == 0) { - throw Error("The parameter must be an array of servers and contain at least one server"); - } else if(Array.isArray(servers) || servers.length > 0) { - var count = 0; - servers.forEach(function(server) { - if(server instanceof Server) count = count + 1; - // Ensure no server has reconnect on - server.options.auto_reconnect = false; - // Set up ssl options - server.ssl = self.ssl; - server.sslValidate = self.sslValidate; - server.sslCA = self.sslCA; - server.sslCert = self.sslCert; - server.sslKey = self.sslKey; - server.sslPass = self.sslPass; - server.poolSize = self.poolSize; - // Set callback store - server._callBackStore = self._callBackStore; - }); - - if(count < servers.length) { - throw Error("All server entries must be of type Server"); - } else { - this.servers = servers; - } - } - - // var deduplicate list - var uniqueServers = {}; - // De-duplicate any servers in the seed list - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - // If server does not exist set it - if(uniqueServers[server.host + ":" + server.port] == null) { - uniqueServers[server.host + ":" + server.port] = server; - } - } - - // Let's set the deduplicated list of servers - this.servers = []; - // Add the servers - for(var key in uniqueServers) { - this.servers.push(uniqueServers[key]); - } - - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - this._haServer = null; - // How often are we checking for new servers in the replicaset - this.replicasetStatusCheckInterval = this.options['haInterval'] == null ? 5000 : this.options['haInterval']; - - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - // Socket connection timeout - this._socketTimeoutMS = this.socketOptions.socketTimeoutMS - ? this.socketOptions.socketTimeoutMS - : (this.replicasetStatusCheckInterval + 1000); -}; - -/** - * @ignore - */ -inherits(ReplSet, Base); - -/** - * @ignore - */ -// Allow setting the read preference at the replicaset level -ReplSet.prototype.setReadPreference = function(preference) { - // Set read preference - this._readPreference = preference; - // Ensure slaveOk is correct for secondaries read preference and tags - if((this._readPreference == ReadPreference.SECONDARY_PREFERRED - || this._readPreference == ReadPreference.SECONDARY - || this._readPreference == ReadPreference.NEAREST) - || (this._readPreference != null && typeof this._readPreference == 'object')) { - this.slaveOk = true; - } -} - -/** - * @ignore - */ -ReplSet.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -ReplSet.prototype.isMongos = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isConnected = function(read) { - if(read == null || read == ReadPreference.PRIMARY || read == false) - return this.primary != null && this._state.master != null && this._state.master.isConnected(); - - if((read == ReadPreference.PRIMARY_PREFERRED || read == ReadPreference.SECONDARY_PREFERRED || read == ReadPreference.NEAREST) - && ((this.primary != null && this._state.master != null && this._state.master.isConnected()) - || (this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0))) { - return true; - } else if(read == ReadPreference.SECONDARY) { - return this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0; - } - - // No valid connection return false - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isSetMember = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isPrimary = function(config) { - return this.readSecondary && Object.keys(this._state.secondaries).length > 0 ? false : true; -} - -/** - * @ignore - */ -ReplSet.prototype.isReadPrimary = ReplSet.prototype.isPrimary; - -/** - * @ignore - */ -ReplSet.prototype.allServerInstances = function() { - var self = this; - // If no state yet return empty - if(!self._state) return []; - // Close all the servers (concatenate entire list of servers first for ease) - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // Arbiter keys - var keys = Object.keys(self._state.arbiters); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.arbiters[keys[i]]); - } - - // Passive keys - var keys = Object.keys(self._state.passives); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.passives[keys[i]]); - } - - // Return complete list of all servers - return allServers; -} - -/** - * Enables high availability pings. - * - * @ignore - */ -ReplSet.prototype._enableHA = function () { - var self = this; - self._haRunning = true; - return check(); - - function ping () { - // We are disconnected stop pinging and close current connection if any - if("disconnected" == self._serverState) { - if(self._haServer != null) self._haServer.close(); - return; - } - - // Create a list of all servers we can send the ismaster command to - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // If no servers quit as are probably connecting - if(allServers.length == 0) return; - // Pick one of the servers - self.updateHealthServerTry = self.updateHealthServerTry++ % allServers.length; - var selectedServer = allServers[self.updateHealthServerTry]; - - // If we have an active db instance - if(self.dbInstances.length > 0) { - var db = self.dbInstances[0]; - - // We have an instance already - if(self._haServer == null) { - // Create a new master connection - self._haServer = new Server(selectedServer.host, selectedServer.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { - connectTimeoutMS: self._connectTimeoutMS, - socketTimeoutMS: self._socketTimeoutMS - }, - ssl: self.ssl, - sslValidate: self.sslValidate, - sslCA: self.sslCA, - sslCert: self.sslCert, - sslKey: self.sslKey, - sslPass: self.sslPass - }); - - self._haServer._callBackStore = self._callBackStore; - - // Add error handlers - self._haServer.on("close", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - self._haServer.on("error", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - self._haServer.on("timeout", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - // Connect using the new _server connection to not impact the driver - // behavior on any errors we could possibly run into - self._haServer.connect(db, function(err, result, _server) { - if("disconnected" == self._serverState) { - if(_server && _server.close) _server.close(); - self._haRunning = false; - return; - } - - if(err) { - if(_server && _server.close) _server.close(); - return check(); - } - - executeMasterCommand(db, _server); - }); - } else { - executeMasterCommand(db, self._haServer); - } - } - } - - function executeMasterCommand(db, _server) { - try { - // Create is master command - var cmd = DbCommand.createIsMasterCommand(db); - // Execute is master command - db._executeQueryCommand(cmd, {failFast:true, connection: _server.checkoutReader()}, function(err, res) { - if("disconnected" == self._serverState) { - if(_server && _server.close) _server.close(); - self._haRunning = false; - self._haServer = null; - return; - } - // If error let's set perform another check - if(err) { - // Force new server selection - self._haServer = null; - return check(); - } - // Validate the replicaset - self._validateReplicaset(res, db.auths, function() { - check(); - }); - }); - } catch(err) { - if(self._haServer) self._haServer.close(); - self._haServer = null; - check(); - } - } - - function check() { - self._haTimer = setTimeout(ping, self.replicasetStatusCheckInterval); - } -} - -/** - * @ignore - */ -ReplSet.prototype._validateReplicaset = function(result, auths, cb) { - var self = this; - var res = result.documents[0]; - - // manage master node changes - if(res.primary && self._state.master && self._state.master.name != res.primary) { - // Delete master record so we can rediscover it - delete self._state.addresses[self._state.master.name]; - - // TODO existing issue? this seems to only work if - // we already have a connection to the new primary. - - // Update information on new primary - // add as master, remove from secondary - var newMaster = self._state.addresses[res.primary]; - newMaster.isMasterDoc.ismaster = true; - newMaster.isMasterDoc.secondary = false; - self._state.master = newMaster; - delete self._state.secondaries[res.primary]; - } - - // discover new hosts - var hosts = []; - - for(var i = 0; i < res.hosts.length; ++i) { - var host = res.hosts[i]; - if (host == res.me) continue; - if (!(self._state.addresses[host] || ~hosts.indexOf(host))) { - // we dont already have a connection to this host and aren't - // already planning on connecting. - hosts.push(host); - } - } - - connectTo(hosts, auths, self, cb); -} - -/** - * Create connections to all `hosts` firing `cb` after - * connections are attempted for all `hosts`. - * - * @param {Array} hosts - * @param {Array} [auths] - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectTo(hosts, auths, replset, cb) { - var pending = hosts.length; - if (!pending) return cb(); - - for(var i = 0; i < hosts.length; ++i) { - connectToHost(hosts[i], auths, replset, handle); - } - - function handle () { - --pending; - if (0 === pending) cb(); - } -} - -/** - * Attempts connection to `host` and authenticates with optional `auth` - * for the given `replset` firing `cb` when finished. - * - * @param {String} host - * @param {Array} auths - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectToHost(host, auths, replset, cb) { - var server = createServer(host, replset); - - var options = { - returnIsMasterResults: true, - eventReceiver: server - } - - server.connect(replset.db, options, function(err, result) { - var doc = result && result.documents && result.documents[0]; - - if (err || !doc) { - server.close(); - return cb(err, result, server); - } - - if(!(doc.ismaster || doc.secondary || doc.arbiterOnly)) { - server.close(); - return cb(null, result, server); - } - - // if host is an arbiter, disconnect if not configured for it - if(doc.arbiterOnly && !replset.connectArbiter) { - server.close(); - return cb(null, result, server); - } - - // create handler for successful connections - var handleConnect = _connectHandler(replset, null, server); - function complete () { - handleConnect(err, result); - cb(); - } - - // authenticate if necessary - if(!(Array.isArray(auths) && auths.length > 0)) { - return complete(); - } - - var pending = auths.length; - - var connections = server.allRawConnections(); - var pendingAuthConn = connections.length; - for(var x = 0; x 0) { - self.db.emit(event, err); - } - - // If it's the primary close all connections - if(self._state.master - && self._state.master.host == server.host - && self._state.master.port == server.port) { - // return self.close(); - self._state.master = null; - } - } -} - -var _connectHandler = function(self, candidateServers, instanceServer) { - return function(err, result) { - // If we have an ssl error store the error - if(err && err.ssl) { - self._sslError = err; - } - - // We are disconnected stop attempting reconnect or connect - if(self._serverState == 'disconnected') return instanceServer.close(); - - // If no error handle isMaster - if(err == null && result.documents[0].hosts != null) { - // Fetch the isMaster command result - var document = result.documents[0]; - // Break out the results - var setName = document.setName; - var isMaster = document.ismaster; - var secondary = document.secondary; - var passive = document.passive; - var arbiterOnly = document.arbiterOnly; - var hosts = Array.isArray(document.hosts) ? document.hosts : []; - var arbiters = Array.isArray(document.arbiters) ? document.arbiters : []; - var passives = Array.isArray(document.passives) ? document.passives : []; - var tags = document.tags ? document.tags : {}; - var primary = document.primary; - // Find the current server name and fallback if none - var userProvidedServerString = instanceServer.host + ":" + instanceServer.port; - var me = document.me || userProvidedServerString; - - // Verify if the set name is the same otherwise shut down and return an error - if(self.replicaSet == null) { - self.replicaSet = setName; - } else if(self.replicaSet != setName) { - // Stop the set - self.close(); - // Emit a connection error - return self.emit("connectionError", - new Error("configured mongodb replicaset does not match provided replicaset [" + setName + "] != [" + self.replicaSet + "]")) - } - - // Make sure we have the right reference - var oldServer = self._state.addresses[userProvidedServerString] - if (oldServer && oldServer !== instanceServer) oldServer.close(); - delete self._state.addresses[userProvidedServerString]; - - if (self._state.addresses[me] && self._state.addresses[me] !== instanceServer) { - self._state.addresses[me].close(); - } - - self._state.addresses[me] = instanceServer; - - // Let's add the server to our list of server types - if(secondary == true && (passive == false || passive == null)) { - self._state.secondaries[me] = instanceServer; - } else if(arbiterOnly == true) { - self._state.arbiters[me] = instanceServer; - } else if(secondary == true && passive == true) { - self._state.passives[me] = instanceServer; - } else if(isMaster == true) { - self._state.master = instanceServer; - } else if(isMaster == false && primary != null && self._state.addresses[primary]) { - self._state.master = self._state.addresses[primary]; - } - - // Set the name - instanceServer.name = me; - // Add tag info - instanceServer.tags = tags; - - // Add the handlers to the instance - instanceServer.on("close", _handler("close", self)); - instanceServer.on("error", _handler("error", self)); - instanceServer.on("timeout", _handler("timeout", self)); - - // Possible hosts - var possibleHosts = Array.isArray(hosts) ? hosts.slice() : []; - possibleHosts = Array.isArray(passives) ? possibleHosts.concat(passives) : possibleHosts; - - if(self.connectArbiter == true) { - possibleHosts = Array.isArray(arbiters) ? possibleHosts.concat(arbiters) : possibleHosts; - } - - if(Array.isArray(candidateServers)) { - // Add any new candidate servers for connection - for(var j = 0; j < possibleHosts.length; j++) { - if(self._state.addresses[possibleHosts[j]] == null && possibleHosts[j] != null) { - var parts = possibleHosts[j].split(/:/); - if(parts.length == 1) { - parts = [parts[0], Connection.DEFAULT_PORT]; - } - - // New candidate server - var candidateServer = new Server(parts[0], parseInt(parts[1])); - candidateServer._callBackStore = self._callBackStore; - candidateServer.name = possibleHosts[j]; - candidateServer.ssl = self.ssl; - candidateServer.sslValidate = self.sslValidate; - candidateServer.sslCA = self.sslCA; - candidateServer.sslCert = self.sslCert; - candidateServer.sslKey = self.sslKey; - candidateServer.sslPass = self.sslPass; - - // Set the candidate server - self._state.addresses[possibleHosts[j]] = candidateServer; - // Add the new server to the list of candidate servers - candidateServers.push(candidateServer); - } - } - } - } else if(err != null || self._serverState == 'disconnected'){ - delete self._state.addresses[instanceServer.host + ":" + instanceServer.port]; - // Remove it from the set - instanceServer.close(); - } - - // Attempt to connect to the next server - if(Array.isArray(candidateServers) && candidateServers.length > 0) { - var server = candidateServers.pop(); - - // Get server addresses - var addresses = self._state.addresses; - - // Default empty socket options object - var socketOptions = {}; - - // Set fast connect timeout - socketOptions['connectTimeoutMS'] = self._connectTimeoutMS; - - // If a socket option object exists clone it - if(self.socketOptions != null && typeof self.socketOptions === 'object') { - var keys = Object.keys(self.socketOptions); - for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = self.socketOptions[keys[j]]; - } - - // If ssl is specified - if(self.ssl) server.ssl = true; - - // Add host information to socket options - socketOptions['host'] = server.host; - socketOptions['port'] = server.port; - server.socketOptions = socketOptions; - server.replicasetInstance = self; - server.enableRecordQueryStats(self.recordQueryStats); - - // Set the server - if (addresses[server.host + ":" + server.port] != server) { - if (addresses[server.host + ":" + server.port]) { - // Close the connection before deleting - addresses[server.host + ":" + server.port].close(); - } - delete addresses[server.host + ":" + server.port]; - } - - addresses[server.host + ":" + server.port] = server; - // Connect - server.connect(self.db, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(self, candidateServers, server)); - } else if(Array.isArray(candidateServers)) { - // If we have no primary emit error - if(self._state.master == null) { - // Stop the set - self.close(); - - // If we have an ssl error send the message instead of no primary found - if(self._sslError) { - return self.emit("connectionError", self._sslError); - } - - // Emit a connection error - return self.emit("connectionError", - new Error("no primary server found in set")) - } else{ - if(self.strategyInstance) { - self.strategyInstance.start(); - } - - for(var i = 0; i < self.dbInstances.length; i++) self.dbInstances[i]._state = 'connected'; - self.emit("fullsetup", null, self.db, self); - self.emit("open", null, self.db, self); - } - } - } -} - -var _fullsetup_emitted = false; - -/** - * Interval state object constructor - * - * @ignore - */ -ReplSet.State = function ReplSetState () { - this.errorMessages = []; - this.secondaries = {}; - this.addresses = {}; - this.arbiters = {}; - this.passives = {}; - this.members = []; - this.errors = {}; - this.setName = null; - this.master = null; -} - -/** - * @ignore - */ -ReplSet.prototype.connect = function(parent, options, callback) { - var self = this; - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Ensure it's all closed - self.close(); - - // Set connecting status - this.db = parent; - this._serverState = 'connecting'; - this._callbackList = []; - - this._state = new ReplSet.State(); - - // Ensure parent can do a slave query if it's set - parent.slaveOk = this.slaveOk - ? this.slaveOk - : parent.slaveOk; - - // Remove any listeners - this.removeAllListeners("fullsetup"); - this.removeAllListeners("connectionError"); - - // Add primary found event handler - this.once("fullsetup", function() { - self._handleOnFullSetup(parent); - - // Callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(null, parent, self); - } - }); - - this.once("connectionError", function(err) { - self._serverState = 'disconnected'; - // Ensure it's all closed - self.close(); - // Perform the callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(err, parent, self); - } - }); - - // Get server addresses - var addresses = this._state.addresses; - - // De-duplicate any servers - var server, key; - for(var i = 0; i < this.servers.length; i++) { - server = this.servers[i]; - key = server.host + ":" + server.port; - if(null == addresses[key]) { - addresses[key] = server; - } - } - - // Get the list of servers that is deduplicated and start connecting - var candidateServers = []; - var keys = Object.keys(addresses); - for(var i = 0; i < keys.length; i++) { - server = addresses[keys[i]]; - server.assignReplicaSet(this); - candidateServers.push(server); - } - - // Let's connect to the first one on the list - server = candidateServers.pop(); - var opts = { - returnIsMasterResults: true, - eventReceiver: server - } - - server.connect(parent, opts, _connectHandler(self, candidateServers, server)); -} - -/** - * Handles the first `fullsetup` event of this ReplSet. - * - * @param {Db} parent - * @ignore - */ -ReplSet.prototype._handleOnFullSetup = function (parent) { - this._serverState = 'connected'; - for(var i = 0; i < this.dbInstances.length; i++) this.dbInstances[i]._state = 'connected'; - if(parent._state) parent._state = 'connected'; - // Emit the fullsetup and open event - parent.emit("open", null, this.db, this); - parent.emit("fullsetup", null, this.db, this); - - if(!this.haEnabled) return; - if(this._haRunning) return; - this._enableHA(); -} - -/** - * Disables high availability pings. - * - * @ignore - */ -ReplSet.prototype._disableHA = function () { - clearTimeout(this._haTimer); - this._haTimer = undefined; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutWriter = function() { - // Establish connection - var connection = this._state.master != null ? this._state.master.checkoutWriter() : null; - // Return the connection - return connection; -} - -/** - * @ignore - */ -var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) { - var keys = Object.keys(self._state.secondaries); - var connection; - - // Find first available reader if any - for(var i = 0; i < keys.length; i++) { - connection = self._state.secondaries[keys[i]].checkoutReader(); - if(connection) return connection; - } - - // If we still have a null, read from primary if it's not secondary only - if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) { - connection = self._state.master.checkoutReader(); - if(connection) return connection; - } - - var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED - ? 'secondary' - : self._readPreference; - - return new Error("No replica set member available for query with ReadPreference " - + preferenceName + " and tags " + JSON.stringify(tags)); -} - -/** - * @ignore - */ -var _pickFromTags = function(self, tags) { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Match all the servers that match the provdided tags - var keys = Object.keys(self._state.secondaries); - var candidateServers = []; - - for(var i = 0; i < keys.length; i++) { - var server = self._state.secondaries[keys[i]]; - // If we have tags match - if(server.tags != null) { - var matching = true; - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - candidateServers.push(server); - } - } - } - - // If we have a candidate server return - if(candidateServers.length > 0) { - if(this.strategyInstance) return this.strategyInstance.checkoutConnection(tags, candidateServers); - // Set instance to return - return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader(); - } - } - - // No connection found - return null; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutReader = function(readPreference, tags) { - var connection = null; - - // If we have a read preference object unpack it - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + readPreference.mode); - // Set the tag - tags = readPreference.tags; - readPreference = readPreference.mode; - } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("read preferences must be either a string or an instance of ReadPreference"); - } - - // Set up our read Preference, allowing us to override the readPreference - var finalReadPreference = readPreference != null ? readPreference : this._readPreference; - finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference; - finalReadPreference = finalReadPreference == null ? ReadPreference.PRIMARY : finalReadPreference; - - // If we are reading from a primary - if(finalReadPreference == 'primary') { - // If we provide a tags set send an error - if(typeof tags == 'object' && tags != null) { - return new Error("PRIMARY cannot be combined with tags"); - } - - // If we provide a tags set send an error - if(this._state.master == null) { - return new Error("No replica set primary available for query with ReadPreference PRIMARY"); - } - - // Checkout a writer - return this.checkoutWriter(); - } - - // If we have specified to read from a secondary server grab a random one and read - // from it, otherwise just pass the primary connection - if((this.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - // Only pick from secondaries - var _secondaries = []; - for(var key in this._state.secondaries) { - _secondaries.push(this._state.secondaries[key]); - } - - if(finalReadPreference == ReadPreference.SECONDARY) { - // Check out the nearest from only the secondaries - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - } else { - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) { - // Check if there is a primary available and return that if possible - connection = this.checkoutWriter(); - // If no connection available checkout a secondary - if(connection == null) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } - } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - // return new Error("No replica set members available for query"); - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - // return new Error("No replica set members available for query"); - } - } - } - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) { - return new Error("A strategy for calculating nearness must be enabled such as ping or statistical"); - } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) { - if(tags != null && typeof tags == 'object') { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } else { - connection = new Error("No replica set secondary available for query with ReadPreference SECONDARY"); - } - } else { - connection = this.checkoutWriter(); - } - - // Return the connection - return connection; -} - -/** - * Pick a secondary using round robin - * - * @ignore - */ -function _roundRobin (replset, tags) { - var keys = Object.keys(replset._state.secondaries); - var key = keys[replset._currentServerChoice++ % keys.length]; - - var conn = null != replset._state.secondaries[key] - ? replset._state.secondaries[key].checkoutReader() - : null; - - // If connection is null fallback to first available secondary - if (null == conn) { - conn = pickFirstConnectedSecondary(replset, tags); - } - - return conn; -} - -/** - * @ignore - */ -ReplSet.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - if(this._state.master == null) return []; - // Get connection object - var allMasterConnections = this._state.master.connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(allMasterConnections); - // If we have read secondary let's add all secondary servers - if(Object.keys(this._state.secondaries).length > 0) { - // Get all the keys - var keys = Object.keys(this._state.secondaries); - // For each of the secondaries grab the connections - for(var i = 0; i < keys.length; i++) { - // Get connection object - var secondaryPoolConnections = this._state.secondaries[keys[i]].connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(secondaryPoolConnections); - } - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -ReplSet.prototype.enableRecordQueryStats = function(enable) { - // Set the global enable record query stats - this.recordQueryStats = enable; - // Ensure all existing servers already have the flag set, even if the - // connections are up already or we have not connected yet - if(this._state != null && this._state.addresses != null) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances and set the enableRecordQueryStats flag - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].enableRecordQueryStats(enable); - } - } else if(Array.isArray(this.servers)) { - for(var i = 0; i < this.servers.length; i++) { - this.servers[i].enableRecordQueryStats(enable); - } - } -} - -/** - * @ignore - */ -ReplSet.prototype.disconnect = function(callback) { - this.close(callback); -} - -/** - * @ignore - */ -ReplSet.prototype.close = function(callback) { - var self = this; - // Disconnect - this._serverState = 'disconnected'; - // Close all servers - if(this._state && this._state.addresses) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].close(); - } - } - - // If we have a strategy stop it - if(this.strategyInstance) { - this.strategyInstance.stop(); - } - // Shut down HA if running connection - if(this._haServer) this._haServer.close(); - - // If it's a callback - if(typeof callback == 'function') callback(null, null); -} - -/** - * Auto Reconnect property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "autoReconnect", { enumerable: true - , get: function () { - return true; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return ReadPreference.SECONDARY_PREFERRED; - } else if(this._readPreference == null && !this.readSecondary) { - return ReadPreference.PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * Db Instances - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "dbInstances", {enumerable:true - , get: function() { - var servers = this.allServerInstances(); - return servers.length > 0 ? servers[0].dbInstances : []; - } -}) - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "host", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.host; - } -}); - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "port", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.port; - } -}); - -/** - * Get status of read - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "read", { enumerable: true - , get: function () { - return this.secondaries.length > 0 ? this.secondaries[0] : null; - } -}); - -/** - * Get list of secondaries - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.secondaries); - var array = new Array(keys.length); - // Convert secondaries to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.secondaries[keys[i]]; - } - return array; - } -}); - -/** - * Get list of all secondaries including passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "allSecondaries", {enumerable: true - , get: function() { - return this.secondaries.concat(this.passives); - } -}); - -/** - * Get list of arbiters - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.arbiters); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.arbiters[keys[i]]; - } - return array; - } -}); - -/** - * Get list of passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "passives", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.passives); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.passives[keys[i]]; - } - return array; - } -}); - -/** - * Master connection property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "primary", { enumerable: true - , get: function () { - return this._state != null ? this._state.master : null; - } -}); - -/** - * @ignore - */ -// Backward compatibility -exports.ReplSetServers = ReplSet; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js deleted file mode 100644 index 20392fa0af4..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js +++ /dev/null @@ -1,905 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - ConnectionPool = require('./connection_pool').ConnectionPool, - EventEmitter = require('events').EventEmitter, - Base = require('./base').Base, - utils = require('../utils'), - timers = require('timers'), - inherits = require('util').inherits; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * Class representing a single MongoDB Server connection - * - * Options - * - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST) - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **auto_reconnect** {Boolean, default:false}, reconnect on error. - * - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big - * - * @class Represents a Server connection. - * @param {String} host the server host - * @param {Number} port the server port - * @param {Object} [options] optional options for insert command - */ -function Server(host, port, options) { - // Set up Server instance - if(!(this instanceof Server)) return new Server(host, port, options); - - // Set up event emitter - Base.call(this); - - // Ensure correct values - if(port != null && typeof port == 'object') { - options = port; - port = Connection.DEFAULT_PORT; - } - - var self = this; - this.host = host; - this.port = port; - this.options = options == null ? {} : options; - this.internalConnection; - this.internalMaster = false; - this.connected = false; - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false; - this.slaveOk = this.options["slave_ok"] ? this.options["slave_ok"] : this.options["slaveOk"]; - this._used = false; - this.replicasetInstance = null; - - // Set ssl as connection method - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Get the readPreference - var readPreference = this.options['readPreference']; - // If readPreference is an object get the mode string - var validateReadPreference = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - // Read preference setting - if(validateReadPreference != null) { - if(validateReadPreference != ReadPreference.PRIMARY && validateReadPreference != ReadPreference.SECONDARY && validateReadPreference != ReadPreference.NEAREST - && validateReadPreference != ReadPreference.SECONDARY_PREFERRED && validateReadPreference != ReadPreference.PRIMARY_PREFERRED) { - throw new Error("Illegal readPreference mode specified, " + validateReadPreference); - } - - // Set read Preference - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Contains the isMaster information returned from the server - this.isMasterDoc; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck; - - // Set ssl up if it's defined - if(this.ssl) { - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // this._timeout = false; - // Contains state information about server connection - this._state = {'runtimeStats': {'queryStats':new RunningStats()}}; - // Do we record server stats or not - this.recordQueryStats = false; -}; - -/** - * @ignore - */ -inherits(Server, Base); - -// -// Deprecated, USE ReadPreferences class -// -Server.READ_PRIMARY = ReadPreference.PRIMARY; -Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED; -Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY; - -/** - * Always ourselves - * @ignore - */ -Server.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Server.prototype.isMongos = function() { - return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false; -} - -/** - * @ignore - */ -Server.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -Server.prototype.close = function(callback) { - // Remove all local listeners - this.removeAllListeners(); - - if(this.connectionPool != null) { - // Remove all the listeners on the pool so it does not fire messages all over the place - this.connectionPool.removeAllEventListeners(); - // Close the connection if it's open - this.connectionPool.stop(true); - } - - // Set server status as disconnected - this._serverState = 'disconnected'; - // Peform callback if present - if(typeof callback === 'function') callback(null); -}; - -/** - * @ignore - */ -Server.prototype.isConnected = function() { - return this._serverState == 'connected'; -} - -/** - * @ignore - */ -Server.prototype.allServerInstances = function() { - return [this]; -} - -/** - * @ignore - */ -Server.prototype.isSetMember = function() { - return this.replicasetInstance != null || this.mongosInstance != null; -} - -/** - * Assigns a replica set to this `server`. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.assignReplicaSet = function (replset) { - this.replicasetInstance = replset; - this.inheritReplSetOptionsFrom(replset); - this.enableRecordQueryStats(replset.recordQueryStats); -} - -/** - * Takes needed options from `replset` and overwrites - * our own options. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.inheritReplSetOptionsFrom = function (replset) { - this.socketOptions = {}; - this.socketOptions.connectTimeoutMS = replset._connectTimeoutMS; - - if(replset.ssl) { - // Set ssl on - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = replset.sslValidate == null ? false : replset.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(replset.sslCA) ? replset.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = replset.sslCert; - // Set certificate to present - this.socketOptions.sslKey = replset.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = replset.sslPass; - } - - // If a socket option object exists clone it - if(utils.isObject(replset.socketOptions)) { - var keys = Object.keys(replset.socketOptions); - for(var i = 0; i < keys.length; i++) - this.socketOptions[keys[i]] = replset.socketOptions[keys[i]]; - } -} - -/** - * Opens this server connection. - * - * @ignore - */ -Server.prototype.connect = function(dbInstance, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Currently needed to work around problems with multiple connections in a pool with ssl - // TODO fix if possible - if(this.ssl == true) { - // Set up socket options for ssl - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Let's connect - var server = this; - // Let's us override the main receiver of events - var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this; - // Save reference to dbInstance - this.db = dbInstance; // `db` property matches ReplSet and Mongos - this.dbInstances = [dbInstance]; - - // Force connection pool if there is one - if(server.connectionPool) server.connectionPool.stop(); - - // Set server state to connecting - this._serverState = 'connecting'; - // Ensure dbInstance can do a slave query if it's set - dbInstance.slaveOk = this.slaveOk ? this.slaveOk : dbInstance.slaveOk; - // Create connection Pool instance with the current BSON serializer - var connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions); - // If ssl is not enabled don't wait between the pool connections - if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null; - // Set logger on pool - connectionPool.logger = this.logger; - - // Set up a new pool using default settings - server.connectionPool = connectionPool; - - // Set basic parameters passed in - var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults; - - // Create a default connect handler, overriden when using replicasets - var connectCallback = function(err, reply) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // If something close down the connection and removed the callback before - // proxy killed connection etc, ignore the erorr as close event was isssued - if(err != null && internalCallback == null) return; - // Internal callback - if(err != null) return internalCallback(err, null, server); - server.master = reply.documents[0].ismaster == 1 ? true : false; - server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize); - server.connectionPool.setMaxMessageSizeBytes(reply.documents[0].maxMessageSizeBytes); - // Set server as connected - server.connected = true; - // Save document returned so we can query it - server.isMasterDoc = reply.documents[0]; - - // Emit open event - _emitAcrossAllDbInstances(server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null); - - // If we have it set to returnIsMasterResults - if(returnIsMasterResults) { - internalCallback(null, reply, server); - } else { - internalCallback(null, dbInstance, server); - } - }; - - // Let's us override the main connect callback - var connectHandler = options.connectHandler == null ? connectCallback : options.connectHandler; - - // Set up on connect method - connectionPool.on("poolReady", function() { - // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks) - var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName); - // Check out a reader from the pool - var connection = connectionPool.checkoutConnection(); - // Set server state to connEcted - server._serverState = 'connected'; - - // Register handler for messages - server._registerHandler(db_command, false, connection, connectHandler); - - // Write the command out - connection.write(db_command); - }) - - // Set up item connection - connectionPool.on("message", function(message) { - // Attempt to parse the message - try { - // Create a new mongo reply - var mongoReply = new MongoReply() - // Parse the header - mongoReply.parseHeader(message, connectionPool.bson) - - // If message size is not the same as the buffer size - // something went terribly wrong somewhere - if(mongoReply.messageLength != message.length) { - // Emit the error - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server); - // Remove all listeners - server.removeAllListeners(); - } else { - var startDate = new Date().getTime(); - - // Callback instance - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - - // The command executed another request, log the handler again under that request id - if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0" - && callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) { - server._reRegisterHandler(mongoReply.requestId, callbackInfo); - } - - // Only execute callback if we have a caller - // chained is for findAndModify as it does not respect write concerns - if(callbackInfo && callbackInfo.callback && callbackInfo.info && Array.isArray(callbackInfo.info.chained)) { - // Check if callback has already been fired (missing chain command) - var chained = callbackInfo.info.chained; - var numberOfFoundCallbacks = 0; - for(var i = 0; i < chained.length; i++) { - if(server._hasHandler(chained[i])) numberOfFoundCallbacks++; - } - - // If we have already fired then clean up rest of chain and move on - if(numberOfFoundCallbacks != chained.length) { - for(var i = 0; i < chained.length; i++) { - server._removeHandler(chained[i]); - } - - // Just return from function - return; - } - - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Fetch the callback - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - // If we have an error let's execute the callback and clean up all other - // chained commands - var firstResult = mongoReply && mongoReply.documents; - - // Check for an error, if we have one let's trigger the callback and clean up - // The chained callbacks - if(firstResult[0].err != null || firstResult[0].errmsg != null) { - // Trigger the callback for the error - server._callHandler(mongoReply.responseTo, mongoReply, null); - } else { - var chainedIds = callbackInfo.info.chained; - - if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) { - // Cleanup all other chained calls - chainedIds.pop(); - // Remove listeners - for(var i = 0; i < chainedIds.length; i++) server._removeHandler(chainedIds[i]); - // Call the handler - server._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null); - } else{ - // Add the results to all the results - for(var i = 0; i < chainedIds.length; i++) { - var handler = server._findHandler(chainedIds[i]); - // Check if we have an object, if it's the case take the current object commands and - // and add this one - if(handler.info != null) { - handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : []; - handler.info.results.push(mongoReply); - } - } - } - } - }); - } else if(callbackInfo && callbackInfo.callback && callbackInfo.info) { - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Let's record the stats info if it's enabled - if(server.recordQueryStats == true && server._state['runtimeStats'] != null - && server._state.runtimeStats['queryStats'] instanceof RunningStats) { - // Add data point to the running statistics object - server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start); - } - - server._callHandler(mongoReply.responseTo, mongoReply, null); - }); - } - } - } catch (err) { - // Throw error in next tick - processor(function() { - throw err; - }) - } - }); - - // Handle timeout - connectionPool.on("timeout", function(err) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(err, null, server); - } else if(server.isSetMember()) { - if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server); - } else { - if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(err); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true); - } - }); - - // Handle errors - connectionPool.on("error", function(message, connection, error_options) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Error message - var error_message = new Error(message && message.err ? message.err : message); - // Error message coming from ssl - if(error_options && error_options.ssl) error_message.ssl = true; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(error_message, null, server); - } else if(server.isSetMember()) { - if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server); - } else { - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(error_message); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true); - } - }); - - // Handle close events - connectionPool.on("close", function() { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback == 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server); - } else { - if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true); - } - }); - - // If we have a parser error we are in an unknown state, close everything and emit - // error - connectionPool.on("parseError", function(message) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - }); - - // Boot up connection poole, pass in a locator of callbacks - connectionPool.start(); -} - -/** - * @ignore - */ -var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) { - // Emit close event across all db instances sharing the sockets - var allServerInstances = server.allServerInstances(); - // Fetch the first server instance - var serverInstance = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(serverInstance.dbInstances) && serverInstance.dbInstances.length >= 1) { - for(var i = 0; i < serverInstance.dbInstances.length; i++) { - var dbInstance = serverInstance.dbInstances[i]; - // Set the parent - if(resetConnection && typeof dbInstance.openCalled != 'undefined') - dbInstance.openCalled = false; - // Check if it's our current db instance and skip if it is - if(filterDb == null || filterDb.databaseName !== dbInstance.databaseName || filterDb.tag !== dbInstance.tag) { - // Only emit if there is a listener - if(dbInstance.listeners(event).length > 0) - dbInstance.emit(event, message, object); - } - } - } -} - -/** - * @ignore - */ -Server.prototype.allRawConnections = function() { - return this.connectionPool.getAllConnections(); -} - -/** - * Check if a writer can be provided - * @ignore - */ -var canCheckoutWriter = function(self, read) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } if(self.isMasterDoc['secondary'] == true) { - return new Error("Cannot write to a secondary"); - } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutWriter = function(read) { - if(read == true) return this.connectionPool.checkoutConnection(); - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutWriter(this, read); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * Check if a reader can be provided - * @ignore - */ -var canCheckoutReader = function(self) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } else if(self._readPreference != null) { - // If the read preference is Primary and the instance is not a master return an error - if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) { - return new Error("Read preference is Server.PRIMARY and server is not master"); - } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutReader = function() { - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutReader(this); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * @ignore - */ -Server.prototype.enableRecordQueryStats = function(enable) { - this.recordQueryStats = enable; -} - -/** - * Internal statistics object used for calculating average and standard devitation on - * running queries - * @ignore - */ -var RunningStats = function() { - var self = this; - this.m_n = 0; - this.m_oldM = 0.0; - this.m_oldS = 0.0; - this.m_newM = 0.0; - this.m_newS = 0.0; - - // Define getters - Object.defineProperty(this, "numDataValues", { enumerable: true - , get: function () { return this.m_n; } - }); - - Object.defineProperty(this, "mean", { enumerable: true - , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; } - }); - - Object.defineProperty(this, "variance", { enumerable: true - , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); } - }); - - Object.defineProperty(this, "standardDeviation", { enumerable: true - , get: function () { return Math.sqrt(this.variance); } - }); - - Object.defineProperty(this, "sScore", { enumerable: true - , get: function () { - var bottom = this.mean + this.standardDeviation; - if(bottom == 0) return 0; - return ((2 * this.mean * this.standardDeviation)/(bottom)); - } - }); -} - -/** - * @ignore - */ -RunningStats.prototype.push = function(x) { - // Update the number of samples - this.m_n = this.m_n + 1; - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if(this.m_n == 1) { - this.m_oldM = this.m_newM = x; - this.m_oldS = 0.0; - } else { - this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n; - this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM); - - // set up for next iteration - this.m_oldM = this.m_newM; - this.m_oldS = this.m_newS; - } -} - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true - , get: function () { - return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect']; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "connection", { enumerable: true - , get: function () { - return this.internalConnection; - } - , set: function(connection) { - this.internalConnection = connection; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "master", { enumerable: true - , get: function () { - return this.internalMaster; - } - , set: function(value) { - this.internalMaster = value; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "primary", { enumerable: true - , get: function () { - return this; - } -}); - -/** - * Getter for query Stats - * @ignore - */ -Object.defineProperty(Server.prototype, "queryStats", { enumerable: true - , get: function () { - return this._state.runtimeStats.queryStats; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true - , get: function () { - return this._state.runtimeStats; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(Server.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return Server.READ_SECONDARY; - } else if(this._readPreference == null && !this.readSecondary) { - return Server.READ_PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * @ignore - */ -exports.Server = Server; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js deleted file mode 100644 index dff9c1260a4..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js +++ /dev/null @@ -1,290 +0,0 @@ -var Server = require("../server").Server - , format = require('util').format; - -// The ping strategy uses pings each server and records the -// elapsed time for the server so it can pick a server based on lowest -// return time for the db command {ping:true} -var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) { - this.replicaset = replicaset; - this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS; - this.state = 'disconnected'; - this.pingInterval = 5000; - // Class instance - this.Db = require("../../db").Db; - // Active db connections - this.dbs = {}; - // Logger api - this.Logger = null; -} - -// Starts any needed code -PingStrategy.prototype.start = function(callback) { - // already running? - if ('connected' == this.state) return; - - this.state = 'connected'; - - // Start ping server - this._pingServer(callback); -} - -// Stops and kills any processes running -PingStrategy.prototype.stop = function(callback) { - // Stop the ping process - this.state = 'disconnected'; - - // Stop all the server instances - for(var key in this.dbs) { - this.dbs[key].close(); - } - - // optional callback - callback && callback(null, null); -} - -PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - var self = this; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // Sort by ping time - finalCandidates.sort(function(a, b) { - return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs']; - }); - - if(0 === finalCandidates.length) - return new Error("No replica set members available for query"); - - // find lowest server with a ping time - var lowest = finalCandidates.filter(function (server) { - return undefined != server.runtimeStats.pingMs; - })[0]; - - if(!lowest) { - lowest = finalCandidates[0]; - } - - // convert to integer - var lowestPing = lowest.runtimeStats.pingMs | 0; - - // determine acceptable latency - var acceptable = lowestPing + this.secondaryAcceptableLatencyMS; - - // remove any server responding slower than acceptable - var len = finalCandidates.length; - while(len--) { - if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) { - finalCandidates.splice(len, 1); - } - } - - if(self.logger && self.logger.debug) { - self.logger.debug("Ping strategy selection order for tags", tags); - finalCandidates.forEach(function(c) { - self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null); - }) - } - - // If no candidates available return an error - if(finalCandidates.length == 0) - return new Error("No replica set members available for query"); - - // Pick a random acceptable server - var connection = finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); - if(self.logger && self.logger.debug) { - if(connection) - self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port); - } - return connection; -} - -PingStrategy.prototype._pingServer = function(callback) { - var self = this; - - // Ping server function - var pingFunction = function() { - if(self.state == 'disconnected') return; - - // Create a list of all servers we can send the ismaster command to - var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : []; - - // Secondary keys - var keys = Object.keys(self.replicaset._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self.replicaset._state.secondaries[keys[i]]); - } - - // Number of server entries - var numberOfEntries = allServers.length; - - // We got keys - for(var i = 0; i < allServers.length; i++) { - - // We got a server instance - var server = allServers[i]; - - // Create a new server object, avoid using internal connections as they might - // be in an illegal state - new function(serverInstance) { - var _db = self.dbs[serverInstance.host + ":" + serverInstance.port]; - // If we have a db - if(_db != null) { - // Startup time of the command - var startTime = Date.now(); - - // Execute ping command in own scope - var _ping = function(__db, __serverInstance) { - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }; - // Ping - _ping(_db, serverInstance); - } else { - // Create a new master connection - var _server = new Server(serverInstance.host, serverInstance.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self.replicaset._connectTimeoutMS }, - ssl: self.replicaset.ssl, - sslValidate: self.replicaset.sslValidate, - sslCA: self.replicaset.sslCA, - sslCert: self.replicaset.sslCert, - sslKey: self.replicaset.sslKey, - sslPass: self.replicaset.sslPass - }); - - // Create Db instance - var _db = new self.Db(self.replicaset.db.databaseName, _server, { safe: true }); - _db.on("close", function() { - delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port]; - }) - - var _ping = function(__db, __serverInstance) { - if(self.state == 'disconnected') { - self.stop(); - return; - } - - __db.open(function(err, db) { - if(self.state == 'disconnected' && __db != null) { - return __db.close(); - } - - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - // Save instance - self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db; - - // Startup time of the command - var startTime = Date.now(); - - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }); - }; - - _ping(_db, serverInstance); - } - - function done() { - // Adjust the number of checks - numberOfEntries--; - - // If we are done with all results coming back trigger ping again - if(0 === numberOfEntries && 'connected' == self.state) { - setTimeout(pingFunction, self.pingInterval); - } - } - }(server); - } - } - - // Start pingFunction - pingFunction(); - - callback && callback(null); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js deleted file mode 100644 index f9b8c46433c..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js +++ /dev/null @@ -1,80 +0,0 @@ -// The Statistics strategy uses the measure of each end-start time for each -// query executed against the db to calculate the mean, variance and standard deviation -// and pick the server which the lowest mean and deviation -var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) { - this.replicaset = replicaset; - // Logger api - this.Logger = null; -} - -// Starts any needed code -StatisticsStrategy.prototype.start = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.stop = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // If no candidates available return an error - if(finalCandidates.length == 0) return new Error("No replica set members available for query"); - // Pick a random server - return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js deleted file mode 100644 index 4c13d0c273f..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js +++ /dev/null @@ -1,225 +0,0 @@ -var fs = require('fs'), - ReadPreference = require('./read_preference').ReadPreference; - -exports.parse = function(url, options) { - // Ensure we have a default options object if none set - options = options || {}; - // Variables - var connection_part = ''; - var auth_part = ''; - var query_string_part = ''; - var dbName = 'admin'; - - // Must start with mongodb - if(url.indexOf("mongodb://") != 0) - throw Error("URL must be in the format mongodb://user:pass@host:port/dbname"); - // If we have a ? mark cut the query elements off - if(url.indexOf("?") != -1) { - query_string_part = url.substr(url.indexOf("?") + 1); - connection_part = url.substring("mongodb://".length, url.indexOf("?")) - } else { - connection_part = url.substring("mongodb://".length); - } - - // Check if we have auth params - if(connection_part.indexOf("@") != -1) { - auth_part = connection_part.split("@")[0]; - connection_part = connection_part.split("@")[1]; - } - - // Check if the connection string has a db - if(connection_part.indexOf(".sock") != -1) { - if(connection_part.indexOf(".sock/") != -1) { - dbName = connection_part.split(".sock/")[1]; - connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length); - } - } else if(connection_part.indexOf("/") != -1) { - dbName = connection_part.split("/")[1]; - connection_part = connection_part.split("/")[0]; - } - - // Result object - var object = {}; - - // Pick apart the authentication part of the string - var authPart = auth_part || ''; - var auth = authPart.split(':', 2); - if(options['uri_decode_auth']){ - auth[0] = decodeURIComponent(auth[0]); - if(auth[1]){ - auth[1] = decodeURIComponent(auth[1]); - } - } - - // Add auth to final object if we have 2 elements - if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]}; - - // Variables used for temporary storage - var hostPart; - var urlOptions; - var servers; - var serverOptions = {socketOptions: {}}; - var dbOptions = {read_preference_tags: []}; - var replSetServersOptions = {socketOptions: {}}; - // Add server options to final object - object.server_options = serverOptions; - object.db_options = dbOptions; - object.rs_options = replSetServersOptions; - object.mongos_options = {}; - - // Let's check if we are using a domain socket - if(url.match(/\.sock/)) { - // Split out the socket part - var domainSocket = url.substring( - url.indexOf("mongodb://") + "mongodb://".length - , url.lastIndexOf(".sock") + ".sock".length); - // Clean out any auth stuff if any - if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1]; - servers = [{domain_socket: domainSocket}]; - } else { - // Split up the db - hostPart = connection_part; - // Parse all server results - servers = hostPart.split(',').map(function(h) { - var hostPort = h.split(':', 2); - var _host = hostPort[0] || 'localhost'; - var _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017; - // Check for localhost?safe=true style case - if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0]; - - // Return the mapped object - return {host: _host, port: _port}; - }); - } - - // Get the db name - object.dbName = dbName || 'admin'; - // Split up all the options - urlOptions = (query_string_part || '').split(/[&;]/); - // Ugh, we have to figure out which options go to which constructor manually. - urlOptions.forEach(function(opt) { - if(!opt) return; - var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1]; - // Options implementations - switch(name) { - case 'slaveOk': - case 'slave_ok': - serverOptions.slave_ok = (value == 'true'); - break; - case 'maxPoolSize': - case 'poolSize': - serverOptions.poolSize = parseInt(value, 10); - replSetServersOptions.poolSize = parseInt(value, 10); - break; - case 'autoReconnect': - case 'auto_reconnect': - serverOptions.auto_reconnect = (value == 'true'); - break; - case 'minPoolSize': - throw new Error("minPoolSize not supported"); - case 'maxIdleTimeMS': - throw new Error("maxIdleTimeMS not supported"); - case 'waitQueueMultiple': - throw new Error("waitQueueMultiple not supported"); - case 'waitQueueTimeoutMS': - throw new Error("waitQueueTimeoutMS not supported"); - case 'uuidRepresentation': - throw new Error("uuidRepresentation not supported"); - case 'ssl': - if(value == 'prefer') { - serverOptions.ssl = value; - replSetServersOptions.ssl = value; - break; - } - serverOptions.ssl = (value == 'true'); - replSetServersOptions.ssl = (value == 'true'); - break; - case 'replicaSet': - case 'rs_name': - replSetServersOptions.rs_name = value; - break; - case 'reconnectWait': - replSetServersOptions.reconnectWait = parseInt(value, 10); - break; - case 'retries': - replSetServersOptions.retries = parseInt(value, 10); - break; - case 'readSecondary': - case 'read_secondary': - replSetServersOptions.read_secondary = (value == 'true'); - break; - case 'fsync': - dbOptions.fsync = (value == 'true'); - break; - case 'journal': - dbOptions.journal = (value == 'true'); - break; - case 'safe': - dbOptions.safe = (value == 'true'); - break; - case 'nativeParser': - case 'native_parser': - dbOptions.native_parser = (value == 'true'); - break; - case 'connectTimeoutMS': - serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - break; - case 'socketTimeoutMS': - serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - break; - case 'w': - dbOptions.w = parseInt(value, 10); - break; - case 'authSource': - dbOptions.authSource = value; - case 'wtimeoutMS': - dbOptions.wtimeoutMS = parseInt(value, 10); - break; - case 'readPreference': - if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest"); - dbOptions.read_preference = value; - break; - case 'readPreferenceTags': - // Contains the tag object - var tagObject = {}; - if(value == null || value == '') { - dbOptions.read_preference_tags.push(tagObject); - break; - } - - // Split up the tags - var tags = value.split(/\,/); - for(var i = 0; i < tags.length; i++) { - var parts = tags[i].trim().split(/\:/); - tagObject[parts[0]] = parts[1]; - } - - // Set the preferences tags - dbOptions.read_preference_tags.push(tagObject); - break; - default: - break; - } - }); - - // No tags: should be null (not []) - if(dbOptions.read_preference_tags.length === 0) { - dbOptions.read_preference_tags = null; - } - - // Validate if there are an invalid write concern combinations - if((dbOptions.w == -1 || dbOptions.w == 0) && ( - dbOptions.journal == true - || dbOptions.fsync == true - || dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync") - - // If no read preference set it to primary - if(!dbOptions.read_preference) dbOptions.read_preference = 'primary'; - - // Add servers to result - object.servers = servers; - // Returned parsed object - return object; -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js deleted file mode 100644 index f7aa55610e5..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js +++ /dev/null @@ -1,988 +0,0 @@ -var QueryCommand = require('./commands/query_command').QueryCommand, - GetMoreCommand = require('./commands/get_more_command').GetMoreCommand, - KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand, - Long = require('bson').Long, - ReadPreference = require('./connection/read_preference').ReadPreference, - CursorStream = require('./cursorstream'), - timers = require('timers'), - utils = require('./utils'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Constructor for a cursor object that handles all the operations on query result - * using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly, - * but use find to acquire a cursor. (INTERNAL TYPE) - * - * Options - * - **skip** {Number} skip number of documents to skip. - * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **hint** {Object}, hint force the query to use a specific index. - * - **explain** {Boolean}, explain return the explaination of the query. - * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned. - * - **timeout** {Boolean}, timeout allow the query to timeout. - * - **tailable** {Boolean}, tailable allow the cursor to be tailable. - * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor. - * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database. - * - **raw** {Boolean}, raw return all query documents as raw buffers (default false). - * - **read** {Boolean}, read specify override of read from source (primary/secondary). - * - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries. - * - **returnKey** {Boolean}, returnKey only return the index key. - * - **maxScan** {Number}, maxScan limit the number of items to scan. - * - **min** {Number}, min set index bounds. - * - **max** {Number}, max set index bounds. - * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results. - * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler. - * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout. - * - **dbName** {String}, dbName override the default dbName. - * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor. - * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets. - * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos. - * - * @class Represents a Cursor. - * @param {Db} db the database object to work with. - * @param {Collection} collection the collection to query. - * @param {Object} selector the query selector. - * @param {Object} fields an object containing what fields to include or exclude from objects returned. - * @param {Object} [options] additional options for the collection. -*/ -function Cursor(db, collection, selector, fields, options) { - this.db = db; - this.collection = collection; - this.selector = selector; - this.fields = fields; - options = !options ? {} : options; - - this.skipValue = options.skip == null ? 0 : options.skip; - this.limitValue = options.limit == null ? 0 : options.limit; - this.sortValue = options.sort; - this.hint = options.hint; - this.explainValue = options.explain; - this.snapshot = options.snapshot; - this.timeout = options.timeout == null ? true : options.timeout; - this.tailable = options.tailable; - this.awaitdata = options.awaitdata; - this.numberOfRetries = options.numberOfRetries == null ? 5 : options.numberOfRetries; - this.currentNumberOfRetries = this.numberOfRetries; - this.batchSizeValue = options.batchSize == null ? 0 : options.batchSize; - this.slaveOk = options.slaveOk == null ? collection.slaveOk : options.slaveOk; - this.raw = options.raw == null ? false : options.raw; - this.read = options.read == null ? ReadPreference.PRIMARY : options.read; - this.returnKey = options.returnKey; - this.maxScan = options.maxScan; - this.min = options.min; - this.max = options.max; - this.showDiskLoc = options.showDiskLoc; - this.comment = options.comment; - this.tailableRetryInterval = options.tailableRetryInterval || 100; - this.exhaust = options.exhaust || false; - this.partial = options.partial || false; - - this.totalNumberOfRecords = 0; - this.items = []; - this.cursorId = Long.fromInt(0); - - // This name - this.dbName = options.dbName; - - // State variables for the cursor - this.state = Cursor.INIT; - // Keep track of the current query run - this.queryRun = false; - this.getMoreTimer = false; - - // If we are using a specific db execute against it - if(this.dbName != null) { - this.collectionName = this.dbName + "." + this.collection.collectionName; - } else { - this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName; - } -}; - -/** - * Resets this cursor to its initial state. All settings like the query string, - * tailable, batchSizeValue, skipValue and limits are preserved. - * - * @return {Cursor} returns itself with rewind applied. - * @api public - */ -Cursor.prototype.rewind = function() { - var self = this; - - if (self.state != Cursor.INIT) { - if (self.state != Cursor.CLOSED) { - self.close(function() {}); - } - - self.numberOfReturned = 0; - self.totalNumberOfRecords = 0; - self.items = []; - self.cursorId = Long.fromInt(0); - self.state = Cursor.INIT; - self.queryRun = false; - } - - return self; -}; - - -/** - * Returns an array of documents. The caller is responsible for making sure that there - * is enough memory to store the results. Note that the array only contain partial - * results when this cursor had been previouly accessed. In that case, - * cursor.rewind() can be used to reset the cursor. - * - * @param {Function} callback This will be called after executing this method successfully. The first parameter will contain the Error object if an error occured, or null otherwise. The second parameter will contain an array of BSON deserialized objects as a result of the query. - * @return {null} - * @api public - */ -Cursor.prototype.toArray = function(callback) { - var self = this; - - if(!callback) { - throw new Error('callback is mandatory'); - } - - if(this.tailable) { - callback(new Error("Tailable cursor cannot be converted to array"), null); - } else if(this.state != Cursor.CLOSED) { - // return toArrayExhaust(self, callback); - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return toArrayExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - self.nextObject({noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err), null); - if(self.cursorId.toString() == "0") { - self.state = Cursor.CLOSED; - return callback(null, self.items); - } - - // Let's issue getMores until we have no more records waiting - getAllByGetMore(self, function(err, done) { - self.state = Cursor.CLOSED; - if(err) return callback(utils.toError(err), null); - callback(null, self.items); - }); - }) - - } else { - callback(new Error("Cursor is closed"), null); - } -} - -var toArrayExhaust = function(self, callback) { - var items = []; - - self.each(function(err, item) { - if(err != null) { - return callback(utils.toError(err), null); - } - - if(item != null && Array.isArray(items)) { - items.push(item); - } else { - var resultItems = items; - items = null; - self.items = []; - callback(null, resultItems); - } - }); -} - -var getAllByGetMore = function(self, callback) { - getMore(self, {noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err)); - if(result == null) return callback(null, null); - if(self.cursorId.toString() == "0") return callback(null, null); - getAllByGetMore(self, callback); - }) -} - -/** - * Iterates over all the documents for this cursor. As with **{cursor.toArray}**, - * not all of the elements will be iterated if this cursor had been previouly accessed. - * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike - * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements - * at any given time if batch size is specified. Otherwise, the caller is responsible - * for making sure that the entire result can fit the memory. - * - * @param {Function} callback this will be called for while iterating every document of the query result. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the document. - * @return {null} - * @api public - */ -Cursor.prototype.each = function(callback) { - var self = this; - var fn; - - if (!callback) { - throw new Error('callback is mandatory'); - } - - if(this.state != Cursor.CLOSED) { - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return eachExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - if(this.items.length > 0) { - // Trampoline all the entries - while(fn = loop(self, callback)) fn(self, callback); - // Call each again - self.each(callback); - } else { - self.nextObject(function(err, item) { - - if(err) { - self.state = Cursor.CLOSED; - return callback(utils.toError(err), item); - } - - if(item == null) return callback(null, null); - callback(null, item); - self.each(callback); - }) - } - } else { - callback(new Error("Cursor is closed"), null); - } -} - -// Special for exhaust command as we don't initiate the actual result sets -// the server just sends them as they arrive meaning we need to get the IO event -// loop happen so we can receive more data from the socket or we return to early -// after the first fetch and loose all the incoming getMore's automatically issued -// from the server. -var eachExhaust = function(self, callback) { - //FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2) - processor(function(){ - // Fetch the next object until there is no more objects - self.nextObject(function(err, item) { - if(err != null) return callback(err, null); - if(item != null) { - callback(null, item); - eachExhaust(self, callback); - } else { - // Close the cursor if done - self.state = Cursor.CLOSED; - callback(err, null); - } - }); - }); -} - -// Trampoline emptying the number of retrieved items -// without incurring a nextTick operation -var loop = function(self, callback) { - // No more items we are done - if(self.items.length == 0) return; - // Get the next document - var doc = self.items.shift(); - // Callback - callback(null, doc); - // Loop - return loop; -} - -/** - * Determines how many result the query for this cursor will return - * - * @param {Boolean} applySkipLimit if set to true will apply the skip and limits set on the cursor. Defaults to false. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the number of results or null if an error occured. - * @return {null} - * @api public - */ -Cursor.prototype.count = function(applySkipLimit, callback) { - if(typeof applySkipLimit == 'function') { - callback = applySkipLimit; - applySkipLimit = false; - } - - var options = {}; - if(applySkipLimit) { - if(typeof this.skipValue == 'number') options.skip = this.skipValue; - if(typeof this.limitValue == 'number') options.limit = this.limitValue; - } - - // Call count command - this.collection.count(this.selector, options, callback); -}; - -/** - * Sets the sort parameter of this cursor to the given value. - * - * This method has the following method signatures: - * (keyOrList, callback) - * (keyOrList, direction, callback) - * - * @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction]. - * @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive. - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.sort = function(keyOrList, direction, callback) { - callback = callback || function(){}; - if(typeof direction === "function") { callback = direction; direction = null; } - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support sorting"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - var order = keyOrList; - - if(direction != null) { - order = [[keyOrList, direction]]; - } - - this.sortValue = order; - callback(null, this); - } - return this; -}; - -/** - * Sets the limit parameter of this cursor to the given value. - * - * @param {Number} limit the new limit. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.limit = function(limit, callback) { - if(this.tailable) { - if(callback) { - callback(new Error("Tailable cursor doesn't support limit"), null); - } else { - throw new Error("Tailable cursor doesn't support limit"); - } - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback) { - callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else { - if(limit != null && limit.constructor != Number) { - if(callback) { - callback(new Error("limit requires an integer"), null); - } else { - throw new Error("limit requires an integer"); - } - } else { - this.limitValue = limit; - if(callback) return callback(null, this); - } - } - - return this; -}; - -/** - * Sets the read preference for the cursor - * - * @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.setReadPreference = function(readPreference, tags, callback) { - if(typeof tags == 'function') callback = tags; - - var _mode = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - - if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback == null) throw new Error("Cannot change read preference on executed query or closed cursor"); - callback(new Error("Cannot change read preference on executed query or closed cursor")); - } else if(_mode != null && _mode != 'primary' - && _mode != 'secondaryOnly' && _mode != 'secondary' - && _mode != 'nearest' && _mode != 'primaryPreferred' && _mode != 'secondaryPreferred') { - if(callback == null) throw new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported"); - callback(new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported")); - } else { - this.read = readPreference; - if(callback != null) callback(null, this); - } - - return this; -} - -/** - * Sets the skip parameter of this cursor to the given value. - * - * @param {Number} skip the new skip value. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.skip = function(skip, callback) { - callback = callback || function(){}; - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support skip"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - if(skip != null && skip.constructor != Number) { - callback(new Error("skip requires an integer"), null); - } else { - this.skipValue = skip; - callback(null, this); - } - } - - return this; -}; - -/** - * Sets the batch size parameter of this cursor to the given value. - * - * @param {Number} batchSize the new batch size. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.batchSize = function(batchSize, callback) { - if(this.state == Cursor.CLOSED) { - if(callback != null) { - return callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else if(batchSize != null && batchSize.constructor != Number) { - if(callback != null) { - return callback(new Error("batchSize requires an integer"), null); - } else { - throw new Error("batchSize requires an integer"); - } - } else { - this.batchSizeValue = batchSize; - if(callback != null) return callback(null, this); - } - - return this; -}; - -/** - * The limit used for the getMore command - * - * @return {Number} The number of records to request per batch. - * @ignore - * @api private - */ -var limitRequest = function(self) { - var requestedLimit = self.limitValue; - var absLimitValue = Math.abs(self.limitValue); - var absBatchValue = Math.abs(self.batchSizeValue); - - if(absLimitValue > 0) { - if (absBatchValue > 0) { - requestedLimit = Math.min(absLimitValue, absBatchValue); - } - } else { - requestedLimit = self.batchSizeValue; - } - - return requestedLimit; -}; - - -/** - * Generates a QueryCommand object using the parameters of this cursor. - * - * @return {QueryCommand} The command object - * @ignore - * @api private - */ -var generateQueryCommand = function(self) { - // Unpack the options - var queryOptions = QueryCommand.OPTS_NONE; - if(!self.timeout) { - queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - } - - if(self.tailable != null) { - queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR; - self.skipValue = self.limitValue = 0; - - // if awaitdata is set - if(self.awaitdata != null) { - queryOptions |= QueryCommand.OPTS_AWAIT_DATA; - } - } - - if(self.exhaust) { - queryOptions |= QueryCommand.OPTS_EXHAUST; - } - - if(self.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - if(self.partial) { - queryOptions |= QueryCommand.OPTS_PARTIAL; - } - - // limitValue of -1 is a special case used by Db#eval - var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self); - - // Check if we need a special selector - if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null - || self.returnKey != null || self.maxScan != null || self.min != null || self.max != null - || self.showDiskLoc != null || self.comment != null) { - - // Build special selector - var specialSelector = {'$query':self.selector}; - if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue); - if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint; - if(self.snapshot != null) specialSelector['$snapshot'] = true; - if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey; - if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan; - if(self.min != null) specialSelector['$min'] = self.min; - if(self.max != null) specialSelector['$max'] = self.max; - if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc; - if(self.comment != null) specialSelector['$comment'] = self.comment; - // If we have explain set only return a single document with automatic cursor close - if(self.explainValue != null) { - numberToReturn = (-1)*Math.abs(numberToReturn); - specialSelector['$explain'] = true; - } - - // Return the query - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields); - } else { - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields); - } -}; - -/** - * @return {Object} Returns an object containing the sort value of this cursor with - * the proper formatting that can be used internally in this cursor. - * @ignore - * @api private - */ -Cursor.prototype.formattedOrderClause = function() { - return utils.formattedOrderClause(this.sortValue); -}; - -/** - * Converts the value of the sort direction into its equivalent numerical value. - * - * @param sortDirection {String|number} Range of acceptable values: - * 'ascending', 'descending', 'asc', 'desc', 1, -1 - * - * @return {number} The equivalent numerical value - * @throws Error if the given sortDirection is invalid - * @ignore - * @api private - */ -Cursor.prototype.formatSortValue = function(sortDirection) { - return utils.formatSortValue(sortDirection); -}; - -/** - * Gets the next document from the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @api public - */ -Cursor.prototype.nextObject = function(options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.INIT) { - var cmd; - try { - cmd = generateQueryCommand(self); - } catch (err) { - return callback(err, null); - } - - // Execute command - var commandHandler = function(err, result) { - self.state = Cursor.OPEN; - if(err != null && result == null) return callback(utils.toError(err), null); - - if(!err && result.documents[0] && result.documents[0]['$err']) { - return self.close(function() {callback(utils.toError(result.documents[0]['$err']), null);}); - } - - self.queryRun = true; - self.state = Cursor.OPEN; // Adjust the state of the cursor - self.cursorId = result.cursorId; - self.totalNumberOfRecords = result.numberReturned; - - // Add the new documents to the list of items, using forloop to avoid - // new array allocations and copying - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // If we have noReturn set just return (not modifying the internal item list) - // used for toArray - if(options.noReturn) { - return callback(null, true); - } - - // Ignore callbacks until the cursor is dead for exhausted - if(self.exhaust && result.cursorId.toString() == "0") { - self.nextObject(callback); - } else if(self.exhaust == false || self.exhaust == null) { - self.nextObject(callback); - } - }; - - // If we have no connection set on this cursor check one out - if(self.connection == null) { - try { - self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read); - } catch(err) { - return callback(utils.toError(err), null); - } - } - - // Execute the command - self.db._executeQueryCommand(cmd, {exhaust: self.exhaust, raw:self.raw, read:self.read, connection:self.connection}, commandHandler); - // Set the command handler to null - commandHandler = null; - } else if(self.items.length) { - callback(null, self.items.shift()); - } else if(self.cursorId.greaterThan(Long.fromInt(0))) { - getMore(self, callback); - } else { - // Force cursor to stay open - return self.close(function() {callback(null, null);}); - } -} - -/** - * Gets more results from the database if any. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @ignore - * @api private - */ -var getMore = function(self, options, callback) { - var limit = 0; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.GET_MORE) return callback(null, null); - - // Set get more in progress - self.state = Cursor.GET_MORE; - - // Set options - if (!self.tailable && self.limitValue > 0) { - limit = self.limitValue - self.totalNumberOfRecords; - if (limit < 1) { - self.close(function() {callback(null, null);}); - return; - } - } - - try { - var getMoreCommand = new GetMoreCommand( - self.db - , self.collectionName - , limitRequest(self) - , self.cursorId - ); - - // Set up options - var command_options = {read: self.read, raw: self.raw, connection:self.connection }; - - // Execute the command - self.db._executeQueryCommand(getMoreCommand, command_options, function(err, result) { - var cbValue; - - // Get more done - self.state = Cursor.OPEN; - - if(err != null) { - return callback(utils.toError(err), null); - } - - try { - var isDead = 1 === result.responseFlag && result.cursorId.isZero(); - - self.cursorId = result.cursorId; - self.totalNumberOfRecords += result.numberReturned; - - // Determine if there's more documents to fetch - if(result.numberReturned > 0) { - if (self.limitValue > 0) { - var excessResult = self.totalNumberOfRecords - self.limitValue; - - if (excessResult > 0) { - result.documents.splice(-1 * excessResult, excessResult); - } - } - - // Reset the tries for awaitdata if we are using it - self.currentNumberOfRetries = self.numberOfRetries; - // Get the documents - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // Don's shift a document out as we need it for toArray - if(options.noReturn) { - cbValue = true; - } else { - cbValue = self.items.shift(); - } - } else if(self.tailable && !isDead && self.awaitdata) { - // Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used - self.currentNumberOfRetries = self.currentNumberOfRetries - 1; - if(self.currentNumberOfRetries == 0) { - self.close(function() { - callback(new Error("tailable cursor timed out"), null); - }); - } else { - getMore(self, callback); - } - } else if(self.tailable && !isDead) { - self.getMoreTimer = setTimeout(function() { getMore(self, callback); }, self.tailableRetryInterval); - } else { - self.close(function() {callback(null, null); }); - } - - result = null; - } catch(err) { - callback(utils.toError(err), null); - } - if (cbValue != null) callback(null, cbValue); - }); - - getMoreCommand = null; - } catch(err) { - // Get more done - self.state = Cursor.OPEN; - - var handleClose = function() { - callback(utils.toError(err), null); - }; - - self.close(handleClose); - handleClose = null; - } -} - -/** - * Gets a detailed information about how the query is performed on this cursor and how - * long it took the database to process it. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details. - * @api public - */ -Cursor.prototype.explain = function(callback) { - var limit = (-1)*Math.abs(this.limitValue); - - // Create a new cursor and fetch the plan - var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, { - skip: this.skipValue - , limit:limit - , sort: this.sortValue - , hint: this.hint - , explain: true - , snapshot: this.snapshot - , timeout: this.timeout - , tailable: this.tailable - , batchSize: this.batchSizeValue - , slaveOk: this.slaveOk - , raw: this.raw - , read: this.read - , returnKey: this.returnKey - , maxScan: this.maxScan - , min: this.min - , max: this.max - , showDiskLoc: this.showDiskLoc - , comment: this.comment - , awaitdata: this.awaitdata - , numberOfRetries: this.numberOfRetries - , dbName: this.dbName - }); - - // Fetch the explaination document - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - // close the cursor - cursor.close(function(err, result) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); - }); -}; - -/** - * @ignore - */ -Cursor.prototype.streamRecords = function(options) { - console.log("[WARNING] streamRecords method is deprecated, please use stream method which is much faster"); - var args = Array.prototype.slice.call(arguments, 0); - options = args.length ? args.shift() : {}; - - var - self = this, - stream = new process.EventEmitter(), - recordLimitValue = this.limitValue || 0, - emittedRecordCount = 0, - queryCommand = generateQueryCommand(self); - - // see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol - queryCommand.numberToReturn = options.fetchSize ? options.fetchSize : 500; - // Execute the query - execute(queryCommand); - - function execute(command) { - self.db._executeQueryCommand(command, {exhaust: self.exhaust, read:self.read, raw:self.raw, connection:self.connection}, function(err,result) { - if(err) { - stream.emit('error', err); - self.close(function(){}); - return; - } - - if (!self.queryRun && result) { - self.queryRun = true; - self.cursorId = result.cursorId; - self.state = Cursor.OPEN; - self.getMoreCommand = new GetMoreCommand(self.db, self.collectionName, queryCommand.numberToReturn, result.cursorId); - } - - var resflagsMap = { - CursorNotFound:1<<0, - QueryFailure:1<<1, - ShardConfigStale:1<<2, - AwaitCapable:1<<3 - }; - - if(result.documents && result.documents.length && !(result.responseFlag & resflagsMap.QueryFailure)) { - try { - result.documents.forEach(function(doc){ - if(recordLimitValue && emittedRecordCount>=recordLimitValue) { - throw("done"); - } - emittedRecordCount++; - stream.emit('data', doc); - }); - } catch(err) { - if (err != "done") { throw err; } - else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - self.close(function(){}); - return; - } - } - // rinse & repeat - execute(self.getMoreCommand); - } else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - } - }); - } - - return stream; -}; - -/** - * Returns a Node ReadStream interface for this cursor. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * @return {CursorStream} returns a stream object. - * @api public - */ -Cursor.prototype.stream = function stream(options) { - return new CursorStream(this, options); -} - -/** - * Close the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor. - * @return {null} - * @api public - */ -Cursor.prototype.close = function(callback) { - var self = this - this.getMoreTimer && clearTimeout(this.getMoreTimer); - // Close the cursor if not needed - if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) { - try { - var command = new KillCursorCommand(this.db, [this.cursorId]); - // Added an empty callback to ensure we don't throw any null exceptions - this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function() {}); - } catch(err) {} - } - - // Null out the connection - self.connection = null; - // Reset cursor id - this.cursorId = Long.fromInt(0); - // Set to closed status - this.state = Cursor.CLOSED; - - if(callback) { - callback(null, self); - self.items = []; - } - - return this; -}; - -/** - * Check if the cursor is closed or open. - * - * @return {Boolean} returns the state of the cursor. - * @api public - */ -Cursor.prototype.isClosed = function() { - return this.state == Cursor.CLOSED ? true : false; -}; - -/** - * Init state - * - * @classconstant INIT - **/ -Cursor.INIT = 0; - -/** - * Cursor open - * - * @classconstant OPEN - **/ -Cursor.OPEN = 1; - -/** - * Cursor closed - * - * @classconstant CLOSED - **/ -Cursor.CLOSED = 2; - -/** - * Cursor performing a get more - * - * @classconstant OPEN - **/ -Cursor.GET_MORE = 3; - -/** - * @ignore - * @api private - */ -exports.Cursor = Cursor; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js deleted file mode 100644 index 27520913e2b..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js +++ /dev/null @@ -1,164 +0,0 @@ -var timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Module dependecies. - */ -var Stream = require('stream').Stream; - -/** - * CursorStream - * - * Returns a stream interface for the **cursor**. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - **close** {function() {}} the end event triggers when there is no more documents available. - * - * @class Represents a CursorStream. - * @param {Cursor} cursor a cursor object that the stream wraps. - * @return {Stream} - */ -function CursorStream(cursor, options) { - if(!(this instanceof CursorStream)) return new CursorStream(cursor); - options = options ? options : {}; - - Stream.call(this); - - this.readable = true; - this.paused = false; - this._cursor = cursor; - this._destroyed = null; - this.options = options; - - // give time to hook up events - var self = this; - process.nextTick(function() { - self._init(); - }); -} - -/** - * Inherit from Stream - * @ignore - * @api private - */ -CursorStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -CursorStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -CursorStream.prototype.paused; - -/** - * Initialize the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._init = function () { - if (this._destroyed) return; - this._next(); -} - -/** - * Pull the next document from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._next = function () { - if(this.paused || this._destroyed) return; - - var self = this; - // Get the next object - processor(function() { - if(self.paused || self._destroyed) return; - - self._cursor.nextObject(function (err, doc) { - self._onNextObject(err, doc); - }); - }); -} - -/** - * Handle each document as its returned from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._onNextObject = function (err, doc) { - if(err) return this.destroy(err); - - // when doc is null we hit the end of the cursor - if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) { - this.emit('end') - return this.destroy(); - } else if(doc) { - var data = typeof this.options.transform == 'function' ? this.options.transform(doc) : doc; - this.emit('data', data); - this._next(); - } -} - -/** - * Pauses the stream. - * - * @api public - */ -CursorStream.prototype.pause = function () { - this.paused = true; -} - -/** - * Resumes the stream. - * - * @api public - */ -CursorStream.prototype.resume = function () { - var self = this; - - // Don't do anything if we are not paused - if(!this.paused) return; - if(!this._cursor.state == 3) return; - - process.nextTick(function() { - self.paused = false; - // Only trigger more fetching if the cursor is open - self._next(); - }) -} - -/** - * Destroys the stream, closing the underlying - * cursor. No more events will be emitted. - * - * @api public - */ -CursorStream.prototype.destroy = function (err) { - if (this._destroyed) return; - this._destroyed = true; - this.readable = false; - - this._cursor.close(); - - if(err) { - this.emit('error', err); - } - - this.emit('close'); -} - -// TODO - maybe implement the raw option to pass binary? -//CursorStream.prototype.setEncoding = function () { -//} - -module.exports = exports = CursorStream; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js deleted file mode 100644 index 957e43639fc..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js +++ /dev/null @@ -1,2147 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var QueryCommand = require('./commands/query_command').QueryCommand, - DbCommand = require('./commands/db_command').DbCommand, - MongoReply = require('./responses/mongo_reply').MongoReply, - Admin = require('./admin').Admin, - Collection = require('./collection').Collection, - Server = require('./connection/server').Server, - ReplSet = require('./connection/repl_set').ReplSet, - ReadPreference = require('./connection/read_preference').ReadPreference, - Mongos = require('./connection/mongos').Mongos, - Cursor = require('./cursor').Cursor, - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - crypto = require('crypto'), - timers = require('timers'), - utils = require('./utils'), - parse = require('./connection/url_parser').parse; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * Create a new Db instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a Db - * @param {String} databaseName name of the database. - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function Db(databaseName, serverConfig, options) { - if(!(this instanceof Db)) return new Db(databaseName, serverConfig, options); - - EventEmitter.call(this); - this.databaseName = databaseName; - this.serverConfig = serverConfig; - this.options = options == null ? {} : options; - // State to check against if the user force closed db - this._applicationClosed = false; - // Fetch the override flag if any - var overrideUsedFlag = this.options['override_used_flag'] == null ? false : this.options['override_used_flag']; - - // Verify that nobody is using this config - if(!overrideUsedFlag && this.serverConfig != null && typeof this.serverConfig == 'object' && this.serverConfig._isUsed && this.serverConfig._isUsed()) { - throw new Error("A Server or ReplSet instance cannot be shared across multiple Db instances"); - } else if(!overrideUsedFlag && typeof this.serverConfig == 'object'){ - // Set being used - this.serverConfig._used = true; - } - - // Ensure we have a valid db name - validateDatabaseName(databaseName); - - // Contains all the connections for the db - try { - this.native_parser = this.options.native_parser; - // The bson lib - var bsonLib = this.bsonLib = this.options.native_parser ? require('bson').BSONNative : require('bson').BSONPure; - // Fetch the serializer object - var BSON = bsonLib.BSON; - // Create a new instance - this.bson = new BSON([bsonLib.Long, bsonLib.ObjectID, bsonLib.Binary, bsonLib.Code, bsonLib.DBRef, bsonLib.Symbol, bsonLib.Double, bsonLib.Timestamp, bsonLib.MaxKey, bsonLib.MinKey]); - // Backward compatibility to access types - this.bson_deserializer = bsonLib; - this.bson_serializer = bsonLib; - } catch (err) { - // If we tried to instantiate the native driver - var msg = "Native bson parser not compiled, please compile " - + "or avoid using native_parser=true"; - throw Error(msg); - } - - // Internal state of the server - this._state = 'disconnected'; - - this.pkFactory = this.options.pk == null ? bsonLib.ObjectID : this.options.pk; - this.forceServerObjectId = this.options.forceServerObjectId != null ? this.options.forceServerObjectId : false; - - // Added safe - this.safe = this.options.safe == null ? false : this.options.safe; - - // If we have not specified a "safe mode" we just print a warning to the console - if(this.options.safe == null && this.options.w == null && this.options.journal == null && this.options.fsync == null) { - console.log("========================================================================================"); - console.log("= Please ensure that you set the default write concern for the database by setting ="); - console.log("= one of the options ="); - console.log("= ="); - console.log("= w: (value of > -1 or the string 'majority'), where < 1 means ="); - console.log("= no write acknowlegement ="); - console.log("= journal: true/false, wait for flush to journal before acknowlegement ="); - console.log("= fsync: true/false, wait for flush to file system before acknowlegement ="); - console.log("= ="); - console.log("= For backward compatibility safe is still supported and ="); - console.log("= allows values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}] ="); - console.log("= the default value is false which means the driver receives does not ="); - console.log("= return the information of the success/error of the insert/update/remove ="); - console.log("= ="); - console.log("= ex: new Db(new Server('localhost', 27017), {safe:false}) ="); - console.log("= ="); - console.log("= http://www.mongodb.org/display/DOCS/getLastError+Command ="); - console.log("= ="); - console.log("= The default of no acknowlegement will change in the very near future ="); - console.log("= ="); - console.log("= This message will disappear when the default safe is set on the driver Db ="); - console.log("========================================================================================"); - } - - // Internal states variables - this.notReplied ={}; - this.isInitializing = true; - this.auths = []; - this.openCalled = false; - - // Command queue, keeps a list of incoming commands that need to be executed once the connection is up - this.commands = []; - - // Set up logger - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - // Allow slaveOk - this.slaveOk = this.options["slave_ok"] == null ? false : this.options["slave_ok"]; - - var self = this; - // Associate the logger with the server config - this.serverConfig.logger = this.logger; - if(this.serverConfig.strategyInstance) this.serverConfig.strategyInstance.logger = this.logger; - this.tag = new Date().getTime(); - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[]}; - - // Controls serialization options - this.serializeFunctions = this.options.serializeFunctions != null ? this.options.serializeFunctions : false; - - // Raw mode - this.raw = this.options.raw != null ? this.options.raw : false; - - // Record query stats - this.recordQueryStats = this.options.recordQueryStats != null ? this.options.recordQueryStats : false; - - // If we have server stats let's make sure the driver objects have it enabled - if(this.recordQueryStats == true) { - this.serverConfig.enableRecordQueryStats(true); - } - - // Retry information - this.retryMiliSeconds = this.options.retryMiliSeconds != null ? this.options.retryMiliSeconds : 1000; - this.numberOfRetries = this.options.numberOfRetries != null ? this.options.numberOfRetries : 60; - - // Set default read preference if any - this.readPreference = this.options.readPreference; -}; - -/** - * @ignore - */ -function validateDatabaseName(databaseName) { - if(typeof databaseName !== 'string') throw new Error("database name must be a string"); - if(databaseName.length === 0) throw new Error("database name cannot be the empty string"); - - var invalidChars = [" ", ".", "$", "/", "\\"]; - for(var i = 0; i < invalidChars.length; i++) { - if(databaseName.indexOf(invalidChars[i]) != -1) throw new Error("database names cannot contain the character '" + invalidChars[i] + "'"); - } -} - -/** - * @ignore - */ -inherits(Db, EventEmitter); - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the index information or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.open = function(callback) { - var self = this; - - // Check that the user has not called this twice - if(this.openCalled) { - // Close db - this.close(); - // Throw error - throw new Error("db object already connecting, open cannot be called multiple times"); - } - - // If we have a specified read preference - if(this.readPreference != null) this.serverConfig.setReadPreference(this.readPreference); - - // Set that db has been opened - this.openCalled = true; - - // Set the status of the server - self._state = 'connecting'; - // Set up connections - if(self.serverConfig instanceof Server || self.serverConfig instanceof ReplSet || self.serverConfig instanceof Mongos) { - self.serverConfig.connect(self, {firstCall: true}, function(err, result) { - if(err != null) { - // Set that db has been closed - self.openCalled = false; - // Return error from connection - return callback(err, null); - } - // Set the status of the server - self._state = 'connected'; - // If we have queued up commands execute a command to trigger replays - if(self.commands.length > 0) _execute_queued_command(self); - // Callback - return callback(null, self); - }); - } else { - return callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null); - } -}; - -// Execute any baked up commands -var _execute_queued_command = function(self) { - // Execute any backed up commands - processor(function() { - // Execute any backed up commands - while(self.commands.length > 0) { - // Fetch the command - var command = self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(self, command['db_command'], command['options'], command['callback']); - } - } - }); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -Db.prototype.db = function(dbName) { - // Copy the options and add out internal override of the not shared flag - var options = {}; - for(var key in this.options) { - options[key] = this.options[key]; - } - - // Add override flag - options['override_used_flag'] = true; - // Create a new db instance - var newDbInstance = new Db(dbName, this.serverConfig, options); - //copy over any auths, we may need them for reconnecting - if (this.serverConfig.db) { - newDbInstance.auths = this.serverConfig.db.auths; - } - // Add the instance to the list of approved db instances - var allServerInstances = this.serverConfig.allServerInstances(); - // Add ourselves to all server callback instances - for(var i = 0; i < allServerInstances.length; i++) { - var server = allServerInstances[i]; - server.dbInstances.push(newDbInstance); - } - // Return new db object - return newDbInstance; -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Boolean} [forceClose] connection can never be reused. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.close = function(forceClose, callback) { - var self = this; - // Ensure we force close all connections - this._applicationClosed = false; - - if(typeof forceClose == 'function') { - callback = forceClose; - } else if(typeof forceClose == 'boolean') { - this._applicationClosed = forceClose; - } - - // Remove all listeners and close the connection - this.serverConfig.close(function(err, result) { - // Emit the close event - if(typeof callback !== 'function') self.emit("close"); - - // Emit close event across all db instances sharing the sockets - var allServerInstances = self.serverConfig.allServerInstances(); - // Fetch the first server instance - if(Array.isArray(allServerInstances) && allServerInstances.length > 0) { - var server = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(server.dbInstances) && server.dbInstances.length > 1) { - for(var i = 0; i < server.dbInstances.length; i++) { - var dbInstance = server.dbInstances[i]; - // Check if it's our current db instance and skip if it is - if(dbInstance.databaseName !== self.databaseName && dbInstance.tag !== self.tag) { - server.dbInstances[i].emit("close"); - } - } - } - } - - // Remove all listeners - self.removeAllEventListeners(); - // You can reuse the db as everything is shut down - self.openCalled = false; - // If we have a callback call it - if(callback) callback(err, result); - }); -}; - -/** - * Access the Admin database - * - * @param {Function} [callback] returns the results. - * @return {Admin} the admin db object. - * @api public - */ -Db.prototype.admin = function(callback) { - if(callback == null) return new Admin(this); - callback(null, new Admin(this)); -}; - -/** - * Returns a cursor to all the collection information. - * - * @param {String} [collectionName] the collection name we wish to retrieve the information from. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the options or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionsInfo = function(collectionName, callback) { - if(callback == null && typeof collectionName == 'function') { callback = collectionName; collectionName = null; } - // Create selector - var selector = {}; - // If we are limiting the access to a specific collection name - if(collectionName != null) selector.name = this.databaseName + "." + collectionName; - - // Return Cursor - // callback for backward compatibility - if(callback) { - callback(null, new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector)); - } else { - return new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector); - } -}; - -/** - * Get the list of all collection names for the specified db - * - * Options - * - **namesOnly** {String, default:false}, Return only the full collection namespace. - * - * @param {String} [collectionName] the collection name we wish to filter by. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection names or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionNames = function(collectionName, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - collectionName = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure no breaking behavior - if(collectionName != null && typeof collectionName == 'object') { - options = collectionName; - collectionName = null; - } - - // Let's make our own callback to reuse the existing collections info method - self.collectionsInfo(collectionName, function(err, cursor) { - if(err != null) return callback(err, null); - - cursor.toArray(function(err, documents) { - if(err != null) return callback(err, null); - - // List of result documents that have been filtered - var filtered_documents = documents.filter(function(document) { - return !(document.name.indexOf(self.databaseName) == -1 || document.name.indexOf('$') != -1); - }); - - // If we are returning only the names - if(options.namesOnly) { - filtered_documents = filtered_documents.map(function(document) { return document.name }); - } - - // Return filtered items - callback(null, filtered_documents); - }); - }); -}; - -/** - * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you can - * can use it without a callback in the following way. var collection = db.collection('mycollection'); - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if the collection does not exist - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collection = function(collectionName, options, callback) { - var self = this; - if(typeof options === "function") { callback = options; options = {}; } - // Execute safe - - if(options && (options.strict)) { - self.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - if(collections.length == 0) { - return callback(new Error("Collection " + collectionName + " does not exist. Currently in safe mode."), null); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - }); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - if(callback == null) { - throw err; - } else { - return callback(err, null); - } - } - - // If we have no callback return collection object - return callback == null ? collection : callback(null, collection); - } -}; - -/** - * Fetch all collections for the current db. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collections or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collections = function(callback) { - var self = this; - // Let's get the collection names - self.collectionNames(function(err, documents) { - if(err != null) return callback(err, null); - var collections = []; - documents.forEach(function(document) { - collections.push(new Collection(self, document.name.replace(self.databaseName + ".", ''), self.pkFactory)); - }); - // Return the collection objects - callback(null, collections); - }); -}; - -/** - * Evaluate javascript on the server - * - * Options - * - **nolock** {Boolean, default:false}, Tell MongoDB not to block on the evaulation of the javascript. - * - * @param {Code} code javascript to execute on server. - * @param {Object|Array} [parameters] the parameters for the call. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from eval or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.eval = function(code, parameters, options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - parameters = args.length ? args.shift() : parameters; - options = args.length ? args.shift() : {}; - - var finalCode = code; - var finalParameters = []; - // If not a code object translate to one - if(!(finalCode instanceof this.bsonLib.Code)) { - finalCode = new this.bsonLib.Code(finalCode); - } - - // Ensure the parameters are correct - if(parameters != null && parameters.constructor != Array && typeof parameters !== 'function') { - finalParameters = [parameters]; - } else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') { - finalParameters = parameters; - } - - // Create execution selector - var selector = {'$eval':finalCode, 'args':finalParameters}; - // Check if the nolock parameter is passed in - if(options['nolock']) { - selector['nolock'] = options['nolock']; - } - - // Set primary read preference - options.readPreference = ReadPreference.PRIMARY; - - // Execute the eval - this.collection(DbCommand.SYSTEM_COMMAND_COLLECTION).findOne(selector, options, function(err, result) { - if(err) return callback(err); - - if(result && result.ok == 1) { - callback(null, result.retval); - } else if(result) { - callback(new Error("eval failed: " + result.errmsg), null); return; - } else { - callback(err, result); - } - }); -}; - -/** - * Dereference a dbref, against a db - * - * @param {DBRef} dbRef db reference object we wish to resolve. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dereference or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dereference = function(dbRef, callback) { - var db = this; - // If we have a db reference then let's get the db first - if(dbRef.db != null) db = this.db(dbRef.db); - // Fetch the collection and find the reference - var collection = db.collection(dbRef.namespace); - collection.findOne({'_id':dbRef.oid}, function(err, result) { - callback(err, result); - }); -}; - -/** - * Logout user from server, fire off on all connections and remove all auth info - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.logout = function(options, callback) { - var self = this; - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Number of connections we need to logout from - var numberOfConnections = this.serverConfig.allRawConnections().length; - - // Let's generate the logout command object - var logoutCommand = DbCommand.logoutCommand(self, {logout:1}, options); - self._executeQueryCommand(logoutCommand, {onAll:true}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - // Reset auth - self.auths = []; - // Handle any errors - if(err == null && result.documents[0].ok == 1) { - internalCallback(null, true); - } else { - err != null ? internalCallback(err, false) : internalCallback(new Error(result.documents[0].errmsg), false); - } - } - }); -} - -/** - * Authenticate a user against the server. - * - * Options - * - **authSource** {String}, The database that the credentials are for, - * different from the name of the current DB, for example admin - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authentication or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.authenticate = function(username, password, options, callback) { - var self = this; - - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - // the default db to authenticate against is 'this' - // if authententicate is called from a retry context, it may be another one, like admin - var authdb = options.authdb ? options.authdb : self.databaseName; - authdb = options.authSource ? options.authSource : authdb; - // Push the new auth if we have no previous record - - var numberOfConnections = 0; - var errorObject = null; - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = this.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - // Execute all four - this._executeQueryCommand(DbCommand.createGetNonceCommand(self), options, function(err, result, connection) { - // Execute on all the connections - if(err == null) { - // Nonce used to make authentication request with md5 hash - var nonce = result.documents[0].nonce; - // Execute command - self._executeQueryCommand(DbCommand.createAuthenticationCommand(self, username, password, nonce, authdb), {connection:connection}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Ensure we save any error - if(err) { - errorObject = err; - } else if(result.documents[0].err != null || result.documents[0].errmsg != null){ - errorObject = utils.toError(result.documents[0]); - } - - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - - if(errorObject == null && result.documents[0].ok == 1) { - // We authenticated correctly save the credentials - self.auths = [{'username':username, 'password':password, 'authdb': authdb}]; - // Return callback - internalCallback(errorObject, true); - } else { - internalCallback(errorObject, false); - } - } - }); - } - }); -}; - -/** - * Add a user to the database. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.addUser = function(username, password, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - errorOptions.w = errorOptions.w == null ? 1 : errorOptions.w; - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var userPassword = md5.digest('hex'); - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - // Check if we are inserting the first user - collection.count({}, function(err, count) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Check if the user exists and update i - collection.find({user: username}, {dbName: options['dbName']}).toArray(function(err, documents) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Add command keys - var commandOptions = errorOptions; - commandOptions.dbName = options['dbName']; - commandOptions.upsert = true; - - // We have a user, let's update the password or upsert if not - collection.update({user: username},{$set: {user: username, pwd: userPassword}}, commandOptions, function(err, results) { - if(count == 0 && err) { - callback(null, [{user:username, pwd:userPassword}]); - } else if(err) { - callback(err, null) - } else { - callback(null, [{user:username, pwd:userPassword}]); - } - }); - }); - }); -}; - -/** - * Remove a user from a database - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - collection.findOne({user: username}, {dbName: options['dbName']}, function(err, user) { - if(user != null) { - // Add command keys - var commandOptions = safe; - commandOptions.dbName = options['dbName']; - - collection.remove({user: username}, commandOptions, function(err, result) { - callback(err, true); - }); - } else { - callback(err, false); - } - }); -}; - -/** - * Creates a collection on a server pre-allocating space, need to create f.ex capped collections. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **capped** {Boolean, default:false}, create a capped collection. - * - **size** {Number}, the size of the capped collection in bytes. - * - **max** {Number}, the maximum number of documents in the capped collection. - * - **autoIndexId** {Boolean, default:true}, create an index on the _id field of the document, True by default on MongoDB 2.2 or higher off for version < 2.2. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if collection already exists - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : null; - var self = this; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Check if we have the name - this.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - var found = false; - collections.forEach(function(collection) { - if(collection.name == self.databaseName + "." + collectionName) found = true; - }); - - // If the collection exists either throw an exception (if db in safe mode) or return the existing collection - if(found && options && options.strict) { - return callback(new Error("Collection " + collectionName + " already exists. Currently in safe mode."), null); - } else if(found){ - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - - // Create a new collection and return it - self._executeQueryCommand(DbCommand.createCreateCollectionCommand(self, collectionName, options), {read:false, safe:safe}, function(err, result) { - var document = result.documents[0]; - // If we have no error let's return the collection - if(err == null && document.ok == 1) { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } else { - if (null == err) err = utils.toError(document); - callback(err, null); - } - }); - }); -}; - -/** - * Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server. - * - * @param {Object} selector the command hash to send to the server, ex: {ping:1}. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} - * @api public - */ -Db.prototype.command = function(selector, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Set up the options - var cursor = new Cursor(this - , new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, { - limit: -1, timeout: QueryCommand.OPTS_NO_CURSOR_TIMEOUT, dbName: options['dbName'] - }); - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Ensure only commands who support read Prefrences are exeuted otherwise override and use Primary - if(readPreference != false) { - if(selector['group'] || selector['aggregate'] || selector['collStats'] || selector['dbStats'] - || selector['count'] || selector['distinct'] || selector['geoNear'] || selector['geoSearch'] || selector['geoWalk'] - || (selector['mapreduce'] && selector.out == 'inline')) { - // Set the read preference - cursor.setReadPreference(readPreference); - } else { - cursor.setReadPreference(ReadPreference.PRIMARY); - } - } - - // Return the next object - cursor.nextObject(callback); -}; - -/** - * Drop a collection from the database, removing it permanently. New accesses will create a new collection. - * - * @param {String} collectionName the name of the collection we wish to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropCollection = function(collectionName, callback) { - var self = this; - callback || (callback = function(){}); - - // Drop the collection - this._executeQueryCommand(DbCommand.createDropCollectionCommand(this, collectionName), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, true); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Rename a collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} fromCollection the name of the current collection we wish to rename. - * @param {String} toCollection the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from renameCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - callback || (callback = function(){}); - // Execute the command, return the new renamed collection if successful - this._executeQueryCommand(DbCommand.createRenameCollectionCommand(this, fromCollection, toCollection, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, new Collection(self, toCollection, self.pkFactory)); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Return last error message for the given connection, note options can be combined. - * - * Options - * - **fsync** {Boolean, default:false}, option forces the database to fsync all files before returning. - * - **j** {Boolean, default:false}, awaits the journal commit before returning, > MongoDB 2.0. - * - **w** {Number}, until a write operation has been replicated to N servers. - * - **wtimeout** {Number}, number of miliseconds to wait before timing out. - * - * Connection Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Object} [connectionOptions] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from lastError or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.lastError = function(options, connectionOptions, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - connectionOptions = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetLastErrorCommand(options, this), connectionOptions, function(err, error) { - callback(err, error && error.documents); - }); -}; - -/** - * Legacy method calls. - * - * @ignore - * @api private - */ -Db.prototype.error = Db.prototype.lastError; -Db.prototype.lastStatus = Db.prototype.lastError; - -/** - * Return all errors up to the last time db reset_error_history was called. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from previousErrors or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.previousErrors = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetPreviousErrorsCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Runs a command on the database. - * @ignore - * @api private - */ -Db.prototype.executeDbCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, command_hash, options), options, callback); -}; - -/** - * Runs a command on the database as admin. - * @ignore - * @api private - */ -Db.prototype.executeDbAdminCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createAdminDbCommand(this, command_hash), options, callback); -}; - -/** - * Resets the error history of the mongo instance. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from resetErrorHistory or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.resetErrorHistory = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createResetErrorHistoryCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - // Default command options - var commandOptions = {}; - - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute insert command - this._executeInsertCommand(command, commandOptions, function(err, result) { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute insert command - var result = this._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, null); - } -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ensureIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Make sure we don't try to do a write concern without a callback - if(_hasWriteConcern(errorOptions) && callback == null) - throw new Error("Cannot use a writeConcern without a provided callback"); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - var index_name = command.documents[0].name; - - // Default command options - var commandOptions = {}; - // Check if the index allready exists - this.indexInformation(collectionName, function(err, collectionInfo) { - if(err != null) return callback(err, null); - - if(!collectionInfo[index_name]) { - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - if(typeof callback === 'function' - && commandOptions.w < 1 && !commandOptions.fsync && !commandOptions.journal) { - commandOptions.w = 1; - } - - self._executeInsertCommand(command, commandOptions, function(err, result) { - // Only callback if we have one specified - if(typeof callback === 'function') { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - } - }); - } else { - // Execute insert command - var result = self._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, index_name); - } - } else { - if(typeof callback === 'function') return callback(null, index_name); - } - }); -}; - -/** - * Returns the information available on allocated cursors. - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from cursorInfo or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.cursorInfo = function(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, {'cursorInfo':1}), options, function(err, result) { - callback(err, result.documents[0]); - }); -}; - -/** - * Drop an index on a collection. - * - * @param {String} collectionName the name of the collection where the command will drop an index. - * @param {String} indexName name of the index to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropIndex = function(collectionName, indexName, callback) { - this._executeQueryCommand(DbCommand.createDropIndexCommand(this, collectionName, indexName), callback); -}; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {String} collectionName the name of the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from reIndex or null if an error occured. - * @api public -**/ -Db.prototype.reIndex = function(collectionName, callback) { - this._executeQueryCommand(DbCommand.createReIndexCommand(this, collectionName), function(err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} collectionName the name of the collection. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from indexInformation or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.indexInformation = function(collectionName, options, callback) { - if(typeof callback === 'undefined') { - if(typeof options === 'undefined') { - callback = collectionName; - collectionName = null; - } else { - callback = options; - } - options = {}; - } - - // If we specified full information - var full = options['full'] == null ? false : options['full']; - // Build selector for the indexes - var selector = collectionName != null ? {ns: (this.databaseName + "." + collectionName)} : {}; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : ReadPreference.PRIMARY; - - // Iterate through all the fields of the index - this.collection(DbCommand.SYSTEM_INDEX_COLLECTION, function(err, collection) { - // Perform the find for the collection - collection.find(selector).setReadPreference(readPreference).toArray(function(err, indexes) { - if(err != null) return callback(err, null); - // Contains all the information - var info = {}; - - // if full defined just return all the indexes directly - if(full) return callback(null, indexes); - - // Process all the indexes - for(var i = 0; i < indexes.length; i++) { - var index = indexes[i]; - // Let's unpack the object - info[index.name] = []; - for(var name in index.key) { - info[index.name].push([name, index.key[name]]); - } - } - - // Return all the indexes - callback(null, info); - }); - }); -}; - -/** - * Drop a database. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropDatabase or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropDatabase = function(callback) { - var self = this; - - this._executeQueryCommand(DbCommand.createDropDatabaseCommand(this), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - callback(null, true); - } else { - if(err) { - callback(err, false); - } else { - callback(utils.toError(result.documents[0]), false); - } - } - }); -}; - -/** - * Get all the db statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from stats or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - dbStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.command(commandObject, options, callback); -} - -/** - * @ignore - */ -var __executeQueryCommand = function(self, db_command, options, callback) { - // Options unpacking - var read = options['read'] != null ? options['read'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var onAll = options['onAll'] != null ? options['onAll'] : false; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - - // Correct read preference to default primary if set to false, null or primary - if(!(typeof read == 'object') && read._type == 'ReadPreference') { - read = (read == null || read == 'primary' || read == false) ? ReadPreference.PRIMARY : read; - if(!ReadPreference.isValid(read)) return callback(new Error("Illegal readPreference mode specified, " + read)); - } else if(typeof read == 'object' && read._type == 'ReadPreference') { - if(!read.isValid()) return callback(new Error("Illegal readPreference mode specified, " + read.mode)); - } - - // If we have a read preference set and we are a mongos pass the read preference on to the mongos instance, - if(self.serverConfig.isMongos() && read != null && read != false) { - db_command.setMongosReadPreference(read); - } - - // If we got a callback object - if(typeof callback === 'function' && !onAll) { - // Override connection if we passed in a specific connection - var connection = specifiedConnection != null ? specifiedConnection : null; - - if(connection instanceof Error) return callback(connection, null); - - // Fetch either a reader or writer dependent on the specified read option if no connection - // was passed in - if(connection == null) { - connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - } - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error || connection['message'] != null) { - return callback(connection); - } - - // Exhaust Option - var exhaust = options.exhaust || false; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, exhaust, callback); - // Write the message out and handle any errors if there are any - connection.write(db_command, function(err) { - if(err != null) { - // Call the handler with an error - self.serverConfig._callHandler(db_command.getRequestId(), null, err); - } - }); - } else if(typeof callback === 'function' && onAll) { - var connections = self.serverConfig.allRawConnections(); - var numberOfEntries = connections.length; - // Go through all the connections - for(var i = 0; i < connections.length; i++) { - // Fetch a connection - var connection = connections[i]; - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, callback); - // Write the message out - connection.write(db_command, function(err) { - // Adjust the number of entries we need to process - numberOfEntries = numberOfEntries - 1; - // Remove listener - if(err != null) { - // Clean up listener and return error - self.serverConfig._removeHandler(db_command.getRequestId()); - } - - // No more entries to process callback with the error - if(numberOfEntries <= 0) { - callback(err); - } - }); - - // Update the db_command request id - db_command.updateRequestId(); - } - } else { - // Fetch either a reader or writer dependent on the specified read option - var connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - // Ensure we have a valid connection - if(connection == null || connection instanceof Error || connection['message'] != null) return null; - // Write the message out - connection.write(db_command, function(err) { - if(err != null) { - // Emit the error - self.emit("error", err); - } - }); - } -} - -/** - * @ignore - */ -var __retryCommandOnFailure = function(self, retryInMilliseconds, numberOfTimes, command, db_command, options, callback) { - if(this._state == 'connected' || this._state == 'disconnected') this._state = 'connecting'; - // Number of retries done - var numberOfRetriesDone = numberOfTimes; - // Retry function, execute once - var retryFunction = function(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback) { - _self.serverConfig.connect(_self, {}, function(err, result, _serverConfig) { - if(_options) delete _options['connection']; - - // Adjust the number of retries left - _numberOfRetriesDone = _numberOfRetriesDone - 1; - // Definitively restart - if(err != null && _numberOfRetriesDone > 0) { - _self._state = 'connecting'; - // Close the server config - _serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } else if(err != null && _numberOfRetriesDone <= 0) { - _self._state = 'disconnected'; - // Force close the current connections - _serverConfig.close(function(_err) { - // Force close the current connections - if(typeof _callback == 'function') _callback(err, null); - }); - } else if(err == null && _self.serverConfig.isConnected() == true && Array.isArray(_self.auths) && _self.auths.length > 0) { - _self._state = 'connected'; - // Get number of auths we need to execute - var numberOfAuths = _self.auths.length; - // Apply all auths - for(var i = 0; i < _self.auths.length; i++) { - _self.authenticate(_self.auths[i].username, _self.auths[i].password, {'authdb':_self.auths[i].authdb}, function(err, authenticated) { - numberOfAuths = numberOfAuths - 1; - - // If we have no more authentications to replay - if(numberOfAuths == 0) { - if(err != null || !authenticated) { - if(typeof _callback == 'function') _callback(err, null); - return; - } else { - // Execute command - command(_self, _db_command, _options, _callback); - // Execute all the commands - if(_self.commands.length > 0) _execute_queued_command(_self); - } - } - }); - } - } else if(err == null && _self.serverConfig.isConnected() == true) { - _self._state = 'connected'; - - // Execute command - command(_self, _db_command, _options, _callback); - - processor(function() { - // Execute any backed up commands - while(_self.commands.length > 0) { - // Fetch the command - var command = _self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(_self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(_self, command['db_command'], command['options'], command['callback']); - } - } - }); - } else { - _self._state = 'connecting'; - // Force close the current connections - _serverConfig.close(function(err) { - // _self.serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } - }); - }; - - // Execute function first time - retryFunction(self, numberOfRetriesDone, retryInMilliseconds, numberOfTimes, command, db_command, options, callback); -} - -/** - * Execute db query command (not safe) - * @ignore - * @api private - */ -Db.prototype._executeQueryCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - - // fast fail option used for HA, no retry - var failFast = options['failFast'] != null - ? options['failFast'] - : false; - - // Check if the user force closed the command - if(this._applicationClosed) { - var err = new Error("db closed by application"); - if('function' == typeof callback) { - return callback(err, null); - } else { - throw err; - } - } - - var config = this.serverConfig; - // If the pool is not connected, attemp to reconnect to send the message - if(this._state == 'connecting' && config.autoReconnect && !failFast) { - return processor(function() { - self.commands.push({ - type: 'query', - db_command: db_command, - options: options, - callback: callback - }); - }) - } - - if(!failFast && !config.isConnected(options.read) && config.autoReconnect - && (options.read == null - || options.read == false - || options.read == ReadPreference.PRIMARY - || config.checkoutReader(options.read) == null)) { - this._state = 'connecting'; - return __retryCommandOnFailure(this, - this.retryMiliSeconds, - this.numberOfRetries, - __executeQueryCommand, - db_command, - options, - callback); - } - - if(!config.isConnected(options.read) && !config.autoReconnect && callback) { - // Fire an error to the callback if we are not connected - // and don't reconnect. - return callback(new Error("no open connections"), null); - } - - __executeQueryCommand(self, db_command, options, function (err, result, conn) { - if(callback) callback(err, result, conn); - }); - -}; - -/** - * @ignore - */ -var __executeInsertCommand = function(self, db_command, options, callback) { - // Always checkout a writer for this kind of operations - var connection = self.serverConfig.checkoutWriter(); - // Get safe mode - var safe = options['safe'] != null ? options['safe'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - - // Ensure we have a valid connection - if(typeof callback === 'function') { - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - var errorOptions = _getWriteConcern(self, options, callback); - if(errorOptions.w > 0 || errorOptions.w == 'majority' || errorOptions.j || errorOptions.journal || errorOptions.fsync) { - // db command is now an array of commands (original command + lastError) - db_command = [db_command, DbCommand.createGetLastErrorCommand(safe, self)]; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command[1], raw, connection, callback); - } - } - - // If we have no callback and there is no connection - if(connection == null) return null; - if(connection instanceof Error && typeof callback == 'function') return callback(connection, null); - if(connection instanceof Error) return null; - if(connection == null && typeof callback == 'function') return callback(new Error("no primary server found"), null); - - // Write the message out - connection.write(db_command, function(err) { - // Return the callback if it's not a safe operation and the callback is defined - if(typeof callback === 'function' && (safe == null || safe == false)) { - // Perform the callback - callback(err, null); - } else if(typeof callback === 'function') { - // Call the handler with an error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, err); - } else if(typeof callback == 'function' && safe && safe.w == -1) { - // Call the handler with no error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, null); - } else if(!safe || safe.w == -1) { - self.emit("error", err); - } - }); -} - -/** - * Execute an insert Command - * @ignore - * @api private - */ -Db.prototype._executeInsertCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if(callback == null && typeof options === 'function') { - callback = options; - options = {}; - } - - // Ensure options are not null - options = options == null ? {} : options; - - // Check if the user force closed the command - if(this._applicationClosed) { - if(typeof callback == 'function') { - return callback(new Error("db closed by application"), null); - } else { - throw new Error("db closed by application"); - } - } - - // If the pool is not connected, attemp to reconnect to send the message - if(self._state == 'connecting' && this.serverConfig.autoReconnect) { - processor(function() { - self.commands.push({type:'insert', 'db_command':db_command, 'options':options, 'callback':callback}); - }) - } else if(!this.serverConfig.isConnected() && this.serverConfig.autoReconnect) { - this._state = 'connecting'; - // Retry command - __retryCommandOnFailure(this, this.retryMiliSeconds, this.numberOfRetries, __executeInsertCommand, db_command, options, callback); - } else if(!this.serverConfig.isConnected() && !this.serverConfig.autoReconnect && callback) { - // Fire an error to the callback if we are not connected and don't do reconnect - if(callback) callback(new Error("no open connections"), null); - } else { - __executeInsertCommand(self, db_command, options, callback); - } -} - -/** - * Update command is the same - * @ignore - * @api private - */ -Db.prototype._executeUpdateCommand = Db.prototype._executeInsertCommand; -/** - * Remove command is the same - * @ignore - * @api private - */ -Db.prototype._executeRemoveCommand = Db.prototype._executeInsertCommand; - -/** - * Wrap a Mongo error document into an Error instance. - * Deprecated. Use utils.toError instead. - * - * @ignore - * @api private - * @deprecated - */ -Db.prototype.wrap = utils.toError; - -/** - * Default URL - * - * @classconstant DEFAULT_URL - **/ -Db.DEFAULT_URL = 'mongodb://localhost:27017/default'; - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the db instance or null if an error occured. - * @return {null} - * @api public - */ -Db.connect = function(url, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = typeof args[args.length - 1] == 'function' ? args.pop() : null; - options = args.length ? args.shift() : null; - options = options || {}; - var serverOptions = options.server || {}; - var mongosOptions = options.mongos || {}; - var replSetServersOptions = options.replSet || options.replSetServers || {}; - var dbOptions = options.db || {}; - - // If callback is null throw an exception - if(callback == null) throw new Error("no callback function provided"); - - // Parse the string - var object = parse(url); - // Merge in any options for db in options object - if(dbOptions) { - for(var name in dbOptions) object.db_options[name] = dbOptions[name]; - } - - // Merge in any options for server in options object - if(serverOptions) { - for(var name in serverOptions) object.server_options[name] = serverOptions[name]; - } - - // Merge in any replicaset server options - if(replSetServersOptions) { - for(var name in replSetServersOptions) object.rs_options[name] = replSetServersOptions[name]; - } - - // Merge in any replicaset server options - if(mongosOptions) { - for(var name in mongosOptions) object.mongos_options[name] = mongosOptions[name]; - } - - // We need to ensure that the list of servers are only either direct members or mongos - // they cannot be a mix of monogs and mongod's - var totalNumberOfServers = object.servers.length; - var totalNumberOfMongosServers = 0; - var totalNumberOfMongodServers = 0; - var serverConfig = null; - var errorServers = {}; - - // Failure modes - if(object.servers.length == 0) throw new Error("connection string must contain at least one seed host"); - - // If we have no db setting for the native parser try to set the c++ one first - object.db_options.native_parser = _setNativeParser(object.db_options); - // If no auto_reconnect is set, set it to true as default for single servers - if(typeof object.server_options.auto_reconnect != 'boolean') { - object.server_options.auto_reconnect = true; - } - - // If we have more than a server, it could be replicaset or mongos list - // need to verify that it's one or the other and fail if it's a mix - // Connect to all servers and run ismaster - for(var i = 0; i < object.servers.length; i++) { - // Set up socket options - var _server_options = {poolSize:1, socketOptions:{connectTimeoutMS:1000}, auto_reconnect:false}; - - // Ensure we have ssl setup for the servers - if(object.rs_options.ssl) { - _server_options.ssl = object.rs_options.ssl; - _server_options.sslValidate = object.rs_options.sslValidate; - _server_options.sslCA = object.rs_options.sslCA; - _server_options.sslCert = object.rs_options.sslCert; - _server_options.sslKey = object.rs_options.sslKey; - _server_options.sslPass = object.rs_options.sslPass; - } else if(object.server_options.ssl) { - _server_options.ssl = object.server_options.ssl; - _server_options.sslValidate = object.server_options.sslValidate; - _server_options.sslCA = object.server_options.sslCA; - _server_options.sslCert = object.server_options.sslCert; - _server_options.sslKey = object.server_options.sslKey; - _server_options.sslPass = object.server_options.sslPass; - } - - // Set up the Server object - var _server = object.servers[i].domain_socket - ? new Server(object.servers[i].domain_socket, _server_options) - : new Server(object.servers[i].host, object.servers[i].port, _server_options); - - var connectFunction = function(__server) { - // Attempt connect - new Db(object.dbName, __server, {safe:false, native_parser:false}).open(function(err, db) { - // Update number of servers - totalNumberOfServers = totalNumberOfServers - 1; - // If no error do the correct checks - if(!err) { - // Close the connection - db.close(true); - var isMasterDoc = db.serverConfig.isMasterDoc; - // Check what type of server we have - if(isMasterDoc.setName) totalNumberOfMongodServers++; - if(isMasterDoc.msg && isMasterDoc.msg == "isdbgrid") totalNumberOfMongosServers++; - } else { - errorServers[__server.host + ":" + __server.port] = __server; - } - - if(totalNumberOfServers == 0) { - // If we have a mix of mongod and mongos, throw an error - if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) - return callback(new Error("cannot combine a list of replicaset seeds and mongos seeds")); - - if(totalNumberOfMongodServers == 0 && object.servers.length == 1) { - var obj = object.servers[0]; - serverConfig = obj.domain_socket ? - new Server(obj.domain_socket, object.server_options) - : new Server(obj.host, obj.port, object.server_options); - } else if(totalNumberOfMongodServers > 0 || totalNumberOfMongosServers > 0) { - var finalServers = object.servers - .filter(function(serverObj) { - return errorServers[serverObj.host + ":" + serverObj.port] == null; - }) - .map(function(serverObj) { - return new Server(serverObj.host, serverObj.port, object.server_options); - }); - // Clean out any error servers - errorServers = {}; - // Set up the final configuration - if(totalNumberOfMongodServers > 0) { - serverConfig = new ReplSet(finalServers, object.rs_options); - } else { - serverConfig = new Mongos(finalServers, object.mongos_options); - } - } - - if(serverConfig == null) return callback(new Error("Could not locate any valid servers in initial seed list")); - // Set up all options etc and connect to the database - _finishConnecting(serverConfig, object, options, callback) - } - }); - } - - // Wrap the context of the call - connectFunction(_server); - } -} - -var _setNativeParser = function(db_options) { - if(typeof db_options.native_parser == 'boolean') return db_options.native_parser; - - try { - require('bson').BSONNative.BSON; - return true; - } catch(err) { - return false; - } -} - -var _finishConnecting = function(serverConfig, object, options, callback) { - // Safe settings - var safe = {}; - // Build the safe parameter if needed - if(object.db_options.journal) safe.j = object.db_options.journal; - if(object.db_options.w) safe.w = object.db_options.w; - if(object.db_options.fsync) safe.fsync = object.db_options.fsync; - if(object.db_options.wtimeoutMS) safe.wtimeout = object.db_options.wtimeoutMS; - - // If we have a read Preference set - if(object.db_options.read_preference) { - var readPreference = new ReadPreference(object.db_options.read_preference); - // If we have the tags set up - if(object.db_options.read_preference_tags) - readPreference = new ReadPreference(object.db_options.read_preference, object.db_options.read_preference_tags); - // Add the read preference - object.db_options.readPreference = readPreference; - } - - // No safe mode if no keys - if(Object.keys(safe).length == 0) safe = false; - - // Add the safe object - object.db_options.safe = safe; - - // Set up the db options - var db = new Db(object.dbName, serverConfig, object.db_options); - - // Open the db - db.open(function(err, db){ - if(err == null && object.auth){ - // What db to authenticate against - var authentication_db = db; - if(object.db_options && object.db_options.authSource) { - authentication_db = db.db(object.db_options.authSource); - } - - // Authenticate - authentication_db.authenticate(object.auth.user, object.auth.password, function(err, success){ - if(success){ - callback(null, db); - } else { - if(db) db.close(); - callback(err ? err : new Error('Could not authenticate user ' + auth[0]), null); - } - }); - } else { - callback(err, db); - } - }); -} - -/** - * State of the db connection - * @ignore - */ -Object.defineProperty(Db.prototype, "state", { enumerable: true - , get: function () { - return this.serverConfig._serverState; - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(self.options.w != null || typeof self.options.j == 'boolean' || typeof self.options.journal == 'boolean' || typeof self.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.options); - } else if(self.safe.w != null || typeof self.safe.j == 'boolean' || typeof self.safe.journal == 'boolean' || typeof self.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.safe); - } else if(typeof self.safe == "boolean") { - finalOptions = {w: (self.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Legacy support - * - * @ignore - * @api private - */ -exports.connect = Db.connect; -exports.Db = Db; - -/** - * Remove all listeners to the db instance. - * @ignore - * @api private - */ -Db.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("parseError"); - this.removeAllListeners("poolReady"); - this.removeAllListeners("message"); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js deleted file mode 100644 index 572d144653c..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js +++ /dev/null @@ -1,213 +0,0 @@ -var Binary = require('bson').Binary, - ObjectID = require('bson').ObjectID; - -/** - * Class for representing a single chunk in GridFS. - * - * @class - * - * @param file {GridStore} The {@link GridStore} object holding this chunk. - * @param mongoObject {object} The mongo object representation of this chunk. - * - * @throws Error when the type of data field for {@link mongoObject} is not - * supported. Currently supported types for data field are instances of - * {@link String}, {@link Array}, {@link Binary} and {@link Binary} - * from the bson module - * - * @see Chunk#buildMongoObject - */ -var Chunk = exports.Chunk = function(file, mongoObject) { - if(!(this instanceof Chunk)) return new Chunk(file, mongoObject); - - this.file = file; - var self = this; - var mongoObjectFinal = mongoObject == null ? {} : mongoObject; - - this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id; - this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n; - this.data = new Binary(); - - if(mongoObjectFinal.data == null) { - } else if(typeof mongoObjectFinal.data == "string") { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data, 'binary', 0); - this.data = new Binary(buffer); - } else if(Array.isArray(mongoObjectFinal.data)) { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data.join(''), 'binary', 0); - this.data = new Binary(buffer); - } else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") { - this.data = mongoObjectFinal.data; - } else if(Buffer.isBuffer(mongoObjectFinal.data)) { - } else { - throw Error("Illegal chunk format"); - } - // Update position - this.internalPosition = 0; -}; - -/** - * Writes a data to this object and advance the read/write head. - * - * @param data {string} the data to write - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.write = function(data, callback) { - this.data.write(data, this.internalPosition); - this.internalPosition = this.data.length(); - if(callback != null) return callback(null, this); - return this; -}; - -/** - * Reads data and advances the read/write head. - * - * @param length {number} The length of data to read. - * - * @return {string} The data read if the given length will not exceed the end of - * the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.read = function(length) { - // Default to full read if no index defined - length = length == null || length == 0 ? this.length() : length; - - if(this.length() - this.internalPosition + 1 >= length) { - var data = this.data.read(this.internalPosition, length); - this.internalPosition = this.internalPosition + length; - return data; - } else { - return ''; - } -}; - -Chunk.prototype.readSlice = function(length) { - if ((this.length() - this.internalPosition) >= length) { - var data = null; - if (this.data.buffer != null) { //Pure BSON - data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length); - } else { //Native BSON - data = new Buffer(length); - length = this.data.readInto(data, this.internalPosition); - } - this.internalPosition = this.internalPosition + length; - return data; - } else { - return null; - } -}; - -/** - * Checks if the read/write head is at the end. - * - * @return {boolean} Whether the read/write head has reached the end of this - * chunk. - */ -Chunk.prototype.eof = function() { - return this.internalPosition == this.length() ? true : false; -}; - -/** - * Reads one character from the data of this chunk and advances the read/write - * head. - * - * @return {string} a single character data read if the the read/write head is - * not at the end of the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.getc = function() { - return this.read(1); -}; - -/** - * Clears the contents of the data in this chunk and resets the read/write head - * to the initial position. - */ -Chunk.prototype.rewind = function() { - this.internalPosition = 0; - this.data = new Binary(); -}; - -/** - * Saves this chunk to the database. Also overwrites existing entries having the - * same id as this chunk. - * - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.save = function(callback) { - var self = this; - - self.file.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) { - if(err) return callback(err); - - if(self.data.length() > 0) { - self.buildMongoObject(function(mongoObject) { - collection.insert(mongoObject, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - } else { - callback(null, self); - } - }); - }); -}; - -/** - * Creates a mongoDB object representation of this chunk. - * - * @param callback {function(Object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *

- *        {
- *          '_id' : , // {number} id for this chunk
- *          'files_id' : , // {number} foreign key to the file collection
- *          'n' : , // {number} chunk number
- *          'data' : , // {bson#Binary} the chunk data itself
- *        }
- *        
- * - * @see MongoDB GridFS Chunk Object Structure - */ -Chunk.prototype.buildMongoObject = function(callback) { - var mongoObject = {'_id': this.objectId, - 'files_id': this.file.fileId, - 'n': this.chunkNumber, - 'data': this.data}; - callback(mongoObject); -}; - -/** - * @return {number} the length of the data - */ -Chunk.prototype.length = function() { - return this.data.length(); -}; - -/** - * The position of the read/write head - * @name position - * @lends Chunk# - * @field - */ -Object.defineProperty(Chunk.prototype, "position", { enumerable: true - , get: function () { - return this.internalPosition; - } - , set: function(value) { - this.internalPosition = value; - } -}); - -/** - * The default chunk size - * @constant - */ -Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js deleted file mode 100644 index aa695b723cd..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js +++ /dev/null @@ -1,103 +0,0 @@ -var GridStore = require('./gridstore').GridStore, - ObjectID = require('bson').ObjectID; - -/** - * A class representation of a simple Grid interface. - * - * @class Represents the Grid. - * @param {Db} db A database instance to interact with. - * @param {String} [fsName] optional different root collection for GridFS. - * @return {Grid} - */ -function Grid(db, fsName) { - - if(!(this instanceof Grid)) return new Grid(db, fsName); - - this.db = db; - this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName; -} - -/** - * Puts binary data to the grid - * - * Options - * - **_id** {Any}, unique id for this file - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @param {Buffer} data buffer with Binary Data. - * @param {Object} [options] the options for the files. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.put = function(data, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // If root is not defined add our default one - options['root'] = options['root'] == null ? this.fsName : options['root']; - - // Return if we don't have a buffer object as data - if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null); - // Get filename if we are using it - var filename = options['filename'] || null; - // Get id if we are using it - var id = options['_id'] || null; - // Create gridstore - var gridStore = new GridStore(this.db, id, filename, "w", options); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - gridStore.write(data, function(err, result) { - if(err) return callback(err, null); - - gridStore.close(function(err, result) { - if(err) return callback(err, null); - callback(null, result); - }) - }) - }) -} - -/** - * Get binary data to the grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.get = function(id, callback) { - // Create gridstore - var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName}); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - // Return the data - gridStore.read(function(err, data) { - return callback(err, data) - }); - }) -} - -/** - * Delete file from grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.delete = function(id, callback) { - // Create gridstore - GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) { - if(err) return callback(err, false); - return callback(null, true); - }); -} - -exports.Grid = Grid; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js deleted file mode 100644 index 615b22ecda5..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js +++ /dev/null @@ -1,1476 +0,0 @@ -/** - * @fileOverview GridFS is a tool for MongoDB to store files to the database. - * Because of the restrictions of the object size the database can hold, a - * facility to split a file into several chunks is needed. The {@link GridStore} - * class offers a simplified api to interact with files while managing the - * chunks of split files behind the scenes. More information about GridFS can be - * found here. - */ -var Chunk = require('./chunk').Chunk, - DbCommand = require('../commands/db_command').DbCommand, - ObjectID = require('bson').ObjectID, - Buffer = require('buffer').Buffer, - fs = require('fs'), - timers = require('timers'), - util = require('util'), - inherits = util.inherits, - ReadStream = require('./readstream').ReadStream, - Stream = require('stream'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var REFERENCE_BY_FILENAME = 0, - REFERENCE_BY_ID = 1; - -/** - * A class representation of a file stored in GridFS. - * - * Modes - * - **"r"** - read only. This is the default mode. - * - **"w"** - write in truncate mode. Existing data will be overwriten. - * - **w+"** - write in edit mode. - * - * Options - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @class Represents the GridStore. - * @param {Db} db A database instance to interact with. - * @param {Any} [id] optional unique id for this file - * @param {String} [filename] optional filename for this file, no unique constrain on the field - * @param {String} mode set the mode for this file. - * @param {Object} options optional properties to specify. - * @return {GridStore} - */ -var GridStore = function GridStore(db, id, filename, mode, options) { - if(!(this instanceof GridStore)) return new GridStore(db, id, filename, mode, options); - - var self = this; - this.db = db; - - // Call stream constructor - if(typeof Stream == 'function') { - Stream.call(this); - } else { - // 0.4.X backward compatibility fix - Stream.Stream.call(this); - } - - // Handle options - if(typeof options === 'undefined') options = {}; - // Handle mode - if(typeof mode === 'undefined') { - mode = filename; - filename = undefined; - } else if(typeof mode == 'object') { - options = mode; - mode = filename; - filename = undefined; - } - - if(id instanceof ObjectID) { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } else if(typeof filename == 'undefined') { - this.referenceBy = REFERENCE_BY_FILENAME; - this.filename = id; - if (mode.indexOf('w') != null) { - this.fileId = new ObjectID(); - } - } else { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } - - // Set up the rest - this.mode = mode == null ? "r" : mode; - this.options = options == null ? {} : options; - this.root = this.options['root'] == null ? exports.GridStore.DEFAULT_ROOT_COLLECTION : this.options['root']; - this.position = 0; - // Set default chunk size - this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize']; -} - -/** - * Code for the streaming capabilities of the gridstore object - * Most code from Aaron heckmanns project https://github.com/aheckmann/gridfs-stream - * Modified to work on the gridstore object itself - * @ignore - */ -if(typeof Stream == 'function') { - GridStore.prototype = { __proto__: Stream.prototype } -} else { - // Node 0.4.X compatibility code - GridStore.prototype = { __proto__: Stream.Stream.prototype } -} - -// Move pipe to _pipe -GridStore.prototype._pipe = GridStore.prototype.pipe; - -/** - * Opens the file from the database and initialize this object. Also creates a - * new one if file does not exist. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an **{Error}** object and the second parameter will be null if an error occured. Otherwise, the first parameter will be null and the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.open = function(callback) { - if( this.mode != "w" && this.mode != "w+" && this.mode != "r"){ - callback(new Error("Illegal mode " + this.mode), null); - return; - } - - var self = this; - - if((self.mode == "w" || self.mode == "w+") && self.db.serverConfig.primary != null) { - // Get files collection - self.collection(function(err, collection) { - if(err) return callback(err); - - // Put index on filename - collection.ensureIndex([['filename', 1]], function(err, index) { - if(err) return callback(err); - - // Get chunk collection - self.chunkCollection(function(err, chunkCollection) { - if(err) return callback(err); - - // Ensure index on chunk collection - chunkCollection.ensureIndex([['files_id', 1], ['n', 1]], function(err, index) { - if(err) return callback(err); - _open(self, callback); - }); - }); - }); - }); - } else { - // Open the gridstore - _open(self, callback); - } -}; - -/** - * Hidding the _open function - * @ignore - * @api private - */ -var _open = function(self, callback) { - self.collection(function(err, collection) { - if(err!==null) { - callback(new Error("at collection: "+err), null); - return; - } - - // Create the query - var query = self.referenceBy == REFERENCE_BY_ID ? {_id:self.fileId} : {filename:self.filename}; - query = null == self.fileId && this.filename == null ? null : query; - - // Fetch the chunks - if(query != null) { - collection.find(query, function(err, cursor) { - if(err) return error(err); - - // Fetch the file - cursor.nextObject(function(err, doc) { - if(err) return error(err); - - // Check if the collection for the files exists otherwise prepare the new one - if(doc != null) { - self.fileId = doc._id; - self.filename = doc.filename; - self.contentType = doc.contentType; - self.internalChunkSize = doc.chunkSize; - self.uploadDate = doc.uploadDate; - self.aliases = doc.aliases; - self.length = doc.length; - self.metadata = doc.metadata; - self.internalMd5 = doc.md5; - } else if (self.mode != 'r') { - self.fileId = self.fileId == null ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - } else { - self.length = 0; - var txtId = self.fileId instanceof ObjectID ? self.fileId.toHexString() : self.fileId; - return error(new Error((self.referenceBy == REFERENCE_BY_ID ? txtId : self.filename) + " does not exist", self)); - } - - // Process the mode of the object - if(self.mode == "r") { - nthChunk(self, 0, function(err, chunk) { - if(err) return error(err); - self.currentChunk = chunk; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - }); - } else { - // Write only mode - self.fileId = null == self.fileId ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - - self.chunkCollection(function(err, collection2) { - if(err) return error(err); - - // No file exists set up write mode - if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - } - }); - - // only pass error to callback once - function error (err) { - if(error.err) return; - callback(error.err = err); - } -}; - -/** - * Stores a file from the file system to the GridFS database. - * - * @param {String|Buffer|FileHandle} file the file to store. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.writeFile = function (file, callback) { - var self = this; - if (typeof file === 'string') { - fs.open(file, 'r', 0666, function (err, fd) { - if(err) return callback(err); - self.writeFile(fd, callback); - }); - return; - } - - self.open(function (err, self) { - if(err) return callback(err); - - fs.fstat(file, function (err, stats) { - if(err) return callback(err); - - var offset = 0; - var index = 0; - var numberOfChunksLeft = Math.min(stats.size / self.chunkSize); - - // Write a chunk - var writeChunk = function() { - fs.read(file, self.chunkSize, offset, 'binary', function(err, data, bytesRead) { - if(err) return callback(err); - - offset = offset + bytesRead; - - // Create a new chunk for the data - var chunk = new Chunk(self, {n:index++}); - chunk.write(data, function(err, chunk) { - if(err) return callback(err); - - chunk.save(function(err, result) { - if(err) return callback(err); - - self.position = self.position + data.length; - - // Point to current chunk - self.currentChunk = chunk; - - if(offset >= stats.size) { - fs.close(file); - self.close(callback); - } else { - return processor(writeChunk); - } - }); - }); - }); - } - - // Process the first write - processor(writeChunk); - }); - }); -}; - -/** - * Writes some data. This method will work properly only if initialized with mode - * "w" or "w+". - * - * @param string {string} The data to write. - * @param close {boolean=false} opt_argument Closes this file after writing if - * true. - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - * - * @ignore - * @api private - */ -var writeBuffer = function(self, buffer, close, callback) { - if(typeof close === "function") { callback = close; close = null; } - var finalClose = (close == null) ? false : close; - - if(self.mode[0] != "w") { - callback(new Error((self.referenceBy == REFERENCE_BY_ID ? self.toHexString() : self.filename) + " not opened for writing"), null); - } else { - if(self.currentChunk.position + buffer.length >= self.chunkSize) { - // Write out the current Chunk and then keep writing until we have less data left than a chunkSize left - // to a new chunk (recursively) - var previousChunkNumber = self.currentChunk.chunkNumber; - var leftOverDataSize = self.chunkSize - self.currentChunk.position; - var firstChunkData = buffer.slice(0, leftOverDataSize); - var leftOverData = buffer.slice(leftOverDataSize); - // A list of chunks to write out - var chunksToWrite = [self.currentChunk.write(firstChunkData)]; - // If we have more data left than the chunk size let's keep writing new chunks - while(leftOverData.length >= self.chunkSize) { - // Create a new chunk and write to it - var newChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - var firstChunkData = leftOverData.slice(0, self.chunkSize); - leftOverData = leftOverData.slice(self.chunkSize); - // Update chunk number - previousChunkNumber = previousChunkNumber + 1; - // Write data - newChunk.write(firstChunkData); - // Push chunk to save list - chunksToWrite.push(newChunk); - } - - // Set current chunk with remaining data - self.currentChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - // If we have left over data write it - if(leftOverData.length > 0) self.currentChunk.write(leftOverData); - - // Update the position for the gridstore - self.position = self.position + buffer.length; - // Total number of chunks to write - var numberOfChunksToWrite = chunksToWrite.length; - // Write out all the chunks and then return - for(var i = 0; i < chunksToWrite.length; i++) { - var chunk = chunksToWrite[i]; - chunk.save(function(err, result) { - if(err) return callback(err); - - numberOfChunksToWrite = numberOfChunksToWrite - 1; - - if(numberOfChunksToWrite <= 0) { - return callback(null, self); - } - }) - } - } else { - // Update the position for the gridstore - self.position = self.position + buffer.length; - // We have less data than the chunk size just write it and callback - self.currentChunk.write(buffer); - callback(null, self); - } - } -}; - -/** - * Creates a mongoDB object representation of this object. - * - * @param callback {function(object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *

- *        {
- *          '_id' : , // {number} id for this file
- *          'filename' : , // {string} name for this file
- *          'contentType' : , // {string} mime type for this file
- *          'length' : , // {number} size of this file?
- *          'chunksize' : , // {number} chunk size used by this file
- *          'uploadDate' : , // {Date}
- *          'aliases' : , // {array of string}
- *          'metadata' : , // {string}
- *        }
- *        
- * - * @ignore - * @api private - */ -var buildMongoObject = function(self, callback) { - // // Keeps the final chunk number - // var chunkNumber = 0; - // var previousChunkSize = 0; - // // Get the correct chunk Number, if we have an empty chunk return the previous chunk number - // if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) { - // chunkNumber = self.currentChunk.chunkNumber - 1; - // } else { - // chunkNumber = self.currentChunk.chunkNumber; - // previousChunkSize = self.currentChunk.position; - // } - - // // Calcuate the length - // var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0; - var mongoObject = { - '_id': self.fileId, - 'filename': self.filename, - 'contentType': self.contentType, - 'length': self.position ? self.position : 0, - 'chunkSize': self.chunkSize, - 'uploadDate': self.uploadDate, - 'aliases': self.aliases, - 'metadata': self.metadata - }; - - var md5Command = {filemd5:self.fileId, root:self.root}; - self.db.command(md5Command, function(err, results) { - mongoObject.md5 = results.md5; - callback(mongoObject); - }); -}; - -/** - * Saves this file to the database. This will overwrite the old entry if it - * already exists. This will work properly only if mode was initialized to - * "w" or "w+". - * - * @param {Function} callback this will be called after executing this method. Passes an **{Error}** object to the first parameter and null to the second if an error occured. Otherwise, passes null to the first and a reference to this object to the second. - * @return {null} - * @api public - */ -GridStore.prototype.close = function(callback) { - var self = this; - - if(self.mode[0] == "w") { - if(self.currentChunk != null && self.currentChunk.position > 0) { - self.currentChunk.save(function(err, chunk) { - if(err) return callback(err); - - self.collection(function(err, files) { - if(err) return callback(err); - - // Build the mongo object - if(self.uploadDate != null) { - files.remove({'_id':self.fileId}, {safe:true}, function(err, collection) { - if(err) return callback(err); - - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } else { - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - } - }); - }); - } else { - self.collection(function(err, files) { - if(err) return callback(err); - - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } - } else if(self.mode[0] == "r") { - callback(null, null); - } else { - callback(new Error("Illegal mode " + self.mode), null); - } -}; - -/** - * Gets the nth chunk of this file. - * - * @param chunkNumber {number} The nth chunk to retrieve. - * @param callback {function(*, Chunk|object)} This will be called after - * executing this method. null will be passed to the first parameter while - * a new {@link Chunk} instance will be passed to the second parameter if - * the chunk was found or an empty object {} if not. - * - * @ignore - * @api private - */ -var nthChunk = function(self, chunkNumber, callback) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.find({'files_id':self.fileId, 'n':chunkNumber}, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, chunk) { - if(err) return callback(err); - - var finalChunk = chunk == null ? {} : chunk; - callback(null, new Chunk(self, finalChunk)); - }); - }); - }); -}; - -/** - * - * @ignore - * @api private - */ -GridStore.prototype._nthChunk = function(chunkNumber, callback) { - nthChunk(this, chunkNumber, callback); -} - -/** - * @return {Number} The last chunk number of this file. - * - * @ignore - * @api private - */ -var lastChunkNumber = function(self) { - return Math.floor(self.length/self.chunkSize); -}; - -/** - * Retrieve this file's chunks collection. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.chunkCollection = function(callback) { - this.db.collection((this.root + ".chunks"), callback); -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param callback {function(*, boolean)} This will be called after this method - * executes. Passes null to the first and true to the second argument. - * - * @ignore - * @api private - */ -var deleteChunks = function(self, callback) { - if(self.fileId != null) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err, false); - collection.remove({'files_id':self.fileId}, {safe:true}, function(err, result) { - if(err) return callback(err, false); - callback(null, true); - }); - }); - } else { - callback(null, true); - } -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param {Function} callback this will be called after this method executes. Passes null to the first and true to the second argument. - * @return {null} - * @api public - */ -GridStore.prototype.unlink = function(callback) { - var self = this; - deleteChunks(this, function(err) { - if(err!==null) { - err.message = "at deleteChunks: " + err.message; - return callback(err); - } - - self.collection(function(err, collection) { - if(err!==null) { - err.message = "at collection: " + err.message; - return callback(err); - } - - collection.remove({'_id':self.fileId}, {safe:true}, function(err) { - callback(err, self); - }); - }); - }); -}; - -/** - * Retrieves the file collection associated with this object. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.collection = function(callback) { - this.db.collection(this.root + ".files", callback); -}; - -/** - * Reads the data of this file. - * - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Function} callback This will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.prototype.readlines = function(separator, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - separator = args.length ? args.shift() : "\n"; - - this.read(function(err, data) { - if(err) return callback(err); - - var items = data.toString().split(separator); - items = items.length > 0 ? items.splice(0, items.length - 1) : []; - for(var i = 0; i < items.length; i++) { - items[i] = items[i] + separator; - } - - callback(null, items); - }); -}; - -/** - * Deletes all the chunks of this file in the database if mode was set to "w" or - * "w+" and resets the read/write head to the initial position. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.rewind = function(callback) { - var self = this; - - if(this.currentChunk.chunkNumber != 0) { - if(this.mode[0] == "w") { - deleteChunks(self, function(err, gridStore) { - if(err) return callback(err); - self.currentChunk = new Chunk(self, {'n': 0}); - self.position = 0; - callback(null, self); - }); - } else { - self.currentChunk(0, function(err, chunk) { - if(err) return callback(err); - self.currentChunk = chunk; - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - }); - } - } else { - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - } -}; - -/** - * Retrieves the contents of this file and advances the read/write head. Works with Buffers only. - * - * There are 3 signatures for this method: - * - * (callback) - * (length, callback) - * (length, buffer, callback) - * - * @param {Number} [length] the number of characters to read. Reads all the characters from the read/write head to the EOF if not specified. - * @param {String|Buffer} [buffer] a string to hold temporary data. This is used for storing the string data read so far when recursively calling this method. - * @param {Function} callback this will be called after this method is executed. null will be passed to the first parameter and a string containing the contents of the buffer concatenated with the contents read from this file will be passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.read = function(length, buffer, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - length = args.length ? args.shift() : null; - buffer = args.length ? args.shift() : null; - - // The data is a c-terminated string and thus the length - 1 - var finalLength = length == null ? self.length - self.position : length; - var finalBuffer = buffer == null ? new Buffer(finalLength) : buffer; - // Add a index to buffer to keep track of writing position or apply current index - finalBuffer._index = buffer != null && buffer._index != null ? buffer._index : 0; - - if((self.currentChunk.length() - self.currentChunk.position + finalBuffer._index) >= finalLength) { - var slice = self.currentChunk.readSlice(finalLength - finalBuffer._index); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update internal position - self.position = self.position + finalBuffer.length; - // Check if we don't have a file at all - if(finalLength == 0 && finalBuffer.length == 0) return callback(new Error("File does not exist"), null); - // Else return data - callback(null, finalBuffer); - } else { - var slice = self.currentChunk.readSlice(self.currentChunk.length() - self.currentChunk.position); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update index position - finalBuffer._index += slice.length; - - // Load next chunk and read more - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) return callback(err); - - if(chunk.length() > 0) { - self.currentChunk = chunk; - self.read(length, finalBuffer, callback); - } else { - if (finalBuffer._index > 0) { - callback(null, finalBuffer) - } else { - callback(new Error("no chunks found for file, possibly corrupt"), null); - } - } - }); - } -} - -/** - * Retrieves the position of the read/write head of this file. - * - * @param {Function} callback This gets called after this method terminates. null is passed to the first parameter and the position is passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.tell = function(callback) { - callback(null, this.position); -}; - -/** - * Moves the read/write head to a new location. - * - * There are 3 signatures for this method - * - * Seek Location Modes - * - **GridStore.IO_SEEK_SET**, **(default)** set the position from the start of the file. - * - **GridStore.IO_SEEK_CUR**, set the position from the current position in the file. - * - **GridStore.IO_SEEK_END**, set the position from the end of the file. - * - * @param {Number} [position] the position to seek to - * @param {Number} [seekLocation] seek mode. Use one of the Seek Location modes. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.seek = function(position, seekLocation, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - seekLocation = args.length ? args.shift() : null; - - var seekLocationFinal = seekLocation == null ? exports.GridStore.IO_SEEK_SET : seekLocation; - var finalPosition = position; - var targetPosition = 0; - - // console.dir(targetPosition) - - // Calculate the position - if(seekLocationFinal == exports.GridStore.IO_SEEK_CUR) { - targetPosition = self.position + finalPosition; - } else if(seekLocationFinal == exports.GridStore.IO_SEEK_END) { - targetPosition = self.length + finalPosition; - } else { - targetPosition = finalPosition; - } - - // Get the chunk - var newChunkNumber = Math.floor(targetPosition/self.chunkSize); - if(newChunkNumber != self.currentChunk.chunkNumber) { - var seekChunk = function() { - nthChunk(self, newChunkNumber, function(err, chunk) { - self.currentChunk = chunk; - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(err, self); - }); - }; - - if(self.mode[0] == 'w') { - self.currentChunk.save(function(err) { - if(err) return callback(err); - seekChunk(); - }); - } else { - seekChunk(); - } - } else { - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(null, self); - } -}; - -/** - * Verify if the file is at EOF. - * - * @return {Boolean} true if the read/write head is at the end of this file. - * @api public - */ -GridStore.prototype.eof = function() { - return this.position == this.length ? true : false; -}; - -/** - * Retrieves a single character from this file. - * - * @param {Function} callback this gets called after this method is executed. Passes null to the first parameter and the character read to the second or null to the second if the read/write head is at the end of the file. - * @return {null} - * @api public - */ -GridStore.prototype.getc = function(callback) { - var self = this; - - if(self.eof()) { - callback(null, null); - } else if(self.currentChunk.eof()) { - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - self.currentChunk = chunk; - self.position = self.position + 1; - callback(err, self.currentChunk.getc()); - }); - } else { - self.position = self.position + 1; - callback(null, self.currentChunk.getc()); - } -}; - -/** - * Writes a string to the file with a newline character appended at the end if - * the given string does not have one. - * - * @param {String} string the string to write. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.puts = function(string, callback) { - var finalString = string.match(/\n$/) == null ? string + "\n" : string; - this.write(finalString, callback); -}; - -/** - * Returns read stream based on this GridStore file - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @param {Boolean} autoclose if true current GridStore will be closed when EOF and 'close' event will be fired - * @return {null} - * @api public - */ -GridStore.prototype.stream = function(autoclose) { - return new ReadStream(autoclose, this); -}; - -/** -* The collection to be used for holding the files and chunks collection. -* -* @classconstant DEFAULT_ROOT_COLLECTION -**/ -GridStore.DEFAULT_ROOT_COLLECTION = 'fs'; - -/** -* Default file mime type -* -* @classconstant DEFAULT_CONTENT_TYPE -**/ -GridStore.DEFAULT_CONTENT_TYPE = 'binary/octet-stream'; - -/** -* Seek mode where the given length is absolute. -* -* @classconstant IO_SEEK_SET -**/ -GridStore.IO_SEEK_SET = 0; - -/** -* Seek mode where the given length is an offset to the current read/write head. -* -* @classconstant IO_SEEK_CUR -**/ -GridStore.IO_SEEK_CUR = 1; - -/** -* Seek mode where the given length is an offset to the end of the file. -* -* @classconstant IO_SEEK_END -**/ -GridStore.IO_SEEK_END = 2; - -/** - * Checks if a file exists in the database. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file to look for. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes true to the second if the file exists and false otherwise. - * @return {null} - * @api public - */ -GridStore.exist = function(db, fileIdObject, rootCollection, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - - // Fetch collection - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - db.collection(rootCollectionFinal + ".files", function(err, collection) { - if(err) return callback(err); - - // Build query - var query = (typeof fileIdObject == 'string' || Object.prototype.toString.call(fileIdObject) == '[object RegExp]' ) - ? {'filename':fileIdObject} - : {'_id':fileIdObject}; // Attempt to locate file - - collection.find(query, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, item) { - if(err) return callback(err); - callback(null, item == null ? false : true); - }); - }); - }); -}; - -/** - * Gets the list of files stored in the GridFS. - * - * @param {Db} db the database to query. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes an array of strings containing the names of the files. - * @return {null} - * @api public - */ -GridStore.list = function(db, rootCollection, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure we have correct values - if(rootCollection != null && typeof rootCollection == 'object') { - options = rootCollection; - rootCollection = null; - } - - // Check if we are returning by id not filename - var byId = options['id'] != null ? options['id'] : false; - // Fetch item - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - var items = []; - db.collection((rootCollectionFinal + ".files"), function(err, collection) { - if(err) return callback(err); - - collection.find(function(err, cursor) { - if(err) return callback(err); - - cursor.each(function(err, item) { - if(item != null) { - items.push(byId ? item._id : item.filename); - } else { - callback(err, items); - } - }); - }); - }); -}; - -/** - * Reads the contents of a file. - * - * This method has the following signatures - * - * (db, name, callback) - * (db, name, length, callback) - * (db, name, length, offset, callback) - * (db, name, length, offset, options, callback) - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {Number} [length] the size of data to read. - * @param {Number} [offset] the offset from the head of the file of which to start reading from. - * @param {Object} [options] the options for the file. - * @param {Function} callback this will be called after this method executes. A string with an error message will be passed to the first parameter when the length and offset combination exceeds the length of the file while an Error object will be passed if other forms of error occured, otherwise, a string is passed. The second parameter will contain the data read if successful or null if an error occured. - * @return {null} - * @api public - */ -GridStore.read = function(db, name, length, offset, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - length = args.length ? args.shift() : null; - offset = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - // Make sure we are not reading out of bounds - if(offset && offset >= gridStore.length) return callback("offset larger than size of file", null); - if(length && length > gridStore.length) return callback("length is larger than the size of the file", null); - if(offset && length && (offset + length) > gridStore.length) return callback("offset and length is larger than the size of the file", null); - - if(offset != null) { - gridStore.seek(offset, function(err, gridStore) { - if(err) return callback(err); - gridStore.read(length, callback); - }); - } else { - gridStore.read(length, callback); - } - }); -}; - -/** - * Reads the data of this file. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Object} [options] file options. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.readlines = function(db, name, separator, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - separator = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - var finalSeperator = separator == null ? "\n" : separator; - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - gridStore.readlines(finalSeperator, callback); - }); -}; - -/** - * Deletes the chunks and metadata information of a file from GridFS. - * - * @param {Db} db the database to interact with. - * @param {String|Array} names the name/names of the files to delete. - * @param {Object} [options] the options for the files. - * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.unlink = function(db, names, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : null; - - if(names.constructor == Array) { - var tc = 0; - for(var i = 0; i < names.length; i++) { - ++tc; - self.unlink(db, names[i], function(result) { - if(--tc == 0) { - callback(null, self); - } - }); - } - } else { - new GridStore(db, names, "w", options).open(function(err, gridStore) { - if(err) return callback(err); - deleteChunks(gridStore, function(err, result) { - if(err) return callback(err); - gridStore.collection(function(err, collection) { - if(err) return callback(err); - collection.remove({'_id':gridStore.fileId}, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - }); - }); - } -}; - -/** - * Returns the current chunksize of the file. - * - * @field chunkSize - * @type {Number} - * @getter - * @setter - * @property return number of bytes in the current chunkSize. - */ -Object.defineProperty(GridStore.prototype, "chunkSize", { enumerable: true - , get: function () { - return this.internalChunkSize; - } - , set: function(value) { - if(!(this.mode[0] == "w" && this.position == 0 && this.uploadDate == null)) { - this.internalChunkSize = this.internalChunkSize; - } else { - this.internalChunkSize = value; - } - } -}); - -/** - * The md5 checksum for this file. - * - * @field md5 - * @type {Number} - * @getter - * @setter - * @property return this files md5 checksum. - */ -Object.defineProperty(GridStore.prototype, "md5", { enumerable: true - , get: function () { - return this.internalMd5; - } -}); - -/** - * GridStore Streaming methods - * Handles the correct return of the writeable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "writable", { enumerable: true - , get: function () { - if(this._writeable == null) { - this._writeable = this.mode != null && this.mode.indexOf("w") != -1; - } - // Return the _writeable - return this._writeable; - } - , set: function(value) { - this._writeable = value; - } -}); - -/** - * Handles the correct return of the readable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "readable", { enumerable: true - , get: function () { - if(this._readable == null) { - this._readable = this.mode != null && this.mode.indexOf("r") != -1; - } - return this._readable; - } - , set: function(value) { - this._readable = value; - } -}); - -GridStore.prototype.paused; - -/** - * Handles the correct setting of encoding for the stream - * @ignore - */ -GridStore.prototype.setEncoding = fs.ReadStream.prototype.setEncoding; - -/** - * Handles the end events - * @ignore - */ -GridStore.prototype.end = function end(data) { - var self = this; - // allow queued data to write before closing - if(!this.writable) return; - this.writable = false; - - if(data) { - this._q.push(data); - } - - this.on('drain', function () { - self.close(function (err) { - if (err) return _error(self, err); - self.emit('close'); - }); - }); - - _flush(self); -} - -/** - * Handles the normal writes to gridstore - * @ignore - */ -var _writeNormal = function(self, data, close, callback) { - // If we have a buffer write it using the writeBuffer method - if(Buffer.isBuffer(data)) { - return writeBuffer(self, data, close, callback); - } else { - // Wrap the string in a buffer and write - return writeBuffer(self, new Buffer(data, 'binary'), close, callback); - } -} - -/** - * Writes some data. This method will work properly only if initialized with mode "w" or "w+". - * - * @param {String|Buffer} data the data to write. - * @param {Boolean} [close] closes this file after writing if set to true. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.write = function write(data, close, callback) { - // If it's a normal write delegate the call - if(typeof close == 'function' || typeof callback == 'function') { - return _writeNormal(this, data, close, callback); - } - - // Otherwise it's a stream write - var self = this; - if (!this.writable) { - throw new Error('GridWriteStream is not writable'); - } - - // queue data until we open. - if (!this._opened) { - // Set up a queue to save data until gridstore object is ready - this._q = []; - _openStream(self); - this._q.push(data); - return false; - } - - // Push data to queue - this._q.push(data); - _flush(this); - // Return write successful - return true; -} - -/** - * Handles the destroy part of a stream - * @ignore - */ -GridStore.prototype.destroy = function destroy() { - // close and do not emit any more events. queued data is not sent. - if(!this.writable) return; - this.readable = false; - if(this.writable) { - this.writable = false; - this._q.length = 0; - this.emit('close'); - } -} - -/** - * Handles the destroySoon part of a stream - * @ignore - */ -GridStore.prototype.destroySoon = function destroySoon() { - // as soon as write queue is drained, destroy. - // may call destroy immediately if no data is queued. - if(!this._q.length) { - return this.destroy(); - } - this._destroying = true; -} - -/** - * Handles the pipe part of the stream - * @ignore - */ -GridStore.prototype.pipe = function(destination, options) { - var self = this; - // Open the gridstore - this.open(function(err, result) { - if(err) _errorRead(self, err); - if(!self.readable) return; - // Set up the pipe - self._pipe(destination, options); - // Emit the stream is open - self.emit('open'); - // Read from the stream - _read(self); - }) -} - -/** - * Internal module methods - * @ignore - */ -var _read = function _read(self) { - if (!self.readable || self.paused || self.reading) { - return; - } - - self.reading = true; - var stream = self._stream = self.stream(); - stream.paused = self.paused; - - stream.on('data', function (data) { - if (self._decoder) { - var str = self._decoder.write(data); - if (str.length) self.emit('data', str); - } else { - self.emit('data', data); - } - }); - - stream.on('end', function (data) { - self.emit('end', data); - }); - - stream.on('error', function (data) { - _errorRead(self, data); - }); - - stream.on('close', function (data) { - self.emit('close', data); - }); - - self.pause = function () { - // native doesn't always pause. - // bypass its pause() method to hack it - self.paused = stream.paused = true; - } - - self.resume = function () { - if(!self.paused) return; - - self.paused = false; - stream.resume(); - self.readable = stream.readable; - } - - self.destroy = function () { - self.readable = false; - stream.destroy(); - } -} - -/** - * pause - * @ignore - */ -GridStore.prototype.pause = function pause () { - // Overridden when the GridStore opens. - this.paused = true; -} - -/** - * resume - * @ignore - */ -GridStore.prototype.resume = function resume () { - // Overridden when the GridStore opens. - this.paused = false; -} - -/** - * Internal module methods - * @ignore - */ -var _flush = function _flush(self, _force) { - if (!self._opened) return; - if (!_force && self._flushing) return; - self._flushing = true; - - // write the entire q to gridfs - if (!self._q.length) { - self._flushing = false; - self.emit('drain'); - - if(self._destroying) { - self.destroy(); - } - return; - } - - self.write(self._q.shift(), function (err, store) { - if (err) return _error(self, err); - self.emit('progress', store.position); - _flush(self, true); - }); -} - -var _openStream = function _openStream (self) { - if(self._opening == true) return; - self._opening = true; - - // Open the store - self.open(function (err, gridstore) { - if (err) return _error(self, err); - self._opened = true; - self.emit('open'); - _flush(self); - }); -} - -var _error = function _error(self, err) { - self.destroy(); - self.emit('error', err); -} - -var _errorRead = function _errorRead (self, err) { - self.readable = false; - self.emit('error', err); -} - -/** - * @ignore - * @api private - */ -exports.GridStore = GridStore; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js deleted file mode 100644 index 8ff99731ea0..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js +++ /dev/null @@ -1,193 +0,0 @@ -var Stream = require('stream').Stream, - timers = require('timers'), - util = require('util'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * ReadStream - * - * Returns a stream interface for the **file**. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @class Represents a GridFS File Stream. - * @param {Boolean} autoclose automatically close file when the stream reaches the end. - * @param {GridStore} cursor a cursor object that the stream wraps. - * @return {ReadStream} - */ -function ReadStream(autoclose, gstore) { - if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore); - Stream.call(this); - - this.autoclose = !!autoclose; - this.gstore = gstore; - - this.finalLength = gstore.length - gstore.position; - this.completedLength = 0; - this.currentChunkNumber = gstore.currentChunk.chunkNumber; - - this.paused = false; - this.readable = true; - this.pendingChunk = null; - this.executing = false; - - // Calculate the number of chunks - this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize); - - // This seek start position inside the current chunk - this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize); - - var self = this; - processor(function() { - self._execute(); - }); -}; - -/** - * Inherit from Stream - * @ignore - * @api private - */ -ReadStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -ReadStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -ReadStream.prototype.paused; - -/** - * @ignore - * @api private - */ -ReadStream.prototype._execute = function() { - if(this.paused === true || this.readable === false) { - return; - } - - var gstore = this.gstore; - var self = this; - // Set that we are executing - this.executing = true; - - var last = false; - var toRead = 0; - - if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) { - self.executing = false; - last = true; - } - - // Data setup - var data = null; - - // Read a slice (with seek set if none) - if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition); - this.seekStartPosition = 0; - } else { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length()); - } - - // Return the data - if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) { - self.currentChunkNumber = self.currentChunkNumber + 1; - self.completedLength += data.length; - self.pendingChunk = null; - self.emit("data", data); - } - - if(last === true) { - self.readable = false; - self.emit("end"); - - if(self.autoclose === true) { - if(gstore.mode[0] == "w") { - gstore.close(function(err, doc) { - if (err) { - self.emit("error", err); - return; - } - self.readable = false; - self.emit("close", doc); - }); - } else { - self.readable = false; - self.emit("close"); - } - } - } else { - gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) { - self.readable = false; - self.emit("error", err); - self.executing = false; - return; - } - - self.pendingChunk = chunk; - if(self.paused === true) { - self.executing = false; - return; - } - - gstore.currentChunk = self.pendingChunk; - self._execute(); - }); - } -}; - -/** - * Pauses this stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.pause = function() { - if(!this.executing) { - this.paused = true; - } -}; - -/** - * Destroys the stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.destroy = function() { - this.readable = false; - // Emit close event - this.emit("close"); -}; - -/** - * Resumes this stream. - * - * @ignore - * @api public - */ -ReadStream.prototype.resume = function() { - if(this.paused === false || !this.readable) { - return; - } - - this.paused = false; - var self = this; - processor(function() { - self._execute(); - }); -}; - -exports.ReadStream = ReadStream; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js deleted file mode 100644 index 6a2b72759dc..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js +++ /dev/null @@ -1,69 +0,0 @@ -try { - exports.BSONPure = require('bson').BSONPure; - exports.BSONNative = require('bson').BSONNative; -} catch(err) { - // do nothing -} - -[ 'commands/base_command' - , 'admin' - , 'collection' - , 'connection/read_preference' - , 'connection/connection' - , 'connection/server' - , 'connection/mongos' - , 'connection/repl_set' - , 'mongo_client' - , 'cursor' - , 'db' - , 'mongo_client' - , 'gridfs/grid' - , 'gridfs/chunk' - , 'gridfs/gridstore'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } - - // backwards compat - exports.ReplSetServers = exports.ReplSet; - - // Add BSON Classes - exports.Binary = require('bson').Binary; - exports.Code = require('bson').Code; - exports.DBRef = require('bson').DBRef; - exports.Double = require('bson').Double; - exports.Long = require('bson').Long; - exports.MinKey = require('bson').MinKey; - exports.MaxKey = require('bson').MaxKey; - exports.ObjectID = require('bson').ObjectID; - exports.Symbol = require('bson').Symbol; - exports.Timestamp = require('bson').Timestamp; - - // Add BSON Parser - exports.BSON = require('bson').BSONPure.BSON; - -}); - -// Get the Db object -var Db = require('./db').Db; -// Set up the connect function -var connect = Db.connect; -var obj = connect; -// Map all values to the exports value -for(var name in exports) { - obj[name] = exports[name]; -} - -// Add the pure and native backward compatible functions -exports.pure = exports.native = function() { - return obj; -} - -// Map all values to the exports value -for(var name in exports) { - connect[name] = exports[name]; -} - -// Set our exports to be the connect function -module.exports = connect; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js deleted file mode 100644 index f1f3a8da62b..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js +++ /dev/null @@ -1,116 +0,0 @@ -var Db = require('./db').Db; - -/** - * Create a new MongoClient instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a MongoClient - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function MongoClient(serverConfig, options) { - options = options == null ? {} : options; - // If no write concern is set set the default to w:1 - if(options != null && !options.journal && !options.w && !options.fsync) { - options.w = 1; - } - - // The internal db instance we are wrapping - this._db = new Db('test', serverConfig, options); -} - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the connected mongoclient or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.open = function(callback) { - // Self reference - var self = this; - - this._db.open(function(err, db) { - if(err) return callback(err, null); - callback(null, self); - }) -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the close method or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.close = function(callback) { - this._db.close(callback); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -MongoClient.prototype.db = function(dbName) { - return this._db.db(dbName); -} - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.connect = function(url, options, callback) { - if(typeof options == 'function') { - callback = options; - options = {}; - } - - Db.connect(url, options, function(err, db) { - if(err) return callback(err, null); - - if(db.options !== null && !db.options.safe && !db.options.journal - && !db.options.w && !db.options.fsync && typeof db.options.w != 'number' - && (db.options.safe == false && url.indexOf("safe=") == -1)) { - db.options.w = 1; - } - - // Return the db - callback(null, db); - }); -} - -exports.MongoClient = MongoClient; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js deleted file mode 100644 index 743618fa4c6..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js +++ /dev/null @@ -1,145 +0,0 @@ -var Long = require('bson').Long - , timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - Reply message from mongo db -**/ -var MongoReply = exports.MongoReply = function() { - this.documents = []; - this.index = 0; -}; - -MongoReply.prototype.parseHeader = function(binary_reply, bson) { - // Unpack the standard header first - this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the request id for this reply - this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the id of the request that triggered the response - this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // Skip op-code field - this.index = this.index + 4 + 4; - // Unpack the reply message - this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the cursor id (a 64 bit long integer) - var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - this.cursorId = new Long(low_bits, high_bits); - // Unpack the starting from - this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the number of objects returned - this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; -} - -MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) { - raw = raw == null ? false : raw; - // Just set a doc limit for deserializing - var docLimitSize = 1024*20; - - // If our message length is very long, let's switch to process.nextTick for messages - if(this.messageLength > docLimitSize) { - var batchSize = this.numberReturned; - this.documents = new Array(this.numberReturned); - - // Just walk down until we get a positive number >= 1 - for(var i = 50; i > 0; i--) { - if((this.numberReturned/i) >= 1) { - batchSize = i; - break; - } - } - - // Actual main creator of the processFunction setting internal state to control the flow - var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) { - var object_index = 0; - // Internal loop process that will use nextTick to ensure we yield some time - var processFunction = function() { - // Adjust batchSize if we have less results left than batchsize - if((_numberReturned - object_index) < _batchSize) { - _batchSize = _numberReturned - object_index; - } - - // If raw just process the entries - if(raw) { - // Iterate over the batch - for(var i = 0; i < _batchSize; i++) { - // Are we done ? - if(object_index <= _numberReturned) { - // Read the size of the bson object - var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - _self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize); - // Adjust binary index to point to next block of binary bson data - _self.index = _self.index + bsonObjectSize; - // Update number of docs parsed - object_index = object_index + 1; - } - } - } else { - try { - // Parse documents - _self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index); - // Adjust index - object_index = object_index + _batchSize; - } catch (err) { - return callback(err); - } - } - - // If we hav more documents process NextTick - if(object_index < _numberReturned) { - processor(processFunction); - } else { - callback(null); - } - } - - // Return the process function - return processFunction; - }(this, binary_reply, batchSize, this.numberReturned)(); - } else { - try { - // Let's unpack all the bson documents, deserialize them and store them - for(var object_index = 0; object_index < this.numberReturned; object_index++) { - // Read the size of the bson object - var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - if(raw) { - // Deserialize the object and add to the documents array - this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize)); - } else { - // Deserialize the object and add to the documents array - this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize))); - } - // Adjust binary index to point to next block of binary bson data - this.index = this.index + bsonObjectSize; - } - } catch(err) { - return callback(err); - } - - // No error return - callback(null); - } -} - -MongoReply.prototype.is_error = function(){ - if(this.documents.length == 1) { - return this.documents[0].ok == 1 ? false : true; - } - return false; -}; - -MongoReply.prototype.error_message = function() { - return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg; -}; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js b/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js deleted file mode 100644 index a67aca5172f..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Sort functions, Normalize and prepare sort parameters - */ -var formatSortValue = exports.formatSortValue = function(sortDirection) { - var value = ("" + sortDirection).toLowerCase(); - - switch (value) { - case 'ascending': - case 'asc': - case '1': - return 1; - case 'descending': - case 'desc': - case '-1': - return -1; - default: - throw new Error("Illegal sort clause, must be of the form " - + "[['field1', '(ascending|descending)'], " - + "['field2', '(ascending|descending)']]"); - } -}; - -var formattedOrderClause = exports.formattedOrderClause = function(sortValue) { - var orderBy = {}; - - if (Array.isArray(sortValue)) { - for(var i = 0; i < sortValue.length; i++) { - if(sortValue[i].constructor == String) { - orderBy[sortValue[i]] = 1; - } else { - orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]); - } - } - } else if(Object.prototype.toString.call(sortValue) === '[object Object]') { - orderBy = sortValue; - } else if (sortValue.constructor == String) { - orderBy[sortValue] = 1; - } else { - throw new Error("Illegal sort clause, must be of the form " + - "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"); - } - - return orderBy; -}; - -exports.encodeInt = function(value) { - var buffer = new Buffer(4); - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = value & 0xff; - return buffer; -} - -exports.encodeIntInPlace = function(value, buffer, index) { - buffer[index + 3] = (value >> 24) & 0xff; - buffer[index + 2] = (value >> 16) & 0xff; - buffer[index + 1] = (value >> 8) & 0xff; - buffer[index] = value & 0xff; -} - -exports.encodeCString = function(string) { - var buf = new Buffer(string, 'utf8'); - return [buf, new Buffer([0])]; -} - -exports.decodeUInt32 = function(array, index) { - return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24; -} - -// Decode the int -exports.decodeUInt8 = function(array, index) { - return array[index]; -} - -/** - * Context insensitive type checks - */ - -var toString = Object.prototype.toString; - -exports.isObject = function (arg) { - return '[object Object]' == toString.call(arg) -} - -exports.isArray = function (arg) { - return Array.isArray(arg) || - 'object' == typeof arg && '[object Array]' == toString.call(arg) -} - -exports.isDate = function (arg) { - return 'object' == typeof arg && '[object Date]' == toString.call(arg) -} - -exports.isRegExp = function (arg) { - return 'object' == typeof arg && '[object RegExp]' == toString.call(arg) -} - -/** - * Wrap a Mongo error document in an Error instance - * @ignore - * @api private - */ -exports.toError = function(error) { - if (error instanceof Error) return error; - - var msg = error.err || error.errmsg || error; - var e = new Error(msg); - e.name = 'MongoError'; - - // Get all object keys - var keys = typeof error == 'object' - ? Object.keys(error) - : []; - - for(var i = 0; i < keys.length; i++) { - e[keys[i]] = error[keys[i]]; - } - - return e; -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile deleted file mode 100644 index 77ce4e04085..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit - -all: clean node_gyp - -test: clean node_gyp - npm test - -node_gyp: clean - node-gyp configure build - -clean: - node-gyp clean - -browserify: - node_modules/.bin/onejs build browser_build/package.json browser_build/bson.js - -.PHONY: all diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md deleted file mode 100644 index 73892e2d19a..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md +++ /dev/null @@ -1 +0,0 @@ -A JS/C++ Bson parser for node, used in the MongoDB Native driver \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js deleted file mode 100644 index 45a11115484..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js +++ /dev/null @@ -1,130 +0,0 @@ -// var BSON = require('../../lib/mongodb').BSONNative.BSON, -// ObjectID = require('../../lib/mongodb').BSONNative.ObjectID, -// Code = require('../../lib/mongodb').BSONNative.Code, -// Long = require('../../lib/mongodb').BSONNative.Long, -// Binary = require('../../lib/mongodb').BSONNative.Binary, -// debug = require('util').debug, -// inspect = require('util').inspect, -// -// Long = require('../../lib/mongodb').Long, -// ObjectID = require('../../lib/mongodb').ObjectID, -// Binary = require('../../lib/mongodb').Binary, -// Code = require('../../lib/mongodb').Code, -// DBRef = require('../../lib/mongodb').DBRef, -// Symbol = require('../../lib/mongodb').Symbol, -// Double = require('../../lib/mongodb').Double, -// MaxKey = require('../../lib/mongodb').MaxKey, -// MinKey = require('../../lib/mongodb').MinKey, -// Timestamp = require('../../lib/mongodb').Timestamp; - - -// var BSON = require('../../lib/mongodb').BSONPure.BSON, -// ObjectID = require('../../lib/mongodb').BSONPure.ObjectID, -// Code = require('../../lib/mongodb').BSONPure.Code, -// Long = require('../../lib/mongodb').BSONPure.Long, -// Binary = require('../../lib/mongodb').BSONPure.Binary; - -var BSON = require('../lib/bson').BSONNative.BSON, - Long = require('../lib/bson').Long, - ObjectID = require('../lib/bson').ObjectID, - Binary = require('../lib/bson').Binary, - Code = require('../lib/bson').Code, - DBRef = require('../lib/bson').DBRef, - Symbol = require('../lib/bson').Symbol, - Double = require('../lib/bson').Double, - MaxKey = require('../lib/bson').MaxKey, - MinKey = require('../lib/bson').MinKey, - Timestamp = require('../lib/bson').Timestamp; - - // console.dir(require('../lib/bson')) - -var COUNT = 1000; -var COUNT = 100; - -var object = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - date: new Date(), - double: new Double(1.4), - id: new ObjectID(), - min: new MinKey(), - max: new MaxKey(), - symbol: new Symbol('hello'), - long: Long.fromNumber(100), - bin: new Binary(new Buffer(100)), - - subObject: { - moreText: "Bacon ipsum dolor sit amet cow pork belly rump ribeye pastrami andouille. Tail hamburger pork belly, drumstick flank salami t-bone sirloin pork chop ribeye ham chuck pork loin shankle. Ham fatback pork swine, sirloin shankle short loin andouille shank sausage meatloaf drumstick. Pig chicken cow bresaola, pork loin jerky meatball tenderloin brisket strip steak jowl spare ribs. Biltong sirloin pork belly boudin, bacon pastrami rump chicken. Jowl rump fatback, biltong bacon t-bone turkey. Turkey pork loin boudin, tenderloin jerky beef ribs pastrami spare ribs biltong pork chop beef.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly boudin shoulder ribeye pork chop brisket biltong short ribs. Salami beef pork belly, t-bone sirloin meatloaf tail jowl spare ribs. Sirloin biltong bresaola cow turkey. Biltong fatback meatball, bresaola tail shankle turkey pancetta ham ribeye flank bacon jerky pork chop. Boudin sirloin shoulder, salami swine flank jerky t-bone pork chop pork beef tongue. Bresaola ribeye jerky andouille. Ribeye ground round sausage biltong beef ribs chuck, shank hamburger chicken short ribs spare ribs tenderloin meatloaf pork loin." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string", - code: new Code("function() {}", {i:1}) -} - -// Number of objects -var numberOfObjects = 10000; -var bson = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -console.log("---------------------- 1") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - objectBSON = bson.serialize(object, null, true) -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -console.log("---------------------- 2") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - bson.deserialize(objectBSON); -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -// // Buffer With copies of the objectBSON -// var data = new Buffer(objectBSON.length * numberOfObjects); -// var index = 0; -// -// // Copy the buffer 1000 times to create a strea m of objects -// for(var i = 0; i < numberOfObjects; i++) { -// // Copy data -// objectBSON.copy(data, index); -// // Adjust index -// index = index + objectBSON.length; -// } -// -// // console.log("-----------------------------------------------------------------------------------") -// // console.dir(objectBSON) -// -// var x, start, end, j -// var objectBSON, objectJSON -// -// // Allocate the return array (avoid concatinating everything) -// var results = new Array(numberOfObjects); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// // var objects = BSON.deserializeStream(data, 0, numberOfObjects); -// // console.log("----------------------------------------------------------------------------------- 0") -// // var objects = BSON.deserialize(data); -// // console.log("----------------------------------------------------------------------------------- 1") -// // console.dir(objects) -// -// for (j=COUNT; --j>=0; ) { -// var nextIndex = BSON.deserializeStream(data, 0, numberOfObjects, results, 0); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectBSON.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectBSON.length)/1024)); -// -// // console.dir(nextIndex) -// // console.dir(results) - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp deleted file mode 100644 index 42445d325d7..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp +++ /dev/null @@ -1,17 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'bson', - 'sources': [ 'ext/bson.cc' ], - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js deleted file mode 100644 index e7a1c74fea3..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js +++ /dev/null @@ -1,4814 +0,0 @@ -var bson = (function(){ - - var pkgmap = {}, - global = {}, - nativeRequire = typeof require != 'undefined' && require, - lib, ties, main, async; - - function exports(){ return main(); }; - - exports.main = exports; - exports.module = module; - exports.packages = pkgmap; - exports.pkg = pkg; - exports.require = function require(uri){ return pkgmap.main.index.require(uri); }; - - - ties = {}; - - aliases = {}; - - - return exports; - -function join() { - return normalize(Array.prototype.join.call(arguments, "/")); -}; - -function normalize(path) { - var ret = [], parts = path.split('/'), cur, prev; - - var i = 0, l = parts.length-1; - for (; i <= l; i++) { - cur = parts[i]; - - if (cur === "." && prev !== undefined) continue; - - if (cur === ".." && ret.length && prev !== ".." && prev !== "." && prev !== undefined) { - ret.pop(); - prev = ret.slice(-1)[0]; - } else { - if (prev === ".") ret.pop(); - ret.push(cur); - prev = cur; - } - } - - return ret.join("/"); -}; - -function dirname(path) { - return path && path.substr(0, path.lastIndexOf("/")) || "."; -}; - -function findModule(workingModule, uri){ - var moduleId = join(dirname(workingModule.id), uri).replace(/\.js$/, ''), - moduleIndexId = join(moduleId, 'index'), - pkg = workingModule.pkg, - module; - - var i = pkg.modules.length, - id; - - while(i-->0){ - id = pkg.modules[i].id; - if(id==moduleId || id == moduleIndexId){ - module = pkg.modules[i]; - break; - } - } - - return module; -} - -function newRequire(callingModule){ - function require(uri){ - var module, pkg; - - if(/^\./.test(uri)){ - module = findModule(callingModule, uri); - } else if ( ties && ties.hasOwnProperty( uri ) ) { - return ties[uri]; - } else if ( aliases && aliases.hasOwnProperty( uri ) ) { - return require(aliases[uri]); - } else { - pkg = pkgmap[uri]; - - if(!pkg && nativeRequire){ - try { - pkg = nativeRequire(uri); - } catch (nativeRequireError) {} - - if(pkg) return pkg; - } - - if(!pkg){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module = pkg.index; - } - - if(!module){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module.parent = callingModule; - return module.call(); - }; - - - return require; -} - - -function module(parent, id, wrapper){ - var mod = { pkg: parent, id: id, wrapper: wrapper }, - cached = false; - - mod.exports = {}; - mod.require = newRequire(mod); - - mod.call = function(){ - if(cached) { - return mod.exports; - } - - cached = true; - - global.require = mod.require; - - mod.wrapper(mod, mod.exports, global, global.require); - return mod.exports; - }; - - if(parent.mainModuleId == mod.id){ - parent.index = mod; - parent.parents.length === 0 && ( main = mod.call ); - } - - parent.modules.push(mod); -} - -function pkg(/* [ parentId ...], wrapper */){ - var wrapper = arguments[ arguments.length - 1 ], - parents = Array.prototype.slice.call(arguments, 0, arguments.length - 1), - ctx = wrapper(parents); - - - pkgmap[ctx.name] = ctx; - - arguments.length == 1 && ( pkgmap.main = ctx ); - - return function(modules){ - var id; - for(id in modules){ - module(ctx, id, modules[id]); - } - }; -} - - -}(this)); - -bson.pkg(function(parents){ - - return { - 'name' : 'bson', - 'mainModuleId' : 'bson', - 'modules' : [], - 'parents' : parents - }; - -})({ 'binary': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - - -}, - - - -'binary_parser': function(module, exports, global, require, undefined){ - /** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; - -}, - - - -'bson': function(module, exports, global, require, undefined){ - var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; -}, - - - -'code': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; -}, - - - -'db_ref': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; -}, - - - -'double': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; -}, - - - -'float_parser': function(module, exports, global, require, undefined){ - // Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; -}, - - - -'index': function(module, exports, global, require, undefined){ - try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -}, - - - -'long': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; -}, - - - -'max_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; -}, - - - -'min_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; -}, - - - -'objectid': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; -}, - - - -'symbol': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; -}, - - - -'timestamp': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; -}, - - }); - - -if(typeof module != 'undefined' && module.exports ){ - module.exports = bson; - - if( !module.parent ){ - bson(); - } -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json deleted file mode 100644 index 3ebb58761c5..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ "name" : "bson" -, "description" : "A bson parser for node.js and the browser" -, "main": "../lib/bson/bson" -, "directories" : { "lib" : "../lib/bson" } -, "engines" : { "node" : ">=0.6.0" } -, "licenses" : [ { "type" : "Apache License, Version 2.0" - , "url" : "http://www.apache.org/licenses/LICENSE-2.0" } ] -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile deleted file mode 100644 index b1074623b37..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile +++ /dev/null @@ -1,333 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bson.target.mk)))),) - include bson.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/home/b/Desktop/countly/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/root/.node-gyp/0.10.11/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/root/.node-gyp/0.10.11" "-Dmodule_root_dir=/home/b/Desktop/countly/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../../root/.node-gyp/0.10.11/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d deleted file mode 100644 index 866c155bc23..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bson.node := rm -rf "Release/bson.node" && cp -af "Release/obj.target/bson.node" "Release/bson.node" diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d deleted file mode 100644 index a7317de71b7..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/bson.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m32 -Wl,-soname=bson.node -o Release/obj.target/bson.node -Wl,--start-group Release/obj.target/bson/ext/bson.o -Wl,--end-group diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d deleted file mode 100644 index 5cdc93f8392..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d +++ /dev/null @@ -1,28 +0,0 @@ -cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/root/.node-gyp/0.10.11/src -I/root/.node-gyp/0.10.11/deps/uv/include -I/root/.node-gyp/0.10.11/deps/v8/include -Wall -Wextra -Wno-unused-parameter -pthread -m32 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-tree-sink -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc -Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \ - /root/.node-gyp/0.10.11/deps/v8/include/v8.h \ - /root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/src/node_version.h \ - /root/.node-gyp/0.10.11/src/node_buffer.h ../ext/bson.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h -../ext/bson.cc: -/root/.node-gyp/0.10.11/deps/v8/include/v8.h: -/root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/src/node_version.h: -/root/.node-gyp/0.10.11/src/node_buffer.h: -../ext/bson.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o deleted file mode 100644 index a2bfc494436..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile deleted file mode 100644 index 90bf8247b39..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) bson diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk deleted file mode 100644 index 5359f669c3e..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk +++ /dev/null @@ -1,126 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bson -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti - -INCS_Debug := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-tree-sink - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti - -INCS_Release := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/ext/bson.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m32 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m32 - -LIBS := - -$(obj).target/bson.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/bson.node: LIBS := $(LIBS) -$(obj).target/bson.node: TOOLSET := $(TOOLSET) -$(obj).target/bson.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/bson.node -# Add target alias -.PHONY: bson -bson: $(builddir)/bson.node - -# Copy this to the executable output path. -$(builddir)/bson.node: TOOLSET := $(TOOLSET) -$(builddir)/bson.node: $(obj).target/bson.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/bson.node -# Short alias for building this executable. -.PHONY: bson.node -bson.node: $(obj).target/bson.node $(builddir)/bson.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bson.node - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi deleted file mode 100644 index 69c52b6eb0f..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi +++ /dev/null @@ -1,114 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 44, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/root/.node-gyp/0.10.11", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "pre": "", - "sign_git_tag": "", - "always_auth": "", - "user_agent": "node/v0.10.11 linux ia32", - "bin_links": "true", - "description": "true", - "fetch_retries": "2", - "init_version": "0.0.0", - "user": "", - "force": "", - "ignore": "", - "cache_min": "10", - "editor": "vi", - "rollback": "true", - "cache_max": "null", - "userconfig": "/root/.npmrc", - "coverage": "", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/root/tmp", - "userignorefile": "/root/.npmignore", - "yes": "", - "depth": "null", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/root/.npm", - "npaturl": "http://npat.npmjs.org/", - "searchsort": "name", - "version": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.11", - "tag": "latest", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/root/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "group": "", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "json": "" - } -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js deleted file mode 100644 index bb802384453..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js +++ /dev/null @@ -1,7 +0,0 @@ -require('one'); - -one('./package.json') - .tie('bson', BSON) - // .exclude('buffer') - .tie('buffer', {}) - .save('./browser_build/bson.js') \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile deleted file mode 100644 index 435999ee960..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc deleted file mode 100644 index 8a2ec8b7e7a..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc +++ /dev/null @@ -1,1006 +0,0 @@ -//=========================================================================== - -#include -#include -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -// this and the above block must be around the v8.h header otherwise -// v8 is not happy -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __sun - #include -#endif - -#include "bson.h" - -using namespace v8; -using namespace node; - -//=========================================================================== - -void DataStream::WriteObjectId(const Handle& object, const Handle& key) -{ - uint16_t buffer[12]; - object->Get(key)->ToString()->Write(buffer, 0, 12); - for(uint32_t i = 0; i < 12; ++i) - { - *p++ = (char) buffer[i]; - } -} - -void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...) -{ - va_list args; - va_start(args, format); - char* string = (char*) malloc(allocationSize); - vsprintf(string, format, args); - va_end(args); - - throw string; -} - -void DataStream::CheckKey(const Local& keyName) -{ - size_t keyLength = keyName->Utf8Length(); - if(keyLength == 0) return; - - char* keyStringBuffer = (char*) alloca(keyLength+1); - keyName->WriteUtf8(keyStringBuffer); - - if(keyStringBuffer[0] == '$') - { - ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer); - } - - if(strchr(keyStringBuffer, '.') != NULL) - { - ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer); - } -} - -template void BSONSerializer::SerializeDocument(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - Local object = bson->GetSerializeObject(value); - - // Get the object property names - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local propertyNames = object->GetPropertyNames(); - #else - Local propertyNames = object->GetOwnPropertyNames(); - #endif - - // Length of the property - int propertyLength = propertyNames->Length(); - for(int i = 0; i < propertyLength; ++i) - { - const Local& propertyName = propertyNames->Get(i)->ToString(); - if(checkKeys) this->CheckKey(propertyName); - - const Local& propertyValue = object->Get(propertyName); - - if(serializeFunctions || !propertyValue->IsFunction()) - { - void* typeLocation = this->BeginWriteType(); - this->WriteString(propertyName); - SerializeValue(typeLocation, propertyValue); - } - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -template void BSONSerializer::SerializeArray(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - - Local array = Local::Cast(value->ToObject()); - uint32_t arrayLength = array->Length(); - - for(uint32_t i = 0; i < arrayLength; ++i) - { - void* typeLocation = this->BeginWriteType(); - this->WriteUInt32String(i); - SerializeValue(typeLocation, array->Get(i)); - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes. -// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths) -// and ensures that there is always consistency between bytes counted and bytes written by design. -template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value) -{ - if(value->IsNumber()) - { - double doubleValue = value->NumberValue(); - int intValue = (int) doubleValue; - if(intValue == doubleValue) - { - this->CommitType(typeLocation, BSON_TYPE_INT); - this->WriteInt32(intValue); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(doubleValue); - } - } - else if(value->IsString()) - { - this->CommitType(typeLocation, BSON_TYPE_STRING); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsBoolean()) - { - this->CommitType(typeLocation, BSON_TYPE_BOOLEAN); - this->WriteBool(value); - } - else if(value->IsArray()) - { - this->CommitType(typeLocation, BSON_TYPE_ARRAY); - SerializeArray(value); - } - else if(value->IsDate()) - { - this->CommitType(typeLocation, BSON_TYPE_DATE); - this->WriteInt64(value); - } - else if(value->IsRegExp()) - { - this->CommitType(typeLocation, BSON_TYPE_REGEXP); - const Handle& regExp = Handle::Cast(value); - - this->WriteString(regExp->GetSource()); - - int flags = regExp->GetFlags(); - if(flags & RegExp::kGlobal) this->WriteByte('s'); - if(flags & RegExp::kIgnoreCase) this->WriteByte('i'); - if(flags & RegExp::kMultiline) this->WriteByte('m'); - this->WriteByte(0); - } - else if(value->IsFunction()) - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsObject()) - { - const Local& object = value->ToObject(); - if(object->Has(bson->_bsontypeString)) - { - const Local& constructorString = object->GetConstructorName(); - if(bson->longString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_LONG); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->timestampString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->objectIDString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OID); - this->WriteObjectId(object, bson->_objectIDidString); - } - else if(bson->binaryString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value(); - Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject(); - - this->WriteInt32(length); - this->WriteByte(object, bson->_binarySubTypeString); // write subtype - // If type 0x02 write the array length aswell - if(object->Get(bson->_binarySubTypeString)->Int32Value() == 0x02) { - this->WriteInt32(length); - } - // Write the actual data - this->WriteData(Buffer::Data(bufferObj), length); - } - else if(bson->doubleString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(object, bson->_doubleValueString); - } - else if(bson->symbolString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_SYMBOL); - this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString()); - } - else if(bson->codeString->StrictEquals(constructorString)) - { - const Local& function = object->Get(bson->_codeCodeString)->ToString(); - const Local& scope = object->Get(bson->_codeScopeString)->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - if(propertyNameLength > 0) - { - this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE); - void* codeWidthScopeSize = this->BeginWriteSize(); - this->WriteLengthPrefixedString(function->ToString()); - SerializeDocument(scope); - this->CommitSize(codeWidthScopeSize); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(function->ToString()); - } - } - else if(bson->dbrefString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - - void* dbRefSize = this->BeginWriteSize(); - - void* refType = this->BeginWriteType(); - this->WriteData("$ref", 5); - SerializeValue(refType, object->Get(bson->_dbRefNamespaceString)); - - void* idType = this->BeginWriteType(); - this->WriteData("$id", 4); - SerializeValue(idType, object->Get(bson->_dbRefOidString)); - - const Local& refDbValue = object->Get(bson->_dbRefDbString); - if(!refDbValue->IsUndefined()) - { - void* dbType = this->BeginWriteType(); - this->WriteData("$db", 4); - SerializeValue(dbType, refDbValue); - } - - this->WriteByte(0); - this->CommitSize(dbRefSize); - } - else if(bson->minKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MIN_KEY); - } - else if(bson->maxKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MAX_KEY); - } - } - else if(Buffer::HasInstance(value)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(value->ToObject()); - uint32_t length = object->length(); - #else - uint32_t length = Buffer::Length(value->ToObject()); - #endif - - this->WriteInt32(length); - this->WriteByte(0); - this->WriteData(Buffer::Data(value->ToObject()), length); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - SerializeDocument(value); - } - } - else if(value->IsNull() || value->IsUndefined()) - { - this->CommitType(typeLocation, BSON_TYPE_NULL); - } -} - -// Data points to start of element list, length is length of entire document including '\0' but excluding initial size -BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length) -: bson(aBson), - pStart(data), - p(data), - pEnd(data + length - 1) -{ - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length) -: bson(parentSerializer.bson), - pStart(parentSerializer.p), - p(parentSerializer.p), - pEnd(parentSerializer.p + length - 1) -{ - parentSerializer.p += length; - if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds"); - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -Local BSONDeserializer::ReadCString() -{ - char* start = p; - while(*p++) { } - return String::New(start, (int32_t) (p-start-1) ); -} - -int32_t BSONDeserializer::ReadRegexOptions() -{ - int32_t options = 0; - for(;;) - { - switch(*p++) - { - case '\0': return options; - case 's': options |= RegExp::kGlobal; break; - case 'i': options |= RegExp::kIgnoreCase; break; - case 'm': options |= RegExp::kMultiline; break; - } - } -} - -uint32_t BSONDeserializer::ReadIntegerString() -{ - uint32_t value = 0; - while(*p) - { - if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array"); - value = value * 10 + *p++ - '0'; - } - ++p; - return value; -} - -Local BSONDeserializer::ReadString() -{ - uint32_t length = ReadUInt32(); - char* start = p; - p += length; - return String::New(start, length-1); -} - -Local BSONDeserializer::ReadObjectId() -{ - uint16_t objectId[12]; - for(size_t i = 0; i < 12; ++i) - { - objectId[i] = *reinterpret_cast(p++); - } - return String::New(objectId, 12); -} - -Handle BSONDeserializer::DeserializeDocument() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeDocumentInternal(); -} - -Handle BSONDeserializer::DeserializeDocumentInternal() -{ - Local returnObject = Object::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - const Local& name = ReadCString(); - const Handle& value = DeserializeValue(type); - returnObject->ForceSet(name, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes"); - - // From JavaScript: - // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - if(returnObject->Has(bson->_dbRefIdRefString)) - { - Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) }; - return bson->dbrefConstructor->NewInstance(3, argv); - } - else - { - return returnObject; - } -} - -Handle BSONDeserializer::DeserializeArray() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeArrayInternal(); -} - -Handle BSONDeserializer::DeserializeArrayInternal() -{ - Local returnArray = Array::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - uint32_t index = ReadIntegerString(); - const Handle& value = DeserializeValue(type); - returnArray->Set(index, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes"); - - return returnArray; -} - -Handle BSONDeserializer::DeserializeValue(BsonType type) -{ - switch(type) - { - case BSON_TYPE_STRING: - return ReadString(); - - case BSON_TYPE_INT: - return Integer::New(ReadInt32()); - - case BSON_TYPE_NUMBER: - return Number::New(ReadDouble()); - - case BSON_TYPE_NULL: - return Null(); - - case BSON_TYPE_UNDEFINED: - return Undefined(); - - case BSON_TYPE_TIMESTAMP: - { - int32_t lowBits = ReadInt32(); - int32_t highBits = ReadInt32(); - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->timestampConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_BOOLEAN: - return (ReadByte() != 0) ? True() : False(); - - case BSON_TYPE_REGEXP: - { - const Local& regex = ReadCString(); - int32_t options = ReadRegexOptions(); - return RegExp::New(regex, (RegExp::Flags) options); - } - - case BSON_TYPE_CODE: - { - const Local& code = ReadString(); - const Local& scope = Object::New(); - Local argv[] = { code, scope }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_CODE_W_SCOPE: - { - ReadUInt32(); - const Local& code = ReadString(); - const Handle& scope = DeserializeDocument(); - Local argv[] = { code, scope->ToObject() }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_OID: - { - Local argv[] = { ReadObjectId() }; - return bson->objectIDConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_BINARY: - { - uint32_t length = ReadUInt32(); - uint32_t subType = ReadByte(); - if(subType == 0x02) { - length = ReadInt32(); - } - - Buffer* buffer = Buffer::New(p, length); - p += length; - - Handle argv[] = { buffer->handle_, Uint32::New(subType) }; - return bson->binaryConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_LONG: - { - // Read 32 bit integers - int32_t lowBits = (int32_t) ReadInt32(); - int32_t highBits = (int32_t) ReadInt32(); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - // Adjust the pointer and read as 64 bit value - p -= 8; - // Read the 64 bit value - int64_t finalValue = (int64_t) ReadInt64(); - return Number::New(finalValue); - } - - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->longConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_DATE: - return Date::New((double) ReadInt64()); - - case BSON_TYPE_ARRAY: - return DeserializeArray(); - - case BSON_TYPE_OBJECT: - return DeserializeDocument(); - - case BSON_TYPE_SYMBOL: - { - const Local& string = ReadString(); - Local argv[] = { string }; - return bson->symbolConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_MIN_KEY: - return bson->minKeyConstructor->NewInstance(); - - case BSON_TYPE_MAX_KEY: - return bson->maxKeyConstructor->NewInstance(); - - default: - ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type); - } - - return v8::Null(); -} - - -static Handle VException(const char *msg) -{ - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Persistent BSON::constructor_template; - -BSON::BSON() : ObjectWrap() -{ - // Setup pre-allocated comparision objects - _bsontypeString = Persistent::New(String::New("_bsontype")); - _longLowString = Persistent::New(String::New("low_")); - _longHighString = Persistent::New(String::New("high_")); - _objectIDidString = Persistent::New(String::New("id")); - _binaryPositionString = Persistent::New(String::New("position")); - _binarySubTypeString = Persistent::New(String::New("sub_type")); - _binaryBufferString = Persistent::New(String::New("buffer")); - _doubleValueString = Persistent::New(String::New("value")); - _symbolValueString = Persistent::New(String::New("value")); - _dbRefRefString = Persistent::New(String::New("$ref")); - _dbRefIdRefString = Persistent::New(String::New("$id")); - _dbRefDbRefString = Persistent::New(String::New("$db")); - _dbRefNamespaceString = Persistent::New(String::New("namespace")); - _dbRefDbString = Persistent::New(String::New("db")); - _dbRefOidString = Persistent::New(String::New("oid")); - _codeCodeString = Persistent::New(String::New("code")); - _codeScopeString = Persistent::New(String::New("scope")); - _toBSONString = Persistent::New(String::New("toBSON")); - - longString = Persistent::New(String::New("Long")); - objectIDString = Persistent::New(String::New("ObjectID")); - binaryString = Persistent::New(String::New("Binary")); - codeString = Persistent::New(String::New("Code")); - dbrefString = Persistent::New(String::New("DBRef")); - symbolString = Persistent::New(String::New("Symbol")); - doubleString = Persistent::New(String::New("Double")); - timestampString = Persistent::New(String::New("Timestamp")); - minKeyString = Persistent::New(String::New("MinKey")); - maxKeyString = Persistent::New(String::New("MaxKey")); -} - -void BSON::Initialize(v8::Handle target) -{ - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and passing it the existing context -Handle BSON::New(const Arguments &args) -{ - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) - { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) - { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - uint32_t foundClassesMask = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(bson->longString)) { - bson->longConstructor = Persistent::New(func); - foundClassesMask |= 1; - } else if(functionName->StrictEquals(bson->objectIDString)) { - bson->objectIDConstructor = Persistent::New(func); - foundClassesMask |= 2; - } else if(functionName->StrictEquals(bson->binaryString)) { - bson->binaryConstructor = Persistent::New(func); - foundClassesMask |= 4; - } else if(functionName->StrictEquals(bson->codeString)) { - bson->codeConstructor = Persistent::New(func); - foundClassesMask |= 8; - } else if(functionName->StrictEquals(bson->dbrefString)) { - bson->dbrefConstructor = Persistent::New(func); - foundClassesMask |= 0x10; - } else if(functionName->StrictEquals(bson->symbolString)) { - bson->symbolConstructor = Persistent::New(func); - foundClassesMask |= 0x20; - } else if(functionName->StrictEquals(bson->doubleString)) { - bson->doubleConstructor = Persistent::New(func); - foundClassesMask |= 0x40; - } else if(functionName->StrictEquals(bson->timestampString)) { - bson->timestampConstructor = Persistent::New(func); - foundClassesMask |= 0x80; - } else if(functionName->StrictEquals(bson->minKeyString)) { - bson->minKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x100; - } else if(functionName->StrictEquals(bson->maxKeyString)) { - bson->maxKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x200; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(foundClassesMask != 0x3ff) { - delete bson; - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } - else - { - return VException("No types passed in"); - } - } - else - { - return VException("Argument passed in must be an array of types"); - } -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ - -Handle BSON::BSONDeserialize(const Arguments &args) -{ - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) - { -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Validate that we have at least 5 bytes - if(length < 5) return VException("corrupt bson message < 5 bytes long"); - - try - { - BSONDeserializer deserializer(bson, data, length); - return deserializer.DeserializeDocument(); - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - } - else - { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) return VException("corrupt bson message < 5 bytes long"); - - // Let's define the buffer size - char* data = (char *)malloc(len); - DecodeWrite(data, len, args[0], BINARY); - - try - { - BSONDeserializer deserializer(bson, data, len); - Handle result = deserializer.DeserializeDocument(); - free(data); - return result; - - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - free(data); - return error; - } - } -} - -Local BSON::GetSerializeObject(const Handle& argValue) -{ - Local object = argValue->ToObject(); - if(object->Has(_toBSONString)) - { - const Local& toBSON = object->Get(_toBSONString); - if(!toBSON->IsFunction()) ThrowAllocatedStringException(64, "toBSON is not a function"); - - Local result = Local::Cast(toBSON)->Call(object, 0, NULL); - if(!result->IsObject()) ThrowAllocatedStringException(64, "toBSON function did not return an object"); - return result->ToObject(); - } - else - { - return object; - } -} - -Handle BSON::BSONSerialize(const Arguments &args) -{ - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - bool serializeFunctions = (args.Length() >= 4) && args[3]->BooleanValue(); - - char *serialized_object = NULL; - size_t object_size; - try - { - Local object = bson->GetSerializeObject(args[0]); - - BSONSerializer counter(bson, false, serializeFunctions); - counter.SerializeDocument(object); - object_size = counter.GetSerializeSize(); - - // Allocate the memory needed for the serialization - serialized_object = (char *)malloc(object_size); - - // Check if we have a boolean value - bool checkKeys = args.Length() >= 3 && args[1]->IsBoolean() && args[1]->BooleanValue(); - BSONSerializer data(bson, checkKeys, serializeFunctions, serialized_object); - data.SerializeDocument(object); - } - catch(char *err_msg) - { - free(serialized_object); - Handle error = VException(err_msg); - free(err_msg); - return error; - } - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) - { - Buffer *buffer = Buffer::New(serialized_object, object_size); - free(serialized_object); - return scope.Close(buffer->handle_); - } - else - { - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - free(serialized_object); - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) -{ - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - bool serializeFunctions = (args.Length() >= 2) && args[1]->BooleanValue(); - BSONSerializer countSerializer(bson, false, serializeFunctions); - countSerializer.SerializeDocument(args[0]); - - // Return the object size - return scope.Close(Uint32::New((uint32_t) countSerializer.GetSerializeSize())); -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) -{ - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, ->, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - uint32_t index; - size_t object_size; - - try - { - BSON *bson = ObjectWrap::Unwrap(args.This()); - - Local obj = args[2]->ToObject(); - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); - - index = args[3]->Uint32Value(); - bool checkKeys = args.Length() >= 4 && args[1]->IsBoolean() && args[1]->BooleanValue(); - bool serializeFunctions = (args.Length() == 5) && args[4]->BooleanValue(); - - BSONSerializer dataSerializer(bson, checkKeys, serializeFunctions, data+index); - dataSerializer.SerializeDocument(bson->GetSerializeObject(args[0])); - object_size = dataSerializer.GetSerializeSize(); - - if(object_size + index > length) return VException("Serious error - overflowed buffer!!"); - } - catch(char *exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - return scope.Close(Uint32::New((uint32_t) (index + object_size - 1))); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) -{ - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) return VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) - { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->Uint32Value(); - uint32_t index = args[1]->Uint32Value(); - uint32_t resultIndex = args[4]->Uint32Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - BSONDeserializer deserializer(bson, data+index, length-index); - for(uint32_t i = 0; i < numberOfDocuments; i++) - { - try - { - documents->Set(i + resultIndex, deserializer.DeserializeDocument()); - } - catch (char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - } - - // Return new index of parsing - return scope.Close(Uint32::New((uint32_t) (index + deserializer.GetSerializeSize()))); -} - -// Exporting function -extern "C" void init(Handle target) -{ - HandleScope scope; - BSON::Initialize(target); -} - -NODE_MODULE(bson, BSON::Initialize); diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h deleted file mode 100644 index 580abd4de2b..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h +++ /dev/null @@ -1,273 +0,0 @@ -//=========================================================================== - -#ifndef BSON_H_ -#define BSON_H_ - -//=========================================================================== - -#define USE_MISALIGNED_MEMORY_ACCESS 1 - -#include -#include -#include - -using namespace v8; -using namespace node; - -//=========================================================================== - -enum BsonType -{ - BSON_TYPE_NUMBER = 1, - BSON_TYPE_STRING = 2, - BSON_TYPE_OBJECT = 3, - BSON_TYPE_ARRAY = 4, - BSON_TYPE_BINARY = 5, - BSON_TYPE_UNDEFINED = 6, - BSON_TYPE_OID = 7, - BSON_TYPE_BOOLEAN = 8, - BSON_TYPE_DATE = 9, - BSON_TYPE_NULL = 10, - BSON_TYPE_REGEXP = 11, - BSON_TYPE_CODE = 13, - BSON_TYPE_SYMBOL = 14, - BSON_TYPE_CODE_W_SCOPE = 15, - BSON_TYPE_INT = 16, - BSON_TYPE_TIMESTAMP = 17, - BSON_TYPE_LONG = 18, - BSON_TYPE_MAX_KEY = 0x7f, - BSON_TYPE_MIN_KEY = 0xff -}; - -//=========================================================================== - -template class BSONSerializer; - -class BSON : public ObjectWrap { -public: - BSON(); - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - -private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparison objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - Persistent _codeCodeString; - Persistent _codeScopeString; - Persistent _toBSONString; - - Local GetSerializeObject(const Handle& object); - - template friend class BSONSerializer; - friend class BSONDeserializer; -}; - -//=========================================================================== - -class CountStream -{ -public: - CountStream() : count(0) { } - - void WriteByte(int value) { ++count; } - void WriteByte(const Handle&, const Handle&) { ++count; } - void WriteBool(const Handle& value) { ++count; } - void WriteInt32(int32_t value) { count += 4; } - void WriteInt32(const Handle& value) { count += 4; } - void WriteInt32(const Handle& object, const Handle& key) { count += 4; } - void WriteInt64(int64_t value) { count += 8; } - void WriteInt64(const Handle& value) { count += 8; } - void WriteDouble(double value) { count += 8; } - void WriteDouble(const Handle& value) { count += 8; } - void WriteDouble(const Handle&, const Handle&) { count += 8; } - void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { count += value->Utf8Length()+5; } - void WriteObjectId(const Handle& object, const Handle& key) { count += 12; } - void WriteString(const Local& value) { count += value->Utf8Length() + 1; } // This returns the number of bytes exclusive of the NULL terminator - void WriteData(const char* data, size_t length) { count += length; } - - void* BeginWriteType() { ++count; return NULL; } - void CommitType(void*, BsonType) { } - void* BeginWriteSize() { count += 4; return NULL; } - void CommitSize(void*) { } - - size_t GetSerializeSize() const { return count; } - - // Do nothing. CheckKey is implemented for DataStream - void CheckKey(const Local&) { } - -private: - size_t count; -}; - -class DataStream -{ -public: - DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { } - - void WriteByte(int value) { *p++ = value; } - void WriteByte(const Handle& object, const Handle& key) { *p++ = object->Get(key)->Int32Value(); } -#if USE_MISALIGNED_MEMORY_ACCESS - void WriteInt32(int32_t value) { *reinterpret_cast(p) = value; p += 4; } - void WriteInt64(int64_t value) { *reinterpret_cast(p) = value; p += 8; } - void WriteDouble(double value) { *reinterpret_cast(p) = value; p += 8; } -#else - void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; } - void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; } - void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; } -#endif - void WriteBool(const Handle& value) { WriteByte(value->BooleanValue() ? 1 : 0); } - void WriteInt32(const Handle& value) { WriteInt32(value->Int32Value()); } - void WriteInt32(const Handle& object, const Handle& key) { WriteInt32(object->Get(key)); } - void WriteInt64(const Handle& value) { WriteInt64(value->IntegerValue()); } - void WriteDouble(const Handle& value) { WriteDouble(value->NumberValue()); } - void WriteDouble(const Handle& object, const Handle& key) { WriteDouble(object->Get(key)); } - void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); } - void WriteObjectId(const Handle& object, const Handle& key); - void WriteString(const Local& value) { p += value->WriteUtf8(p); } // This returns the number of bytes inclusive of the NULL terminator. - void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; } - - void* BeginWriteType() { void* returnValue = p; p++; return returnValue; } - void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast(beginPoint) = value; } - void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; } - -#if USE_MISALIGNED_MEMORY_ACCESS - void CommitSize(void* beginPoint) { *reinterpret_cast(beginPoint) = (int32_t) (p - (char*) beginPoint); } -#else - void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); } -#endif - - size_t GetSerializeSize() const { return p - destinationBuffer; } - - void CheckKey(const Local& keyName); - -protected: - char *const destinationBuffer; // base, never changes - char* p; // cursor into buffer -}; - -template class BSONSerializer : public T -{ -private: - typedef T Inherited; - -public: - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - - void SerializeDocument(const Handle& value); - void SerializeArray(const Handle& value); - void SerializeValue(void* typeLocation, const Handle& value); - -private: - bool checkKeys; - bool serializeFunctions; - BSON* bson; -}; - -//=========================================================================== - -class BSONDeserializer -{ -public: - BSONDeserializer(BSON* aBson, char* data, size_t length); - BSONDeserializer(BSONDeserializer& parentSerializer, size_t length); - - Handle DeserializeDocument(); - - bool HasMoreData() const { return p < pEnd; } - Local ReadCString(); - uint32_t ReadIntegerString(); - int32_t ReadRegexOptions(); - Local ReadString(); - Local ReadObjectId(); - - unsigned char ReadByte() { return *reinterpret_cast(p++); } -#if USE_MISALIGNED_MEMORY_ACCESS - int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast(p); p += 8; return returnValue; } - double ReadDouble() { double returnValue = *reinterpret_cast(p); p += 8; return returnValue; } -#else - int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } - double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } -#endif - - size_t GetSerializeSize() const { return p - pStart; } - -private: - Handle DeserializeArray(); - Handle DeserializeValue(BsonType type); - Handle DeserializeDocumentInternal(); - Handle DeserializeArrayInternal(); - - BSON* bson; - char* const pStart; - char* p; - char* const pEnd; -}; - -//=========================================================================== - -#endif // BSON_H_ - -//=========================================================================== diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js deleted file mode 100644 index 85e243cc2e1..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js +++ /dev/null @@ -1,30 +0,0 @@ -var bson = null; - -// Load the precompiled win32 binary -if(process.platform == "win32" && process.arch == "x64") { - bson = require('./win32/x64/bson'); -} else if(process.platform == "win32" && process.arch == "ia32") { - bson = require('./win32/ia32/bson'); -} else { - bson = require('../build/Release/bson'); -} - -exports.BSON = bson.BSON; -exports.Long = require('../lib/bson/long').Long; -exports.ObjectID = require('../lib/bson/objectid').ObjectID; -exports.DBRef = require('../lib/bson/db_ref').DBRef; -exports.Code = require('../lib/bson/code').Code; -exports.Timestamp = require('../lib/bson/timestamp').Timestamp; -exports.Binary = require('../lib/bson/binary').Binary; -exports.Double = require('../lib/bson/double').Double; -exports.MaxKey = require('../lib/bson/max_key').MaxKey; -exports.MinKey = require('../lib/bson/min_key').MinKey; -exports.Symbol = require('../lib/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node deleted file mode 100644 index b27819bb1a8..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node deleted file mode 100644 index a544c8ed638..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js deleted file mode 100644 index c9cc91d0742..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js +++ /dev/null @@ -1,41 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_config_mongodb_native'] != null ? process.env['npm_config_mongodb_native'] : 'false'; -build_native = build_native == 'true' ? true : false; - -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total'], {cwd:process.env['PWD']}); - } else { - make = spawn('gmake', ['total'], {cwd:process.env['PWD']}); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js deleted file mode 100644 index 82d4d04c10b..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js deleted file mode 100644 index d2fc811f416..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js deleted file mode 100644 index 57fdd7958b8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js +++ /dev/null @@ -1,1519 +0,0 @@ -var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js deleted file mode 100644 index 69b56a3ff51..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js deleted file mode 100644 index 56b651029bd..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js deleted file mode 100644 index ae5146378f0..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js deleted file mode 100644 index 6fca3924f6c..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js deleted file mode 100644 index 950fcad343d..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js +++ /dev/null @@ -1,74 +0,0 @@ -try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js deleted file mode 100644 index f8f37a6b865..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js +++ /dev/null @@ -1,854 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js deleted file mode 100644 index 0825408d0c9..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js deleted file mode 100644 index 230c2e64a1d..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js deleted file mode 100644 index 1ff9a8326a8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js deleted file mode 100644 index 8e2838d1783..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js deleted file mode 100644 index c650d1536c8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json deleted file mode 100644 index 1a4fde856aa..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "bson", - "description": "A bson parser for node.js and the browser", - "keywords": [ - "mongodb", - "bson", - "parser" - ], - "version": "0.1.8", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [], - "repository": { - "type": "git", - "url": "git://github.com/mongodb/js-bson.git" - }, - "bugs": { - "url": "https://github.com/mongodb/js-bson/issues" - }, - "devDependencies": { - "nodeunit": "0.7.3", - "gleak": "0.2.3", - "one": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/bson/index", - "directories": { - "lib": "./lib/bson" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "nodeunit ./test/node && TEST_NATIVE=TRUE nodeunit ./test/node" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "A JS/C++ Bson parser for node, used in the MongoDB Native driver", - "readmeFilename": "README.md", - "_id": "bson@0.1.8", - "_from": "bson@0.1.8" -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm deleted file mode 100644 index 4ee148bde39..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js deleted file mode 100644 index 84d8ffc78a9..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js +++ /dev/null @@ -1,260 +0,0 @@ -this.bson_test = { - 'Full document serialization and deserialization': function (test) { - var motherOfAllDocuments = { - 'string': "客家è¯", - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary('hello world'), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSON.serialize(motherOfAllDocuments, true, true, false); - // Deserialize the object - var object = BSON.deserialize(data); - - // Asserts - test.equal(Utf8.decode(motherOfAllDocuments.string), object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - test.ok(assertArrayEqual(motherOfAllDocuments.binary.value(true), object.binary.value(true))); - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); - }, - - 'exercise all the binary object constructor methods': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - test.done(); - }, - - 'exercise the put binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); - }, - - 'exercise the write binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); - }, - - 'exercise the read binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(assertArrayEqual(stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(assertArrayEqual(stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(assertArrayEqual(stringToArrayBuffer('world'), data)); - test.done(); - }, - - 'Should correctly handle toBson function for an object': function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = BSON.serialize(doc, false, true); - var deserialized_doc = BSON.deserialize(serialized_data); - test.equal(1, deserialized_doc.b); - test.done(); - } -}; - -var assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -var stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -var stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -var Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js deleted file mode 100644 index af7fd0b5867..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js +++ /dev/null @@ -1,2034 +0,0 @@ -/*! - * Nodeunit - * https://github.com/caolan/nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * json2.js - * http://www.JSON.org/json2.js - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -nodeunit = (function(){ -/* - http://www.JSON.org/json2.js - 2010-11-17 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, strict: false, regexp: false */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -var JSON = {}; - -(function () { - "use strict"; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) ? - this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? - '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : - '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : - gap ? '[\n' + gap + - partial.join(',\n' + gap) + '\n' + - mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : - gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + - mind + '}' : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ -.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') -.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') -.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); -var assert = this.assert = {}; -var types = {}; -var core = {}; -var nodeunit = {}; -var reporter = {}; -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - var _indexOf = function (arr, item) { - if (arr.indexOf) { - return arr.indexOf(item); - } - for (var i = 0; i < arr.length; i += 1) { - if (arr[i] === item) { - return i; - } - } - return -1; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var completed = []; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners, function (fn) { - fn(); - }); - }; - - addListener(function () { - if (completed.length === keys.length) { - callback(null); - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - completed.push(k); - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && _indexOf(completed, x) !== -1); - }, true); - }; - if (ready()) { - task[task.length - 1](taskCallback); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - if (!tasks.length) { - return callback(); - } - callback = callback || function () {}; - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var tasks = []; - var q = { - concurrency: concurrency, - push: function (data, callback) { - tasks.push({data: data, callback: callback}); - async.nextTick(q.process); - }, - process: function () { - if (workers < q.concurrency && tasks.length) { - var task = tasks.splice(0, 1)[0]; - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - q.process(); - }); - } - }, - length: function () { - return tasks.length; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - hasher = hasher || function (x) { - return x; - }; - return function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else { - fn.apply(null, args.concat([function () { - memo[key] = arguments; - callback.apply(null, arguments); - }])); - } - }; - }; - -}()); -(function(exports){ -/** - * This file is based on the node.js assert module, but with some small - * changes for browser-compatibility - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - */ - - -/** - * Added for browser compatibility - */ - -var _keys = function(obj){ - if(Object.keys) return Object.keys(obj); - if (typeof obj != 'object' && typeof obj != 'function') { - throw new TypeError('-'); - } - var keys = []; - for(var k in obj){ - if(obj.hasOwnProperty(k)) keys.push(k); - } - return keys; -}; - - - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({message: message, actual: actual, expected: expected}) - -assert.AssertionError = function AssertionError (options) { - this.name = "AssertionError"; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// code from util.inherits in node -assert.AssertionError.super_ = Error; - - -// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call -// TODO: test what effect this may have -var ctor = function () { this.constructor = assert.AssertionError; }; -ctor.prototype = Error.prototype; -assert.AssertionError.prototype = new ctor(); - - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name+":", this.message].join(' '); - } else { - return [ this.name+":" - , JSON.stringify(this.expected ) - , this.operator - , JSON.stringify(this.actual) - ].join(" "); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, "==", assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, "==", assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, "!=", assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, "deepEqual", assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == "object", - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical "prototype" property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull (value) { - return value === null || value === undefined; -} - -function isArguments (object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv (a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical "prototype" property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try{ - var ka = _keys(a), - kb = _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; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, "===", assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, "!==", assert.notStrictEqual); - } -}; - -function _throws (shouldThrow, block, err, message) { - var exception = null, - threw = false, - typematters = true; - - message = message || ""; - - //handle optional arguments - if (arguments.length == 3) { - if (typeof(err) == "string") { - message = err; - typematters = false; - } - } else if (arguments.length == 2) { - typematters = false; - } - - try { - block(); - } catch (e) { - threw = true; - exception = e; - } - - if (shouldThrow && !threw) { - fail( "Missing expected exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if (!shouldThrow && threw && typematters && exception instanceof err) { - fail( "Got unwanted exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if ((shouldThrow && threw && typematters && !(exception instanceof err)) || - (!shouldThrow && threw)) { - throw exception; - } -}; - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function (err) { if (err) {throw err;}}; -})(assert); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var assert = require('./assert'), //@REMOVE_LINE_FOR_BROWSER -// async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Creates assertion objects representing the result of an assert call. - * Accepts an object or AssertionError as its argument. - * - * @param {object} obj - * @api public - */ - -exports.assertion = function (obj) { - return { - method: obj.method || '', - message: obj.message || (obj.error && obj.error.message) || '', - error: obj.error, - passed: function () { - return !this.error; - }, - failed: function () { - return Boolean(this.error); - } - }; -}; - -/** - * Creates an assertion list object representing a group of assertions. - * Accepts an array of assertion objects. - * - * @param {Array} arr - * @param {Number} duration - * @api public - */ - -exports.assertionList = function (arr, duration) { - var that = arr || []; - that.failures = function () { - var failures = 0; - for (var i = 0; i < this.length; i += 1) { - if (this[i].failed()) { - failures += 1; - } - } - return failures; - }; - that.passes = function () { - return that.length - that.failures(); - }; - that.duration = duration || 0; - return that; -}; - -/** - * Create a wrapper function for assert module methods. Executes a callback - * after the it's complete with an assertion object representing the result. - * - * @param {Function} callback - * @api private - */ - -var assertWrapper = function (callback) { - return function (new_method, assert_method, arity) { - return function () { - var message = arguments[arity - 1]; - var a = exports.assertion({method: new_method, message: message}); - try { - assert[assert_method].apply(null, arguments); - } - catch (e) { - a.error = e; - } - callback(a); - }; - }; -}; - -/** - * Creates the 'test' object that gets passed to every test function. - * Accepts the name of the test function as its first argument, followed by - * the start time in ms, the options object and a callback function. - * - * @param {String} name - * @param {Number} start - * @param {Object} options - * @param {Function} callback - * @api public - */ - -exports.test = function (name, start, options, callback) { - var expecting; - var a_list = []; - - var wrapAssert = assertWrapper(function (a) { - a_list.push(a); - if (options.log) { - async.nextTick(function () { - options.log(a); - }); - } - }); - - var test = { - done: function (err) { - if (expecting !== undefined && expecting !== a_list.length) { - var e = new Error( - 'Expected ' + expecting + ' assertions, ' + - a_list.length + ' ran' - ); - var a1 = exports.assertion({method: 'expect', error: e}); - a_list.push(a1); - if (options.log) { - async.nextTick(function () { - options.log(a1); - }); - } - } - if (err) { - var a2 = exports.assertion({error: err}); - a_list.push(a2); - if (options.log) { - async.nextTick(function () { - options.log(a2); - }); - } - } - var end = new Date().getTime(); - async.nextTick(function () { - var assertion_list = exports.assertionList(a_list, end - start); - options.testDone(name, assertion_list); - callback(null, a_list); - }); - }, - ok: wrapAssert('ok', 'ok', 2), - same: wrapAssert('same', 'deepEqual', 3), - equals: wrapAssert('equals', 'equal', 3), - expect: function (num) { - expecting = num; - }, - _assertion_list: a_list - }; - // add all functions from the assert module - for (var k in assert) { - if (assert.hasOwnProperty(k)) { - test[k] = wrapAssert(k, k, assert[k].length); - } - } - return test; -}; - -/** - * Ensures an options object has all callbacks, adding empty callback functions - * if any are missing. - * - * @param {Object} opt - * @return {Object} - * @api public - */ - -exports.options = function (opt) { - var optionalCallback = function (name) { - opt[name] = opt[name] || function () {}; - }; - - optionalCallback('moduleStart'); - optionalCallback('moduleDone'); - optionalCallback('testStart'); - optionalCallback('testDone'); - //optionalCallback('log'); - - // 'done' callback is not optional. - - return opt; -}; -})(types); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER -// types = require('./types'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Added for browser compatibility - */ - -var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; -}; - - -var _copy = function (obj) { - var nobj = {}; - var keys = _keys(obj); - for (var i = 0; i < keys.length; i += 1) { - nobj[keys[i]] = obj[keys[i]]; - } - return nobj; -}; - - -/** - * Runs a test function (fn) from a loaded module. After the test function - * calls test.done(), the callback is executed with an assertionList as its - * second argument. - * - * @param {String} name - * @param {Function} fn - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runTest = function (name, fn, opt, callback) { - var options = types.options(opt); - - options.testStart(name); - var start = new Date().getTime(); - var test = types.test(name, start, options, callback); - - try { - fn(test); - } - catch (e) { - test.done(e); - } -}; - -/** - * Takes an object containing test functions or other test suites as properties - * and runs each in series. After all tests have completed, the callback is - * called with a list of all assertions as the second argument. - * - * If a name is passed to this function it is prepended to all test and suite - * names that run within it. - * - * @param {String} name - * @param {Object} suite - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runSuite = function (name, suite, opt, callback) { - var keys = _keys(suite); - - async.concatSeries(keys, function (k, cb) { - var prop = suite[k], _name; - - _name = name ? [].concat(name, k) : [k]; - - _name.toString = function () { - // fallback for old one - return this.join(' - '); - }; - - if (typeof prop === 'function') { - var in_name = false; - for (var i = 0; i < _name.length; i += 1) { - if (_name[i] === opt.testspec) { - in_name = true; - } - } - if (!opt.testspec || in_name) { - if (opt.moduleStart) { - opt.moduleStart(); - } - exports.runTest(_name, suite[k], opt, cb); - } - else { - return cb(); - } - } - else { - exports.runSuite(_name, suite[k], opt, cb); - } - }, callback); -}; - -/** - * Run each exported test function or test suite from a loaded module. - * - * @param {String} name - * @param {Object} mod - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runModule = function (name, mod, opt, callback) { - var options = _copy(types.options(opt)); - - var _run = false; - var _moduleStart = options.moduleStart; - function run_once() { - if (!_run) { - _run = true; - _moduleStart(name); - } - } - options.moduleStart = run_once; - - var start = new Date().getTime(); - - exports.runSuite(null, mod, options, function (err, a_list) { - var end = new Date().getTime(); - var assertion_list = types.assertionList(a_list, end - start); - options.moduleDone(name, assertion_list); - callback(null, a_list); - }); -}; - -/** - * Treats an object literal as a list of modules keyed by name. Runs each - * module and finished with calling 'done'. You can think of this as a browser - * safe alternative to runFiles in the nodeunit module. - * - * @param {Object} modules - * @param {Object} opt - * @api public - */ - -// TODO: add proper unit tests for this function -exports.runModules = function (modules, opt) { - var all_assertions = []; - var options = types.options(opt); - var start = new Date().getTime(); - - async.concatSeries(_keys(modules), function (k, cb) { - exports.runModule(k, modules[k], options, cb); - }, - function (err, all_assertions) { - var end = new Date().getTime(); - options.done(types.assertionList(all_assertions, end - start)); - }); -}; - - -/** - * Wraps a test function with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Function} fn - * @api private - */ - -var wrapTest = function (setUp, tearDown, fn) { - return function (test) { - var context = {}; - if (tearDown) { - var done = test.done; - test.done = function (err) { - try { - tearDown.call(context, function (err2) { - if (err && err2) { - test._assertion_list.push( - types.assertion({error: err}) - ); - return done(err2); - } - done(err || err2); - }); - } - catch (e) { - done(e); - } - }; - } - if (setUp) { - setUp.call(context, function (err) { - if (err) { - return test.done(err); - } - fn.call(context, test); - }); - } - else { - fn.call(context, test); - } - }; -}; - - -/** - * Wraps a group of tests with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Object} group - * @api private - */ - -var wrapGroup = function (setUp, tearDown, group) { - var tests = {}; - var keys = _keys(group); - for (var i = 0; i < keys.length; i += 1) { - var k = keys[i]; - if (typeof group[k] === 'function') { - tests[k] = wrapTest(setUp, tearDown, group[k]); - } - else if (typeof group[k] === 'object') { - tests[k] = wrapGroup(setUp, tearDown, group[k]); - } - } - return tests; -}; - - -/** - * Utility for wrapping a suite of test functions with setUp and tearDown - * functions. - * - * @param {Object} suite - * @return {Object} - * @api public - */ - -exports.testCase = function (suite) { - var setUp = suite.setUp; - var tearDown = suite.tearDown; - delete suite.setUp; - delete suite.tearDown; - return wrapGroup(setUp, tearDown, suite); -}; -})(core); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - - -/** - * NOTE: this test runner is not listed in index.js because it cannot be - * used with the command-line tool, only inside the browser. - */ - - -/** - * Reporter info string - */ - -exports.info = "Browser-based test reporter"; - - -/** - * Run all tests within each module, reporting the results - * - * @param {Array} files - * @api public - */ - -exports.run = function (modules, options) { - var start = new Date().getTime(); - - function setText(el, txt) { - if ('innerText' in el) { - el.innerText = txt; - } - else if ('textContent' in el){ - el.textContent = txt; - } - } - - function getOrCreate(tag, id) { - var el = document.getElementById(id); - if (!el) { - el = document.createElement(tag); - el.id = id; - document.body.appendChild(el); - } - return el; - }; - - var header = getOrCreate('h1', 'nodeunit-header'); - var banner = getOrCreate('h2', 'nodeunit-banner'); - var userAgent = getOrCreate('h2', 'nodeunit-userAgent'); - var tests = getOrCreate('ol', 'nodeunit-tests'); - var result = getOrCreate('p', 'nodeunit-testresult'); - - setText(userAgent, navigator.userAgent); - - nodeunit.runModules(modules, { - moduleStart: function (name) { - /*var mheading = document.createElement('h2'); - mheading.innerText = name; - results.appendChild(mheading); - module = document.createElement('ol'); - results.appendChild(module);*/ - }, - testDone: function (name, assertions) { - var test = document.createElement('li'); - var strong = document.createElement('strong'); - strong.innerHTML = name + ' (' + - '' + assertions.failures() + ', ' + - '' + assertions.passes() + ', ' + - assertions.length + - ')'; - test.className = assertions.failures() ? 'fail': 'pass'; - test.appendChild(strong); - - var aList = document.createElement('ol'); - aList.style.display = 'none'; - test.onclick = function () { - var d = aList.style.display; - aList.style.display = (d == 'none') ? 'block': 'none'; - }; - for (var i=0; i' + (a.error.stack || a.error) + ''; - li.className = 'fail'; - } - else { - li.innerHTML = a.message || a.method || 'no message'; - li.className = 'pass'; - } - aList.appendChild(li); - } - test.appendChild(aList); - tests.appendChild(test); - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - - var failures = assertions.failures(); - banner.className = failures ? 'fail': 'pass'; - - result.innerHTML = 'Tests completed in ' + duration + - ' milliseconds.
' + - assertions.passes() + ' assertions of ' + - '' + assertions.length + ' passed, ' + - assertions.failures() + ' failed.'; - } - }); -}; -})(reporter); -nodeunit = core; -nodeunit.assert = assert; -nodeunit.reporter = reporter; -nodeunit.run = reporter.run; -return nodeunit; })(); diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js deleted file mode 100644 index c7288e8d875..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js +++ /dev/null @@ -1,13 +0,0 @@ -this.suite2 = { - 'another test': function (test) { - setTimeout(function () { - // lots of assertions - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.done(); - }, 10); - } -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js deleted file mode 100644 index 89297419bf1..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js +++ /dev/null @@ -1,7 +0,0 @@ -this.suite3 = { - 'test for ie6,7,8': function (test) { - test.deepEqual(["test"], ["test"]); - test.notDeepEqual(["a"], ["b"]); - test.done(); - } -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html deleted file mode 100644 index 56d4d9643b6..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Example tests - - - - - - - - - - - - - - - - - - - - - - - diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js deleted file mode 100644 index 5304bef45c8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js +++ /dev/null @@ -1,240 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -var _Uint8Array = null; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - _Uint8Array = global.Uint8Array; - delete global['Uint8Array']; - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - global['Uint8Array'] = _Uint8Array; - callback(); -} - -// /** -// * @ignore -// */ -// exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { -// var motherOfAllDocuments = { -// 'string': '客家è¯', -// 'array': [1,2,3], -// 'hash': {'a':1, 'b':2}, -// 'date': new Date(), -// 'oid': new ObjectID(), -// 'binary': new Binary(new Buffer("hello")), -// 'int': 42, -// 'float': 33.3333, -// 'regexp': /regexp/, -// 'boolean': true, -// 'long': Long.fromNumber(100), -// 'where': new Code('this.a > i', {i:1}), -// 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), -// 'minkey': new MinKey(), -// 'maxkey': new MaxKey() -// } -// -// // Let's serialize it -// var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); -// // Build a typed array -// var arr = new Uint8Array(new ArrayBuffer(data.length)); -// // Iterate over all the fields and copy -// for(var i = 0; i < data.length; i++) { -// arr[i] = data[i] -// } -// -// // Deserialize the object -// var object = BSONDE.BSON.deserialize(arr); -// // Asserts -// test.equal(motherOfAllDocuments.string, object.string); -// test.deepEqual(motherOfAllDocuments.array, object.array); -// test.deepEqual(motherOfAllDocuments.date, object.date); -// test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); -// // Assert the values of the binary -// for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { -// test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); -// } -// test.deepEqual(motherOfAllDocuments.int, object.int); -// test.deepEqual(motherOfAllDocuments.float, object.float); -// test.deepEqual(motherOfAllDocuments.regexp, object.regexp); -// test.deepEqual(motherOfAllDocuments.boolean, object.boolean); -// test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); -// test.deepEqual(motherOfAllDocuments.where, object.where); -// test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); -// test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); -// test.deepEqual(motherOfAllDocuments.minkey, object.minkey); -// test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); -// test.done(); -// } - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js deleted file mode 100644 index 74815402ffb..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js +++ /dev/null @@ -1,493 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple edge value'] = function(test) { - // Simple serialization and deserialization of edge value - var doc = {doc:0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly execute toJSON'] = function(test) { - var a = Long.fromNumber(10); - assert.equal(10, a); - - var a = Long.fromNumber(9223372036854775807); - assert.equal(9223372036854775807, a); - - // Simple serialization and deserialization test for a Single String value - var doc = {doc:'Serialize'}; - var simple_string_serialized = bsonC.serialize(doc, true, false); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize nested document'] = function(test) { - // Nested doc - var doc = {a:{b:{c:1}}}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple integer serialization/deserialization test, including testing boundary conditions'] = function(test) { - var doc = {doc:-1}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization test for a Long value'] = function(test) { - var doc = {doc:Long.fromNumber(9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:Long.fromNumber(-9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Float value'] = function(test) { - var doc = {doc:2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a null value'] = function(test) { - var doc = {doc:null}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:true}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a date value'] = function(test) { - var date = new Date(); - var doc = {doc:date}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:/abcd/mi}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - - var doc = {doc:/abcd/}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a objectId value'] = function(test) { - var doc = {doc:new ObjectID()}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value'] = function(test) { - var binary = new Binary(); - var string = 'binstring' - for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value of type 2'] = function(test) { - var binary = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Code value'] = function(test) { - var code = new Code('this.a > i', {'i': 1}); - var simple_string_serialized_2 = bsonJS.serialize({doc:code}, false, true); - var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for an Object'] = function(test) { - var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - - // Simple serialization and deserialization for an Array - var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a DBRef'] = function(test) { - var oid = new ObjectID() - var oid2 = new ObjectID.createFromHexString(oid.toHexString()) - var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - // Ensure we have the same values for the dbref - var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object_c = bsonC.deserialize(simple_string_serialized); - - assert.equal(object_js.doc.namespace, object_c.doc.namespace); - assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); - assert.equal(object_js.doc.db, object_c.doc.db); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize bytes array'] = function(test) { - // Serialized document - var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal('Patty', object.name) - assert.equal(34, object.age) - assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize utf8'] = function(test) { - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.equal(doc.name, object.name) - assert.equal(doc.name1, object.name1) - assert.equal(doc.name2, object.name2) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize object with array'] = function(test) { - var doc = {b:[1, 2, 3]}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc, object) - test.done(); -} - -/** - * @ignore - */ -exports['Test equality of an object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id_2 = new ObjectID(); - assert.ok(object_id.equals(object_id)); - assert.ok(!(object_id.equals(object_id_2))) - test.done(); -} - -/** - * @ignore - */ -exports['Test same serialization for Object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id2 = ObjectID.createFromHexString(object_id.toString()) - var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - - assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object2 = bsonC.deserialize(simple_string_serialized); - assert.equal(object.doc.id, object2.doc.id) - test.done(); -} - -/** - * @ignore - */ -exports['Complex object serialization'] = function(test) { - // JS Object - var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; - var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - - // C++ Object - var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; - var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) - }; - - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - - for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); - } - - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc._id.id, doc1._id.id) - assert.equal(doc._id.id, doc2._id.id) - assert.equal(doc1._id.id, doc2._id.id) - - var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize function'] = function(test) { - var doc = { - _id: 'testid', - key1: function() {} - } - - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Deserialize the string - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize document with special operators'] = function(test) { - var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Should serialize to the same value - assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) - var doc1 = bsonJS.deserialize(simple_string_serialized_2); - var doc2 = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc1, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Create ObjectID from hex string'] = function(test) { - // Hex Id - var hexId = new ObjectID().toString(); - var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docJSBin = bsonJS.serialize(docJS, false, true, true); - var docCBin = bsonC.serialize(docC, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize big complex document'] = function(test) { - // Complex document serialization - var doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} - var docJSBin = bsonJS.serialize(doc, false, true, true); - var docCBin = bsonC.serialize(doc, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Should error out due to 24 characters but not valid hexstring for ObjectID'] = function(test) { - try { - var oid = new ObjectID("tttttttttttttttttttttttt"); - test.ok(false); - } catch(err) {} - - test.done(); -} - - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js deleted file mode 100644 index 9eb5756e193..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js +++ /dev/null @@ -1,1694 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - ObjectId = mongoO.ObjectId, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - vm = require('vm'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly create ObjectID and do deep equals'] = function(test) { - var test_string = {hello: new ObjectID()}; - test_string.hello.toHexString(); - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly get BSON types from require'] = function(test) { - var _mongodb = require('../../lib/bson'); - test.ok(_mongodb.ObjectID === ObjectID); - test.ok(_mongodb.Binary === Binary); - test.ok(_mongodb.Long === Long); - test.ok(_mongodb.Timestamp === Timestamp); - test.ok(_mongodb.Code === Code); - test.ok(_mongodb.DBRef === DBRef); - test.ok(_mongodb.Symbol === Symbol); - test.ok(_mongodb.MinKey === MinKey); - test.ok(_mongodb.MaxKey === MaxKey); - test.ok(_mongodb.Double === Double); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary')); - test.equal("a_1", object.name); - test.equal(false, object.unique); - test.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary'));//, false, true); - // Perform tests - test.equal("hello", object.string); - test.deepEqual([1,2,3], object.array); - test.equal(1, object.hash.a); - test.equal(2, object.hash.b); - test.ok(object.date != null); - test.ok(object.oid != null); - test.ok(object.binary != null); - test.equal(42, object.int); - test.equal(33.3333, object.float); - test.ok(object.regexp != null); - test.equal(true, object.boolean); - test.ok(object.where != null); - test.ok(object.dbref != null); - test.ok(object[null] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize Empty String'] = function(test) { - var test_string = {hello: ''}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data2)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_null, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_null)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_null, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(null, object.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -5600}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: 2147483647}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -2147483648}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.age, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.age); - test.deepEqual(doc.doc.name, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.name); - test.deepEqual(doc.doc.shoe_size, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.shoe_size); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - Array.prototype.toXml = function() {}; - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize a nested object'] = function(test) { - var doc = {doc: {doc:1}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date(); - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date from another VM'] = function(test) { - var script = "date1 = new Date();", - ctx = vm.createContext({ - date1 : null - }); - vm.runInContext(script, ctx, 'myfile.vm'); - - var date = ctx.date1; - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize nested doc'] = function(test) { - var doc = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - - subObject: { - moreText: "Bacon ipsum dolor.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string" - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()}; - var doc2 = {doc: ObjectID.createFromHexString(doc.doc.toHexString())}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var decoded_hash = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc; - var keys = []; - - for(var name in decoded_hash) keys.push(name); - test.deepEqual(['b', 'a', 'c', 'd'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - // Serialize the regular expression - var doc = {doc: /foobar/mi}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.toString(), doc2.doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary(); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Type 2 Binary object'] = function(test) { - var bin = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary(); - bin.write(data); - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports["Should Correctly Serialize and Deserialize DBRef"] = function(test) { - var oid = new ObjectID(); - var doc = {dbref: new DBRef('namespace', oid, null)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal("namespace", doc2.dbref.namespace); - test.deepEqual(doc2.dbref.oid.toHexString(), oid.toHexString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize partial DBRef'] = function(test) { - var id = new ObjectID(); - var doc = {'name':'something', 'user':{'$ref':'username', '$id': id}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal('something', doc2.name); - test.equal('username', doc2.user.namespace); - test.equal(id.toString(), doc2.user.oid.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple Int'] = function(test) { - var doc = {doc:2147483648}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, doc2.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer'] = function(test) { - var doc = {doc: Long.fromNumber(9223372036854775807)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775809)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Deserialize Large Integers as Number not Long'] = function(test) { - function roundTrip(val) { - var doc = {doc: val}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - }; - - roundTrip(Math.pow(2,52)); - roundTrip(Math.pow(2,53) - 1); - roundTrip(Math.pow(2,53)); - roundTrip(-Math.pow(2,52)); - roundTrip(-Math.pow(2,53) + 1); - roundTrip(-Math.pow(2,53)); - roundTrip(Math.pow(2,65)); // Too big for Long. - roundTrip(-Math.pow(2,65)); - roundTrip(9223372036854775807); - roundTrip(1234567890123456800); // Bigger than 2^53, stays a double. - roundTrip(-1234567890123456800); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer and Timestamp as different types'] = function(test) { - var long = Long.fromNumber(9223372036854775807); - var timestamp = Timestamp.fromNumber(9223372036854775807); - test.ok(long instanceof Long); - test.ok(!(long instanceof Timestamp)); - test.ok(timestamp instanceof Timestamp); - test.ok(!(timestamp instanceof Long)); - - var test_int = {doc: long, doc2: timestamp}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(test_int.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Always put the id as the first item in a hash'] = function(test) { - var hash = {doc: {not_id:1, '_id':2}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(hash, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(hash)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(hash, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - var keys = []; - - for(var name in deserialized_data.doc) { - keys.push(name); - } - - test.deepEqual(['not_id', '_id'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a User defined Binary object'] = function(test) { - var bin = new Binary(); - bin.sub_type = BSON.BSON_BINARY_SUBTYPE_USER_DEFINED; - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(deserialized_data.doc.sub_type, BSON.BSON_BINARY_SUBTYPE_USER_DEFINED); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correclty Serialize and Deserialize a Code object'] = function(test) { - var doc = {'doc': {'doc2': new Code('this.a > i', {i:1})}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.doc2.code, deserialized_data.doc.doc2.code); - test.deepEqual(doc.doc.doc2.scope.i, deserialized_data.doc.doc2.scope.i); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly serialize and deserialize and embedded array'] = function(test) { - var doc = {'a':0, - 'b':['tmp1', 'tmp2', 'tmp3', 'tmp4', 'tmp5', 'tmp6', 'tmp7', 'tmp8', 'tmp9', 'tmp10', 'tmp11', 'tmp12', 'tmp13', 'tmp14', 'tmp15', 'tmp16'] - }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.a, deserialized_data.a); - test.deepEqual(doc.b, deserialized_data.b); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize UTF8'] = function(test) { - // Serialize utf8 - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize query object'] = function(test) { - var doc = { count: 'remove_with_no_callback_bug_test', query: {}, fields: null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize empty query object'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize array based doc'] = function(test) { - var doc = { b: [ 1, 2, 3 ], _id: new ObjectID() }; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Symbol'] = function(test) { - if(Symbol != null) { - var doc = { b: [ new Symbol('test') ]}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.ok(deserialized_data.b[0] instanceof Symbol); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should handle Deeply nested document'] = function(test) { - var doc = {a:{b:{c:{d:2}}}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should handle complicated all typed object'] = function(test) { - // First doc - var date = new Date(); - var oid = new ObjectID(); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - // Second doc - var oid = new ObjectID.createFromHexString(oid.toHexString()); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc2 = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize Complex Nested Object'] = function(test) { - var doc = { email: 'email@email.com', - encrypted_password: 'password', - friends: [ '4db96b973d01205364000006', - '4dc77b24c5ba38be14000002' ], - location: [ 72.4930088, 23.0431957 ], - name: 'Amit Kumar', - password_salt: 'salty', - profile_fields: [], - username: 'amit', - _id: new ObjectID() } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = doc; - doc2._id = ObjectID.createFromHexString(doc2._id.toHexString()); - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly massive doc'] = function(test) { - var oid1 = new ObjectID(); - var oid2 = new ObjectID(); - - // JS doc - var doc = { dbref2: new DBRef('namespace', oid1, 'integration_tests_'), - _id: oid2 }; - - var doc2 = { dbref2: new DBRef('namespace', ObjectID.createFromHexString(oid1.toHexString()), 'integration_tests_'), - _id: new ObjectID.createFromHexString(oid2.toHexString()) }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize regexp object'] = function(test) { - var doc = {'b':/foobaré/}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize complicated object'] = function(test) { - var doc = {a:{b:{c:[new ObjectID(), new ObjectID()]}}, d:{f:1332.3323}}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object'] = function(test) { - var doc = { "_id" : { "date" : new Date(), "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object with even more nesting'] = function(test) { - var doc = { "_id" : { "date" : {a:1, b:2, c:new Date()}, "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize empty name object'] = function(test) { - var doc = {'':'test', - 'bbbb':1}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc2[''], 'test'); - test.equal(doc2['bbbb'], 1); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly handle Forced Doubles to ensure we allocate enough space for cap collections'] = function(test) { - if(Double != null) { - var doubleValue = new Double(100); - var doc = {value:doubleValue}; - - // Serialize - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({value:100}, doc2); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should deserialize correctly'] = function(test) { - var doc = { - "_id" : new ObjectID("4e886e687ff7ef5e00000162"), - "str" : "foreign", - "type" : 2, - "timestamp" : ISODate("2011-10-02T14:00:08.383Z"), - "links" : [ - "http://www.reddit.com/r/worldnews/comments/kybm0/uk_home_secretary_calls_for_the_scrapping_of_the/" - ] - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize and deserialize MinKey and MaxKey values'] = function(test) { - var doc = { - _id : new ObjectID("4e886e687ff7ef5e00000162"), - minKey : new MinKey(), - maxKey : new MaxKey() - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.ok(doc2.minKey instanceof MinKey); - test.ok(doc2.maxKey instanceof MaxKey); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize Double value'] = function(test) { - var doc = { - value : new Double(34343.2222) - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.ok(doc.value.valueOf(), doc2.value); - test.ok(doc.value.value, doc2.value); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly create objects'] = function(test) { - try { - var object1 = ObjectID.createFromHexString('000000000000000000000001') - var object2 = ObjectID.createFromHexString('00000000000000000000001') - test.ok(false); - } catch(err) { - test.ok(err != null); - } - - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly retrieve timestamp'] = function(test) { - var testDate = new Date(); - var object1 = new ObjectID(); - test.equal(Math.floor(testDate.getTime()/1000), Math.floor(object1.getTimestamp().getTime()/1000)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly throw error on bsonparser errors'] = function(test) { - var data = new Buffer(3); - var parser = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - - // Catch to small buffer error - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - data = new Buffer(5); - data[0] = 0xff; - data[1] = 0xff; - // Catch illegal size - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - // Finish up - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function BSON.calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the object without serializing the function - var size = BSON.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = BSON.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object using instance method'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the object without serializing the function - var size = bson.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = bson.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function BSON.serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object using a BSON instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function BSON.serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = BSON.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object using a bson instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = bson.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function BSON.deserialize - * @ignore - */ - exports['Should correctly deserialize a buffer using the BSON class level parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = BSON.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = BSON.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function deserialize - * @ignore - */ -exports['Should correctly deserialize a buffer using the BSON instance parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = bson.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = bson.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function BSON.deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should have a correct cached representation of the hexString'] = function (test) { - ObjectID.cacheHexString = true; - var a = new ObjectID; - var __id = a.__id; - test.equal(__id, a.toHexString()); - - // hexString - a = new ObjectID(__id); - test.equal(__id, a.toHexString()); - - // fromHexString - a = ObjectID.createFromHexString(__id); - test.equal(a.__id, a.toHexString()); - test.equal(__id, a.toHexString()); - - // number - var genTime = a.generationTime; - a = new ObjectID(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - - // generationTime - delete a.__id; - a.generationTime = genTime; - test.equal(__id, a.toHexString()); - - // createFromTime - a = ObjectId.createFromTime(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - ObjectId.cacheHexString = false; - - test.done(); -} - -/** - * @ignore - */ -// 'Should Correctly Function' = function(test) { -// var doc = {b:1, func:function() { -// this.b = 2; -// }}; -// -// var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); -// -// debug("----------------------------------------------------------------------") -// debug(inspect(serialized_data)) -// -// // var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); -// // new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); -// // assertBuffersEqual(test, serialized_data, serialized_data2, 0); -// var COUNT = 100000; -// -// // var b = null; -// // eval("b = function(x) { return x+x; }"); -// // var b = new Function("x", "return x+x;"); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// for (i=COUNT; --i>=0; ) { -// var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// } -// -// end = new Date -// console.log("time = ", end - start, "ms -", COUNT * 1000 / (end - start), " ops/sec") -// -// // debug(inspect(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).functionCache)) -// // -// // var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // // test.deepEqual(doc, doc2) -// // // -// // debug(inspect(doc2)) -// // doc2.func() -// // debug(inspect(doc2)) -// // -// // var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); -// // var doc3 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // -// // debug("-----------------------------------------------") -// // debug(inspect(doc3)) -// -// // var key = "0" -// // for(var i = 1; i < 10000; i++) { -// // key = key + " " + i -// // } -// -// test.done(); -// -// -// // var car = { -// // model : "Volvo", -// // country : "Sweden", -// // -// // isSwedish : function() { -// // return this.country == "Sweden"; -// // } -// // } -// -// }, - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js deleted file mode 100644 index cde83f8fd03..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js +++ /dev/null @@ -1,392 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': '客家è¯', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); - // Build a typed array - var arr = new Uint8Array(new ArrayBuffer(data.length)); - // Iterate over all the fields and copy - for(var i = 0; i < data.length; i++) { - arr[i] = data[i] - } - - // Deserialize the object - var object = BSONDE.BSON.deserialize(arr); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports['exercise all the binary object constructor methods'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(utils.stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - test.done(); -}; - -/** - * @ignore - */ -exports['exercise the put binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(utils.assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(utils.assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the write binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the read binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('world'), data)); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js deleted file mode 100644 index 7a78347ec7e..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js +++ /dev/null @@ -1,315 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonC.deserialize(serialized_data); - assert.equal("a_1", object.name); - assert.equal(false, object.unique); - assert.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal("hello", object.string); - assert.deepEqual([1, 2, 3], object.array); - assert.equal(1, object.hash.a); - assert.equal(2, object.hash.b); - assert.ok(object.date != null); - assert.ok(object.oid != null); - assert.ok(object.binary != null); - assert.equal(42, object.int); - assert.equal(33.3333, object.float); - assert.ok(object.regexp != null); - assert.equal(true, object.boolean); - assert.ok(object.where != null); - assert.ok(object.dbref != null); - assert.ok(object['null'] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'} - var serialized_data = bsonC.serialize(test_string) - assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null} - var serialized_data = bsonC.serialize(test_null) - var object = bsonC.deserialize(serialized_data); - assert.deepEqual(test_null, object); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize undefined value'] = function(test) { - var test_undefined = {doc:undefined} - var serialized_data = bsonC.serialize(test_undefined) - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal(null, object.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42} - var serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -5600} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: 2147483647} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -2147483648} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date() - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12) - date.setUTCFullYear(2009) - date.setUTCMonth(11 - 1) - date.setUTCHours(12) - date.setUTCMinutes(0) - date.setUTCSeconds(30) - var doc = {doc: date} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Buffer'] = function(test) { - var doc = {doc: new Buffer("123451234512345")} - var serialized_data = bsonC.serialize(doc) - - assert.equal("123451234512345", bsonC.deserialize(serialized_data).doc.buffer.toString('ascii')); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var test_code = {} - var serialized_data = bsonC.serialize(test_code) - assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}} - var serialized_data = bsonC.serialize(doc) - var decoded_hash = bsonC.deserialize(serialized_data).doc - var keys = [] - for(var name in decoded_hash) keys.push(name) - assert.deepEqual(['b', 'a', 'c', 'd'], keys) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - var doc = {doc: /foobar/mi} - var serialized_data = bsonC.serialize(doc) - var doc2 = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.toString(), doc2.doc.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary() - var string = 'binstring' - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary() - bin.write(data) - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js deleted file mode 100644 index e9282e54908..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js +++ /dev/null @@ -1,109 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser; - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should correctly handle toBson function for an object'] = function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var deserialized_doc = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({b:1}, deserialized_doc); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js deleted file mode 100644 index 9d7cbe7c6ea..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js +++ /dev/null @@ -1,80 +0,0 @@ -exports.assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -exports.stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -exports.stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -exports.Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js deleted file mode 100644 index c707cfcb56c..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js +++ /dev/null @@ -1,21 +0,0 @@ - -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE deleted file mode 100644 index 7c435baaec8..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js deleted file mode 100644 index 73834010f60..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js +++ /dev/null @@ -1,190 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css deleted file mode 100644 index 6583fe7c66d..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js deleted file mode 100644 index c3d2dc7d2d3..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png b/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png deleted file mode 100644 index 218f3b43713..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/package.json b/api/node_modules/mongoskin/node_modules/mongodb/package.json deleted file mode 100644 index 2326bf86fa5..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/package.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "name": "mongodb", - "description": "A node.js driver for MongoDB", - "keywords": [ - "mongodb", - "mongo", - "driver", - "db" - ], - "version": "1.2.14", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [ - { - "name": "Aaron Heckmann" - }, - { - "name": "Christoph Pojer" - }, - { - "name": "Pau Ramon Revilla" - }, - { - "name": "Nathan White" - }, - { - "name": "Emmerman" - }, - { - "name": "Seth LaForge" - }, - { - "name": "Boris Filipov" - }, - { - "name": "Stefan Schärmeli" - }, - { - "name": "Tedde Lundgren" - }, - { - "name": "renctan" - }, - { - "name": "Sergey Ukustov" - }, - { - "name": "Ciaran Jessup" - }, - { - "name": "kuno" - }, - { - "name": "srimonti" - }, - { - "name": "Erik Abele" - }, - { - "name": "Pratik Daga" - }, - { - "name": "Slobodan Utvic" - }, - { - "name": "Kristina Chodorow" - }, - { - "name": "Yonathan Randolph" - }, - { - "name": "Brian Noguchi" - }, - { - "name": "Sam Epstein" - }, - { - "name": "James Harrison Fisher" - }, - { - "name": "Vladimir Dronnikov" - }, - { - "name": "Ben Hockey" - }, - { - "name": "Henrik Johansson" - }, - { - "name": "Simon Weare" - }, - { - "name": "Alex Gorbatchev" - }, - { - "name": "Shimon Doodkin" - }, - { - "name": "Kyle Mueller" - }, - { - "name": "Eran Hammer-Lahav" - }, - { - "name": "Marcin Ciszak" - }, - { - "name": "François de Metz" - }, - { - "name": "Vinay Pulim" - }, - { - "name": "nstielau" - }, - { - "name": "Adam Wiggins" - }, - { - "name": "entrinzikyl" - }, - { - "name": "Jeremy Selier" - }, - { - "name": "Ian Millington" - }, - { - "name": "Public Keating" - }, - { - "name": "andrewjstone" - }, - { - "name": "Christopher Stott" - }, - { - "name": "Corey Jewett" - }, - { - "name": "brettkiefer" - }, - { - "name": "Rob Holland" - }, - { - "name": "Senmiao Liu" - }, - { - "name": "heroic" - }, - { - "name": "gitfy" - }, - { - "name": "Andrew Stone" - }, - { - "name": "John Le Drew" - }, - { - "name": "Lucasfilm Singapore" - }, - { - "name": "Roman Shtylman" - }, - { - "name": "Matt Self" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/mongodb/node-mongodb-native.git" - }, - "bugs": { - "url": "http://github.com/mongodb/node-mongodb-native/issues" - }, - "dependencies": { - "bson": "0.1.8" - }, - "devDependencies": { - "dox": "0.2.0", - "uglify-js": "1.2.5", - "ejs": "0.6.1", - "nodeunit": "0.7.4", - "github3": ">=0.3.0", - "markdown": "0.3.1", - "gleak": "0.2.3", - "step": "0.0.5", - "async": "0.1.22", - "integra": "0.0.1", - "optimist": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/mongodb/index", - "homepage": "http://mongodb.github.com/node-mongodb-native/", - "directories": { - "lib": "./lib/mongodb" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "test": "make test_functional" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Up to date documentation\n========================\n\n[Documentation](http://mongodb.github.com/node-mongodb-native/)\n\nInstall\n=======\n\nTo install the most recent release from npm, run:\n\n npm install mongodb\n\nThat may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version)\n\nTo install the latest from the repository, run::\n\n npm install path/to/node-mongodb-native\n\nCommunity\n=========\nCheck out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver.\n\nTry it live\n============\n\n\nIntroduction\n============\n\nThis is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/.\n\nA simple example of inserting a document.\n\n```javascript\n var client = new Db('test', new Server(\"127.0.0.1\", 27017, {}), {w: 1}),\n test = function (err, collection) {\n collection.insert({a:2}, function(err, docs) {\n\n collection.count(function(err, count) {\n test.assertEquals(1, count);\n });\n\n // Locate all the entries using find\n collection.find().toArray(function(err, results) {\n test.assertEquals(1, results.length);\n test.assertTrue(results[0].a === 2);\n\n // Let's close the db\n client.close();\n });\n });\n };\n\n client.open(function(err, p_client) {\n client.collection('test_insert', test);\n });\n```\n\nData types\n==========\n\nTo store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code).\n\nIn particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example:\n\n```javascript\n // Get the objectID type\n var ObjectID = require('mongodb').ObjectID;\n\n var idString = '4e4e1638c85e808431000003';\n collection.findOne({_id: new ObjectID(idString)}, console.log) // ok\n collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined\n```\n\nHere are the constructors the non-Javascript BSON primitive types:\n\n```javascript\n // Fetch the library\n var mongo = require('mongodb');\n // Create new instances of BSON types\n new mongo.Long(numberString)\n new mongo.ObjectID(hexString)\n new mongo.Timestamp() // the actual unique number is generated on insert.\n new mongo.DBRef(collectionName, id, dbName)\n new mongo.Binary(buffer) // takes a string or Buffer\n new mongo.Code(code, [context])\n new mongo.Symbol(string)\n new mongo.MinKey()\n new mongo.MaxKey()\n new mongo.Double(number)\t// Force double storage\n```\n\nThe C/C++ bson parser/serializer\n--------------------------------\n\nIf you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below\n\n```javascript\n // using native_parser:\n var client = new Db('integration_tests_20',\n new Server(\"127.0.0.1\", 27017),\n {native_parser:true});\n```\n\nThe C++ parser uses the js objects both for serialization and deserialization.\n\nGitHub information\n==================\n\nThe source code is available at http://github.com/mongodb/node-mongodb-native.\nYou can either clone the repository or download a tarball of the latest release.\n\nOnce you have the source you can test the driver by running\n\n $ make test\n\nin the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass.\n\nExamples\n========\n\nFor examples look in the examples/ directory. You can execute the examples using node.\n\n $ cd examples\n $ node queries.js\n\nGridStore\n=========\n\nThe GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition.\n\nFor more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)\n\nReplicasets\n===========\nFor more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md)\n\nPrimary Key Factories\n---------------------\n\nDefining your own primary key factory allows you to generate your own series of id's\n(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long \"string\".\n\nSimple example below\n\n```javascript\n // Custom factory (need to provide a 12 byte array);\n CustomPKFactory = function() {}\n CustomPKFactory.prototype = new Object();\n CustomPKFactory.createPk = function() {\n return new ObjectID(\"aaaaaaaaaaaa\");\n }\n\n var p_client = new Db('integration_tests_20', new Server(\"127.0.0.1\", 27017, {}), {'pk':CustomPKFactory});\n p_client.open(function(err, p_client) {\n p_client.dropDatabase(function(err, done) {\n p_client.createCollection('test_custom_key', function(err, collection) {\n collection.insert({'a':1}, function(err, docs) {\n collection.find({'_id':new ObjectID(\"aaaaaaaaaaaa\")}, function(err, cursor) {\n cursor.toArray(function(err, items) {\n test.assertEquals(1, items.length);\n\n // Let's close the db\n p_client.close();\n });\n });\n });\n });\n });\n });\n```\n\nStrict mode\n-----------\n\nEach database has an optional strict mode. If it is set then asking for a collection\nthat does not exist will return an Error object in the callback. Similarly if you\nattempt to create a collection that already exists. Strict is provided for convenience.\n\n```javascript\n var error_client = new Db('integration_tests_', new Server(\"127.0.0.1\", 27017, {auto_reconnect: false}), {strict:true});\n test.assertEquals(true, error_client.strict);\n\n error_client.open(function(err, error_client) {\n error_client.collection('does-not-exist', function(err, collection) {\n test.assertTrue(err instanceof Error);\n test.assertEquals(\"Collection does-not-exist does not exist. Currently in strict mode.\", err.message);\n });\n\n error_client.createCollection('test_strict_access_collection', function(err, collection) {\n error_client.collection('test_strict_access_collection', function(err, collection) {\n test.assertTrue(collection instanceof Collection);\n // Let's close the db\n error_client.close();\n });\n });\n });\n```\n\nDocumentation\n=============\n\nIf this document doesn't answer your questions, see the source of\n[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js)\nor [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js),\nor the documentation at MongoDB for query and update formats.\n\nFind\n----\n\nThe find method is actually a factory method to create\nCursor objects. A Cursor lazily uses the connection the first time\nyou call `nextObject`, `each`, or `toArray`.\n\nThe basic operation on a cursor is the `nextObject` method\nthat fetches the next matching document from the database. The convenience\nmethods `each` and `toArray` call `nextObject` until the cursor is exhausted.\n\nSignatures:\n\n```javascript\n var cursor = collection.find(query, [fields], options);\n cursor.sort(fields).limit(n).skip(m).\n\n cursor.nextObject(function(err, doc) {});\n cursor.each(function(err, doc) {});\n cursor.toArray(function(err, docs) {});\n\n cursor.rewind() // reset the cursor to its initial state.\n```\n\nUseful chainable methods of cursor. These can optionally be options of `find` instead of method calls:\n\n* `.limit(n).skip(m)` to control paging.\n* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes:\n * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2.\n * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above\n * `.sort([['field1', 'desc'], 'field2'])` same as above\n * `.sort('field1')` ascending by field1\n\nOther options of `find`:\n\n* `fields` the fields to fetch (to avoid transferring the entire document)\n* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors).\n* `batchSize` The number of the subset of results to request the database\nto return for every request. This should initially be greater than 1 otherwise\nthe database will automatically close the cursor. The batch size can be set to 1\nwith `batchSize(n, function(err){})` after performing the initial query to the database.\n* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint).\n* `explain` turns this into an explain query. You can also call\n`explain()` on any cursor to fetch the explanation.\n* `snapshot` prevents documents that are updated while the query is active\nfrom being returned multiple times. See more\n[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database).\n* `timeout` if false, asks MongoDb not to time out this cursor after an\ninactivity period.\n\n\nFor information on how to create queries, see the\n[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.find({}, {limit:10}).toArray(function(err, docs) {\n console.dir(docs);\n });\n });\n```\n\nInsert\n------\n\nSignature:\n\n```javascript\n collection.insert(docs, options, [callback]);\n```\n\nwhere `docs` can be a single document or an array of documents.\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n\nSee also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.insert({hello: 'world'}, {safe:true},\n function(err, objects) {\n if (err) console.warn(err.message);\n if (err && err.message.indexOf('E11000 ') !== -1) {\n // this _id was already inserted in the database\n }\n });\n });\n```\n\nNote that there's no reason to pass a callback to the insert or update commands\nunless you use the `safe:true` option. If you don't specify `safe:true`, then\nyour callback will be called immediately.\n\nUpdate; update and insert (upsert)\n----------------------------------\n\nThe update operation will update the first document that matches your query\n(or all documents that match if you use `multi:true`).\nIf `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated.\n\nSee the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for\nthe modifier (`$inc`, `$set`, `$push`, etc.) formats.\n\nSignature:\n\n```javascript\n collection.update(criteria, objNew, options, [callback]);\n```\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n* `multi:true` If set, all matching documents are updated, not just the first.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `update`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true},\n function(err) {\n if (err) console.warn(err.message);\n else console.log('successfully updated');\n });\n });\n```\n\nFind and modify\n---------------\n\n`findAndModify` is like `update`, but it also gives the updated document to\nyour callback. But there are a few key differences between findAndModify and\nupdate:\n\n 1. The signatures differ.\n 2. You can only findAndModify a single item, not multiple items.\n\nSignature:\n\n```javascript\n collection.findAndModify(query, sort, update, options, callback)\n```\n\nThe sort parameter is used to specify which object to operate on, if more than\none document matches. It takes the same format as the cursor sort (see\nConnection.find above).\n\nSee the\n[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command)\nfor more details.\n\nUseful options:\n\n* `remove:true` set to a true to remove the object before returning\n* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `findAndModify`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {},\n function(err, object) {\n if (err) console.warn(err.message);\n else console.dir(object); // undefined if no matching object exists.\n });\n });\n```\n\nSave\n----\n\nThe `save` method is a shorthand for upsert if the document contains an\n`_id`, or an insert if there is no `_id`.\n\nSponsors\n========\nJust as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB.\n\nIf your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details.\n\nAnd I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing.\n\nRelease Notes\n=============\n\nSee HISTORY\n\nCredits\n=======\n\n1. [10gen](http://github.com/mongodb/mongo-ruby-driver/)\n2. [Google Closure Library](http://code.google.com/closure/library/)\n3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser)\n\nContributors\n============\n\nAaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy\n\nLicense\n=======\n\n Copyright 2009 - 2012 Christian Amor Kvalheim.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n", - "readmeFilename": "Readme.md", - "_id": "mongodb@1.2.14", - "_from": "mongodb@1.2.14", - "dist": { - "shasum": "ed4907d6b3b6b45ce2b4f69cb27bd57fed0636c2" - }, - "_resolved": "https://registry.npmjs.org/mongodb/-/mongodb-1.2.14.tgz" -} diff --git a/api/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp b/api/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp b/api/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp deleted file mode 100644 index 74cba0de8ca..00000000000 Binary files a/api/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp and /dev/null differ diff --git a/api/node_modules/mongoskin/node_modules/mongodb/upload.py b/api/node_modules/mongoskin/node_modules/mongodb/upload.py deleted file mode 100644 index 6296fdeddd2..00000000000 --- a/api/node_modules/mongoskin/node_modules/mongodb/upload.py +++ /dev/null @@ -1,2347 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 -# -# Copyright 2007 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tool for uploading diffs from a version control system to the codereview app. - -Usage summary: upload.py [options] [-- diff_options] [path...] - -Diff options are passed to the diff command of the underlying system. - -Supported version control systems: - Git - Mercurial - Subversion - Perforce - CVS - -It is important for Git/Mercurial users to specify a tree/node/branch to diff -against by using the '--rev' option. -""" -# This code is derived from appcfg.py in the App Engine SDK (open source), -# and from ASPN recipe #146306. - -import ConfigParser -import cookielib -import errno -import fnmatch -import getpass -import logging -import marshal -import mimetypes -import optparse -import os -import re -import socket -import subprocess -import sys -import urllib -import urllib2 -import urlparse - -# The md5 module was deprecated in Python 2.5. -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - -try: - import readline -except ImportError: - pass - -try: - import keyring -except ImportError: - keyring = None - -# The logging verbosity: -# 0: Errors only. -# 1: Status messages. -# 2: Info logs. -# 3: Debug logs. -verbosity = 1 - -# The account type used for authentication. -# This line could be changed by the review server (see handler for -# upload.py). -AUTH_ACCOUNT_TYPE = "HOSTED" - -# URL of the default review server. As for AUTH_ACCOUNT_TYPE, this line could be -# changed by the review server (see handler for upload.py). -DEFAULT_REVIEW_SERVER = "codereview.10gen.com" - -# Max size of patch or base file. -MAX_UPLOAD_SIZE = 900 * 1024 - -# Constants for version control names. Used by GuessVCSName. -VCS_GIT = "Git" -VCS_MERCURIAL = "Mercurial" -VCS_SUBVERSION = "Subversion" -VCS_PERFORCE = "Perforce" -VCS_CVS = "CVS" -VCS_UNKNOWN = "Unknown" - -VCS_ABBREVIATIONS = { - VCS_MERCURIAL.lower(): VCS_MERCURIAL, - "hg": VCS_MERCURIAL, - VCS_SUBVERSION.lower(): VCS_SUBVERSION, - "svn": VCS_SUBVERSION, - VCS_PERFORCE.lower(): VCS_PERFORCE, - "p4": VCS_PERFORCE, - VCS_GIT.lower(): VCS_GIT, - VCS_CVS.lower(): VCS_CVS, -} - -# The result of parsing Subversion's [auto-props] setting. -svn_auto_props_map = None - -def GetEmail(prompt): - """Prompts the user for their email address and returns it. - - The last used email address is saved to a file and offered up as a suggestion - to the user. If the user presses enter without typing in anything the last - used email address is used. If the user enters a new address, it is saved - for next time we prompt. - - """ - last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") - last_email = "" - if os.path.exists(last_email_file_name): - try: - last_email_file = open(last_email_file_name, "r") - last_email = last_email_file.readline().strip("\n") - last_email_file.close() - prompt += " [%s]" % last_email - except IOError, e: - pass - email = raw_input(prompt + ": ").strip() - if email: - try: - last_email_file = open(last_email_file_name, "w") - last_email_file.write(email) - last_email_file.close() - except IOError, e: - pass - else: - email = last_email - return email - - -def StatusUpdate(msg): - """Print a status message to stdout. - - If 'verbosity' is greater than 0, print the message. - - Args: - msg: The string to print. - """ - if verbosity > 0: - print msg - - -def ErrorExit(msg): - """Print an error message to stderr and exit.""" - print >>sys.stderr, msg - sys.exit(1) - - -class ClientLoginError(urllib2.HTTPError): - """Raised to indicate there was an error authenticating with ClientLogin.""" - - def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) - self.args = args - self.reason = args["Error"] - self.info = args.get("Info", None) - - -class AbstractRpcServer(object): - """Provides a common interface for a simple RPC server.""" - - def __init__(self, host, auth_function, host_override=None, extra_headers={}, - save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): - """Creates a new HttpRpcServer. - - Args: - host: The host to send requests to. - auth_function: A function that takes no arguments and returns an - (email, password) tuple when called. Will be called if authentication - is required. - host_override: The host header to send to the server (defaults to host). - extra_headers: A dict of extra headers to append to every request. - save_cookies: If True, save the authentication cookies to local disk. - If False, use an in-memory cookiejar instead. Subclasses must - implement this functionality. Defaults to False. - account_type: Account type used for authentication. Defaults to - AUTH_ACCOUNT_TYPE. - """ - self.host = host - if (not self.host.startswith("http://") and - not self.host.startswith("https://")): - self.host = "http://" + self.host - self.host_override = host_override - self.auth_function = auth_function - self.authenticated = False - self.extra_headers = extra_headers - self.save_cookies = save_cookies - self.account_type = account_type - self.opener = self._GetOpener() - if self.host_override: - logging.info("Server: %s; Host: %s", self.host, self.host_override) - else: - logging.info("Server: %s", self.host) - - def _GetOpener(self): - """Returns an OpenerDirector for making HTTP requests. - - Returns: - A urllib2.OpenerDirector object. - """ - raise NotImplementedError() - - def _CreateRequest(self, url, data=None): - """Creates a new urllib request.""" - logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data, headers={"Accept": "text/plain"}) - if self.host_override: - req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): - req.add_header(key, value) - return req - - def _GetAuthToken(self, email, password): - """Uses ClientLogin to authenticate the user, returning an auth token. - - Args: - email: The user's email address - password: The user's password - - Raises: - ClientLoginError: If there was an error authenticating with ClientLogin. - HTTPError: If there was some other form of HTTP error. - - Returns: - The authentication token returned by ClientLogin. - """ - account_type = self.account_type - if self.host.endswith(".google.com"): - # Needed for use inside Google. - account_type = "HOSTED" - req = self._CreateRequest( - url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ - "Email": email, - "Passwd": password, - "service": "ah", - "source": "rietveld-codereview-upload", - "accountType": account_type, - }), - ) - try: - response = self.opener.open(req) - response_body = response.read() - response_dict = dict(x.split("=") - for x in response_body.split("\n") if x) - return response_dict["Auth"] - except urllib2.HTTPError, e: - if e.code == 403: - body = e.read() - response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) - raise ClientLoginError(req.get_full_url(), e.code, e.msg, - e.headers, response_dict) - else: - raise - - def _GetAuthCookie(self, auth_token): - """Fetches authentication cookies for an authentication token. - - Args: - auth_token: The authentication token returned by ClientLogin. - - Raises: - HTTPError: If there was an error fetching the authentication cookies. - """ - # This is a dummy value to allow us to identify when we're successful. - continue_location = "http://localhost/" - args = {"continue": continue_location, "auth": auth_token} - req = self._CreateRequest("%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) - try: - response = self.opener.open(req) - except urllib2.HTTPError, e: - response = e - if (response.code != 302 or - response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) - self.authenticated = True - - def _Authenticate(self): - """Authenticates the user. - - The authentication process works as follows: - 1) We get a username and password from the user - 2) We use ClientLogin to obtain an AUTH token for the user - (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). - 3) We pass the auth token to /_ah/login on the server to obtain an - authentication cookie. If login was successful, it tries to redirect - us to the URL we provided. - - If we attempt to access the upload API without first obtaining an - authentication cookie, it returns a 401 response (or a 302) and - directs us to authenticate ourselves with ClientLogin. - """ - for i in range(3): - credentials = self.auth_function() - try: - auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: - print >>sys.stderr, '' - if e.reason == "BadAuthentication": - if e.info == "InvalidSecondFactor": - print >>sys.stderr, ( - "Use an application-specific password instead " - "of your regular account password.\n" - "See http://www.google.com/" - "support/accounts/bin/answer.py?answer=185833") - else: - print >>sys.stderr, "Invalid username or password." - elif e.reason == "CaptchaRequired": - print >>sys.stderr, ( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.\n" - "If you are using a Google Apps account the URL is:\n" - "https://www.google.com/a/yourdomain.com/UnlockCaptcha") - elif e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." - elif e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." - elif e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." - elif e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." - break - elif e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") - elif e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." - else: - # Unknown error. - raise - print >>sys.stderr, '' - continue - self._GetAuthCookie(auth_token) - return - - def Send(self, request_path, payload=None, - content_type="application/octet-stream", - timeout=None, - extra_headers=None, - **kwargs): - """Sends an RPC and returns the response. - - Args: - request_path: The path to send the request to, eg /api/appversion/create. - payload: The body of the request, or None to send an empty request. - content_type: The Content-Type header to use. - timeout: timeout in seconds; default None i.e. no timeout. - (Note: for large requests on OS X, the timeout doesn't work right.) - extra_headers: Dict containing additional HTTP headers that should be - included in the request (string header names mapped to their values), - or None to not include any additional headers. - kwargs: Any keyword arguments are converted into query string parameters. - - Returns: - The response body, as a string. - """ - # TODO: Don't require authentication. Let the server say - # whether it is necessary. - if not self.authenticated: - self._Authenticate() - - old_timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) - try: - tries = 0 - while True: - tries += 1 - args = dict(kwargs) - url = "%s%s" % (self.host, request_path) - if args: - url += "?" + urllib.urlencode(args) - req = self._CreateRequest(url=url, data=payload) - req.add_header("Content-Type", content_type) - if extra_headers: - for header, value in extra_headers.items(): - req.add_header(header, value) - try: - f = self.opener.open(req) - response = f.read() - f.close() - return response - except urllib2.HTTPError, e: - if tries > 3: - raise - elif e.code == 401 or e.code == 302: - self._Authenticate() - elif e.code == 301: - # Handle permanent redirect manually. - url = e.info()["location"] - url_loc = urlparse.urlparse(url) - self.host = '%s://%s' % (url_loc[0], url_loc[1]) - elif e.code >= 500: - ErrorExit(e.read()) - else: - raise - finally: - socket.setdefaulttimeout(old_timeout) - - -class HttpRpcServer(AbstractRpcServer): - """Provides a simplified RPC-style interface for HTTP requests.""" - - def _Authenticate(self): - """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() - if self.save_cookies: - StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) - self.cookie_jar.save() - - def _GetOpener(self): - """Returns an OpenerDirector that supports cookies and ignores redirects. - - Returns: - A urllib2.OpenerDirector object. - """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) - if self.save_cookies: - self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) - if os.path.exists(self.cookie_file): - try: - self.cookie_jar.load() - self.authenticated = True - StatusUpdate("Loaded authentication cookies from %s" % - self.cookie_file) - except (cookielib.LoadError, IOError): - # Failed to load cookies - just ignore them. - pass - else: - # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) - os.close(fd) - # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) - else: - # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) - return opener - - -class CondensedHelpFormatter(optparse.IndentedHelpFormatter): - """Frees more horizontal space by removing indentation from group - options and collapsing arguments between short and long, e.g. - '-o ARG, --opt=ARG' to -o --opt ARG""" - - def format_heading(self, heading): - return "%s:\n" % heading - - def format_option(self, option): - self.dedent() - res = optparse.HelpFormatter.format_option(self, option) - self.indent() - return res - - def format_option_strings(self, option): - self.set_long_opt_delimiter(" ") - optstr = optparse.HelpFormatter.format_option_strings(self, option) - optlist = optstr.split(", ") - if len(optlist) > 1: - if option.takes_value(): - # strip METAVAR from all but the last option - optlist = [x.split()[0] for x in optlist[:-1]] + optlist[-1:] - optstr = " ".join(optlist) - return optstr - - -parser = optparse.OptionParser( - usage="%prog [options] [-- diff_options] [path...]", - add_help_option=False, - formatter=CondensedHelpFormatter() -) -parser.add_option("-h", "--help", action="store_true", - help="Show this help message and exit.") -parser.add_option("-y", "--assume_yes", action="store_true", - dest="assume_yes", default=False, - help="Assume that the answer to yes/no questions is 'yes'.") -# Logging -group = parser.add_option_group("Logging options") -group.add_option("-q", "--quiet", action="store_const", const=0, - dest="verbose", help="Print errors only.") -group.add_option("-v", "--verbose", action="store_const", const=2, - dest="verbose", default=1, - help="Print info level logs.") -group.add_option("--noisy", action="store_const", const=3, - dest="verbose", help="Print all logs.") -group.add_option("--print_diffs", dest="print_diffs", action="store_true", - help="Print full diffs.") -# Review server -group = parser.add_option_group("Review server options") -group.add_option("-s", "--server", action="store", dest="server", - default=DEFAULT_REVIEW_SERVER, - metavar="SERVER", - help=("The server to upload to. The format is host[:port]. " - "Defaults to '%default'.")) -group.add_option("-e", "--email", action="store", dest="email", - metavar="EMAIL", default=None, - help="The username to use. Will prompt if omitted.") -group.add_option("-H", "--host", action="store", dest="host", - metavar="HOST", default=None, - help="Overrides the Host header sent with all RPCs.") -group.add_option("--no_cookies", action="store_false", - dest="save_cookies", default=True, - help="Do not save authentication cookies to local disk.") -group.add_option("--account_type", action="store", dest="account_type", - metavar="TYPE", default=AUTH_ACCOUNT_TYPE, - choices=["GOOGLE", "HOSTED"], - help=("Override the default account type " - "(defaults to '%default', " - "valid choices are 'GOOGLE' and 'HOSTED').")) -# Issue -group = parser.add_option_group("Issue options") -group.add_option("-t", "--title", action="store", dest="title", - help="New issue subject or new patch set title") -group.add_option("-m", "--message", action="store", dest="message", - default=None, - help="New issue description or new patch set message") -group.add_option("-F", "--file", action="store", dest="file", - default=None, help="Read the message above from file.") -group.add_option("-r", "--reviewers", action="store", dest="reviewers", - metavar="REVIEWERS", default=None, - help="Add reviewers (comma separated email addresses).") -group.add_option("--cc", action="store", dest="cc", - metavar="CC", default=None, - help="Add CC (comma separated email addresses).") -group.add_option("--private", action="store_true", dest="private", - default=False, - help="Make the issue restricted to reviewers and those CCed") -# Upload options -group = parser.add_option_group("Patch options") -group.add_option("-i", "--issue", type="int", action="store", - metavar="ISSUE", default=None, - help="Issue number to which to add. Defaults to new issue.") -group.add_option("--base_url", action="store", dest="base_url", default=None, - help="Base URL path for files (listed as \"Base URL\" when " - "viewing issue). If omitted, will be guessed automatically " - "for SVN repos and left blank for others.") -group.add_option("--download_base", action="store_true", - dest="download_base", default=False, - help="Base files will be downloaded by the server " - "(side-by-side diffs may not work on files with CRs).") -group.add_option("--rev", action="store", dest="revision", - metavar="REV", default=None, - help="Base revision/branch/tree to diff against. Use " - "rev1:rev2 range to review already committed changeset.") -group.add_option("--send_mail", action="store_true", - dest="send_mail", default=False, - help="Send notification email to reviewers.") -group.add_option("-p", "--send_patch", action="store_true", - dest="send_patch", default=False, - help="Same as --send_mail, but include diff as an " - "attachment, and prepend email subject with 'PATCH:'.") -group.add_option("--vcs", action="store", dest="vcs", - metavar="VCS", default=None, - help=("Version control system (optional, usually upload.py " - "already guesses the right VCS).")) -group.add_option("--emulate_svn_auto_props", action="store_true", - dest="emulate_svn_auto_props", default=False, - help=("Emulate Subversion's auto properties feature.")) -# Perforce-specific -group = parser.add_option_group("Perforce-specific options " - "(overrides P4 environment variables)") -group.add_option("--p4_port", action="store", dest="p4_port", - metavar="P4_PORT", default=None, - help=("Perforce server and port (optional)")) -group.add_option("--p4_changelist", action="store", dest="p4_changelist", - metavar="P4_CHANGELIST", default=None, - help=("Perforce changelist id")) -group.add_option("--p4_client", action="store", dest="p4_client", - metavar="P4_CLIENT", default=None, - help=("Perforce client/workspace")) -group.add_option("--p4_user", action="store", dest="p4_user", - metavar="P4_USER", default=None, - help=("Perforce user")) - -def GetRpcServer(server, email=None, host_override=None, save_cookies=True, - account_type=AUTH_ACCOUNT_TYPE): - """Returns an instance of an AbstractRpcServer. - - Args: - server: String containing the review server URL. - email: String containing user's email address. - host_override: If not None, string containing an alternate hostname to use - in the host header. - save_cookies: Whether authentication cookies should be saved to disk. - account_type: Account type for authentication, either 'GOOGLE' - or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. - - Returns: - A new AbstractRpcServer, on which RPC calls can be made. - """ - - rpc_server_class = HttpRpcServer - - # If this is the dev_appserver, use fake authentication. - host = (host_override or server).lower() - if re.match(r'(http://)?localhost([:/]|$)', host): - if email is None: - email = "test@example.com" - logging.info("Using debug user %s. Override with --email" % email) - server = rpc_server_class( - server, - lambda: (email, "password"), - host_override=host_override, - extra_headers={"Cookie": - 'dev_appserver_login="%s:False"' % email}, - save_cookies=save_cookies, - account_type=account_type) - # Don't try to talk to ClientLogin. - server.authenticated = True - return server - - def GetUserCredentials(): - """Prompts the user for a username and password.""" - # Create a local alias to the email variable to avoid Python's crazy - # scoping rules. - global keyring - local_email = email - if local_email is None: - local_email = GetEmail("Email (login for uploading to %s)" % server) - password = None - if keyring: - try: - password = keyring.get_password(host, local_email) - except: - # Sadly, we have to trap all errors here as - # gnomekeyring.IOError inherits from object. :/ - print "Failed to get password from keyring" - keyring = None - if password is not None: - print "Using password from system keyring." - else: - password = getpass.getpass("Password for %s: " % local_email) - if keyring: - answer = raw_input("Store password in system keyring?(y/N) ").strip() - if answer == "y": - keyring.set_password(host, local_email, password) - return (local_email, password) - - return rpc_server_class(server, - GetUserCredentials, - host_override=host_override, - save_cookies=save_cookies) - - -def EncodeMultipartFormData(fields, files): - """Encode form fields for multipart/form-data. - - Args: - fields: A sequence of (name, value) elements for regular form fields. - files: A sequence of (name, filename, value) elements for data to be - uploaded as files. - Returns: - (content_type, body) ready for httplib.HTTP instance. - - Source: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 - """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - for (key, value) in fields: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - for (key, filename, value) in files: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - lines.append('Content-Type: %s' % GetContentType(filename)) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - -def GetContentType(filename): - """Helper to guess the content-type from the filename.""" - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - -# Use a shell for subcommands on Windows to get a PATH search. -use_shell = sys.platform.startswith("win") - -def RunShellWithReturnCodeAndStderr(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout, stderr and the return code. - - Args: - command: Command to execute. - print_output: If True, the output is printed to stdout. - If False, both stdout and stderr are ignored. - universal_newlines: Use universal_newlines flag (default: True). - - Returns: - Tuple (stdout, stderr, return code) - """ - logging.info("Running %s", command) - env = env.copy() - env['LC_MESSAGES'] = 'C' - p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=use_shell, universal_newlines=universal_newlines, - env=env) - if print_output: - output_array = [] - while True: - line = p.stdout.readline() - if not line: - break - print line.strip("\n") - output_array.append(line) - output = "".join(output_array) - else: - output = p.stdout.read() - p.wait() - errout = p.stderr.read() - if print_output and errout: - print >>sys.stderr, errout - p.stdout.close() - p.stderr.close() - return output, errout, p.returncode - -def RunShellWithReturnCode(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout and the return code.""" - out, err, retcode = RunShellWithReturnCodeAndStderr(command, print_output, - universal_newlines, env) - return out, retcode - -def RunShell(command, silent_ok=False, universal_newlines=True, - print_output=False, env=os.environ): - data, retcode = RunShellWithReturnCode(command, print_output, - universal_newlines, env) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) - if not silent_ok and not data: - ErrorExit("No output from %s" % command) - return data - - -class VersionControlSystem(object): - """Abstract base class providing an interface to the VCS.""" - - def __init__(self, options): - """Constructor. - - Args: - options: Command line options. - """ - self.options = options - - def GetGUID(self): - """Return string to distinguish the repository from others, for example to - query all opened review issues for it""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def PostProcessDiff(self, diff): - """Return the diff with any special post processing this VCS needs, e.g. - to include an svn-style "Index:".""" - return diff - - def GenerateDiff(self, args): - """Return the current diff as a string. - - Args: - args: Extra arguments to pass to the diff command. - """ - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def CheckForUnknownFiles(self): - """Show an "are you sure?" prompt if there are unknown files.""" - unknown_files = self.GetUnknownFiles() - if unknown_files: - print "The following files are not added to version control:" - for line in unknown_files: - print line - prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() - if answer != "y": - ErrorExit("User aborted") - - def GetBaseFile(self, filename): - """Get the content of the upstream version of a file. - - Returns: - A tuple (base_content, new_content, is_binary, status) - base_content: The contents of the base file. - new_content: For text files, this is empty. For binary files, this is - the contents of the new file, since the diff output won't contain - information to reconstruct the current file. - is_binary: True iff the file is binary. - status: The status of the file. - """ - - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - - def GetBaseFiles(self, diff): - """Helper that calls GetBase file for each file in the patch. - - Returns: - A dictionary that maps from filename to GetBaseFile's tuple. Filenames - are retrieved based on lines that start with "Index:" or - "Property changes on:". - """ - files = {} - for line in diff.splitlines(True): - if line.startswith('Index:') or line.startswith('Property changes on:'): - unused, filename = line.split(':', 1) - # On Windows if a file has property changes its filename uses '\' - # instead of '/'. - filename = filename.strip().replace('\\', '/') - files[filename] = self.GetBaseFile(filename) - return files - - - def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, - files): - """Uploads the base files (and if necessary, the current ones as well).""" - - def UploadFile(filename, file_id, content, is_binary, status, is_base): - """Uploads a file to the server.""" - file_too_large = False - if is_base: - type = "base" - else: - type = "current" - if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % - (type, filename)) - file_too_large = True - content = "" - checksum = md5(content).hexdigest() - if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) - url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) - form_fields = [("filename", filename), - ("status", status), - ("checksum", checksum), - ("is_binary", str(is_binary)), - ("is_current", str(not is_base)), - ] - if file_too_large: - form_fields.append(("file_too_large", "1")) - if options.email: - form_fields.append(("user", options.email)) - ctype, body = EncodeMultipartFormData(form_fields, - [("data", filename, content)]) - response_body = rpc_server.Send(url, body, - content_type=ctype) - if not response_body.startswith("OK"): - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - - patches = dict() - [patches.setdefault(v, k) for k, v in patch_list] - for filename in patches.keys(): - base_content, new_content, is_binary, status = files[filename] - file_id_str = patches.get(filename) - if file_id_str.find("nobase") != -1: - base_content = None - file_id_str = file_id_str[file_id_str.rfind("_") + 1:] - file_id = int(file_id_str) - if base_content != None: - UploadFile(filename, file_id, base_content, is_binary, status, True) - if new_content != None: - UploadFile(filename, file_id, new_content, is_binary, status, False) - - def IsImage(self, filename): - """Returns true if the filename has an image extension.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False - return mimetype.startswith("image/") - - def IsBinaryData(self, data): - """Returns true if data contains a null byte.""" - # Derived from how Mercurial's heuristic, see - # http://selenic.com/hg/file/848a6658069e/mercurial/util.py#l229 - return bool(data and "\0" in data) - - -class SubversionVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Subversion.""" - - def __init__(self, options): - super(SubversionVCS, self).__init__(options) - if self.options.revision: - match = re.match(r"(\d+)(:(\d+))?", self.options.revision) - if not match: - ErrorExit("Invalid Subversion revision %s." % self.options.revision) - self.rev_start = match.group(1) - self.rev_end = match.group(3) - else: - self.rev_start = self.rev_end = None - # Cache output from "svn list -r REVNO dirname". - # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). - self.svnls_cache = {} - # Base URL is required to fetch files deleted in an older revision. - # Result is cached to not guess it over and over again in GetBaseFile(). - required = self.options.download_base or self.options.revision is not None - self.svn_base = self._GuessBase(required) - - def GetGUID(self): - return self._GetInfo("Repository UUID") - - def GuessBase(self, required): - """Wrapper for _GuessBase.""" - return self.svn_base - - def _GuessBase(self, required): - """Returns base URL for current diff. - - Args: - required: If true, exits if the url can't be guessed, otherwise None is - returned. - """ - url = self._GetInfo("URL") - if url: - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - guess = "" - # TODO(anatoli) - repository specific hacks should be handled by server - if netloc == "svn.python.org" and scheme == "svn+ssh": - path = "projects" + path - scheme = "http" - guess = "Python " - elif netloc.endswith(".googlecode.com"): - scheme = "http" - guess = "Google Code " - path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - logging.info("Guessed %sbase = %s", guess, base) - return base - if required: - ErrorExit("Can't find URL in output from svn info") - return None - - def _GetInfo(self, key): - """Parses 'svn info' for current dir. Returns value for key or None""" - for line in RunShell(["svn", "info"]).splitlines(): - if line.startswith(key + ": "): - return line.split(":", 1)[1].strip() - - def _EscapeFilename(self, filename): - """Escapes filename for SVN commands.""" - if "@" in filename and not filename.endswith("@"): - filename = "%s@" % filename - return filename - - def GenerateDiff(self, args): - cmd = ["svn", "diff"] - if self.options.revision: - cmd += ["-r", self.options.revision] - cmd.extend(args) - data = RunShell(cmd) - count = 0 - for line in data.splitlines(): - if line.startswith("Index:") or line.startswith("Property changes on:"): - count += 1 - logging.info(line) - if not count: - ErrorExit("No valid patches found in output from svn diff") - return data - - def _CollapseKeywords(self, content, keyword_str): - """Collapses SVN keywords.""" - # svn cat translates keywords but svn diff doesn't. As a result of this - # behavior patching.PatchChunks() fails with a chunk mismatch error. - # This part was originally written by the Review Board development team - # who had the same problem (http://reviews.review-board.org/r/276/). - # Mapping of keywords to known aliases - svn_keywords = { - # Standard keywords - 'Date': ['Date', 'LastChangedDate'], - 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], - 'Author': ['Author', 'LastChangedBy'], - 'HeadURL': ['HeadURL', 'URL'], - 'Id': ['Id'], - - # Aliases - 'LastChangedDate': ['LastChangedDate', 'Date'], - 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], - 'LastChangedBy': ['LastChangedBy', 'Author'], - 'URL': ['URL', 'HeadURL'], - } - - def repl(m): - if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) - return "$%s$" % m.group(1) - keywords = [keyword - for name in keyword_str.split(" ") - for keyword in svn_keywords.get(name, [])] - return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) - - def GetUnknownFiles(self): - status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) - unknown_files = [] - for line in status.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - - def ReadFile(self, filename): - """Returns the contents of a file.""" - file = open(filename, 'rb') - result = "" - try: - result = file.read() - finally: - file.close() - return result - - def GetStatus(self, filename): - """Returns the status of a file.""" - if not self.options.revision: - status = RunShell(["svn", "status", "--ignore-externals", - self._EscapeFilename(filename)]) - if not status: - ErrorExit("svn status returned no output for %s" % filename) - status_lines = status.splitlines() - # If file is in a cl, the output will begin with - # "\n--- Changelist 'cl_name':\n". See - # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt - if (len(status_lines) == 3 and - not status_lines[0] and - status_lines[1].startswith("--- Changelist")): - status = status_lines[2] - else: - status = status_lines[0] - # If we have a revision to diff against we need to run "svn list" - # for the old and the new revision and compare the results to get - # the correct status for a file. - else: - dirname, relfilename = os.path.split(filename) - if dirname not in self.svnls_cache: - cmd = ["svn", "list", "-r", self.rev_start, - self._EscapeFilename(dirname) or "."] - out, err, returncode = RunShellWithReturnCodeAndStderr(cmd) - if returncode: - # Directory might not yet exist at start revison - # svn: Unable to find repository location for 'abc' in revision nnn - if re.match('^svn: Unable to find repository location for .+ in revision \d+', err): - old_files = () - else: - ErrorExit("Failed to get status for %s:\n%s" % (filename, err)) - else: - old_files = out.splitlines() - args = ["svn", "list"] - if self.rev_end: - args += ["-r", self.rev_end] - cmd = args + [self._EscapeFilename(dirname) or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to run command %s" % cmd) - self.svnls_cache[dirname] = (old_files, out.splitlines()) - old_files, new_files = self.svnls_cache[dirname] - if relfilename in old_files and relfilename not in new_files: - status = "D " - elif relfilename in old_files and relfilename in new_files: - status = "M " - else: - status = "A " - return status - - def GetBaseFile(self, filename): - status = self.GetStatus(filename) - base_content = None - new_content = None - - # If a file is copied its status will be "A +", which signifies - # "addition-with-history". See "svn st" for more information. We need to - # upload the original file or else diff parsing will fail if the file was - # edited. - if status[0] == "A" and status[3] != "+": - # We'll need to upload the new content if we're adding a binary file - # since diff's output won't contain it. - mimetype = RunShell(["svn", "propget", "svn:mime-type", - self._EscapeFilename(filename)], silent_ok=True) - base_content = "" - is_binary = bool(mimetype) and not mimetype.startswith("text/") - if is_binary and self.IsImage(filename): - new_content = self.ReadFile(filename) - elif (status[0] in ("M", "D", "R") or - (status[0] == "A" and status[3] == "+") or # Copied file. - (status[0] == " " and status[1] == "M")): # Property change. - args = [] - if self.options.revision: - # filename must not be escaped. We already add an ampersand here. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - # Don't change filename, it's needed later. - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:mime-type", url] - mimetype, returncode = RunShellWithReturnCode(cmd) - if returncode: - # File does not exist in the requested revision. - # Reset mimetype, it contains an error message. - mimetype = "" - else: - mimetype = mimetype.strip() - get_base = False - # this test for binary is exactly the test prescribed by the - # official SVN docs at - # http://subversion.apache.org/faq.html#binary-files - is_binary = (bool(mimetype) and - not mimetype.startswith("text/") and - mimetype not in ("image/x-xbitmap", "image/x-xpixmap")) - if status[0] == " ": - # Empty base content just to force an upload. - base_content = "" - elif is_binary: - if self.IsImage(filename): - get_base = True - if status[0] == "M": - if not self.rev_end: - new_content = self.ReadFile(filename) - else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) - new_content = RunShell(["svn", "cat", url], - universal_newlines=True, silent_ok=True) - else: - base_content = "" - else: - get_base = True - - if get_base: - if is_binary: - universal_newlines = False - else: - universal_newlines = True - if self.rev_start: - # "svn cat -r REV delete_file.txt" doesn't work. cat requires - # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - else: - base_content, ret_code = RunShellWithReturnCode( - ["svn", "cat", self._EscapeFilename(filename)], - universal_newlines=universal_newlines) - if ret_code and status[0] == "R": - # It's a replaced file without local history (see issue208). - # The base file needs to be fetched from the server. - url = "%s/%s" % (self.svn_base, filename) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - elif ret_code: - ErrorExit("Got error status from 'svn cat %s'" % filename) - if not is_binary: - args = [] - if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:keywords", url] - keywords, returncode = RunShellWithReturnCode(cmd) - if keywords and not returncode: - base_content = self._CollapseKeywords(base_content, keywords) - else: - StatusUpdate("svn status returned unexpected output: %s" % status) - sys.exit(1) - return base_content, new_content, is_binary, status[0:5] - - -class GitVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Git.""" - - def __init__(self, options): - super(GitVCS, self).__init__(options) - # Map of filename -> (hash before, hash after) of base file. - # Hashes for "no such file" are represented as None. - self.hashes = {} - # Map of new filename -> old filename for renames. - self.renames = {} - - def GetGUID(self): - revlist = RunShell("git rev-list --parents HEAD".split()).splitlines() - # M-A: Return the 1st root hash, there could be multiple when a - # subtree is merged. In that case, more analysis would need to - # be done to figure out which HEAD is the 'most representative'. - for r in revlist: - if ' ' not in r: - return r - - def PostProcessDiff(self, gitdiff): - """Converts the diff output to include an svn-style "Index:" line as well - as record the hashes of the files, so we can upload them along with our - diff.""" - # Special used by git to indicate "no such content". - NULL_HASH = "0"*40 - - def IsFileNew(filename): - return filename in self.hashes and self.hashes[filename][0] is None - - def AddSubversionPropertyChange(filename): - """Add svn's property change information into the patch if given file is - new file. - - We use Subversion's auto-props setting to retrieve its property. - See http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2 for - Subversion's [auto-props] setting. - """ - if self.options.emulate_svn_auto_props and IsFileNew(filename): - svnprops = GetSubversionPropertyChanges(filename) - if svnprops: - svndiff.append("\n" + svnprops + "\n") - - svndiff = [] - filecount = 0 - filename = None - for line in gitdiff.splitlines(): - match = re.match(r"diff --git a/(.*) b/(.*)$", line) - if match: - # Add auto property here for previously seen file. - if filename is not None: - AddSubversionPropertyChange(filename) - filecount += 1 - # Intentionally use the "after" filename so we can show renames. - filename = match.group(2) - svndiff.append("Index: %s\n" % filename) - if match.group(1) != match.group(2): - self.renames[match.group(2)] = match.group(1) - else: - # The "index" line in a git diff looks like this (long hashes elided): - # index 82c0d44..b2cee3f 100755 - # We want to save the left hash, as that identifies the base file. - match = re.match(r"index (\w+)\.\.(\w+)", line) - if match: - before, after = (match.group(1), match.group(2)) - if before == NULL_HASH: - before = None - if after == NULL_HASH: - after = None - self.hashes[filename] = (before, after) - svndiff.append(line + "\n") - if not filecount: - ErrorExit("No valid patches found in output from git diff") - # Add auto property for the last seen file. - assert filename is not None - AddSubversionPropertyChange(filename) - return "".join(svndiff) - - def GenerateDiff(self, extra_args): - extra_args = extra_args[:] - if self.options.revision: - if ":" in self.options.revision: - extra_args = self.options.revision.split(":", 1) + extra_args - else: - extra_args = [self.options.revision] + extra_args - - # --no-ext-diff is broken in some versions of Git, so try to work around - # this by overriding the environment (but there is still a problem if the - # git config key "diff.external" is used). - env = os.environ.copy() - if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] - return RunShell( - [ "git", "diff", "--no-color", "--no-ext-diff", "--full-index", - "--ignore-submodules", "-M"] + extra_args, - env=env) - - def GetUnknownFiles(self): - status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], - silent_ok=True) - return status.splitlines() - - def GetFileContent(self, file_hash, is_binary): - """Returns the content of a file identified by its git hash.""" - data, retcode = RunShellWithReturnCode(["git", "show", file_hash], - universal_newlines=not is_binary) - if retcode: - ErrorExit("Got error status from 'git show %s'" % file_hash) - return data - - def GetBaseFile(self, filename): - hash_before, hash_after = self.hashes.get(filename, (None,None)) - base_content = None - new_content = None - status = None - - if filename in self.renames: - status = "A +" # Match svn attribute name for renames. - if filename not in self.hashes: - # If a rename doesn't change the content, we never get a hash. - base_content = RunShell( - ["git", "show", "HEAD:" + filename], silent_ok=True) - elif not hash_before: - status = "A" - base_content = "" - elif not hash_after: - status = "D" - else: - status = "M" - - is_binary = self.IsBinaryData(base_content) - is_image = self.IsImage(filename) - - # Grab the before/after content if we need it. - # We should include file contents if it's text or it's an image. - if not is_binary or is_image: - # Grab the base content if we don't have it already. - if base_content is None and hash_before: - base_content = self.GetFileContent(hash_before, is_binary) - # Only include the "after" file if it's an image; otherwise it - # it is reconstructed from the diff. - if is_image and hash_after: - new_content = self.GetFileContent(hash_after, is_binary) - - return (base_content, new_content, is_binary, status) - - -class CVSVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for CVS.""" - - def __init__(self, options): - super(CVSVCS, self).__init__(options) - - def GetGUID(self): - """For now we don't know how to get repository ID for CVS""" - return - - def GetOriginalContent_(self, filename): - RunShell(["cvs", "up", filename], silent_ok=True) - # TODO need detect file content encoding - content = open(filename).read() - return content.replace("\r\n", "\n") - - def GetBaseFile(self, filename): - base_content = None - new_content = None - status = "A" - - output, retcode = RunShellWithReturnCode(["cvs", "status", filename]) - if retcode: - ErrorExit("Got error status from 'cvs status %s'" % filename) - - if output.find("Status: Locally Modified") != -1: - status = "M" - temp_filename = "%s.tmp123" % filename - os.rename(filename, temp_filename) - base_content = self.GetOriginalContent_(filename) - os.rename(temp_filename, filename) - elif output.find("Status: Locally Added"): - status = "A" - base_content = "" - elif output.find("Status: Needs Checkout"): - status = "D" - base_content = self.GetOriginalContent_(filename) - - return (base_content, new_content, self.IsBinaryData(base_content), status) - - def GenerateDiff(self, extra_args): - cmd = ["cvs", "diff", "-u", "-N"] - if self.options.revision: - cmd += ["-r", self.options.revision] - - cmd.extend(extra_args) - data, retcode = RunShellWithReturnCode(cmd) - count = 0 - if retcode in [0, 1]: - for line in data.splitlines(): - if line.startswith("Index:"): - count += 1 - logging.info(line) - - if not count: - ErrorExit("No valid patches found in output from cvs diff") - - return data - - def GetUnknownFiles(self): - data, retcode = RunShellWithReturnCode(["cvs", "diff"]) - if retcode not in [0, 1]: - ErrorExit("Got error status from 'cvs diff':\n%s" % (data,)) - unknown_files = [] - for line in data.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - -class MercurialVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Mercurial.""" - - def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) - # Absolute path to repository (we can be in a subdir) - self.repo_dir = os.path.normpath(repo_dir) - # Compute the subdir - cwd = os.path.normpath(os.getcwd()) - assert cwd.startswith(self.repo_dir) - self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") - if self.options.revision: - self.base_rev = self.options.revision - else: - self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() - - def GetGUID(self): - # See chapter "Uniquely identifying a repository" - # http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html - info = RunShell("hg log -r0 --template {node}".split()) - return info.strip() - - def _GetRelPath(self, filename): - """Get relative path of a file according to the current directory, - given its logical path in the repo.""" - absname = os.path.join(self.repo_dir, filename) - return os.path.relpath(absname) - - def GenerateDiff(self, extra_args): - cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args - data = RunShell(cmd, silent_ok=True) - svndiff = [] - filecount = 0 - for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) - if m: - # Modify line to make it look like as it comes from svn diff. - # With this modification no changes on the server side are required - # to make upload.py work with Mercurial repos. - # NOTE: for proper handling of moved/copied files, we have to use - # the second filename. - filename = m.group(2) - svndiff.append("Index: %s" % filename) - svndiff.append("=" * 67) - filecount += 1 - logging.info(line) - else: - svndiff.append(line) - if not filecount: - ErrorExit("No valid patches found in output from hg diff") - return "\n".join(svndiff) + "\n" - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - args = [] - status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], - silent_ok=True) - unknown_files = [] - for line in status.splitlines(): - st, fn = line.split(" ", 1) - if st == "?": - unknown_files.append(fn) - return unknown_files - - def GetBaseFile(self, filename): - # "hg status" and "hg cat" both take a path relative to the current subdir, - # but "hg diff" has given us the path relative to the repo root. - base_content = "" - new_content = None - is_binary = False - oldrelpath = relpath = self._GetRelPath(filename) - # "hg status -C" returns two lines for moved/copied files, one otherwise - out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) - out = out.splitlines() - # HACK: strip error message about missing file/directory if it isn't in - # the working copy - if out[0].startswith('%s: ' % relpath): - out = out[1:] - status, _ = out[0].split(' ', 1) - if len(out) > 1 and status == "A": - # Moved/copied => considered as modified, use old filename to - # retrieve base contents - oldrelpath = out[1].strip() - status = "M" - if ":" in self.base_rev: - base_rev = self.base_rev.split(":", 1)[0] - else: - base_rev = self.base_rev - if status != "A": - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True) - is_binary = self.IsBinaryData(base_content) - if status != "R": - new_content = open(relpath, "rb").read() - is_binary = is_binary or self.IsBinaryData(new_content) - if is_binary and base_content: - # Fetch again without converting newlines - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True, universal_newlines=False) - if not is_binary or not self.IsImage(relpath): - new_content = None - return base_content, new_content, is_binary, status - - -class PerforceVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Perforce.""" - - def __init__(self, options): - - def ConfirmLogin(): - # Make sure we have a valid perforce session - while True: - data, retcode = self.RunPerforceCommandWithReturnCode( - ["login", "-s"], marshal_output=True) - if not data: - ErrorExit("Error checking perforce login") - if not retcode and (not "code" in data or data["code"] != "error"): - break - print "Enter perforce password: " - self.RunPerforceCommandWithReturnCode(["login"]) - - super(PerforceVCS, self).__init__(options) - - self.p4_changelist = options.p4_changelist - if not self.p4_changelist: - ErrorExit("A changelist id is required") - if (options.revision): - ErrorExit("--rev is not supported for perforce") - - self.p4_port = options.p4_port - self.p4_client = options.p4_client - self.p4_user = options.p4_user - - ConfirmLogin() - - if not options.title: - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - if description and "desc" in description: - # Rietveld doesn't support multi-line descriptions - raw_title = description["desc"].strip() - lines = raw_title.splitlines() - if len(lines): - options.title = lines[0] - - def GetGUID(self): - """For now we don't know how to get repository ID for Perforce""" - return - - def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False, - universal_newlines=True): - args = ["p4"] - if marshal_output: - # -G makes perforce format its output as marshalled python objects - args.extend(["-G"]) - if self.p4_port: - args.extend(["-p", self.p4_port]) - if self.p4_client: - args.extend(["-c", self.p4_client]) - if self.p4_user: - args.extend(["-u", self.p4_user]) - args.extend(extra_args) - - data, retcode = RunShellWithReturnCode( - args, print_output=False, universal_newlines=universal_newlines) - if marshal_output and data: - data = marshal.loads(data) - return data, retcode - - def RunPerforceCommand(self, extra_args, marshal_output=False, - universal_newlines=True): - # This might be a good place to cache call results, since things like - # describe or fstat might get called repeatedly. - data, retcode = self.RunPerforceCommandWithReturnCode( - extra_args, marshal_output, universal_newlines) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (extra_args, data)) - return data - - def GetFileProperties(self, property_key_prefix = "", command = "describe"): - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - - changed_files = {} - file_index = 0 - # Try depotFile0, depotFile1, ... until we don't find a match - while True: - file_key = "depotFile%d" % file_index - if file_key in description: - filename = description[file_key] - change_type = description[property_key_prefix + str(file_index)] - changed_files[filename] = change_type - file_index += 1 - else: - break - return changed_files - - def GetChangedFiles(self): - return self.GetFileProperties("action") - - def GetUnknownFiles(self): - # Perforce doesn't detect new files, they have to be explicitly added - return [] - - def IsBaseBinary(self, filename): - base_filename = self.GetBaseFilename(filename) - return self.IsBinaryHelper(base_filename, "files") - - def IsPendingBinary(self, filename): - return self.IsBinaryHelper(filename, "describe") - - def IsBinaryHelper(self, filename, command): - file_types = self.GetFileProperties("type", command) - if not filename in file_types: - ErrorExit("Trying to check binary status of unknown file %s." % filename) - # This treats symlinks, macintosh resource files, temporary objects, and - # unicode as binary. See the Perforce docs for more details: - # http://www.perforce.com/perforce/doc.current/manuals/cmdref/o.ftypes.html - return not file_types[filename].endswith("text") - - def GetFileContent(self, filename, revision, is_binary): - file_arg = filename - if revision: - file_arg += "#" + revision - # -q suppresses the initial line that displays the filename and revision - return self.RunPerforceCommand(["print", "-q", file_arg], - universal_newlines=not is_binary) - - def GetBaseFilename(self, filename): - actionsWithDifferentBases = [ - "move/add", # p4 move - "branch", # p4 integrate (to a new file), similar to hg "add" - "add", # p4 integrate (to a new file), after modifying the new file - ] - - # We only see a different base for "add" if this is a downgraded branch - # after a file was branched (integrated), then edited. - if self.GetAction(filename) in actionsWithDifferentBases: - # -Or shows information about pending integrations/moves - fstat_result = self.RunPerforceCommand(["fstat", "-Or", filename], - marshal_output=True) - - baseFileKey = "resolveFromFile0" # I think it's safe to use only file0 - if baseFileKey in fstat_result: - return fstat_result[baseFileKey] - - return filename - - def GetBaseRevision(self, filename): - base_filename = self.GetBaseFilename(filename) - - have_result = self.RunPerforceCommand(["have", base_filename], - marshal_output=True) - if "haveRev" in have_result: - return have_result["haveRev"] - - def GetLocalFilename(self, filename): - where = self.RunPerforceCommand(["where", filename], marshal_output=True) - if "path" in where: - return where["path"] - - def GenerateDiff(self, args): - class DiffData: - def __init__(self, perforceVCS, filename, action): - self.perforceVCS = perforceVCS - self.filename = filename - self.action = action - self.base_filename = perforceVCS.GetBaseFilename(filename) - - self.file_body = None - self.base_rev = None - self.prefix = None - self.working_copy = True - self.change_summary = None - - def GenerateDiffHeader(diffData): - header = [] - header.append("Index: %s" % diffData.filename) - header.append("=" * 67) - - if diffData.base_filename != diffData.filename: - if diffData.action.startswith("move"): - verb = "rename" - else: - verb = "copy" - header.append("%s from %s" % (verb, diffData.base_filename)) - header.append("%s to %s" % (verb, diffData.filename)) - - suffix = "\t(revision %s)" % diffData.base_rev - header.append("--- " + diffData.base_filename + suffix) - if diffData.working_copy: - suffix = "\t(working copy)" - header.append("+++ " + diffData.filename + suffix) - if diffData.change_summary: - header.append(diffData.change_summary) - return header - - def GenerateMergeDiff(diffData, args): - # -du generates a unified diff, which is nearly svn format - diffData.file_body = self.RunPerforceCommand( - ["diff", "-du", diffData.filename] + args) - diffData.base_rev = self.GetBaseRevision(diffData.filename) - diffData.prefix = "" - - # We have to replace p4's file status output (the lines starting - # with +++ or ---) to match svn's diff format - lines = diffData.file_body.splitlines() - first_good_line = 0 - while (first_good_line < len(lines) and - not lines[first_good_line].startswith("@@")): - first_good_line += 1 - diffData.file_body = "\n".join(lines[first_good_line:]) - return diffData - - def GenerateAddDiff(diffData): - fstat = self.RunPerforceCommand(["fstat", diffData.filename], - marshal_output=True) - if "headRev" in fstat: - diffData.base_rev = fstat["headRev"] # Re-adding a deleted file - else: - diffData.base_rev = "0" # Brand new file - diffData.working_copy = False - rel_path = self.GetLocalFilename(diffData.filename) - diffData.file_body = open(rel_path, 'r').read() - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -0,0 +1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " @@" - diffData.prefix = "+" - return diffData - - def GenerateDeleteDiff(diffData): - diffData.base_rev = self.GetBaseRevision(diffData.filename) - is_base_binary = self.IsBaseBinary(diffData.filename) - # For deletes, base_filename == filename - diffData.file_body = self.GetFileContent(diffData.base_filename, - None, - is_base_binary) - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " +0,0 @@" - diffData.prefix = "-" - return diffData - - changed_files = self.GetChangedFiles() - - svndiff = [] - filecount = 0 - for (filename, action) in changed_files.items(): - svn_status = self.PerforceActionToSvnStatus(action) - if svn_status == "SKIP": - continue - - diffData = DiffData(self, filename, action) - # Is it possible to diff a branched file? Stackoverflow says no: - # http://stackoverflow.com/questions/1771314/in-perforce-command-line-how-to-diff-a-file-reopened-for-add - if svn_status == "M": - diffData = GenerateMergeDiff(diffData, args) - elif svn_status == "A": - diffData = GenerateAddDiff(diffData) - elif svn_status == "D": - diffData = GenerateDeleteDiff(diffData) - else: - ErrorExit("Unknown file action %s (svn action %s)." % \ - (action, svn_status)) - - svndiff += GenerateDiffHeader(diffData) - - for line in diffData.file_body.splitlines(): - svndiff.append(diffData.prefix + line) - filecount += 1 - if not filecount: - ErrorExit("No valid patches found in output from p4 diff") - return "\n".join(svndiff) + "\n" - - def PerforceActionToSvnStatus(self, status): - # Mirroring the list at http://permalink.gmane.org/gmane.comp.version-control.mercurial.devel/28717 - # Is there something more official? - return { - "add" : "A", - "branch" : "A", - "delete" : "D", - "edit" : "M", # Also includes changing file types. - "integrate" : "M", - "move/add" : "M", - "move/delete": "SKIP", - "purge" : "D", # How does a file's status become "purge"? - }[status] - - def GetAction(self, filename): - changed_files = self.GetChangedFiles() - if not filename in changed_files: - ErrorExit("Trying to get base version of unknown file %s." % filename) - - return changed_files[filename] - - def GetBaseFile(self, filename): - base_filename = self.GetBaseFilename(filename) - base_content = "" - new_content = None - - status = self.PerforceActionToSvnStatus(self.GetAction(filename)) - - if status != "A": - revision = self.GetBaseRevision(base_filename) - if not revision: - ErrorExit("Couldn't find base revision for file %s" % filename) - is_base_binary = self.IsBaseBinary(base_filename) - base_content = self.GetFileContent(base_filename, - revision, - is_base_binary) - - is_binary = self.IsPendingBinary(filename) - if status != "D" and status != "SKIP": - relpath = self.GetLocalFilename(filename) - if is_binary and self.IsImage(relpath): - new_content = open(relpath, "rb").read() - - return base_content, new_content, is_binary, status - -# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. -def SplitPatch(data): - """Splits a patch into separate pieces for each file. - - Args: - data: A string containing the output of svn diff. - - Returns: - A list of 2-tuple (filename, text) where text is the svn diff output - pertaining to filename. - """ - patches = [] - filename = None - diff = [] - for line in data.splitlines(True): - new_filename = None - if line.startswith('Index:'): - unused, new_filename = line.split(':', 1) - new_filename = new_filename.strip() - elif line.startswith('Property changes on:'): - unused, temp_filename = line.split(':', 1) - # When a file is modified, paths use '/' between directories, however - # when a property is modified '\' is used on Windows. Make them the same - # otherwise the file shows up twice. - temp_filename = temp_filename.strip().replace('\\', '/') - if temp_filename != filename: - # File has property changes but no modifications, create a new diff. - new_filename = temp_filename - if new_filename: - if filename and diff: - patches.append((filename, ''.join(diff))) - filename = new_filename - diff = [line] - continue - if diff is not None: - diff.append(line) - if filename and diff: - patches.append((filename, ''.join(diff))) - return patches - - -def UploadSeparatePatches(issue, rpc_server, patchset, data, options): - """Uploads a separate patch for each file in the diff output. - - Returns a list of [patch_key, filename] for each file. - """ - patches = SplitPatch(data) - rv = [] - for patch in patches: - if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + - " because the file is too large.") - continue - form_fields = [("filename", patch[0])] - if not options.download_base: - form_fields.append(("content_upload", "1")) - files = [("data", "data.diff", patch[1])] - ctype, body = EncodeMultipartFormData(form_fields, files) - url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] - response_body = rpc_server.Send(url, body, content_type=ctype) - lines = response_body.splitlines() - if not lines or lines[0] != "OK": - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - rv.append([lines[1], patch[0]]) - return rv - - -def GuessVCSName(options): - """Helper to guess the version control system. - - This examines the current directory, guesses which VersionControlSystem - we're using, and returns an string indicating which VCS is detected. - - Returns: - A pair (vcs, output). vcs is a string indicating which VCS was detected - and is one of VCS_GIT, VCS_MERCURIAL, VCS_SUBVERSION, VCS_PERFORCE, - VCS_CVS, or VCS_UNKNOWN. - Since local perforce repositories can't be easily detected, this method - will only guess VCS_PERFORCE if any perforce options have been specified. - output is a string containing any interesting output from the vcs - detection routine, or None if there is nothing interesting. - """ - for attribute, value in options.__dict__.iteritems(): - if attribute.startswith("p4") and value != None: - return (VCS_PERFORCE, None) - - def RunDetectCommand(vcs_type, command): - """Helper to detect VCS by executing command. - - Returns: - A pair (vcs, output) or None. Throws exception on error. - """ - try: - out, returncode = RunShellWithReturnCode(command) - if returncode == 0: - return (vcs_type, out.strip()) - except OSError, (errcode, message): - if errcode != errno.ENOENT: # command not found code - raise - - # Mercurial has a command to get the base directory of a repository - # Try running it, but don't die if we don't have hg installed. - # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. - res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) - if res != None: - return res - - # Subversion from 1.7 has a single centralized .svn folder - # ( see http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng ) - # That's why we use 'svn info' instead of checking for .svn dir - res = RunDetectCommand(VCS_SUBVERSION, ["svn", "info"]) - if res != None: - return res - - # Git has a command to test if you're in a git tree. - # Try running it, but don't die if we don't have git installed. - res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", - "--is-inside-work-tree"]) - if res != None: - return res - - # detect CVS repos use `cvs status && $? == 0` rules - res = RunDetectCommand(VCS_CVS, ["cvs", "status"]) - if res != None: - return res - - return (VCS_UNKNOWN, None) - - -def GuessVCS(options): - """Helper to guess the version control system. - - This verifies any user-specified VersionControlSystem (by command line - or environment variable). If the user didn't specify one, this examines - the current directory, guesses which VersionControlSystem we're using, - and returns an instance of the appropriate class. Exit with an error - if we can't figure it out. - - Returns: - A VersionControlSystem instance. Exits if the VCS can't be guessed. - """ - vcs = options.vcs - if not vcs: - vcs = os.environ.get("CODEREVIEW_VCS") - if vcs: - v = VCS_ABBREVIATIONS.get(vcs.lower()) - if v is None: - ErrorExit("Unknown version control system %r specified." % vcs) - (vcs, extra_output) = (v, None) - else: - (vcs, extra_output) = GuessVCSName(options) - - if vcs == VCS_MERCURIAL: - if extra_output is None: - extra_output = RunShell(["hg", "root"]).strip() - return MercurialVCS(options, extra_output) - elif vcs == VCS_SUBVERSION: - return SubversionVCS(options) - elif vcs == VCS_PERFORCE: - return PerforceVCS(options) - elif vcs == VCS_GIT: - return GitVCS(options) - elif vcs == VCS_CVS: - return CVSVCS(options) - - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) - - -def CheckReviewer(reviewer): - """Validate a reviewer -- either a nickname or an email addres. - - Args: - reviewer: A nickname or an email address. - - Calls ErrorExit() if it is an invalid email address. - """ - if "@" not in reviewer: - return # Assume nickname - parts = reviewer.split("@") - if len(parts) > 2: - ErrorExit("Invalid email address: %r" % reviewer) - assert len(parts) == 2 - if "." not in parts[1]: - ErrorExit("Invalid email address: %r" % reviewer) - - -def LoadSubversionAutoProperties(): - """Returns the content of [auto-props] section of Subversion's config file as - a dictionary. - - Returns: - A dictionary whose key-value pair corresponds the [auto-props] section's - key-value pair. - In following cases, returns empty dictionary: - - config file doesn't exist, or - - 'enable-auto-props' is not set to 'true-like-value' in [miscellany]. - """ - if os.name == 'nt': - subversion_config = os.environ.get("APPDATA") + "\\Subversion\\config" - else: - subversion_config = os.path.expanduser("~/.subversion/config") - if not os.path.exists(subversion_config): - return {} - config = ConfigParser.ConfigParser() - config.read(subversion_config) - if (config.has_section("miscellany") and - config.has_option("miscellany", "enable-auto-props") and - config.getboolean("miscellany", "enable-auto-props") and - config.has_section("auto-props")): - props = {} - for file_pattern in config.options("auto-props"): - props[file_pattern] = ParseSubversionPropertyValues( - config.get("auto-props", file_pattern)) - return props - else: - return {} - -def ParseSubversionPropertyValues(props): - """Parse the given property value which comes from [auto-props] section and - returns a list whose element is a (svn_prop_key, svn_prop_value) pair. - - See the following doctest for example. - - >>> ParseSubversionPropertyValues('svn:eol-style=LF') - [('svn:eol-style', 'LF')] - >>> ParseSubversionPropertyValues('svn:mime-type=image/jpeg') - [('svn:mime-type', 'image/jpeg')] - >>> ParseSubversionPropertyValues('svn:eol-style=LF;svn:executable') - [('svn:eol-style', 'LF'), ('svn:executable', '*')] - """ - key_value_pairs = [] - for prop in props.split(";"): - key_value = prop.split("=") - assert len(key_value) <= 2 - if len(key_value) == 1: - # If value is not given, use '*' as a Subversion's convention. - key_value_pairs.append((key_value[0], "*")) - else: - key_value_pairs.append((key_value[0], key_value[1])) - return key_value_pairs - - -def GetSubversionPropertyChanges(filename): - """Return a Subversion's 'Property changes on ...' string, which is used in - the patch file. - - Args: - filename: filename whose property might be set by [auto-props] config. - - Returns: - A string like 'Property changes on |filename| ...' if given |filename| - matches any entries in [auto-props] section. None, otherwise. - """ - global svn_auto_props_map - if svn_auto_props_map is None: - svn_auto_props_map = LoadSubversionAutoProperties() - - all_props = [] - for file_pattern, props in svn_auto_props_map.items(): - if fnmatch.fnmatch(filename, file_pattern): - all_props.extend(props) - if all_props: - return FormatSubversionPropertyChanges(filename, all_props) - return None - - -def FormatSubversionPropertyChanges(filename, props): - """Returns Subversion's 'Property changes on ...' strings using given filename - and properties. - - Args: - filename: filename - props: A list whose element is a (svn_prop_key, svn_prop_value) pair. - - Returns: - A string which can be used in the patch file for Subversion. - - See the following doctest for example. - - >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) - Property changes on: foo.cc - ___________________________________________________________________ - Added: svn:eol-style - + LF - - """ - prop_changes_lines = [ - "Property changes on: %s" % filename, - "___________________________________________________________________"] - for key, value in props: - prop_changes_lines.append("Added: " + key) - prop_changes_lines.append(" + " + value) - return "\n".join(prop_changes_lines) + "\n" - - -def RealMain(argv, data=None): - """The real main function. - - Args: - argv: Command line arguments. - data: Diff contents. If None (default) the diff is generated by - the VersionControlSystem implementation returned by GuessVCS(). - - Returns: - A 2-tuple (issue id, patchset id). - The patchset id is None if the base files are not uploaded by this - script (applies only to SVN checkouts). - """ - options, args = parser.parse_args(argv[1:]) - if options.help: - if options.verbose < 2: - # hide Perforce options - parser.epilog = "Use '--help -v' to show additional Perforce options." - parser.option_groups.remove(parser.get_option_group('--p4_port')) - parser.print_help() - sys.exit(0) - - global verbosity - verbosity = options.verbose - if verbosity >= 3: - logging.getLogger().setLevel(logging.DEBUG) - elif verbosity >= 2: - logging.getLogger().setLevel(logging.INFO) - - vcs = GuessVCS(options) - - base = options.base_url - if isinstance(vcs, SubversionVCS): - # Guessing the base field is only supported for Subversion. - # Note: Fetching base files may become deprecated in future releases. - guessed_base = vcs.GuessBase(options.download_base) - if base: - if guessed_base and base != guessed_base: - print "Using base URL \"%s\" from --base_url instead of \"%s\"" % \ - (base, guessed_base) - else: - base = guessed_base - - if not base and options.download_base: - options.download_base = True - logging.info("Enabled upload of base file") - if not options.assume_yes: - vcs.CheckForUnknownFiles() - if data is None: - data = vcs.GenerateDiff(args) - data = vcs.PostProcessDiff(data) - if options.print_diffs: - print "Rietveld diff start:*****" - print data - print "Rietveld diff end:*****" - files = vcs.GetBaseFiles(data) - if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" - rpc_server = GetRpcServer(options.server, - options.email, - options.host, - options.save_cookies, - options.account_type) - form_fields = [] - - repo_guid = vcs.GetGUID() - if repo_guid: - form_fields.append(("repo_guid", repo_guid)) - if base: - b = urlparse.urlparse(base) - username, netloc = urllib.splituser(b.netloc) - if username: - logging.info("Removed username from base URL") - base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params, - b.query, b.fragment)) - form_fields.append(("base", base)) - if options.issue: - form_fields.append(("issue", str(options.issue))) - if options.email: - form_fields.append(("user", options.email)) - if options.reviewers: - for reviewer in options.reviewers.split(','): - CheckReviewer(reviewer) - form_fields.append(("reviewers", options.reviewers)) - if options.cc: - for cc in options.cc.split(','): - CheckReviewer(cc) - form_fields.append(("cc", options.cc)) - - # Process --message, --title and --file. - message = options.message or "" - title = options.title or "" - if options.file: - if options.message: - ErrorExit("Can't specify both message and message file options") - file = open(options.file, 'r') - message = file.read() - file.close() - if options.issue: - prompt = "Title describing this patch set: " - else: - prompt = "New issue subject: " - title = ( - title or message.split('\n', 1)[0].strip() or raw_input(prompt).strip()) - if not title and not options.issue: - ErrorExit("A non-empty title is required for a new issue") - # For existing issues, it's fine to give a patchset an empty name. Rietveld - # doesn't accept that so use a whitespace. - title = title or " " - if len(title) > 100: - title = title[:99] + '…' - if title and not options.issue: - message = message or title - - form_fields.append(("subject", title)) - # If it's a new issue send message as description. Otherwise a new - # message is created below on upload_complete. - if message and not options.issue: - form_fields.append(("description", message)) - - # Send a hash of all the base file so the server can determine if a copy - # already exists in an earlier patchset. - base_hashes = "" - for file, info in files.iteritems(): - if not info[0] is None: - checksum = md5(info[0]).hexdigest() - if base_hashes: - base_hashes += "|" - base_hashes += checksum + ":" + file - form_fields.append(("base_hashes", base_hashes)) - if options.private: - if options.issue: - print "Warning: Private flag ignored when updating an existing issue." - else: - form_fields.append(("private", "1")) - if options.send_patch: - options.send_mail = True - if not options.download_base: - form_fields.append(("content_upload", "1")) - if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." - uploaded_diff_file = [] - form_fields.append(("separate_patches", "1")) - else: - uploaded_diff_file = [("data", "data.diff", data)] - ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) - response_body = rpc_server.Send("/upload", body, content_type=ctype) - patchset = None - if not options.download_base or not uploaded_diff_file: - lines = response_body.splitlines() - if len(lines) >= 2: - msg = lines[0] - patchset = lines[1].strip() - patches = [x.split(" ", 1) for x in lines[2:]] - else: - msg = response_body - else: - msg = response_body - StatusUpdate(msg) - if not response_body.startswith("Issue created.") and \ - not response_body.startswith("Issue updated."): - sys.exit(0) - issue = msg[msg.rfind("/")+1:] - - if not uploaded_diff_file: - result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) - if not options.download_base: - patches = result - - if not options.download_base: - vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) - - payload = {} # payload for final request - if options.send_mail: - payload["send_mail"] = "yes" - if options.send_patch: - payload["attach_patch"] = "yes" - if options.issue and message: - payload["message"] = message - payload = urllib.urlencode(payload) - rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""), - payload=payload) - return issue, patchset - - -def main(): - try: - logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" - "%(lineno)s %(message)s ")) - os.environ['LC_ALL'] = 'C' - RealMain(sys.argv) - except KeyboardInterrupt: - print - StatusUpdate("Interrupted.") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/api/node_modules/mongoskin/package.json b/api/node_modules/mongoskin/package.json deleted file mode 100644 index 27c438dc2e0..00000000000 --- a/api/node_modules/mongoskin/package.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "name": "mongoskin", - "description": "The future layer above node-mongodb-native", - "version": "0.5.0", - "author": { - "name": "Gui Lin", - "email": "guileen@gmail.com" - }, - "homepage": "https://github.com/kissjs/node-mongoskin", - "repository": { - "type": "git", - "url": "git://github.com/guileen/node-mongoskin.git" - }, - "bugs": { - "url": "https://github.com/kissjs/node-mongoskin/issues" - }, - "main": "./index.js", - "keywords": [ - "mongodb", - "database", - "nosql" - ], - "engines": { - "node": ">= 0.4.0" - }, - "dependencies": { - "mongodb": "1.2.x" - }, - "devDependencies": { - "mocha": "*", - "jscover": "*", - "should": "*" - }, - "scripts": { - "test": "make test" - }, - "directories": { - "example": "./examples", - "lib": "./lib/mongoskin" - }, - "license": "MIT", - "contributors": [ - { - "name": "Gui Lin", - "email": "guileen@gmail.com", - "url": "https://github.com/guileen" - }, - { - "name": "François de Metz", - "email": "francois@2metz.fr", - "url": "https://github.com/francois2metz" - }, - { - "name": "fengmk2", - "email": "fengmk2@gmail.com", - "url": "http://fengmk2.github.com" - }, - { - "name": "Quang Van", - "email": "quangvvv@gmail.com", - "url": "https://github.com/quangv" - }, - { - "name": "Matt Perpick", - "email": "clutchski@gmail.com", - "url": "https://github.com/clutchski" - }, - { - "name": "humanchimp", - "email": "morphcham@gmail.com", - "url": "https://github.com/humanchimp" - }, - { - "name": "Joe Faber", - "email": "joe.faber@mandiant.com", - "url": "https://github.com/jlfaber" - }, - { - "name": "Harvey McQueen", - "email": "hmcqueen@gmail.com", - "url": "https://github.com/hmcqueen" - }, - { - "name": "Paul Gebheim", - "email": "pgebheim@monkeyinferno.com", - "url": "https://github.com/paulirish" - }, - { - "name": "Aneil Mallavarapu", - "email": "aneil@blipboard.com", - "url": "https://github.com/amallavarapu" - }, - { - "name": "wmertens", - "email": "Wout.Mertens@gmail.com", - "url": "https://github.com/wmertens" - }, - { - "name": "Rakshit Menpara", - "email": "deltasquare4@gmail.com", - "url": "https://github.com/deltasquare4" - } - ], - "readme": "# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin)\n\n![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png)\n\nThis project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native).\nThe api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first.\n\n## Test\n\n* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md)\n* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html)\n\n## Test pass [mongodb] versions\n\n* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` \n when connection open error.\n* 1.0.x\n* 1.1.x\n* 1.2.x\n\n```bash\n$ make test\n```\n\n\n\n# Mongoskin document\n\n* [Nodejs mongodb drivers comparation](#comparation)\n* [Install](#install)\n* [Quick Start](#quickstart)\n * [Connect easier](#quickstart-1)\n * [Server options and BSON options](#quickstart-2)\n * [Similar API with node-mongodb-native](#quickstart-3)\n * [Cursor easier](#quickstart-4)\n * [MVC helper](#quickstart-5)\n* [Documentation](#documentation)\n * [Module](#module)\n * [SkinServer](#skinserver)\n * [SkinDb](#skindb)\n * [SkinCollection](#skincollection)\n * [Additional methods](#additional-collection-op)\n * [Collection operation](#inherit-collection-op)\n * [Indexes](#inherit-indexes)\n * [Querying](#inherit-query)\n * [Aggregation](#inherit-aggregation)\n * [Inserting](#inherit-inserting)\n * [Updating](#inherit-updating)\n * [Removing](#inherit-removing)\n * [SkinCursor](#skincursor)\n\n\n\nNodejs Mongodb Driver Comparison\n========\n\nnode-mongodb-native\n--------\n\nOne of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build\non top of it, including mongoskin. Unfortunately, it has an awkward interface with too many \ncallbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model.\n \nSee [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs)\n\nmongoose\n--------\n\nMongoose provides an ORM way to hold Collection instance as Model,\n you should define schema first. But why mongodb need schema?\n Some guys like me, want to write code from application layer but not database layer,\n and we can use any fields without define it before.\n\n Mongoose provide a DAL that you can do validation, and write your middlewares.\n But some guys like me would like to validate manually, I think it is the tao of mongodb.\n\n If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice.\n\nmongoskin\n--------\n\nMongoskin is an easy to use driver of mongodb for nodejs,\n it is similar with mongo shell, powerful like node-mongodb-native,\n and support additional javascript method binding, which make it can act as a Model(in document way).\n\nIt will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native),\n and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29).\n\nIf you need validation, you can use [node-iform](https://github.com/guileen/node-iform).\n\n[Back to index](#index)\n\n\n\nInstall\n========\n\n```bash\n$ npm install mongoskin\n```\n\n[Back to index](#index)\n\n\n\n\nQuick Start\n========\n\n **Is mongoskin synchronized?**\n\nNope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29).\n**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native)\n\n\n\nConnect easier\n--------\nYou can connect to mongodb easier now.\n\n```js\nvar mongo = require('mongoskin');\nmongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) {\n console.dir(items);\n})\n```\n\n\n\nServer options and BSON options\n--------\nYou can also set `auto_reconnect` options querystring.\nAnd native_parser options will automatically set if native_parser is available.\n\n```js\nvar mongo = require('mongoskin');\nvar db = mongo.db('localhost:27017/test?auto_reconnect');\n```\n\n\n\nSimilar API with node-mongodb-native\n--------\nYou can do everything that node-mongodb-native can do.\n\n```js\ndb.createCollection(...);\ndb.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {});\ndb.collection('posts').hint = 'slug';\ndb.collection('posts').findOne({slug: 'whats-up'}, function (err, post) {\n // do something\n});\n```\n\n\n\nCursor easier\n--------\n\n```js\ndb.collection('posts').find().toArray(function (err, posts) {\n // do something\n});\n```\n\n\n\nMVC helper\n--------\n\nYou can bind **additional methods** for collection.\nIt is very useful if you want to use MVC patterns with nodejs and mongodb.\nYou can also invoke collection by properties after bind,\nit could simplfy your `require`.\n\nTo keep your code in line with DRY principles, it's possible to create your own\ndata layer by for example, setting up your own validators and/or default values\ninside the MVC methods as shown below in the config example\n\n```js\ndb.bind('posts', {\n findTop10 : function (fn) {\n this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn);\n },\n removeTagWith : function (tag, fn) {\n this.remove({tags:tag},fn);\n }\n } \n});\n\ndb.bind('settings', {\n\n getAll: function(user, fn) {\n \n \tthis.find({user: user}).toArray(function(err, settings) {\n \t\n \t // We want to set a default currency from within our app instead of storing it\n \t // for every user\n \t settings.currency = (typeof settings.currency !== \"undefined\") ? settings.currency : 'USD';\n \t\t\n \t fn(err, settings);\n \t\n \t});\n }\n});\n\n \ndb.bind('comments');\n\ndb.collection('posts').removeTagWith('delete', function (err, replies) {\n //do something\n});\n\ndb.posts.findTop10(function (err, topPosts) {\n //do something\n});\n\ndb.comments.find().toArray(function (err, comments) {\n //do something\n});\n```\n\n[Back to index](#index)\n\n\n\n\nDocumentation\n========\n\nfor more information, see the source.\n\n[Back to index](#index)\n\n\n\n\nModule\n--------\n\n### MongoSkin Url format\n\n```\n[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]`\n```\n\ne.g.\n\n```\nlocalhost/blog\nmongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect\n127.0.0.1?auto_reconnect=false\n```\n\n### db(serverURL[s], dbOptions, replicasetOptions)\n\nGet or create instance of [SkinDb](#skindb).\n\n```js\nvar db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5');\n```\n\nfor ReplSet server\n\n```js\nvar db = mongoskin.db([\n '192.168.0.1:27017/?auto_reconnect=true',\n '192.168.0.2:27017/?auto_reconnect=true',\n '192.168.0.3:27017/?auto_reconnect=true'\n], {\n database: 'testdb',\n safe: true\n}, {\n connectArbiter: false,\n socketOptions: {\n timeout: 2000\n }\n});\n```\n\n### router(select)\n\nselect is `function(collectionName)` returns a database instance, means router collectionName to that database.\n\n```js\nvar db = mongo.router(function (coll_name) {\n switch(coll_name) {\n case 'user':\n case 'message':\n return mongo.db('192.168.1.3/auth_db');\n default:\n return mongo.db('192.168.1.2/app_db');\n }\n});\ndb.bind('user', require('./shared-user-methods'));\nvar users = db.user; //auth_db.user\nvar messages = db.collection('message'); // auth_db.message\nvar products = db.collection('product'); //app_db.product\n```\n\n### classes extends frome node-mongodb-native\n\n* BSONPure\n* BSONNative\n* BinaryParser\n* Binary\n* Code\n* DBRef\n* Double\n* MaxKey\n* MinKey\n* ObjectID\n* Symbol\n* Timestamp\n* Long\n* BaseCommand\n* DbCommand\n* DeleteCommand\n* GetMoreCommand\n* InsertCommand\n* KillCursorCommand\n* QueryCommand\n* UpdateCommand\n* MongoReply\n* Admin\n* Collection\n* Connection\n* Server\n* ReplSetServers\n* Cursor\n* Db\n* connect\n* Grid\n* Chunk\n* GridStore\n* native\n* pure\n\n\n[Back to index](#index)\n\n\n\nSkinServer\n--------\n\n### SkinServer(server)\n\nConstruct SkinServer from native Server instance.\n\n### db(dbname, username=null, password=null)\n\nConstruct [SkinDb](#skindb) from SkinServer.\n\n[Back to index](#index)\n\n\n\nSkinDb\n--------\n\n### SkinDb(db, username=null, password=null)\n\nConstruct SkinDb.\n\n### open(callback)\n\nConnect to database, retrieval native\n[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17)\ninstance, callback is function(err, db).\n\n### collection(collectionName)\n\nRetrieval [SkinCollection](#skincollection) instance of specified collection name.\n\n\n\n### bind(collectionName)\n\n### bind(collectionName, SkinCollection)\n\n### bind(collectionName, extendObject1, extendObject2 ...)\n\nBind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name).\nYou can also bind additional methods to the SkinCollection, it is useful when\nyou want to reuse a complex operation. This will also affect\ndb.collection(name) method.\n\ne.g.\n\n```js\ndb.bind('book', {\n firstBook: function (fn) {\n this.findOne(fn);\n }\n});\ndb.book.firstBook(function (err, book) {});\n```\n\n### all the methods from Db.prototype\n\nSee [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information.\n\n[Back to index](#index)\n\n\n\nSkinCollection\n--------\n\nSee [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information.\n\n\n### open(callback)\n\nRetrieval native\n[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45)\ninstance, callback is function(err, collection).\n\n### id(hex)\n\nEquivalent to\n\n```js\ndb.bson_serializer.ObjectID.createFromHexString(hex);\n```\n\nSee [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548)\n\n\n\n\n### Collection operation\n\n```js\ncheckCollectionName(collectionName)\noptions(callback)\nrename(collectionName, callback)\ndrop(callback)\n```\n\n\n\n### Indexes\n\n```js\ncreateIndex(fieldOrSpec, unique, callback)\nensureIndex(fieldOrSpec, unique, callback)\nindexInformation(callback)\ndropIndex(indexName, callback)\ndropIndexes(callback)\n```\n \nSee [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md)\n\n\n\n### Queries\n\nSee [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md)\n\n#### findItems(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.toArray(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findEach(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.each(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findById(id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417)\n\n#### find(...)\n\nIf the last parameter is function, it is equivalent to native\n[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\nmethod, else it will return a future [SkinCursor](#skincursor).\n\ne.g.\n\n```js\n// callback\ndb.book.find({}, function (err, cursor) {/* do something */});\n// future SkinCursor\ndb.book.find().toArray(function (err, books) {/* do something */});\n```\n\n#### normalizeHintField(hint)\n\n#### find\n\n```js\n/**\n * Various argument possibilities\n * 1 callback\n * 2 selector, callback,\n * 2 callback, options // really?!\n * 3 selector, fields, callback\n * 3 selector, options, callback\n * 4,selector, fields, options, callback\n * 5 selector, fields, skip, limit, callback\n * 6 selector, fields, skip, limit, timeout, callback\n *\n * Available options:\n * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize\n */\n```\n\n#### findAndModify(query, sort, update, options, callback) \n\n```js\n/**\n Fetch and update a collection\n query: a filter for the query\n sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate\n update: an object describing the modifications to the documents selected by the query\n options:\n remove: set to a true to remove the object before returning\n new: set to true if you want to return the modified object rather than the original. Ignored for remove.\n upsert: true/false (perform upsert operation)\n**/\n```\n\n#### findOne(queryObject, options, callback)\n\n\n\n### Aggregation\n\n#### mapReduce(map, reduce, options, callback)\n\ne.g.\n\n```js\nvar map = function () {\n emit(test(this.timestamp.getYear()), 1);\n}\n\nvar reduce = function (k, v){\n count = 0;\n for (i = 0; i < v.length; i++) {\n count += v[i];\n }\n return count;\n}\nvar options = {scope: {test: new client.bson_serializer.Code(t.toString())}};\ncollection.mapReduce(map, reduce, options, function (err, collection) {\n collection.find(function (err, cursor) {\n cursor.toArray(function (err, results) {\n test.equal(2, results[0].value)\n finished_test({test_map_reduce_functions_scope:'ok'}); \n })\n})\n```\n\n#### group(keys, condition, initial, reduce, command, callback)\n\ne.g. \n\n```js\ncollection.group([], {}, {\"count\":0}, \"function (obj, prev) { prev.count++; }\", true, function(err, results) {});\n```\n\n#### count(query, callback)\n#### distinct(key, query, callback)\n\n\n\n### Inserting\n\n#### insert(docs, options, callback)\n\n\n\n### Updating\n\n#### save(doc, options, callback)\n\n```js\n/**\n Update a single document in this collection.\n spec - a associcated array containing the fields that need to be present in\n the document for the update to succeed\n\n document - an associated array with the fields to be updated or in the case of\n a upsert operation the fields to be inserted.\n\n Options:\n upsert - true/false (perform upsert operation)\n multi - true/false (update all documents matching spec)\n strict - true/false (perform check if the operation failed, required extra call to db)\n Deprecated Options:\n safe - true/false (perform check if the operation failed, required extra call to db)\n**/\n```\n\n#### update(spec, document, options, callback)\n\n#### updateById(_id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.update({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md)\n\n\n\n### Removing\n\n#### remove(selector, options, callback)\n\n#### removeById(_id, options, callback)\n\n[Back to index](#index)\n\n\n\nSkinCursor\n---------\n\nSee [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1)\nof node-mongodb-native for more information.\n\nAll these methods will return the SkinCursor itself.\n\n```js\nsort(keyOrList, [direction], [callback])\nlimit(limit, [callback])\nskip(skip, [callback])\nbatchSize(skip, [callback])\n\ntoArray(callback)\neach(callback)\ncount(callback)\nnextObject(callback)\ngetMore(callback)\nexplain(callback)\n```\n\n[Back to index](#index)\n\n## How to validate input?\n\nI wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) \nbase on [node-validator](https://github.com/chriso/node-validator)\n\n## Authors\n\nBelow is the output from `git-summary`.\n\n```\n project: node-mongoskin\n commits: 112\n active : 54 days\n files : 39\n authors: \n 49 Lin Gui 43.8%\n 34 guilin æ¡‚æž— 30.4%\n 9 fengmk2 8.0%\n 5 guilin 4.5%\n 2 François de Metz 1.8%\n 2 Paul Gebheim 1.8%\n 2 Gui Lin 1.8%\n 1 humanchimp 0.9%\n 1 Aneil Mallavarapu 0.9%\n 1 wmertens 0.9%\n 1 Harvey McQueen 0.9%\n 1 Joe Faber 0.9%\n 1 Matt Perpick 0.9%\n 1 Quang Van 0.9%\n 1 Rakshit Menpara 0.9%\n 1 Wout Mertens 0.9%\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 - 2012 kissjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "_id": "mongoskin@0.5.0", - "_from": "mongoskin" -} diff --git a/api/node_modules/mongoskin/test/collection.test.js b/api/node_modules/mongoskin/test/collection.test.js deleted file mode 100644 index 462180b2c1a..00000000000 --- a/api/node_modules/mongoskin/test/collection.test.js +++ /dev/null @@ -1,55 +0,0 @@ - -/** - * Module dependencies. - */ - -var mongoskin = require('../') - , should = require('should'); - - -module.exports = { - 'test id()': function() { - var db = mongoskin.db('localhost/test'); - db.bind('testcollection'); - var id = '4ec4b2b9f44a927223000001'; - id = db.testcollection.id(id); - id.should.be.instanceof(db.testcollection.ObjectID); - id = db.testcollection.id(id); - id.should.be.instanceof(db.testcollection.ObjectID); - db.close(); - }, - 'test findById string id': function() { - var db = mongoskin.db('localhost/test'); - var ObjectID = db.db.bson_serializer.ObjectID; - db.bind('article'); - var now = new Date(); - var article = {title: 'test article title ' + now.getTime(), created_at: now}; - db.article.insert(article, function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.length(1); - article.should.have.property('_id').with.instanceof(ObjectID); - obj[0].should.have.property('_id').with.instanceof(ObjectID); - - var count = 2; - db.article.findById(article._id.toString(), function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.property('_id').with.instanceof(ObjectID); - obj._id.should.eql(article._id); - if(--count === 0) { - db.close(); - } - }); - db.article.findById(article._id, function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.property('_id').with.instanceof(ObjectID); - obj._id.should.eql(article._id); - if(--count === 0) { - db.close(); - } - }); - }); - } -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/.npmignore b/api/node_modules/nodemailer/.npmignore deleted file mode 100644 index 61c8fa4b7e5..00000000000 --- a/api/node_modules/nodemailer/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -npm-debug.log -.DS_Store -.idea diff --git a/api/node_modules/nodemailer/.travis.yml b/api/node_modules/nodemailer/.travis.yml deleted file mode 100644 index 48c1cc912da..00000000000 --- a/api/node_modules/nodemailer/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js -node_js: - - 0.8 - - "0.10" - -notifications: - email: - recipients: - - andris@node.ee - on_success: change - on_failure: change diff --git a/api/node_modules/nodemailer/LICENSE b/api/node_modules/nodemailer/LICENSE deleted file mode 100644 index dca6ebe1f28..00000000000 --- a/api/node_modules/nodemailer/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2011-2012 Andris Reinman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/nodemailer/README.md b/api/node_modules/nodemailer/README.md deleted file mode 100644 index 3e0b439e23f..00000000000 --- a/api/node_modules/nodemailer/README.md +++ /dev/null @@ -1,767 +0,0 @@ -Nodemailer -========== - -**Nodemailer** is an easy to use module to send e-mails with Node.JS (using -SMTP or sendmail or Amazon SES) and is unicode friendly - You can use any characters you like ✔ - -Nodemailer is Windows friendly, you can install it with *npm* on Windows just like any other module, there are no compiled dependencies. Use it from Azure or from your Windows box hassle free. - -**[Read about using Nodemailer from the Node Knockout blog](http://blog.nodeknockout.com/post/34641712180/sending-email-from-node-js)** - -[![Build Status](https://secure.travis-ci.org/andris9/Nodemailer.png)](http://travis-ci.org/andris9/Nodemailer) -[![NPM version](https://badge.fury.io/js/nodemailer.png)](http://badge.fury.io/js/nodemailer) - -## Notes and information - -### Nodemailer supports - - * **Unicode** to use any characters - * **HTML content** as well as **plain text** alternative - * **Attachments** (including attachment **streaming** for sending larger files) - * **Embedded images** in HTML - * **SSL/STARTTLS** for secure e-mail delivery - * Different transport methods - **SMTP**, **sendmail** and **Amazon SES** - * SMTP **Connection pool** and connection reuse for rapid delivery - * **Preconfigured** services for using SMTP with Gmail, Hotmail etc. - * Use objects as header values for **SendGrid** SMTP API - * **XOAUTH2** authentication and token generation support - useful with Gmail - * **DKIM** signing - -### Support Nodemailer development - -[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W) - -If you want to support with Bitcoins, then my wallet address is `15Z8ADxhssKUiwP3jbbqJwA21744KMCfTM` - -### Nodemailer PaaS support - -Nodemailer has been tested successfully on the following PaaS platforms (using free/trial accounts): - - * [heroku](http://www.heroku.com/) - * [AppFog](http://www.appfog.com/) - * [OpenShift](https://openshift.redhat.com/app/) - * [Nodejitsu](http://nodejitsu.com/) - * [Windows Azure](http://www.windowsazure.com/) - -### Check out my other mail related modules - -If you want to parse generated or received e-mail instead of sending it, check -out [MailParser](https://github.com/andris9/mailparser). - -If you only want to generate the raw e-mail stream, check out -[MailComposer](https://github.com/andris9/mailcomposer). - -If you only want to communicate with the SMTP (both as client and the server), -check out [simplesmtp](https://github.com/andris9/simplesmtp). - -### Templates - -To use Nodemailer with templates, please see documentation for these projects. - - * [swig-email-templates](https://github.com/superjoe30/swig-email-templates) - swig, template inheritance, dummy context - * [node-email-templates](https://github.com/niftylettuce/node-email-templates) - ejs - -## TL;DR Usage Example - -This is a complete example to send an e-mail with plaintext and HTML body - -```javascript -var nodemailer = require("nodemailer"); - -// create reusable transport method (opens pool of SMTP connections) -var smtpTransport = nodemailer.createTransport("SMTP",{ - service: "Gmail", - auth: { - user: "gmail.user@gmail.com", - pass: "userpass" - } -}); - -// setup e-mail data with unicode symbols -var mailOptions = { - from: "Fred Foo ✔ ", // sender address - to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers - subject: "Hello ✔", // Subject line - text: "Hello world ✔", // plaintext body - html: "Hello world ✔" // html body -} - -// send mail with defined transport object -smtpTransport.sendMail(mailOptions, function(error, response){ - if(error){ - console.log(error); - }else{ - console.log("Message sent: " + response.message); - } - - // if you don't want to use this transport object anymore, uncomment following line - //smtpTransport.close(); // shut down the connection pool, no more messages -}); -``` - -See also the [examples folder](https://github.com/andris9/Nodemailer/tree/master/examples) -for full featured examples - -## Installation - -Install through NPM - -``` -npm install nodemailer -``` - -## Usage - -Include the module - -```javascript -var nodemailer = require("nodemailer"); -``` - -An e-mail can be sent with `sendMail(mailOptions[, callback])` command - -```javascript -transport.sendMail(mailOptions, callback); -``` - -Where - - * `transport` is a transport object created from the `nodemailer.createTransport` method - * **mailOptions** defines the e-mail (set its subject, body text, receivers etc.), see [E-mail Message Fields](#e-mail-message-fields) for details - * **callback** is the callback function that will be run after the e-mail is sent or the sending failed (see [Return callback](#return-callback) for details) - -## Setting up a transport method - -Before you can send any e-mails you need to set up a transport method. This can -be done with `nodemailer.createTransport(type, options)` where `type` indicates -the transport protocol and `options` defines how it is used. - -```javascript -var transport = nodemailer.createTransport("SMTP", {smtp_options}); -``` - -The same transport object can and should be reused several times. - -When the transport method is defined, it can be used to send e-mail with `sendMail` - -```javascript -var transport = nodemailer.createTransport("SMTP", {smtp_options}); - -transport.sendMail({ - from: "sender@tr.ee", - to: "receiver@tr.ee" - ... -}); -``` - -### Possible transport methods - -Required `type` parameter can be one of the following: - - * **SMTP** for using SMTP - * **SES** for using Amazon SES - * **Sendmail** for utilizing systems *sendmail* command - -### Setting up SMTP - -SMTP is different from the other transport mechanisms, as in its case a connection -pool is created. All the connections try to stay alive as long as possible and -are reusable to minimize the protocol overhead delay - for example setting up -TLS for authenticating is relatively lengthy process (in CPU terms, not by human -terms), you do not want to do it several times. - -Possible SMTP options are the following: - - * **service** - an optional well known service identifier ("Gmail", "Hotmail" etc., see [Well known Services](#well-known-services-for-smtp) for a list of supported services) to auto-configure host, port and secure connection settings - * **host** - hostname of the SMTP server (defaults to "localhost", not needed with `service`) - * **port** - port of the SMTP server (defaults to 25, not needed with `service`) - * **secureConnection** - use SSL (default is `false`, not needed with `service`). If you're using port 587 then keep `secureConnection` false, since the connection is started in insecure plain text mode and only later upgraded with STARTTLS - * **name** - the name of the client server (defaults to machine name) - * **auth** - authentication object as `{user:"...", pass:"..."}` or `{XOAuth2: {xoauth2_options}}` or `{XOAuthToken: "base64data"}` - * **ignoreTLS** - ignore server support for STARTTLS (defaults to `false`) - * **debug** - output client and server messages to console - * **maxConnections** - how many connections to keep in the pool (defaults to 5) - -Example: - -```javascript -var transport = nodemailer.createTransport("SMTP", { - service: "Gmail", - auth: { - user: "gmail.user@gmail.com", - pass: "userpass" - } -}); -``` - -or the same without `service` parameter - -```javascript -var transport = nodemailer.createTransport("SMTP", { - host: "smtp.gmail.com", // hostname - secureConnection: true, // use SSL - port: 465, // port for secure SMTP - auth: { - user: "gmail.user@gmail.com", - pass: "userpass" - } -}); -``` - -**NB!** if you want to close the pool (cancel all open connections) you can use `transport.close()` - -```javascript - -var transport = nodemailer.createTransport("SMTP",{}); -... -transport.close(); // close the pool -``` - - -#### SMTP XOAUTH and token generation - -##### XOAUTH2 - -**nodemailer** supports XOAUTH2 authentication protocol. To use this you need to obtain a Client ID and a Client Secret from [Google API Console](https://code.google.com/apis/console) (Open "API Access" and create "Client ID for web applications") and then request a refresh token for an user. See [Google OAuth 2.0 Offline Access](https://developers.google.com/accounts/docs/OAuth2WebServer#offline) for more information. - -Once you have obtained the Client ID, Client Secret and a Refresh Token for an user, you can use these values to send mail on behalf of the user. - -```javascript -var transportOptions = { - ..., - auth: { - XOAuth2: { - user: "example.user@gmail.com", - clientId: "8819981768.apps.googleusercontent.com", - clientSecret: "{client_secret}", - refreshToken: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI", - accessToken: "vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==", - timeout: 3600 - } - } -} -``` - -`accessToken` and `timeout` values are both optional. If XOAUTH2 login fails a new access token is generated automatically and the login is retried. - -##### XOAUTH - -Older XOAUTH is also supporteb by **nodemailer** for SMTP. XOAUTH is based on OAuth protocol 1.0 and is considered deprecated. - -To use this, include `XOAuthToken` option in `auth` instead of the regular `user` and `pass`. - -```javascript -var transportOptions = { - ..., - auth: { - XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...." - } -} -``` - -**nodemailer** includes also built in XOAUTH token generator which can be used -with `nodemailer.createXOAuthGenerator()`. The function is preconfigured for -Gmail, so in this case only mandatory options are `user`, `token` and `tokenSecret`. - -```javascript -var XOAuthTokenGenerator = nodemailer.createXOAuthGenerator({ - user: "test.nodemailer@gmail.com", - // requestUrl: "https://oauth.access.point", - // consumerKey: "anonymous", - // consumerSecret: "anonymous", - token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM", - tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c" - }); -``` - -One of `user` or `requestUrl` is mandatory. `consumerKey` and `consumerSecret` both -default to `"anonymous"`. - -```javascript -var transportOptions = { - service: "Gmail", - auth: { - XOAuthToken: nodemailer.createXOAuthGenerator({ - user: "test.nodemailer@gmail.com", - token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM", - tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c" - }) - } -} -``` - -### Setting up SES - -SES is actually a HTTP based protocol, the compiled e-mail and related info -(signatures and such) are sent as a HTTP request to SES servers. - -Possible SES options are the following: - - * **AWSAccessKeyID** - AWS access key (required) - * **AWSSecretKey** - AWS secret (required) - * **ServiceUrl** - optional API end point URL (defaults to *"https://email.us-east-1.amazonaws.com"*) - -Example: - -```javascript -var transport = nodemailer.createTransport("SES", { - AWSAccessKeyID: "AWSACCESSKEY", - AWSSecretKey: "AWS/Secret/key" -}); -``` - -### Setting up Sendmail - -Sendmail transport method streams the compiled message to the *stdin* of *sendmail* -command. - -Options object is optional, possible sendmail options are the following: - - * **path** - path to the `sendmail` command (defaults to *"sendmail"*) - * **args** - an array of extra command line options to pass to the `sendmail` command (ie. `["-f foo@blurdybloop.com"]`) - -Example: - -```javascript -var transport = nodemailer.createTransport("sendmail"); -``` - -or - -```javascript -var transport = nodemailer.createTransport("sendmail", { - path: "/usr/local/bin/sendmail", - args: ["-f foo@blurdybloop.com"] -}); -``` - -### DKIM Signing - -**Nodemailer** supports DKIM signing with very simple setup. Use this with caution -though since the generated message needs to be buffered entirely before it can be -signed. Not a big deal with small messages but might consume a lot of RAM when -using larger attachments. - -Set up the DKIM signing with `useDKIM` method for a transport object: - -```javascript -transport.useDKIM(dkimOptions) -``` - -Where `dkimOptions` includes necessary options for signing - - * **domainName** - the domainname that is being used for signing - * **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.blurdybloop.com* then `zzz` is the selector - * **privateKey** - DKIM private key that is used for signing as a string - * **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used - -All messages transmitted through this transport objects are from now on DKIM signed. - -Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed. - -Example: - -```javascript -var transport = nodemailer.createTransport("Sendmail"); - -transport.useDKIM({ - domainName: "kreata.ee", - keySelector: "dkim", - privateKey: fs.readFileSync("private_key.pem") -}); - -transport.sendMail(mailOptions); -``` - -See [examples/example_dkim.js](https://github.com/andris9/Nodemailer/blob/master/examples/example_dkim.js) for a complete example. - -### Well known services for SMTP - -If you want to use a well known service as the SMTP host, you do not need -to enter the hostname or port number, just use the `service` parameter - -Currently supported services are: - - * **DynectEmail** - * **Gmail** - * **hot.ee** - * **Hotmail** - * **iCloud** - * **mail.ee** - * **Mail.Ru** - * **Mailgun** - * **Mandrill** - * **Postmark** - * **QQ** - * **SendGrid** - * **SES** - * **Yahoo** - * **yandex** - * **Zoho** - -Predefined service data covers `host`, `port` and secure connection settings, -any other parameters (ie. `auth`) need to be set separately. Service names are -case insensitive, so using "gmail" instead of "Gmail" is totally fine. - -Example: - -```javascript -var smtpTransport = nodemailer.createTransport("Gmail",{ - auth: { - user: "gmail.user@gmail.com", - pass: "userpass" - } -}); -``` - -or alternatively - -```javascript -var smtpTransport = nodemailer.createTransport("SMTP",{ - service: "Gmail", // sets automatically host, port and connection security settings - auth: { - user: "gmail.user@gmail.com", - pass: "userpass" - } -}); -``` - -Actually, if you are authenticatinw with an e-mail address that has a domain name -like @gmail.com or @yahoo.com etc., then you don't even need to provide the service name, -it is detected automatically. - -```javascript -var smtpTransport = nodemailer.createTransport("SMTP",{ - auth: { - user: "gmail.user@gmail.com", // service is detected from the username - pass: "userpass" - } -}); -``` - -## E-mail message fields - -The following are the possible fields of an e-mail message: - - - **from** - The e-mail address of the sender. All e-mail addresses can be plain `sender@server.com` or formatted `Sender Name ` - - **to** - Comma separated list or an array of recipients e-mail addresses that will appear on the `To:` field - - **cc** - Comma separated list or an array of recipients e-mail addresses that will appear on the `Cc:` field - - **bcc** - Comma separated list or an array of recipients e-mail addresses that will appear on the `Bcc:` field - - **replyTo** - An e-mail address that will appear on the `Reply-To:` field - - **inReplyTo** - The message-id this message is replying - - **references** - Message-id list - - **subject** - The subject of the e-mail - - **text** - The plaintext version of the message - - **html** - The HTML version of the message - - **generateTextFromHTML** - if set to true uses HTML to generate plain text body part from the HTML if the text is not defined - - **headers** - An object of additional header fields `{"X-Key-Name": "key value"}` (NB! values are passed as is, you should do your own encoding to 7bit if needed) - - **attachments** - An array of attachment objects. - - **alternatives** - An array of alternative text contents (in addition to text and html parts) - - **envelope** - optional SMTP envelope, if auto generated envelope is not suitable - - **messageId** - optional Message-Id value, random value will be generated if not set. Set to false to omit the Message-Id header - - **date** - optional Date value, current UTC string will be used if not set - - **encoding** - optional transfer encoding for the textual parts (defaults to "quoted-printable") - - **charset** - optional output character set for the textual parts (defaults to "utf-8") - -All text fields (e-mail addresses, plaintext body, html body) use UTF-8 as the encoding. -Attachments are streamed as binary. - -Example: - -```javascript -var transport = nodemailer.createTransport("Sendmail"); - -var mailOptions = { - from: "me@tr.ee", - to: "me@tr.ee", - subject: "Hello world!", - text: "Plaintext body" -} - -transport.sendMail(mailOptions); -``` - -### SendGrid support - -Nodemailer supports SendGrid [SMTP API](http://docs.sendgrid.com/documentation/api/smtp-api/) out of the box - you can -use objects as header values and these are automatically JSONized (and mime encoded if needed). - -```javascript -var mailOptions = { - ..., - headers: { - 'X-SMTPAPI': { - category : "newuser", - sub:{ - "%name%": ["Žiguli Õllepruul"] - } - } - }, - subject: "Hello, %name%" -} -``` - -This also applies to any other service that expects a JSON string as a header value for specified key. - -### Generate Text from HTML - -If `generateTextFromHTML` option is set to true, then HTML contents of the mail is automatically converted -to plaintext format when plaintext content is empty or missing. - -For example - -```javascript -mailOptions = { - ..., - generateTextFromHTML: true, - html: '

Hello world

How are you?', - // text: '' // no text part -} -``` - -is automatically converted in the backround by Nodemailer to: - -```javascript -mailOptions = { - ..., - // source html: - html: '

Hello world

How are you?', - // automatically generated plaintext message: - text: "Hello world\n"+ - "===========\n"+ - "\n"+ - "**How** are you?" -} -``` - -As you can see the output syntax for `generateTextFromHTML` looks similar to markdown, and that -is exactly the case here - Nodemailer includes a simple HTML to markdown converter. But don't -expect too much from it, it's not full featured or perfect, just some regexes here and there. - -### Attachment fields - -Attachment object consists of the following properties: - - * **fileName** - filename to be reported as the name of the attached file, use of unicode is allowed (except when using Amazon SES which doesn't like it) - * **cid** - optional content id for using inline images in HTML message source - * **contents** - String or a Buffer contents for the attachment - * **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments) - * **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*) - * **contentType** - optional content type for the attachment, if not set will be derived from the `fileName` property - * **contentDisposition** - optional content disposition type for the attachment, defaults to "attachment" - -One of `contents`, `filePath` or `streamSource` must be specified, if none is -present, the attachment will be discarded. Other fields are optional. - -Attachments can be added as many as you want. - -```javascript -var mailOptions = { - ... - attachments: [ - { // utf-8 string as an attachment - fileName: "text1.txt", - contents: "hello world!" - }, - { // binary buffer as an attachment - fileName: "text2.txt", - contents: new Buffer("hello world!","utf-8") - }, - { // file on disk as an attachment - fileName: "text3.txt", - filePath: "/path/to/file.txt" // stream this file - }, - { // fileName and content type is derived from filePath - filePath: "/path/to/file.txt" - }, - { // stream as an attachment - fileName: "text4.txt", - streamSource: fs.createReadStream("file.txt") - }, - { // define custom content type for the attachment - fileName: "text.bin", - contents: "hello world!", - contentType: "text/plain" - }, - { // use URL as an attachment - fileName: "license.txt", - filePath: "https://raw.github.com/andris9/Nodemailer/master/LICENSE" - } - ] -} -``` - -### Alternative fields - -In addition to text and HTML, any kind of data can be inserted as an alternative content of the main body - for example a word processing document with the same text as in the HTML field. It is the job of the e-mail client to select and show the best fitting alternative to the reader. - -Attahcment object consists of the following properties: - - * **contents** - String or a Buffer contents for the attachment - * **contentType** - optional content type for the attachment, if not set will be set to "application/octet-stream" - * **contentEncoding** - optional value of how the data is encoded, defaults to "base64" - -If `contents` is empty, the alternative will be discarded. Other fields are optional. - -**Usage example:** - -```javascript -var mailOptions = { - ... - html: "Hello world!", - alternatives: [ - { - contentType: "text/x-web-markdown", - contents: "**Hello world!**" - } - ] -} -``` -If the receiving e-mail client can render messages in Markdown syntax as well, it could prefer -to display this alternative as the main content of the message instead of the html part. - -Alternatives can be added as many as you want. - -### Address Formatting - -All the e-mail addresses can be plain e-mail address - -``` -foobar@blurdybloop.com -``` - -or with formatted name (includes unicode support) - -``` -"Ðоде Майлер" -``` - -To, Cc and Bcc fields accept comma separated list of e-mails or an array of -emails or an array of comma separated list of e-mails - use it as you like. -Formatting can be mixed. - -``` -..., -to: 'foobar@blurdybloop.com, "Ðоде Майлер" , "Name, User" ', -cc: ['foobar@blurdybloop.com', '"Ðоде Майлер" , "Name, User" '] -... -``` - -You can even use unicode domain and user names, these are automatically converted -to the supported form - -``` -"Unicode Domain" -``` - -### SMTP envelope - -SMTP envelope is usually auto generated from `from`, `to`, `cc` and `bcc` fields but -if for some reason you want to specify it yourself, you can do it with `envelope` property. - -`envelope` is an object with the following params: `from`, `to`, `cc` and `bcc` just like -with regular mail options. You can also use the regular address format, unicode domains etc. - -```javascript -mailOptions = { - ..., - from: "mailer@kreata.ee", - to: "daemon@kreata.ee", - envelope: { - from: "Daemon ", - to: "mailer@kreata.ee, Mailer " - } -} -``` - -The envelope only applies when using SMTP or sendmail, setting envelope has no effect with SES. - -### Using Embedded Images - -Attachments can be used as embedded images in the HTML body. To use this -feature, you need to set additional property of the attachment - `cid` (unique -identifier of the file) which is a reference to the attachment file. The same -`cid` value must be used as the image URL in HTML (using `cid:` as the URL -protocol, see example below). - -**NB!** the cid value should be as unique as possible! - -```javascript -var mailOptions = { - ... - html: "Embedded image: ", - attachments: [{ - filename: "image.png", - filePath: "/path/to/file", - cid: "unique@kreata.ee" //same cid value as in the html img src - }] -} -``` - -**Automatic embedding images** - -If you want to convert images in the HTML to embedded images automatically, you can -set mail option `forceEmbeddedImages` to true. In this case all images in -the HTML that are either using an absolute URL (http://...) or absolute file path -(/path/to/file) are replaced with embedded attachments. - -For example when using this code - -```javascript -var mailOptions = { - forceEmbeddedImages: true - html: 'Embedded image: ' -}; -``` - -The image linked is fetched and added automatically as an attachment and the url -in the HTML is replaced automatically with a proper `cid:` string. - -## Return callback - -Return callback gets two parameters - - * **error** - an error object if the message failed - * **responseStatus** - an object with some information about the status on success - * **responseStatus.messageId** - message ID used with the message - -Example: - -```javascript -nodemailer.sendMail(mailOptions, function(error, responseStatus){ - if(!error){ - console.log(responseStatus.message); // response from the server - console.log(responseStatus.messageId); // Message-ID value used - } -}); -``` - -**NB!** Message-ID used might not be the same that reaches recipients inbox since some providers (like **SES**) may change the value. - -## Command line usage - -**NB!** Command line usage was removed from v0.4 - -## Tests - -Run the tests with npm in Nodemailer's directory - -``` -npm test -``` - -There aren't currently many tests for Nodemailer but there are a lot of tests -in the modules that are used to generate the raw e-mail body and to use the -SMTP client connection. - -## Tweaking - -Nodemailer in itself is actually more like a wrapper for my other modules -[mailcomposer](https://github.com/andris9/mailcomposer) for composing the raw message stream -and [simplesmtp](https://github.com/andris9/simplesmtp) for delivering it, by providing an -unified API. If there's some problems with particular parts of the -message composing/sending process you should look at the appropriate module. - -## License - -**Nodemailer** is licensed under [MIT license](https://github.com/andris9/Nodemailer/blob/master/LICENSE). Basically you can do whatever you want to with it. diff --git a/api/node_modules/nodemailer/examples/example_alternative.js b/api/node_modules/nodemailer/examples/example_alternative.js deleted file mode 100644 index c969b5e962e..00000000000 --- a/api/node_modules/nodemailer/examples/example_alternative.js +++ /dev/null @@ -1,53 +0,0 @@ -var nodemailer = require('../lib/nodemailer'); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("SMTP", { - service: 'Gmail', // use well known service - auth: { - user: "test.nodemailer@gmail.com", - pass: "Nodemailer123" - } - }); - -console.log('SMTP Configured'); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - text: "plaintext alternative", - - // An array of alternatives - alternatives:[ - { - contentType: "text/x-web-markdown", - contents: '**markdown** alternative' - }, - { - contentType: "text/html; charset=utf-8", - contentEncoding: "7bit", - contents: '

html alternative

' - } - ] -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_autoembedding.js b/api/node_modules/nodemailer/examples/example_autoembedding.js deleted file mode 100644 index c96ed301d12..00000000000 --- a/api/node_modules/nodemailer/examples/example_autoembedding.js +++ /dev/null @@ -1,43 +0,0 @@ -var nodemailer = require('../lib/nodemailer'); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("SMTP", { - service: 'Gmail', // use well known service - auth: { - user: "test.nodemailer@gmail.com", - pass: "Nodemailer123" - } - }); - -console.log('SMTP Configured'); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Automatically embedded image', // - - // HTML body with image that will be converted to embedded attachment - html:'

Embedded image:

', - - forceEmbeddedImages: true -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_dkim.js b/api/node_modules/nodemailer/examples/example_dkim.js deleted file mode 100644 index 1a58374b019..00000000000 --- a/api/node_modules/nodemailer/examples/example_dkim.js +++ /dev/null @@ -1,78 +0,0 @@ -var nodemailer = require('../lib/nodemailer'), - fs = require("fs"), - pathlib = require("path"); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("sendmail"); - -// Set up DKIM signing for outgoing messages with this transport object -transport.useDKIM({ - domainName: "do-not-trust.node.ee", // signing domain - keySelector: "dkim", // selector name (in this case there's a dkim._domainkey.do-not-trust.node.ee TXT record set up) - privateKey: fs.readFileSync(pathlib.join(__dirname,"test_private.pem")) -}); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - headers: { - 'X-Laziness-level': 1000 - }, - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyan cat ✔.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_sendmail.js b/api/node_modules/nodemailer/examples/example_sendmail.js deleted file mode 100644 index c971925d855..00000000000 --- a/api/node_modules/nodemailer/examples/example_sendmail.js +++ /dev/null @@ -1,65 +0,0 @@ -var nodemailer = require('../lib/nodemailer'); - -// Create a Sendmail transport object -var transport = nodemailer.createTransport("Sendmail", "/usr/sbin/sendmail"); - -console.log('Sendmail Configured'); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyan cat ✔.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); - -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_ses.js b/api/node_modules/nodemailer/examples/example_ses.js deleted file mode 100644 index c81a08a32e1..00000000000 --- a/api/node_modules/nodemailer/examples/example_ses.js +++ /dev/null @@ -1,80 +0,0 @@ -var nodemailer = require('../lib/nodemailer'), - fs = require("fs"), - pathlib = require("path"); - -// Create an Amazon SES transport object -var transport = nodemailer.createTransport("SES", { - AWSAccessKeyID: "AWSACCESSKEY", - AWSSecretKey: "/AWS/SECRET", - ServiceUrl: "https://email.us-east-1.amazonaws.com" // optional - }); - -console.log('SES Configured'); - -// optional DKIM signing -/* -transport.useDKIM({ - domainName: "do-not-trust.node.ee", // signing domain - keySelector: "dkim", // selector name (in this case there's a dkim._domainkey.do-not-trust.node.ee TXT record set up) - privateKey: fs.readFileSync(pathlib.join(__dirname,"test_private.pem")) -}); -*/ - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyancat.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); - -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_smtp.js b/api/node_modules/nodemailer/examples/example_smtp.js deleted file mode 100644 index 11b5f41c59a..00000000000 --- a/api/node_modules/nodemailer/examples/example_smtp.js +++ /dev/null @@ -1,79 +0,0 @@ -var nodemailer = require('../lib/nodemailer'); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("SMTP", { - //service: 'Gmail', // use well known service. - // If you are using @gmail.com address, then you don't - // even have to define the service name - auth: { - user: "test.nodemailer@gmail.com", - pass: "Nodemailer123" - } - }); - -console.log('SMTP Configured'); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - headers: { - 'X-Laziness-level': 1000 - }, - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyan cat ✔.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_xoauth.js b/api/node_modules/nodemailer/examples/example_xoauth.js deleted file mode 100644 index 5a357d563c8..00000000000 --- a/api/node_modules/nodemailer/examples/example_xoauth.js +++ /dev/null @@ -1,86 +0,0 @@ -var nodemailer = require('../lib/nodemailer'); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("SMTP", { - service: 'Gmail', // use well known service - auth: { - // Option one - provide pregenerated token - // XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...." - // or alternatively, use built in generator - XOAuthToken: nodemailer.createXOAuthGenerator({ - user: "test.nodemailer@gmail.com", - consumerKey: "anonymous", // optional - consumerSecret: "anonymous", // optional - token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM", - tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c" - }) - }, - debug: true - }); - -console.log('SMTP Configured'); - -// Message object -var message = { - - // sender info - from: 'Sender Name ', - - // Comma separated list of recipients - to: '"Receiver Name" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - headers: { - 'X-Laziness-level': 1000 - }, - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyan cat ✔.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/example_xoauth2.js b/api/node_modules/nodemailer/examples/example_xoauth2.js deleted file mode 100644 index 2cbae086430..00000000000 --- a/api/node_modules/nodemailer/examples/example_xoauth2.js +++ /dev/null @@ -1,82 +0,0 @@ -var nodemailer = require('../Projects/Nodemailer'); - -// Create a SMTP transport object -var transport = nodemailer.createTransport("SMTP", { - service: 'Gmail', // use well known service - auth: { - XOAuth2: { - user: "example.user@gmail.com", - clientId: "8819981768.apps.googleusercontent.com", - clientSecret: "{client_secret}", - refreshToken: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" - } - }, - debug: true - }); - -console.log('SMTP Configured'); - -// Message object -var message = { - - // sender info - from: 'Andris Reinman ', - - // Comma separated list of recipients - to: '"Andris Tahvel" ', - - // Subject of the message - subject: 'Nodemailer is unicode friendly ✔', // - - headers: { - 'X-Laziness-level': 1000 - }, - - // plaintext body - text: 'Hello to myself!', - - // HTML body - html:'

Hello to myself

'+ - '

Here\'s a nyan cat for you as an embedded attachment:

', - - // An array of attachments - attachments:[ - - // String attachment - { - fileName: 'notes.txt', - contents: 'Some notes about this e-mail', - contentType: 'text/plain' // optional, would be detected from the filename - }, - - // Binary Buffer attachment - { - fileName: 'image.png', - contents: new Buffer('iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' + - '//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' + - 'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC', 'base64'), - - cid: 'note@node' // should be as unique as possible - }, - - // File Stream attachment - { - fileName: 'nyan cat ✔.gif', - filePath: __dirname+"/nyan.gif", - cid: 'nyan@node' // should be as unique as possible - } - ] -}; - -console.log('Sending Mail'); -transport.sendMail(message, function(error){ - if(error){ - console.log('Error occured'); - console.log(error.message); - return; - } - console.log('Message sent successfully!'); - - // if you don't want to use this transport object anymore, uncomment following line - //transport.close(); // close the connection pool -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/examples/nyan.gif b/api/node_modules/nodemailer/examples/nyan.gif deleted file mode 100644 index bf0314f8e4a..00000000000 Binary files a/api/node_modules/nodemailer/examples/nyan.gif and /dev/null differ diff --git a/api/node_modules/nodemailer/examples/test_private.pem b/api/node_modules/nodemailer/examples/test_private.pem deleted file mode 100644 index 9d0326665b8..00000000000 --- a/api/node_modules/nodemailer/examples/test_private.pem +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBywIBAAJhANCx7ncKUfQ8wBUYmMqq6ky8rBB0NL8knBf3+uA7q/CSxpX6sQ8N -dFNtEeEd7gu7BWEM7+PkO1P0M78eZOvVmput8BP9R44ARpgHY4V0qSCdUt4rD32n -wfjlGbh8p5ua5wIDAQABAmAm+uUQpQPTu7kg95wqVqw2sxLsa9giT6M8MtxQH7Uo -1TF0eAO0TQ4KOxgY1S9OT5sGPVKnag258m3qX7o5imawcuyStb68DQgAUg6xv7Af -AqAEDfYN5HW6xK+X81jfOUECMQDr7XAS4PERATvgb1B3vRu5UEbuXcenHDYgdoyT -3qJFViTbep4qeaflF0uF9eFveMcCMQDic10rJ8fopGD7/a45O4VJb0+lRXVdqZxJ -QzAp+zVKWqDqPfX7L93SQLzOGhdd7OECMQDeQyD7WBkjSQNMy/GF7I1qxrscIxNN -VqGTcbu8Lti285Hjhx/sqhHHHGwU9vB7oM8CMQDKTS3Kw/s/xrot5O+kiZwFgr+w -cmDrj/7jJHb+ykFNb7GaEkiSYqzUjKkfpweBDYECMFJUyzuuFJAjq3BXmGJlyykQ -TweUw+zMVdSXjO+FCPcYNi6CP1t1KoESzGKBVoqA/g== ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/nodemailer/lib/engines/sendmail.js b/api/node_modules/nodemailer/lib/engines/sendmail.js deleted file mode 100644 index ec7c98066db..00000000000 --- a/api/node_modules/nodemailer/lib/engines/sendmail.js +++ /dev/null @@ -1,52 +0,0 @@ -var spawn = require('child_process').spawn; - -// Expose to the world -module.exports = SendmailTransport; - -/** - *

Generates a Transport object for Sendmail

- * - * @constructor - * @param {String} [config] path to the sendmail command - */ -function SendmailTransport(config){ - this.path = "sendmail"; - this.args = false; - if(typeof config=="string") { - this.path = config; - } else if(typeof config=="object") { - if(config.path) { - this.path = config.path; - } - if(Array.isArray(config.args)) { - this.args = config.args; - } - } -} - -/** - *

Spawns a 'sendmail -t' command and streams the outgoing - * message to sendmail stdin. Return callback checks if the sendmail process - * ended with 0 (no error) or not.

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run when the sending is completed - */ -SendmailTransport.prototype.sendMail = function(emailMessage, callback) { - - var envelope = emailMessage.getEnvelope(); - var args = this.args || ["-f"].concat(envelope.from).concat(envelope.to); - args.unshift("-i"); // force -i to keep single dots - - var sendmail = spawn(this.path, args); - sendmail.on('exit', function (code) { - var msg = "Sendmail exited with "+code; - if(typeof callback == "function"){ - callback(code?new Error(msg):null, {message: msg, messageId: emailMessage._messageId}); - } - }); - - emailMessage.pipe(sendmail.stdin); - emailMessage.streamMessage(); - -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/lib/engines/ses.js b/api/node_modules/nodemailer/lib/engines/ses.js deleted file mode 100644 index baf7617867f..00000000000 --- a/api/node_modules/nodemailer/lib/engines/ses.js +++ /dev/null @@ -1,226 +0,0 @@ -/* - * This file is based on the original SES module for Nodemailer by dfellis - * https://github.com/andris9/Nodemailer/blob/11fb3ef560b87e1c25e8bc15c2179df5647ea6f5/lib/engines/SES.js - */ - -// NB! Amazon SES does not allow unicode filenames on attachments! - -var http = require('http'), - https = require('https'), - crypto = require('crypto'), - urllib = require("url"); - -// Expose to the world -module.exports = SESTransport; - -/** - *

Generates a Transport object for Amazon SES

- * - *

Possible options can be the following:

- * - *
    - *
  • AWSAccessKeyID - AWS access key (required)
  • - *
  • AWSSecretKey - AWS secret (required)
  • - *
  • ServiceUrl - optional API endpoint URL (defaults to "https://email.us-east-1.amazonaws.com") - *
- * - * @constructor - * @param {Object} options Options object for the SES transport - */ -function SESTransport(options){ - this.options = options || {}; - - //Set defaults if necessary - this.options.ServiceUrl = this.options.ServiceUrl || "https://email.us-east-1.amazonaws.com"; -} - -/** - *

Compiles a mailcomposer message and forwards it to handler that sends it.

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run when the sending is completed - */ -SESTransport.prototype.sendMail = function(emailMessage, callback) { - - // SES strips this header line by itself - emailMessage.options.keepBcc = true; - - //Check if required config settings set - if(!this.options.AWSAccessKeyID || !this.options.AWSSecretKey) { - return callback(new Error("Missing AWS Credentials")); - } - - this.generateMessage(emailMessage, (function(err, email){ - if(err){ - return typeof callback == "function" && callback(err); - } - this.handleMessage(email, callback); - }).bind(this)); -}; - -/** - *

Compiles and sends the request to SES with e-mail data

- * - * @param {String} email Compiled raw e-mail as a string - * @param {Function} callback Callback function to run once the message has been sent - */ -SESTransport.prototype.handleMessage = function(email, callback) { - var request, - date = new Date(), - urlparts = urllib.parse(this.options.ServiceUrl), - pairs = { - 'Action': 'SendRawEmail', - 'RawMessage.Data': (new Buffer(email, "utf-8")).toString('base64'), - 'Version': '2010-12-01', - 'Timestamp': this.ISODateString(date) - }; - - if (this.options.AWSSecurityToken) { - pairs.SecurityToken = this.options.AWSSecurityToken; - } - - var params = this.buildKeyValPairs(pairs), - - reqObj = { - host: urlparts.hostname, - path: urlparts.path || "/", - method: "POST", - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': params.length, - 'Date': date.toUTCString(), - 'X-Amzn-Authorization': - ['AWS3-HTTPS AWSAccessKeyID='+this.options.AWSAccessKeyID, - "Signature="+this.buildSignature(date.toUTCString(), this.options.AWSSecretKey), - "Algorithm=HmacSHA256"].join(",") - } - }; - - //Execute the request on the correct protocol - if(urlparts.protocol.substr() == "https:") { - request = https.request(reqObj, this.responseHandler.bind(this, callback)); - } else { - request = http.request(reqObj, this.responseHandler.bind(this, callback)); - } - request.end(params); -}; - -/** - *

Handles the response for the HTTP request to SES

- * - * @param {Function} callback Callback function to run on end (binded) - * @param {Object} response HTTP Response object - */ -SESTransport.prototype.responseHandler = function(callback, response) { - var body = "", match; - response.setEncoding('utf8'); - - //Re-assembles response data - response.on('data', function(d) { - body += d.toString(); - }); - - //Performs error handling and executes callback, if it exists - response.on('end', function(err) { - if(err instanceof Error) { - return typeof callback == "function" && callback(err, null); - } - if(response.statusCode != 200) { - return typeof callback == "function" && - callback(new Error('Email failed: ' + response.statusCode + '\n' + body), { - message: body, - response: response - }); - } - match = (body || "").toString().match(/]*>([^<]+)<\/MessageId\b[^>]*>/i); - return typeof callback == "function" && callback(null, { - message: body, - response: response, - messageId: match && match[1] && match[1] + "@email.amazonses.com" - }); - }); -}; - -/** - *

Compiles the messagecomposer object to a string.

- * - *

It really sucks but I don't know a good way to stream a POST request with - * unknown legth, so the message needs to be fully composed as a string.

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run once the message has been compiled - */ - -SESTransport.prototype.generateMessage = function(emailMessage, callback) { - var email = ""; - - emailMessage.on("data", function(chunk){ - email += (chunk || "").toString("utf-8"); - }); - - emailMessage.on("end", function(chunk){ - email += (chunk || "").toString("utf-8"); - callback(null, email); - }); - - emailMessage.streamMessage(); -}; - -/** - *

Converts an object into a Array with "key=value" values

- * - * @param {Object} config Object with keys and values - * @return {Array} Array of key-value pairs - */ -SESTransport.prototype.buildKeyValPairs = function(config){ - var keys = Object.keys(config).sort(), - keyValPairs = [], - key, i, len; - - for(i=0, len = keys.length; i < len; i++) { - key = keys[i]; - if(key != "ServiceUrl") { - keyValPairs.push((encodeURIComponent(key) + "=" + encodeURIComponent(config[key]))); - } - } - - return keyValPairs.join("&"); -}; - -/** - *

Uses SHA-256 HMAC with AWS key on date string to generate a signature

- * - * @param {String} date ISO UTC date string - * @param {String} AWSSecretKey ASW secret key - */ -SESTransport.prototype.buildSignature = function(date, AWSSecretKey) { - var sha256 = crypto.createHmac('sha256', AWSSecretKey); - sha256.update(date); - return sha256.digest('base64'); -}; - -/** - *

Generates an UTC string in the format of YYY-MM-DDTHH:MM:SSZ

- * - * @param {Date} d Date object - * @return {String} Date string - */ -SESTransport.prototype.ISODateString = function(d){ - return d.getUTCFullYear() + '-' + - this.strPad(d.getUTCMonth()+1) + '-' + - this.strPad(d.getUTCDate()) + 'T' + - this.strPad(d.getUTCHours()) + ':' + - this.strPad(d.getUTCMinutes()) + ':' + - this.strPad(d.getUTCSeconds()) + 'Z'; -}; - -/** - *

Simple padding function. If the number is below 10, add a zero

- * - * @param {Number} n Number to pad with 0 - * @return {String} 0 padded number - */ -SESTransport.prototype.strPad = function(n){ - return n<10 ? '0'+n : n; -}; - diff --git a/api/node_modules/nodemailer/lib/engines/smtp.js b/api/node_modules/nodemailer/lib/engines/smtp.js deleted file mode 100644 index 1015ed68e56..00000000000 --- a/api/node_modules/nodemailer/lib/engines/smtp.js +++ /dev/null @@ -1,131 +0,0 @@ -var wellKnownHosts = require("../wellknown"), - simplesmtp = require("simplesmtp"), - wellKnownDomains = {}; - -// Expose to the world -module.exports = SMTPTransport; - -// Convert Wellknown keys to lowercase -wellKnownHosts = Object.keys(wellKnownHosts).reduce(function(lowerCaseKeys, currentKey){ - - [].concat(wellKnownHosts[currentKey].domains || []).forEach(function(domain){ - wellKnownDomains[domain] = currentKey.toLowerCase().trim(); - }); - - lowerCaseKeys[currentKey.toLowerCase().trim()] = wellKnownHosts[currentKey]; - return lowerCaseKeys; -},{}); - -/** - *

Generates a Transport object for SMTP

- * - *

NB! This is a pool of connections that try to keep themselves alive. The - * connection is not closed to the server once the message is delivered.

- * - *

Possible options can be the following:

- * - *
    - *
  • service - a well known service identifier ("Gmail", "Hotmail" - * etc.) for auto-completing host, port and secure connection settings
  • - *
  • host - hostname of the SMTP server
  • - *
  • port - port of the SMTP server
  • - *
  • secureConnection - use SSL
  • - *
  • name - the name of the client server
  • - *
  • authMethod -specified the authMethod, value can be ["plain", "login"], default is "plain"
  • - *
  • auth - authentication object as {user:"...", pass:"..."} - *
  • ignoreTLS - ignore server support for STARTTLS
  • - *
  • debug - output client and server messages to console
  • - *
  • maxConnections - how many connections to keep in the pool
  • - *
- * - * @constructor - * @param {Object} [options] SMTP options - */ -function SMTPTransport(options){ - - - this.options = options || {}; - - this.initOptions(); - - this.pool = simplesmtp.createClientPool(this.options.port, - this.options.host, this.options); -} - -SMTPTransport.wellKnownHosts = wellKnownHosts; - -/** - *

Initializes the SMTP connection options. Needed mostly for legacy option - * values and also for filling in the well known hosts data if needed.

- */ -SMTPTransport.prototype.initOptions = function(){ - var keys, key, i, len, service; - - // provide support for legacy API - if(this.options.use_authentication === false){ - this.options.auth = false; - }else if(this.options.user || this.options.pass || this.options.XOAuthToken){ - if(!this.options.auth){ - this.options.auth = {}; - } - this.options.authMethod = this.options.authMethod || "PLAIN"; - this.options.auth.user = this.options.auth.user || this.options.user; - this.options.auth.pass = this.options.auth.pass || this.options.pass; - this.options.auth.XOAuthToken = this.options.auth.XOAuthToken || this.options.XOAuthToken; - this.options.auth.XOAuth2 = this.options.auth.XOAuth2 || this.options.XOAuth2; - } - - if(this.options.ssl){ - this.options.secureConnection = true; - } - - if(this.options.tls === false){ - this.options.ignoreTLS = true; - } - - // lets be modest just in case - this.options.maxConnections = this.options.maxConnections || 5; - - // detect service from the e-mail address if host is not provided before falling to localhost - if(!this.options.host && !this.options.port && !this.options.service && this.options.auth && this.options.auth.user){ - this.options.service = wellKnownDomains[(this.options.auth.user || "").toString().split("@").pop().toLowerCase().trim()] || false; - } - - // use well known settings if service is defined - if((service = this.options.service) && (service = service.toString().toLowerCase().trim()) && wellKnownHosts[service]){ - keys = Object.keys(wellKnownHosts[service]); - for(i=0, len=keys.length; iForwards the mailcomposer message object to the simplesmpt client pool

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run when the sending is completed - */ -SMTPTransport.prototype.sendMail = function(emailMessage, callback){ - // force SMTP encoding - emailMessage.options.escapeSMTP = true; - - if(this.options.requiresAuth && - (!this.options.auth || !((this.options.auth.user && this.options.auth.pass) || this.options.auth.XOAuth2 || this.options.auth.XOAuthToken))){ - return typeof callback == "function" && - callback(new Error("Authentication required, invalid details provided")); - } - - this.pool.sendMail(emailMessage, callback); -}; - -/** - *

Closes the client pool

- * - * @param {Function} callback Callback function to run once the pool is closed - */ -SMTPTransport.prototype.close = function(callback){ - this.pool.close(callback); -}; diff --git a/api/node_modules/nodemailer/lib/engines/stub.js b/api/node_modules/nodemailer/lib/engines/stub.js deleted file mode 100644 index 1d1ba98ff2b..00000000000 --- a/api/node_modules/nodemailer/lib/engines/stub.js +++ /dev/null @@ -1,39 +0,0 @@ - -// Expose to the world -module.exports = StubTransport; - -/** - *

Generates a stub Transport object for testing purposes

- * - * @constructor - */ -function StubTransport(){} - -/** - *

Generates a raw e-mail source and returns it with callback

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run when the e-mail is composed - */ -StubTransport.prototype.sendMail = function(emailMessage, callback) { - - var output = ""; - - // sendmail strips this header line by itself - emailMessage.options.keepBcc = true; - - emailMessage.on("data", function(data){ - output += (data || "").toString("utf-8"); - }); - - emailMessage.on("error", function(err){ - callback(err); - }); - - emailMessage.on("end", function(){ - callback(null, {message: output, envelope: emailMessage.getEnvelope(), messageId: emailMessage._messageId}); - }); - - emailMessage.streamMessage(); - -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/lib/helpers.js b/api/node_modules/nodemailer/lib/helpers.js deleted file mode 100644 index 232ae787597..00000000000 --- a/api/node_modules/nodemailer/lib/helpers.js +++ /dev/null @@ -1,225 +0,0 @@ -// expose to the world -module.exports.stripHTML = stripHTML; - -/** - *

Converts a HTML stringo into plaintext format that resembles Markdown

- * - *

Only good for simple and valid HTML, probably breaks on eveything else

- * - *

Placeholders:

- * - *
    - *
  • -\u0000\u0000- for newline
  • - *
  • -\u0001\u0001- for a space
  • - *
  • -\u0002\u0002- temporary newlines
  • - *
- * - * @param {String} str HTML string to convert - * @return {String} Plaintext that resembles Markdown - */ -function stripHTML(str){ - str = (str || "").toString("utf-8").trim(); - - // remove head - str = str.replace(//gi, ''); - - // replace newlines - str = str.replace(/\r?\n|\r/g,"-\u0002\u0002-"); - - // convert block element endings to linebreak markers - str = str.replace(/<(?:\/p|br|\/tr|\/table|\/div)>/g,"-\u0000\u0000--\u0000\u0000-"); - - // H1-H6, add underline or prepend with # - str = str.replace(/<[hH](\d)[^>]*>(.*?)<\/[hH]\d[^>]*>/g,function(match, level, content){ - var line = "", - symbol, // line symbol char - len; - - level = Number(level) || 0; - - content = decodeHTMLEntities(content.replace(/<[^>]*>/g," "). - replace(/\s\s+/g," ")). - trim(); - - if(!content){ - // the tag was empty or only included other tags ( and such), nothing to show - return ""; - } - - // select correct symbol for the line - switch(level){ - case 1: - symbol = "="; - len = content.length; - break; - case 2: - symbol = "-"; - len = content.length; - break; - default: - symbol = "#"; - len = level; - } - - line = new Array(len+1).join(symbol); - - if(symbol == "#"){ - // prepend the line: - // ### This is a H3 - return line + " " + content + "\n\n"; - }else{ - // add underline: - // This is a H1 - // ============ - return content + "\n" + line + "\n\n"; - } - - }); - - // B - str = str.replace(/<(?:b|strong)(?: [^>])?>(.*?)<\/(?:b|strong)>/ig,function(match, content){ - return "**" + content.trim() + "**"; - }); - - // U - str = str.replace(/])?>(.*?)<\/u>/ig,function(match, content){ - return "_" + content.trim() + "_"; - }); - - // EM - str = str.replace(/<(?:i|em)(?: [^>])?>(.*?)<\/(?:i|em)>/ig,function(match, content){ - return "*" + content.trim() + "*"; - }); - - // CODE - str = str.replace(/])?>(.*?)<\/code>/ig,function(match, content){ - return "`" + content.trim() + "`"; - }); - - // A - str = str.replace(/
]*)>(.*?)<\/a[^>]*>/ig,function(match, params, content){ - var paramMatch = params.match(/href\s*=\s*['"]([^'"]+)['"]/), - url = paramMatch && paramMatch[1] || "#"; - - return "[" + content.trim() + "]" + "(" + url +")"; - }); - - // UL, replace with newlines - str = str.replace(/(<\/(?:ul|ol)>)/gi,"$1-\u0000\u0000--\u0000\u0000-"); - - // LI, indent by 2 spaces + * - str = str.replace(/]*>(.*?)<\/?(?:li|ol|ul)[^>]*>/ig,function(match, content){ - - content = content.replace(/<[^>]*>/g," "). - replace(/\s\s+/g," "). - trim(); - - if(!content){ - // the tag was empty or only included other tags ( and such), nothing to show - return ""; - } - - // return with the space placeholders - return "-\u0001\u0001--\u0001\u0001-* " + content + "\n"; - }); - - // PRE, indent by 4 spaces - str = str.replace(/]*>(.*?)<\/pre[^>]*>/ig,function(match, content){ - if(!content){ - return ""; - } - - // remove empty lines before and after - content = content.replace(/^((?:[ \t]*)\-\u0002\u0002\-)+|((?:\-\u0002\u0002\-[ \t]*))+$/g, ""); - - // replace tabs with 4 spaces - content = content.replace(/\t/g, " "); - - // replace temp. linebreak placeholders with 4 space placehorlders - content = content.replace(/\-\u0002\u0002\-([ ]*)/g, function(match, spaces){ - // keep spaces in the beginning of the lines - spaces = spaces.replace(/ /g, "-\u0001\u0001-"); - - return "\n-\u0001\u0001--\u0001\u0001--\u0001\u0001--\u0001\u0001-" + spaces; - }); - - content = content.replace(//g,">"); - - // add prepending 4 spaces - return "\n-\u0001\u0001--\u0001\u0001--\u0001\u0001--\u0001\u0001-" + content.trim() + "\n\n"; - }); - - // remove all remaining html tags - str = str.replace(/<[^>]*>/g," "); - - // remove duplicate spaces - str = str.replace(/[ ][ ]+/g," "); - - // remove temp. newlines - str = str.replace(/-\u0002\u0002-/g," "); - - // restore newlines - str = str.replace(/-\u0000\u0000-/g,"\n"); - - // remove spaces before and after newlines - str = str.replace(/[ \t]*\n[ \t]*/g,"\n"); - - // remove more than 2 newlines in a row - str = str.replace(/\n\n+/g,"\n\n"); - - // restore hidden spaces - str = str.replace(/-\u0001\u0001-/g," "); - - // decode HTML entities (< and such) - str = decodeHTMLEntities(str); - - return str.trim(); -} - -/** - *

Decodes any HTML entities in a string into their unicode form

- * - * @param {String} text text to decode - * @return {String} Decoded text - */ -function decodeHTMLEntities(text){ - var HTMLEntities = { - apos:0x0027,quot:0x0022,amp:0x0026,lt:0x003C,gt:0x003E,nbsp:0x00A0,iexcl:0x00A1,cent:0x00A2,pound:0x00A3, - curren:0x00A4,yen:0x00A5,brvbar:0x00A6,sect:0x00A7,uml:0x00A8,copy:0x00A9,ordf:0x00AA,laquo:0x00AB, - not:0x00AC,shy:0x00AD,reg:0x00AE,macr:0x00AF,deg:0x00B0,plusmn:0x00B1,sup2:0x00B2,sup3:0x00B3, - acute:0x00B4,micro:0x00B5,para:0x00B6,middot:0x00B7,cedil:0x00B8,sup1:0x00B9,ordm:0x00BA,raquo:0x00BB, - frac14:0x00BC,frac12:0x00BD,frac34:0x00BE,iquest:0x00BF,Agrave:0x00C0,Aacute:0x00C1,Acirc:0x00C2,Atilde:0x00C3, - Auml:0x00C4,Aring:0x00C5,AElig:0x00C6,Ccedil:0x00C7,Egrave:0x00C8,Eacute:0x00C9,Ecirc:0x00CA,Euml:0x00CB, - Igrave:0x00CC,Iacute:0x00CD,Icirc:0x00CE,Iuml:0x00CF,ETH:0x00D0,Ntilde:0x00D1,Ograve:0x00D2,Oacute:0x00D3, - Ocirc:0x00D4,Otilde:0x00D5,Ouml:0x00D6,times:0x00D7,Oslash:0x00D8,Ugrave:0x00D9,Uacute:0x00DA,Ucirc:0x00DB, - Uuml:0x00DC,Yacute:0x00DD,THORN:0x00DE,szlig:0x00DF,agrave:0x00E0,aacute:0x00E1,acirc:0x00E2,atilde:0x00E3, - auml:0x00E4,aring:0x00E5,aelig:0x00E6,ccedil:0x00E7,egrave:0x00E8,eacute:0x00E9,ecirc:0x00EA,euml:0x00EB, - igrave:0x00EC,iacute:0x00ED,icirc:0x00EE,iuml:0x00EF,eth:0x00F0,ntilde:0x00F1,ograve:0x00F2,oacute:0x00F3, - ocirc:0x00F4,otilde:0x00F5,ouml:0x00F6,divide:0x00F7,oslash:0x00F8,ugrave:0x00F9,uacute:0x00FA,ucirc:0x00FB, - uuml:0x00FC,yacute:0x00FD,thorn:0x00FE,yuml:0x00FF,OElig:0x0152,oelig:0x0153,Scaron:0x0160,scaron:0x0161, - Yuml:0x0178,fnof:0x0192,circ:0x02C6,tilde:0x02DC,Alpha:0x0391,Beta:0x0392,Gamma:0x0393,Delta:0x0394, - Epsilon:0x0395,Zeta:0x0396,Eta:0x0397,Theta:0x0398,Iota:0x0399,Kappa:0x039A,Lambda:0x039B,Mu:0x039C, - Nu:0x039D,Xi:0x039E,Omicron:0x039F,Pi:0x03A0,Rho:0x03A1,Sigma:0x03A3,Tau:0x03A4,Upsilon:0x03A5, - Phi:0x03A6,Chi:0x03A7,Psi:0x03A8,Omega:0x03A9,alpha:0x03B1,beta:0x03B2,gamma:0x03B3,delta:0x03B4, - epsilon:0x03B5,zeta:0x03B6,eta:0x03B7,theta:0x03B8,iota:0x03B9,kappa:0x03BA,lambda:0x03BB,mu:0x03BC, - nu:0x03BD,xi:0x03BE,omicron:0x03BF,pi:0x03C0,rho:0x03C1,sigmaf:0x03C2,sigma:0x03C3,tau:0x03C4, - upsilon:0x03C5,phi:0x03C6,chi:0x03C7,psi:0x03C8,omega:0x03C9,thetasym:0x03D1,upsih:0x03D2,piv:0x03D6, - ensp:0x2002,emsp:0x2003,thinsp:0x2009,zwnj:0x200C,zwj:0x200D,lrm:0x200E,rlm:0x200F,ndash:0x2013, - mdash:0x2014,lsquo:0x2018,rsquo:0x2019,sbquo:0x201A,ldquo:0x201C,rdquo:0x201D,bdquo:0x201E,dagger:0x2020, - Dagger:0x2021,bull:0x2022,hellip:0x2026,permil:0x2030,prime:0x2032,Prime:0x2033,lsaquo:0x2039,rsaquo:0x203A, - oline:0x203E,frasl:0x2044,euro:0x20AC,image:0x2111,weierp:0x2118,real:0x211C,trade:0x2122,alefsym:0x2135, - larr:0x2190,uarr:0x2191,rarr:0x2192,darr:0x2193,harr:0x2194,crarr:0x21B5,lArr:0x21D0,uArr:0x21D1, - rArr:0x21D2,dArr:0x21D3,hArr:0x21D4,forall:0x2200,part:0x2202,exist:0x2203,empty:0x2205,nabla:0x2207, - isin:0x2208,notin:0x2209,ni:0x220B,prod:0x220F,sum:0x2211,minus:0x2212,lowast:0x2217,radic:0x221A, - prop:0x221D,infin:0x221E,ang:0x2220,and:0x2227,or:0x2228,cap:0x2229,cup:0x222A,"int":0x222B, - there4:0x2234,sim:0x223C,cong:0x2245,asymp:0x2248,ne:0x2260,equiv:0x2261,le:0x2264,ge:0x2265, - sub:0x2282,sup:0x2283,nsub:0x2284,sube:0x2286,supe:0x2287,oplus:0x2295,otimes:0x2297,perp:0x22A5, - sdot:0x22C5,lceil:0x2308,rceil:0x2309,lfloor:0x230A,rfloor:0x230B,lang:0x2329,rang:0x232A,loz:0x25CA, - spades:0x2660,clubs:0x2663,hearts:0x2665,diams:0x2666 - }; - - return text.replace(/&(.+?);/g, function(str, ent){ - return String.fromCharCode(ent[0] !== '#' ? HTMLEntities[ent] : ent[1] === 'x' ? parseInt(ent.substr(2),16) : parseInt(ent.substr(1), 10)); - } - ); -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/lib/nodemailer.js b/api/node_modules/nodemailer/lib/nodemailer.js deleted file mode 100644 index a524bf8c069..00000000000 --- a/api/node_modules/nodemailer/lib/nodemailer.js +++ /dev/null @@ -1,332 +0,0 @@ -var Transport = require("./transport").Transport, - MailComposer = require("mailcomposer").MailComposer, - XOAuthGenerator = require("./xoauth").XOAuthGenerator, - helpers = require("./helpers"), - packageData; - -try{ - packageData = require("../package.json"); -}catch(E){ - // probably node 0.4 which doesn't support loading json files as objects - packageData = JSON.parse( - require("fs"). - readFileSync( - require("path"). - join( - __dirname, - "..", - "package.json" - ) - ) - ); -} - - -/* - * Version constants - */ -var X_MAILER_NAME = "Nodemailer", - X_MAILER_HOMEPAGE = "http://www.nodemailer.com/"; - -module.exports.X_MAILER_NAME = X_MAILER_NAME; -module.exports.X_MAILER_HOMEPAGE = X_MAILER_HOMEPAGE; - -// Export createTransport method -module.exports.createTransport = function(type, options){ - var transport = new Transport(type, options); - transport.sendMail = function(options, callback){ - options = options || {}; - options.transport = options.transport || transport; - sendMail(options, callback); - }; - return transport; -}; - -//Export createXOAuthGenerator function -module.exports.createXOAuthGenerator = function(options){ - return new XOAuthGenerator(options); -}; - - -// Export Transport constructor -module.exports.Transport = Transport; - -// Export Nodemailer constructor -module.exports.Nodemailer = Nodemailer; - -// Export sendMail function (and the alias send_mail for legacy) -module.exports.sendMail = module.exports.send_mail = sendMail; - -function sendMail(options, callback){ - var mailer = new Nodemailer(options); - - mailer.validateSettings(function(err){ - if(err){ - // report validation error back to the client - return callback(err); - }else{ - // try to send the e-mail message - mailer.sendMail(callback); - } - }); - - return mailer; -} - - -/** - *

Generates a Nodemailer object which is the main 'hub' for managing the - * send process

- * - * @constructor - * @param {Object} options Message options object, see README for the complete list of possible options - */ -function Nodemailer(options){ - var mailcomposerOptions = {}; - - this.options = options || {}; - - this.transport = this.options.transport; - - mailcomposerOptions.identityString = X_MAILER_NAME + " " + packageData.version; - - if(this.options.encoding){ - mailcomposerOptions.encoding = this.options.encoding; - } - - if(this.options.charset){ - mailcomposerOptions.charset = this.options.charset; - } - - if(!!this.options.forceEmbeddedImages){ - mailcomposerOptions.forceEmbeddedImages = true; - } - - this.mailcomposer = new MailComposer(mailcomposerOptions); - - if(!this.transport){ - this.transport = this.getGlobalTransport(); - } -} - -/** - *

Generates an user agent string for Nodemailer with homepage, version etc.

- * - * @return {String} user agent string for X-Mailer value - */ -Nodemailer.prototype.generateUserAgentString = function(){ - var details = []; - - if(packageData.version){ - details.push(packageData.version); - } - - if(X_MAILER_HOMEPAGE){ - details.push("+"+X_MAILER_HOMEPAGE); - } - - return X_MAILER_NAME+ (details.length?" ("+details.join("; ")+")":""); -}; - -/** - *

Add support for legacy transport settings by checking for global - * variables SMTP, sendmail and SES

- * - * @return {Object} {@link Transport} object - */ -Nodemailer.prototype.getGlobalTransport = function(){ - if(this.options.SMTP){ - // cache the transport for SMTP as it is actually a connection pool - if(!this.options.SMTP._smtp_transport){ - this.options.SMTP._smtp_transport = new Transport("SMTP", this.options.SMTP); - } - return this.options.SMTP._smtp_transport; - }else if(this.options.sendmail){ - return new Transport("sendmail", this.options.sendmail); - }else if(this.options.SES){ - return new Transport("SES", this.options.SES); - }else if(module.exports.SMTP){ - // cache the transport for SMTP as it is actually a connection pool - if(!module.exports._smtp_transport){ - module.exports._smtp_transport = new Transport("SMTP", module.exports.SMTP); - } - return module.exports._smtp_transport; - }else if(module.exports.sendmail){ - return new Transport("sendmail", module.exports.sendmail); - }else if(module.exports.SES){ - return new Transport("SES", module.exports.SES); - } - return false; -}; - -/** - *

Doesn't do much currently, if the future should link to transport - * validation methods. For example in case of SES should check that AWS - * keys are set up etc.

- * - * @param {Function} callback Callback function to run after validation - */ -Nodemailer.prototype.validateSettings = function(callback){ - if(!this.transport || !this.transport.transport){ - return callback(new Error("No transport method defined")); - } - callback(null); -}; - -/** - *

Send the e-mail message by using data from the original options object - * and selected transport

- * - * @param {Function} callback Callback function to run when the e-mail has been sent (or it failed) - */ -Nodemailer.prototype.sendMail = function(callback){ - // compose the e-mail - this.generateMailObject(); - // send the message using preselected transport method - this.transport.sendMailWithTransport(this.mailcomposer, callback); -}; - -/** - *

Uses the data from the original options object to compose a mailcomposer - * e-mail message that can be later streamed to the selected transport

- */ -Nodemailer.prototype.generateMailObject = function(){ - - // set envelope data, subject etc. - this.setGeneralOptions(); - - // set module defined headers (date, message-id, etc.) - this.setModuleHeaders(); - - // set user defined headers (if any) - this.setUserHeaders(); - - // set alternatives (if any) - this.setAlternatives(); - - // set attachments (if any) - this.setAttachments(); -}; - -/** - *

Uses the general options (message sender and receiver, subject body, etc.) - * to set mailcomposer properties. Includes support for legacy properties.

- */ -Nodemailer.prototype.setGeneralOptions = function(){ - - // generate plaintext if only HTML exists and generateTextFromHTML is true - if(!(this.options.text || this.options.body) && (this.options.html) && - this.options.generateTextFromHTML){ - this.options.text = helpers.stripHTML(this.options.html); - } - - var acceptedFields = ["from", "sender", "to", "subject", "replyTo", "debug", - "reply_to", "cc", "bcc", "body", "text", "html", - "envelope", "inReplyTo", "references"], - mailOptions = {}, - keys = Object.keys(this.options), - key; - - for(var i=0, len=keys.length; i=0 && this.options[key]){ - mailOptions[key] = this.options[key]; - } - } - - if(this.options.debug){ - console.log(mailOptions); - } - - this.mailcomposer.setMessageOption(mailOptions); -}; - -/** - *

If the 'headers' property was set on the options, add the values to the - * header of the e-mail message

- */ -Nodemailer.prototype.setUserHeaders = function(){ - if(typeof this.options.headers != "object"){ - return; - } - var keys = Object.keys(this.options.headers), - key; - - for(var i=0, len=keys.length; iAdd some required headers to the message, such as Date: and Message-Id:

- */ -Nodemailer.prototype.setModuleHeaders = function(){ - var messageId; - - // Mailer name + version - this.mailcomposer.addHeader("X-Mailer", this.generateUserAgentString()); - - // Date - if(this.options.date){ - this.mailcomposer.addHeader("Date", this.options.date); - }else{ - this.mailcomposer.addHeader("Date", new Date().toUTCString()); - } - - // Message ID - if(this.options.messageId){ - messageId = this.options.messageId; - }else if(this.options.messageId !== false){ - messageId = Date.now()+Math.random().toString(16).substr(1) +"@"+ X_MAILER_NAME; - } - - if(messageId){ - this.mailcomposer.addHeader("Message-Id", "<"+messageId+">"); - this.mailcomposer._messageId = messageId; - } - -}; - -/** - *

If attachment array is set on the options object, add these alternatives - * to the mailcomposer object

- */ -Nodemailer.prototype.setAlternatives = function(){ - var alternative; - - if(!this.options.alternatives){ - return; - } - - // convert non array value to an array if needed - this.options.alternatives = [].concat(this.options.alternatives); - - for(var i=0, len=this.options.alternatives.length; iIf attachment array is set on the options object, add these attachments - * to the mailcomposer object

- */ -Nodemailer.prototype.setAttachments = function(){ - var attachment; - - if(!this.options.attachments){ - return; - } - - // convert non array value to an array if needed - this.options.attachments = [].concat(this.options.attachments); - - for(var i=0, len=this.options.attachments.length; iGenerates a Transport object that can be used to deliver e-mail.

- * - *

All transport objects need to have sendMail property defined - * and if needed, also an close method

- * - * @constructor - * @param {String} type The type of the transport, currently available: SMTP, SES and Sendmail - */ -function Transport(type, options){ - - this.options = options; - - this.transportType = (type || "").toString().trim().toUpperCase(); - this.dkimOptions = false; - - if(!(this.transportType in Transport.transports) && this.transportType.toLowerCase() in SMTPTransport.wellKnownHosts){ - this.options.service = this.transportType; - this.transportType = SMTPTransport.wellKnownHosts[this.transportType.toLowerCase()].transport; - } - - var constructor = Transport.transports[this.transportType]; - if(constructor){ - this.transport = new constructor(this.options); - }else{ - this.transport = false; - } - -} - -/** - *

Forwards the generated mailcomposer object to the selected transport - * object for message delivery

- * - * @param {Object} emailMessage MailComposer object - * @param {Function} callback Callback function to run when the sending is completed - */ -Transport.prototype.sendMailWithTransport = function(emailMessage, callback){ - if(!this.transport){ - return callback(new Error("Invalid transport method defined")); - } - - if(this.dkimOptions){ - emailMessage.useDKIM(this.dkimOptions); - } - - this.transport.sendMail(emailMessage, callback); -}; - -/** - *

Sets up DKIM signing for this transport object

- * - * @param {Object} dkim DKIM options - */ -Transport.prototype.useDKIM = function(dkim){ - this.dkimOptions = dkim; -}; - -/** - *

Closes the transport when needed, useful with SMTP (which uses connection - * pool) but not so much with SES or Sendmail

- * - * @param {Function} Callback function to run when the connection is closed - */ -Transport.prototype.close = function(callback){ - if(!this.transport){ - return callback(new Error("Invalid transport method defined")); - } - - if(typeof this.transport.close == "function"){ - this.transport.close(callback); - }else{ - if(typeof callback == "function"){ - callback(null); - } - } -}; diff --git a/api/node_modules/nodemailer/lib/wellknown.js b/api/node_modules/nodemailer/lib/wellknown.js deleted file mode 100644 index 57e0e3ce374..00000000000 --- a/api/node_modules/nodemailer/lib/wellknown.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This is a collection of well known SMTP service providers - */ - -module.exports = { - "Gmail":{ - transport: "SMTP", - host: "smtp.gmail.com", - secureConnection: true, - port: 465, - requiresAuth: true, - domains: ["gmail.com", "googlemail.com"] - }, - "Yahoo":{ - transport: "SMTP", - host: "smtp.mail.yahoo.com", - secureConnection: true, - port: 465, - requiresAuth: true, - domains: ["yahoo.com"] - }, - "Hotmail":{ - transport: "SMTP", - host: "smtp.live.com", - port: 587, - requiresAuth: true, - domains: ["hotmail.com", "outlook.com"], - tls: {ciphers:'SSLv3'} - }, - "hot.ee":{ - transport: "SMTP", - host: "mail.hot.ee", - requiresAuth: true, - domains: ["hot.ee"] - }, - "mail.ee":{ - transport: "SMTP", - host: "smtp.mail.ee", - requiresAuth: true, - domains: ["mail.ee"] - }, - "SES":{ - transport: "SMTP", - host: "email-smtp.us-east-1.amazonaws.com", - secureConnection: true, - port: 465, - requiresAuth: true - }, - "Zoho":{ - transport: "SMTP", - host: "smtp.zoho.com", - secureConnection: true, - port: 465, - requiresAuth: true, - authMethod: 'LOGIN' - }, - "iCloud":{ - transport: "SMTP", - host:"smtp.mail.me.com", - port: 587, - requiresAuth: true, - domains: ["me.com", "mac.com"] - }, - "SendGrid":{ - transport: "SMTP", - host: "smtp.sendgrid.net", - port: 587, - requiresAuth: true - }, - "Mailgun":{ - transport: "SMTP", - host: "smtp.mailgun.org", - port: 587, - requiresAuth: true - }, - "Postmark":{ - transport: "SMTP", - host: "smtp.postmarkapp.com", - port: 25, - requiresAuth: true - }, - "yandex":{ - transport: "SMTP", - host: "smtp.yandex.ru", - port: 465, - secureConnection: true, - requiresAuth: true, - domains: ["yandex.ru"] - }, - "Mail.Ru":{ - transport: "SMTP", - host: "smtp.mail.ru", - port: 465, - secureConnection: true, - requiresAuth: true, - domains: ["mail.ru"] - }, - "DynectEmail":{ - transport: "SMTP", - host:"smtp.dynect.net", - port:25, - requiresAuth: true - }, - "Mandrill":{ - transport: "SMTP", - host: "smtp.mandrillapp.com", - port: 587, - requiresAuth: true - }, - "Mailjet":{ - transport: "SMTP", - host: "in.mailjet.com", - port: 587, - requiresAuth: true - }, - "QQ":{ - transport: "SMTP", - host: "smtp.qq.com", - secureConnection: true, - port: 465, - requiresAuth: true, - domains: ["qq.com"] - } -}; diff --git a/api/node_modules/nodemailer/lib/xoauth.js b/api/node_modules/nodemailer/lib/xoauth.js deleted file mode 100644 index f8445404c3c..00000000000 --- a/api/node_modules/nodemailer/lib/xoauth.js +++ /dev/null @@ -1,71 +0,0 @@ -// this module is inspired by xoauth.py -// http://code.google.com/p/google-mail-xoauth-tools/ - -var crypto = require("crypto"); - -module.exports.XOAuthGenerator = XOAuthGenerator; - -function XOAuthGenerator(options){ - this.options = options || {}; -} - -XOAuthGenerator.prototype.generate = function(callback){ - return generateXOAuthStr(this.options, callback); -}; - -function escapeAndJoin(arr){ - return arr.map(encodeURIComponent).join("&"); -} - -function hmacSha1(str, key){ - var hmac = crypto.createHmac("sha1", key); - hmac.update(str); - return hmac.digest("base64"); -} - -function initOAuthParams(options){ - return { - oauth_consumer_key: options.consumerKey || "anonymous", - oauth_nonce: options.nonce || "" + Date.now() + Math.round(Math.random()*1000000), - oauth_signature_method: "HMAC-SHA1", - oauth_version: "1.0", - oauth_timestamp: options.timestamp || "" + Math.round(Date.now()/1000) - }; -} - -function generateOAuthBaseStr(method, requestUrl, params){ - var reqArr = [method, requestUrl].concat(Object.keys(params).sort().map(function(key){ - return key + "=" + encodeURIComponent(params[key]); - }).join("&")); - - return escapeAndJoin(reqArr); -} - -function generateXOAuthStr(options, callback){ - options = options || {}; - - var params = initOAuthParams(options), - requestUrl = options.requestUrl || "https://mail.google.com/mail/b/" + (options.user || "") + "/smtp/", - baseStr, signatureKey, paramsStr, returnStr; - - if(options.token){ - params.oauth_token = options.token; - } - - baseStr = generateOAuthBaseStr(options.method || "GET", requestUrl, params); - - signatureKey = escapeAndJoin([options.consumerSecret || "anonymous", options.tokenSecret]); - params.oauth_signature = hmacSha1(baseStr, signatureKey); - - paramsStr = Object.keys(params).sort().map(function(key){ - return key+"=\""+encodeURIComponent(params[key])+"\""; - }).join(","); - - returnStr = [options.method || "GET", requestUrl, paramsStr].join(" "); - - if(typeof callback == "function"){ - callback(null, new Buffer(returnStr, "utf-8").toString("base64")); - }else{ - return new Buffer(returnStr, "utf-8").toString("base64"); - } -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/.npmignore b/api/node_modules/nodemailer/node_modules/mailcomposer/.npmignore deleted file mode 100644 index 28f1ba7565f..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.DS_Store \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml b/api/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml deleted file mode 100644 index 27b9be585b8..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - "0.10" - -notifications: - email: - recipients: - - andris@node.ee - on_success: change - on_failure: change diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/LICENSE b/api/node_modules/nodemailer/node_modules/mailcomposer/LICENSE deleted file mode 100644 index a47b0eaf959..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2012 Andris Reinman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/README.md deleted file mode 100644 index a262f10960b..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/README.md +++ /dev/null @@ -1,377 +0,0 @@ -# mailcomposer - -**mailcomposer** is a Node.JS module for generating e-mail messages that can be -streamed to SMTP or file. - -This is a standalone module that only generates raw e-mail source, you need to -write your own or use an existing transport mechanism (SMTP client, Amazon SES, -SendGrid etc). **mailcomposer** frees you from the tedious task of generating -[rfc2822](http://tools.ietf.org/html/rfc2822) compatible messages. - -[![Build Status](https://secure.travis-ci.org/andris9/mailcomposer.png)](http://travis-ci.org/andris9/mailcomposer) - -**mailcomposer** supports: - - * **Unicode** to use any characters ✔ - * **HTML** content as well as **plain text** alternative - * **Attachments** and streaming for larger files (use strings, buffers, files or binary streams as attachments) - * **Embedded images** in HTML - * **DKIM** signing - * usage of **your own** transport mechanism - -## Support mailcomposer development - -[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W) - -## Installation - -Install through NPM - - npm install mailcomposer - -## Usage - -### Include mailcomposer module - - var MailComposer = require("mailcomposer").MailComposer; - -### Create a new `MailComposer` instance - - var mailcomposer = new MailComposer([options]); - -Where `options` is an optional options object with the following possible properties: - - * **escapeSMTP** - if set replaces dots in the beginning of a line with double dots - * **encoding** - sets transfer encoding for the textual parts (defaults to `"quoted-printable"`) - * **charset** - sets output character set for strings (defaults to `"utf-8"`) - * **keepBcc** - if set to true, includes `Bcc:` field in the message headers. Useful for *sendmail* command. - * **forceEmbeddedImages** - convert image urls and absolute paths in HTML to embedded attachments. - -### Simple example - -The following example generates a simple e-mail message with plaintext and html -body. - - var MailComposer = require("mailcomposer").MailComposer; - mailcomposer = new MailComposer(), - fs = require("fs"); - - // add additional header field - mailcomposer.addHeader("x-mailer", "Nodemailer 1.0"); - - // setup message data - mailcomposer.setMessageOption({ - from: "andris@tr.ee", - to: "andris@node.ee", - body: "Hello world!", - html: "Hello world!" - }); - - mailcomposer.streamMessage(); - - // pipe the output to a file - mailcomposer.pipe(fs.createWriteStream("test.eml")); - -The output for such a script (the contents for "test.eml") would look like: - - MIME-Version: 1.0 - X-Mailer: Nodemailer 1.0 - From: andris@tr.ee - To: andris@node.ee - Content-Type: multipart/alternative; - boundary="----mailcomposer-?=_1-1328088797399" - - ------mailcomposer-?=_1-1328088797399 - Content-Type: text/plain; charset=utf-8 - Content-Transfer-Encoding: quoted-printable - - Hello world! - ------mailcomposer-?=_1-1328088797399 - Content-Type: text/html; charset=utf-8 - Content-Transfer-Encoding: quoted-printable - - Hello world! - ------mailcomposer-?=_1-1328088797399-- - -## API - -### Add custom headers - -Headers can be added with `mailcomposer.addHeader(key, value)` - - var mailcomposer = new MailComposer(); - mailcomposer.addHeader("x-mailer", "Nodemailer 1.0"); - -If you add an header value with the same key several times, all of the values will be used -in the generated header. For example: - - mailcomposer.addHeader("x-mailer", "Nodemailer 1.0"); - mailcomposer.addHeader("x-mailer", "Nodemailer 2.0"); - -Will be generated into - - ... - X-Mailer: Nodemailer 1.0 - X-Mailer: Nodemailer 2.0 - ... - -The contents of the field value is not edited in any way (except for the folding), -so if you want to use unicode symbols you need to escape these to mime words -by yourself. Exception being object values - in this case the object -is automatically JSONized and mime encoded. - - // using objects as header values is allowed (will be converted to JSON) - var apiOptions = {}; - apiOptions.category = "newuser"; - apiOptions.tags = ["user", "web"]; - mailcomposer.addHeader("X-SMTPAPI", apiOptions) - -### Add message parts - -You can set message sender, receiver, subject line, message body etc. with -`mailcomposer.setMessageOption(options)` where options is an object with the -data to be set. This function overwrites any previously set values with the -same key - -The following example creates a simple e-mail with sender being `andris@tr.ee`, -receiver `andris@node.ee` and plaintext part of the message as `Hello world!`: - - mailcomposer.setMessageOption({ - from: "andris@tr.ee", - to: "andris@node.ee", - body: "Hello world!" - }); - -Possible options that can be used are (all fields accept unicode): - - * **from** (alias `sender`) - the sender of the message. If several addresses are given, only the first one will be used - * **to** - receivers for the `To:` field - * **cc** - receivers for the `Cc:` field - * **bcc** - receivers for the `Bcc:` field - * **replyTo** (alias `reply_to`) - e-mail address for the `Reply-To:` field - * **inReplyTo** - The message-id this message is replying - * **references** - Message-id list - * **subject** - the subject line of the message - * **body** (alias `text`) - the plaintext part of the message - * **html** - the HTML part of the message - * **envelope** - optional SMTP envelope, if auto generated envelope is not suitable - -This method can be called several times - - mailcomposer.setMessageOption({from: "andris@tr.ee"}); - mailcomposer.setMessageOption({to: "andris@node.ee"}); - mailcomposer.setMessageOption({body: "Hello world!"}); - -Trying to set the same key several times will yield in overwrite - - mailcomposer.setMessageOption({body: "Hello world!"}); - mailcomposer.setMessageOption({body: "Hello world?"}); - // body contents will be "Hello world?" - -### Address format - -All e-mail address fields take structured e-mail lists (comma separated) -as the input. Unicode is allowed for all the parts (receiver name, e-mail username -and domain) of the address. If the domain part contains unicode symbols, it is -automatically converted into punycode, user part will be converted into UTF-8 -mime word. - -E-mail addresses can be a plain e-mail addresses - - username@example.com - -or with a formatted name - - 'Ðоде Майлер' - -Or in case of comma separated lists, the formatting can be mixed - - username@example.com, 'Ðоде Майлер' , "Name, User" - -### SMTP envelope - -SMTP envelope is usually auto generated from `from`, `to`, `cc` and `bcc` fields but -if for some reason you want to specify it yourself, you can do it with `envelope` property. - -`envelope` is an object with the following params: `from`, `to`, `cc` and `bcc` just like -with regular mail options. You can also use the regular address format. - - mailOptions = { - ..., - from: "mailer@node.ee", - to: "daemon@node.ee", - envelope: { - from: "Daemon ", - to: "mailer@node.ee, Mailer " - } - } - -### Add attachments - -Attachments can be added with `mailcomposer.addAttachment(attachment)` where -`attachment` is an object with attachment (meta)data with the following possible -properties: - - * **fileName** (alias `filename`) - filename to be reported as the name of the attached file, use of unicode is allowed - * **cid** - content id for using inline images in HTML message source - * **contents** - String or a Buffer contents for the attachment - * **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments) - * **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*) - * **contentType** - content type for the attachment, if not set will be derived from the `fileName` property - * **contentDisposition** - content disposition type for the attachment, defaults to "attachment" - * **userAgent** - User-Agent string to be used if the fileName points to an URL - -One of `contents`, `filePath` or `streamSource` must be specified, if none is -present, the attachment will be discarded. Other fields are optional. - -Attachments can be added as many as you want. - -**Using embedded images in HTML** - -Attachments can be used as embedded images in the HTML body. To use this -feature, you need to set additional property of the attachment - `cid` -(unique identifier of the file) which is a reference to the attachment file. -The same `cid` value must be used as the image URL in HTML (using `cid:` as -the URL protocol, see example below). - -NB! the cid value should be as unique as possible! - - var cid_value = Date.now() + '.image.jpg'; - - var html = 'Embedded image: '; - - var attachment = { - fileName: "image.png", - filePath: "/static/images/image.png", - cid: cid_value - }; - -**Automatic embedding images** - -If you want to convert images in the HTML to embedded images automatically, you can -set mailcomposer option `forceEmbeddedImages` to true. In this case all images in -the HTML that are either using an absolute URL (http://...) or absolute file path -(/path/to/file) are replaced with embedded attachments. - -For example when using this code - - var mailcomposer = new MailComposer({forceEmbeddedImages: true}); - mailcomposer.setMessageOption({ - html: 'Embedded image: ' - }); - -The image linked is fetched and added automatically as an attachment and the url -in the HTML is replaced automatically with a proper `cid:` string. - -### Add alternatives to HTML and text - -In addition to text and HTML, any kind of data can be inserted as an alternative content of the main body - for example a word processing document with the same text as in the HTML field. It is the job of the e-mail client to select and show the best fitting alternative to the reader. - -Alternatives to text and HTML can be added with `mailcomposer.addAlternative(alternative)` where -`alternative` is an object with alternative (meta)data with the following possible -properties: - - * **contents** - String or a Buffer contents for the attachment - * **contentType** - optional content type for the attachment, if not set will be set to "application/octet-stream" - * **contentEncoding** - optional value of how the data is encoded, defaults to "base64" - -If `contents` is empty, the alternative will be discarded. Other fields are optional. - -**Usage example:** - - // add HTML "alternative" - mailcomposer.setMessageOption({ - html: "Hello world!" - }); - - // add Markdown alternative - mailcomposer.addAlternative({ - contentType: "text/x-web-markdown", - contents: "**Hello world!**" - }); - -If the receiving e-mail client can render messages in Markdown syntax as well, it could prefer -to display this alternative as the main content of the message. - -Alternatives can be added as many as you want. - -### DKIM Signing - -**mailcomposer** supports DKIM signing with very simple setup. Use this with caution -though since the generated message needs to be buffered entirely before it can be -signed - in this case the streaming capability offered by mailcomposer is illusionary, -there will only be one `'data'` event with the entire message. Not a big deal with -small messages but might consume a lot of RAM when using larger attachments. - -Set up the DKIM signing with `useDKIM` method: - - mailcomposer.useDKIM(dkimOptions) - -Where `dkimOptions` includes necessary options for signing - - * **domainName** - the domainname that is being used for signing - * **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.example.com* then `zzz` is the selector - * **privateKey** - DKIM private key that is used for signing as a string - * **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used - -**NB!** Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed. - -Example: - - mailcomposer.setMessageOption({from: "andris@tr.ee"}); - mailcomposer.setMessageOption({to: "andris@node.ee"}); - mailcomposer.setMessageOption({body: "Hello world!"}); - mailcomposer.useDKIM({ - domainName: "node.ee", - keySelector: "dkim", - privateKey: fs.readFileSync("private_key.pem") - }); - -### Start streaming - -When the message data is setup, streaming can be started. After this it is not -possible to add headers, attachments or change body contents. - - mailcomposer.streamMessage(); - -This generates `'data'` events for the message headers and body and final `'end'` event. -As `MailComposer` objects are Stream instances, these can be piped - - // save the output to a file - mailcomposer.streamMessage(); - mailcomposer.pipe(fs.createWriteStream("out.txt")); - -### Compile the message in one go - -If you do not want to use the streaming possibilities, you can compile the entire -message into a string in one go with `buildMessage`. - - mailcomposer.buildMessage(function(err, messageSource){ - console.log(err || messageSource); - }); - -The function is actually just a wrapper around `streamMessage` and emitted events. - -## Envelope - -Envelope can be generated with an `getEnvelope()` which returns an object -that includes a `from` address (string) and a list of `to` addresses (array of -strings) suitable for forwarding to a SMTP server as `MAIL FROM:` and `RCPT TO:`. - - console.log(mailcomposer.getEnvelope()); - // {from:"sender@example.com", to:["receiver@example.com"]} - -**NB!** both `from` and `to` properties might be missing from the envelope object -if corresponding addresses were not detected from the e-mail. - -## Running tests - -Tests are run with [nodeunit](https://github.com/caolan/nodeunit) - -Run - - npm test - -## License - -**MIT** diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js b/api/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js deleted file mode 100644 index 2c8e0b5bbc0..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js +++ /dev/null @@ -1,219 +0,0 @@ -var crypto = require("crypto"), - mimelib = require("mimelib"), - toPunycode = require("./punycode"); - -/** - * @namespace DKIM Signer module - * @name dkimsign - */ -module.exports.DKIMSign = DKIMSign; -module.exports.generateDKIMHeader = generateDKIMHeader; -module.exports.sha256 = sha256; - - -/** - *

Sign an email with provided DKIM key, uses RSA-SHA256.

- * - * @memberOf dkimsign - * @param {String} email Full e-mail source complete with headers and body to sign - * @param {Object} options DKIM options - * @param {String} [options.headerFieldNames="from:to:cc:subject"] Header fields to sign - * @param {String} options.privateKey DKMI private key - * @param {String} options.domainName Domain name to use for signing (ie: "domain.com") - * @param {String} options.keySelector Selector for the DKMI public key (ie. "dkim" if you have set up a TXT record for "dkim._domainkey.domain.com") - * - * @return {String} Signed DKIM-Signature header field for prepending - */ -function DKIMSign(email, options){ - options = options || {}; - email = (email || "").toString("utf-8"); - - var match = email.match(/^\r?\n|(?:\r?\n){2}/), - headers = match && email.substr(0, match.index) || "", - body = match && email.substr(match.index + match[0].length) || email; - - // all listed fields from RFC4871 #5.5 - // Some prociders do not like Message-Id, Date, Bounces-To and Return-Path - // fields in DKIM signed data so these are not automatcially included - var defaultFieldNames = "From:Sender:Reply-To:Subject:To:" + - "Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:" + - "Content-Description:Resent-Date:Resent-From:Resent-Sender:" + - "Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:" + - "List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:" + - "List-Owner:List-Archive"; - - var dkim = generateDKIMHeader(options.domainName, options.keySelector, options.headerFieldNames || defaultFieldNames, headers, body), - canonicalizedHeaderData = DKIMCanonicalizer.relaxedHeaders(headers, options.headerFieldNames || defaultFieldNames), - canonicalizedDKIMHeader = DKIMCanonicalizer.relaxedHeaderLine(dkim), - signer, signature; - - canonicalizedHeaderData.headers += canonicalizedDKIMHeader.key+":"+canonicalizedDKIMHeader.value; - - signer = crypto.createSign("RSA-SHA256"); - signer.update(canonicalizedHeaderData.headers); - signature = signer.sign(options.privateKey, 'base64'); - - return dkim + signature.replace(/(.{76}(?!\r?\n|\r))/g,"$&\r\n "); -} - -/** - *

Generates a DKIM-Signature header field without the signature part ("b=" is empty)

- * - * @memberOf dkimsign - * @private - * @param {String} domainName Domain name to use for signing - * @param {String} keySelector Selector for the DKMI public key - * @param {String} headerFieldNames Header fields to sign - * @param {String} headers E-mail headers - * @param {String} body E-mail body - * - * @return {String} Mime folded DKIM-Signature string - */ -function generateDKIMHeader(domainName, keySelector, headerFieldNames, headers, body){ - var canonicalizedBody = DKIMCanonicalizer.relaxedBody(body), - canonicalizedBodyHash = sha256(canonicalizedBody, "base64"), - canonicalizedHeaderData = DKIMCanonicalizer.relaxedHeaders(headers, headerFieldNames), - dkim; - - if(hasUTFChars(domainName)){ - domainName = toPunycode(domainName); - } - - dkim = [ - "v=1", - "a=rsa-sha256", - "c=relaxed/relaxed", - "d="+domainName, - "q=dns/txt", - "s="+keySelector, - "bh="+canonicalizedBodyHash, - "h="+canonicalizedHeaderData.fieldNames - ].join("; "); - - return mimelib.foldLine("DKIM-Signature: " + dkim, 76)+";\r\n b="; -} - -/** - *

DKIM canonicalization functions

- * - * @memberOf dkimsign - * @private - */ -var DKIMCanonicalizer = { - - /** - *

Simple body canonicalization by rfc4871 #3.4.3

- * - * @param {String} body E-mail body part - * @return {String} Canonicalized body - */ - simpleBody: function(body){ - return (body || "").toString().replace(/(?:\r?\n|\r)*$/, "\r\n"); - }, - - /** - *

Relaxed body canonicalization by rfc4871 #3.4.4

- * - * @param {String} body E-mail body part - * @return {String} Canonicalized body - */ - relaxedBody: function(body){ - return (body || "").toString(). - replace(/\r?\n|\r/g, "\n"). - split("\n"). - map(function(line){ - return line.replace(/\s*$/, ""). //rtrim - replace(/\s+/g, " "); // only single spaces - }). - join("\n"). - replace(/\n*$/, "\n"). - replace(/\n/g, "\r\n"); - }, - - /** - *

Relaxed headers canonicalization by rfc4871 #3.4.2 with filtering

- * - * @param {String} body E-mail headers part - * @return {String} Canonicalized headers - */ - relaxedHeaders: function(headers, fieldNames){ - var includedFields = (fieldNames || "").toLowerCase(). - split(":"). - map(function(field){ - return field.trim(); - }), - headerFields = {}, - headerLines = headers.split(/\r?\n|\r/), - line, i; - - // join lines - for(i = headerLines.length-1; i>=0; i--){ - if(i && headerLines[i].match(/^\s/)){ - headerLines[i-1] += headerLines.splice(i,1); - }else{ - line = DKIMCanonicalizer.relaxedHeaderLine(headerLines[i]); - - // on multiple values, include only the first one (the one in the bottom of the list) - if(includedFields.indexOf(line.key) >= 0 && !(line.key in headerFields)){ - headerFields[line.key] = line.value; - } - } - } - - headers = []; - for(i = includedFields.length-1; i>=0; i--){ - if(!headerFields[includedFields[i]]){ - includedFields.splice(i,1); - }else{ - headers.unshift(includedFields[i]+":"+headerFields[includedFields[i]]); - } - } - - return { - headers: headers.join("\r\n")+"\r\n", - fieldNames: includedFields.join(":") - }; - }, - - /** - *

Relaxed header canonicalization for single header line

- * - * @param {String} line Single header line - * @return {String} Canonicalized header line - */ - relaxedHeaderLine: function(line){ - var value = line.split(":"), - key = (value.shift() || "").toLowerCase().trim(); - - value = value.join(":").replace(/\s+/g, " ").trim(); - - return {key: key, value: value}; - } -}; -module.exports.DKIMCanonicalizer = DKIMCanonicalizer; - -/** - *

Generates a SHA-256 hash

- * - * @param {String} str String to be hashed - * @param {String} [encoding="hex"] Output encoding - * @return {String} SHA-256 hash in the selected output encoding - */ -function sha256(str, encoding){ - var shasum = crypto.createHash('sha256'); - shasum.update(str); - return shasum.digest(encoding || "hex"); -} - - - -/** - *

Detects if a string includes unicode symbols

- * - * @param {String} str String to be checked - * @return {String} true, if string contains non-ascii symbols - */ -function hasUTFChars(str){ - var rforeign = /[^\u0000-\u007f]/; - return !!rforeign.test(str); -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js b/api/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js deleted file mode 100644 index 44aa0f3dcd0..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js +++ /dev/null @@ -1,1393 +0,0 @@ -var Stream = require("stream").Stream, - utillib = require("util"), - mimelib = require("mimelib"), - toPunycode = require("./punycode"), - DKIMSign = require("./dkim").DKIMSign, - urlFetch = require("./urlfetch"), - fs = require("fs"), - mime = require("mime"), - crypto = require("crypto"); - -module.exports.MailComposer = MailComposer; - -/** - *

Costructs a MailComposer object. This is a Stream instance so you could - * pipe the output to a file or send it to network.

- * - *

Possible options properties are:

- * - *
    - *
  • escapeSMTP - convert dots in the beginning of line to double dots
  • - *
  • encoding - forced transport encoding (quoted-printable, base64, 7bit or 8bit)
  • - *
  • charset - forced output charset (utf-8, iso-8859-1 etc)
  • - *
  • keepBcc - include Bcc: field in the message headers (default is false)
  • - *
  • forceEmbeddedImages - convert image urls and absolute paths in HTML to embedded attachments (default is false)
  • - *
- * - *

Events

- * - *
    - *
  • 'envelope' - emits an envelope object with from and to (array) addresses.
  • - *
  • 'data' - emits a chunk of data
  • - *
  • 'end' - composing the message has ended
  • - *
- * - * @constructor - * @param {Object} [options] Optional options object - */ -function MailComposer(options){ - Stream.call(this); - - this.options = options || {}; - this.options.charset = (this.options.charset || "utf-8").toString().trim().toLowerCase(); - this.options.identityString = (this.options.identityString || "mailcomposer").toString().trim().replace(/\s/g,"-"); - - this._init(); -} -utillib.inherits(MailComposer, Stream); - -/** - *

Resets and initializes MailComposer

- */ -MailComposer.prototype._init = function(){ - /** - *

Contains all header values

- * @private - */ - this._headers = {}; - - /** - *

Contains message related values

- * @private - */ - this._message = {}; - - /** - *

Contains a list of alternatives for text and html body

- * @private - */ - this._alternatives = []; - - /** - *

Contains a list of attachments

- * @private - */ - this._attachments = []; - - /** - *

Contains a list of attachments that are related to HTML body

- * @private - */ - this._relatedAttachments = []; - - /** - *

Contains e-mail addresses for the SMTP

- * @private - */ - this._envelope = {}; - - /** - *

If set to true, caches the output for further processing (DKIM signing etc.)

- * @private - */ - this._cacheOutput = false; - - /** - *

If _cacheOutput is true, caches the output to _outputBuffer

- * @private - */ - this._outputBuffer = ""; - - /** - *

DKIM message signing options, set with useDKIM

- * @private - */ - this._dkim = false; - - /** - *

Counter for generating unique mime boundaries etc.

- * @private - */ - this._gencounter = 0; - - this.addHeader("MIME-Version", "1.0"); -}; - -/* PUBLIC API */ - -/** - *

Adds a header field to the headers object

- * - * @param {String} key Key name - * @param {String} value Header value - */ -MailComposer.prototype.addHeader = function(key, value){ - key = this._normalizeKey(key); - - if(value && Object.prototype.toString.call(value) == "[object Object]"){ - value = this._encodeMimeWord(JSON.stringify(value), "Q", 52); - }else{ - value = (value || "").toString().trim(); - } - - if(!key || !value){ - return; - } - - if(!(key in this._headers)){ - this._headers[key] = value; - }else{ - if(!Array.isArray(this._headers[key])){ - this._headers[key] = [this._headers[key], value]; - }else{ - this._headers[key].push(value); - } - } -}; - -/** - *

Resets and initializes MailComposer

- * - *

Setting an option overwrites an earlier setup for the same keys

- * - *

Possible options:

- * - *
    - *
  • from - The e-mail address of the sender. All e-mail addresses can be plain sender@server.com or formatted Sender Name <sender@server.com>
  • - *
  • to - Comma separated list of recipients e-mail addresses that will appear on the To: field
  • - *
  • cc - Comma separated list of recipients e-mail addresses that will appear on the Cc: field
  • - *
  • bcc - Comma separated list of recipients e-mail addresses that will appear on the Bcc: field
  • - *
  • replyTo - An e-mail address that will appear on the Reply-To: field
  • - *
  • subject - The subject of the e-mail
  • - *
  • body - The plaintext version of the message
  • - *
  • html - The HTML version of the message
  • - *
- * - * @param {Object} options Message related options - */ -MailComposer.prototype.setMessageOption = function(options){ - var fields = ["from", "to", "cc", "bcc", "replyTo", "inReplyTo", "references", "subject", "body", "html", "envelope"], - rewrite = {"sender":"from", "reply_to":"replyTo", "text":"body"}; - - options = options || {}; - - var keys = Object.keys(options), key, value; - for(var i=0, len=keys.length; i= 0){ - this._message[key] = this._handleValue(key, value); - } - } -}; - -/** - *

Setup DKIM for signing generated message. Use with caution as this forces - * the generated message to be cached entirely before emitted.

- * - * @param {Object} dkim DKIM signing settings - * @param {String} [dkim.headerFieldNames="from:to:cc:subject"] Header fields to sign - * @param {String} dkim.privateKey DKMI private key - * @param {String} dkim.domainName Domain name to use for signing (ie: "domain.com") - * @param {String} dkim.keySelector Selector for the DKMI public key (ie. "dkim" if you have set up a TXT record for "dkim._domainkey.domain.com" - */ -MailComposer.prototype.useDKIM = function(dkim){ - this._dkim = dkim || {}; - this._cacheOutput = true; -}; - - -/** - *

Adds an alternative to the list

- * - *

Following options are allowed:

- * - *
    - *
  • fileName - filename for the alternative
  • - *
  • contentType - content type for the attachmetn (default will be derived from the filename)
  • - *
  • cid - Content ID value for inline images
  • - *
  • contents - String or Buffer alternative contents
  • - *
  • filePath - Path to a file for streaming
  • - *
  • streamSource - Stream object for arbitrary streams
  • - *
- * - *

One of contents or filePath or stream - * must be specified, otherwise the alternative is not included

- * - * @param {Object} alternative Alternative info - */ -MailComposer.prototype.addAlternative = function(alternative){ - alternative = alternative || {}; - - if(!alternative.contentType){ - alternative.contentType = "application/octet-stream"; - } - - if(!alternative.contentEncoding){ - alternative.contentEncoding = "base64"; - } - - if(alternative.contents){ - this._alternatives.push(alternative); - } -}; - - -/** - *

Adds an attachment to the list

- * - *

Following options are allowed:

- * - *
    - *
  • fileName - filename for the attachment
  • - *
  • contentType - content type for the attachmetn (default will be derived from the filename)
  • - *
  • cid - Content ID value for inline images
  • - *
  • contents - String or Buffer attachment contents
  • - *
  • filePath - Path to a file for streaming
  • - *
  • streamSource - Stream object for arbitrary streams
  • - *
- * - *

One of contents or filePath or stream - * must be specified, otherwise the attachment is not included

- * - * @param {Object} attachment Attachment info - */ -MailComposer.prototype.addAttachment = function(attachment){ - attachment = attachment || {}; - - // Needed for Nodemailer compatibility - if(attachment.filename){ - attachment.fileName = attachment.filename; - delete attachment.filename; - } - - if(!attachment.fileName && attachment.filePath){ - attachment.fileName = attachment.filePath.split(/[\/\\]/).pop(); - } - - if(!attachment.contentType){ - attachment.contentType = mime.lookup(attachment.fileName || attachment.filePath || ""); - } - - if(attachment.streamSource){ - // check for pause and resume support - if(typeof attachment.streamSource.pause != "function" || - typeof attachment.streamSource.resume != "function"){ - // Unsupported Stream source, skip it - return; - } - attachment.streamSource.pause(); - } - - if(attachment.filePath || attachment.contents || attachment.streamSource){ - this._attachments.push(attachment); - } -}; - -/** - *

Composes and returns an envelope from the this._envelope - * object. Needed for the SMTP client

- * - *

Generated envelope is int hte following structure:

- * - *
- * {
- *     to: "address",
- *     from: ["list", "of", "addresses"]
- * }
- * 
- * - *

Both properties (from and to) are optional - * and may not exist

- * - * @return {Object} envelope object with "from" and "to" params - */ -MailComposer.prototype.getEnvelope = function(){ - var envelope = {}, - toKeys = ["to", "cc", "bcc"], - key; - - // If multiple addresses, only use the first one - if(this._envelope.from && this._envelope.from.length){ - envelope.from = [].concat(this._envelope.from).shift(); - } - - for(var i=0, len=toKeys.length; iStarts streaming the message

- */ -MailComposer.prototype.streamMessage = function(){ - process.nextTick(this._composeMessage.bind(this)); -}; - -/** - *

Builds the entire message and returns it as a string

- * - * @param {Function} callback Callback function to run - */ -MailComposer.prototype.buildMessage = function(callback){ - var body = "", - done = false; - - this.on("data", function(chunk){ - body += (chunk || "").toString(); - }); - - this.on("error", function(error){ - if(done){ - return; - } - done = true; - callback(error); - }); - - this.on("end", function(){ - if(done){ - return; - } - done = true; - callback(null, body); - }); - - this.streamMessage(); -}; - -/* PRIVATE API */ - -/** - *

Handles a message object value, converts addresses etc.

- * - * @param {String} key Message options key - * @param {String} value Message options value - * @return {String} converted value - */ -MailComposer.prototype._handleValue = function(key, value){ - key = (key || "").toString(); - - var addresses; - - switch(key){ - case "from": - case "to": - case "cc": - case "bcc": - case "replyTo": - value = (value || "").toString().replace(/\r?\n|\r/g, " "); - addresses = [].concat.apply([], [].concat(value).map(mimelib.parseAddresses.bind(mimelib))); - if(!this._envelope.userDefined){ - this._envelope[key] = addresses.map((function(address){ - if(this._hasUTFChars(address.address)){ - return toPunycode(address.address); - }else{ - return address.address; - } - }).bind(this)); - } - return this._convertAddresses(addresses); - - case "inReplyTo": - value = (value || "").toString().replace(/\s/g, ""); - if(value.charAt(0)!="<"){ - value = "<"+value; - } - if(value.charAt(value.length-1)!=">"){ - value = value + ">"; - } - return value; - - case "references": - value = [].concat.apply([], [].concat(value || "").map(function(elm){ - elm = (elm || "").toString().trim(); - return elm.replace(/<[^>]*>/g,function(str){ - return str.replace(/\s/g, ""); - }).split(/\s+/); - })).map(function(elm){ - elm = (elm || "").toString().trim(); - if(elm.charAt(0) != "<"){ - elm = "<" + elm; - } - if(elm.charAt(elm.length-1) != ">"){ - elm = elm + ">"; - } - return elm; - }); - - return value.join(" ").trim(); - - case "subject": - value = (value || "").toString().replace(/\r?\n|\r/g, " "); - return this._encodeMimeWord(value, "Q", 52); - - case "envelope": - - this._envelope = { - userDefined: true - }; - - Object.keys(value).forEach((function(key){ - - this._envelope[key] = []; - - [].concat(value[key]).forEach((function(address){ - var addresses = mimelib.parseAddresses(address); - - this._envelope[key] = this._envelope[key].concat(addresses.map((function(address){ - if(this._hasUTFChars(address.address)){ - return toPunycode(address.address); - }else{ - return address.address; - } - }).bind(this))); - - }).bind(this)); - }).bind(this)); - break; - } - - return value; -}; - -/** - *

Handles a list of parsed e-mail addresses, checks encoding etc.

- * - * @param {Array} value A list or single e-mail address {address:'...', name:'...'} - * @return {String} Comma separated and encoded list of addresses - */ -MailComposer.prototype._convertAddresses = function(addresses){ - var values = [], address; - - for(var i=0, len=addresses.length; i'); - } - } - } - return values.join(", "); -}; - -/** - *

Gets a header field

- * - * @param {String} key Key name - * @return {String|Array} Header field - if several values, then it's an array - */ -MailComposer.prototype._getHeader = function(key){ - var value; - - key = this._normalizeKey(key); - value = this._headers[key] || ""; - - return value; -}; - -/** - *

Generate an e-mail from the described info

- */ -MailComposer.prototype._composeMessage = function(){ - - // Preprocess functions - if(this.options.forceEmbeddedImages){ - this._convertImagesToInline(); - } - - // Generate headers for the message - this._composeHeader(); - - // Make the mime tree flat - this._flattenMimeTree(); - - // Compose message body - this._composeBody(); - -}; - -/** - *

Composes a header for the message and emits it with a 'data' - * event

- * - *

Also checks and build a structure for the message (is it a multipart message - * and does it need a boundary etc.)

- * - *

By default the message is not a multipart. If the message containes both - * plaintext and html contents, an alternative block is used. it it containes - * attachments, a mixed block is used. If both alternative and mixed exist, then - * alternative resides inside mixed.

- */ -MailComposer.prototype._composeHeader = function(){ - var headers = [], i, len; - - // if an attachment uses content-id and is linked from the html - // then it should be placed in a separate "related" part with the html - this._message.useRelated = false; - if(this._message.html && (len = this._attachments.length)){ - - for(i=len-1; i>=0; i--){ - if(this._attachments[i].cid && - this._message.html.indexOf("cid:"+this._attachments[i].cid)>=0){ - this._message.useRelated = true; - this._relatedAttachments.unshift(this._attachments[i]); - this._attachments.splice(i,1); - } - } - - } - - if(this._attachments.length){ - this._message.useMixed = true; - this._message.mixedBoundary = this._generateBoundary(); - }else{ - this._message.useMixed = false; - } - - if([].concat(this._message.body || []).concat(this._message.html || []). - concat(this._alternatives || []).length > 1){ - this._message.useAlternative = true; - this._message.alternativeBoundary = this._generateBoundary(); - }else{ - this._message.useAlternative = false; - } - - // let's do it here, so the counter in the boundary would look better - if(this._message.useRelated){ - this._message.relatedBoundary = this._generateBoundary(); - } - - if(!this._message.html && !this._message.body){ - // If there's nothing to show, show a linebreak - this._message.body = "\r\n"; - } - - this._buildMessageHeaders(); - this._generateBodyStructure(); - - // Compile header lines - headers = this.compileHeaders(this._headers); - - if(!this._cacheOutput){ - this.emit("data", new Buffer(headers.join("\r\n")+"\r\n\r\n", "utf-8")); - }else{ - this._outputBuffer += headers.join("\r\n")+"\r\n\r\n"; - } -}; - -/** - *

Uses data from the this._message object to build headers

- */ -MailComposer.prototype._buildMessageHeaders = function(){ - - // FROM - if(this._message.from && this._message.from.length){ - [].concat(this._message.from).forEach((function(from){ - this.addHeader("From", from); - }).bind(this)); - } - - // TO - if(this._message.to && this._message.to.length){ - [].concat(this._message.to).forEach((function(to){ - this.addHeader("To", to); - }).bind(this)); - } - - // CC - if(this._message.cc && this._message.cc.length){ - [].concat(this._message.cc).forEach((function(cc){ - this.addHeader("Cc", cc); - }).bind(this)); - } - - // BCC - // By default not included, set options.keepBcc to true to keep - if(this.options.keepBcc){ - if(this._message.bcc && this._message.bcc.length){ - [].concat(this._message.bcc).forEach((function(bcc){ - this.addHeader("Bcc", bcc); - }).bind(this)); - } - } - - // REPLY-TO - if(this._message.replyTo && this._message.replyTo.length){ - [].concat(this._message.replyTo).forEach((function(replyTo){ - this.addHeader("Reply-To", replyTo); - }).bind(this)); - } - - // REFERENCES - if(this._message.references && this._message.references.length){ - this.addHeader("References", this._message.references); - } - - // IN-REPLY-TO - if(this._message.inReplyTo && this._message.inReplyTo.length){ - this.addHeader("In-Reply-To", this._message.inReplyTo); - } - - // SUBJECT - if(this._message.subject){ - this.addHeader("Subject", this._message.subject); - } -}; - -/** - *

Generates the structure (mime tree) of the body. This sets up multipart - * structure, individual part headers, boundaries etc.

- * - *

The headers of the root element will be appended to the message - * headers

- */ -MailComposer.prototype._generateBodyStructure = function(){ - - var tree = this._createMimeNode(), - currentNode, node, - i, len; - - if(this._message.useMixed){ - - node = this._createMimeNode(); - node.boundary = this._message.mixedBoundary; - node.headers.push(["Content-Type", "multipart/mixed; boundary=\""+node.boundary+"\""]); - - if(currentNode){ - currentNode.childNodes.push(node); - node.parentNode = currentNode; - }else{ - tree = node; - } - currentNode = node; - - } - - if(this._message.useAlternative){ - - node = this._createMimeNode(); - node.boundary = this._message.alternativeBoundary; - node.headers.push(["Content-Type", "multipart/alternative; boundary=\""+node.boundary+"\""]); - if(currentNode){ - currentNode.childNodes.push(node); - node.parentNode = currentNode; - }else{ - tree = node; - } - currentNode = node; - - } - - if(this._message.body){ - node = this._createTextComponent(this._message.body, "text/plain"); - if(currentNode){ - currentNode.childNodes.push(node); - node.parentNode = currentNode; - }else{ - tree = node; - } - } - - if(this._message.useRelated){ - - node = this._createMimeNode(); - node.boundary = this._message.relatedBoundary; - node.headers.push(["Content-Type", "multipart/related; boundary=\""+node.boundary+"\""]); - if(currentNode){ - currentNode.childNodes.push(node); - node.parentNode = currentNode; - }else{ - tree = node; - } - currentNode = node; - - } - - if(this._message.html){ - node = this._createTextComponent(this._message.html, "text/html"); - if(currentNode){ - currentNode.childNodes.push(node); - node.parentNode = currentNode; - }else{ - tree = node; - } - } - - // Alternatives - if(this._alternatives && this._alternatives.length){ - for(i=0, len = this._alternatives.length; iCreates a mime tree node for a text component (plaintext, HTML)

- * - * @param {String} text Text contents for the component - * @param {String} [contentType="text/plain"] Content type for the text component - * @return {Object} Mime tree node - */ -MailComposer.prototype._createTextComponent = function(text, contentType){ - var node = this._createMimeNode(); - - node.contentEncoding = (this.options.encoding || "quoted-printable").toLowerCase().trim(); - node.useTextType = true; - - contentType = [contentType || "text/plain"]; - contentType.push("charset=" + this.options.charset); - - if(["7bit", "8bit", "binary"].indexOf(node.contentEncoding)>=0){ - node.textFormat = "flowed"; - contentType.push("format=" + node.textFormat); - } - - node.headers.push(["Content-Type", contentType.join("; ")]); - node.headers.push(["Content-Transfer-Encoding", node.contentEncoding]); - - node.contents = text; - - return node; -}; - -/** - *

Creates a mime tree node for an attachment component

- * - * @param {Object} attachment Attachment info for the component - * @return {Object} Mime tree node - */ -MailComposer.prototype._createAttachmentComponent = function(attachment){ - var node = this._createMimeNode(), - contentType = [attachment.contentType], - contentDisposition = [attachment.contentDisposition || "attachment"], - fileName; - - node.contentEncoding = "base64"; - - if(attachment.fileName){ - fileName = this._encodeMimeWord(attachment.fileName, "Q", 1024).replace(/"/g,"\\\""); - contentType.push("name=\"" +fileName+ "\""); - contentDisposition.push("filename=\"" +fileName+ "\""); - } - - node.headers.push(["Content-Type", contentType.join("; ")]); - node.headers.push(["Content-Disposition", contentDisposition.join("; ")]); - node.headers.push(["Content-Transfer-Encoding", node.contentEncoding]); - - if(attachment.cid){ - node.headers.push(["Content-Id", "<" + this._encodeMimeWord(attachment.cid) + ">"]); - } - - if(attachment.contents){ - node.contents = attachment.contents; - }else if(attachment.filePath){ - node.filePath = attachment.filePath; - if(attachment.userAgent){ - node.userAgent = attachment.userAgent; - } - }else if(attachment.streamSource){ - node.streamSource = attachment.streamSource; - } - - return node; -}; - -/** - *

Creates a mime tree node for an alternative text component (ODF/DOC/etc)

- * - * @param {Object} alternative Alternative info for the component - * @return {Object} Mime tree node - */ -MailComposer.prototype._createAlternativeComponent = function(alternative){ - var node = this._createMimeNode(), - contentType = alternative.contentType.split(";").map(function(part){ - return (part || "").trim() - }), - fileName; - - node.contentEncoding = alternative.contentEncoding || "base64"; - - if(["7bit", "8bit", "binary"].indexOf(node.contentEncoding)>=0){ - node.textFormat = "flowed"; - contentType.push("format=" + node.textFormat); - } - - node.headers.push(["Content-Type", contentType.join("; ")]); - node.headers.push(["Content-Transfer-Encoding", node.contentEncoding]); - - node.contents = alternative.contents; - - return node; -}; - -/** - *

Creates an empty mime tree node

- * - * @return {Object} Mime tree node - */ -MailComposer.prototype._createMimeNode = function(){ - return { - childNodes: [], - headers: [], - parentNode: null - }; -}; - -/** - *

Compiles headers object into an array of header lines. If needed, the - * lines are folded

- * - * @param {Object|Array} headers An object with headers in the form of - * {key:value} or [[key, value]] or - * [{key:key, value: value}] - * @return {Array} A list of header lines. Can be joined with \r\n - */ -MailComposer.prototype.compileHeaders = function(headers){ - var headersArr = [], keys, key; - - if(Array.isArray(headers)){ - headersArr = headers.map((function(field){ - var key = this._normalizeKey(field.key || field[0]), - value = this._sanitizeHeaderValue(field.value || field[1], key); - return mimelib.foldLine(key+": "+value, 76, false, false, 52); - }).bind(this)); - }else{ - keys = Object.keys(headers); - for(var i=0, len = keys.length; iConverts a structured mimetree into an one dimensional array of - * components. This includes headers and multipart boundaries as strings, - * textual and attachment contents are.

- */ -MailComposer.prototype._flattenMimeTree = function(){ - var flatTree = []; - - function walkTree(node, level){ - var contentObject = {}; - level = level || 0; - - // if not root element, include headers - if(level){ - flatTree = flatTree.concat(this.compileHeaders(node.headers)); - flatTree.push(''); - } - - if(node.textFormat){ - contentObject.textFormat = node.textFormat; - } - - if(node.contentEncoding){ - contentObject.contentEncoding = node.contentEncoding; - } - - if(node.contents){ - contentObject.contents = node.contents; - }else if(node.filePath){ - contentObject.filePath = node.filePath; - if(node.userAgent){ - contentObject.userAgent = node.userAgent; - } - }else if(node.streamSource){ - contentObject.streamSource = node.streamSource; - } - - if(node.contents || node.filePath || node.streamSource){ - flatTree.push(contentObject); - } - - // walk children - for(var i=0, len = node.childNodes.length; iComposes the e-mail body based on the previously generated mime tree

- * - *

Assumes that the linebreak separating headers and contents is already - * sent

- * - *

Emits 'data' events

- */ -MailComposer.prototype._composeBody = function(){ - var flatTree = this._message.flatTree, - slice, isObject = false, isEnd = false, - curObject; - - this._message.processingStart = this._message.processingStart || 0; - this._message.processingPos = this._message.processingPos || 0; - - for(var len = flatTree.length; this._message.processingPos < len; this._message.processingPos++){ - - isEnd = this._message.processingPos >= len-1; - isObject = typeof flatTree[this._message.processingPos] == "object"; - - if(isEnd || isObject){ - - slice = flatTree.slice(this._message.processingStart, isEnd && !isObject?undefined:this._message.processingPos); - if(slice && slice.length){ - if(!this._cacheOutput){ - this.emit("data", new Buffer(slice.join("\r\n")+"\r\n", "utf-8")); - }else{ - this._outputBuffer += slice.join("\r\n")+"\r\n"; - } - } - - if(isObject){ - curObject = flatTree[this._message.processingPos]; - - this._message.processingPos++; - this._message.processingStart = this._message.processingPos; - - this._emitDataElement(curObject, (function(){ - if(!isEnd){ - process.nextTick(this._composeBody.bind(this)); - }else{ - if(!this._cacheOutput){ - this.emit("end"); - }else{ - this._processBufferedOutput(); - } - } - }).bind(this)); - - }else if(isEnd){ - if(!this._cacheOutput){ - this.emit("end"); - }else{ - this._processBufferedOutput(); - } - } - break; - } - - } -}; - -/** - *

Emits a data event for a text or html body and attachments. If it is a - * file, stream it

- * - *

If this.options.escapeSMTP is true, replace dots in the - * beginning of a line with double dots - only valid for QP encoding

- * - * @param {Object} element Data element descriptor - * @param {Function} callback Callback function to run when completed - */ -MailComposer.prototype._emitDataElement = function(element, callback){ - - var data = ""; - - if(element.contents){ - switch(element.contentEncoding){ - case "quoted-printable": - data = mimelib.encodeQuotedPrintable(element.contents, false, this.options.charset); - break; - case "base64": - data = new Buffer(element.contents, "utf-8").toString("base64").replace(/.{76}/g,"$&\r\n"); - break; - case "7bit": - case "8bit": - case "binary": - default: - data = mimelib.foldLine(element.contents, 76, false, element.textFormat=="flowed"); - //mimelib puts a long whitespace to the beginning of the lines - data = data.replace(/^[ ]{7}/mg, ""); - break; - } - - if(this.options.escapeSMTP){ - data = data.replace(/^\./gm,'..'); - } - - if(!this._cacheOutput){ - this.emit("data", new Buffer(data + "\r\n", "utf-8")); - }else{ - this._outputBuffer += data + "\r\n"; - } - process.nextTick(callback); - return; - } - - if(element.filePath){ - if(element.filePath.match(/^https?:\/\//)){ - this._serveStream(urlFetch(element.filePath, {userAgent: element.userAgent}), callback); - }else{ - this._serveFile(element.filePath, callback); - } - return; - }else if(element.streamSource){ - this._serveStream(element.streamSource, callback); - return; - } - - callback(); -}; - -/** - *

Pipes a file to the e-mail stream

- * - * @param {String} filePath Path to the file - * @param {Function} callback Callback function to run after completion - */ -MailComposer.prototype._serveFile = function(filePath, callback){ - fs.stat(filePath, (function(err, stat){ - if(err || !stat.isFile()){ - - - if(!this._cacheOutput){ - this.emit("data", new Buffer(new Buffer("", - "utf-8").toString("base64")+"\r\n", "utf-8")); - }else{ - this._outputBuffer += new Buffer("", - "utf-8").toString("base64")+"\r\n"; - } - - process.nextTick(callback); - return; - } - - var stream = fs.createReadStream(filePath); - - this._serveStream(stream, callback); - - }).bind(this)); -}; - -/** - *

Pipes a stream source to the e-mail stream

- * - *

This function resumes the stream and starts sending 76 bytes long base64 - * encoded lines. To achieve this, the incoming stream is divded into - * chunks of 57 bytes (57/3*4=76) to achieve exactly 76 byte long - * base64

- * - * @param {Object} stream Stream to be piped - * @param {Function} callback Callback function to run after completion - */ -MailComposer.prototype._serveStream = function(stream, callback){ - var remainder = new Buffer(0); - - stream.on("error", (function(error){ - if(!this._cacheOutput){ - this.emit("data", new Buffer(new Buffer("", - "utf-8").toString("base64")+"\r\n", "utf-8")); - }else{ - this._outputBuffer += new Buffer("", - "utf-8").toString("base64")+"\r\n"; - } - process.nextTick(callback); - }).bind(this)); - - stream.on("data", (function(chunk){ - var data = "", - len = remainder.length + chunk.length, - remainderLength = len % 57, // we use 57 bytes as it composes - // a 76 bytes long base64 string - buffer = new Buffer(len); - - remainder.copy(buffer); // copy remainder into the beginning of the new buffer - chunk.copy(buffer, remainder.length); // copy data chunk after the remainder - remainder = buffer.slice(len - remainderLength); // create a new remainder - - data = buffer.slice(0, len - remainderLength).toString("base64").replace(/.{76}/g,"$&\r\n"); - - if(data.length){ - if(!this._cacheOutput){ - this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8")); - }else{ - this._outputBuffer += data.trim()+"\r\n"; - } - } - }).bind(this)); - - stream.on("end", (function(chunk){ - var data; - - // stream the remainder (if any) - if(remainder.length){ - data = remainder.toString("base64").replace(/.{76}/g,"$&\r\n"); - if(!this._cacheOutput){ - this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8")); - }else{ - this._outputBuffer += data.trim()+"\r\n"; - } - } - process.nextTick(callback); - }).bind(this)); - - // resume streaming if paused - stream.resume(); -}; - -/** - *

Processes buffered output and emits 'end'

- */ -MailComposer.prototype._processBufferedOutput = function(){ - var dkimSignature; - - if(this._dkim){ - if((dkimSignature = DKIMSign(this.options.escapeSMTP ? this._outputBuffer.replace(/^\.\./mg, ".") : this._outputBuffer, this._dkim))){ - this.emit("data", new Buffer(dkimSignature+"\r\n", "utf-8")); - } - } - - this.emit("data", new Buffer(this._outputBuffer, "utf-8")); - - process.nextTick(this.emit.bind(this,"end")); -}; - -/* HELPER FUNCTIONS */ - -/** - *

Normalizes a key name by cpitalizing first chars of words, except for - * custom keys (starting with "X-") that have only uppercase letters, which will - * not be modified.

- * - *

x-mailer will become X-Mailer

- * - *

Needed to avoid duplicate header keys

- * - * @param {String} key Key name - * @return {String} First chars uppercased - */ -MailComposer.prototype._normalizeKey = function(key){ - key = (key || "").toString().trim(); - - // If only uppercase letters, leave everything as is - if(key.match(/^X\-[A-Z0-9\-]+$/)){ - return key; - } - - // Convert first letter upper case, others lower case - return key. - toLowerCase(). - replace(/^\S|[\-\s]\S/g, function(c){ - return c.toUpperCase(); - }). - replace(/^MIME\-/i, "MIME-"). - replace(/^DKIM\-/i, "DKIM-"); -}; - -/** - *

Tests if a string has high bit (UTF-8) symbols

- * - * @param {String} str String to be tested for high bit symbols - * @return {Boolean} true if high bit symbols were found - */ -MailComposer.prototype._hasUTFChars = function(str){ - var rforeign = /[^\u0000-\u007f]/; - return !!rforeign.test(str); -}; - -/** - *

Generates a boundary for multipart bodies

- * - * @return {String} Boundary String - */ -MailComposer.prototype._generateBoundary = function(){ - // "_" is not allowed in quoted-printable and "?" not in base64 - return "----" + this.options.identityString + "-?=_"+(++this._gencounter)+"-"+Date.now(); -}; - -/** - *

Converts a string to mime word format. If the length is longer than - * maxlen, split it

- * - *

If the string doesn't have any unicode characters return the original - * string instead

- * - * @param {String} str String to be encoded - * @param {String} encoding Either Q for Quoted-Printable or B for Base64 - * @param {Number} [maxlen] Optional length of the resulting string, whitespace will be inserted if needed - * - * @return {String} Mime-word encoded string (if needed) - */ -MailComposer.prototype._encodeMimeWord = function(str, encoding, maxlen){ - return mimelib.encodeMimeWords(str, encoding, maxlen, this.options.charset); -}; - -/** - *

Splits a mime-encoded string

- * - * @param {String} str Input string - * @param {Number} maxlen Maximum line length - * @return {Array} split string - */ -MailComposer.prototype._splitEncodedString = function(str, maxlen){ - var curLine, match, chr, done, - lines = []; - - while(str.length){ - curLine = str.substr(0, maxlen); - - // move incomplete escaped char back to main - if((match = curLine.match(/\=[0-9A-F]?$/i))){ - curLine = curLine.substr(0, match.index); - } - - done = false; - while(!done){ - done = true; - // check if not middle of a unicode char sequence - if((match = str.substr(curLine.length).match(/^\=([0-9A-F]{2})/i))){ - chr = parseInt(match[1], 16); - // invalid sequence, move one char back anc recheck - if(chr < 0xC2 && chr > 0x7F){ - curLine = curLine.substr(0, curLine.length-3); - done = false; - } - } - } - - if(curLine.length){ - lines.push(curLine); - } - str = str.substr(curLine.length); - } - - return lines; -}; - -/** - * Detects image urls and paths from HTML code and replaces with attachments - * for embedding images inline - */ -MailComposer.prototype._convertImagesToInline = function(){ - if(!this._message.html){ - return; - } - - this._message.html = this._message.html.replace(/]*>/gi, (function(imgTag){ - return imgTag.replace(/\b(src\s*=\s*(?:['"]?))([^'"> ]+)/i, (function(src, prefix, url){ - var cid; - url = (url || "").trim(); - prefix = prefix || ""; - - if(url.match(/^https?:\/\//i) || url.match(/^\//i)){ - cid = crypto.randomBytes(20).toString("hex") + "@" + this.options.identityString; - this.addAttachment({ - filePath: url, - cid: cid - }); - url = "cid:"+cid; - } - - return prefix + url; - }).bind(this)); - }).bind(this)); -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js b/api/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js deleted file mode 100644 index ab14f4b2287..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js +++ /dev/null @@ -1,329 +0,0 @@ -//Javascript Punycode converter derived from example in RFC3492. -//This implementation is created by some@domain.name and released into public domain -var punycode = new function Punycode() { - // This object converts to and from puny-code used in IDN - // - // punycode.ToASCII ( domain ) - // - // Returns a puny coded representation of "domain". - // It only converts the part of the domain name that - // has non ASCII characters. I.e. it dosent matter if - // you call it with a domain that already is in ASCII. - // - // punycode.ToUnicode (domain) - // - // Converts a puny-coded domain name to unicode. - // It only converts the puny-coded parts of the domain name. - // I.e. it dosent matter if you call it on a string - // that already has been converted to unicode. - // - // - this.utf16 = { - // The utf16-class is necessary to convert from javascripts internal character representation to unicode and back. - decode:function(input){ - var output = [], i=0, len=input.length,value,extra; - while (i < len) { - value = input.charCodeAt(i++); - if ((value & 0xF800) === 0xD800) { - extra = input.charCodeAt(i++); - if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) { - throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence"); - } - value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; - } - output.push(value); - } - return output; - }, - encode:function(input){ - var output = [], i=0, len=input.length,value; - while (i < len) { - value = input[i++]; - if ( (value & 0xF800) === 0xD800 ) { - throw new RangeError("UTF-16(encode): Illegal UTF-16 value"); - } - if (value > 0xFFFF) { - value -= 0x10000; - output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800)); - value = 0xDC00 | (value & 0x3FF); - } - output.push(String.fromCharCode(value)); - } - return output.join(""); - } - }; - - //Default parameters - var initial_n = 0x80; - var initial_bias = 72; - var delimiter = "-"; - var base = 36; - var damp = 700; - var tmin=1; - var tmax=26; - var skew=38; - var maxint = 0x7FFFFFFF; - - // decode_digit(cp) returns the numeric value of a basic code - // point (for use in representing integers) in the range 0 to - // base-1, or base if cp is does not represent a value. - - function decode_digit(cp) { - return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base; - } - - // encode_digit(d,flag) returns the basic code point whose value - // (when used for representing integers) is d, which needs to be in - // the range 0 to base-1. The lowercase form is used unless flag is - // nonzero, in which case the uppercase form is used. The behavior - // is undefined if flag is nonzero and digit d has no uppercase form. - - function encode_digit(d, flag) { - return d + 22 + 75 * (d < 26) - ((flag !== 0) << 5); - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - } - //** Bias adaptation function ** - function adapt(delta, numpoints, firsttime ) { - var k; - delta = firsttime ? Math.floor(delta / damp) : (delta >> 1); - delta += Math.floor(delta / numpoints); - - for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) { - delta = Math.floor(delta / ( base - tmin )); - } - return Math.floor(k + (base - tmin + 1) * delta / (delta + skew)); - } - - // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero, - // uppercase if flag is nonzero, and returns the resulting code point. - // The code point is unchanged if it is caseless. - // The behavior is undefined if bcp is not a basic code point. - - function encode_basic(bcp, flag) { - bcp -= (bcp - 97 < 26) << 5; - return bcp + ((!flag && (bcp - 65 < 26)) << 5); - } - - // Main decode - this.decode=function(input,preserveCase) { - // Dont use utf16 - var output=[]; - var case_flags=[]; - var input_length = input.length; - - var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len; - - // Initialize the state: - - n = initial_n; - i = 0; - bias = initial_bias; - - // Handle the basic code points: Let basic be the number of input code - // points before the last delimiter, or 0 if there is none, then - // copy the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) basic = 0; - - for (j = 0; j < basic; ++j) { - if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26); - if ( input.charCodeAt(j) >= 0x80) { - throw new RangeError("Illegal input >= 0x80"); - } - output.push( input.charCodeAt(j) ); - } - - // Main decoding loop: Start just after the last delimiter if any - // basic code points were copied; start at the beginning otherwise. - - for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) { - - // ic is the index of the next character to be consumed, - - // Decode a generalized variable-length integer into delta, - // which gets added to i. The overflow checking is easier - // if we increase i as we go, then subtract off its starting - // value at the end to obtain delta. - for (oldi = i, w = 1, k = base; ; k += base) { - if (ic >= input_length) { - throw RangeError ("punycode_bad_input(1)"); - } - digit = decode_digit(input.charCodeAt(ic++)); - - if (digit >= base) { - throw RangeError("punycode_bad_input(2)"); - } - if (digit > Math.floor((maxint - i) / w)) { - throw RangeError ("punycode_overflow(1)"); - } - i += digit * w; - t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; - if (digit < t) { break; } - if (w > Math.floor(maxint / (base - t))) { - throw RangeError("punycode_overflow(2)"); - } - w *= (base - t); - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi === 0); - - // i was supposed to wrap around from out to 0, - // incrementing n each time, so we'll fix that now: - if ( Math.floor(i / out) > maxint - n) { - throw RangeError("punycode_overflow(3)"); - } - n += Math.floor( i / out ) ; - i %= out; - - // Insert n at position i of the output: - // Case of last character determines uppercase flag: - if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);} - - output.splice(i, 0, n); - i++; - } - if (preserveCase) { - for (i = 0, len = output.length; i < len; i++) { - if (case_flags[i]) { - output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0); - } - } - } - return this.utf16.encode(output); - }; - - //** Main encode function ** - - this.encode = function (input,preserveCase) { - //** Bias adaptation function ** - - var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags; - - if (preserveCase) { - // Preserve case, step1 of 2: Get a list of the unaltered string - case_flags = this.utf16.decode(input); - } - // Converts the input in UTF-16 to Unicode - input = this.utf16.decode(input.toLowerCase()); - - var input_length = input.length; // Cache the length - - if (preserveCase) { - // Preserve case, step2 of 2: Modify the list to true/false - for (j=0; j < input_length; j++) { - case_flags[j] = input[j] != case_flags[j]; - } - } - - var output=[]; - - - // Initialize the state: - n = initial_n; - delta = 0; - bias = initial_bias; - - // Handle the basic code points: - for (j = 0; j < input_length; ++j) { - if ( input[j] < 0x80) { - output.push( - String.fromCharCode( - case_flags ? encode_basic(input[j], case_flags[j]) : input[j] - ) - ); - } - } - - h = b = output.length; - - // h is the number of code points that have been handled, b is the - // number of basic code points - - if (b > 0) output.push(delimiter); - - // Main encoding loop: - // - while (h < input_length) { - // All non-basic code points < n have been - // handled already. Find the next larger one: - - for (m = maxint, j = 0; j < input_length; ++j) { - ijv = input[j]; - if (ijv >= n && ijv < m) m = ijv; - } - - // Increase delta enough to advance the decoder's - // state to , but guard against overflow: - - if (m - n > Math.floor((maxint - delta) / (h + 1))) { - throw RangeError("punycode_overflow (1)"); - } - delta += (m - n) * (h + 1); - n = m; - - for (j = 0; j < input_length; ++j) { - ijv = input[j]; - - if (ijv < n ) { - if (++delta > maxint) return Error("punycode_overflow(2)"); - } - - if (ijv == n) { - // Represent delta as a generalized variable-length integer: - for (q = delta, k = base; ; k += base) { - t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; - if (q < t) break; - output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) ); - q = Math.floor( (q - t) / (base - t) ); - } - output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 ))); - bias = adapt(delta, h + 1, h == b); - delta = 0; - ++h; - } - } - - ++delta; - ++n; - } - return output.join(""); - }; - - this.ToASCII = function ( domain ) { - var domain_array = domain.split("."); - var out = []; - for (var i=0; i < domain_array.length; ++i) { - var s = domain_array[i]; - out.push( - s.match(/[^A-Za-z0-9\-]/) ? - "xn--" + punycode.encode(s) : - s - ); - } - return out.join("."); - }; - - this.ToUnicode = function ( domain ) { - var domain_array = domain.split("."); - var out = []; - for (var i=0; i < domain_array.length; ++i) { - var s = domain_array[i]; - out.push( - s.match(/^xn--/) ? - punycode.decode(s.slice(4)) : - s - ); - } - return out.join("."); - }; -}(); - -module.exports = function(address){ - return address.replace(/((?:https?:\/\/)?.*\@)?([^\/]*)/, function(o, start, domain){ - var domainParts = domain.split(/\./).map(punycode.ToASCII); - return (start || "") + domainParts.join("."); - }); -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js b/api/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js deleted file mode 100644 index 10f29ec5a2f..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js +++ /dev/null @@ -1,72 +0,0 @@ -var http = require("http"), - https = require("https"), - urllib = require("url"), - Stream = require('stream').Stream; - -/** - * @namespace URLFetch - * @name urlfetch - */ -module.exports = openUrlStream; - -/** - *

Open a stream to a specified URL

- * - * @memberOf urlfetch - * @param {String} url URL to open - * @param {Object} [options] Optional options object - * @param {String} [options.userAgent="mailcomposer"] User Agent for the request - * @return {Stream} Stream for the URL contents - */ -function openUrlStream(url, options){ - options = options || {}; - var urlparts = urllib.parse(url), - urloptions = { - host: urlparts.hostname, - port: urlparts.port || (urlparts.protocol=="https:"?443:80), - path: urlparts.path || urlparts.pathname, - method: "GET", - headers: { - "User-Agent": options.userAgent || "mailcomposer" - }, - agent: false - }, - client = (urlparts.protocol=="https:"?https:http), - stream = new Stream(), - request; - - stream.resume = function(){}; - - if(urlparts.auth){ - urloptions.auth = urlparts.auth; - } - - request = client.request(urloptions, function(response) { - if((response.statusCode || 0).toString().charAt(0) != "2"){ - stream.emit("error", "Invalid status code " + (response.statusCode || 0)); - return; - } - - response.on('error', function(err) { - stream.emit("error", err); - }); - - response.on('data', function(chunk) { - stream.emit("data", chunk); - }); - - response.on('end', function(chunk) { - if(chunk){ - stream.emit("data", chunk); - } - stream.emit("end"); - }); - }); - request.end(); - - request.on('error', function(err) { - stream.emit("error", err); - }); - - return stream; -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/LICENSE b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/LICENSE deleted file mode 100644 index 451fc4550c2..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Benjamin Thomas, Robert Kieffer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/README.md deleted file mode 100644 index b90552a3b96..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# mime - -Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community. - -## Install - -Install with [npm](http://github.com/isaacs/npm): - - npm install mime - -## API - Queries - -### mime.lookup(path) -Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. - - var mime = require('mime'); - - mime.lookup('/path/to/file.txt'); // => 'text/plain' - mime.lookup('file.txt'); // => 'text/plain' - mime.lookup('.TXT'); // => 'text/plain' - mime.lookup('htm'); // => 'text/html' - -### mime.extension(type) -Get the default extension for `type` - - mime.extension('text/html'); // => 'html' - mime.extension('application/octet-stream'); // => 'bin' - -### mime.charsets.lookup() - -Map mime-type to charset - - mime.charsets.lookup('text/plain'); // => 'UTF-8' - -(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) - -## API - Defining Custom Types - -The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types). - -### mime.define() - -Add custom mime/extension mappings - - mime.define({ - 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], - 'application/x-my-type': ['x-mt', 'x-mtt'], - // etc ... - }); - - mime.lookup('x-sft'); // => 'text/x-some-format' - -The first entry in the extensions array is returned by `mime.extension()`. E.g. - - mime.extension('text/x-some-format'); // => 'x-sf' - -### mime.load(filepath) - -Load mappings from an Apache ".types" format file - - mime.load('./my_project.types'); - -The .types file format is simple - See the `types` dir for examples. diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/mime.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/mime.js deleted file mode 100644 index 70a63842486..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/mime.js +++ /dev/null @@ -1,113 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -function Mime() { - // Map of extension -> mime type - this.types = Object.create(null); - - // Map of mime type -> extension - this.extensions = Object.create(null); -} - -/** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * @param map (Object) type definitions - */ -Mime.prototype.define = function (map) { - for (var type in map) { - var exts = map[type]; - - for (var i = 0; i < exts.length; i++) { - if (process.env.DEBUG_MIME && this.types[exts]) { - console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' + - this.types[exts] + ' to ' + type); - } - - this.types[exts[i]] = type; - } - - // Default extension is the first one we encounter - if (!this.extensions[type]) { - this.extensions[type] = exts[0]; - } - } -}; - -/** - * Load an Apache2-style ".types" file - * - * This may be called multiple times (it's expected). Where files declare - * overlapping types/extensions, the last file wins. - * - * @param file (String) path of file to load. - */ -Mime.prototype.load = function(file) { - - this._loading = file; - // Read file and split into lines - var map = {}, - content = fs.readFileSync(file, 'ascii'), - lines = content.split(/[\r\n]+/); - - lines.forEach(function(line) { - // Clean up whitespace/comments, and split into fields - var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); - map[fields.shift()] = fields; - }); - - this.define(map); - - this._loading = null; -}; - -/** - * Lookup a mime type based on extension - */ -Mime.prototype.lookup = function(path, fallback) { - var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); - - return this.types[ext] || fallback || this.default_type; -}; - -/** - * Return file extension associated with a mime type - */ -Mime.prototype.extension = function(mimeType) { - return this.extensions[mimeType]; -}; - -// Default instance -var mime = new Mime(); - -// Load local copy of -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -mime.load(path.join(__dirname, 'types/mime.types')); - -// Load additional types from node.js community -mime.load(path.join(__dirname, 'types/node.types')); - -// Default type -mime.default_type = mime.lookup('bin'); - -// -// Additional API specific to the default instance -// - -mime.Mime = Mime; - -/** - * Lookup a charset based on mime type. - */ -mime.charsets = { - lookup: function(mimeType, fallback) { - // Assume text types are utf8 - return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; - } -}; - -module.exports = mime; diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/package.json b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/package.json deleted file mode 100644 index dfa9ef5a970..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "dependencies": {}, - "description": "A comprehensive library for mime-type mapping", - "devDependencies": {}, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "https://github.com/broofa/node-mime", - "type": "git" - }, - "version": "1.2.9", - "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-mime/issues" - }, - "_id": "mime@1.2.9", - "_from": "mime@~1.2.9" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/test.js deleted file mode 100644 index cbad034a18f..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/test.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Usage: node test.js - */ - -var mime = require('./mime'); -var assert = require('assert'); - -function eq(a, b) { - console.log('Test: ' + a + ' === ' + b); - assert.strictEqual.apply(null, arguments); -} - -console.log(Object.keys(mime.extensions).length + ' types'); -console.log(Object.keys(mime.types).length + ' extensions\n'); - -// -// Test mime lookups -// - -eq('text/plain', mime.lookup('text.txt')); -eq('text/plain', mime.lookup('.text.txt')); -eq('text/plain', mime.lookup('.txt')); -eq('text/plain', mime.lookup('txt')); -eq('application/octet-stream', mime.lookup('text.nope')); -eq('fallback', mime.lookup('text.fallback', 'fallback')); -eq('application/octet-stream', mime.lookup('constructor')); -eq('text/plain', mime.lookup('TEXT.TXT')); -eq('text/event-stream', mime.lookup('text/event-stream')); -eq('application/x-web-app-manifest+json', mime.lookup('text.webapp')); - -// -// Test extensions -// - -eq('txt', mime.extension(mime.types.text)); -eq('html', mime.extension(mime.types.htm)); -eq('bin', mime.extension('application/octet-stream')); -eq(undefined, mime.extension('constructor')); - -// -// Test node types -// - -eq('application/octet-stream', mime.lookup('file.buffer')); -eq('audio/mp4', mime.lookup('file.m4a')); - -// -// Test charsets -// - -eq('UTF-8', mime.charsets.lookup('text/plain')); -eq(undefined, mime.charsets.lookup(mime.types.js)); -eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); - -console.log('\nOK'); diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/mime.types b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/mime.types deleted file mode 100644 index b90b1658761..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/mime.types +++ /dev/null @@ -1,1588 +0,0 @@ -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/calendar+xml -# application/cals-1840 -# application/ccmp+xml -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -application/docbook+xml dbk -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -application/gml+xml gml -application/gpx+xml gpx -application/gxf gxf -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -application/inkml+xml ink inkml -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -application/jsonml+json jsonml -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink+xml metalink -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/omdoc+xml omdoc -application/onenote onetoc onetoc2 onetmp onepkg -application/oxps oxps -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rpki-ghostbusters gbr -application/rpki-manifest mft -application/rpki-roa roa -# application/rpki-updown -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssdl+xml ssdl -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vcard+xml -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.formscentral.fcdt fcdt -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.astraea-software.iota iota -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.collection+json -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -# application/vnd.curl -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.dart dart -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.dece.zip uvz uvvz -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.ds-keypoint kpxx -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -# application/vnd.eprints.data+xml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -# application/vnd.hal+json -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -# application/vnd.hzn-3d-crossword -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -# application/vnd.innopath.wamp.notification -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.newsmessage+xml -# application/vnd.iptc.g2.packageitem+xml -# application/vnd.iptc.g2.planningitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -# application/vnd.ms-color.iccprofile -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -# application/vnd.ms-opentype -# application/vnd.ms-package.obfuscated-opentype -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -# application/vnd.ms-printing.printticket+xml -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -application/vnd.mynfc taglet -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.nitf ntf nitf -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oftn.l10n+json -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-feature-handler+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.cab-user-prefs+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.pal+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -application/vnd.osgi.subsystem esa -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.rn-realmedia-vbr rmvb -application/vnd.route66.link66+xml link66 -# application/vnd.rs-274x -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.package smzip -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tcpdump.pcap pcap cap dmp -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.through-ngn -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -# application/x-amf -application/x-apple-diskimage dmg -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-blorb blb blorb -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cbr cbr cba cbt cbz cb7 -application/x-cdlink vcd -application/x-cfs-compressed cfs -application/x-chat chat -application/x-chess-pgn pgn -application/x-conference nsc -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-dgc-compressed dgc -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-envoy evy -application/x-eva eva -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff -# application/x-font-vfont -application/x-freearc arc -application/x-futuresplash spl -application/x-gca-compressed gca -application/x-glulx ulx -application/x-gnumeric gnumeric -application/x-gramps-xml gramps -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-install-instructions install -application/x-iso9660-image iso -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-lzh-compressed lzh lha -application/x-mie mie -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-shortcut lnk -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf wmz emf emz -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-nzb nzb -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-research-info-systems ris -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-sql sql -application/x-stuffit sit -application/x-stuffitx sitx -application/x-subrip srt -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-t3vm-image t3 -application/x-tads gam -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-tgif obj -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xliff+xml xlf -application/x-xpinstall xpi -application/x-xz xz -application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 -# application/x400-bp -application/xaml+xml xaml -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xproc+xml xpl -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dv -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/fwdred -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/ip-mr_v2.5 -# audio/isac -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -# audio/musepack -audio/ogg oga ogg spx -# audio/opus -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -audio/s3m s3m -audio/silk sil -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.dvb.file -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-caf caf -audio/x-flac flac -audio/x-matroska mka -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -# audio/x-tta -audio/x-wav wav -audio/xm xm -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/sgi sgi -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.ms-photo wdp -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-3ds 3ds -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-mrsid-image sid -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-tga tga -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -model/x3d+binary x3db x3dbz -model/x3d+vrml x3dv x3dvz -model/x3d+xml x3d x3dz -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/cache-manifest appcache -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -# text/fwdred -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -text/vcard vcard -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -text/vnd.dvb.subtitle sub -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-java-source java -text/x-opml opml -text/x-pascal p pas -text/x-nfo nfo -text/x-setext etx -text/x-sfv sfv -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.dvb.file dvb -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-matroska mkv mk3d mks -video/x-mng mng -video/x-ms-asf asf asx -video/x-ms-vob vob -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -video/x-smv smv -x-conference/x-cooltalk ice diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/node.types b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/node.types deleted file mode 100644 index 970a1bd85d6..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mime/types/node.types +++ /dev/null @@ -1,60 +0,0 @@ -# What: WebVTT -# Why: To allow formats intended for marking up external text track resources. -# http://dev.w3.org/html5/webvtt/ -# Added by: niftylettuce -text/vtt vtt - -# What: Google Chrome Extension -# Why: To allow apps to (work) be served with the right content type header. -# http://codereview.chromium.org/2830017 -# Added by: niftylettuce -application/x-chrome-extension crx - -# What: HTC support -# Why: To properly render .htc files such as CSS3PIE -# Added by: niftylettuce -text/x-component htc - -# What: HTML5 application cache manifest -# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps -# per https://developer.mozilla.org/en/offline_resources_in_firefox -# Added by: louisremi -text/cache-manifest appcache manifest - -# What: node binary buffer format -# Why: semi-standard extension w/in the node community -# Added by: tootallnate -application/octet-stream buffer - -# What: The "protected" MP-4 formats used by iTunes. -# Why: Required for streaming music to browsers (?) -# Added by: broofa -application/mp4 m4p -audio/mp4 m4a - -# What: Video format, Part of RFC1890 -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -video/MP2T ts - -# What: EventSource mime type -# Why: mime type of Server-Sent Events stream -# http://www.w3.org/TR/eventsource/#text-event-stream -# Added by: francois2metz -text/event-stream event-stream - -# What: Mozilla App manifest mime type -# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests -# Added by: ednapiranha -application/x-web-app-manifest+json webapp - -# What: Lua file types -# Why: Googling around shows de-facto consensus on these -# Added by: creationix (Issue #45) -text/x-lua lua -application/x-lua-bytecode luac - -# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax -# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown -# Added by: avoidwork -text/x-markdown markdown md mkd diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE deleted file mode 100644 index 2950902b104..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2011 Andris Reinman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md deleted file mode 100644 index 58a0871b376..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# mimelib - -*mimelib* is a collection of useful functions to deal with mime-encoded data. - -## Reference - -See [API reference](/andris9/mimelib/blob/master/doc.md) for documentation - -## Installation - -Install with *npm* - - npm install mimelib-noiconv - -## Usage - - var mimelib = require("mimelib-noiconv"); diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js deleted file mode 100644 index bc5aa672ae5..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js +++ /dev/null @@ -1,60 +0,0 @@ -// list of mime types -module.exports = { - "doc": "application/msword", - "docx": "application/msword", - "pdf": "application/pdf", - "rss": "application/rss+xml", - "xls": "application/vnd.ms-excel", - "xlsx": "application/vnd.ms-excel", - "pps": "application/vnd.ms-powerpoint", - "ppt": "application/vnd.ms-powerpoint", - "pptx": "application/vnd.ms-powerpoint", - "odp": "application/vnd.oasis.opendocument.presentation", - "ods": "application/vnd.oasis.opendocument.spreadsheet", - "odt": "application/vnd.oasis.opendocument.text", - "sxc": "application/vnd.sun.xml.calc", - "sxw": "application/vnd.sun.xml.writer", - "au": "audio/basic", - "snd": "audio/basic", - "flac": "audio/flac", - "mid": "audio/mid", - "rmi": "audio/mid", - "m4a": "audio/mp4", - "mp3": "audio/mpeg", - "oga": "audio/ogg", - "ogg": "audio/ogg", - "aif": "audio/x-aiff", - "aifc": "audio/x-aiff", - "aiff": "audio/x-aiff", - "wav": "audio/x-wav", - "gif": "image/gif", - "jpeg": "image/jpeg", - "jpg": "image/jpeg", - "jpe": "image/jpeg", - "png": "image/png", - "tiff": "image/tiff", - "tif": "image/tiff", - "wbmp": "image/vnd.wap.wbmp", - "bmp": "image/x-ms-bmp", - "ics": "text/calendar", - "csv": "text/comma-separated-values", - "css": "text/css", - "htm": "text/html", - "html": "text/html", - "text": "text/plain", - "txt": "text/plain", - "asc": "text/plain", - "diff": "text/plain", - "pot": "text/plain", - "vcf": "text/x-vcard", - "mp4": "video/mp4", - "mpeg": "video/mpeg", - "mpg": "video/mpeg", - "mpe": "video/mpeg", - "ogv": "video/ogg", - "qt": "video/quicktime", - "mov": "video/quicktime", - "avi": "video/x-msvideo", - "zip": "application/zip", - "rar": "application/x-rar-compressed" -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md deleted file mode 100644 index 3c895148d1d..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/doc.md +++ /dev/null @@ -1,191 +0,0 @@ -mimelib(1) -- MIME functions for Node.JS -============================================= - -## DESCRIPTION - -This document lists all the available methods for mimelib. You can include mimelib -in your projects with `var mimelib = require("mimelib");` - -When installed with npm dependency module iconv will also be installed if not already -present. - -## contentTypes - -`mimelib.contentTypes` is an object to provide content type strings for common -file extensions - - mimelib.contentTypes["xls"]; // "application/vnd.ms-excel" - -## foldLine - -Folds a long line according to the RFC 5322 - - mimelib.foldLine(str [, maxLength][, foldAnywhere]) -> String - - - `str` (String): mime string that might need folding - - `maxLength` (Number): max length for a line, defaults to 78 - - `foldAnywhere` (Boolean): can fold at any location (ie. in base64) - - `afterSpace` (Boolean): If `true` fold after the space - - -For example: - - Content-Type: multipart/alternative; boundary="----zzzz----" - -will become - - Content-Type: multipart/alternative; - boundary="----zzzz----" - -## encodeMimeWord - -Encodes a string into mime encoded word format (see also `decodeMimeWord`) - - mimelib.encodeMimeWord = function(str [, encoding][, charset]) - - - `str` (String): String to be encoded - - `encoding` (String): Encoding Q for quoted printable or B (def.) for base64 - - `charset` (String): Charset to be used - -For example: - - See on õhin test - -Becomes with UTF-8 and Quoted-printable encoding - - =?UTF-8?q?See_on_=C3=B5hin_test?= - -## decodeMimeWord - -Decodes a string from mime encoded word format (see also `encodeMimeWord`) - - mimelib.decodeMimeWord(str) -> String - - - `str` (String): String to be decoded - -For example - - mimelib.decodeMimeWord("=?UTF-8?q?See_on_=C3=B5hin_test?="); - -will become - - See on õhin test - -## encodeQuotedPrintable - -Encodes a string into Quoted-printable format (see also `decodeQuotedPrintable`) - - mimelib.encodeQuotedPrintable(str [, mimeWord][, charset]) -> String - - - `str` (String): String to be encoded into Quoted-printable - - `mimeWord` (Boolean): Use mime-word mode (defaults to false) - - `charset` (String): Destination charset, defaults to UTF-8 - -TODO: Currently only allowed charsets: UTF-8, LATIN1 - -## decodeQuotedPrintable - -Decodes a string from Quoted-printable format (see also `encodeQuotedPrintable`) - - mimelib.deccodeQuotedPrintable(str [, mimeWord][, charset]) -> String - - - `str` (String): String to be decoded - - `mimeWord` (Boolean): Use mime-word mode (defaults to false) - - `charset` (String): Charset to be used, defaults to UTF-8 - -## encodeBase64 - -Encodes a string into Base64 format. Base64 is mime-word safe (see also `decodeBase64`) - - mimelib.encodeBase64(str [, charset]) -> String - - - `str` (String): String to be encoded into Base64 - - `charset` (String): Destination charset, defaults to UTF-8 - -## decodeBase64 - -Decodes a string from Base64 format. Base64 is mime-word safe (see also `encodeBase64`) - -NB! Always returns UTF-8 - - mimelib.decodeBase64(str) -> String - - - `str` (String): String to be decoded from Base64 - - `charset` (String): Source charset, defaults to UTF-8 - -## parseHeaders - -Parses header lines into an array of objects (see `parseHeaderLine`) - - mimelib.parseHeaders(headers) -> Array - - - `headers` (String): header section of the e-mail - -Example: - - var headers = [ - "From: andris@node.ee", - "To: juulius@node.ee", - "To: juulius2@node.ee", - "Content-type: text/html;", - " charset=utf-8" - ].join("\r\n"); - mimelib.parseHeaders(headers); - -Results in - - {"from": [ 'andris@node.ee' ], - "to": [ 'juulius@node.ee', 'juulius2@node.ee' ], - "content-type": [ 'text/html; charset=utf-8' ] } - -## parseAddresses - -Parses names and addresses from a from, to, cc or bcc line - - mimelib.parseAddresses(addresses) -> Array - - - `addresses` (String): string with comma separated e-mail addresses - -Example: - - var to = '"Andris Reinman" , juulius@node.ee' - mimelib.parseAddresses(to); - -Results in - - [{ address: 'andris@node.ee', name: 'Andris Reinman' }, - { address: 'juulius@node.ee', name: false }] - -## parseMimeWords - -Parses mime-words into UTF-8 strings - - mimelib.parseMimeWords(str) -> String - - - `str` (String): string to be parsed, if includes any mime words, then these are converted to UTF-8 strings - - -For example: - - mimelib.parseMimeWords("Hello: =?UTF-8?q?See_on_=C3=B5hin_test?="); - -Results in - - "Hello: See on õhin test" - -## parseHeaderLine - -Parses a header line to search for additional parameters. - - mimelib.parseHeaderLine(line) -> Object - - - `line` (String): a line from a message headers - -For example: - - mimelib.parseHeaderLine("text/plain; charset=utf-8")imelib - -Results in - - {"defaultValue": 'text/plain', - "charset": 'utf-8' } diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js deleted file mode 100644 index a7ea3eec3bc..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js +++ /dev/null @@ -1,3 +0,0 @@ - -module.exports = require("./mime-functions"); -module.exports.contentTypes = require("./content-types"); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js deleted file mode 100644 index d3bf24539e4..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js +++ /dev/null @@ -1,483 +0,0 @@ - -try{ - // see http://github.com/bnoordhuis/node-iconv for more info - var Iconv = require("iconv").Iconv; -}catch(E){ - // convert nothing - Iconv = function(){} - Iconv.prototype.convert = function(buf){return buf;}; -} - -/* mime related functions - encoding/decoding etc*/ -/* TODO: Only UTF-8 and Latin1 are allowed with encodeQuotedPrintable */ -/* TODO: Check if the input string even needs encoding */ - -/** - * mime.foldLine(str, maxLength, foldAnywhere) -> String - * - str (String): mime string that might need folding - * - maxLength (Number): max length for a line, defaults to 78 - * - foldAnywhere (Boolean): can fold at any location (ie. in base64) - * - afterSpace (Boolean): If [true] fold after the space - * - * Folds a long line according to the RFC 5322 - * - * - * For example: - * Content-Type: multipart/alternative; boundary="----bd_n3-lunchhour1283962663300----" - * will become - * Content-Type: multipart/alternative; - * boundary="----bd_n3-lunchhour1283962663300----" - * - **/ -this.foldLine = function(str, maxLength, foldAnywhere, afterSpace){ - var line=false, curpos=0, response="", lf; - maxLength = maxLength || 78; - - // return original if no need to fold - if(str.length<=maxLength) - return str; - - // read in bytes and try to fold it - while(line = str.substr(curpos, maxLength)){ - if(!!foldAnywhere){ - response += line; - if(curpos+maxLength=maxLength && lf>0){ - if(!!afterSpace){ - // move forward until line end or no more \s and \t - while(lf String - * - str (String): String to be encoded - * - encoding (String): Encoding Q for quoted printable or B (def.) for base64 - * - charset (String): Charset to be used - * - * Encodes a string into mime encoded word format - * - * - * For example: - * See on õhin test - * Becomes with UTF-8 and Quoted-printable encoding - * =?UTF-8?q?See_on_=C3=B5hin_test?= - * - **/ -this.encodeMimeWord = function(str, encoding, charset){ - charset = charset || "UTF-8"; - encoding = encoding && encoding.toUpperCase() || "B"; - - if(encoding=="Q"){ - str = this.encodeQuotedPrintable(str, true, charset); - } - - if(encoding=="B"){ - str = this.encodeBase64(str); - } - - return "=?"+charset+"?"+encoding+"?"+str+"?="; -} - -/** - * mime.decodeMimeWord(str, encoding, charset) -> String - * - str (String): String to be encoded - * - encoding (String): Encoding Q for quoted printable or B (def.) for base64 - * - charset (String): Charset to be used, defaults to UTF-8 - * - * Decodes a string from mime encoded word format, see [[encodeMimeWord]] - * - **/ - -this.decodeMimeWord = function(str){ - var parts = str.split("?"), - charset = parts && parts[1], - encoding = parts && parts[2], - text = parts && parts[3]; - if(!charset || !encoding || !text) - return str; - if(encoding.toUpperCase()=="Q"){ - return this.decodeQuotedPrintable(text, true, charset); - } - - if(encoding.toUpperCase()=="B"){ - return this.decodeBase64(text); - } - - return text; -} - - -/** - * mime.encodeQuotedPrintable(str, mimeWord, charset) -> String - * - str (String): String to be encoded into Quoted-printable - * - mimeWord (Boolean): Use mime-word mode (defaults to false) - * - charset (String): Destination charset, defaults to UTF-8 - * TODO: Currently only allowed charsets: UTF-8, LATIN1 - * - * Encodes a string into Quoted-printable format. - **/ -this.encodeQuotedPrintable = function(str, mimeWord, charset){ - charset = charset || "UTF-8"; - - /* - * Characters from 33-126 OK (except for =; and ?_ when in mime word mode) - * Spaces + tabs OK (except for line beginnings and endings) - * \n + \r OK - */ - - str = str.replace(/[^\sa-zA-Z\d]/gm,function(c){ - if(!!mimeWord){ - if(c=="?")return "=3F"; - if(c=="_")return "=5F"; - } - if(c!=="=" && c.charCodeAt(0)>=33 && c.charCodeAt(0)<=126) - return c; - return c=="="?"=3D":(charset=="UTF-8"?encodeURIComponent(c):escape(c)).replace(/%/g,'='); - }); - - str = lineEdges(str); - - if(!mimeWord){ - // lines might not be longer than 76 bytes, soft break: "=\r\n" - var lines = str.split(/\r?\n/); - str.replace(/(.{73}(?!\r?\n))/,"$&=\r\n") - for(var i=0, len = lines.length; i76){ - lines[i] = this.foldLine(lines[i],76, false, true).replace(/\r\n/g,"=\r\n"); - } - } - str = lines.join("\r\n"); - }else{ - str = str.replace(/\s/g, function(a){ - if(a==" ")return "_"; - if(a=="\t")return "=09"; - return a=="\r"?"=0D":"=0A"; - }); - } - - return str; -} - -/** - * mime.deccodeQuotedPrintable(str, mimeWord, charset) -> String - * - str (String): String to be decoded - * - mimeWord (Boolean): Use mime-word mode (defaults to false) - * - charset (String): Charset to be used, defaults to UTF-8 - * - * Decodes a string from Quoted-printable format. - **/ -this.decodeQuotedPrintable = function(str, mimeWord, charset){ - charset = charset && charset.toUpperCase() || "UTF-8"; - - if(mimeWord){ - str = str.replace(/_/g," "); - }else{ - str = str.replace(/=\r\n/gm,''); - str = str.replace(/=$/,""); - } - if(charset == "UTF-8") - str = decodeURIComponent(str.replace(/%/g,'%25').replace(/=/g,"%")); - else{ - str = str.replace(/%/g,'%25').replace(/=/g,"%"); - if(charset=="ISO-8859-1" || charset=="LATIN1") - str = unescape(str); - else{ - str = decodeBytestreamUrlencoding(str); - str = fromCharset(charset, str); - } - } - return str; -} - -/** - * mime.encodeBase64(str) -> String - * - str (String): String to be encoded into Base64 - * - charset (String): Destination charset, defaults to UTF-8 - * - * Encodes a string into Base64 format. Base64 is mime-word safe. - **/ -this.encodeBase64 = function(str, charset){ - var buffer; - if(charset && charset.toUpperCase()!="UTF-8") - buffer = toCharset(charset, str); - else - buffer = new Buffer(str, "UTF-8"); - return buffer.toString("base64"); -} - -/** - * mime.decodeBase64(str) -> String - * - str (String): String to be decoded from Base64 - * - charset (String): Source charset, defaults to UTF-8 - * - * Decodes a string from Base64 format. Base64 is mime-word safe. - * NB! Always returns UTF-8 - **/ -this.decodeBase64 = function(str, charset){ - var buffer = new Buffer(str, "base64"); - - if(charset && charset.toUpperCase()!="UTF-8"){ - return fromCharset(charset, buffer); - } - - // defaults to utf-8 - return buffer.toString("UTF-8"); -} - -/** - * mime.parseHeaders(headers) -> Array - * - headers (String): header section of the e-mail - * - * Parses header lines into an array of objects (see [[parseHeaderLine]]) - * FIXME: This should probably not be here but in "envelope" instead - **/ -this.parseHeaders = function(headers){ - var text, lines, line, i, name, value, cmd, header_lines = {}; - // unfold - headers = headers.replace(/\r?\n([ \t])/gm," "); - - // split lines - lines = headers.split(/\r?\n/); - for(i=0; i Array - * - addresses (String): string with comma separated e-mail addresses - * - * Parses names and addresses from a from, to, cc or bcc line - **/ -this.parseAddresses = function(addresses){ - if(!addresses) - return []; - - addresses = addresses.replace(/\=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a){return this.decodeMimeWord(a);}).bind(this)); - - // not sure if it's even needed - urlencode escaped \\ and \" and \' - addresses = addresses.replace(/\\\\/g,function(a){return escape(a.charAt(1));}); - addresses = addresses.replace(/\\["']/g,function(a){return escape(a.charAt(1));}); - - // find qutoed strings - - var parts = addresses.split(','), curStr, - curQuote, lastPos, remainder="", str, list = [], - curAddress, address, addressArr = [], name, email, i, len; - var rightEnd; - - // separate quoted text from text parts - for(i=0, len=parts.length; i]+)>/, function(original, addr){ - email = addr.indexOf("@")>=0 && addr; - return email ? "" : original; - }).trim(); - - if(!email){ - address = address.replace(/(\S+@\S+)/, function(original, m){ - email = m; - return email ? "" : original; - }); - } - - if(!name){ - if(email){ - email = email.replace(/\(([^)]+)\)/,function(original, n){ - name = n; - return ""; - }); - } - if(!name){ - name = address.replace(/"/g,"").trim(); - } - } - - // just in case something got mixed up - if(!email && name.indexOf("@")>=0){ - email = name; - name = false; - } - - if(name || email){ - addressArr.push({address:decodeURIComponent(email || ""), name: decodeURIComponent(name || "")}); - } - } - return addressArr; -}; - -/** - * mime.parseMimeWords(str) -> String - * - str (String): string to be parsed - * - * Parses mime-words into UTF-8 strings - **/ -this.parseMimeWords = function(str){ - return str.replace(/=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a){ - return this.decodeMimeWord(a); - }).bind(this)); -} - -/** - * mime.parseHeaderLine(line) -> Object - * - line (String): a line from a message headers - * - * Parses a header line to search for additional parameters. - * For example with "text/plain; charset=utf-8" the output would be - * - defaultValue = text/plain - * - charset = utf-8 - **/ -this.parseHeaderLine = function(line){ - if(!line) - return {}; - var result = {}, parts = line.split(";"), pos; - for(var i=0, len = parts.length; i String - * - str (String): String to be processed - * - * Replaces all spaces and tabs in the beginning and end of the string - * with quoted printable encoded chars. Needed by [[encodeQuotedPrintable]] - **/ -function lineEdges(str){ - str = str.replace(/^[ \t]+/gm, function(wsc){ - return wsc.replace(/ /g,"=20").replace(/\t/g,"=09"); - }); - - str = str.replace(/[ \t]+$/gm, function(wsc){ - return wsc.replace(/ /g,"=20").replace(/\t/g,"=09"); - }); - return str; -} - -/** - * fromCharset(charset, buffer, keep_buffer) -> String | Buffer - * - charset (String): Source charset - * - buffer (Buffer): Buffer in - * - keep_buffer (Boolean): If true, return buffer, otherwise UTF-8 string - * - * Converts a buffer in codepage into UTF-8 string - **/ -function fromCharset(charset, buffer, keep_buffer){ - var iconv = new Iconv(charset,'UTF-8'), - buffer = iconv.convert(buffer); - return keep_buffer?buffer:buffer.toString("utf-8"); -} - -/** - * toCharset(charset, buffer) -> Buffer - * - charset (String): Source charset - * - buffer (Buffer): Buffer in UTF-8 or string - * - * Converts a string or buffer to codepage - **/ -function toCharset(charset, buffer){ - var iconv = new Iconv('UTF-8',charset); - return iconv.convert(buffer); -} - -/** - * decodeBytestreamUrlencoding(encoded_string) -> Buffer - * - encoded_string (String): String in urlencode coding - * - * Converts an urlencoded string into a bytestream buffer. If the used - * charset is known the resulting string can be converted to UTF-8 with - * [[fromCharset]]. - * NB! For UTF-8 use decodeURIComponent and for Latin 1 decodeURL instead - **/ -function decodeBytestreamUrlencoding(encoded_string){ - var c, i, j=0, prcnts = encoded_string.match(/%/g) || "", - buffer_length = encoded_string.length - (prcnts.length*2), - buffer = new Buffer(buffer_length); - - for(var i=0; i - - mimelib.foldLine(str [, maxLength][, foldAnywhere][, afterSpace]) -> String - - - `str` (String): mime string that might need folding - - `maxLength` (Number): max length for a line, defaults to 78 - - `foldAnywhere` (Boolean): can fold at any location (ie. in base64) - - `afterSpace` (Boolean): If `true` fold after the space - - -For example: - - Content-Type: multipart/alternative; boundary="----zzzz----" - -will become - - Content-Type: multipart/alternative; - boundary="----zzzz----" - -### encodeMimeWord - -Encodes a string into mime encoded word format (see also `decodeMimeWord`) - - mimelib.encodeMimeWord = function(str [, encoding][, charset]) - - - `str` (String): String to be encoded - - `encoding` (String): Encoding Q for quoted printable or B (def.) for base64 - - `charset` (String): Charset to be used - -For example: - - See on õhin test - -Becomes with UTF-8 and Quoted-printable encoding - - =?UTF-8?Q?See_on_=C3=B5hin_test?= - -### decodeMimeWord - -Decodes a string from mime encoded word format (see also `encodeMimeWord`) - - mimelib.decodeMimeWord(str) -> String - - - `str` (String): String to be decoded - -For example - - mimelib.decodeMimeWord("=?UTF-8?Q?See_on_=C3=B5hin_test?="); - -will become - - See on õhin test - -### encodeQuotedPrintable - -Encodes a string into Quoted-printable format (see also `decodeQuotedPrintable`) - - mimelib.encodeQuotedPrintable(str [, mimeWord][, charset]) -> String - - - `str` (String): String to be encoded into Quoted-printable - - `mimeWord` (Boolean): Deprecated, has no effect, ignore it - - `charset` (String): Destination charset, defaults to UTF-8 - -### decodeQuotedPrintable - -Decodes a string from Quoted-printable format (see also `encodeQuotedPrintable`) - - mimelib.decodeQuotedPrintable(str [, mimeWord][, charset]) -> String - - - `str` (String): String to be decoded - - `mimeWord` (Boolean): Deprecated, has no effect, ignore it - - `charset` (String): Charset to be used, defaults to UTF-8 - -### encodeBase64 - -Encodes a string into Base64 format. Base64 is mime-word safe (see also `decodeBase64`) - - mimelib.encodeBase64(str [, charset]) -> String - - - `str` (String): String to be encoded into Base64 - - `charset` (String): Destination charset, defaults to UTF-8 - -### decodeBase64 - -Decodes a string from Base64 format. Base64 is mime-word safe (see also `encodeBase64`) - -NB! Always returns UTF-8 - - mimelib.decodeBase64(str) -> String - - - `str` (String): String to be decoded from Base64 - - `charset` (String): Source charset, defaults to UTF-8 - -### parseHeaders - -Parses header lines into an array of objects (see `parseHeaderLine`) - - mimelib.parseHeaders(headers) -> Array - - - `headers` (String): header section of the e-mail - -Example: - - var headers = [ - "From: andris@node.ee", - "To: juulius@node.ee", - "To: juulius2@node.ee", - "Content-type: text/html;", - " charset=utf-8" - ].join("\r\n"); - mimelib.parseHeaders(headers); - -Results in - - {"from": [ 'andris@node.ee' ], - "to": [ 'juulius@node.ee', 'juulius2@node.ee' ], - "content-type": [ 'text/html; charset=utf-8' ] } - -### parseAddresses - -Parses names and addresses from a from, to, cc or bcc line - - mimelib.parseAddresses(addresses) -> Array - - - `addresses` (String): string with comma separated e-mail addresses - -Example: - - var to = '"Andris Reinman" , juulius@node.ee' - mimelib.parseAddresses(to); - -Results in - - [{ address: 'andris@node.ee', name: 'Andris Reinman' }, - { address: 'juulius@node.ee', name: false }] - -### parseMimeWords - -Parses mime-words into UTF-8 strings - - mimelib.parseMimeWords(str) -> String - - - `str` (String): string to be parsed, if includes any mime words, then these are converted to UTF-8 strings - - -For example: - - mimelib.parseMimeWords("Hello: =?UTF-8?Q?See_on_=C3=B5hin_test?="); - -Results in - - "Hello: See on õhin test" - -### parseHeaderLine - -Parses a header line to search for additional parameters. - - mimelib.parseHeaderLine(line) -> Object - - - `line` (String): a line from a message headers - -For example: - - mimelib.parseHeaderLine("text/plain; charset=utf-8")imelib - -Results in - - {"defaultValue": 'text/plain', - "charset": 'utf-8' } - -### contentTypes - -**NB! this feature is deprecated**, use [mime](https://github.com/broofa/node-mime) module instead to detect content types and extensions - -`mimelib.contentTypes` is an object to provide content type strings for common -file extensions - - mimelib.contentTypes["xls"]; // "application/vnd.ms-excel" - -## iconv support - -By default only iconv-lite support is bundled. If you need node-iconv support, you need to add it -as an additional dependency for your project: - - ..., - "dependencies":{ - "mimelib": "*", - "iconv": "*" - }, - ... - -## License - -mimelib license is \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/20000.txt b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/20000.txt deleted file mode 100644 index 65fbbfaa9de..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/20000.txt +++ /dev/null @@ -1,5389 +0,0 @@ - -Project Gutenberg's Twenty Thousand Leagues under the Sea, by Jules Verne - -This eBook is for the use of anyone anywhere at no cost and with -almost no restrictions whatsoever. You may copy it, give it away or -re-use it under the terms of the Project Gutenberg License included -with this eBook or online at www.gutenberg.net - - -Title: Twenty Thousand Leagues under the Sea - -Author: Jules Verne - -Release Date: May 24, 2008 [EBook #164] - -Language: English - -Character set encoding: ISO-8859-1 - -*** START OF THIS PROJECT GUTENBERG EBOOK 20000 LEAGUES UNDER THE SEA *** - - - - - - - - - - - - -This etext was done by a number of anonymous volunteers of the Gutenberg Project, -to whom we owe a great deal of thanks and to whom we dedicate this book. - - - - -TWENTY THOUSAND LEAGUES UNDER THE SEA - - -by - -JULES VERNE - - - - -CONTENTS - -PART I - -CHAPTER -I A SHIFTING REEF -II PRO AND CON -III I FORM MY RESOLUTION -IV NED LAND -V AT A VENTURE -VI AT FULL STEAM -VII AN UNKNOWN SPECIES OF WHALE -VIII MOBILIS IN MOBILI -IX NED LAND'S TEMPERS -X THE MAN OF THE SEAS -XI ALL BY ELECTRICITY -XII SOME FIGURES -XIII THE BLACK RIVER -XIV A NOTE OF INVITATION -XV A WALK ON THE BOTTOM OF THE SEA -XVI A SUBMARINE FOREST -XVII FOUR THOUSAND LEAGUES UNDER THE PACIFIC -XVIII VANIKORO -XIX TORRES STRAITS -XX A FEW DAYS ON LAND -XXI CAPTAIN NEMO'S THUNDERBOLT -XXII "AEGRI SOMNIA" -XXIII THE CORAL KINGDOM - - - -CONTENTS - -PART II - -CHAPTER -I THE INDIAN OCEAN -II A NOVEL PROPOSAL OF CAPTAIN NEMO'S -III A PEARL OF TEN MILLIONS -IV THE RED SEA -V THE ARABIAN TUNNEL -VI THE GRECIAN ARCHIPELAGO -VII THE MEDITERRANEAN IN FORTY-EIGHT HOURS -VIII VIGO BAY -IX A VANISHED CONTINENT -X THE SUBMARINE COAL-MINES -XI THE SARGASSO SEA -XII CACHALOTS AND WHALES -XIII THE ICEBERG -XIV THE SOUTH POLE -XV ACCIDENT OR INCIDENT? -XVI WANT OF AIR -XVII FROM CAPE HORN TO THE AMAZON -XVIII THE POULPS -XIX THE GULF STREAM -XX FROM LATITUDE 47° 24' TO LONGITUDE 17° 28' -XXI A HECATOMB -XXII THE LAST WORDS OF CAPTAIN NEMO -XXIII CONCLUSION - - - -PART ONE - - - - - -CHAPTER I - -A SHIFTING REEF - -The year 1866 was signalised by a remarkable incident, a mysterious and puzzling phenomenon, which doubtless no one has yet forgotten. Not to mention rumours which agitated the maritime population and excited the public mind, even in the interior of continents, seafaring men were particularly excited. Merchants, common sailors, captains of vessels, skippers, both of Europe and America, naval officers of all countries, and the Governments of several States on the two continents, were deeply interested in the matter. - -For some time past vessels had been met by "an enormous thing," a long object, spindle-shaped, occasionally phosphorescent, and infinitely larger and more rapid in its movements than a whale. - -The facts relating to this apparition (entered in various log-books) agreed in most respects as to the shape of the object or creature in question, the untiring rapidity of its movements, its surprising power of locomotion, and the peculiar life with which it seemed endowed. If it was a whale, it surpassed in size all those hitherto classified in science. Taking into consideration the mean of observations made at divers times—rejecting the timid estimate of those who assigned to this object a length of two hundred feet, equally with the exaggerated opinions which set it down as a mile in width and three in length—we might fairly conclude that this mysterious being surpassed greatly all dimensions admitted by the learned ones of the day, if it existed at all. And that it DID exist was an undeniable fact; and, with that tendency which disposes the human mind in favour of the marvellous, we can understand the excitement produced in the entire world by this supernatural apparition. As to classing it in the list of fables, the idea was out of the question. - -On the 20th of July, 1866, the steamer Governor Higginson, of the Calcutta and Burnach Steam Navigation Company, had met this moving mass five miles off the east coast of Australia. Captain Baker thought at first that he was in the presence of an unknown sandbank; he even prepared to determine its exact position when two columns of water, projected by the mysterious object, shot with a hissing noise a hundred and fifty feet up into the air. Now, unless the sandbank had been submitted to the intermittent eruption of a geyser, the Governor Higginson had to do neither more nor less than with an aquatic mammal, unknown till then, which threw up from its blow-holes columns of water mixed with air and vapour. - -Similar facts were observed on the 23rd of July in the same year, in the Pacific Ocean, by the Columbus, of the West India and Pacific Steam Navigation Company. But this extraordinary creature could transport itself from one place to another with surprising velocity; as, in an interval of three days, the Governor Higginson and the Columbus had observed it at two different points of the chart, separated by a distance of more than seven hundred nautical leagues. - -Fifteen days later, two thousand miles farther off, the Helvetia, of the Compagnie-Nationale, and the Shannon, of the Royal Mail Steamship Company, sailing to windward in that portion of the Atlantic lying between the United States and Europe, respectively signalled the monster to each other in 42° 15' N. lat. and 60° 35' W. long. In these simultaneous observations they thought themselves justified in estimating the minimum length of the mammal at more than three hundred and fifty feet, as the Shannon and Helvetia were of smaller dimensions than it, though they measured three hundred feet over all. - -Now the largest whales, those which frequent those parts of the sea round the Aleutian, Kulammak, and Umgullich islands, have never exceeded the length of sixty yards, if they attain that. - -In every place of great resort the monster was the fashion. They sang of it in the cafes, ridiculed it in the papers, and represented it on the stage. All kinds of stories were circulated regarding it. There appeared in the papers caricatures of every gigantic and imaginary creature, from the white whale, the terrible "Moby Dick" of sub-arctic regions, to the immense kraken, whose tentacles could entangle a ship of five hundred tons and hurry it into the abyss of the ocean. The legends of ancient times were even revived. - -Then burst forth the unending argument between the believers and the unbelievers in the societies of the wise and the scientific journals. "The question of the monster" inflamed all minds. Editors of scientific journals, quarrelling with believers in the supernatural, spilled seas of ink during this memorable campaign, some even drawing blood; for from the sea-serpent they came to direct personalities. - -During the first months of the year 1867 the question seemed buried, never to revive, when new facts were brought before the public. It was then no longer a scientific problem to be solved, but a real danger seriously to be avoided. The question took quite another shape. The monster became a small island, a rock, a reef, but a reef of indefinite and shifting proportions. - -On the 5th of March, 1867, the Moravian, of the Montreal Ocean Company, finding herself during the night in 27° 30' lat. and 72° 15' long., struck on her starboard quarter a rock, marked in no chart for that part of the sea. Under the combined efforts of the wind and its four hundred horse power, it was going at the rate of thirteen knots. Had it not been for the superior strength of the hull of the Moravian, she would have been broken by the shock and gone down with the 237 passengers she was bringing home from Canada. - -The accident happened about five o'clock in the morning, as the day was breaking. The officers of the quarter-deck hurried to the after-part of the vessel. They examined the sea with the most careful attention. They saw nothing but a strong eddy about three cables' length distant, as if the surface had been violently agitated. The bearings of the place were taken exactly, and the Moravian continued its route without apparent damage. Had it struck on a submerged rock, or on an enormous wreck? They could not tell; but, on examination of the ship's bottom when undergoing repairs, it was found that part of her keel was broken. - -This fact, so grave in itself, might perhaps have been forgotten like many others if, three weeks after, it had not been re-enacted under similar circumstances. But, thanks to the nationality of the victim of the shock, thanks to the reputation of the company to which the vessel belonged, the circumstance became extensively circulated. - -The 13th of April, 1867, the sea being beautiful, the breeze favourable, the Scotia, of the Cunard Company's line, found herself in 15° 12' long. and 45° 37' lat. She was going at the speed of thirteen knots and a half. - -At seventeen minutes past four in the afternoon, whilst the passengers were assembled at lunch in the great saloon, a slight shock was felt on the hull of the Scotia, on her quarter, a little aft of the port-paddle. - -The Scotia had not struck, but she had been struck, and seemingly by something rather sharp and penetrating than blunt. The shock had been so slight that no one had been alarmed, had it not been for the shouts of the carpenter's watch, who rushed on to the bridge, exclaiming, "We are sinking! we are sinking!" At first the passengers were much frightened, but Captain Anderson hastened to reassure them. The danger could not be imminent. The Scotia, divided into seven compartments by strong partitions, could brave with impunity any leak. Captain Anderson went down immediately into the hold. He found that the sea was pouring into the fifth compartment; and the rapidity of the influx proved that the force of the water was considerable. Fortunately this compartment did not hold the boilers, or the fires would have been immediately extinguished. Captain Anderson ordered the engines to be stopped at once, and one of the men went down to ascertain the extent of the injury. Some minutes afterwards they discovered the existence of a large hole, two yards in diameter, in the ship's bottom. Such a leak could not be stopped; and the Scotia, her paddles half submerged, was obliged to continue her course. She was then three hundred miles from Cape Clear, and, after three days' delay, which caused great uneasiness in Liverpool, she entered the basin of the company. - -The engineers visited the Scotia, which was put in dry dock. They could scarcely believe it possible; at two yards and a half below water-mark was a regular rent, in the form of an isosceles triangle. The broken place in the iron plates was so perfectly defined that it could not have been more neatly done by a punch. It was clear, then, that the instrument producing the perforation was not of a common stamp and, after having been driven with prodigious strength, and piercing an iron plate 1 3/8 inches thick, had withdrawn itself by a backward motion. - -Such was the last fact, which resulted in exciting once more the torrent of public opinion. From this moment all unlucky casualties which could not be otherwise accounted for were put down to the monster. - -Upon this imaginary creature rested the responsibility of all these shipwrecks, which unfortunately were considerable; for of three thousand ships whose loss was annually recorded at Lloyd's, the number of sailing and steam-ships supposed to be totally lost, from the absence of all news, amounted to not less than two hundred! - -Now, it was the "monster" who, justly or unjustly, was accused of their disappearance, and, thanks to it, communication between the different continents became more and more dangerous. The public demanded sharply that the seas should at any price be relieved from this formidable cetacean.[1] - - - -[1] Member of the whale family. - - - - -CHAPTER II - -PRO AND CON - -At the period when these events took place, I had just returned from a scientific research in the disagreeable territory of Nebraska, in the United States. In virtue of my office as Assistant Professor in the Museum of Natural History in Paris, the French Government had attached me to that expedition. After six months in Nebraska, I arrived in New York towards the end of March, laden with a precious collection. My departure for France was fixed for the first days in May. Meanwhile I was occupying myself in classifying my mineralogical, botanical, and zoological riches, when the accident happened to the Scotia. - -I was perfectly up in the subject which was the question of the day. How could I be otherwise? I had read and reread all the American and European papers without being any nearer a conclusion. This mystery puzzled me. Under the impossibility of forming an opinion, I jumped from one extreme to the other. That there really was something could not be doubted, and the incredulous were invited to put their finger on the wound of the Scotia. - -On my arrival at New York the question was at its height. The theory of the floating island, and the unapproachable sandbank, supported by minds little competent to form a judgment, was abandoned. And, indeed, unless this shoal had a machine in its stomach, how could it change its position with such astonishing rapidity? - -From the same cause, the idea of a floating hull of an enormous wreck was given up. - -There remained, then, only two possible solutions of the question, which created two distinct parties: on one side, those who were for a monster of colossal strength; on the other, those who were for a submarine vessel of enormous motive power. - -But this last theory, plausible as it was, could not stand against inquiries made in both worlds. That a private gentleman should have such a machine at his command was not likely. Where, when, and how was it built? and how could its construction have been kept secret? Certainly a Government might possess such a destructive machine. And in these disastrous times, when the ingenuity of man has multiplied the power of weapons of war, it was possible that, without the knowledge of others, a State might try to work such a formidable engine. - -But the idea of a war machine fell before the declaration of Governments. As public interest was in question, and transatlantic communications suffered, their veracity could not be doubted. But how admit that the construction of this submarine boat had escaped the public eye? For a private gentleman to keep the secret under such circumstances would be very difficult, and for a State whose every act is persistently watched by powerful rivals, certainly impossible. - -Upon my arrival in New York several persons did me the honour of consulting me on the phenomenon in question. I had published in France a work in quarto, in two volumes, entitled Mysteries of the Great Submarine Grounds. This book, highly approved of in the learned world, gained for me a special reputation in this rather obscure branch of Natural History. My advice was asked. As long as I could deny the reality of the fact, I confined myself to a decided negative. But soon, finding myself driven into a corner, I was obliged to explain myself point by point. I discussed the question in all its forms, politically and scientifically; and I give here an extract from a carefully-studied article which I published in the number of the 30th of April. It ran as follows: - -"After examining one by one the different theories, rejecting all other suggestions, it becomes necessary to admit the existence of a marine animal of enormous power. - -"The great depths of the ocean are entirely unknown to us. Soundings cannot reach them. What passes in those remote depths—what beings live, or can live, twelve or fifteen miles beneath the surface of the waters—what is the organisation of these animals, we can scarcely conjecture. However, the solution of the problem submitted to me may modify the form of the dilemma. Either we do know all the varieties of beings which people our planet, or we do not. If we do NOT know them all—if Nature has still secrets in the deeps for us, nothing is more conformable to reason than to admit the existence of fishes, or cetaceans of other kinds, or even of new species, of an organisation formed to inhabit the strata inaccessible to soundings, and which an accident of some sort has brought at long intervals to the upper level of the ocean. - -"If, on the contrary, we DO know all living kinds, we must necessarily seek for the animal in question amongst those marine beings already classed; and, in that case, I should be disposed to admit the existence of a gigantic narwhal. - -"The common narwhal, or unicorn of the sea, often attains a length of sixty feet. Increase its size fivefold or tenfold, give it strength proportionate to its size, lengthen its destructive weapons, and you obtain the animal required. It will have the proportions determined by the officers of the Shannon, the instrument required by the perforation of the Scotia, and the power necessary to pierce the hull of the steamer. - -"Indeed, the narwhal is armed with a sort of ivory sword, a halberd, according to the expression of certain naturalists. The principal tusk has the hardness of steel. Some of these tusks have been found buried in the bodies of whales, which the unicorn always attacks with success. Others have been drawn out, not without trouble, from the bottoms of ships, which they had pierced through and through, as a gimlet pierces a barrel. The Museum of the Faculty of Medicine of Paris possesses one of these defensive weapons, two yards and a quarter in length, and fifteen inches in diameter at the base. - -"Very well! suppose this weapon to be six times stronger and the animal ten times more powerful; launch it at the rate of twenty miles an hour, and you obtain a shock capable of producing the catastrophe required. Until further information, therefore, I shall maintain it to be a sea-unicorn of colossal dimensions, armed not with a halberd, but with a real spur, as the armoured frigates, or the `rams' of war, whose massiveness and motive power it would possess at the same time. Thus may this puzzling phenomenon be explained, unless there be something over and above all that one has ever conjectured, seen, perceived, or experienced; which is just within the bounds of possibility." - -These last words were cowardly on my part; but, up to a certain point, I wished to shelter my dignity as professor, and not give too much cause for laughter to the Americans, who laugh well when they do laugh. I reserved for myself a way of escape. In effect, however, I admitted the existence of the "monster." My article was warmly discussed, which procured it a high reputation. It rallied round it a certain number of partisans. The solution it proposed gave, at least, full liberty to the imagination. The human mind delights in grand conceptions of supernatural beings. And the sea is precisely their best vehicle, the only medium through which these giants (against which terrestrial animals, such as elephants or rhinoceroses, are as nothing) can be produced or developed. - -The industrial and commercial papers treated the question chiefly from this point of view. The Shipping and Mercantile Gazette, the Lloyd's List, the Packet-Boat, and the Maritime and Colonial Review, all papers devoted to insurance companies which threatened to raise their rates of premium, were unanimous on this point. Public opinion had been pronounced. The United States were the first in the field; and in New York they made preparations for an expedition destined to pursue this narwhal. A frigate of great speed, the Abraham Lincoln, was put in commission as soon as possible. The arsenals were opened to Commander Farragut, who hastened the arming of his frigate; but, as it always happens, the moment it was decided to pursue the monster, the monster did not appear. For two months no one heard it spoken of. No ship met with it. It seemed as if this unicorn knew of the plots weaving around it. It had been so much talked of, even through the Atlantic cable, that jesters pretended that this slender fly had stopped a telegram on its passage and was making the most of it. - -So when the frigate had been armed for a long campaign, and provided with formidable fishing apparatus, no one could tell what course to pursue. Impatience grew apace, when, on the 2nd of July, they learned that a steamer of the line of San Francisco, from California to Shanghai, had seen the animal three weeks before in the North Pacific Ocean. The excitement caused by this news was extreme. The ship was revictualled and well stocked with coal. - -Three hours before the Abraham Lincoln left Brooklyn pier, I received a letter worded as follows: - -To M. ARONNAX, Professor in the Museum of Paris, Fifth Avenue Hotel, New York. - -SIR,—If you will consent to join the Abraham Lincoln in this expedition, the Government of the United States will with pleasure see France represented in the enterprise. Commander Farragut has a cabin at your disposal. - -Very cordially yours, J.B. HOBSON, Secretary of Marine. - - - - -CHAPTER III - -I FORM MY RESOLUTION - -Three seconds before the arrival of J. B. Hobson's letter I no more thought of pursuing the unicorn than of attempting the passage of the North Sea. Three seconds after reading the letter of the honourable Secretary of Marine, I felt that my true vocation, the sole end of my life, was to chase this disturbing monster and purge it from the world. - -But I had just returned from a fatiguing journey, weary and longing for repose. I aspired to nothing more than again seeing my country, my friends, my little lodging by the Jardin des Plantes, my dear and precious collections—but nothing could keep me back! I forgot all—fatigue, friends and collections—and accepted without hesitation the offer of the American Government. - -"Besides," thought I, "all roads lead back to Europe; and the unicorn may be amiable enough to hurry me towards the coast of France. This worthy animal may allow itself to be caught in the seas of Europe (for my particular benefit), and I will not bring back less than half a yard of his ivory halberd to the Museum of Natural History." But in the meanwhile I must seek this narwhal in the North Pacific Ocean, which, to return to France, was taking the road to the antipodes. - -"Conseil," I called in an impatient voice. - -Conseil was my servant, a true, devoted Flemish boy, who had accompanied me in all my travels. I liked him, and he returned the liking well. He was quiet by nature, regular from principle, zealous from habit, evincing little disturbance at the different surprises of life, very quick with his hands, and apt at any service required of him; and, despite his name, never giving advice—even when asked for it. - -Conseil had followed me for the last ten years wherever science led. Never once did he complain of the length or fatigue of a journey, never make an objection to pack his portmanteau for whatever country it might be, or however far away, whether China or Congo. Besides all this, he had good health, which defied all sickness, and solid muscles, but no nerves; good morals are understood. This boy was thirty years old, and his age to that of his master as fifteen to twenty. May I be excused for saying that I was forty years old? - -But Conseil had one fault: he was ceremonious to a degree, and would never speak to me but in the third person, which was sometimes provoking. - -"Conseil," said I again, beginning with feverish hands to make preparations for my departure. - -Certainly I was sure of this devoted boy. As a rule, I never asked him if it were convenient for him or not to follow me in my travels; but this time the expedition in question might be prolonged, and the enterprise might be hazardous in pursuit of an animal capable of sinking a frigate as easily as a nutshell. Here there was matter for reflection even to the most impassive man in the world. What would Conseil say? - -"Conseil," I called a third time. - -Conseil appeared. - -"Did you call, sir?" said he, entering. - -"Yes, my boy; make preparations for me and yourself too. We leave in two hours." - -"As you please, sir," replied Conseil, quietly. - -"Not an instant to lose; lock in my trunk all travelling utensils, coats, shirts, and stockings—without counting, as many as you can, and make haste." - -"And your collections, sir?" observed Conseil. - -"They will keep them at the hotel." - -"We are not returning to Paris, then?" said Conseil. - -"Oh! certainly," I answered, evasively, "by making a curve." - -"Will the curve please you, sir?" - -"Oh! it will be nothing; not quite so direct a road, that is all. We take our passage in the Abraham, Lincoln." - -"As you think proper, sir," coolly replied Conseil. - -"You see, my friend, it has to do with the monster—the famous narwhal. We are going to purge it from the seas. A glorious mission, but a dangerous one! We cannot tell where we may go; these animals can be very capricious. But we will go whether or no; we have got a captain who is pretty wide-awake." - -Our luggage was transported to the deck of the frigate immediately. I hastened on board and asked for Commander Farragut. One of the sailors conducted me to the poop, where I found myself in the presence of a good-looking officer, who held out his hand to me. - -"Monsieur Pierre Aronnax?" said he. - -"Himself," replied I. "Commander Farragut?" - -"You are welcome, Professor; your cabin is ready for you." - -I bowed, and desired to be conducted to the cabin destined for me. - -The Abraham Lincoln had been well chosen and equipped for her new destination. She was a frigate of great speed, fitted with high-pressure engines which admitted a pressure of seven atmospheres. Under this the Abraham Lincoln attained the mean speed of nearly eighteen knots and a third an hour—a considerable speed, but, nevertheless, insufficient to grapple with this gigantic cetacean. - -The interior arrangements of the frigate corresponded to its nautical qualities. I was well satisfied with my cabin, which was in the after part, opening upon the gunroom. - -"We shall be well off here," said I to Conseil. - -"As well, by your honour's leave, as a hermit-crab in the shell of a whelk," said Conseil. - -I left Conseil to stow our trunks conveniently away, and remounted the poop in order to survey the preparations for departure. - -At that moment Commander Farragut was ordering the last moorings to be cast loose which held the Abraham Lincoln to the pier of Brooklyn. So in a quarter of an hour, perhaps less, the frigate would have sailed without me. I should have missed this extraordinary, supernatural, and incredible expedition, the recital of which may well meet with some suspicion. - -But Commander Farragut would not lose a day nor an hour in scouring the seas in which the animal had been sighted. He sent for the engineer. - -"Is the steam full on?" asked he. - -"Yes, sir," replied the engineer. - -"Go ahead," cried Commander Farragut. - - - - -CHAPTER IV - -NED LAND - -Captain Farragut was a good seaman, worthy of the frigate he commanded. His vessel and he were one. He was the soul of it. On the question of the monster there was no doubt in his mind, and he would not allow the existence of the animal to be disputed on board. He believed in it, as certain good women believe in the leviathan—by faith, not by reason. The monster did exist, and he had sworn to rid the seas of it. Either Captain Farragut would kill the narwhal, or the narwhal would kill the captain. There was no third course. - -The officers on board shared the opinion of their chief. They were ever chatting, discussing, and calculating the various chances of a meeting, watching narrowly the vast surface of the ocean. More than one took up his quarters voluntarily in the cross-trees, who would have cursed such a berth under any other circumstances. As long as the sun described its daily course, the rigging was crowded with sailors, whose feet were burnt to such an extent by the heat of the deck as to render it unbearable; still the Abraham Lincoln had not yet breasted the suspected waters of the Pacific. As to the ship's company, they desired nothing better than to meet the unicorn, to harpoon it, hoist it on board, and despatch it. They watched the sea with eager attention. - -Besides, Captain Farragut had spoken of a certain sum of two thousand dollars, set apart for whoever should first sight the monster, were he cabin-boy, common seaman, or officer. - -I leave you to judge how eyes were used on board the Abraham Lincoln. - -For my own part I was not behind the others, and, left to no one my share of daily observations. The frigate might have been called the Argus, for a hundred reasons. Only one amongst us, Conseil, seemed to protest by his indifference against the question which so interested us all, and seemed to be out of keeping with the general enthusiasm on board. - -I have said that Captain Farragut had carefully provided his ship with every apparatus for catching the gigantic cetacean. No whaler had ever been better armed. We possessed every known engine, from the harpoon thrown by the hand to the barbed arrows of the blunderbuss, and the explosive balls of the duck-gun. On the forecastle lay the perfection of a breech-loading gun, very thick at the breech, and very narrow in the bore, the model of which had been in the Exhibition of 1867. This precious weapon of American origin could throw with ease a conical projectile of nine pounds to a mean distance of ten miles. - -Thus the Abraham Lincoln wanted for no means of destruction; and, what was better still she had on board Ned Land, the prince of harpooners. - -Ned Land was a Canadian, with an uncommon quickness of hand, and who knew no equal in his dangerous occupation. Skill, coolness, audacity, and cunning he possessed in a superior degree, and it must be a cunning whale to escape the stroke of his harpoon. - -Ned Land was about forty years of age; he was a tall man (more than six feet high), strongly built, grave and taciturn, occasionally violent, and very passionate when contradicted. His person attracted attention, but above all the boldness of his look, which gave a singular expression to his face. - -Who calls himself Canadian calls himself French; and, little communicative as Ned Land was, I must admit that he took a certain liking for me. My nationality drew him to me, no doubt. It was an opportunity for him to talk, and for me to hear, that old language of Rabelais, which is still in use in some Canadian provinces. The harpooner's family was originally from Quebec, and was already a tribe of hardy fishermen when this town belonged to France. - -Little by little, Ned Land acquired a taste for chatting, and I loved to hear the recital of his adventures in the polar seas. He related his fishing, and his combats, with natural poetry of expression; his recital took the form of an epic poem, and I seemed to be listening to a Canadian Homer singing the Iliad of the regions of the North. - -I am portraying this hardy companion as I really knew him. We are old friends now, united in that unchangeable friendship which is born and cemented amidst extreme dangers. Ah, brave Ned! I ask no more than to live a hundred years longer, that I may have more time to dwell the longer on your memory. - -Now, what was Ned Land's opinion upon the question of the marine monster? I must admit that he did not believe in the unicorn, and was the only one on board who did not share that universal conviction. He even avoided the subject, which I one day thought it my duty to press upon him. One magnificent evening, the 30th July (that is to say, three weeks after our departure), the frigate was abreast of Cape Blanc, thirty miles to leeward of the coast of Patagonia. We had crossed the tropic of Capricorn, and the Straits of Magellan opened less than seven hundred miles to the south. Before eight days were over the Abraham Lincoln would be ploughing the waters of the Pacific. - -Seated on the poop, Ned Land and I were chatting of one thing and another as we looked at this mysterious sea, whose great depths had up to this time been inaccessible to the eye of man. I naturally led up the conversation to the giant unicorn, and examined the various chances of success or failure of the expedition. But, seeing that Ned Land let me speak without saying too much himself, I pressed him more closely. - -"Well, Ned," said I, "is it possible that you are not convinced of the existence of this cetacean that we are following? Have you any particular reason for being so incredulous?" - -The harpooner looked at me fixedly for some moments before answering, struck his broad forehead with his hand (a habit of his), as if to collect himself, and said at last, "Perhaps I have, Mr. Aronnax." - -"But, Ned, you, a whaler by profession, familiarised with all the great marine mammalia—YOU ought to be the last to doubt under such circumstances!" - -"That is just what deceives you, Professor," replied Ned. "As a whaler I have followed many a cetacean, harpooned a great number, and killed several; but, however strong or well-armed they may have been, neither their tails nor their weapons would have been able even to scratch the iron plates of a steamer." - -"But, Ned, they tell of ships which the teeth of the narwhal have pierced through and through." - -"Wooden ships—that is possible," replied the Canadian, "but I have never seen it done; and, until further proof, I deny that whales, cetaceans, or sea-unicorns could ever produce the effect you describe." - -"Well, Ned, I repeat it with a conviction resting on the logic of facts. I believe in the existence of a mammal power fully organised, belonging to the branch of vertebrata, like the whales, the cachalots, or the dolphins, and furnished with a horn of defence of great penetrating power." - -"Hum!" said the harpooner, shaking his head with the air of a man who would not be convinced. - -"Notice one thing, my worthy Canadian," I resumed. "If such an animal is in existence, if it inhabits the depths of the ocean, if it frequents the strata lying miles below the surface of the water, it must necessarily possess an organisation the strength of which would defy all comparison." - -"And why this powerful organisation?" demanded Ned. - -"Because it requires incalculable strength to keep one's self in these strata and resist their pressure. Listen to me. Let us admit that the pressure of the atmosphere is represented by the weight of a column of water thirty-two feet high. In reality the column of water would be shorter, as we are speaking of sea water, the density of which is greater than that of fresh water. Very well, when you dive, Ned, as many times 32 feet of water as there are above you, so many times does your body bear a pressure equal to that of the atmosphere, that is to say, 15 lb. for each square inch of its surface. It follows, then, that at 320 feet this pressure equals that of 10 atmospheres, of 100 atmospheres at 3,200 feet, and of 1,000 atmospheres at 32,000 feet, that is, about 6 miles; which is equivalent to saying that if you could attain this depth in the ocean, each square three-eighths of an inch of the surface of your body would bear a pressure of 5,600 lb. Ah! my brave Ned, do you know how many square inches you carry on the surface of your body?" - -"I have no idea, Mr. Aronnax." - -"About 6,500; and as in reality the atmospheric pressure is about 15 lb. to the square inch, your 6,500 square inches bear at this moment a pressure of 97,500 lb." - -"Without my perceiving it?" - -"Without your perceiving it. And if you are not crushed by such a pressure, it is because the air penetrates the interior of your body with equal pressure. Hence perfect equilibrium between the interior and exterior pressure, which thus neutralise each other, and which allows you to bear it without inconvenience. But in the water it is another thing." - -"Yes, I understand," replied Ned, becoming more attentive; "because the water surrounds me, but does not penetrate." - -"Precisely, Ned: so that at 32 feet beneath the surface of the sea you would undergo a pressure of 97,500 lb.; at 320 feet, ten times that pressure; at 3,200 feet, a hundred times that pressure; lastly, at 32,000 feet, a thousand times that pressure would be 97,500,000 lb.—that is to say, that you would be flattened as if you had been drawn from the plates of a hydraulic machine!" - -"The devil!" exclaimed Ned. - -"Very well, my worthy harpooner, if some vertebrate, several hundred yards long, and large in proportion, can maintain itself in such depths—of those whose surface is represented by millions of square inches, that is by tens of millions of pounds, we must estimate the pressure they undergo. Consider, then, what must be the resistance of their bony structure, and the strength of their organisation to withstand such pressure!" - -"Why!" exclaimed Ned Land, "they must be made of iron plates eight inches thick, like the armoured frigates." - -"As you say, Ned. And think what destruction such a mass would cause, if hurled with the speed of an express train against the hull of a vessel." - -"Yes—certainly—perhaps," replied the Canadian, shaken by these figures, but not yet willing to give in. - -"Well, have I convinced you?" - -"You have convinced me of one thing, sir, which is that, if such animals do exist at the bottom of the seas, they must necessarily be as strong as you say." - -"But if they do not exist, mine obstinate harpooner, how explain the accident to the Scotia?" - - - - -CHAPTER V - -AT A VENTURE - -The voyage of the Abraham Lincoln was for a long time marked by no special incident. But one circumstance happened which showed the wonderful dexterity of Ned Land, and proved what confidence we might place in him. - -The 30th of June, the frigate spoke some American whalers, from whom we learned that they knew nothing about the narwhal. But one of them, the captain of the Monroe, knowing that Ned Land had shipped on board the Abraham Lincoln, begged for his help in chasing a whale they had in sight. Commander Farragut, desirous of seeing Ned Land at work, gave him permission to go on board the Monroe. And fate served our Canadian so well that, instead of one whale, he harpooned two with a double blow, striking one straight to the heart, and catching the other after some minutes' pursuit. - -Decidedly, if the monster ever had to do with Ned Land's harpoon, I would not bet in its favour. - -The frigate skirted the south-east coast of America with great rapidity. The 3rd of July we were at the opening of the Straits of Magellan, level with Cape Vierges. But Commander Farragut would not take a tortuous passage, but doubled Cape Horn. - -The ship's crew agreed with him. And certainly it was possible that they might meet the narwhal in this narrow pass. Many of the sailors affirmed that the monster could not pass there, "that he was too big for that!" - -The 6th of July, about three o'clock in the afternoon, the Abraham Lincoln, at fifteen miles to the south, doubled the solitary island, this lost rock at the extremity of the American continent, to which some Dutch sailors gave the name of their native town, Cape Horn. The course was taken towards the north-west, and the next day the screw of the frigate was at last beating the waters of the Pacific. - -"Keep your eyes open!" called out the sailors. - -And they were opened widely. Both eyes and glasses, a little dazzled, it is true, by the prospect of two thousand dollars, had not an instant's repose. - -I myself, for whom money had no charms, was not the least attentive on board. Giving but few minutes to my meals, but a few hours to sleep, indifferent to either rain or sunshine, I did not leave the poop of the vessel. Now leaning on the netting of the forecastle, now on the taffrail, I devoured with eagerness the soft foam which whitened the sea as far as the eye could reach; and how often have I shared the emotion of the majority of the crew, when some capricious whale raised its black back above the waves! The poop of the vessel was crowded on a moment. The cabins poured forth a torrent of sailors and officers, each with heaving breast and troubled eye watching the course of the cetacean. I looked and looked till I was nearly blind, whilst Conseil kept repeating in a calm voice: - -"If, sir, you would not squint so much, you would see better!" - -But vain excitement! The Abraham Lincoln checked its speed and made for the animal signalled, a simple whale, or common cachalot, which soon disappeared amidst a storm of abuse. - -But the weather was good. The voyage was being accomplished under the most favourable auspices. It was then the bad season in Australia, the July of that zone corresponding to our January in Europe, but the sea was beautiful and easily scanned round a vast circumference. - -The 20th of July, the tropic of Capricorn was cut by 105d of longitude, and the 27th of the same month we crossed the Equator on the 110th meridian. This passed, the frigate took a more decided westerly direction, and scoured the central waters of the Pacific. Commander Farragut thought, and with reason, that it was better to remain in deep water, and keep clear of continents or islands, which the beast itself seemed to shun (perhaps because there was not enough water for him! suggested the greater part of the crew). The frigate passed at some distance from the Marquesas and the Sandwich Islands, crossed the tropic of Cancer, and made for the China Seas. We were on the theatre of the last diversions of the monster: and, to say truth, we no longer LIVED on board. The entire ship's crew were undergoing a nervous excitement, of which I can give no idea: they could not eat, they could not sleep—twenty times a day, a misconception or an optical illusion of some sailor seated on the taffrail, would cause dreadful perspirations, and these emotions, twenty times repeated, kept us in a state of excitement so violent that a reaction was unavoidable. - -And truly, reaction soon showed itself. For three months, during which a day seemed an age, the Abraham Lincoln furrowed all the waters of the Northern Pacific, running at whales, making sharp deviations from her course, veering suddenly from one tack to another, stopping suddenly, putting on steam, and backing ever and anon at the risk of deranging her machinery, and not one point of the Japanese or American coast was left unexplored. - -The warmest partisans of the enterprise now became its most ardent detractors. Reaction mounted from the crew to the captain himself, and certainly, had it not been for the resolute determination on the part of Captain Farragut, the frigate would have headed due southward. This useless search could not last much longer. The Abraham Lincoln had nothing to reproach herself with, she had done her best to succeed. Never had an American ship's crew shown more zeal or patience; its failure could not be placed to their charge—there remained nothing but to return. - -This was represented to the commander. The sailors could not hide their discontent, and the service suffered. I will not say there was a mutiny on board, but after a reasonable period of obstinacy, Captain Farragut (as Columbus did) asked for three days' patience. If in three days the monster did not appear, the man at the helm should give three turns of the wheel, and the Abraham Lincoln would make for the European seas. - -This promise was made on the 2nd of November. It had the effect of rallying the ship's crew. The ocean was watched with renewed attention. Each one wished for a last glance in which to sum up his remembrance. Glasses were used with feverish activity. It was a grand defiance given to the giant narwhal, and he could scarcely fail to answer the summons and "appear." - -Two days passed, the steam was at half pressure; a thousand schemes were tried to attract the attention and stimulate the apathy of the animal in case it should be met in those parts. Large quantities of bacon were trailed in the wake of the ship, to the great satisfaction (I must say) of the sharks. Small craft radiated in all directions round the Abraham Lincoln as she lay to, and did not leave a spot of the sea unexplored. But the night of the 4th of November arrived without the unveiling of this submarine mystery. - -The next day, the 5th of November, at twelve, the delay would (morally speaking) expire; after that time, Commander Farragut, faithful to his promise, was to turn the course to the south-east and abandon for ever the northern regions of the Pacific. - -The frigate was then in 31° 15' N. lat. and 136° 42' E. long. The coast of Japan still remained less than two hundred miles to leeward. Night was approaching. They had just struck eight bells; large clouds veiled the face of the moon, then in its first quarter. The sea undulated peaceably under the stern of the vessel. - -At that moment I was leaning forward on the starboard netting. Conseil, standing near me, was looking straight before him. The crew, perched in the ratlines, examined the horizon which contracted and darkened by degrees. Officers with their night glasses scoured the growing darkness: sometimes the ocean sparkled under the rays of the moon, which darted between two clouds, then all trace of light was lost in the darkness. - -In looking at Conseil, I could see he was undergoing a little of the general influence. At least I thought so. Perhaps for the first time his nerves vibrated to a sentiment of curiosity. - -"Come, Conseil," said I, "this is the last chance of pocketing the two thousand dollars." - -"May I be permitted to say, sir," replied Conseil, "that I never reckoned on getting the prize; and, had the government of the Union offered a hundred thousand dollars, it would have been none the poorer." - -"You are right, Conseil. It is a foolish affair after all, and one upon which we entered too lightly. What time lost, what useless emotions! We should have been back in France six months ago." - -"In your little room, sir," replied Conseil, "and in your museum, sir; and I should have already classed all your fossils, sir. And the Babiroussa would have been installed in its cage in the Jardin des Plantes, and have drawn all the curious people of the capital!" - -"As you say, Conseil. I fancy we shall run a fair chance of being laughed at for our pains." - -"That's tolerably certain," replied Conseil, quietly; "I think they will make fun of you, sir. And, must I say it——?" - -"Go on, my good friend." - -"Well, sir, you will only get your deserts." - -"Indeed!" - -"When one has the honour of being a savant as you are, sir, one should not expose one's self to——" - -Conseil had not time to finish his compliment. In the midst of general silence a voice had just been heard. It was the voice of Ned Land shouting: - -"Look out there! The very thing we are looking for—on our weather beam!" - - - - -CHAPTER VI - -AT FULL STEAM - -At this cry the whole ship's crew hurried towards the harpooner—commander, officers, masters, sailors, cabin boys; even the engineers left their engines, and the stokers their furnaces. - -The order to stop her had been given, and the frigate now simply went on by her own momentum. The darkness was then profound, and, however good the Canadian's eyes were, I asked myself how he had managed to see, and what he had been able to see. My heart beat as if it would break. But Ned Land was not mistaken, and we all perceived the object he pointed to. At two cables' length from the Abraham Lincoln, on the starboard quarter, the sea seemed to be illuminated all over. It was not a mere phosphoric phenomenon. The monster emerged some fathoms from the water, and then threw out that very intense but mysterious light mentioned in the report of several captains. This magnificent irradiation must have been produced by an agent of great SHINING power. The luminous part traced on the sea an immense oval, much elongated, the centre of which condensed a burning heat, whose overpowering brilliancy died out by successive gradations. - -"It is only a massing of phosphoric particles," cried one of the officers. - -"No, sir, certainly not," I replied. "That brightness is of an essentially electrical nature. Besides, see, see! it moves; it is moving forwards, backwards; it is darting towards us!" - -A general cry arose from the frigate. - -"Silence!" said the captain. "Up with the helm, reverse the engines." - -The steam was shut off, and the Abraham Lincoln, beating to port, described a semicircle. - -"Right the helm, go ahead," cried the captain. - -These orders were executed, and the frigate moved rapidly from the burning light. - -I was mistaken. She tried to sheer off, but the supernatural animal approached with a velocity double her own. - -We gasped for breath. Stupefaction more than fear made us dumb and motionless. The animal gained on us, sporting with the waves. It made the round of the frigate, which was then making fourteen knots, and enveloped it with its electric rings like luminous dust. - -Then it moved away two or three miles, leaving a phosphorescent track, like those volumes of steam that the express trains leave behind. All at once from the dark line of the horizon whither it retired to gain its momentum, the monster rushed suddenly towards the Abraham Lincoln with alarming rapidity, stopped suddenly about twenty feet from the hull, and died out—not diving under the water, for its brilliancy did not abate—but suddenly, and as if the source of this brilliant emanation was exhausted. Then it reappeared on the other side of the vessel, as if it had turned and slid under the hull. Any moment a collision might have occurred which would have been fatal to us. However, I was astonished at the manoeuvres of the frigate. She fled and did not attack. - -On the captain's face, generally so impassive, was an expression of unaccountable astonishment. - -"Mr. Aronnax," he said, "I do not know with what formidable being I have to deal, and I will not imprudently risk my frigate in the midst of this darkness. Besides, how attack this unknown thing, how defend one's self from it? Wait for daylight, and the scene will change." - -"You have no further doubt, captain, of the nature of the animal?" - -"No, sir; it is evidently a gigantic narwhal, and an electric one." - -"Perhaps," added I, "one can only approach it with a torpedo." - -"Undoubtedly," replied the captain, "if it possesses such dreadful power, it is the most terrible animal that ever was created. That is why, sir, I must be on my guard." - -The crew were on their feet all night. No one thought of sleep. The Abraham Lincoln, not being able to struggle with such velocity, had moderated its pace, and sailed at half speed. For its part, the narwhal, imitating the frigate, let the waves rock it at will, and seemed decided not to leave the scene of the struggle. Towards midnight, however, it disappeared, or, to use a more appropriate term, it "died out" like a large glow-worm. Had it fled? One could only fear, not hope it. But at seven minutes to one o'clock in the morning a deafening whistling was heard, like that produced by a body of water rushing with great violence. - -The captain, Ned Land, and I were then on the poop, eagerly peering through the profound darkness. - -"Ned Land," asked the commander, "you have often heard the roaring of whales?" - -"Often, sir; but never such whales the sight of which brought me in two thousand dollars. If I can only approach within four harpoons' length of it!" - -"But to approach it," said the commander, "I ought to put a whaler at your disposal?" - -"Certainly, sir." - -"That will be trifling with the lives of my men." - -"And mine too," simply said the harpooner. - -Towards two o'clock in the morning, the burning light reappeared, not less intense, about five miles to windward of the Abraham Lincoln. Notwithstanding the distance, and the noise of the wind and sea, one heard distinctly the loud strokes of the animal's tail, and even its panting breath. It seemed that, at the moment that the enormous narwhal had come to take breath at the surface of the water, the air was engulfed in its lungs, like the steam in the vast cylinders of a machine of two thousand horse-power. - -"Hum!" thought I, "a whale with the strength of a cavalry regiment would be a pretty whale!" - -We were on the qui vive till daylight, and prepared for the combat. The fishing implements were laid along the hammock nettings. The second lieutenant loaded the blunder busses, which could throw harpoons to the distance of a mile, and long duck-guns, with explosive bullets, which inflicted mortal wounds even to the most terrible animals. Ned Land contented himself with sharpening his harpoon—a terrible weapon in his hands. - -At six o'clock day began to break; and, with the first glimmer of light, the electric light of the narwhal disappeared. At seven o'clock the day was sufficiently advanced, but a very thick sea fog obscured our view, and the best spy glasses could not pierce it. That caused disappointment and anger. - -I climbed the mizzen-mast. Some officers were already perched on the mast-heads. At eight o'clock the fog lay heavily on the waves, and its thick scrolls rose little by little. The horizon grew wider and clearer at the same time. Suddenly, just as on the day before, Ned Land's voice was heard: - -"The thing itself on the port quarter!" cried the harpooner. - -Every eye was turned towards the point indicated. There, a mile and a half from the frigate, a long blackish body emerged a yard above the waves. Its tail, violently agitated, produced a considerable eddy. Never did a tail beat the sea with such violence. An immense track, of dazzling whiteness, marked the passage of the animal, and described a long curve. - -The frigate approached the cetacean. I examined it thoroughly. - -The reports of the Shannon and of the Helvetia had rather exaggerated its size, and I estimated its length at only two hundred and fifty feet. As to its dimensions, I could only conjecture them to be admirably proportioned. While I watched this phenomenon, two jets of steam and water were ejected from its vents, and rose to the height of 120 feet; thus I ascertained its way of breathing. I concluded definitely that it belonged to the vertebrate branch, class mammalia. - -The crew waited impatiently for their chief's orders. The latter, after having observed the animal attentively, called the engineer. The engineer ran to him. - -"Sir," said the commander, "you have steam up?" - -"Yes, sir," answered the engineer. - -"Well, make up your fires and put on all steam." - -Three hurrahs greeted this order. The time for the struggle had arrived. Some moments after, the two funnels of the frigate vomited torrents of black smoke, and the bridge quaked under the trembling of the boilers. - -The Abraham Lincoln, propelled by her wonderful screw, went straight at the animal. The latter allowed it to come within half a cable's length; then, as if disdaining to dive, it took a little turn, and stopped a short distance off. - -This pursuit lasted nearly three-quarters of an hour, without the frigate gaining two yards on the cetacean. It was quite evident that at that rate we should never come up with it. - -"Well, Mr. Land," asked the captain, "do you advise me to put the boats out to sea?" - -"No, sir," replied Ned Land; "because we shall not take that beast easily." - -"What shall we do then?" - -"Put on more steam if you can, sir. With your leave, I mean to post myself under the bowsprit, and, if we get within harpooning distance, I shall throw my harpoon." - -"Go, Ned," said the captain. "Engineer, put on more pressure." - -Ned Land went to his post. The fires were increased, the screw revolved forty-three times a minute, and the steam poured out of the valves. We heaved the log, and calculated that the Abraham Lincoln was going at the rate of 18 1/2 miles an hour. - -But the accursed animal swam at the same speed. - -For a whole hour the frigate kept up this pace, without gaining six feet. It was humiliating for one of the swiftest sailers in the American navy. A stubborn anger seized the crew; the sailors abused the monster, who, as before, disdained to answer them; the captain no longer contented himself with twisting his beard—he gnawed it. - -The engineer was called again. - -"You have turned full steam on?" - -"Yes, sir," replied the engineer. - -The speed of the Abraham Lincoln increased. Its masts trembled down to their stepping holes, and the clouds of smoke could hardly find way out of the narrow funnels. - -They heaved the log a second time. - -"Well?" asked the captain of the man at the wheel. - -"Nineteen miles and three-tenths, sir." - -"Clap on more steam." - -The engineer obeyed. The manometer showed ten degrees. But the cetacean grew warm itself, no doubt; for without straining itself, it made 19 3/10 miles. - -What a pursuit! No, I cannot describe the emotion that vibrated through me. Ned Land kept his post, harpoon in hand. Several times the animal let us gain upon it.—"We shall catch it! we shall catch it!" cried the Canadian. But just as he was going to strike, the cetacean stole away with a rapidity that could not be estimated at less than thirty miles an hour, and even during our maximum of speed, it bullied the frigate, going round and round it. A cry of fury broke from everyone! - -At noon we were no further advanced than at eight o'clock in the morning. - -The captain then decided to take more direct means. - -"Ah!" said he, "that animal goes quicker than the Abraham Lincoln. Very well! we will see whether it will escape these conical bullets. Send your men to the forecastle, sir." - -The forecastle gun was immediately loaded and slewed round. But the shot passed some feet above the cetacean, which was half a mile off. - -"Another, more to the right," cried the commander, "and five dollars to whoever will hit that infernal beast." - -An old gunner with a grey beard—that I can see now—with steady eye and grave face, went up to the gun and took a long aim. A loud report was heard, with which were mingled the cheers of the crew. - -The bullet did its work; it hit the animal, and, sliding off the rounded surface, was lost in two miles depth of sea. - -The chase began again, and the captain, leaning towards me, said: - -"I will pursue that beast till my frigate bursts up." - -"Yes," answered I; "and you will be quite right to do it." - -I wished the beast would exhaust itself, and not be insensible to fatigue like a steam engine. But it was of no use. Hours passed, without its showing any signs of exhaustion. - -However, it must be said in praise of the Abraham Lincoln that she struggled on indefatigably. I cannot reckon the distance she made under three hundred miles during this unlucky day, November the 6th. But night came on, and overshadowed the rough ocean. - -Now I thought our expedition was at an end, and that we should never again see the extraordinary animal. I was mistaken. At ten minutes to eleven in the evening, the electric light reappeared three miles to windward of the frigate, as pure, as intense as during the preceding night. - -The narwhal seemed motionless; perhaps, tired with its day's work, it slept, letting itself float with the undulation of the waves. Now was a chance of which the captain resolved to take advantage. - -He gave his orders. The Abraham Lincoln kept up half steam, and advanced cautiously so as not to awake its adversary. It is no rare thing to meet in the middle of the ocean whales so sound asleep that they can be successfully attacked, and Ned Land had harpooned more than one during its sleep. The Canadian went to take his place again under the bowsprit. - -The frigate approached noiselessly, stopped at two cables' lengths from the animal, and following its track. No one breathed; a deep silence reigned on the bridge. We were not a hundred feet from the burning focus, the light of which increased and dazzled our eyes. - -At this moment, leaning on the forecastle bulwark, I saw below me Ned Land grappling the martingale in one hand, brandishing his terrible harpoon in the other, scarcely twenty feet from the motionless animal. Suddenly his arm straightened, and the harpoon was thrown; I heard the sonorous stroke of the weapon, which seemed to have struck a hard body. The electric light went out suddenly, and two enormous waterspouts broke over the bridge of the frigate, rushing like a torrent from stem to stern, overthrowing men, and breaking the lashings of the spars. A fearful shock followed, and, thrown over the rail without having time to stop myself, I fell into the sea. - - - - -CHAPTER VII - -AN UNKNOWN SPECIES OF WHALE - -This unexpected fall so stunned me that I have no clear recollection of my sensations at the time. I was at first drawn down to a depth of about twenty feet. I am a good swimmer (though without pretending to rival Byron or Edgar Poe, who were masters of the art), and in that plunge I did not lose my presence of mind. Two vigorous strokes brought me to the surface of the water. My first care was to look for the frigate. Had the crew seen me disappear? Had the Abraham Lincoln veered round? Would the captain put out a boat? Might I hope to be saved? - -The darkness was intense. I caught a glimpse of a black mass disappearing in the east, its beacon lights dying out in the distance. It was the frigate! I was lost. - -"Help, help!" I shouted, swimming towards the Abraham Lincoln in desperation. - -My clothes encumbered me; they seemed glued to my body, and paralysed my movements. - -I was sinking! I was suffocating! - -"Help!" - -This was my last cry. My mouth filled with water; I struggled against being drawn down the abyss. Suddenly my clothes were seized by a strong hand, and I felt myself quickly drawn up to the surface of the sea; and I heard, yes, I heard these words pronounced in my ear: - -"If master would be so good as to lean on my shoulder, master would swim with much greater ease." - -I seized with one hand my faithful Conseil's arm. - -"Is it you?" said I, "you?" - -"Myself," answered Conseil; "and waiting master's orders." - -"That shock threw you as well as me into the sea?" - -"No; but, being in my master's service, I followed him." - -The worthy fellow thought that was but natural. - -"And the frigate?" I asked. - -"The frigate?" replied Conseil, turning on his back; "I think that master had better not count too much on her." - -"You think so?" - -"I say that, at the time I threw myself into the sea, I heard the men at the wheel say, `The screw and the rudder are broken.' - -"Broken?" - -"Yes, broken by the monster's teeth. It is the only injury the Abraham Lincoln has sustained. But it is a bad look-out for us—she no longer answers her helm." - -"Then we are lost!" - -"Perhaps so," calmly answered Conseil. "However, we have still several hours before us, and one can do a good deal in some hours." - -Conseil's imperturbable coolness set me up again. I swam more vigorously; but, cramped by my clothes, which stuck to me like a leaden weight, I felt great difficulty in bearing up. Conseil saw this. - -"Will master let me make a slit?" said he; and, slipping an open knife under my clothes, he ripped them up from top to bottom very rapidly. Then he cleverly slipped them off me, while I swam for both of us. - -Then I did the same for Conseil, and we continued to swim near to each other. - -Nevertheless, our situation was no less terrible. Perhaps our disappearance had not been noticed; and, if it had been, the frigate could not tack, being without its helm. Conseil argued on this supposition, and laid his plans accordingly. This quiet boy was perfectly self-possessed. We then decided that, as our only chance of safety was being picked up by the Abraham Lincoln's boats, we ought to manage so as to wait for them as long as possible. I resolved then to husband our strength, so that both should not be exhausted at the same time; and this is how we managed: while one of us lay on our back, quite still, with arms crossed, and legs stretched out, the other would swim and push the other on in front. This towing business did not last more than ten minutes each; and relieving each other thus, we could swim on for some hours, perhaps till day-break. Poor chance! but hope is so firmly rooted in the heart of man! Moreover, there were two of us. Indeed I declare (though it may seem improbable) if I sought to destroy all hope—if I wished to despair, I could not. - -The collision of the frigate with the cetacean had occurred about eleven o'clock in the evening before. I reckoned then we should have eight hours to swim before sunrise, an operation quite practicable if we relieved each other. The sea, very calm, was in our favour. Sometimes I tried to pierce the intense darkness that was only dispelled by the phosphorescence caused by our movements. I watched the luminous waves that broke over my hand, whose mirror-like surface was spotted with silvery rings. One might have said that we were in a bath of quicksilver. - -Near one o'clock in the morning, I was seized with dreadful fatigue. My limbs stiffened under the strain of violent cramp. Conseil was obliged to keep me up, and our preservation devolved on him alone. I heard the poor boy pant; his breathing became short and hurried. I found that he could not keep up much longer. - -"Leave me! leave me!" I said to him. - -"Leave my master? Never!" replied he. "I would drown first." - -Just then the moon appeared through the fringes of a thick cloud that the wind was driving to the east. The surface of the sea glittered with its rays. This kindly light reanimated us. My head got better again. I looked at all points of the horizon. I saw the frigate! She was five miles from us, and looked like a dark mass, hardly discernible. But no boats! - -I would have cried out. But what good would it have been at such a distance! My swollen lips could utter no sounds. Conseil could articulate some words, and I heard him repeat at intervals, "Help! help!" - -Our movements were suspended for an instant; we listened. It might be only a singing in the ear, but it seemed to me as if a cry answered the cry from Conseil. - -"Did you hear?" I murmured. - -"Yes! Yes!" - -And Conseil gave one more despairing cry. - -This time there was no mistake! A human voice responded to ours! Was it the voice of another unfortunate creature, abandoned in the middle of the ocean, some other victim of the shock sustained by the vessel? Or rather was it a boat from the frigate, that was hailing us in the darkness? - -Conseil made a last effort, and, leaning on my shoulder, while I struck out in a desperate effort, he raised himself half out of the water, then fell back exhausted. - -"What did you see?" - -"I saw——" murmured he; "I saw—but do not talk—reserve all your strength!" - -What had he seen? Then, I know not why, the thought of the monster came into my head for the first time! But that voice! The time is past for Jonahs to take refuge in whales' bellies! However, Conseil was towing me again. He raised his head sometimes, looked before us, and uttered a cry of recognition, which was responded to by a voice that came nearer and nearer. I scarcely heard it. My strength was exhausted; my fingers stiffened; my hand afforded me support no longer; my mouth, convulsively opening, filled with salt water. Cold crept over me. I raised my head for the last time, then I sank. - -At this moment a hard body struck me. I clung to it: then I felt that I was being drawn up, that I was brought to the surface of the water, that my chest collapsed—I fainted. - -It is certain that I soon came to, thanks to the vigorous rubbings that I received. I half opened my eyes. - -"Conseil!" I murmured. - -"Does master call me?" asked Conseil. - -Just then, by the waning light of the moon which was sinking down to the horizon, I saw a face which was not Conseil's and which I immediately recognised. - -"Ned!" I cried. - -"The same, sir, who is seeking his prize!" replied the Canadian. - -"Were you thrown into the sea by the shock to the frigate?" - -"Yes, Professor; but more fortunate than you, I was able to find a footing almost directly upon a floating island." - -"An island?" - -"Or, more correctly speaking, on our gigantic narwhal." - -"Explain yourself, Ned!" - -"Only I soon found out why my harpoon had not entered its skin and was blunted." - -"Why, Ned, why?" - -"Because, Professor, that beast is made of sheet iron." - -The Canadian's last words produced a sudden revolution in my brain. I wriggled myself quickly to the top of the being, or object, half out of the water, which served us for a refuge. I kicked it. It was evidently a hard, impenetrable body, and not the soft substance that forms the bodies of the great marine mammalia. But this hard body might be a bony covering, like that of the antediluvian animals; and I should be free to class this monster among amphibious reptiles, such as tortoises or alligators. - -Well, no! the blackish back that supported me was smooth, polished, without scales. The blow produced a metallic sound; and, incredible though it may be, it seemed, I might say, as if it was made of riveted plates. - -There was no doubt about it! This monster, this natural phenomenon that had puzzled the learned world, and over thrown and misled the imagination of seamen of both hemispheres, it must be owned was a still more astonishing phenomenon, inasmuch as it was a simply human construction. - -We had no time to lose, however. We were lying upon the back of a sort of submarine boat, which appeared (as far as I could judge) like a huge fish of steel. Ned Land's mind was made up on this point. Conseil and I could only agree with him. - -Just then a bubbling began at the back of this strange thing (which was evidently propelled by a screw), and it began to move. We had only just time to seize hold of the upper part, which rose about seven feet out of the water, and happily its speed was not great. - -"As long as it sails horizontally," muttered Ned Land, "I do not mind; but, if it takes a fancy to dive, I would not give two straws for my life." - -The Canadian might have said still less. It became really necessary to communicate with the beings, whatever they were, shut up inside the machine. I searched all over the outside for an aperture, a panel, or a manhole, to use a technical expression; but the lines of the iron rivets, solidly driven into the joints of the iron plates, were clear and uniform. Besides, the moon disappeared then, and left us in total darkness. - -At last this long night passed. My indistinct remembrance prevents my describing all the impressions it made. I can only recall one circumstance. During some lulls of the wind and sea, I fancied I heard several times vague sounds, a sort of fugitive harmony produced by words of command. What was, then, the mystery of this submarine craft, of which the whole world vainly sought an explanation? What kind of beings existed in this strange boat? What mechanical agent caused its prodigious speed? - -Daybreak appeared. The morning mists surrounded us, but they soon cleared off. I was about to examine the hull, which formed on deck a kind of horizontal platform, when I felt it gradually sinking. - -"Oh! confound it!" cried Ned Land, kicking the resounding plate. "Open, you inhospitable rascals!" - -Happily the sinking movement ceased. Suddenly a noise, like iron works violently pushed aside, came from the interior of the boat. One iron plate was moved, a man appeared, uttered an odd cry, and disappeared immediately. - -Some moments after, eight strong men, with masked faces, appeared noiselessly, and drew us down into their formidable machine. - - - - -CHAPTER VIII - -MOBILIS IN MOBILI - -This forcible abduction, so roughly carried out, was accomplished with the rapidity of lightning. I shivered all over. Whom had we to deal with? No doubt some new sort of pirates, who explored the sea in their own way. Hardly had the narrow panel closed upon me, when I was enveloped in darkness. My eyes, dazzled with the outer light, could distinguish nothing. I felt my naked feet cling to the rungs of an iron ladder. Ned Land and Conseil, firmly seized, followed me. At the bottom of the ladder, a door opened, and shut after us immediately with a bang. - -We were alone. Where, I could not say, hardly imagine. All was black, and such a dense black that, after some minutes, my eyes had not been able to discern even the faintest glimmer. - -Meanwhile, Ned Land, furious at these proceedings, gave free vent to his indignation. - -"Confound it!" cried he, "here are people who come up to the Scotch for hospitality. They only just miss being cannibals. I should not be surprised at it, but I declare that they shall not eat me without my protesting." - -"Calm yourself, friend Ned, calm yourself," replied Conseil, quietly. "Do not cry out before you are hurt. We are not quite done for yet." - -"Not quite," sharply replied the Canadian, "but pretty near, at all events. Things look black. Happily, my bowie knife I have still, and I can always see well enough to use it. The first of these pirates who lays a hand on me——" - -"Do not excite yourself, Ned," I said to the harpooner, "and do not compromise us by useless violence. Who knows that they will not listen to us? Let us rather try to find out where we are." - -I groped about. In five steps I came to an iron wall, made of plates bolted together. Then turning back I struck against a wooden table, near which were ranged several stools. The boards of this prison were concealed under a thick mat, which deadened the noise of the feet. The bare walls revealed no trace of window or door. Conseil, going round the reverse way, met me, and we went back to the middle of the cabin, which measured about twenty feet by ten. As to its height, Ned Land, in spite of his own great height, could not measure it. - -Half an hour had already passed without our situation being bettered, when the dense darkness suddenly gave way to extreme light. Our prison was suddenly lighted, that is to say, it became filled with a luminous matter, so strong that I could not bear it at first. In its whiteness and intensity I recognised that electric light which played round the submarine boat like a magnificent phenomenon of phosphorescence. After shutting my eyes involuntarily, I opened them, and saw that this luminous agent came from a half globe, unpolished, placed in the roof of the cabin. - -"At last one can see," cried Ned Land, who, knife in hand, stood on the defensive. - -"Yes," said I; "but we are still in the dark about ourselves." - -"Let master have patience," said the imperturbable Conseil. - -The sudden lighting of the cabin enabled me to examine it minutely. It only contained a table and five stools. The invisible door might be hermetically sealed. No noise was heard. All seemed dead in the interior of this boat. Did it move, did it float on the surface of the ocean, or did it dive into its depths? I could not guess. - -A noise of bolts was now heard, the door opened, and two men appeared. - -One was short, very muscular, broad-shouldered, with robust limbs, strong head, an abundance of black hair, thick moustache, a quick penetrating look, and the vivacity which characterises the population of Southern France. - -The second stranger merits a more detailed description. I made out his prevailing qualities directly: self-confidence—because his head was well set on his shoulders, and his black eyes looked around with cold assurance; calmness—for his skin, rather pale, showed his coolness of blood; energy—evinced by the rapid contraction of his lofty brows; and courage—because his deep breathing denoted great power of lungs. - -Whether this person was thirty-five or fifty years of age, I could not say. He was tall, had a large forehead, straight nose, a clearly cut mouth, beautiful teeth, with fine taper hands, indicative of a highly nervous temperament. This man was certainly the most admirable specimen I had ever met. One particular feature was his eyes, rather far from each other, and which could take in nearly a quarter of the horizon at once. - -This faculty—(I verified it later)—gave him a range of vision far superior to Ned Land's. When this stranger fixed upon an object, his eyebrows met, his large eyelids closed around so as to contract the range of his vision, and he looked as if he magnified the objects lessened by distance, as if he pierced those sheets of water so opaque to our eyes, and as if he read the very depths of the seas. - -The two strangers, with caps made from the fur of the sea otter, and shod with sea boots of seal's skin, were dressed in clothes of a particular texture, which allowed free movement of the limbs. The taller of the two, evidently the chief on board, examined us with great attention, without saying a word; then, turning to his companion, talked with him in an unknown tongue. It was a sonorous, harmonious, and flexible dialect, the vowels seeming to admit of very varied accentuation. - -The other replied by a shake of the head, and added two or three perfectly incomprehensible words. Then he seemed to question me by a look. - -I replied in good French that I did not know his language; but he seemed not to understand me, and my situation became more embarrassing. - -"If master were to tell our story," said Conseil, "perhaps these gentlemen may understand some words." - -I began to tell our adventures, articulating each syllable clearly, and without omitting one single detail. I announced our names and rank, introducing in person Professor Aronnax, his servant Conseil, and master Ned Land, the harpooner. - -The man with the soft calm eyes listened to me quietly, even politely, and with extreme attention; but nothing in his countenance indicated that he had understood my story. When I finished, he said not a word. - -There remained one resource, to speak English. Perhaps they would know this almost universal language. I knew it—as well as the German language—well enough to read it fluently, but not to speak it correctly. But, anyhow, we must make ourselves understood. - -"Go on in your turn," I said to the harpooner; "speak your best Anglo-Saxon, and try to do better than I." - -Ned did not beg off, and recommenced our story. - -To his great disgust, the harpooner did not seem to have made himself more intelligible than I had. Our visitors did not stir. They evidently understood neither the language of England nor of France. - -Very much embarrassed, after having vainly exhausted our speaking resources, I knew not what part to take, when Conseil said: - -"If master will permit me, I will relate it in German." - -But in spite of the elegant terms and good accent of the narrator, the German language had no success. At last, nonplussed, I tried to remember my first lessons, and to narrate our adventures in Latin, but with no better success. This last attempt being of no avail, the two strangers exchanged some words in their unknown language, and retired. - -The door shut. - -"It is an infamous shame," cried Ned Land, who broke out for the twentieth time. "We speak to those rogues in French, English, German, and Latin, and not one of them has the politeness to answer!" - -"Calm yourself," I said to the impetuous Ned; "anger will do no good." - -"But do you see, Professor," replied our irascible companion, "that we shall absolutely die of hunger in this iron cage?" - -"Bah!" said Conseil, philosophically; "we can hold out some time yet." - -"My friends," I said, "we must not despair. We have been worse off than this. Do me the favour to wait a little before forming an opinion upon the commander and crew of this boat." - -"My opinion is formed," replied Ned Land, sharply. "They are rascals." - -"Good! and from what country?" - -"From the land of rogues!" - -"My brave Ned, that country is not clearly indicated on the map of the world; but I admit that the nationality of the two strangers is hard to determine. Neither English, French, nor German, that is quite certain. However, I am inclined to think that the commander and his companion were born in low latitudes. There is southern blood in them. But I cannot decide by their appearance whether they are Spaniards, Turks, Arabians, or Indians. As to their language, it is quite incomprehensible." - -"There is the disadvantage of not knowing all languages," said Conseil, "or the disadvantage of not having one universal language." - -As he said these words, the door opened. A steward entered. He brought us clothes, coats and trousers, made of a stuff I did not know. I hastened to dress myself, and my companions followed my example. During that time, the steward—dumb, perhaps deaf—had arranged the table, and laid three plates. - -"This is something like!" said Conseil. - -"Bah!" said the angry harpooner, "what do you suppose they eat here? Tortoise liver, filleted shark, and beef steaks from seadogs." - -"We shall see," said Conseil. - -The dishes, of bell metal, were placed on the table, and we took our places. Undoubtedly we had to do with civilised people, and, had it not been for the electric light which flooded us, I could have fancied I was in the dining-room of the Adelphi Hotel at Liverpool, or at the Grand Hotel in Paris. I must say, however, that there was neither bread nor wine. The water was fresh and clear, but it was water and did not suit Ned Land's taste. Amongst the dishes which were brought to us, I recognised several fish delicately dressed; but of some, although excellent, I could give no opinion, neither could I tell to what kingdom they belonged, whether animal or vegetable. As to the dinner-service, it was elegant, and in perfect taste. Each utensil—spoon, fork, knife, plate—had a letter engraved on it, with a motto above it, of which this is an exact facsimile: - - -MOBILIS IN MOBILI N - -The letter N was no doubt the initial of the name of the enigmatical person who commanded at the bottom of the seas. - -Ned and Conseil did not reflect much. They devoured the food, and I did likewise. I was, besides, reassured as to our fate; and it seemed evident that our hosts would not let us die of want. - -However, everything has an end, everything passes away, even the hunger of people who have not eaten for fifteen hours. Our appetites satisfied, we felt overcome with sleep. - -"Faith! I shall sleep well," said Conseil. - -"So shall I," replied Ned Land. - -My two companions stretched themselves on the cabin carpet, and were soon sound asleep. For my own part, too many thoughts crowded my brain, too many insoluble questions pressed upon me, too many fancies kept my eyes half open. Where were we? What strange power carried us on? I felt—or rather fancied I felt—the machine sinking down to the lowest beds of the sea. Dreadful nightmares beset me; I saw in these mysterious asylums a world of unknown animals, amongst which this submarine boat seemed to be of the same kind, living, moving, and formidable as they. Then my brain grew calmer, my imagination wandered into vague unconsciousness, and I soon fell into a deep sleep. - - - - -CHAPTER IX - -NED LAND'S TEMPERS - -How long we slept I do not know; but our sleep must have lasted long, for it rested us completely from our fatigues. I woke first. My companions had not moved, and were still stretched in their corner. - -Hardly roused from my somewhat hard couch, I felt my brain freed, my mind clear. I then began an attentive examination of our cell. Nothing was changed inside. The prison was still a prison—the prisoners, prisoners. However, the steward, during our sleep, had cleared the table. I breathed with difficulty. The heavy air seemed to oppress my lungs. Although the cell was large, we had evidently consumed a great part of the oxygen that it contained. Indeed, each man consumes, in one hour, the oxygen contained in more than 176 pints of air, and this air, charged (as then) with a nearly equal quantity of carbonic acid, becomes unbreathable. - -It became necessary to renew the atmosphere of our prison, and no doubt the whole in the submarine boat. That gave rise to a question in my mind. How would the commander of this floating dwelling-place proceed? Would he obtain air by chemical means, in getting by heat the oxygen contained in chlorate of potash, and in absorbing carbonic acid by caustic potash? Or—a more convenient, economical, and consequently more probable alternative—would he be satisfied to rise and take breath at the surface of the water, like a whale, and so renew for twenty-four hours the atmospheric provision? - -In fact, I was already obliged to increase my respirations to eke out of this cell the little oxygen it contained, when suddenly I was refreshed by a current of pure air, and perfumed with saline emanations. It was an invigorating sea breeze, charged with iodine. I opened my mouth wide, and my lungs saturated themselves with fresh particles. - -At the same time I felt the boat rolling. The iron-plated monster had evidently just risen to the surface of the ocean to breathe, after the fashion of whales. I found out from that the mode of ventilating the boat. - -When I had inhaled this air freely, I sought the conduit pipe, which conveyed to us the beneficial whiff, and I was not long in finding it. Above the door was a ventilator, through which volumes of fresh air renewed the impoverished atmosphere of the cell. - -I was making my observations, when Ned and Conseil awoke almost at the same time, under the influence of this reviving air. They rubbed their eyes, stretched themselves, and were on their feet in an instant. - -"Did master sleep well?" asked Conseil, with his usual politeness. - -"Very well, my brave boy. And you, Mr. Land?" - -"Soundly, Professor. But, I don't know if I am right or not, there seems to be a sea breeze!" - -A seaman could not be mistaken, and I told the Canadian all that had passed during his sleep. - -"Good!" said he. "That accounts for those roarings we heard, when the supposed narwhal sighted the Abraham Lincoln." - -"Quite so, Master Land; it was taking breath." - -"Only, Mr. Aronnax, I have no idea what o'clock it is, unless it is dinner-time." - -"Dinner-time! my good fellow? Say rather breakfast-time, for we certainly have begun another day." - -"So," said Conseil, "we have slept twenty-four hours?" - -"That is my opinion." - -"I will not contradict you," replied Ned Land. "But, dinner or breakfast, the steward will be welcome, whichever he brings." - -"Master Land, we must conform to the rules on board, and I suppose our appetites are in advance of the dinner hour." - -"That is just like you, friend Conseil," said Ned, impatiently. "You are never out of temper, always calm; you would return thanks before grace, and die of hunger rather than complain!" - -Time was getting on, and we were fearfully hungry; and this time the steward did not appear. It was rather too long to leave us, if they really had good intentions towards us. Ned Land, tormented by the cravings of hunger, got still more angry; and, notwithstanding his promise, I dreaded an explosion when he found himself with one of the crew. - -For two hours more Ned Land's temper increased; he cried, he shouted, but in vain. The walls were deaf. There was no sound to be heard in the boat; all was still as death. It did not move, for I should have felt the trembling motion of the hull under the influence of the screw. Plunged in the depths of the waters, it belonged no longer to earth: this silence was dreadful. - -I felt terrified, Conseil was calm, Ned Land roared. - -Just then a noise was heard outside. Steps sounded on the metal flags. The locks were turned, the door opened, and the steward appeared. - -Before I could rush forward to stop him, the Canadian had thrown him down, and held him by the throat. The steward was choking under the grip of his powerful hand. - -Conseil was already trying to unclasp the harpooner's hand from his half-suffocated victim, and I was going to fly to the rescue, when suddenly I was nailed to the spot by hearing these words in French: - -"Be quiet, Master Land; and you, Professor, will you be so good as to listen to me?" - - - - -CHAPTER X - -THE MAN OF THE SEAS - -It was the commander of the vessel who thus spoke. - -At these words, Ned Land rose suddenly. The steward, nearly strangled, tottered out on a sign from his master. But such was the power of the commander on board, that not a gesture betrayed the resentment which this man must have felt towards the Canadian. Conseil interested in spite of himself, I stupefied, awaited in silence the result of this scene. - -The commander, leaning against the corner of a table with his arms folded, scanned us with profound attention. Did he hesitate to speak? Did he regret the words which he had just spoken in French? One might almost think so. - -After some moments of silence, which not one of us dreamed of breaking, "Gentlemen," said he, in a calm and penetrating voice, "I speak French, English, German, and Latin equally well. I could, therefore, have answered you at our first interview, but I wished to know you first, then to reflect. The story told by each one, entirely agreeing in the main points, convinced me of your identity. I know now that chance has brought before me M. Pierre Aronnax, Professor of Natural History at the Museum of Paris, entrusted with a scientific mission abroad, Conseil, his servant, and Ned Land, of Canadian origin, harpooner on board the frigate Abraham Lincoln of the navy of the United States of America." - -I bowed assent. It was not a question that the commander put to me. Therefore there was no answer to be made. This man expressed himself with perfect ease, without any accent. His sentences were well turned, his words clear, and his fluency of speech remarkable. Yet, I did not recognise in him a fellow-countryman. - -He continued the conversation in these terms: - -"You have doubtless thought, sir, that I have delayed long in paying you this second visit. The reason is that, your identity recognised, I wished to weigh maturely what part to act towards you. I have hesitated much. Most annoying circumstances have brought you into the presence of a man who has broken all the ties of humanity. You have come to trouble my existence." - -"Unintentionally!" said I. - -"Unintentionally?" replied the stranger, raising his voice a little. "Was it unintentionally that the Abraham Lincoln pursued me all over the seas? Was it unintentionally that you took passage in this frigate? Was it unintentionally that your cannon-balls rebounded off the plating of my vessel? Was it unintentionally that Mr. Ned Land struck me with his harpoon?" - -I detected a restrained irritation in these words. But to these recriminations I had a very natural answer to make, and I made it. - -"Sir," said I, "no doubt you are ignorant of the discussions which have taken place concerning you in America and Europe. You do not know that divers accidents, caused by collisions with your submarine machine, have excited public feeling in the two continents. I omit the theories without number by which it was sought to explain that of which you alone possess the secret. But you must understand that, in pursuing you over the high seas of the Pacific, the Abraham Lincoln believed itself to be chasing some powerful sea-monster, of which it was necessary to rid the ocean at any price." - -A half-smile curled the lips of the commander: then, in a calmer tone: - -"M. Aronnax," he replied, "dare you affirm that your frigate would not as soon have pursued and cannonaded a submarine boat as a monster?" - -This question embarrassed me, for certainly Captain Farragut might not have hesitated. He might have thought it his duty to destroy a contrivance of this kind, as he would a gigantic narwhal. - -"You understand then, sir," continued the stranger, "that I have the right to treat you as enemies?" - -I answered nothing, purposely. For what good would it be to discuss such a proposition, when force could destroy the best arguments? - -"I have hesitated some time," continued the commander; "nothing obliged me to show you hospitality. If I chose to separate myself from you, I should have no interest in seeing you again; I could place you upon the deck of this vessel which has served you as a refuge, I could sink beneath the waters, and forget that you had ever existed. Would not that be my right?" - -"It might be the right of a savage," I answered, "but not that of a civilised man." - -"Professor," replied the commander, quickly, "I am not what you call a civilised man! I have done with society entirely, for reasons which I alone have the right of appreciating. I do not, therefore, obey its laws, and I desire you never to allude to them before me again!" - -This was said plainly. A flash of anger and disdain kindled in the eyes of the Unknown, and I had a glimpse of a terrible past in the life of this man. Not only had he put himself beyond the pale of human laws, but he had made himself independent of them, free in the strictest acceptation of the word, quite beyond their reach! Who then would dare to pursue him at the bottom of the sea, when, on its surface, he defied all attempts made against him? - -What vessel could resist the shock of his submarine monitor? What cuirass, however thick, could withstand the blows of his spur? No man could demand from him an account of his actions; God, if he believed in one—his conscience, if he had one—were the sole judges to whom he was answerable. - -These reflections crossed my mind rapidly, whilst the stranger personage was silent, absorbed, and as if wrapped up in himself. I regarded him with fear mingled with interest, as, doubtless, OEdiphus regarded the Sphinx. - -After rather a long silence, the commander resumed the conversation. - -"I have hesitated," said he, "but I have thought that my interest might be reconciled with that pity to which every human being has a right. You will remain on board my vessel, since fate has cast you there. You will be free; and, in exchange for this liberty, I shall only impose one single condition. Your word of honour to submit to it will suffice." - -"Speak, sir," I answered. "I suppose this condition is one which a man of honour may accept?" - -"Yes, sir; it is this: It is possible that certain events, unforeseen, may oblige me to consign you to your cabins for some hours or some days, as the case may be. As I desire never to use violence, I expect from you, more than all the others, a passive obedience. In thus acting, I take all the responsibility: I acquit you entirely, for I make it an impossibility for you to see what ought not to be seen. Do you accept this condition?" - -Then things took place on board which, to say the least, were singular, and which ought not to be seen by people who were not placed beyond the pale of social laws. Amongst the surprises which the future was preparing for me, this might not be the least. - -"We accept," I answered; "only I will ask your permission, sir, to address one question to you—one only." - -"Speak, sir." - -"You said that we should be free on board." - -"Entirely." - -"I ask you, then, what you mean by this liberty?" - -"Just the liberty to go, to come, to see, to observe even all that passes here save under rare circumstances—the liberty, in short, which we enjoy ourselves, my companions and I." - -It was evident that we did not understand one another. - -"Pardon me, sir," I resumed, "but this liberty is only what every prisoner has of pacing his prison. It cannot suffice us." - -"It must suffice you, however." - -"What! we must renounce for ever seeing our country, our friends, our relations again?" - -"Yes, sir. But to renounce that unendurable worldly yoke which men believe to be liberty is not perhaps so painful as you think." - -"Well," exclaimed Ned Land, "never will I give my word of honour not to try to escape." - -"I did not ask you for your word of honour, Master Land," answered the commander, coldly. - -"Sir," I replied, beginning to get angry in spite of my self, "you abuse your situation towards us; it is cruelty." - -"No, sir, it is clemency. You are my prisoners of war. I keep you, when I could, by a word, plunge you into the depths of the ocean. You attacked me. You came to surprise a secret which no man in the world must penetrate—the secret of my whole existence. And you think that I am going to send you back to that world which must know me no more? Never! In retaining you, it is not you whom I guard—it is myself." - -These words indicated a resolution taken on the part of the commander, against which no arguments would prevail. - -"So, sir," I rejoined, "you give us simply the choice between life and death?" - -"Simply." - -"My friends," said I, "to a question thus put, there is nothing to answer. But no word of honour binds us to the master of this vessel." - -"None, sir," answered the Unknown. - -Then, in a gentler tone, he continued: - -"Now, permit me to finish what I have to say to you. I know you, M. Aronnax. You and your companions will not, perhaps, have so much to complain of in the chance which has bound you to my fate. You will find amongst the books which are my favourite study the work which you have published on `the depths of the sea.' I have often read it. You have carried out your work as far as terrestrial science permitted you. But you do not know all—you have not seen all. Let me tell you then, Professor, that you will not regret the time passed on board my vessel. You are going to visit the land of marvels." - -These words of the commander had a great effect upon me. I cannot deny it. My weak point was touched; and I forgot, for a moment, that the contemplation of these sublime subjects was not worth the loss of liberty. Besides, I trusted to the future to decide this grave question. So I contented myself with saying: - -"By what name ought I to address you?" - -"Sir," replied the commander, "I am nothing to you but Captain Nemo; and you and your companions are nothing to me but the passengers of the Nautilus." - -Captain Nemo called. A steward appeared. The captain gave him his orders in that strange language which I did not understand. Then, turning towards the Canadian and Conseil: - -"A repast awaits you in your cabin," said he. "Be so good as to follow this man. - -"And now, M. Aronnax, our breakfast is ready. Permit me to lead the way." - -"I am at your service, Captain." - -I followed Captain Nemo; and as soon as I had passed through the door, I found myself in a kind of passage lighted by electricity, similar to the waist of a ship. After we had proceeded a dozen yards, a second door opened before me. - -I then entered a dining-room, decorated and furnished in severe taste. High oaken sideboards, inlaid with ebony, stood at the two extremities of the room, and upon their shelves glittered china, porcelain, and glass of inestimable value. The plate on the table sparkled in the rays which the luminous ceiling shed around, while the light was tempered and softened by exquisite paintings. - -In the centre of the room was a table richly laid out. Captain Nemo indicated the place I was to occupy. - -The breakfast consisted of a certain number of dishes, the contents of which were furnished by the sea alone; and I was ignorant of the nature and mode of preparation of some of them. I acknowledged that they were good, but they had a peculiar flavour, which I easily became accustomed to. These different aliments appeared to me to be rich in phosphorus, and I thought they must have a marine origin. - -Captain Nemo looked at me. I asked him no questions, but he guessed my thoughts, and answered of his own accord the questions which I was burning to address to him. - -"The greater part of these dishes are unknown to you," he said to me. "However, you may partake of them without fear. They are wholesome and nourishing. For a long time I have renounced the food of the earth, and I am never ill now. My crew, who are healthy, are fed on the same food." - -"So," said I, "all these eatables are the produce of the sea?" - -"Yes, Professor, the sea supplies all my wants. Sometimes I cast my nets in tow, and I draw them in ready to break. Sometimes I hunt in the midst of this element, which appears to be inaccessible to man, and quarry the game which dwells in my submarine forests. My flocks, like those of Neptune's old shepherds, graze fearlessly in the immense prairies of the ocean. I have a vast property there, which I cultivate myself, and which is always sown by the hand of the Creator of all things." - -"I can understand perfectly, sir, that your nets furnish excellent fish for your table; I can understand also that you hunt aquatic game in your submarine forests; but I cannot understand at all how a particle of meat, no matter how small, can figure in your bill of fare." - -"This, which you believe to be meat, Professor, is nothing else than fillet of turtle. Here are also some dolphins' livers, which you take to be ragout of pork. My cook is a clever fellow, who excels in dressing these various products of the ocean. Taste all these dishes. Here is a preserve of sea-cucumber, which a Malay would declare to be unrivalled in the world; here is a cream, of which the milk has been furnished by the cetacea, and the sugar by the great fucus of the North Sea; and, lastly, permit me to offer you some preserve of anemones, which is equal to that of the most delicious fruits." - -I tasted, more from curiosity than as a connoisseur, whilst Captain Nemo enchanted me with his extraordinary stories. - -"You like the sea, Captain?" - -"Yes; I love it! The sea is everything. It covers seven tenths of the terrestrial globe. Its breath is pure and healthy. It is an immense desert, where man is never lonely, for he feels life stirring on all sides. The sea is only the embodiment of a supernatural and wonderful existence. It is nothing but love and emotion; it is the `Living Infinite,' as one of your poets has said. In fact, Professor, Nature manifests herself in it by her three kingdoms—mineral, vegetable, and animal. The sea is the vast reservoir of Nature. The globe began with sea, so to speak; and who knows if it will not end with it? In it is supreme tranquillity. The sea does not belong to despots. Upon its surface men can still exercise unjust laws, fight, tear one another to pieces, and be carried away with terrestrial horrors. But at thirty feet below its level, their reign ceases, their influence is quenched, and their power disappears. Ah! sir, live—live in the bosom of the waters! There only is independence! There I recognise no masters! There I am free!" - -Captain Nemo suddenly became silent in the midst of this enthusiasm, by which he was quite carried away. For a few moments he paced up and down, much agitated. Then he became more calm, regained his accustomed coldness of expression, and turning towards me: - -"Now, Professor," said he, "if you wish to go over the Nautilus, I am at your service." - -Captain Nemo rose. I followed him. A double door, contrived at the back of the dining-room, opened, and I entered a room equal in dimensions to that which I had just quitted. - -It was a library. High pieces of furniture, of black violet ebony inlaid with brass, supported upon their wide shelves a great number of books uniformly bound. They followed the shape of the room, terminating at the lower part in huge divans, covered with brown leather, which were curved, to afford the greatest comfort. Light movable desks, made to slide in and out at will, allowed one to rest one's book while reading. In the centre stood an immense table, covered with pamphlets, amongst which were some newspapers, already of old date. The electric light flooded everything; it was shed from four unpolished globes half sunk in the volutes of the ceiling. I looked with real admiration at this room, so ingeniously fitted up, and I could scarcely believe my eyes. - -"Captain Nemo," said I to my host, who had just thrown himself on one of the divans, "this is a library which would do honour to more than one of the continental palaces, and I am absolutely astounded when I consider that it can follow you to the bottom of the seas." - -"Where could one find greater solitude or silence, Professor?" replied Captain Nemo. "Did your study in the Museum afford you such perfect quiet?" - -"No, sir; and I must confess that it is a very poor one after yours. You must have six or seven thousand volumes here." - -"Twelve thousand, M. Aronnax. These are the only ties which bind me to the earth. But I had done with the world on the day when my Nautilus plunged for the first time beneath the waters. That day I bought my last volumes, my last pamphlets, my last papers, and from that time I wish to think that men no longer think or write. These books, Professor, are at your service besides, and you can make use of them freely." - -I thanked Captain Nemo, and went up to the shelves of the library. Works on science, morals, and literature abounded in every language; but I did not see one single work on political economy; that subject appeared to be strictly proscribed. Strange to say, all these books were irregularly arranged, in whatever language they were written; and this medley proved that the Captain of the Nautilus must have read indiscriminately the books which he took up by chance. - -"Sir," said I to the Captain, "I thank you for having placed this library at my disposal. It contains treasures of science, and I shall profit by them." - -"This room is not only a library," said Captain Nemo, "it is also a smoking-room." - -"A smoking-room!" I cried. "Then one may smoke on board?" - -"Certainly." - -"Then, sir, I am forced to believe that you have kept up a communication with Havannah." - -"Not any," answered the Captain. "Accept this cigar, M. Aronnax; and, though it does not come from Havannah, you will be pleased with it, if you are a connoisseur." - -I took the cigar which was offered me; its shape recalled the London ones, but it seemed to be made of leaves of gold. I lighted it at a little brazier, which was supported upon an elegant bronze stem, and drew the first whiffs with the delight of a lover of smoking who has not smoked for two days. - -"It is excellent, but it is not tobacco." - -"No!" answered the Captain, "this tobacco comes neither from Havannah nor from the East. It is a kind of sea-weed, rich in nicotine, with which the sea provides me, but somewhat sparingly." - -At that moment Captain Nemo opened a door which stood opposite to that by which I had entered the library, and I passed into an immense drawing-room splendidly lighted. - -It was a vast, four-sided room, thirty feet long, eighteen wide, and fifteen high. A luminous ceiling, decorated with light arabesques, shed a soft clear light over all the marvels accumulated in this museum. For it was in fact a museum, in which an intelligent and prodigal hand had gathered all the treasures of nature and art, with the artistic confusion which distinguishes a painter's studio. - -Thirty first-rate pictures, uniformly framed, separated by bright drapery, ornamented the walls, which were hung with tapestry of severe design. I saw works of great value, the greater part of which I had admired in the special collections of Europe, and in the exhibitions of paintings. The several schools of the old masters were represented by a Madonna of Raphael, a Virgin of Leonardo da Vinci, a nymph of Corregio, a woman of Titan, an Adoration of Veronese, an Assumption of Murillo, a portrait of Holbein, a monk of Velasquez, a martyr of Ribera, a fair of Rubens, two Flemish landscapes of Teniers, three little "genre" pictures of Gerard Dow, Metsu, and Paul Potter, two specimens of Gericault and Prudhon, and some sea-pieces of Backhuysen and Vernet. Amongst the works of modern painters were pictures with the signatures of Delacroix, Ingres, Decamps, Troyon, Meissonier, Daubigny, etc.; and some admirable statues in marble and bronze, after the finest antique models, stood upon pedestals in the corners of this magnificent museum. Amazement, as the Captain of the Nautilus had predicted, had already begun to take possession of me. - -"Professor," said this strange man, "you must excuse the unceremonious way in which I receive you, and the disorder of this room." - -"Sir," I answered, "without seeking to know who you are, I recognise in you an artist." - -"An amateur, nothing more, sir. Formerly I loved to collect these beautiful works created by the hand of man. I sought them greedily, and ferreted them out indefatigably, and I have been able to bring together some objects of great value. These are my last souvenirs of that world which is dead to me. In my eyes, your modern artists are already old; they have two or three thousand years of existence; I confound them in my own mind. Masters have no age." - -"And these musicians?" said I, pointing out some works of Weber, Rossini, Mozart, Beethoven, Haydn, Meyerbeer, Herold, Wagner, Auber, Gounod, and a number of others, scattered over a large model piano-organ which occupied one of the panels of the drawing-room. - -"These musicians," replied Captain Nemo, "are the contemporaries of Orpheus; for in the memory of the dead all chronological differences are effaced; and I am dead, Professor; as much dead as those of your friends who are sleeping six feet under the earth!" - -Captain Nemo was silent, and seemed lost in a profound reverie. I contemplated him with deep interest, analysing in silence the strange expression of his countenance. Leaning on his elbow against an angle of a costly mosaic table, he no longer saw me,—he had forgotten my presence. - -I did not disturb this reverie, and continued my observation of the curiosities which enriched this drawing-room. - -Under elegant glass cases, fixed by copper rivets, were classed and labelled the most precious productions of the sea which had ever been presented to the eye of a naturalist. My delight as a professor may be conceived. - -The division containing the zoophytes presented the most curious specimens of the two groups of polypi and echinodermes. In the first group, the tubipores, were gorgones arranged like a fan, soft sponges of Syria, ises of the Moluccas, pennatules, an admirable virgularia of the Norwegian seas, variegated unbellulairae, alcyonariae, a whole series of madrepores, which my master Milne Edwards has so cleverly classified, amongst which I remarked some wonderful flabellinae oculinae of the Island of Bourbon, the "Neptune's car" of the Antilles, superb varieties of corals—in short, every species of those curious polypi of which entire islands are formed, which will one day become continents. Of the echinodermes, remarkable for their coating of spines, asteri, sea-stars, pantacrinae, comatules, asterophons, echini, holothuri, etc., represented individually a complete collection of this group. - -A somewhat nervous conchyliologist would certainly have fainted before other more numerous cases, in which were classified the specimens of molluscs. It was a collection of inestimable value, which time fails me to describe minutely. Amongst these specimens I will quote from memory only the elegant royal hammer-fish of the Indian Ocean, whose regular white spots stood out brightly on a red and brown ground, an imperial spondyle, bright-coloured, bristling with spines, a rare specimen in the European museums—(I estimated its value at not less than L1000); a common hammer-fish of the seas of New Holland, which is only procured with difficulty; exotic buccardia of Senegal; fragile white bivalve shells, which a breath might shatter like a soap-bubble; several varieties of the aspirgillum of Java, a kind of calcareous tube, edged with leafy folds, and much debated by amateurs; a whole series of trochi, some a greenish-yellow, found in the American seas, others a reddish-brown, natives of Australian waters; others from the Gulf of Mexico, remarkable for their imbricated shell; stellari found in the Southern Seas; and last, the rarest of all, the magnificent spur of New Zealand; and every description of delicate and fragile shells to which science has given appropriate names. - -Apart, in separate compartments, were spread out chaplets of pearls of the greatest beauty, which reflected the electric light in little sparks of fire; pink pearls, torn from the pinna-marina of the Red Sea; green pearls of the haliotyde iris; yellow, blue and black pearls, the curious productions of the divers molluscs of every ocean, and certain mussels of the water-courses of the North; lastly, several specimens of inestimable value which had been gathered from the rarest pintadines. Some of these pearls were larger than a pigeon's egg, and were worth as much, and more than that which the traveller Tavernier sold to the Shah of Persia for three millions, and surpassed the one in the possession of the Imaum of Muscat, which I had believed to be unrivalled in the world. - -Therefore, to estimate the value of this collection was simply impossible. Captain Nemo must have expended millions in the acquirement of these various specimens, and I was thinking what source he could have drawn from, to have been able thus to gratify his fancy for collecting, when I was interrupted by these words: - -"You are examining my shells, Professor? Unquestionably they must be interesting to a naturalist; but for me they have a far greater charm, for I have collected them all with my own hand, and there is not a sea on the face of the globe which has escaped my researches." - -"I can understand, Captain, the delight of wandering about in the midst of such riches. You are one of those who have collected their treasures themselves. No museum in Europe possesses such a collection of the produce of the ocean. But if I exhaust all my admiration upon it, I shall have none left for the vessel which carries it. I do not wish to pry into your secrets: but I must confess that this Nautilus, with the motive power which is confined in it, the contrivances which enable it to be worked, the powerful agent which propels it, all excite my curiosity to the highest pitch. I see suspended on the walls of this room instruments of whose use I am ignorant." - -"You will find these same instruments in my own room, Professor, where I shall have much pleasure in explaining their use to you. But first come and inspect the cabin which is set apart for your own use. You must see how you will be accommodated on board the Nautilus." - -I followed Captain Nemo who, by one of the doors opening from each panel of the drawing-room, regained the waist. He conducted me towards the bow, and there I found, not a cabin, but an elegant room, with a bed, dressing-table, and several other pieces of excellent furniture. - -I could only thank my host. - -"Your room adjoins mine," said he, opening a door, "and mine opens into the drawing-room that we have just quitted." - -I entered the Captain's room: it had a severe, almost a monkish aspect. A small iron bedstead, a table, some articles for the toilet; the whole lighted by a skylight. No comforts, the strictest necessaries only. - -Captain Nemo pointed to a seat. - -"Be so good as to sit down," he said. I seated myself, and he began thus: - - - - -CHAPTER XI - -ALL BY ELECTRICITY - -"Sir," said Captain Nemo, showing me the instruments hanging on the walls of his room, "here are the contrivances required for the navigation of the Nautilus. Here, as in the drawing-room, I have them always under my eyes, and they indicate my position and exact direction in the middle of the ocean. Some are known to you, such as the thermometer, which gives the internal temperature of the Nautilus; the barometer, which indicates the weight of the air and foretells the changes of the weather; the hygrometer, which marks the dryness of the atmosphere; the storm-glass, the contents of which, by decomposing, announce the approach of tempests; the compass, which guides my course; the sextant, which shows the latitude by the altitude of the sun; chronometers, by which I calculate the longitude; and glasses for day and night, which I use to examine the points of the horizon, when the Nautilus rises to the surface of the waves." - -"These are the usual nautical instruments," I replied, "and I know the use of them. But these others, no doubt, answer to the particular requirements of the Nautilus. This dial with movable needle is a manometer, is it not?" - -"It is actually a manometer. But by communication with the water, whose external pressure it indicates, it gives our depth at the same time." - -"And these other instruments, the use of which I cannot guess?" - -"Here, Professor, I ought to give you some explanations. Will you be kind enough to listen to me?" - -He was silent for a few moments, then he said: - -"There is a powerful agent, obedient, rapid, easy, which conforms to every use, and reigns supreme on board my vessel. Everything is done by means of it. It lights, warms it, and is the soul of my mechanical apparatus. This agent is electricity." - -"Electricity?" I cried in surprise. - -"Yes, sir." - -"Nevertheless, Captain, you possess an extreme rapidity of movement, which does not agree well with the power of electricity. Until now, its dynamic force has remained under restraint, and has only been able to produce a small amount of power." - -"Professor," said Captain Nemo, "my electricity is not everybody's. You know what sea-water is composed of. In a thousand grammes are found 96 1/2 per cent. of water, and about 2 2/3 per cent. of chloride of sodium; then, in a smaller quantity, chlorides of magnesium and of potassium, bromide of magnesium, sulphate of magnesia, sulphate and carbonate of lime. You see, then, that chloride of sodium forms a large part of it. So it is this sodium that I extract from the sea-water, and of which I compose my ingredients. I owe all to the ocean; it produces electricity, and electricity gives heat, light, motion, and, in a word, life to the Nautilus." - -"But not the air you breathe?" - -"Oh! I could manufacture the air necessary for my consumption, but it is useless, because I go up to the surface of the water when I please. However, if electricity does not furnish me with air to breathe, it works at least the powerful pumps that are stored in spacious reservoirs, and which enable me to prolong at need, and as long as I will, my stay in the depths of the sea. It gives a uniform and unintermittent light, which the sun does not. Now look at this clock; it is electrical, and goes with a regularity that defies the best chronometers. I have divided it into twenty-four hours, like the Italian clocks, because for me there is neither night nor day, sun nor moon, but only that factitious light that I take with me to the bottom of the sea. Look! just now, it is ten o'clock in the morning." - -"Exactly." - -"Another application of electricity. This dial hanging in front of us indicates the speed of the Nautilus. An electric thread puts it in communication with the screw, and the needle indicates the real speed. Look! now we are spinning along with a uniform speed of fifteen miles an hour." - -"It is marvelous! And I see, Captain, you were right to make use of this agent that takes the place of wind, water, and steam." - -"We have not finished, M. Aronnax," said Captain Nemo, rising. "If you will allow me, we will examine the stern of the Nautilus." - -Really, I knew already the anterior part of this submarine boat, of which this is the exact division, starting from the ship's head: the dining-room, five yards long, separated from the library by a water-tight partition; the library, five yards long; the large drawing-room, ten yards long, separated from the Captain's room by a second water-tight partition; the said room, five yards in length; mine, two and a half yards; and, lastly a reservoir of air, seven and a half yards, that extended to the bows. Total length thirty five yards, or one hundred and five feet. The partitions had doors that were shut hermetically by means of india-rubber instruments, and they ensured the safety of the Nautilus in case of a leak. - -I followed Captain Nemo through the waist, and arrived at the centre of the boat. There was a sort of well that opened between two partitions. An iron ladder, fastened with an iron hook to the partition, led to the upper end. I asked the Captain what the ladder was used for. - -"It leads to the small boat," he said. - -"What! have you a boat?" I exclaimed, in surprise. - -"Of course; an excellent vessel, light and insubmersible, that serves either as a fishing or as a pleasure boat." - -"But then, when you wish to embark, you are obliged to come to the surface of the water?" - -"Not at all. This boat is attached to the upper part of the hull of the Nautilus, and occupies a cavity made for it. It is decked, quite water-tight, and held together by solid bolts. This ladder leads to a man-hole made in the hull of the Nautilus, that corresponds with a similar hole made in the side of the boat. By this double opening I get into the small vessel. They shut the one belonging to the Nautilus; I shut the other by means of screw pressure. I undo the bolts, and the little boat goes up to the surface of the sea with prodigious rapidity. I then open the panel of the bridge, carefully shut till then; I mast it, hoist my sail, take my oars, and I'm off." - -"But how do you get back on board?" - -"I do not come back, M. Aronnax; the Nautilus comes to me." - -"By your orders?" - -"By my orders. An electric thread connects us. I telegraph to it, and that is enough." - -"Really," I said, astonished at these marvels, "nothing can be more simple." - -After having passed by the cage of the staircase that led to the platform, I saw a cabin six feet long, in which Conseil and Ned Land, enchanted with their repast, were devouring it with avidity. Then a door opened into a kitchen nine feet long, situated between the large store-rooms. There electricity, better than gas itself, did all the cooking. The streams under the furnaces gave out to the sponges of platina a heat which was regularly kept up and distributed. They also heated a distilling apparatus, which, by evaporation, furnished excellent drinkable water. Near this kitchen was a bathroom comfortably furnished, with hot and cold water taps. - -Next to the kitchen was the berth-room of the vessel, sixteen feet long. But the door was shut, and I could not see the management of it, which might have given me an idea of the number of men employed on board the Nautilus. - -At the bottom was a fourth partition that separated this office from the engine-room. A door opened, and I found myself in the compartment where Captain Nemo—certainly an engineer of a very high order—had arranged his locomotive machinery. This engine-room, clearly lighted, did not measure less than sixty-five feet in length. It was divided into two parts; the first contained the materials for producing electricity, and the second the machinery that connected it with the screw. I examined it with great interest, in order to understand the machinery of the Nautilus. - -"You see," said the Captain, "I use Bunsen's contrivances, not Ruhmkorff's. Those would not have been powerful enough. Bunsen's are fewer in number, but strong and large, which experience proves to be the best. The electricity produced passes forward, where it works, by electro-magnets of great size, on a system of levers and cog-wheels that transmit the movement to the axle of the screw. This one, the diameter of which is nineteen feet, and the thread twenty-three feet, performs about 120 revolutions in a second." - -"And you get then?" - -"A speed of fifty miles an hour." - -"I have seen the Nautilus manoeuvre before the Abraham Lincoln, and I have my own ideas as to its speed. But this is not enough. We must see where we go. We must be able to direct it to the right, to the left, above, below. How do you get to the great depths, where you find an increasing resistance, which is rated by hundreds of atmospheres? How do you return to the surface of the ocean? And how do you maintain yourselves in the requisite medium? Am I asking too much?" - -"Not at all, Professor," replied the Captain, with some hesitation; "since you may never leave this submarine boat. Come into the saloon, it is our usual study, and there you will learn all you want to know about the Nautilus." - - - - -CHAPTER XII - -SOME FIGURES - -A moment after we were seated on a divan in the saloon smoking. The Captain showed me a sketch that gave the plan, section, and elevation of the Nautilus. Then he began his description in these words: - -"Here, M. Aronnax, are the several dimensions of the boat you are in. It is an elongated cylinder with conical ends. It is very like a cigar in shape, a shape already adopted in London in several constructions of the same sort. The length of this cylinder, from stem to stern, is exactly 232 feet, and its maximum breadth is twenty-six feet. It is not built quite like your long-voyage steamers, but its lines are sufficiently long, and its curves prolonged enough, to allow the water to slide off easily, and oppose no obstacle to its passage. These two dimensions enable you to obtain by a simple calculation the surface and cubic contents of the Nautilus. Its area measures 6,032 feet; and its contents about 1,500 cubic yards; that is to say, when completely immersed it displaces 50,000 feet of water, or weighs 1,500 tons. - -"When I made the plans for this submarine vessel, I meant that nine-tenths should be submerged: consequently it ought only to displace nine-tenths of its bulk, that is to say, only to weigh that number of tons. I ought not, therefore, to have exceeded that weight, constructing it on the aforesaid dimensions. - -"The Nautilus is composed of two hulls, one inside, the other outside, joined by T-shaped irons, which render it very strong. Indeed, owing to this cellular arrangement it resists like a block, as if it were solid. Its sides cannot yield; it coheres spontaneously, and not by the closeness of its rivets; and its perfect union of the materials enables it to defy the roughest seas. - -"These two hulls are composed of steel plates, whose density is from .7 to .8 that of water. The first is not less than two inches and a half thick and weighs 394 tons. The second envelope, the keel, twenty inches high and ten thick, weighs only sixty-two tons. The engine, the ballast, the several accessories and apparatus appendages, the partitions and bulkheads, weigh 961.62 tons. Do you follow all this?" - -"I do." - -"Then, when the Nautilus is afloat under these circumstances, one-tenth is out of the water. Now, if I have made reservoirs of a size equal to this tenth, or capable of holding 150 tons, and if I fill them with water, the boat, weighing then 1,507 tons, will be completely immersed. That would happen, Professor. These reservoirs are in the lower part of the Nautilus. I turn on taps and they fill, and the vessel sinks that had just been level with the surface." - -"Well, Captain, but now we come to the real difficulty. I can understand your rising to the surface; but, diving below the surface, does not your submarine contrivance encounter a pressure, and consequently undergo an upward thrust of one atmosphere for every thirty feet of water, just about fifteen pounds per square inch?" - -"Just so, sir." - -"Then, unless you quite fill the Nautilus, I do not see how you can draw it down to those depths." - -"Professor, you must not confound statics with dynamics or you will be exposed to grave errors. There is very little labour spent in attaining the lower regions of the ocean, for all bodies have a tendency to sink. When I wanted to find out the necessary increase of weight required to sink the Nautilus, I had only to calculate the reduction of volume that sea-water acquires according to the depth." - -"That is evident." - -"Now, if water is not absolutely incompressible, it is at least capable of very slight compression. Indeed, after the most recent calculations this reduction is only .000436 of an atmosphere for each thirty feet of depth. If we want to sink 3,000 feet, I should keep account of the reduction of bulk under a pressure equal to that of a column of water of a thousand feet. The calculation is easily verified. Now, I have supplementary reservoirs capable of holding a hundred tons. Therefore I can sink to a considerable depth. When I wish to rise to the level of the sea, I only let off the water, and empty all the reservoirs if I want the Nautilus to emerge from the tenth part of her total capacity." - -I had nothing to object to these reasonings. - -"I admit your calculations, Captain," I replied; "I should be wrong to dispute them since daily experience confirms them; but I foresee a real difficulty in the way." - -"What, sir?" - -"When you are about 1,000 feet deep, the walls of the Nautilus bear a pressure of 100 atmospheres. If, then, just now you were to empty the supplementary reservoirs, to lighten the vessel, and to go up to the surface, the pumps must overcome the pressure of 100 atmospheres, which is 1,500 lbs. per square inch. From that a power——" - -"That electricity alone can give," said the Captain, hastily. "I repeat, sir, that the dynamic power of my engines is almost infinite. The pumps of the Nautilus have an enormous power, as you must have observed when their jets of water burst like a torrent upon the Abraham Lincoln. Besides, I use subsidiary reservoirs only to attain a mean depth of 750 to 1,000 fathoms, and that with a view of managing my machines. Also, when I have a mind to visit the depths of the ocean five or six mlles below the surface, I make use of slower but not less infallible means." - -"What are they, Captain?" - -"That involves my telling you how the Nautilus is worked." - -"I am impatient to learn." - -"To steer this boat to starboard or port, to turn, in a word, following a horizontal plan, I use an ordinary rudder fixed on the back of the stern-post, and with one wheel and some tackle to steer by. But I can also make the Nautilus rise and sink, and sink and rise, by a vertical movement by means of two inclined planes fastened to its sides, opposite the centre of flotation, planes that move in every direction, and that are worked by powerful levers from the interior. If the planes are kept parallel with the boat, it moves horizontally. If slanted, the Nautilus, according to this inclination, and under the influence of the screw, either sinks diagonally or rises diagonally as it suits me. And even if I wish to rise more quickly to the surface, I ship the screw, and the pressure of the water causes the Nautilus to rise vertically like a balloon filled with hydrogen." - -"Bravo, Captain! But how can the steersman follow the route in the middle of the waters?" - -"The steersman is placed in a glazed box, that is raised about the hull of the Nautilus, and furnished with lenses." - -"Are these lenses capable of resisting such pressure?" - -"Perfectly. Glass, which breaks at a blow, is, nevertheless, capable of offering considerable resistance. During some experiments of fishing by electric light in 1864 in the Northern Seas, we saw plates less than a third of an inch thick resist a pressure of sixteen atmospheres. Now, the glass that I use is not less than thirty times thicker." - -"Granted. But, after all, in order to see, the light must exceed the darkness, and in the midst of the darkness in the water, how can you see?" - -"Behind the steersman's cage is placed a powerful electric reflector, the rays from which light up the sea for half a mile in front." - -"Ah! bravo, bravo, Captain! Now I can account for this phosphorescence in the supposed narwhal that puzzled us so. I now ask you if the boarding of the Nautilus and of the Scotia, that has made such a noise, has been the result of a chance rencontre?" - -"Quite accidental, sir. I was sailing only one fathom below the surface of the water when the shock came. It had no bad result." - -"None, sir. But now, about your rencontre with the Abraham Lincoln?" - -"Professor, I am sorry for one of the best vessels in the American navy; but they attacked me, and I was bound to defend myself. I contented myself, however, with putting the frigate hors de combat; she will not have any difficulty in getting repaired at the next port." - -"Ah, Commander! your Nautilus is certainly a marvellous boat." - -"Yes, Professor; and I love it as if it were part of myself. If danger threatens one of your vessels on the ocean, the first impression is the feeling of an abyss above and below. On the Nautilus men's hearts never fail them. No defects to be afraid of, for the double shell is as firm as iron; no rigging to attend to; no sails for the wind to carry away; no boilers to burst; no fire to fear, for the vessel is made of iron, not of wood; no coal to run short, for electricity is the only mechanical agent; no collision to fear, for it alone swims in deep water; no tempest to brave, for when it dives below the water it reaches absolute tranquillity. There, sir! that is the perfection of vessels! And if it is true that the engineer has more confidence in the vessel than the builder, and the builder than the captain himself, you understand the trust I repose in my Nautilus; for I am at once captain, builder, and engineer." - -"But how could you construct this wonderful Nautilus in secret?" - -"Each separate portion, M. Aronnax, was brought from different parts of the globe." - -"But these parts had to be put together and arranged?" - -"Professor, I had set up my workshops upon a desert island in the ocean. There my workmen, that is to say, the brave men that I instructed and educated, and myself have put together our Nautilus. Then, when the work was finished, fire destroyed all trace of our proceedings on this island, that I could have jumped over if I had liked." - -"Then the cost of this vessel is great?" - -"M. Aronnax, an iron vessel costs L145 per ton. Now the Nautilus weighed 1,500. It came therefore to L67,500, and L80,000 more for fitting it up, and about L200,000, with the works of art and the collections it contains." - -"One last question, Captain Nemo." - -"Ask it, Professor." - -"You are rich?" - -"Immensely rich, sir; and I could, without missing it, pay the national debt of France." - -I stared at the singular person who spoke thus. Was he playing upon my credulity? The future would decide that. - - - - -CHAPTER XIII - -THE BLACK RIVER - -The portion of the terrestrial globe which is covered by water is estimated at upwards of eighty millions of acres. This fluid mass comprises two billions two hundred and fifty millions of cubic miles, forming a spherical body of a diameter of sixty leagues, the weight of which would be three quintillions of tons. To comprehend the meaning of these figures, it is necessary to observe that a quintillion is to a billion as a billion is to unity; in other words, there are as many billions in a quintillion as there are units in a billion. This mass of fluid is equal to about the quantity of water which would be discharged by all the rivers of the earth in forty thousand years. - -During the geological epochs the ocean originally prevailed everywhere. Then by degrees, in the silurian period, the tops of the mountains began to appear, the islands emerged, then disappeared in partial deluges, reappeared, became settled, formed continents, till at length the earth became geographically arranged, as we see in the present day. The solid had wrested from the liquid thirty-seven million six hundred and fifty-seven square miles, equal to twelve billions nine hundred and sixty millions of acres. - -The shape of continents allows us to divide the waters into five great portions: the Arctic or Frozen Ocean, the Antarctic, or Frozen Ocean, the Indian, the Atlantic, and the Pacific Oceans. - -The Pacific Ocean extends from north to south between the two Polar Circles, and from east to west between Asia and America, over an extent of 145 degrees of longitude. It is the quietest of seas; its currents are broad and slow, it has medium tides, and abundant rain. Such was the ocean that my fate destined me first to travel over under these strange conditions. - -"Sir," said Captain Nemo, "we will, if you please, take our bearings and fix the starting-point of this voyage. It is a quarter to twelve; I will go up again to the surface." - -The Captain pressed an electric clock three times. The pumps began to drive the water from the tanks; the needle of the manometer marked by a different pressure the ascent of the Nautilus, then it stopped. - -"We have arrived," said the Captain. - -I went to the central staircase which opened on to the platform, clambered up the iron steps, and found myself on the upper part of the Nautilus. - -The platform was only three feet out of water. The front and back of the Nautilus was of that spindle-shape which caused it justly to be compared to a cigar. I noticed that its iron plates, slightly overlaying each other, resembled the shell which clothes the bodies of our large terrestrial reptiles. It explained to me how natural it was, in spite of all glasses, that this boat should have been taken for a marine animal. - -Toward the middle of the platform the longboat, half buried in the hull of the vessel, formed a slight excrescence. Fore and aft rose two cages of medium height with inclined sides, and partly closed by thick lenticular glasses; one destined for the steersman who directed the Nautilus, the other containing a brilliant lantern to give light on the road. - -The sea was beautiful, the sky pure. Scarcely could the long vehicle feel the broad undulations of the ocean. A light breeze from the east rippled the surface of the waters. The horizon, free from fog, made observation easy. Nothing was in sight. Not a quicksand, not an island. A vast desert. - -Captain Nemo, by the help of his sextant, took the altitude of the sun, which ought also to give the latitude. He waited for some moments till its disc touched the horizon. Whilst taking observations not a muscle moved, the instrument could not have been more motionless in a hand of marble. - -"Twelve o'clock, sir," said he. "When you like——" - -I cast a last look upon the sea, slightly yellowed by the Japanese coast, and descended to the saloon. - -"And now, sir, I leave you to your studies," added the Captain; "our course is E.N.E., our depth is twenty-six fathoms. Here are maps on a large scale by which you may follow it. The saloon is at your disposal, and, with your permission, I will retire." Captain Nemo bowed, and I remained alone, lost in thoughts all bearing on the commander of the Nautilus. - -For a whole hour was I deep in these reflections, seeking to pierce this mystery so interesting to me. Then my eyes fell upon the vast planisphere spread upon the table, and I placed my finger on the very spot where the given latitude and longitude crossed. - -The sea has its large rivers like the continents. They are special currents known by their temperature and their colour. The most remarkable of these is known by the name of the Gulf Stream. Science has decided on the globe the direction of five principal currents: one in the North Atlantic, a second in the South, a third in the North Pacific, a fourth in the South, and a fifth in the Southern Indian Ocean. It is even probable that a sixth current existed at one time or another in the Northern Indian Ocean, when the Caspian and Aral Seas formed but one vast sheet of water. - -At this point indicated on the planisphere one of these currents was rolling, the Kuro-Scivo of the Japanese, the Black River, which, leaving the Gulf of Bengal, where it is warmed by the perpendicular rays of a tropical sun, crosses the Straits of Malacca along the coast of Asia, turns into the North Pacific to the Aleutian Islands, carrying with it trunks of camphor-trees and other indigenous productions, and edging the waves of the ocean with the pure indigo of its warm water. It was this current that the Nautilus was to follow. I followed it with my eye; saw it lose itself in the vastness of the Pacific, and felt myself drawn with it, when Ned Land and Conseil appeared at the door of the saloon. - -My two brave companions remained petrified at the sight of the wonders spread before them. - -"Where are we, where are we?" exclaimed the Canadian. "In the museum at Quebec?" - -"My friends," I answered, making a sign for them to enter, "you are not in Canada, but on board the Nautilus, fifty yards below the level of the sea." - -"But, M. Aronnax," said Ned Land, "can you tell me how many men there are on board? Ten, twenty, fifty, a hundred?" - -"I cannot answer you, Mr. Land; it is better to abandon for a time all idea of seizing the Nautilus or escaping from it. This ship is a masterpiece of modern industry, and I should be sorry not to have seen it. Many people would accept the situation forced upon us, if only to move amongst such wonders. So be quiet and let us try and see what passes around us." - -"See!" exclaimed the harpooner, "but we can see nothing in this iron prison! We are walking—we are sailing—blindly." - -Ned Land had scarcely pronounced these words when all was suddenly darkness. The luminous ceiling was gone, and so rapidly that my eyes received a painful impression. - -We remained mute, not stirring, and not knowing what surprise awaited us, whether agreeable or disagreeable. A sliding noise was heard: one would have said that panels were working at the sides of the Nautilus. - -"It is the end of the end!" said Ned Land. - -Suddenly light broke at each side of the saloon, through two oblong openings. The liquid mass appeared vividly lit up by the electric gleam. Two crystal plates separated us from the sea. At first I trembled at the thought that this frail partition might break, but strong bands of copper bound them, giving an almost infinite power of resistance. - -The sea was distinctly visible for a mile all round the Nautilus. What a spectacle! What pen can describe it? Who could paint the effects of the light through those transparent sheets of water, and the softness of the successive gradations from the lower to the superior strata of the ocean? - -We know the transparency of the sea and that its clearness is far beyond that of rock-water. The mineral and organic substances which it holds in suspension heightens its transparency. In certain parts of the ocean at the Antilles, under seventy-five fathoms of water, can be seen with surprising clearness a bed of sand. The penetrating power of the solar rays does not seem to cease for a depth of one hundred and fifty fathoms. But in this middle fluid travelled over by the Nautilus, the electric brightness was produced even in the bosom of the waves. It was no longer luminous water, but liquid light. - -On each side a window opened into this unexplored abyss. The obscurity of the saloon showed to advantage the brightness outside, and we looked out as if this pure crystal had been the glass of an immense aquarium. - -"You wished to see, friend Ned; well, you see now." - -"Curious! curious!" muttered the Canadian, who, forgetting his ill-temper, seemed to submit to some irresistible attraction; "and one would come further than this to admire such a sight!" - -"Ah!" thought I to myself, "I understand the life of this man; he has made a world apart for himself, in which he treasures all his greatest wonders." - -For two whole hours an aquatic army escorted the Nautilus. During their games, their bounds, while rivalling each other in beauty, brightness, and velocity, I distinguished the green labre; the banded mullet, marked by a double line of black; the round-tailed goby, of a white colour, with violet spots on the back; the Japanese scombrus, a beautiful mackerel of these seas, with a blue body and silvery head; the brilliant azurors, whose name alone defies description; some banded spares, with variegated fins of blue and yellow; the woodcocks of the seas, some specimens of which attain a yard in length; Japanese salamanders, spider lampreys, serpents six feet long, with eyes small and lively, and a huge mouth bristling with teeth; with many other species. - -Our imagination was kept at its height, interjections followed quickly on each other. Ned named the fish, and Conseil classed them. I was in ecstasies with the vivacity of their movements and the beauty of their forms. Never had it been given to me to surprise these animals, alive and at liberty, in their natural element. I will not mention all the varieties which passed before my dazzled eyes, all the collection of the seas of China and Japan. These fish, more numerous than the birds of the air, came, attracted, no doubt, by the brilliant focus of the electric light. - -Suddenly there was daylight in the saloon, the iron panels closed again, and the enchanting vision disappeared. But for a long time I dreamt on, till my eyes fell on the instruments hanging on the partition. The compass still showed the course to be E.N.E., the manometer indicated a pressure of five atmospheres, equivalent to a depth of twenty five fathoms, and the electric log gave a speed of fifteen miles an hour. I expected Captain Nemo, but he did not appear. The clock marked the hour of five. - -Ned Land and Conseil returned to their cabin, and I retired to my chamber. My dinner was ready. It was composed of turtle soup made of the most delicate hawks bills, of a surmullet served with puff paste (the liver of which, prepared by itself, was most delicious), and fillets of the emperor-holocanthus, the savour of which seemed to me superior even to salmon. - -I passed the evening reading, writing, and thinking. Then sleep overpowered me, and I stretched myself on my couch of zostera, and slept profoundly, whilst the Nautilus was gliding rapidly through the current of the Black River. - - - - -CHAPTER XIV - -A NOTE OF INVITATION - -The next day was the 9th of November. I awoke after a long sleep of twelve hours. Conseil came, according to custom, to know "how I passed the night," and to offer his services. He had left his friend the Canadian sleeping like a man who had never done anything else all his life. I let the worthy fellow chatter as he pleased, without caring to answer him. I was preoccupied by the absence of the Captain during our sitting of the day before, and hoping to see him to-day. - -As soon as I was dressed I went into the saloon. It was deserted. I plunged into the study of the shell treasures hidden behind the glasses. - -The whole day passed without my being honoured by a visit from Captain Nemo. The panels of the saloon did not open. Perhaps they did not wish us to tire of these beautiful things. - -The course of the Nautilus was E.N.E., her speed twelve knots, the depth below the surface between twenty-five and thirty fathoms. - -The next day, 10th of November, the same desertion, the same solitude. I did not see one of the ship's crew: Ned and Conseil spent the greater part of the day with me. They were astonished at the puzzling absence of the Captain. Was this singular man ill?—had he altered his intentions with regard to us? - -After all, as Conseil said, we enjoyed perfect liberty, we were delicately and abundantly fed. Our host kept to his terms of the treaty. We could not complain, and, indeed, the singularity of our fate reserved such wonderful compensation for us that we had no right to accuse it as yet. - -That day I commenced the journal of these adventures which has enabled me to relate them with more scrupulous exactitude and minute detail. - -11th November, early in the morning. The fresh air spreading over the interior of the Nautilus told me that we had come to the surface of the ocean to renew our supply of oxygen. I directed my steps to the central staircase, and mounted the platform. - -It was six o'clock, the weather was cloudy, the sea grey, but calm. Scarcely a billow. Captain Nemo, whom I hoped to meet, would he be there? I saw no one but the steersman imprisoned in his glass cage. Seated upon the projection formed by the hull of the pinnace, I inhaled the salt breeze with delight. - -By degrees the fog disappeared under the action of the sun's rays, the radiant orb rose from behind the eastern horizon. The sea flamed under its glance like a train of gunpowder. The clouds scattered in the heights were coloured with lively tints of beautiful shades, and numerous "mare's tails," which betokened wind for that day. But what was wind to this Nautilus, which tempests could not frighten! - -I was admiring this joyous rising of the sun, so gay, and so life-giving, when I heard steps approaching the platform. I was prepared to salute Captain Nemo, but it was his second (whom I had already seen on the Captain's first visit) who appeared. He advanced on the platform, not seeming to see me. With his powerful glass to his eye, he scanned every point of the horizon with great attention. This examination over, he approached the panel and pronounced a sentence in exactly these terms. I have remembered it, for every morning it was repeated under exactly the same conditions. It was thus worded: - -"Nautron respoc lorni virch." - -What it meant I could not say. - -These words pronounced, the second descended. I thought that the Nautilus was about to return to its submarine navigation. I regained the panel and returned to my chamber. - -Five days sped thus, without any change in our situation. Every morning I mounted the platform. The same phrase was pronounced by the same individual. But Captain Nemo did not appear. - -I had made up my mind that I should never see him again, when, on the 16th November, on returning to my room with Ned and Conseil, I found upon my table a note addressed to me. I opened it impatiently. It was written in a bold, clear hand, the characters rather pointed, recalling the German type. The note was worded as follows: - - -TO PROFESSOR ARONNAX, On board the Nautilus. 16th of November, 1867. - -Captain Nemo invites Professor Aronnax to a hunting-party, which will take place to-morrow morning in the forests of the Island of Crespo. He hopes that nothing will prevent the Professor from being present, and he will with pleasure see him joined by his companions. - -CAPTAIN NEMO, Commander of the Nautilus. - - -"A hunt!" exclaimed Ned. - -"And in the forests of the Island of Crespo!" added Conseil. - -"Oh! then the gentleman is going on terra firma?" replied Ned Land. - -"That seems to me to be clearly indicated," said I, reading the letter once more. - -"Well, we must accept," said the Canadian. "But once more on dry ground, we shall know what to do. Indeed, I shall not be sorry to eat a piece of fresh venison." - -Without seeking to reconcile what was contradictory between Captain Nemo's manifest aversion to islands and continents, and his invitation to hunt in a forest, I contented myself with replying: - -"Let us first see where the Island of Crespo is." - -I consulted the planisphere, and in 32° 40' N. lat. and 157° 50' W. long., I found a small island, recognised in 1801 by Captain Crespo, and marked in the ancient Spanish maps as Rocca de la Plata, the meaning of which is The Silver Rock. We were then about eighteen hundred miles from our starting-point, and the course of the Nautilus, a little changed, was bringing it back towards the southeast. - -I showed this little rock, lost in the midst of the North Pacific, to my companions. - -"If Captain Nemo does sometimes go on dry ground," said I, "he at least chooses desert islands." - -Ned Land shrugged his shoulders without speaking, and Conseil and he left me. - -After supper, which was served by the steward, mute and impassive, I went to bed, not without some anxiety. - -The next morning, the 17th of November, on awakening, I felt that the Nautilus was perfectly still. I dressed quickly and entered the saloon. - -Captain Nemo was there, waiting for me. He rose, bowed, and asked me if it was convenient for me to accompany him. As he made no allusion to his absence during the last eight days, I did not mention it, and simply answered that my companions and myself were ready to follow him. - -We entered the dining-room, where breakfast was served. - -"M. Aronnax," said the Captain, "pray, share my breakfast without ceremony; we will chat as we eat. For, though I promised you a walk in the forest, I did not undertake to find hotels there. So breakfast as a man who will most likely not have his dinner till very late." - -I did honour to the repast. It was composed of several kinds of fish, and slices of sea-cucumber, and different sorts of seaweed. Our drink consisted of pure water, to which the Captain added some drops of a fermented liquor, extracted by the Kamschatcha method from a seaweed known under the name of Rhodomenia palmata. Captain Nemo ate at first without saying a word. Then he began: - -"Sir, when I proposed to you to hunt in my submarine forest of Crespo, you evidently thought me mad. Sir, you should never judge lightly of any man." - -"But Captain, believe me——" - -"Be kind enough to listen, and you will then see whether you have any cause to accuse me of folly and contradiction." - -"I listen." - -"You know as well as I do, Professor, that man can live under water, providing he carries with him a sufficient supply of breathable air. In submarine works, the workman, clad in an impervious dress, with his head in a metal helmet, receives air from above by means of forcing pumps and regulators." - -"That is a diving apparatus," said I. - -"Just so, but under these conditions the man is not at liberty; he is attached to the pump which sends him air through an india-rubber tube, and if we were obliged to be thus held to the Nautilus, we could not go far." - -"And the means of getting free?" I asked. - -"It is to use the Rouquayrol apparatus, invented by two of your own countrymen, which I have brought to perfection for my own use, and which will allow you to risk yourself under these new physiological conditions without any organ whatever suffering. It consists of a reservoir of thick iron plates, in which I store the air under a pressure of fifty atmospheres. This reservoir is fixed on the back by means of braces, like a soldier's knapsack. Its upper part forms a box in which the air is kept by means of a bellows, and therefore cannot escape unless at its normal tension. In the Rouquayrol apparatus such as we use, two india rubber pipes leave this box and join a sort of tent which holds the nose and mouth; one is to introduce fresh air, the other to let out the foul, and the tongue closes one or the other according to the wants of the respirator. But I, in encountering great pressures at the bottom of the sea, was obliged to shut my head, like that of a diver in a ball of copper; and it is to this ball of copper that the two pipes, the inspirator and the expirator, open." - -"Perfectly, Captain Nemo; but the air that you carry with you must soon be used; when it only contains fifteen per cent. of oxygen it is no longer fit to breathe." - -"Right! But I told you, M. Aronnax, that the pumps of the Nautilus allow me to store the air under considerable pressure, and on those conditions the reservoir of the apparatus can furnish breathable air for nine or ten hours." - -"I have no further objections to make," I answered. "I will only ask you one thing, Captain—how can you light your road at the bottom of the sea?" - -"With the Ruhmkorff apparatus, M. Aronnax; one is carried on the back, the other is fastened to the waist. It is composed of a Bunsen pile, which I do not work with bichromate of potash, but with sodium. A wire is introduced which collects the electricity produced, and directs it towards a particularly made lantern. In this lantern is a spiral glass which contains a small quantity of carbonic gas. When the apparatus is at work this gas becomes luminous, giving out a white and continuous light. Thus provided, I can breathe and I can see." - -"Captain Nemo, to all my objections you make such crushing answers that I dare no longer doubt. But, if I am forced to admit the Rouquayrol and Ruhmkorff apparatus, I must be allowed some reservations with regard to the gun I am to carry." - -"But it is not a gun for powder," answered the Captain. - -"Then it is an air-gun." - -"Doubtless! How would you have me manufacture gun powder on board, without either saltpetre, sulphur, or charcoal?" - -"Besides," I added, "to fire under water in a medium eight hundred and fifty-five times denser than the air, we must conquer very considerable resistance." - -"That would be no difficulty. There exist guns, according to Fulton, perfected in England by Philip Coles and Burley, in France by Furcy, and in Italy by Landi, which are furnished with a peculiar system of closing, which can fire under these conditions. But I repeat, having no powder, I use air under great pressure, which the pumps of the Nautilus furnish abundantly." - -"But this air must be rapidly used?" - -"Well, have I not my Rouquayrol reservoir, which can furnish it at need? A tap is all that is required. Besides M. Aronnax, you must see yourself that, during our submarine hunt, we can spend but little air and but few balls." - -"But it seems to me that in this twilight, and in the midst of this fluid, which is very dense compared with the atmosphere, shots could not go far, nor easily prove mortal." - -"Sir, on the contrary, with this gun every blow is mortal; and, however lightly the animal is touched, it falls as if struck by a thunderbolt." - -"Why?" - -"Because the balls sent by this gun are not ordinary balls, but little cases of glass. These glass cases are covered with a case of steel, and weighted with a pellet of lead; they are real Leyden bottles, into which the electricity is forced to a very high tension. With the slightest shock they are discharged, and the animal, however strong it may be, falls dead. I must tell you that these cases are size number four, and that the charge for an ordinary gun would be ten." - -"I will argue no longer," I replied, rising from the table. "I have nothing left me but to take my gun. At all events, I will go where you go." - -Captain Nemo then led me aft; and in passing before Ned's and Conseil's cabin, I called my two companions, who followed promptly. We then came to a cell near the machinery-room, in which we put on our walking-dress. - - - - -CHAPTER XV - -A WALK ON THE BOTTOM OF THE SEA - -This cell was, to speak correctly, the arsenal and wardrobe of the Nautilus. A dozen diving apparatuses hung from the partition waiting our use. - -Ned Land, on seeing them, showed evident repugnance to dress himself in one. - -"But, my worthy Ned, the forests of the Island of Crespo are nothing but submarine forests." - -"Good!" said the disappointed harpooner, who saw his dreams of fresh meat fade away. "And you, M. Aronnax, are you going to dress yourself in those clothes?" - -"There is no alternative, Master Ned." - -"As you please, sir," replied the harpooner, shrugging his shoulders; "but, as for me, unless I am forced, I will never get into one." - -"No one will force you, Master Ned," said Captain Nemo. - -"Is Conseil going to risk it?" asked Ned. - -"I follow my master wherever he goes," replied Conseil. - -At the Captain's call two of the ship's crew came to help us dress in these heavy and impervious clothes, made of india-rubber without seam, and constructed expressly to resist considerable pressure. One would have thought it a suit of armour, both supple and resisting. This suit formed trousers and waistcoat. The trousers were finished off with thick boots, weighted with heavy leaden soles. The texture of the waistcoat was held together by bands of copper, which crossed the chest, protecting it from the great pressure of the water, and leaving the lungs free to act; the sleeves ended in gloves, which in no way restrained the movement of the hands. There was a vast difference noticeable between these consummate apparatuses and the old cork breastplates, jackets, and other contrivances in vogue during the eighteenth century. - -Captain Nemo and one of his companions (a sort of Hercules, who must have possessed great strength), Conseil and myself were soon enveloped in the dresses. There remained nothing more to be done but to enclose our heads in the metal box. But, before proceeding to this operation, I asked the Captain's permission to examine the guns. - -One of the Nautilus men gave me a simple gun, the butt end of which, made of steel, hollow in the centre, was rather large. It served as a reservoir for compressed air, which a valve, worked by a spring, allowed to escape into a metal tube. A box of projectiles in a groove in the thickness of the butt end contained about twenty of these electric balls, which, by means of a spring, were forced into the barrel of the gun. As soon as one shot was fired, another was ready. - -"Captain Nemo," said I, "this arm is perfect, and easily handled: I only ask to be allowed to try it. But how shall we gain the bottom of the sea?" - -"At this moment, Professor, the Nautilus is stranded in five fathoms, and we have nothing to do but to start." - -"But how shall we get off?" - -"You shall see." - -Captain Nemo thrust his head into the helmet, Conseil and I did the same, not without hearing an ironical "Good sport!" from the Canadian. The upper part of our dress terminated in a copper collar upon which was screwed the metal helmet. Three holes, protected by thick glass, allowed us to see in all directions, by simply turning our head in the interior of the head-dress. As soon as it was in position, the Rouquayrol apparatus on our backs began to act; and, for my part, I could breathe with ease. - -With the Ruhmkorff lamp hanging from my belt, and the gun in my hand, I was ready to set out. But to speak the truth, imprisoned in these heavy garments, and glued to the deck by my leaden soles, it was impossible for me to take a step. - -But this state of things was provided for. I felt myself being pushed into a little room contiguous to the wardrobe room. My companions followed, towed along in the same way. I heard a water-tight door, furnished with stopper plates, close upon us, and we were wrapped in profound darkness. - -After some minutes, a loud hissing was heard. I felt the cold mount from my feet to my chest. Evidently from some part of the vessel they had, by means of a tap, given entrance to the water, which was invading us, and with which the room was soon filled. A second door cut in the side of the Nautilus then opened. We saw a faint light. In another instant our feet trod the bottom of the sea. - -And now, how can I retrace the impression left upon me by that walk under the waters? Words are impotent to relate such wonders! Captain Nemo walked in front, his companion followed some steps behind. Conseil and I remained near each other, as if an exchange of words had been possible through our metallic cases. I no longer felt the weight of my clothing, or of my shoes, of my reservoir of air, or my thick helmet, in the midst of which my head rattled like an almond in its shell. - -The light, which lit the soil thirty feet below the surface of the ocean, astonished me by its power. The solar rays shone through the watery mass easily, and dissipated all colour, and I clearly distinguished objects at a distance of a hundred and fifty yards. Beyond that the tints darkened into fine gradations of ultramarine, and faded into vague obscurity. Truly this water which surrounded me was but another air denser than the terrestrial atmosphere, but almost as transparent. Above me was the calm surface of the sea. We were walking on fine, even sand, not wrinkled, as on a flat shore, which retains the impression of the billows. This dazzling carpet, really a reflector, repelled the rays of the sun with wonderful intensity, which accounted for the vibration which penetrated every atom of liquid. Shall I be believed when I say that, at the depth of thirty feet, I could see as if I was in broad daylight? - -For a quarter of an hour I trod on this sand, sown with the impalpable dust of shells. The hull of the Nautilus, resembling a long shoal, disappeared by degrees; but its lantern, when darkness should overtake us in the waters, would help to guide us on board by its distinct rays. - -Soon forms of objects outlined in the distance were discernible. I recognised magnificent rocks, hung with a tapestry of zoophytes of the most beautiful kind, and I was at first struck by the peculiar effect of this medium. - -It was then ten in the morning; the rays of the sun struck the surface of the waves at rather an oblique angle, and at the touch of their light, decomposed by refraction as through a prism, flowers, rocks, plants, shells, and polypi were shaded at the edges by the seven solar colours. It was marvellous, a feast for the eyes, this complication of coloured tints, a perfect kaleidoscope of green, yellow, orange, violet, indigo, and blue; in one word, the whole palette of an enthusiastic colourist! Why could I not communicate to Conseil the lively sensations which were mounting to my brain, and rival him in expressions of admiration? For aught I knew, Captain Nemo and his companion might be able to exchange thoughts by means of signs previously agreed upon. So, for want of better, I talked to myself; I declaimed in the copper box which covered my head, thereby expending more air in vain words than was perhaps wise. - -Various kinds of isis, clusters of pure tuft-coral, prickly fungi, and anemones formed a brilliant garden of flowers, decked with their collarettes of blue tentacles, sea-stars studding the sandy bottom. It was a real grief to me to crush under my feet the brilliant specimens of molluscs which strewed the ground by thousands, of hammerheads, donaciae (veritable bounding shells), of staircases, and red helmet-shells, angel-wings, and many others produced by this inexhaustible ocean. But we were bound to walk, so we went on, whilst above our heads waved medusae whose umbrellas of opal or rose-pink, escalloped with a band of blue, sheltered us from the rays of the sun and fiery pelagiae, which, in the darkness, would have strewn our path with phosphorescent light. - -All these wonders I saw in the space of a quarter of a mile, scarcely stopping, and following Captain Nemo, who beckoned me on by signs. Soon the nature of the soil changed; to the sandy plain succeeded an extent of slimy mud which the Americans call "ooze," composed of equal parts of silicious and calcareous shells. We then travelled over a plain of seaweed of wild and luxuriant vegetation. This sward was of close texture, and soft to the feet, and rivalled the softest carpet woven by the hand of man. But whilst verdure was spread at our feet, it did not abandon our heads. A light network of marine plants, of that inexhaustible family of seaweeds of which more than two thousand kinds are known, grew on the surface of the water. - -I noticed that the green plants kept nearer the top of the sea, whilst the red were at a greater depth, leaving to the black or brown the care of forming gardens and parterres in the remote beds of the ocean. - -We had quitted the Nautilus about an hour and a half. It was near noon; I knew by the perpendicularity of the sun's rays, which were no longer refracted. The magical colours disappeared by degrees, and the shades of emerald and sapphire were effaced. We walked with a regular step, which rang upon the ground with astonishing intensity; the slightest noise was transmitted with a quickness to which the ear is unaccustomed on the earth; indeed, water is a better conductor of sound than air, in the ratio of four to one. At this period the earth sloped downwards; the light took a uniform tint. We were at a depth of a hundred and five yards and twenty inches, undergoing a pressure of six atmospheres. - -At this depth I could still see the rays of the sun, though feebly; to their intense brilliancy had succeeded a reddish twilight, the lowest state between day and night; but we could still see well enough; it was not necessary to resort to the Ruhmkorff apparatus as yet. At this moment Captain Nemo stopped; he waited till I joined him, and then pointed to an obscure mass, looming in the shadow, at a short distance. - -"It is the forest of the Island of Crespo," thought I; and I was not mistaken. - - - - -CHAPTER XVI - -A SUBMARINE FOREST - -We had at last arrived on the borders of this forest, doubtless one of the finest of Captain Nemo's immense domains. He looked upon it as his own, and considered he had the same right over it that the first men had in the first days of the world. And, indeed, who would have disputed with him the possession of this submarine property? What other hardier pioneer would come, hatchet in hand, to cut down the dark copses? - -This forest was composed of large tree-plants; and the moment we penetrated under its vast arcades, I was struck by the singular position of their branches—a position I had not yet observed. - -Not an herb which carpeted the ground, not a branch which clothed the trees, was either broken or bent, nor did they extend horizontally; all stretched up to the surface of the ocean. Not a filament, not a ribbon, however thin they might be, but kept as straight as a rod of iron. The fuci and llianas grew in rigid perpendicular lines, due to the density of the element which had produced them. Motionless yet, when bent to one side by the hand, they directly resumed their former position. Truly it was the region of perpendicularity! - -I soon accustomed myself to this fantastic position, as well as to the comparative darkness which surrounded us. The soil of the forest seemed covered with sharp blocks, difficult to avoid. The submarine flora struck me as being very perfect, and richer even than it would have been in the arctic or tropical zones, where these productions are not so plentiful. But for some minutes I involuntarily confounded the genera, taking animals for plants; and who would not have been mistaken? The fauna and the flora are too closely allied in this submarine world. - -These plants are self-propagated, and the principle of their existence is in the water, which upholds and nourishes them. The greater number, instead of leaves, shoot forth blades of capricious shapes, comprised within a scale of colours pink, carmine, green, olive, fawn, and brown. - -"Curious anomaly, fantastic element!" said an ingenious naturalist, "in which the animal kingdom blossoms, and the vegetable does not!" - -In about an hour Captain Nemo gave the signal to halt; I, for my part, was not sorry, and we stretched ourselves under an arbour of alariae, the long thin blades of which stood up like arrows. - -This short rest seemed delicious to me; there was nothing wanting but the charm of conversation; but, impossible to speak, impossible to answer, I only put my great copper head to Conseil's. I saw the worthy fellow's eyes glistening with delight, and, to show his satisfaction, he shook himself in his breastplate of air, in the most comical way in the world. - -After four hours of this walking, I was surprised not to find myself dreadfully hungry. How to account for this state of the stomach I could not tell. But instead I felt an insurmountable desire to sleep, which happens to all divers. And my eyes soon closed behind the thick glasses, and I fell into a heavy slumber, which the movement alone had prevented before. Captain Nemo and his robust companion, stretched in the clear crystal, set us the example. - -How long I remained buried in this drowsiness I cannot judge, but, when I woke, the sun seemed sinking towards the horizon. Captain Nemo had already risen, and I was beginning to stretch my limbs, when an unexpected apparition brought me briskly to my feet. - -A few steps off, a monstrous sea-spider, about thirty-eight inches high, was watching me with squinting eyes, ready to spring upon me. Though my diver's dress was thick enough to defend me from the bite of this animal, I could not help shuddering with horror. Conseil and the sailor of the Nautilus awoke at this moment. Captain Nemo pointed out the hideous crustacean, which a blow from the butt end of the gun knocked over, and I saw the horrible claws of the monster writhe in terrible convulsions. This incident reminded me that other animals more to be feared might haunt these obscure depths, against whose attacks my diving-dress would not protect me. I had never thought of it before, but I now resolved to be upon my guard. Indeed, I thought that this halt would mark the termination of our walk; but I was mistaken, for, instead of returning to the Nautilus, Captain Nemo continued his bold excursion. The ground was still on the incline, its declivity seemed to be getting greater, and to be leading us to greater depths. It must have been about three o'clock when we reached a narrow valley, between high perpendicular walls, situated about seventy-five fathoms deep. Thanks to the perfection of our apparatus, we were forty-five fathoms below the limit which nature seems to have imposed on man as to his submarine excursions. - -I say seventy-five fathoms, though I had no instrument by which to judge the distance. But I knew that even in the clearest waters the solar rays could not penetrate further. And accordingly the darkness deepened. At ten paces not an object was visible. I was groping my way, when I suddenly saw a brilliant white light. Captain Nemo had just put his electric apparatus into use; his companion did the same, and Conseil and I followed their example. By turning a screw I established a communication between the wire and the spiral glass, and the sea, lit by our four lanterns, was illuminated for a circle of thirty-six yards. - -As we walked I thought the light of our Ruhmkorff apparatus could not fail to draw some inhabitant from its dark couch. But if they did approach us, they at least kept at a respectful distance from the hunters. Several times I saw Captain Nemo stop, put his gun to his shoulder, and after some moments drop it and walk on. At last, after about four hours, this marvellous excursion came to an end. A wall of superb rocks, in an imposing mass, rose before us, a heap of gigantic blocks, an enormous, steep granite shore, forming dark grottos, but which presented no practicable slope; it was the prop of the Island of Crespo. It was the earth! Captain Nemo stopped suddenly. A gesture of his brought us all to a halt; and, however desirous I might be to scale the wall, I was obliged to stop. Here ended Captain Nemo's domains. And he would not go beyond them. Further on was a portion of the globe he might not trample upon. - -The return began. Captain Nemo had returned to the head of his little band, directing their course without hesitation. I thought we were not following the same road to return to the Nautilus. The new road was very steep, and consequently very painful. We approached the surface of the sea rapidly. But this return to the upper strata was not so sudden as to cause relief from the pressure too rapidly, which might have produced serious disorder in our organisation, and brought on internal lesions, so fatal to divers. Very soon light reappeared and grew, and, the sun being low on the horizon, the refraction edged the different objects with a spectral ring. At ten yards and a half deep, we walked amidst a shoal of little fishes of all kinds, more numerous than the birds of the air, and also more agile; but no aquatic game worthy of a shot had as yet met our gaze, when at that moment I saw the Captain shoulder his gun quickly, and follow a moving object into the shrubs. He fired; I heard a slight hissing, and a creature fell stunned at some distance from us. It was a magnificent sea-otter, an enhydrus, the only exclusively marine quadruped. This otter was five feet long, and must have been very valuable. Its skin, chestnut-brown above and silvery underneath, would have made one of those beautiful furs so sought after in the Russian and Chinese markets: the fineness and the lustre of its coat would certainly fetch L80. I admired this curious mammal, with its rounded head ornamented with short ears, its round eyes, and white whiskers like those of a cat, with webbed feet and nails, and tufted tail. This precious animal, hunted and tracked by fishermen, has now become very rare, and taken refuge chiefly in the northern parts of the Pacific, or probably its race would soon become extinct. - -Captain Nemo's companion took the beast, threw it over his shoulder, and we continued our journey. For one hour a plain of sand lay stretched before us. Sometimes it rose to within two yards and some inches of the surface of the water. I then saw our image clearly reflected, drawn inversely, and above us appeared an identical group reflecting our movements and our actions; in a word, like us in every point, except that they walked with their heads downward and their feet in the air. - -Another effect I noticed, which was the passage of thick clouds which formed and vanished rapidly; but on reflection I understood that these seeming clouds were due to the varying thickness of the reeds at the bottom, and I could even see the fleecy foam which their broken tops multiplied on the water, and the shadows of large birds passing above our heads, whose rapid flight I could discern on the surface of the sea. - -On this occasion I was witness to one of the finest gun shots which ever made the nerves of a hunter thrill. A large bird of great breadth of wing, clearly visible, approached, hovering over us. Captain Nemo's companion shouldered his gun and fired, when it was only a few yards above the waves. The creature fell stunned, and the force of its fall brought it within the reach of dexterous hunter's grasp. It was an albatross of the finest kind. - -Our march had not been interrupted by this incident. For two hours we followed these sandy plains, then fields of algae very disagreeable to cross. Candidly, I could do no more when I saw a glimmer of light, which, for a half mile, broke the darkness of the waters. It was the lantern of the Nautilus. Before twenty minutes were over we should be on board, and I should be able to breathe with ease, for it seemed that my reservoir supplied air very deficient in oxygen. But I did not reckon on an accidental meeting which delayed our arrival for some time. - -I had remained some steps behind, when I presently saw Captain Nemo coming hurriedly towards me. With his strong hand he bent me to the ground, his companion doing the same to Conseil. At first I knew not what to think of this sudden attack, but I was soon reassured by seeing the Captain lie down beside me, and remain immovable. - -I was stretched on the ground, just under the shelter of a bush of algae, when, raising my head, I saw some enormous mass, casting phosphorescent gleams, pass blusteringly by. - -My blood froze in my veins as I recognised two formidable sharks which threatened us. It was a couple of tintoreas, terrible creatures, with enormous tails and a dull glassy stare, the phosphorescent matter ejected from holes pierced around the muzzle. Monstrous brutes! which would crush a whole man in their iron jaws. I did not know whether Conseil stopped to classify them; for my part, I noticed their silver bellies, and their huge mouths bristling with teeth, from a very unscientific point of view, and more as a possible victim than as a naturalist. - -Happily the voracious creatures do not see well. They passed without seeing us, brushing us with their brownish fins, and we escaped by a miracle from a danger certainly greater than meeting a tiger full-face in the forest. Half an hour after, guided by the electric light we reached the Nautilus. The outside door had been left open, and Captain Nemo closed it as soon as we had entered the first cell. He then pressed a knob. I heard the pumps working in the midst of the vessel, I felt the water sinking from around me, and in a few moments the cell was entirely empty. The inside door then opened, and we entered the vestry. - -There our diving-dress was taken off, not without some trouble, and, fairly worn out from want of food and sleep, I returned to my room, in great wonder at this surprising excursion at the bottom of the sea. - - - - -CHAPTER XVII - -FOUR THOUSAND LEAGUES UNDER THE PACIFIC - -The next morning, the 18th of November, I had quite recovered from my fatigues of the day before, and I went up on to the platform, just as the second lieutenant was uttering his daily phrase. - -I was admiring the magnificent aspect of the ocean when Captain Nemo appeared. He did not seem to be aware of my presence, and began a series of astronomical observations. Then, when he had finished, he went and leant on the cage of the watch-light, and gazed abstractedly on the ocean. In the meantime, a number of the sailors of the Nautilus, all strong and healthy men, had come up onto the platform. They came to draw up the nets that had been laid all night. These sailors were evidently of different nations, although the European type was visible in all of them. I recognised some unmistakable Irishmen, Frenchmen, some Sclaves, and a Greek, or a Candiote. They were civil, and only used that odd language among themselves, the origin of which I could not guess, neither could I question them. - -The nets were hauled in. They were a large kind of "chaluts," like those on the Normandy coasts, great pockets that the waves and a chain fixed in the smaller meshes kept open. These pockets, drawn by iron poles, swept through the water, and gathered in everything in their way. That day they brought up curious specimens from those productive coasts. - -I reckoned that the haul had brought in more than nine hundredweight of fish. It was a fine haul, but not to be wondered at. Indeed, the nets are let down for several hours, and enclose in their meshes an infinite variety. We had no lack of excellent food, and the rapidity of the Nautilus and the attraction of the electric light could always renew our supply. These several productions of the sea were immediately lowered through the panel to the steward's room, some to be eaten fresh, and others pickled. - -The fishing ended, the provision of air renewed, I thought that the Nautilus was about to continue its submarine excursion, and was preparing to return to my room, when, without further preamble, the Captain turned to me, saying: - -"Professor, is not this ocean gifted with real life? It has its tempers and its gentle moods. Yesterday it slept as we did, and now it has woke after a quiet night. Look!" he continued, "it wakes under the caresses of the sun. It is going to renew its diurnal existence. It is an interesting study to watch the play of its organisation. It has a pulse, arteries, spasms; and I agree with the learned Maury, who discovered in it a circulation as real as the circulation of blood in animals. - -"Yes, the ocean has indeed circulation, and to promote it, the Creator has caused things to multiply in it—caloric, salt, and animalculae." - -When Captain Nemo spoke thus, he seemed altogether changed, and aroused an extraordinary emotion in me. - -"Also," he added, "true existence is there; and I can imagine the foundations of nautical towns, clusters of submarine houses, which, like the Nautilus, would ascend every morning to breathe at the surface of the water, free towns, independent cities. Yet who knows whether some despot——" - -Captain Nemo finished his sentence with a violent gesture. Then, addressing me as if to chase away some sorrowful thought: - -"M. Aronnax," he asked, "do you know the depth of the ocean?" - -"I only know, Captain, what the principal soundings have taught us." - -"Could you tell me them, so that I can suit them to my purpose?" - -"These are some," I replied, "that I remember. If I am not mistaken, a depth of 8,000 yards has been found in the North Atlantic, and 2,500 yards in the Mediterranean. The most remarkable soundings have been made in the South Atlantic, near the thirty-fifth parallel, and they gave 12,000 yards, 14,000 yards, and 15,000 yards. To sum up all, it is reckoned that if the bottom of the sea were levelled, its mean depth would be about one and three-quarter leagues." - -"Well, Professor," replied the Captain, "we shall show you better than that I hope. As to the mean depth of this part of the Pacific, I tell you it is only 4,000 yards." - -Having said this, Captain Nemo went towards the panel, and disappeared down the ladder. I followed him, and went into the large drawing-room. The screw was immediately put in motion, and the log gave twenty miles an hour. - -During the days and weeks that passed, Captain Nemo was very sparing of his visits. I seldom saw him. The lieutenant pricked the ship's course regularly on the chart, so I could always tell exactly the route of the Nautilus. - -Nearly every day, for some time, the panels of the drawing-room were opened, and we were never tired of penetrating the mysteries of the submarine world. - -The general direction of the Nautilus was south-east, and it kept between 100 and 150 yards of depth. One day, however, I do not know why, being drawn diagonally by means of the inclined planes, it touched the bed of the sea. The thermometer indicated a temperature of 4.25 (cent.): a temperature that at this depth seemed common to all latitudes. - -At three o'clock in the morning of the 26th of November the Nautilus crossed the tropic of Cancer at 172° long. On 27th instant it sighted the Sandwich Islands, where Cook died, February 14, 1779. We had then gone 4,860 leagues from our starting-point. In the morning, when I went on the platform, I saw two miles to windward, Hawaii, the largest of the seven islands that form the group. I saw clearly the cultivated ranges, and the several mountain-chains that run parallel with the side, and the volcanoes that overtop Mouna-Rea, which rise 5,000 yards above the level of the sea. Besides other things the nets brought up, were several flabellariae and graceful polypi, that are peculiar to that part of the ocean. The direction of the Nautilus was still to the south-east. It crossed the equator December 1, in 142° long.; and on the 4th of the same month, after crossing rapidly and without anything in particular occurring, we sighted the Marquesas group. I saw, three miles off, Martin's peak in Nouka-Hiva, the largest of the group that belongs to France. I only saw the woody mountains against the horizon, because Captain Nemo did not wish to bring the ship to the wind. There the nets brought up beautiful specimens of fish: some with azure fins and tails like gold, the flesh of which is unrivalled; some nearly destitute of scales, but of exquisite flavour; others, with bony jaws, and yellow-tinged gills, as good as bonitos; all fish that would be of use to us. After leaving these charming islands protected by the French flag, from the 4th to the 11th of December the Nautilus sailed over about 2,000 miles. - -During the daytime of the 11th of December I was busy reading in the large drawing-room. Ned Land and Conseil watched the luminous water through the half-open panels. The Nautilus was immovable. While its reservoirs were filled, it kept at a depth of 1,000 yards, a region rarely visited in the ocean, and in which large fish were seldom seen. - -I was then reading a charming book by Jean Mace, The Slaves of the Stomach, and I was learning some valuable lessons from it, when Conseil interrupted me. - -"Will master come here a moment?" he said, in a curious voice. - -"What is the matter, Conseil?" - -"I want master to look." - -I rose, went, and leaned on my elbows before the panes and watched. - -In a full electric light, an enormous black mass, quite immovable, was suspended in the midst of the waters. I watched it attentively, seeking to find out the nature of this gigantic cetacean. But a sudden thought crossed my mind. "A vessel!" I said, half aloud. - -"Yes," replied the Canadian, "a disabled ship that has sunk perpendicularly." - -Ned Land was right; we were close to a vessel of which the tattered shrouds still hung from their chains. The keel seemed to be in good order, and it had been wrecked at most some few hours. Three stumps of masts, broken off about two feet above the bridge, showed that the vessel had had to sacrifice its masts. But, lying on its side, it had filled, and it was heeling over to port. This skeleton of what it had once been was a sad spectacle as it lay lost under the waves, but sadder still was the sight of the bridge, where some corpses, bound with ropes, were still lying. I counted five—four men, one of whom was standing at the helm, and a woman standing by the poop, holding an infant in her arms. She was quite young. I could distinguish her features, which the water had not decomposed, by the brilliant light from the Nautilus. In one despairing effort, she had raised her infant above her head—poor little thing!—whose arms encircled its mother's neck. The attitude of the four sailors was frightful, distorted as they were by their convulsive movements, whilst making a last effort to free themselves from the cords that bound them to the vessel. The steersman alone, calm, with a grave, clear face, his grey hair glued to his forehead, and his hand clutching the wheel of the helm, seemed even then to be guiding the three broken masts through the depths of the ocean. - -What a scene! We were dumb; our hearts beat fast before this shipwreck, taken as it were from life and photographed in its last moments. And I saw already, coming towards it with hungry eyes, enormous sharks, attracted by the human flesh. - -However, the Nautilus, turning, went round the submerged vessel, and in one instant I read on the stern—"The Florida, Sunderland." - - - - -CHAPTER XVIII - -VANIKORO - -This terrible spectacle was the forerunner of the series of maritime catastrophes that the Nautilus was destined to meet with in its route. As long as it went through more frequented waters, we often saw the hulls of shipwrecked vessels that were rotting in the depths, and deeper down cannons, bullets, anchors, chains, and a thousand other iron materials eaten up by rust. However, on the 11th of December we sighted the Pomotou Islands, the old "dangerous group" of Bougainville, that extend over a space of 500 leagues at E.S.E. to W.N.W., from the Island Ducie to that of Lazareff. This group covers an area of 370 square leagues, and it is formed of sixty groups of islands, among which the Gambier group is remarkable, over which France exercises sway. These are coral islands, slowly raised, but continuous, created by the daily work of polypi. Then this new island will be joined later on to the neighboring groups, and a fifth continent will stretch from New Zealand and New Caledonia, and from thence to the Marquesas. - -One day, when I was suggesting this theory to Captain Nemo, he replied coldly: - -"The earth does not want new continents, but new men." - -Chance had conducted the Nautilus towards the Island of Clermont-Tonnere, one of the most curious of the group, that was discovered in 1822 by Captain Bell of the Minerva. I could study now the madreporal system, to which are due the islands in this ocean. - -Madrepores (which must not be mistaken for corals) have a tissue lined with a calcareous crust, and the modifications of its structure have induced M. Milne Edwards, my worthy master, to class them into five sections. The animalcule that the marine polypus secretes live by millions at the bottom of their cells. Their calcareous deposits become rocks, reefs, and large and small islands. Here they form a ring, surrounding a little inland lake, that communicates with the sea by means of gaps. There they make barriers of reefs like those on the coasts of New Caledonia and the various Pomoton islands. In other places, like those at Reunion and at Maurice, they raise fringed reefs, high, straight walls, near which the depth of the ocean is considerable. - -Some cable-lengths off the shores of the Island of Clermont I admired the gigantic work accomplished by these microscopical workers. These walls are specially the work of those madrepores known as milleporas, porites, madrepores, and astraeas. These polypi are found particularly in the rough beds of the sea, near the surface; and consequently it is from the upper part that they begin their operations, in which they bury themselves by degrees with the debris of the secretions that support them. Such is, at least, Darwin's theory, who thus explains the formation of the atolls, a superior theory (to my mind) to that given of the foundation of the madreporical works, summits of mountains or volcanoes, that are submerged some feet below the level of the sea. - -I could observe closely these curious walls, for perpendicularly they were more than 300 yards deep, and our electric sheets lighted up this calcareous matter brilliantly. Replying to a question Conseil asked me as to the time these colossal barriers took to be raised, I astonished him much by telling him that learned men reckoned it about the eighth of an inch in a hundred years. - -Towards evening Clermont-Tonnerre was lost in the distance, and the route of the Nautilus was sensibly changed. After having crossed the tropic of Capricorn in 135° longitude, it sailed W.N.W., making again for the tropical zone. Although the summer sun was very strong, we did not suffer from heat, for at fifteen or twenty fathoms below the surface, the temperature did not rise above from ten to twelve degrees. - -On 15th of December, we left to the east the bewitching group of the Societies and the graceful Tahiti, queen of the Pacific. I saw in the morning, some miles to the windward, the elevated summits of the island. These waters furnished our table with excellent fish, mackerel, bonitos, and some varieties of a sea-serpent. - -On the 25th of December the Nautilus sailed into the midst of the New Hebrides, discovered by Quiros in 1606, and that Bougainville explored in 1768, and to which Cook gave its present name in 1773. This group is composed principally of nine large islands, that form a band of 120 leagues N.N.S. to S.S.W., between 15° and 2° S. lat., and 164 deg. and 168° long. We passed tolerably near to the Island of Aurou, that at noon looked like a mass of green woods, surmounted by a peak of great height. - -That day being Christmas Day, Ned Land seemed to regret sorely the non-celebration of "Christmas," the family fete of which Protestants are so fond. I had not seen Captain Nemo for a week, when, on the morning of the 27th, he came into the large drawing-room, always seeming as if he had seen you five minutes before. I was busily tracing the route of the Nautilus on the planisphere. The Captain came up to me, put his finger on one spot on the chart, and said this single word. - -"Vanikoro." - -The effect was magical! It was the name of the islands on which La Perouse had been lost! I rose suddenly. - -"The Nautilus has brought us to Vanikoro?" I asked. - -"Yes, Professor," said the Captain. - -"And I can visit the celebrated islands where the Boussole and the Astrolabe struck?" - -"If you like, Professor." - -"When shall we be there?" - -"We are there now." - -Followed by Captain Nemo, I went up on to the platform, and greedily scanned the horizon. - -To the N.E. two volcanic islands emerged of unequal size, surrounded by a coral reef that measured forty miles in circumference. We were close to Vanikoro, really the one to which Dumont d'Urville gave the name of Isle de la Recherche, and exactly facing the little harbour of Vanou, situated in 16° 4' S. lat., and 164° 32' E. long. The earth seemed covered with verdure from the shore to the summits in the interior, that were crowned by Mount Kapogo, 476 feet high. The Nautilus, having passed the outer belt of rocks by a narrow strait, found itself among breakers where the sea was from thirty to forty fathoms deep. Under the verdant shade of some mangroves I perceived some savages, who appeared greatly surprised at our approach. In the long black body, moving between wind and water, did they not see some formidable cetacean that they regarded with suspicion? - -Just then Captain Nemo asked me what I knew about the wreck of La Perouse. - -"Only what everyone knows, Captain," I replied. - -"And could you tell me what everyone knows about it?" he inquired, ironically. - -"Easily." - -I related to him all that the last works of Dumont d'Urville had made known—works from which the following is a brief account. - -La Perouse, and his second, Captain de Langle, were sent by Louis XVI, in 1785, on a voyage of circumnavigation. They embarked in the corvettes Boussole and the Astrolabe, neither of which were again heard of. In 1791, the French Government, justly uneasy as to the fate of these two sloops, manned two large merchantmen, the Recherche and the Esperance, which left Brest the 28th of September under the command of Bruni d'Entrecasteaux. - -Two months after, they learned from Bowen, commander of the Albemarle, that the debris of shipwrecked vessels had been seen on the coasts of New Georgia. But D'Entrecasteaux, ignoring this communication—rather uncertain, besides—directed his course towards the Admiralty Islands, mentioned in a report of Captain Hunter's as being the place where La Perouse was wrecked. - -They sought in vain. The Esperance and the Recherche passed before Vanikoro without stopping there, and, in fact, this voyage was most disastrous, as it cost D'Entrecasteaux his life, and those of two of his lieutenants, besides several of his crew. - -Captain Dillon, a shrewd old Pacific sailor, was the first to find unmistakable traces of the wrecks. On the 15th of May, 1824, his vessel, the St. Patrick, passed close to Tikopia, one of the New Hebrides. There a Lascar came alongside in a canoe, sold him the handle of a sword in silver that bore the print of characters engraved on the hilt. The Lascar pretended that six years before, during a stay at Vanikoro, he had seen two Europeans that belonged to some vessels that had run aground on the reefs some years ago. - -Dillon guessed that he meant La Perouse, whose disappearance had troubled the whole world. He tried to get on to Vanikoro, where, according to the Lascar, he would find numerous debris of the wreck, but winds and tides prevented him. - -Dillon returned to Calcutta. There he interested the Asiatic Society and the Indian Company in his discovery. A vessel, to which was given the name of the Recherche, was put at his disposal, and he set out, 23rd January, 1827, accompanied by a French agent. - -The Recherche, after touching at several points in the Pacific, cast anchor before Vanikoro, 7th July, 1827, in that same harbour of Vanou where the Nautilus was at this time. - -There it collected numerous relics of the wreck—iron utensils, anchors, pulley-strops, swivel-guns, an 18 lb. shot, fragments of astronomical instruments, a piece of crown work, and a bronze clock, bearing this inscription—"Bazin m'a fait," the mark of the foundry of the arsenal at Brest about 1785. There could be no further doubt. - -Dillon, having made all inquiries, stayed in the unlucky place till October. Then he quitted Vanikoro, and directed his course towards New Zealand; put into Calcutta, 7th April, 1828, and returned to France, where he was warmly welcomed by Charles X. - -But at the same time, without knowing Dillon's movements, Dumont d'Urville had already set out to find the scene of the wreck. And they had learned from a whaler that some medals and a cross of St. Louis had been found in the hands of some savages of Louisiade and New Caledonia. Dumont d'Urville, commander of the Astrolabe, had then sailed, and two months after Dillon had left Vanikoro he put into Hobart Town. There he learned the results of Dillon's inquiries, and found that a certain James Hobbs, second lieutenant of the Union of Calcutta, after landing on an island situated 8° 18' S. lat., and 156° 30' E. long., had seen some iron bars and red stuffs used by the natives of these parts. Dumont d'Urville, much perplexed, and not knowing how to credit the reports of low-class journals, decided to follow Dillon's track. - -On the 10th of February, 1828, the Astrolabe appeared off Tikopia, and took as guide and interpreter a deserter found on the island; made his way to Vanikoro, sighted it on the 12th inst., lay among the reefs until the 14th, and not until the 20th did he cast anchor within the barrier in the harbour of Vanou. - -On the 23rd, several officers went round the island and brought back some unimportant trifles. The natives, adopting a system of denials and evasions, refused to take them to the unlucky place. This ambiguous conduct led them to believe that the natives had ill-treated the castaways, and indeed they seemed to fear that Dumont d'Urville had come to avenge La Perouse and his unfortunate crew. - -However, on the 26th, appeased by some presents, and understanding that they had no reprisals to fear, they led M. Jacquireot to the scene of the wreck. - -There, in three or four fathoms of water, between the reefs of Pacou and Vanou, lay anchors, cannons, pigs of lead and iron, embedded in the limy concretions. The large boat and the whaler belonging to the Astrolabe were sent to this place, and, not without some difficulty, their crews hauled up an anchor weighing 1,800 lbs., a brass gun, some pigs of iron, and two copper swivel-guns. - -Dumont d'Urville, questioning the natives, learned too that La Perouse, after losing both his vessels on the reefs of this island, had constructed a smaller boat, only to be lost a second time. Where, no one knew. - -But the French Government, fearing that Dumont d'Urville was not acquainted with Dillon's movements, had sent the sloop Bayonnaise, commanded by Legoarant de Tromelin, to Vanikoro, which had been stationed on the west coast of America. The Bayonnaise cast her anchor before Vanikoro some months after the departure of the Astrolabe, but found no new document; but stated that the savages had respected the monument to La Perouse. That is the substance of what I told Captain Nemo. - -"So," he said, "no one knows now where the third vessel perished that was constructed by the castaways on the island of Vanikoro?" - -"No one knows." - -Captain Nemo said nothing, but signed to me to follow him into the large saloon. The Nautilus sank several yards below the waves, and the panels were opened. - -I hastened to the aperture, and under the crustations of coral, covered with fungi, syphonules, alcyons, madrepores, through myriads of charming fish—girelles, glyphisidri, pompherides, diacopes, and holocentres—I recognised certain debris that the drags had not been able to tear up—iron stirrups, anchors, cannons, bullets, capstan fittings, the stem of a ship, all objects clearly proving the wreck of some vessel, and now carpeted with living flowers. While I was looking on this desolate scene, Captain Nemo said, in a sad voice: - -"Commander La Perouse set out 7th December, 1785, with his vessels La Boussole and the Astrolabe. He first cast anchor at Botany Bay, visited the Friendly Isles, New Caledonia, then directed his course towards Santa Cruz, and put into Namouka, one of the Hapai group. Then his vessels struck on the unknown reefs of Vanikoro. The Boussole, which went first, ran aground on the southerly coast. The Astrolabe went to its help, and ran aground too. The first vessel was destroyed almost immediately. The second, stranded under the wind, resisted some days. The natives made the castaways welcome. They installed themselves in the island, and constructed a smaller boat with the debris of the two large ones. Some sailors stayed willingly at Vanikoro; the others, weak and ill, set out with La Perouse. They directed their course towards the Solomon Islands, and there perished, with everything, on the westerly coast of the chief island of the group, between Capes Deception and Satisfaction." - -"How do you know that?" - -"By this, that I found on the spot where was the last wreck." - -Captain Nemo showed me a tin-plate box, stamped with the French arms, and corroded by the salt water. He opened it, and I saw a bundle of papers, yellow but still readable. - -They were the instructions of the naval minister to Commander La Perouse, annotated in the margin in Louis XVI's handwriting. - -"Ah! it is a fine death for a sailor!" said Captain Nemo, at last. "A coral tomb makes a quiet grave; and I trust that I and my comrades will find no other." - - - - -CHAPTER XIX - -TORRES STRAITS - -During the night of the 27th or 28th of December, the Nautilus left the shores of Vanikoro with great speed. Her course was south-westerly, and in three days she had gone over the 750 leagues that separated it from La Perouse's group and the south-east point of Papua. - -Early on the 1st of January, 1863, Conseil joined me on the platform. - -"Master, will you permit me to wish you a happy New Year?" - -"What! Conseil; exactly as if I was at Paris in my study at the Jardin des Plantes? Well, I accept your good wishes, and thank you for them. Only, I will ask you what you mean by a `Happy New Year' under our circumstances? Do you mean the year that will bring us to the end of our imprisonment, or the year that sees us continue this strange voyage?" - -"Really, I do not know how to answer, master. We are sure to see curious things, and for the last two months we have not had time for dullness. The last marvel is always the most astonishing; and, if we continue this progression, I do not know how it will end. It is my opinion that we shall never again see the like. I think then, with no offence to master, that a happy year would be one in which we could see everything." - -On 2nd January we had made 11,340 miles, or 5,250 French leagues, since our starting-point in the Japan Seas. Before the ship's head stretched the dangerous shores of the coral sea, on the north-east coast of Australia. Our boat lay along some miles from the redoubtable bank on which Cook's vessel was lost, 10th June, 1770. The boat in which Cook was struck on a rock, and, if it did not sink, it was owing to a piece of coral that was broken by the shock, and fixed itself in the broken keel. - -I had wished to visit the reef, 360 leagues long, against which the sea, always rough, broke with great violence, with a noise like thunder. But just then the inclined planes drew the Nautilus down to a great depth, and I could see nothing of the high coral walls. I had to content myself with the different specimens of fish brought up by the nets. I remarked, among others, some germons, a species of mackerel as large as a tunny, with bluish sides, and striped with transverse bands, that disappear with the animal's life. - -These fish followed us in shoals, and furnished us with very delicate food. We took also a large number of gilt-heads, about one and a half inches long, tasting like dorys; and flying pyrapeds like submarine swallows, which, in dark nights, light alternately the air and water with their phosphorescent light. Among the molluscs and zoophytes, I found in the meshes of the net several species of alcyonarians, echini, hammers, spurs, dials, cerites, and hyalleae. The flora was represented by beautiful floating seaweeds, laminariae, and macrocystes, impregnated with the mucilage that transudes through their pores; and among which I gathered an admirable Nemastoma Geliniarois, that was classed among the natural curiosities of the museum. - -Two days after crossing the coral sea, 4th January, we sighted the Papuan coasts. On this occasion, Captain Nemo informed me that his intention was to get into the Indian Ocean by the Strait of Torres. His communication ended there. - -The Torres Straits are nearly thirty-four leagues wide; but they are obstructed by an innumerable quantity of islands, islets, breakers, and rocks, that make its navigation almost impracticable; so that Captain Nemo took all needful precautions to cross them. The Nautilus, floating betwixt wind and water, went at a moderate pace. Her screw, like a cetacean's tail, beat the waves slowly. - -Profiting by this, I and my two companions went up on to the deserted platform. Before us was the steersman's cage, and I expected that Captain Nemo was there directing the course of the Nautilus. I had before me the excellent charts of the Straits of Torres, and I consulted them attentively. Round the Nautilus the sea dashed furiously. The course of the waves, that went from south-east to north-west at the rate of two and a half miles, broke on the coral that showed itself here and there. - -"This is a bad sea!" remarked Ned Land. - -"Detestable indeed, and one that does not suit a boat like the Nautilus." - -"The Captain must be very sure of his route, for I see there pieces of coral that would do for its keel if it only touched them slightly." - -Indeed the situation was dangerous, but the Nautilus seemed to slide like magic off these rocks. It did not follow the routes of the Astrolabe and the Zelee exactly, for they proved fatal to Dumont d'Urville. It bore more northwards, coasted the Islands of Murray, and came back to the south-west towards Cumberland Passage. I thought it was going to pass it by, when, going back to north-west, it went through a large quantity of islands and islets little known, towards the Island Sound and Canal Mauvais. - -I wondered if Captain Nemo, foolishly imprudent, would steer his vessel into that pass where Dumont d'Urville's two corvettes touched; when, swerving again, and cutting straight through to the west, he steered for the Island of Gilboa. - -It was then three in the afternoon. The tide began to recede, being quite full. The Nautilus approached the island, that I still saw, with its remarkable border of screw-pines. He stood off it at about two miles distant. Suddenly a shock overthrew me. The Nautilus just touched a rock, and stayed immovable, laying lightly to port side. - -When I rose, I perceived Captain Nemo and his lieutenant on the platform. They were examining the situation of the vessel, and exchanging words in their incomprehensible dialect. - -She was situated thus: Two miles, on the starboard side, appeared Gilboa, stretching from north to west like an immense arm. Towards the south and east some coral showed itself, left by the ebb. We had run aground, and in one of those seas where the tides are middling—a sorry matter for the floating of the Nautilus. However, the vessel had not suffered, for her keel was solidly joined. But, if she could neither glide off nor move, she ran the risk of being for ever fastened to these rocks, and then Captain Nemo's submarine vessel would be done for. - -I was reflecting thus, when the Captain, cool and calm, always master of himself, approached me. - -"An accident?" I asked. - -"No; an incident." - -"But an incident that will oblige you perhaps to become an inhabitant of this land from which you flee?" - -Captain Nemo looked at me curiously, and made a negative gesture, as much as to say that nothing would force him to set foot on terra firma again. Then he said: - -"Besides, M. Aronnax, the Nautilus is not lost; it will carry you yet into the midst of the marvels of the ocean. Our voyage is only begun, and I do not wish to be deprived so soon of the honour of your company." - -"However, Captain Nemo," I replied, without noticing the ironical turn of his phrase, "the Nautilus ran aground in open sea. Now the tides are not strong in the Pacific; and, if you cannot lighten the Nautilus, I do not see how it will be reinflated." - -"The tides are not strong in the Pacific: you are right there, Professor; but in Torres Straits one finds still a difference of a yard and a half between the level of high and low seas. To-day is 4th January, and in five days the moon will be full. Now, I shall be very much astonished if that satellite does not raise these masses of water sufficiently, and render me a service that I should be indebted to her for." - -Having said this, Captain Nemo, followed by his lieutenant, redescended to the interior of the Nautilus. As to the vessel, it moved not, and was immovable, as if the coralline polypi had already walled it up with their in destructible cement. - -"Well, sir?" said Ned Land, who came up to me after the departure of the Captain. - -"Well, friend Ned, we will wait patiently for the tide on the 9th instant; for it appears that the moon will have the goodness to put it off again." - -"Really?" - -"Really." - -"And this Captain is not going to cast anchor at all since the tide will suffice?" said Conseil, simply. - -The Canadian looked at Conseil, then shrugged his shoulders. - -"Sir, you may believe me when I tell you that this piece of iron will navigate neither on nor under the sea again; it is only fit to be sold for its weight. I think, therefore, that the time has come to part company with Captain Nemo." - -"Friend Ned, I do not despair of this stout Nautilus, as you do; and in four days we shall know what to hold to on the Pacific tides. Besides, flight might be possible if we were in sight of the English or Provencal coast; but on the Papuan shores, it is another thing; and it will be time enough to come to that extremity if the Nautilus does not recover itself again, which I look upon as a grave event." - -"But do they know, at least, how to act circumspectly? There is an island; on that island there are trees; under those trees, terrestrial animals, bearers of cutlets and roast beef, to which I would willingly give a trial." - -"In this, friend Ned is right," said Conseil, "and I agree with him. Could not master obtain permission from his friend Captain Nemo to put us on land, if only so as not to lose the habit of treading on the solid parts of our planet?" - -"I can ask him, but he will refuse." - -"Will master risk it?" asked Conseil, "and we shall know how to rely upon the Captain's amiability." - -To my great surprise, Captain Nemo gave me the permission I asked for, and he gave it very agreeably, without even exacting from me a promise to return to the vessel; but flight across New Guinea might be very perilous, and I should not have counselled Ned Land to attempt it. Better to be a prisoner on board the Nautilus than to fall into the hands of the natives. - -At eight o'clock, armed with guns and hatchets, we got off the Nautilus. The sea was pretty calm; a slight breeze blew on land. Conseil and I rowing, we sped along quickly, and Ned steered in the straight passage that the breakers left between them. The boat was well handled, and moved rapidly. - -Ned Land could not restrain his joy. He was like a prisoner that had escaped from prison, and knew not that it was necessary to re-enter it. - -"Meat! We are going to eat some meat; and what meat!" he replied. "Real game! no, bread, indeed." - -"I do not say that fish is not good; we must not abuse it; but a piece of fresh venison, grilled on live coals, will agreeably vary our ordinary course." - -"Glutton!" said Conseil, "he makes my mouth water." - -"It remains to be seen," I said, "if these forests are full of game, and if the game is not such as will hunt the hunter himself." - -"Well said, M. Aronnax," replied the Canadian, whose teeth seemed sharpened like the edge of a hatchet; "but I will eat tiger—loin of tiger—if there is no other quadruped on this island." - -"Friend Ned is uneasy about it," said Conseil. - -"Whatever it may be," continued Ned Land, "every animal with four paws without feathers, or with two paws without feathers, will be saluted by my first shot." - -"Very well! Master Land's imprudences are beginning." - -"Never fear, M. Aronnax," replied the Canadian; "I do not want twenty-five minutes to offer you a dish, of my sort." - -At half-past eight the Nautilus boat ran softly aground on a heavy sand, after having happily passed the coral reef that surrounds the Island of Gilboa. - - - - -CHAPTER XX - -A FEW DAYS ON LAND - -I was much impressed on touching land. Ned Land tried the soil with his feet, as if to take possession of it. However, it was only two months before that we had become, according to Captain Nemo, "passengers on board the Nautilus," but, in reality, prisoners of its commander. - -In a few minutes we were within musket-shot of the coast. The whole horizon was hidden behind a beautiful curtain of forests. Enormous trees, the trunks of which attained a height of 200 feet, were tied to each other by garlands of bindweed, real natural hammocks, which a light breeze rocked. They were mimosas, figs, hibisci, and palm trees, mingled together in profusion; and under the shelter of their verdant vault grew orchids, leguminous plants, and ferns. - -But, without noticing all these beautiful specimens of Papuan flora, the Canadian abandoned the agreeable for the useful. He discovered a coco-tree, beat down some of the fruit, broke them, and we drunk the milk and ate the nut with a satisfaction that protested against the ordinary food on the Nautilus. - -"Excellent!" said Ned Land. - -"Exquisite!" replied Conseil. - -"And I do not think," said the Canadian, "that he would object to our introducing a cargo of coco-nuts on board." - -"I do not think he would, but he would not taste them." - -"So much the worse for him," said Conseil. - -"And so much the better for us," replied Ned Land. "There will be more for us." - -"One word only, Master Land," I said to the harpooner, who was beginning to ravage another coco-nut tree. "Coco-nuts are good things, but before filling the canoe with them it would be wise to reconnoitre and see if the island does not produce some substance not less useful. Fresh vegetables would be welcome on board the Nautilus." - -"Master is right," replied Conseil; "and I propose to reserve three places in our vessel, one for fruits, the other for vegetables, and the third for the venison, of which I have not yet seen the smallest specimen." - -"Conseil, we must not despair," said the Canadian. - -"Let us continue," I returned, "and lie in wait. Although the island seems uninhabited, it might still contain some individuals that would be less hard than we on the nature of game." - -"Ho! ho!" said Ned Land, moving his jaws significantly. - -"Well, Ned!" said Conseil. - -"My word!" returned the Canadian, "I begin to understand the charms of anthropophagy." - -"Ned! Ned! what are you saying? You, a man-eater? I should not feel safe with you, especially as I share your cabin. I might perhaps wake one day to find myself half devoured." - -"Friend Conseil, I like you much, but not enough to eat you unnecessarily." - -"I would not trust you," replied Conseil. "But enough. We must absolutely bring down some game to satisfy this cannibal, or else one of these fine mornings, master will find only pieces of his servant to serve him." - -While we were talking thus, we were penetrating the sombre arches of the forest, and for two hours we surveyed it in all directions. - -Chance rewarded our search for eatable vegetables, and one of the most useful products of the tropical zones furnished us with precious food that we missed on board. I would speak of the bread-fruit tree, very abundant in the island of Gilboa; and I remarked chiefly the variety destitute of seeds, which bears in Malaya the name of "rima." - -Ned Land knew these fruits well. He had already eaten many during his numerous voyages, and he knew how to prepare the eatable substance. Moreover, the sight of them excited him, and he could contain himself no longer. - -"Master," he said, "I shall die if I do not taste a little of this bread-fruit pie." - -"Taste it, friend Ned—taste it as you want. We are here to make experiments—make them." - -"It won't take long," said the Canadian. - -And, provided with a lentil, he lighted a fire of dead wood that crackled joyously. During this time, Conseil and I chose the best fruits of the bread-fruit. Some had not then attained a sufficient degree of maturity; and their thick skin covered a white but rather fibrous pulp. Others, the greater number yellow and gelatinous, waited only to be picked. - -These fruits enclosed no kernel. Conseil brought a dozen to Ned Land, who placed them on a coal fire, after having cut them in thick slices, and while doing this repeating: - -"You will see, master, how good this bread is. More so when one has been deprived of it so long. It is not even bread," added he, "but a delicate pastry. You have eaten none, master?" - -"No, Ned." - -"Very well, prepare yourself for a juicy thing. If you do not come for more, I am no longer the king of harpooners." - -After some minutes, the part of the fruits that was exposed to the fire was completely roasted. The interior looked like a white pasty, a sort of soft crumb, the flavour of which was like that of an artichoke. - -It must be confessed this bread was excellent, and I ate of it with great relish. - -"What time is it now?" asked the Canadian. - -"Two o'clock at least," replied Conseil. - -"How time flies on firm ground!" sighed Ned Land. - -"Let us be off," replied Conseil. - -We returned through the forest, and completed our collection by a raid upon the cabbage-palms, that we gathered from the tops of the trees, little beans that I recognised as the "abrou" of the Malays, and yams of a superior quality. - -We were loaded when we reached the boat. But Ned Land did not find his provisions sufficient. Fate, however, favoured us. Just as we were pushing off, he perceived several trees, from twenty-five to thirty feet high, a species of palm-tree. - -At last, at five o'clock in the evening, loaded with our riches, we quitted the shore, and half an hour after we hailed the Nautilus. No one appeared on our arrival. The enormous iron-plated cylinder seemed deserted. The provisions embarked, I descended to my chamber, and after supper slept soundly. - -The next day, 6th January, nothing new on board. Not a sound inside, not a sign of life. The boat rested along the edge, in the same place in which we had left it. We resolved to return to the island. Ned Land hoped to be more fortunate than on the day before with regard to the hunt, and wished to visit another part of the forest. - -At dawn we set off. The boat, carried on by the waves that flowed to shore, reached the island in a few minutes. - -We landed, and, thinking that it was better to give in to the Canadian, we followed Ned Land, whose long limbs threatened to distance us. He wound up the coast towards the west: then, fording some torrents, he gained the high plain that was bordered with admirable forests. Some kingfishers were rambling along the water-courses, but they would not let themselves be approached. Their circumspection proved to me that these birds knew what to expect from bipeds of our species, and I concluded that, if the island was not inhabited, at least human beings occasionally frequented it. - -After crossing a rather large prairie, we arrived at the skirts of a little wood that was enlivened by the songs and flight of a large number of birds. - -"There are only birds," said Conseil. - -"But they are eatable," replied the harpooner. - -"I do not agree with you, friend Ned, for I see only parrots there." - -"Friend Conseil," said Ned, gravely, "the parrot is like pheasant to those who have nothing else." - -"And," I added, "this bird, suitably prepared, is worth knife and fork." - -Indeed, under the thick foliage of this wood, a world of parrots were flying from branch to branch, only needing a careful education to speak the human language. For the moment, they were chattering with parrots of all colours, and grave cockatoos, who seemed to meditate upon some philosophical problem, whilst brilliant red lories passed like a piece of bunting carried away by the breeze, papuans, with the finest azure colours, and in all a variety of winged things most charming to behold, but few eatable. - -However, a bird peculiar to these lands, and which has never passed the limits of the Arrow and Papuan islands, was wanting in this collection. But fortune reserved it for me before long. - -After passing through a moderately thick copse, we found a plain obstructed with bushes. I saw then those magnificent birds, the disposition of whose long feathers obliges them to fly against the wind. Their undulating flight, graceful aerial curves, and the shading of their colours, attracted and charmed one's looks. I had no trouble in recognising them. - -"Birds of paradise!" I exclaimed. - -The Malays, who carry on a great trade in these birds with the Chinese, have several means that we could not employ for taking them. Sometimes they put snares on the top of high trees that the birds of paradise prefer to frequent. Sometimes they catch them with a viscous birdlime that paralyses their movements. They even go so far as to poison the fountains that the birds generally drink from. But we were obliged to fire at them during flight, which gave us few chances to bring them down; and, indeed, we vainly exhausted one half our ammunition. - -About eleven o'clock in the morning, the first range of mountains that form the centre of the island was traversed, and we had killed nothing. Hunger drove us on. The hunters had relied on the products of the chase, and they were wrong. Happily Conseil, to his great surprise, made a double shot and secured breakfast. He brought down a white pigeon and a wood-pigeon, which, cleverly plucked and suspended from a skewer, was roasted before a red fire of dead wood. While these interesting birds were cooking, Ned prepared the fruit of the bread-tree. Then the wood-pigeons were devoured to the bones, and declared excellent. The nutmeg, with which they are in the habit of stuffing their crops, flavours their flesh and renders it delicious eating. - -"Now, Ned, what do you miss now?" - -"Some four-footed game, M. Aronnax. All these pigeons are only side-dishes and trifles; and until I have killed an animal with cutlets I shall not be content." - -"Nor I, Ned, if I do not catch a bird of paradise." - -"Let us continue hunting," replied Conseil. "Let us go towards the sea. We have arrived at the first declivities of the mountains, and I think we had better regain the region of forests." - -That was sensible advice, and was followed out. After walking for one hour we had attained a forest of sago-trees. Some inoffensive serpents glided away from us. The birds of paradise fled at our approach, and truly I despaired of getting near one when Conseil, who was walking in front, suddenly bent down, uttered a triumphal cry, and came back to me bringing a magnificent specimen. - -"Ah! bravo, Conseil!" - -"Master is very good." - -"No, my boy; you have made an excellent stroke. Take one of these living birds, and carry it in your hand." - -"If master will examine it, he will see that I have not deserved great merit." - -"Why, Conseil?" - -"Because this bird is as drunk as a quail." - -"Drunk!" - -"Yes, sir; drunk with the nutmegs that it devoured under the nutmeg-tree, under which I found it. See, friend Ned, see the monstrous effects of intemperance!" - -"By Jove!" exclaimed the Canadian, "because I have drunk gin for two months, you must needs reproach me!" - -However, I examined the curious bird. Conseil was right. The bird, drunk with the juice, was quite powerless. It could not fly; it could hardly walk. - -This bird belonged to the most beautiful of the eight species that are found in Papua and in the neighbouring islands. It was the "large emerald bird, the most rare kind." It measured three feet in length. Its head was comparatively small, its eyes placed near the opening of the beak, and also small. But the shades of colour were beautiful, having a yellow beak, brown feet and claws, nut-coloured wings with purple tips, pale yellow at the back of the neck and head, and emerald colour at the throat, chestnut on the breast and belly. Two horned, downy nets rose from below the tail, that prolonged the long light feathers of admirable fineness, and they completed the whole of this marvellous bird, that the natives have poetically named the "bird of the sun." - -But if my wishes were satisfied by the possession of the bird of paradise, the Canadian's were not yet. Happily, about two o'clock, Ned Land brought down a magnificent hog; from the brood of those the natives call "bari-outang." The animal came in time for us to procure real quadruped meat, and he was well received. Ned Land was very proud of his shot. The hog, hit by the electric ball, fell stone dead. The Canadian skinned and cleaned it properly, after having taken half a dozen cutlets, destined to furnish us with a grilled repast in the evening. Then the hunt was resumed, which was still more marked by Ned and Conseil's exploits. - -Indeed, the two friends, beating the bushes, roused a herd of kangaroos that fled and bounded along on their elastic paws. But these animals did not take to flight so rapidly but what the electric capsule could stop their course. - -"Ah, Professor!" cried Ned Land, who was carried away by the delights of the chase, "what excellent game, and stewed, too! What a supply for the Nautilus! Two! three! five down! And to think that we shall eat that flesh, and that the idiots on board shall not have a crumb!" - -I think that, in the excess of his joy, the Canadian, if he had not talked so much, would have killed them all. But he contented himself with a single dozen of these interesting marsupians. These animals were small. They were a species of those "kangaroo rabbits" that live habitually in the hollows of trees, and whose speed is extreme; but they are moderately fat, and furnish, at least, estimable food. We were very satisfied with the results of the hunt. Happy Ned proposed to return to this enchanting island the next day, for he wished to depopulate it of all the eatable quadrupeds. But he had reckoned without his host. - -At six o'clock in the evening we had regained the shore; our boat was moored to the usual place. The Nautilus, like a long rock, emerged from the waves two miles from the beach. Ned Land, without waiting, occupied himself about the important dinner business. He understood all about cooking well. The "bari-outang," grilled on the coals, soon scented the air with a delicious odour. - -Indeed, the dinner was excellent. Two wood-pigeons completed this extraordinary menu. The sago pasty, the artocarpus bread, some mangoes, half a dozen pineapples, and the liquor fermented from some coco-nuts, overjoyed us. I even think that my worthy companions' ideas had not all the plainness desirable. - -"Suppose we do not return to the Nautilus this evening?" said Conseil. - -"Suppose we never return?" added Ned Land. - -Just then a stone fell at our feet and cut short the harpooner's proposition. - - - - -CHAPTER XXI - -CAPTAIN NEMO'S THUNDERBOLT - -We looked at the edge of the forest without rising, my hand stopping in the action of putting it to my mouth, Ned Land's completing its office. - -"Stones do not fall from the sky," remarked Conseil, "or they would merit the name aerolites." - -A second stone, carefully aimed, that made a savoury pigeon's leg fall from Conseil's hand, gave still more weight to his observation. We all three arose, shouldered our guns, and were ready to reply to any attack. - -"Are they apes?" cried Ned Land. - -"Very nearly—they are savages." - -"To the boat!" I said, hurrying to the sea. - -It was indeed necessary to beat a retreat, for about twenty natives armed with bows and slings appeared on the skirts of a copse that masked the horizon to the right, hardly a hundred steps from us. - -Our boat was moored about sixty feet from us. The savages approached us, not running, but making hostile demonstrations. Stones and arrows fell thickly. - -Ned Land had not wished to leave his provisions; and, in spite of his imminent danger, his pig on one side and kangaroos on the other, he went tolerably fast. In two minutes we were on the shore. To load the boat with provisions and arms, to push it out to sea, and ship the oars, was the work of an instant. We had not gone two cable-lengths, when a hundred savages, howling and gesticulating, entered the water up to their waists. I watched to see if their apparition would attract some men from the Nautilus on to the platform. But no. The enormous machine, lying off, was absolutely deserted. - -Twenty minutes later we were on board. The panels were open. After making the boat fast, we entered into the interior of the Nautilus. - -I descended to the drawing-room, from whence I heard some chords. Captain Nemo was there, bending over his organ, and plunged in a musical ecstasy. - -"Captain!" - -He did not hear me. - -"Captain!" I said, touching his hand. - -He shuddered, and, turning round, said, "Ah! it is you, Professor? Well, have you had a good hunt, have you botanised successfully?" - -"Yes Captain; but we have unfortunately brought a troop of bipeds, whose vicinity troubles me." - -"What bipeds?" - -"Savages." - -"Savages!" he echoed, ironically. "So you are astonished, Professor, at having set foot on a strange land and finding savages? Savages! where are there not any? Besides, are they worse than others, these whom you call savages?" - -"But Captain——" - -"How many have you counted?" - -"A hundred at least." - -"M. Aronnax," replied Captain Nemo, placing his fingers on the organ stops, "when all the natives of Papua are assembled on this shore, the Nautilus will have nothing to fear from their attacks." - -The Captain's fingers were then running over the keys of the instrument, and I remarked that he touched only the black keys, which gave his melodies an essentially Scotch character. Soon he had forgotten my presence, and had plunged into a reverie that I did not disturb. I went up again on to the platform: night had already fallen; for, in this low latitude, the sun sets rapidly and without twilight. I could only see the island indistinctly; but the numerous fires, lighted on the beach, showed that the natives did not think of leaving it. I was alone for several hours, sometimes thinking of the natives—but without any dread of them, for the imperturbable confidence of the Captain was catching—sometimes forgetting them to admire the splendours of the night in the tropics. My remembrances went to France in the train of those zodiacal stars that would shine in some hours' time. The moon shone in the midst of the constellations of the zenith. - -The night slipped away without any mischance, the islanders frightened no doubt at the sight of a monster aground in the bay. The panels were open, and would have offered an easy access to the interior of the Nautilus. - -At six o'clock in the morning of the 8th January I went up on to the platform. The dawn was breaking. The island soon showed itself through the dissipating fogs, first the shore, then the summits. - -The natives were there, more numerous than on the day before—five or six hundred perhaps—some of them, profiting by the low water, had come on to the coral, at less than two cable-lengths from the Nautilus. I distinguished them easily; they were true Papuans, with athletic figures, men of good race, large high foreheads, large, but not broad and flat, and white teeth. Their woolly hair, with a reddish tinge, showed off on their black shining bodies like those of the Nubians. From the lobes of their ears, cut and distended, hung chaplets of bones. Most of these savages were naked. Amongst them, I remarked some women, dressed from the hips to knees in quite a crinoline of herbs, that sustained a vegetable waistband. Some chiefs had ornamented their necks with a crescent and collars of glass beads, red and white; nearly all were armed with bows, arrows, and shields and carried on their shoulders a sort of net containing those round stones which they cast from their slings with great skill. One of these chiefs, rather near to the Nautilus, examined it attentively. He was, perhaps, a "mado" of high rank, for he was draped in a mat of banana-leaves, notched round the edges, and set off with brilliant colours. - -I could easily have knocked down this native, who was within a short length; but I thought that it was better to wait for real hostile demonstrations. Between Europeans and savages, it is proper for the Europeans to parry sharply, not to attack. - -During low water the natives roamed about near the Nautilus, but were not troublesome; I heard them frequently repeat the word "Assai," and by their gestures I understood that they invited me to go on land, an invitation that I declined. - -So that, on that day, the boat did not push off, to the great displeasure of Master Land, who could not complete his provisions. - -This adroit Canadian employed his time in preparing the viands and meat that he had brought off the island. As for the savages, they returned to the shore about eleven o'clock in the morning, as soon as the coral tops began to disappear under the rising tide; but I saw their numbers had increased considerably on the shore. Probably they came from the neighbouring islands, or very likely from Papua. However, I had not seen a single native canoe. Having nothing better to do, I thought of dragging these beautiful limpid waters, under which I saw a profusion of shells, zoophytes, and marine plants. Moreover, it was the last day that the Nautilus would pass in these parts, if it float in open sea the next day, according to Captain Nemo's promise. - -I therefore called Conseil, who brought me a little light drag, very like those for the oyster fishery. Now to work! For two hours we fished unceasingly, but without bringing up any rarities. The drag was filled with midas-ears, harps, melames, and particularly the most beautiful hammers I have ever seen. We also brought up some sea-slugs, pearl-oysters, and a dozen little turtles that were reserved for the pantry on board. - -But just when I expected it least, I put my hand on a wonder, I might say a natural deformity, very rarely met with. Conseil was just dragging, and his net came up filled with divers ordinary shells, when, all at once, he saw me plunge my arm quickly into the net, to draw out a shell, and heard me utter a cry. - -"What is the matter, sir?" he asked in surprise. "Has master been bitten?" - -"No, my boy; but I would willingly have given a finger for my discovery." - -"What discovery?" - -"This shell," I said, holding up the object of my triumph. - -"It is simply an olive porphyry, genus olive, order of the pectinibranchidae, class of gasteropods, sub-class mollusca." - -"Yes, Conseil; but, instead of being rolled from right to left, this olive turns from left to right." - -"Is it possible?" - -"Yes, my boy; it is a left shell." - -Shells are all right-handed, with rare exceptions; and, when by chance their spiral is left, amateurs are ready to pay their weight in gold. - -Conseil and I were absorbed in the contemplation of our treasure, and I was promising myself to enrich the museum with it, when a stone unfortunately thrown by a native struck against, and broke, the precious object in Conseil's hand. I uttered a cry of despair! Conseil took up his gun, and aimed at a savage who was poising his sling at ten yards from him. I would have stopped him, but his blow took effect and broke the bracelet of amulets which encircled the arm of the savage. - -"Conseil!" cried I. "Conseil!" - -"Well, sir! do you not see that the cannibal has commenced the attack?" - -"A shell is not worth the life of a man," said I. - -"Ah! the scoundrel!" cried Conseil; "I would rather he had broken my shoulder!" - -Conseil was in earnest, but I was not of his opinion. However, the situation had changed some minutes before, and we had not perceived. A score of canoes surrounded the Nautilus. These canoes, scooped out of the trunk of a tree, long, narrow, well adapted for speed, were balanced by means of a long bamboo pole, which floated on the water. They were managed by skilful, half-naked paddlers, and I watched their advance with some uneasiness. It was evident that these Papuans had already had dealings with the Europeans and knew their ships. But this long iron cylinder anchored in the bay, without masts or chimneys, what could they think of it? Nothing good, for at first they kept at a respectful distance. However, seeing it motionless, by degrees they took courage, and sought to familiarise themselves with it. Now this familiarity was precisely what it was necessary to avoid. Our arms, which were noiseless, could only produce a moderate effect on the savages, who have little respect for aught but blustering things. The thunderbolt without the reverberations of thunder would frighten man but little, though the danger lies in the lightning, not in the noise. - -At this moment the canoes approached the Nautilus, and a shower of arrows alighted on her. - -I went down to the saloon, but found no one there. I ventured to knock at the door that opened into the Captain's room. "Come in," was the answer. - -I entered, and found Captain Nemo deep in algebraical calculations of x and other quantities. - -"I am disturbing you," said I, for courtesy's sake. - -"That is true, M. Aronnax," replied the Captain; "but I think you have serious reasons for wishing to see me?" - -"Very grave ones; the natives are surrounding us in their canoes, and in a few minutes we shall certainly be attacked by many hundreds of savages." - -"Ah!" said Captain Nemo quietly, "they are come with their canoes?" - -"Yes, sir." - -"Well, sir, we must close the hatches." - -"Exactly, and I came to say to you——" - -"Nothing can be more simple," said Captain Nemo. And, pressing an electric button, he transmitted an order to the ship's crew. - -"It is all done, sir," said he, after some moments. "The pinnace is ready, and the hatches are closed. You do not fear, I imagine, that these gentlemen could stave in walls on which the balls of your frigate have had no effect?" - -"No, Captain; but a danger still exists." - -"What is that, sir?" - -"It is that to-morrow, at about this hour, we must open the hatches to renew the air of the Nautilus. Now, if, at this moment, the Papuans should occupy the platform, I do not see how you could prevent them from entering." - -"Then, sir, you suppose that they will board us?" - -"I am certain of it." - -"Well, sir, let them come. I see no reason for hindering them. After all, these Papuans are poor creatures, and I am unwilling that my visit to the island should cost the life of a single one of these wretches." - -Upon that I was going away; But Captain Nemo detained me, and asked me to sit down by him. He questioned me with interest about our excursions on shore, and our hunting; and seemed not to understand the craving for meat that possessed the Canadian. Then the conversation turned on various subjects, and, without being more communicative, Captain Nemo showed himself more amiable. - -Amongst other things, we happened to speak of the situation of the Nautilus, run aground in exactly the same spot in this strait where Dumont d'Urville was nearly lost. Apropos of this: - -"This D'Urville was one of your great sailors," said the Captain to me, "one of your most intelligent navigators. He is the Captain Cook of you Frenchmen. Unfortunate man of science, after having braved the icebergs of the South Pole, the coral reefs of Oceania, the cannibals of the Pacific, to perish miserably in a railway train! If this energetic man could have reflected during the last moments of his life, what must have been uppermost in his last thoughts, do you suppose?" - -So speaking, Captain Nemo seemed moved, and his emotion gave me a better opinion of him. Then, chart in hand, we reviewed the travels of the French navigator, his voyages of circumnavigation, his double detention at the South Pole, which led to the discovery of Adelaide and Louis Philippe, and fixing the hydrographical bearings of the principal islands of Oceania. - -"That which your D'Urville has done on the surface of the seas," said Captain Nemo, "that have I done under them, and more easily, more completely than he. The Astrolabe and the Zelee, incessantly tossed about by the hurricane, could not be worth the Nautilus, quiet repository of labour that she is, truly motionless in the midst of the waters. - -"To-morrow," added the Captain, rising, "to-morrow, at twenty minutes to three p.m., the Nautilus shall float, and leave the Strait of Torres uninjured." - -Having curtly pronounced these words, Captain Nemo bowed slightly. This was to dismiss me, and I went back to my room. - -There I found Conseil, who wished to know the result of my interview with the Captain. - -"My boy," said I, "when I feigned to believe that his Nautilus was threatened by the natives of Papua, the Captain answered me very sarcastically. I have but one thing to say to you: Have confidence in him, and go to sleep in peace." - -"Have you no need of my services, sir?" - -"No, my friend. What is Ned Land doing?" - -"If you will excuse me, sir," answered Conseil, "friend Ned is busy making a kangaroo-pie which will be a marvel." - -I remained alone and went to bed, but slept indifferently. I heard the noise of the savages, who stamped on the platform, uttering deafening cries. The night passed thus, without disturbing the ordinary repose of the crew. The presence of these cannibals affected them no more than the soldiers of a masked battery care for the ants that crawl over its front. - -At six in the morning I rose. The hatches had not been opened. The inner air was not renewed, but the reservoirs, filled ready for any emergency, were now resorted to, and discharged several cubic feet of oxygen into the exhausted atmosphere of the Nautilus. - -I worked in my room till noon, without having seen Captain Nemo, even for an instant. On board no preparations for departure were visible. - -I waited still some time, then went into the large saloon. The clock marked half-past two. In ten minutes it would be high-tide: and, if Captain Nemo had not made a rash promise, the Nautilus would be immediately detached. If not, many months would pass ere she could leave her bed of coral. - -However, some warning vibrations began to be felt in the vessel. I heard the keel grating against the rough calcareous bottom of the coral reef. - -At five-and-twenty minutes to three, Captain Nemo appeared in the saloon. - -"We are going to start," said he. - -"Ah!" replied I. - -"I have given the order to open the hatches." - -"And the Papuans?" - -"The Papuans?" answered Captain Nemo, slightly shrugging his shoulders. - -"Will they not come inside the Nautilus?" - -"How?" - -"Only by leaping over the hatches you have opened." - -"M. Aronnax," quietly answered Captain Nemo, "they will not enter the hatches of the Nautilus in that way, even if they were open." - -I looked at the Captain. - -"You do not understand?" said he. - -"Hardly." - -"Well, come and you will see." - -I directed my steps towards the central staircase. There Ned Land and Conseil were slyly watching some of the ship's crew, who were opening the hatches, while cries of rage and fearful vociferations resounded outside. - -The port lids were pulled down outside. Twenty horrible faces appeared. But the first native who placed his hand on the stair-rail, struck from behind by some invisible force, I know not what, fled, uttering the most fearful cries and making the wildest contortions. - -Ten of his companions followed him. They met with the same fate. - -Conseil was in ecstasy. Ned Land, carried away by his violent instincts, rushed on to the staircase. But the moment he seized the rail with both hands, he, in his turn, was overthrown. - -"I am struck by a thunderbolt," cried he, with an oath. - -This explained all. It was no rail; but a metallic cable charged with electricity from the deck communicating with the platform. Whoever touched it felt a powerful shock—and this shock would have been mortal if Captain Nemo had discharged into the conductor the whole force of the current. It might truly be said that between his assailants and himself he had stretched a network of electricity which none could pass with impunity. - -Meanwhile, the exasperated Papuans had beaten a retreat paralysed with terror. As for us, half laughing, we consoled and rubbed the unfortunate Ned Land, who swore like one possessed. - -But at this moment the Nautilus, raised by the last waves of the tide, quitted her coral bed exactly at the fortieth minute fixed by the Captain. Her screw swept the waters slowly and majestically. Her speed increased gradually, and, sailing on the surface of the ocean, she quitted safe and sound the dangerous passes of the Straits of Torres. - - - - -CHAPTER XXII - -"AEGRI SOMNIA" - -The following day 10th January, the Nautilus continued her course between two seas, but with such remarkable speed that I could not estimate it at less than thirty-five miles an hour. The rapidity of her screw was such that I could neither follow nor count its revolutions. When I reflected that this marvellous electric agent, after having afforded motion, heat, and light to the Nautilus, still protected her from outward attack, and transformed her into an ark of safety which no profane hand might touch without being thunderstricken, my admiration was unbounded, and from the structure it extended to the engineer who had called it into existence. - -Our course was directed to the west, and on the 11th of January we doubled Cape Wessel, situation in 135° long. and 10° S. lat., which forms the east point of the Gulf of Carpentaria. The reefs were still numerous, but more equalised, and marked on the chart with extreme precision. The Nautilus easily avoided the breakers of Money to port and the Victoria reefs to starboard, placed at 130° long. and on the 10th parallel, which we strictly followed. - -On the 13th of January, Captain Nemo arrived in the Sea of Timor, and recognised the island of that name in 122° long. - -From this point the direction of the Nautilus inclined towards the south-west. Her head was set for the Indian Ocean. Where would the fancy of Captain Nemo carry us next? Would he return to the coast of Asia or would he approach again the shores of Europe? Improbable conjectures both, to a man who fled from inhabited continents. Then would he descend to the south? Was he going to double the Cape of Good Hope, then Cape Horn, and finally go as far as the Antarctic pole? Would he come back at last to the Pacific, where his Nautilus could sail free and independently? Time would show. - -After having skirted the sands of Cartier, of Hibernia, Seringapatam, and Scott, last efforts of the solid against the liquid element, on the 14th of January we lost sight of land altogether. The speed of the Nautilus was considerably abated, and with irregular course she sometimes swam in the bosom of the waters, sometimes floated on their surface. - -During this period of the voyage, Captain Nemo made some interesting experiments on the varied temperature of the sea, in different beds. Under ordinary conditions these observations are made by means of rather complicated instruments, and with somewhat doubtful results, by means of thermometrical sounding-leads, the glasses often breaking under the pressure of the water, or an apparatus grounded on the variations of the resistance of metals to the electric currents. Results so obtained could not be correctly calculated. On the contrary, Captain Nemo went himself to test the temperature in the depths of the sea, and his thermometer, placed in communication with the different sheets of water, gave him the required degree immediately and accurately. - -It was thus that, either by overloading her reservoirs or by descending obliquely by means of her inclined planes, the Nautilus successively attained the depth of three, four, five, seven, nine, and ten thousand yards, and the definite result of this experience was that the sea preserved an average temperature of four degrees and a half at a depth of five thousand fathoms under all latitudes. - -On the 16th of January, the Nautilus seemed becalmed only a few yards beneath the surface of the waves. Her electric apparatus remained inactive and her motionless screw left her to drift at the mercy of the currents. I supposed that the crew was occupied with interior repairs, rendered necessary by the violence of the mechanical movements of the machine. - -My companions and I then witnessed a curious spectacle. The hatches of the saloon were open, and, as the beacon light of the Nautilus was not in action, a dim obscurity reigned in the midst of the waters. I observed the state of the sea, under these conditions, and the largest fish appeared to me no more than scarcely defined shadows, when the Nautilus found herself suddenly transported into full light. I thought at first that the beacon had been lighted, and was casting its electric radiance into the liquid mass. I was mistaken, and after a rapid survey perceived my error. - -The Nautilus floated in the midst of a phosphorescent bed which, in this obscurity, became quite dazzling. It was produced by myriads of luminous animalculae, whose brilliancy was increased as they glided over the metallic hull of the vessel. I was surprised by lightning in the midst of these luminous sheets, as though they had been rivulets of lead melted in an ardent furnace or metallic masses brought to a white heat, so that, by force of contrast, certain portions of light appeared to cast a shade in the midst of the general ignition, from which all shade seemed banished. No; this was not the calm irradiation of our ordinary lightning. There was unusual life and vigour: this was truly living light! - -In reality, it was an infinite agglomeration of coloured infusoria, of veritable globules of jelly, provided with a threadlike tentacle, and of which as many as twenty-five thousand have been counted in less than two cubic half-inches of water. - -During several hours the Nautilus floated in these brilliant waves, and our admiration increased as we watched the marine monsters disporting themselves like salamanders. I saw there in the midst of this fire that burns not the swift and elegant porpoise (the indefatigable clown of the ocean), and some swordfish ten feet long, those prophetic heralds of the hurricane whose formidable sword would now and then strike the glass of the saloon. Then appeared the smaller fish, the balista, the leaping mackerel, wolf-thorn-tails, and a hundred others which striped the luminous atmosphere as they swam. This dazzling spectacle was enchanting! Perhaps some atmospheric condition increased the intensity of this phenomenon. Perhaps some storm agitated the surface of the waves. But at this depth of some yards, the Nautilus was unmoved by its fury and reposed peacefully in still water. - -So we progressed, incessantly charmed by some new marvel. The days passed rapidly away, and I took no account of them. Ned, according to habit, tried to vary the diet on board. Like snails, we were fixed to our shells, and I declare it is easy to lead a snail's life. - -Thus this life seemed easy and natural, and we thought no longer of the life we led on land; but something happened to recall us to the strangeness of our situation. - -On the 18th of January, the Nautilus was in 105° long. and 15° S. lat. The weather was threatening, the sea rough and rolling. There was a strong east wind. The barometer, which had been going down for some days, foreboded a coming storm. I went up on to the platform just as the second lieutenant was taking the measure of the horary angles, and waited, according to habit till the daily phrase was said. But on this day it was exchanged for another phrase not less incomprehensible. Almost directly, I saw Captain Nemo appear with a glass, looking towards the horizon. - -For some minutes he was immovable, without taking his eye off the point of observation. Then he lowered his glass and exchanged a few words with his lieutenant. The latter seemed to be a victim to some emotion that he tried in vain to repress. Captain Nemo, having more command over himself, was cool. He seemed, too, to be making some objections to which the lieutenant replied by formal assurances. At least I concluded so by the difference of their tones and gestures. For myself, I had looked carefully in the direction indicated without seeing anything. The sky and water were lost in the clear line of the horizon. - -However, Captain Nemo walked from one end of the platform to the other, without looking at me, perhaps without seeing me. His step was firm, but less regular than usual. He stopped sometimes, crossed his arms, and observed the sea. What could he be looking for on that immense expanse? - -The Nautilus was then some hundreds of miles from the nearest coast. - -The lieutenant had taken up the glass and examined the horizon steadfastly, going and coming, stamping his foot and showing more nervous agitation than his superior officer. Besides, this mystery must necessarily be solved, and before long; for, upon an order from Captain Nemo, the engine, increasing its propelling power, made the screw turn more rapidly. - -Just then the lieutenant drew the Captain's attention again. The latter stopped walking and directed his glass towards the place indicated. He looked long. I felt very much puzzled, and descended to the drawing-room, and took out an excellent telescope that I generally used. Then, leaning on the cage of the watch-light that jutted out from the front of the platform, set myself to look over all the line of the sky and sea. - -But my eye was no sooner applied to the glass than it was quickly snatched out of my hands. - -I turned round. Captain Nemo was before me, but I did not know him. His face was transfigured. His eyes flashed sullenly; his teeth were set; his stiff body, clenched fists, and head shrunk between his shoulders, betrayed the violent agitation that pervaded his whole frame. He did not move. My glass, fallen from his hands, had rolled at his feet. - -Had I unwittingly provoked this fit of anger? Did this incomprehensible person imagine that I had discovered some forbidden secret? No; I was not the object of this hatred, for he was not looking at me; his eye was steadily fixed upon the impenetrable point of the horizon. At last Captain Nemo recovered himself. His agitation subsided. He addressed some words in a foreign language to his lieutenant, then turned to me. "M. Aronnax," he said, in rather an imperious tone, "I require you to keep one of the conditions that bind you to me." - -"What is it, Captain?" - -"You must be confined, with your companions, until I think fit to release you." - -"You are the master," I replied, looking steadily at him. "But may I ask you one question?" - -"None, sir." - -There was no resisting this imperious command, it would have been useless. I went down to the cabin occupied by Ned Land and Conseil, and told them the Captain's determination. You may judge how this communication was received by the Canadian. - -But there was not time for altercation. Four of the crew waited at the door, and conducted us to that cell where we had passed our first night on board the Nautilus. - -Ned Land would have remonstrated, but the door was shut upon him. - -"Will master tell me what this means?" asked Conseil. - -I told my companions what had passed. They were as much astonished as I, and equally at a loss how to account for it. - -Meanwhile, I was absorbed in my own reflections, and could think of nothing but the strange fear depicted in the Captain's countenance. I was utterly at a loss to account for it, when my cogitations were disturbed by these words from Ned Land: - -"Hallo! breakfast is ready." - -And indeed the table was laid. Evidently Captain Nemo had given this order at the same time that he had hastened the speed of the Nautilus. - -"Will master permit me to make a recommendation?" asked Conseil. - -"Yes, my boy." - -"Well, it is that master breakfasts. It is prudent, for we do not know what may happen." - -"You are right, Conseil." - -"Unfortunately," said Ned Land, "they have only given us the ship's fare." - -"Friend Ned," asked Conseil, "what would you have said if the breakfast had been entirely forgotten?" - -This argument cut short the harpooner's recriminations. - -We sat down to table. The meal was eaten in silence. - -Just then the luminous globe that lighted the cell went out, and left us in total darkness. Ned Land was soon asleep, and what astonished me was that Conseil went off into a heavy slumber. I was thinking what could have caused his irresistible drowsiness, when I felt my brain becoming stupefied. In spite of my efforts to keep my eyes open, they would close. A painful suspicion seized me. Evidently soporific substances had been mixed with the food we had just taken. Imprisonment was not enough to conceal Captain Nemo's projects from us, sleep was more necessary. I then heard the panels shut. The undulations of the sea, which caused a slight rolling motion, ceased. Had the Nautilus quitted the surface of the ocean? Had it gone back to the motionless bed of water? I tried to resist sleep. It was impossible. My breathing grew weak. I felt a mortal cold freeze my stiffened and half-paralysed limbs. My eye lids, like leaden caps, fell over my eyes. I could not raise them; a morbid sleep, full of hallucinations, bereft me of my being. Then the visions disappeared, and left me in complete insensibility. - - - - -CHAPTER XXIII - -THE CORAL KINGDOM - -The next day I woke with my head singularly clear. To my great surprise, I was in my own room. My companions, no doubt, had been reinstated in their cabin, without having perceived it any more than I. Of what had passed during the night they were as ignorant as I was, and to penetrate this mystery I only reckoned upon the chances of the future. - -I then thought of quitting my room. Was I free again or a prisoner? Quite free. I opened the door, went to the half-deck, went up the central stairs. The panels, shut the evening before, were open. I went on to the platform. - -Ned Land and Conseil waited there for me. I questioned them; they knew nothing. Lost in a heavy sleep in which they had been totally unconscious, they had been astonished at finding themselves in their cabin. - -As for the Nautilus, it seemed quiet and mysterious as ever. It floated on the surface of the waves at a moderate pace. Nothing seemed changed on board. - -The second lieutenant then came on to the platform, and gave the usual order below. - -As for Captain Nemo, he did not appear. - -Of the people on board, I only saw the impassive steward, who served me with his usual dumb regularity. - -About two o'clock, I was in the drawing-room, busied in arranging my notes, when the Captain opened the door and appeared. I bowed. He made a slight inclination in return, without speaking. I resumed my work, hoping that he would perhaps give me some explanation of the events of the preceding night. He made none. I looked at him. He seemed fatigued; his heavy eyes had not been refreshed by sleep; his face looked very sorrowful. He walked to and fro, sat down and got up again, took a chance book, put it down, consulted his instruments without taking his habitual notes, and seemed restless and uneasy. At last, he came up to me, and said: - -"Are you a doctor, M. Aronnax?" - -I so little expected such a question that I stared some time at him without answering. - -"Are you a doctor?" he repeated. "Several of your colleagues have studied medicine." - -"Well," said I, "I am a doctor and resident surgeon to the hospital. I practised several years before entering the museum." - -"Very well, sir." - -My answer had evidently satisfied the Captain. But, not knowing what he would say next, I waited for other questions, reserving my answers according to circumstances. - -"M. Aronnax, will you consent to prescribe for one of my men?" he asked. - -"Is he ill?" - -"Yes." - -"I am ready to follow you." - -"Come, then." - -I own my heart beat, I do not know why. I saw certain connection between the illness of one of the crew and the events of the day before; and this mystery interested me at least as much as the sick man. - -Captain Nemo conducted me to the poop of the Nautilus, and took me into a cabin situated near the sailors' quarters. - -There, on a bed, lay a man about forty years of age, with a resolute expression of countenance, a true type of an Anglo-Saxon. - -I leant over him. He was not only ill, he was wounded. His head, swathed in bandages covered with blood, lay on a pillow. I undid the bandages, and the wounded man looked at me with his large eyes and gave no sign of pain as I did it. It was a horrible wound. The skull, shattered by some deadly weapon, left the brain exposed, which was much injured. Clots of blood had formed in the bruised and broken mass, in colour like the dregs of wine. - -There was both contusion and suffusion of the brain. His breathing was slow, and some spasmodic movements of the muscles agitated his face. I felt his pulse. It was intermittent. The extremities of the body were growing cold already, and I saw death must inevitably ensue. After dressing the unfortunate man's wounds, I readjusted the bandages on his head, and turned to Captain Nemo. - -"What caused this wound?" I asked. - -"What does it signify?" he replied, evasively. "A shock has broken one of the levers of the engine, which struck myself. But your opinion as to his state?" - -I hesitated before giving it. - -"You may speak," said the Captain. "This man does not understand French." - -I gave a last look at the wounded man. - -"He will be dead in two hours." - -"Can nothing save him?" - -"Nothing." - -Captain Nemo's hand contracted, and some tears glistened in his eyes, which I thought incapable of shedding any. - -For some moments I still watched the dying man, whose life ebbed slowly. His pallor increased under the electric light that was shed over his death-bed. I looked at his intelligent forehead, furrowed with premature wrinkles, produced probably by misfortune and sorrow. I tried to learn the secret of his life from the last words that escaped his lips. - -"You can go now, M. Aronnax," said the Captain. - -I left him in the dying man's cabin, and returned to my room much affected by this scene. During the whole day, I was haunted by uncomfortable suspicions, and at night I slept badly, and between my broken dreams I fancied I heard distant sighs like the notes of a funeral psalm. Were they the prayers of the dead, murmured in that language that I could not understand? - -The next morning I went on to the bridge. Captain Nemo was there before me. As soon as he perceived me he came to me. - -"Professor, will it be convenient to you to make a submarine excursion to-day?" - -"With my companions?" I asked. - -"If they like." - -"We obey your orders, Captain." - -"Will you be so good then as to put on your cork jackets?" - -It was not a question of dead or dying. I rejoined Ned Land and Conseil, and told them of Captain Nemo's proposition. Conseil hastened to accept it, and this time the Canadian seemed quite willing to follow our example. - -It was eight o'clock in the morning. At half-past eight we were equipped for this new excursion, and provided with two contrivances for light and breathing. The double door was open; and, accompanied by Captain Nemo, who was followed by a dozen of the crew, we set foot, at a depth of about thirty feet, on the solid bottom on which the Nautilus rested. - -A slight declivity ended in an uneven bottom, at fifteen fathoms depth. This bottom differed entirely from the one I had visited on my first excursion under the waters of the Pacific Ocean. Here, there was no fine sand, no submarine prairies, no sea-forest. I immediately recognised that marvellous region in which, on that day, the Captain did the honours to us. It was the coral kingdom. - -The light produced a thousand charming varieties, playing in the midst of the branches that were so vividly coloured. I seemed to see the membraneous and cylindrical tubes tremble beneath the undulation of the waters. I was tempted to gather their fresh petals, ornamented with delicate tentacles, some just blown, the others budding, while a small fish, swimming swiftly, touched them slightly, like flights of birds. But if my hand approached these living flowers, these animated, sensitive plants, the whole colony took alarm. The white petals re-entered their red cases, the flowers faded as I looked, and the bush changed into a block of stony knobs. - -Chance had thrown me just by the most precious specimens of the zoophyte. This coral was more valuable than that found in the Mediterranean, on the coasts of France, Italy and Barbary. Its tints justified the poetical names of "Flower of Blood," and "Froth of Blood," that trade has given to its most beautiful productions. Coral is sold for L20 per ounce; and in this place the watery beds would make the fortunes of a company of coral-divers. This precious matter, often confused with other polypi, formed then the inextricable plots called "macciota," and on which I noticed several beautiful specimens of pink coral. - -But soon the bushes contract, and the arborisations increase. Real petrified thickets, long joints of fantastic architecture, were disclosed before us. Captain Nemo placed himself under a dark gallery, where by a slight declivity we reached a depth of a hundred yards. The light from our lamps produced sometimes magical effects, following the rough outlines of the natural arches and pendants disposed like lustres, that were tipped with points of fire. - -At last, after walking two hours, we had attained a depth of about three hundred yards, that is to say, the extreme limit on which coral begins to form. But there was no isolated bush, nor modest brushwood, at the bottom of lofty trees. It was an immense forest of large mineral vegetations, enormous petrified trees, united by garlands of elegant sea-bindweed, all adorned with clouds and reflections. We passed freely under their high branches, lost in the shade of the waves. - -Captain Nemo had stopped. I and my companions halted, and, turning round, I saw his men were forming a semi-circle round their chief. Watching attentively, I observed that four of them carried on their shoulders an object of an oblong shape. - -We occupied, in this place, the centre of a vast glade surrounded by the lofty foliage of the submarine forest. Our lamps threw over this place a sort of clear twilight that singularly elongated the shadows on the ground. At the end of the glade the darkness increased, and was only relieved by little sparks reflected by the points of coral. - -Ned Land and Conseil were near me. We watched, and I thought I was going to witness a strange scene. On observing the ground, I saw that it was raised in certain places by slight excrescences encrusted with limy deposits, and disposed with a regularity that betrayed the hand of man. - -In the midst of the glade, on a pedestal of rocks roughly piled up, stood a cross of coral that extended its long arms that one might have thought were made of petrified blood. Upon a sign from Captain Nemo one of the men advanced; and at some feet from the cross he began to dig a hole with a pickaxe that he took from his belt. I understood all! This glade was a cemetery, this hole a tomb, this oblong object the body of the man who had died in the night! The Captain and his men had come to bury their companion in this general resting-place, at the bottom of this inaccessible ocean! - -The grave was being dug slowly; the fish fled on all sides while their retreat was being thus disturbed; I heard the strokes of the pickaxe, which sparkled when it hit upon some flint lost at the bottom of the waters. The hole was soon large and deep enough to receive the body. Then the bearers approached; the body, enveloped in a tissue of white linen, was lowered into the damp grave. Captain Nemo, with his arms crossed on his breast, and all the friends of him who had loved them, knelt in prayer. - -The grave was then filled in with the rubbish taken from the ground, which formed a slight mound. When this was done, Captain Nemo and his men rose; then, approaching the grave, they knelt again, and all extended their hands in sign of a last adieu. Then the funeral procession returned to the Nautilus, passing under the arches of the forest, in the midst of thickets, along the coral bushes, and still on the ascent. At last the light of the ship appeared, and its luminous track guided us to the Nautilus. At one o'clock we had returned. - -As soon as I had changed my clothes I went up on to the platform, and, a prey to conflicting emotions, I sat down near the binnacle. Captain Nemo joined me. I rose and said to him: - -"So, as I said he would, this man died in the night?" - -"Yes, M. Aronnax." - -"And he rests now, near his companions, in the coral cemetery?" - -"Yes, forgotten by all else, but not by us. We dug the grave, and the polypi undertake to seal our dead for eternity." And, burying his face quickly in his hands, he tried in vain to suppress a sob. Then he added: "Our peaceful cemetery is there, some hundred feet below the surface of the waves." - -"Your dead sleep quietly, at least, Captain, out of the reach of sharks." - -"Yes, sir, of sharks and men," gravely replied the Captain. - - - - -PART TWO - - - - -CHAPTER I - -THE INDIAN OCEAN - -We now come to the second part of our journey under the sea. The first ended with the moving scene in the coral cemetery which left such a deep impression on my mind. Thus, in the midst of this great sea, Captain Nemo's life was passing, even to his grave, which he had prepared in one of its deepest abysses. There, not one of the ocean's monsters could trouble the last sleep of the crew of the Nautilus, of those friends riveted to each other in death as in life. "Nor any man, either," had added the Captain. Still the same fierce, implacable defiance towards human society! - -I could no longer content myself with the theory which satisfied Conseil. - -That worthy fellow persisted in seeing in the Commander of the Nautilus one of those unknown servants who return mankind contempt for indifference. For him, he was a misunderstood genius who, tired of earth's deceptions, had taken refuge in this inaccessible medium, where he might follow his instincts freely. To my mind, this explains but one side of Captain Nemo's character. Indeed, the mystery of that last night during which we had been chained in prison, the sleep, and the precaution so violently taken by the Captain of snatching from my eyes the glass I had raised to sweep the horizon, the mortal wound of the man, due to an unaccountable shock of the Nautilus, all put me on a new track. No; Captain Nemo was not satisfied with shunning man. His formidable apparatus not only suited his instinct of freedom, but perhaps also the design of some terrible retaliation. - -At this moment nothing is clear to me; I catch but a glimpse of light amidst all the darkness, and I must confine myself to writing as events shall dictate. - -That day, the 24th of January, 1868, at noon, the second officer came to take the altitude of the sun. I mounted the platform, lit a cigar, and watched the operation. It seemed to me that the man did not understand French; for several times I made remarks in a loud voice, which must have drawn from him some involuntary sign of attention, if he had understood them; but he remained undisturbed and dumb. - -As he was taking observations with the sextant, one of the sailors of the Nautilus (the strong man who had accompanied us on our first submarine excursion to the Island of Crespo) came to clean the glasses of the lantern. I examined the fittings of the apparatus, the strength of which was increased a hundredfold by lenticular rings, placed similar to those in a lighthouse, and which projected their brilliance in a horizontal plane. The electric lamp was combined in such a way as to give its most powerful light. Indeed, it was produced in vacuo, which insured both its steadiness and its intensity. This vacuum economised the graphite points between which the luminous arc was developed—an important point of economy for Captain Nemo, who could not easily have replaced them; and under these conditions their waste was imperceptible. When the Nautilus was ready to continue its submarine journey, I went down to the saloon. The panel was closed, and the course marked direct west. - -We were furrowing the waters of the Indian Ocean, a vast liquid plain, with a surface of 1,200,000,000 of acres, and whose waters are so clear and transparent that any one leaning over them would turn giddy. The Nautilus usually floated between fifty and a hundred fathoms deep. We went on so for some days. To anyone but myself, who had a great love for the sea, the hours would have seemed long and monotonous; but the daily walks on the platform, when I steeped myself in the reviving air of the ocean, the sight of the rich waters through the windows of the saloon, the books in the library, the compiling of my memoirs, took up all my time, and left me not a moment of ennui or weariness. - -For some days we saw a great number of aquatic birds, sea-mews or gulls. Some were cleverly killed and, prepared in a certain way, made very acceptable water-game. Amongst large-winged birds, carried a long distance from all lands and resting upon the waves from the fatigue of their flight, I saw some magnificent albatrosses, uttering discordant cries like the braying of an ass, and birds belonging to the family of the long-wings. - -As to the fish, they always provoked our admiration when we surprised the secrets of their aquatic life through the open panels. I saw many kinds which I never before had a chance of observing. - -I shall notice chiefly ostracions peculiar to the Red Sea, the Indian Ocean, and that part which washes the coast of tropical America. These fishes, like the tortoise, the armadillo, the sea-hedgehog, and the Crustacea, are protected by a breastplate which is neither chalky nor stony, but real bone. In some it takes the form of a solid triangle, in others of a solid quadrangle. Amongst the triangular I saw some an inch and a half in length, with wholesome flesh and a delicious flavour; they are brown at the tail, and yellow at the fins, and I recommend their introduction into fresh water, to which a certain number of sea-fish easily accustom themselves. I would also mention quadrangular ostracions, having on the back four large tubercles; some dotted over with white spots on the lower part of the body, and which may be tamed like birds; trigons provided with spikes formed by the lengthening of their bony shell, and which, from their strange gruntings, are called "seapigs"; also dromedaries with large humps in the shape of a cone, whose flesh is very tough and leathery. - -I now borrow from the daily notes of Master Conseil. "Certain fish of the genus petrodon peculiar to those seas, with red backs and white chests, which are distinguished by three rows of longitudinal filaments; and some electrical, seven inches long, decked in the liveliest colours. Then, as specimens of other kinds, some ovoides, resembling an egg of a dark brown colour, marked with white bands, and without tails; diodons, real sea-porcupines, furnished with spikes, and capable of swelling in such a way as to look like cushions bristling with darts; hippocampi, common to every ocean; some pegasi with lengthened snouts, which their pectoral fins, being much elongated and formed in the shape of wings, allow, if not to fly, at least to shoot into the air; pigeon spatulae, with tails covered with many rings of shell; macrognathi with long jaws, an excellent fish, nine inches long, and bright with most agreeable colours; pale-coloured calliomores, with rugged heads; and plenty of chaetpdons, with long and tubular muzzles, which kill insects by shooting them, as from an air-gun, with a single drop of water. These we may call the flycatchers of the seas. - -"In the eighty-ninth genus of fishes, classed by Lacepede, belonging to the second lower class of bony, characterised by opercules and bronchial membranes, I remarked the scorpaena, the head of which is furnished with spikes, and which has but one dorsal fin; these creatures are covered, or not, with little shells, according to the sub-class to which they belong. The second sub-class gives us specimens of didactyles fourteen or fifteen inches in length, with yellow rays, and heads of a most fantastic appearance. As to the first sub-class, it gives several specimens of that singular looking fish appropriately called a 'seafrog,' with large head, sometimes pierced with holes, sometimes swollen with protuberances, bristling with spikes, and covered with tubercles; it has irregular and hideous horns; its body and tail are covered with callosities; its sting makes a dangerous wound; it is both repugnant and horrible to look at." - -From the 21st to the 23rd of January the Nautilus went at the rate of two hundred and fifty leagues in twenty-four hours, being five hundred and forty miles, or twenty-two miles an hour. If we recognised so many different varieties of fish, it was because, attracted by the electric light, they tried to follow us; the greater part, however, were soon distanced by our speed, though some kept their place in the waters of the Nautilus for a time. The morning of the 24th, in 12° 5' S. lat., and 94° 33' long., we observed Keeling Island, a coral formation, planted with magnificent cocos, and which had been visited by Mr. Darwin and Captain Fitzroy. The Nautilus skirted the shores of this desert island for a little distance. Its nets brought up numerous specimens of polypi and curious shells of mollusca. Some precious productions of the species of delphinulae enriched the treasures of Captain Nemo, to which I added an astraea punctifera, a kind of parasite polypus often found fixed to a shell. - -Soon Keeling Island disappeared from the horizon, and our course was directed to the north-west in the direction of the Indian Peninsula. - -From Keeling Island our course was slower and more variable, often taking us into great depths. Several times they made use of the inclined planes, which certain internal levers placed obliquely to the waterline. In that way we went about two miles, but without ever obtaining the greatest depths of the Indian Sea, which soundings of seven thousand fathoms have never reached. As to the temperature of the lower strata, the thermometer invariably indicated 4° above zero. I only observed that in the upper regions the water was always colder in the high levels than at the surface of the sea. - -On the 25th of January the ocean was entirely deserted; the Nautilus passed the day on the surface, beating the waves with its powerful screw and making them rebound to a great height. Who under such circumstances would not have taken it for a gigantic cetacean? Three parts of this day I spent on the platform. I watched the sea. Nothing on the horizon, till about four o'clock a steamer running west on our counter. Her masts were visible for an instant, but she could not see the Nautilus, being too low in the water. I fancied this steamboat belonged to the P.O. Company, which runs from Ceylon to Sydney, touching at King George's Point and Melbourne. - -At five o'clock in the evening, before that fleeting twilight which binds night to day in tropical zones, Conseil and I were astonished by a curious spectacle. - -It was a shoal of argonauts travelling along on the surface of the ocean. We could count several hundreds. They belonged to the tubercle kind which are peculiar to the Indian seas. - -These graceful molluscs moved backwards by means of their locomotive tube, through which they propelled the water already drawn in. Of their eight tentacles, six were elongated, and stretched out floating on the water, whilst the other two, rolled up flat, were spread to the wing like a light sail. I saw their spiral-shaped and fluted shells, which Cuvier justly compares to an elegant skiff. A boat indeed! It bears the creature which secretes it without its adhering to it. - -For nearly an hour the Nautilus floated in the midst of this shoal of molluscs. Then I know not what sudden fright they took. But as if at a signal every sail was furled, the arms folded, the body drawn in, the shells turned over, changing their centre of gravity, and the whole fleet disappeared under the waves. Never did the ships of a squadron manoeuvre with more unity. - -At that moment night fell suddenly, and the reeds, scarcely raised by the breeze, lay peaceably under the sides of the Nautilus. - -The next day, 26th of January, we cut the equator at the eighty-second meridian and entered the northern hemisphere. During the day a formidable troop of sharks accompanied us, terrible creatures, which multiply in these seas and make them very dangerous. They were "cestracio philippi" sharks, with brown backs and whitish bellies, armed with eleven rows of teeth—eyed sharks—their throat being marked with a large black spot surrounded with white like an eye. There were also some Isabella sharks, with rounded snouts marked with dark spots. These powerful creatures often hurled themselves at the windows of the saloon with such violence as to make us feel very insecure. At such times Ned Land was no longer master of himself. He wanted to go to the surface and harpoon the monsters, particularly certain smooth-hound sharks, whose mouth is studded with teeth like a mosaic; and large tiger-sharks nearly six yards long, the last named of which seemed to excite him more particularly. But the Nautilus, accelerating her speed, easily left the most rapid of them behind. - -The 27th of January, at the entrance of the vast Bay of Bengal, we met repeatedly a forbidding spectacle, dead bodies floating on the surface of the water. They were the dead of the Indian villages, carried by the Ganges to the level of the sea, and which the vultures, the only undertakers of the country, had not been able to devour. But the sharks did not fail to help them at their funeral work. - -About seven o'clock in the evening, the Nautilus, half-immersed, was sailing in a sea of milk. At first sight the ocean seemed lactified. Was it the effect of the lunar rays? No; for the moon, scarcely two days old, was still lying hidden under the horizon in the rays of the sun. The whole sky, though lit by the sidereal rays, seemed black by contrast with the whiteness of the waters. - -Conseil could not believe his eyes, and questioned me as to the cause of this strange phenomenon. Happily I was able to answer him. - -"It is called a milk sea," I explained. "A large extent of white wavelets often to be seen on the coasts of Amboyna, and in these parts of the sea." - -"But, sir," said Conseil, "can you tell me what causes such an effect? for I suppose the water is not really turned into milk." - -"No, my boy; and the whiteness which surprises you is caused only by the presence of myriads of infusoria, a sort of luminous little worm, gelatinous and without colour, of the thickness of a hair, and whose length is not more than seven-thousandths of an inch. These insects adhere to one another sometimes for several leagues." - -"Several leagues!" exclaimed Conseil. - -"Yes, my boy; and you need not try to compute the number of these infusoria. You will not be able, for, if I am not mistaken, ships have floated on these milk seas for more than forty miles." - -Towards midnight the sea suddenly resumed its usual colour; but behind us, even to the limits of the horizon, the sky reflected the whitened waves, and for a long time seemed impregnated with the vague glimmerings of an aurora borealis. - - - - -CHAPTER II - -A NOVEL PROPOSAL OF CAPTAIN NEMO'S - -On the 28th of February, when at noon the Nautilus came to the surface of the sea, in 9° 4' N. lat., there was land in sight about eight miles to westward. The first thing I noticed was a range of mountains about two thousand feet high, the shapes of which were most capricious. On taking the bearings, I knew that we were nearing the island of Ceylon, the pearl which hangs from the lobe of the Indian Peninsula. - -Captain Nemo and his second appeared at this moment. The Captain glanced at the map. Then turning to me, said: - -"The Island of Ceylon, noted for its pearl-fisheries. Would you like to visit one of them, M. Aronnax?" - -"Certainly, Captain." - -"Well, the thing is easy. Though, if we see the fisheries, we shall not see the fishermen. The annual exportation has not yet begun. Never mind, I will give orders to make for the Gulf of Manaar, where we shall arrive in the night." - -The Captain said something to his second, who immediately went out. Soon the Nautilus returned to her native element, and the manometer showed that she was about thirty feet deep. - -"Well, sir," said Captain Nemo, "you and your companions shall visit the Bank of Manaar, and if by chance some fisherman should be there, we shall see him at work." - -"Agreed, Captain!" - -"By the bye, M. Aronnax you are not afraid of sharks?" - -"Sharks!" exclaimed I. - -This question seemed a very hard one. - -"Well?" continued Captain Nemo. - -"I admit, Captain, that I am not yet very familiar with that kind of fish." - -"We are accustomed to them," replied Captain Nemo, "and in time you will be too. However, we shall be armed, and on the road we may be able to hunt some of the tribe. It is interesting. So, till to-morrow, sir, and early." - -This said in a careless tone, Captain Nemo left the saloon. Now, if you were invited to hunt the bear in the mountains of Switzerland, what would you say? - -"Very well! to-morrow we will go and hunt the bear." If you were asked to hunt the lion in the plains of Atlas, or the tiger in the Indian jungles, what would you say? - -"Ha! ha! it seems we are going to hunt the tiger or the lion!" But when you are invited to hunt the shark in its natural element, you would perhaps reflect before accepting the invitation. As for myself, I passed my hand over my forehead, on which stood large drops of cold perspiration. "Let us reflect," said I, "and take our time. Hunting otters in submarine forests, as we did in the Island of Crespo, will pass; but going up and down at the bottom of the sea, where one is almost certain to meet sharks, is quite another thing! I know well that in certain countries, particularly in the Andaman Islands, the negroes never hesitate to attack them with a dagger in one hand and a running noose in the other; but I also know that few who affront those creatures ever return alive. However, I am not a negro, and if I were I think a little hesitation in this case would not be ill-timed." - -At this moment Conseil and the Canadian entered, quite composed, and even joyous. They knew not what awaited them. - -"Faith, sir," said Ned Land, "your Captain Nemo—the devil take him!—has just made us a very pleasant offer." - -"Ah!" said I, "you know?" - -"If agreeable to you, sir," interrupted Conseil, "the commander of the Nautilus has invited us to visit the magnificent Ceylon fisheries to-morrow, in your company; he did it kindly, and behaved like a real gentleman." - -"He said nothing more?" - -"Nothing more, sir, except that he had already spoken to you of this little walk." - -"Sir," said Conseil, "would you give us some details of the pearl fishery?" - -"As to the fishing itself," I asked, "or the incidents, which?" - -"On the fishing," replied the Canadian; "before entering upon the ground, it is as well to know something about it." - -"Very well; sit down, my friends, and I will teach you." - -Ned and Conseil seated themselves on an ottoman, and the first thing the Canadian asked was: - -"Sir, what is a pearl?" - -"My worthy Ned," I answered, "to the poet, a pearl is a tear of the sea; to the Orientals, it is a drop of dew solidified; to the ladies, it is a jewel of an oblong shape, of a brilliancy of mother-of-pearl substance, which they wear on their fingers, their necks, or their ears; for the chemist it is a mixture of phosphate and carbonate of lime, with a little gelatine; and lastly, for naturalists, it is simply a morbid secretion of the organ that produces the mother-of-pearl amongst certain bivalves." - -"Branch of molluscs," said Conseil. - -"Precisely so, my learned Conseil; and, amongst these testacea the earshell, the tridacnae, the turbots, in a word, all those which secrete mother-of-pearl, that is, the blue, bluish, violet, or white substance which lines the interior of their shells, are capable of producing pearls." - -"Mussels too?" asked the Canadian. - -"Yes, mussels of certain waters in Scotland, Wales, Ireland, Saxony, Bohemia, and France." - -"Good! For the future I shall pay attention," replied the Canadian. - -"But," I continued, "the particular mollusc which secretes the pearl is the pearl-oyster, the meleagrina margaritiferct, that precious pintadine. The pearl is nothing but a nacreous formation, deposited in a globular form, either adhering to the oyster shell, or buried in the folds of the creature. On the shell it is fast; in the flesh it is loose; but always has for a kernel a small hard substance, may be a barren egg, may be a grain of sand, around which the pearly matter deposits itself year after year successively, and by thin concentric layers." - -"Are many pearls found in the same oyster?" asked Conseil. - -"Yes, my boy. Some are a perfect casket. One oyster has been mentioned, though I allow myself to doubt it, as having contained no less than a hundred and fifty sharks." - -"A hundred and fifty sharks!" exclaimed Ned Land. - -"Did I say sharks?" said I hurriedly. "I meant to say a hundred and fifty pearls. Sharks would not be sense." - -"Certainly not," said Conseil; "but will you tell us now by what means they extract these pearls?" - -"They proceed in various ways. When they adhere to the shell, the fishermen often pull them off with pincers; but the most common way is to lay the oysters on mats of the seaweed which covers the banks. Thus they die in the open air; and at the end of ten days they are in a forward state of decomposition. They are then plunged into large reservoirs of sea-water; then they are opened and washed." - -"The price of these pearls varies according to their size?" asked Conseil. - -"Not only according to their size," I answered, "but also according to their shape, their water (that is, their colour), and their lustre: that is, that bright and diapered sparkle which makes them so charming to the eye. The most beautiful are called virgin pearls, or paragons. They are formed alone in the tissue of the mollusc, are white, often opaque, and sometimes have the transparency of an opal; they are generally round or oval. The round are made into bracelets, the oval into pendants, and, being more precious, are sold singly. Those adhering to the shell of the oyster are more irregular in shape, and are sold by weight. Lastly, in a lower order are classed those small pearls known under the name of seed-pearls; they are sold by measure, and are especially used in embroidery for church ornaments." - -"But," said Conseil, "is this pearl-fishery dangerous?" - -"No," I answered, quickly; "particularly if certain precautions are taken." - -"What does one risk in such a calling?" said Ned Land, "the swallowing of some mouthfuls of sea-water?" - -"As you say, Ned. By the bye," said I, trying to take Captain Nemo's careless tone, "are you afraid of sharks, brave Ned?" - -"I!" replied the Canadian; "a harpooner by profession? It is my trade to make light of them." - -"But," said I, "it is not a question of fishing for them with an iron-swivel, hoisting them into the vessel, cutting off their tails with a blow of a chopper, ripping them up, and throwing their heart into the sea!" - -"Then, it is a question of——" - -"Precisely." - -"In the water?" - -"In the water." - -"Faith, with a good harpoon! You know, sir, these sharks are ill-fashioned beasts. They turn on their bellies to seize you, and in that time——" - -Ned Land had a way of saying "seize" which made my blood run cold. - -"Well, and you, Conseil, what do you think of sharks?" - -"Me!" said Conseil. "I will be frank, sir." - -"So much the better," thought I. - -"If you, sir, mean to face the sharks, I do not see why your faithful servant should not face them with you." - - - - -CHAPTER III - -A PEARL OF TEN MILLIONS - -The next morning at four o'clock I was awakened by the steward whom Captain Nemo had placed at my service. I rose hurriedly, dressed, and went into the saloon. - -Captain Nemo was awaiting me. - -"M. Aronnax," said he, "are you ready to start?" - -"I am ready." - -"Then please to follow me." - -"And my companions, Captain?" - -"They have been told and are waiting." - -"Are we not to put on our diver's dresses?" asked I. - -"Not yet. I have not allowed the Nautilus to come too near this coast, and we are some distance from the Manaar Bank; but the boat is ready, and will take us to the exact point of disembarking, which will save us a long way. It carries our diving apparatus, which we will put on when we begin our submarine journey." - -Captain Nemo conducted me to the central staircase, which led on the platform. Ned and Conseil were already there, delighted at the idea of the "pleasure party" which was preparing. Five sailors from the Nautilus, with their oars, waited in the boat, which had been made fast against the side. - -The night was still dark. Layers of clouds covered the sky, allowing but few stars to be seen. I looked on the side where the land lay, and saw nothing but a dark line enclosing three parts of the horizon, from south-west to north west. The Nautilus, having returned during the night up the western coast of Ceylon, was now west of the bay, or rather gulf, formed by the mainland and the Island of Manaar. There, under the dark waters, stretched the pintadine bank, an inexhaustible field of pearls, the length of which is more than twenty miles. - -Captain Nemo, Ned Land, Conseil, and I took our places in the stern of the boat. The master went to the tiller; his four companions leaned on their oars, the painter was cast off, and we sheered off. - -The boat went towards the south; the oarsmen did not hurry. I noticed that their strokes, strong in the water, only followed each other every ten seconds, according to the method generally adopted in the navy. Whilst the craft was running by its own velocity, the liquid drops struck the dark depths of the waves crisply like spats of melted lead. A little billow, spreading wide, gave a slight roll to the boat, and some samphire reeds flapped before it. - -We were silent. What was Captain Nemo thinking of? Perhaps of the land he was approaching, and which he found too near to him, contrary to the Canadian's opinion, who thought it too far off. As to Conseil, he was merely there from curiosity. - -About half-past five the first tints on the horizon showed the upper line of coast more distinctly. Flat enough in the east, it rose a little to the south. Five miles still lay between us, and it was indistinct owing to the mist on the water. At six o'clock it became suddenly daylight, with that rapidity peculiar to tropical regions, which know neither dawn nor twilight. The solar rays pierced the curtain of clouds, piled up on the eastern horizon, and the radiant orb rose rapidly. I saw land distinctly, with a few trees scattered here and there. The boat neared Manaar Island, which was rounded to the south. Captain Nemo rose from his seat and watched the sea. - -At a sign from him the anchor was dropped, but the chain scarcely ran, for it was little more than a yard deep, and this spot was one of the highest points of the bank of pintadines. - -"Here we are, M. Aronnax," said Captain Nemo. "You see that enclosed bay? Here, in a month will be assembled the numerous fishing boats of the exporters, and these are the waters their divers will ransack so boldly. Happily, this bay is well situated for that kind of fishing. It is sheltered from the strongest winds; the sea is never very rough here, which makes it favourable for the diver's work. We will now put on our dresses, and begin our walk." - -I did not answer, and, while watching the suspected waves, began with the help of the sailors to put on my heavy sea-dress. Captain Nemo and my companions were also dressing. None of the Nautilus men were to accompany us on this new excursion. - -Soon we were enveloped to the throat in india-rubber clothing; the air apparatus fixed to our backs by braces. As to the Ruhmkorff apparatus, there was no necessity for it. Before putting my head into the copper cap, I had asked the question of the Captain. - -"They would be useless," he replied. "We are going to no great depth, and the solar rays will be enough to light our walk. Besides, it would not be prudent to carry the electric light in these waters; its brilliancy might attract some of the dangerous inhabitants of the coast most inopportunely." - -As Captain Nemo pronounced these words, I turned to Conseil and Ned Land. But my two friends had already encased their heads in the metal cap, and they could neither hear nor answer. - -One last question remained to ask of Captain Nemo. - -"And our arms?" asked I; "our guns?" - -"Guns! What for? Do not mountaineers attack the bear with a dagger in their hand, and is not steel surer than lead? Here is a strong blade; put it in your belt, and we start." - -I looked at my companions; they were armed like us, and, more than that, Ned Land was brandishing an enormous harpoon, which he had placed in the boat before leaving the Nautilus. - -Then, following the Captain's example, I allowed myself to be dressed in the heavy copper helmet, and our reservoirs of air were at once in activity. An instant after we were landed, one after the other, in about two yards of water upon an even sand. Captain Nemo made a sign with his hand, and we followed him by a gentle declivity till we disappeared under the waves. - -Over our feet, like coveys of snipe in a bog, rose shoals of fish, of the genus monoptera, which have no other fins but their tail. I recognized the Javanese, a real serpent two and a half feet long, of a livid colour underneath, and which might easily be mistaken for a conger eel if it were not for the golden stripes on its side. In the genus stromateus, whose bodies are very flat and oval, I saw some of the most brilliant colours, carrying their dorsal fin like a scythe; an excellent eating fish, which, dried and pickled, is known by the name of Karawade; then some tranquebars, belonging to the genus apsiphoroides, whose body is covered with a shell cuirass of eight longitudinal plates. - -The heightening sun lit the mass of waters more and more. The soil changed by degrees. To the fine sand succeeded a perfect causeway of boulders, covered with a carpet of molluscs and zoophytes. Amongst the specimens of these branches I noticed some placenae, with thin unequal shells, a kind of ostracion peculiar to the Red Sea and the Indian Ocean; some orange lucinae with rounded shells; rockfish three feet and a half long, which raised themselves under the waves like hands ready to seize one. There were also some panopyres, slightly luminous; and lastly, some oculines, like magnificent fans, forming one of the richest vegetations of these seas. - -In the midst of these living plants, and under the arbours of the hydrophytes, were layers of clumsy articulates, particularly some raninae, whose carapace formed a slightly rounded triangle; and some horrible looking parthenopes. - -At about seven o'clock we found ourselves at last surveying the oyster-banks on which the pearl-oysters are reproduced by millions. - -Captain Nemo pointed with his hand to the enormous heap of oysters; and I could well understand that this mine was inexhaustible, for Nature's creative power is far beyond man's instinct of destruction. Ned Land, faithful to his instinct, hastened to fill a net which he carried by his side with some of the finest specimens. But we could not stop. We must follow the Captain, who seemed to guide him self by paths known only to himself. The ground was sensibly rising, and sometimes, on holding up my arm, it was above the surface of the sea. Then the level of the bank would sink capriciously. Often we rounded high rocks scarped into pyramids. In their dark fractures huge crustacea, perched upon their high claws like some war-machine, watched us with fixed eyes, and under our feet crawled various kinds of annelides. - -At this moment there opened before us a large grotto dug in a picturesque heap of rocks and carpeted with all the thick warp of the submarine flora. At first it seemed very dark to me. The solar rays seemed to be extinguished by successive gradations, until its vague transparency became nothing more than drowned light. Captain Nemo entered; we followed. My eyes soon accustomed themselves to this relative state of darkness. I could distinguish the arches springing capriciously from natural pillars, standing broad upon their granite base, like the heavy columns of Tuscan architecture. Why had our incomprehensible guide led us to the bottom of this submarine crypt? I was soon to know. After descending a rather sharp declivity, our feet trod the bottom of a kind of circular pit. There Captain Nemo stopped, and with his hand indicated an object I had not yet perceived. It was an oyster of extraordinary dimensions, a gigantic tridacne, a goblet which could have contained a whole lake of holy-water, a basin the breadth of which was more than two yards and a half, and consequently larger than that ornamenting the saloon of the Nautilus. I approached this extraordinary mollusc. It adhered by its filaments to a table of granite, and there, isolated, it developed itself in the calm waters of the grotto. I estimated the weight of this tridacne at 600 lb. Such an oyster would contain 30 lb. of meat; and one must have the stomach of a Gargantua to demolish some dozens of them. - -Captain Nemo was evidently acquainted with the existence of this bivalve, and seemed to have a particular motive in verifying the actual state of this tridacne. The shells were a little open; the Captain came near and put his dagger between to prevent them from closing; then with his hand he raised the membrane with its fringed edges, which formed a cloak for the creature. There, between the folded plaits, I saw a loose pearl, whose size equalled that of a coco-nut. Its globular shape, perfect clearness, and admirable lustre made it altogether a jewel of inestimable value. Carried away by my curiosity, I stretched out my hand to seize it, weigh it, and touch it; but the Captain stopped me, made a sign of refusal, and quickly withdrew his dagger, and the two shells closed suddenly. I then understood Captain Nemo's intention. In leaving this pearl hidden in the mantle of the tridacne he was allowing it to grow slowly. Each year the secretions of the mollusc would add new concentric circles. I estimated its value at L500,000 at least. - -After ten minutes Captain Nemo stopped suddenly. I thought he had halted previously to returning. No; by a gesture he bade us crouch beside him in a deep fracture of the rock, his hand pointed to one part of the liquid mass, which I watched attentively. - -About five yards from me a shadow appeared, and sank to the ground. The disquieting idea of sharks shot through my mind, but I was mistaken; and once again it was not a monster of the ocean that we had anything to do with. - -It was a man, a living man, an Indian, a fisherman, a poor devil who, I suppose, had come to glean before the harvest. I could see the bottom of his canoe anchored some feet above his head. He dived and went up successively. A stone held between his feet, cut in the shape of a sugar loaf, whilst a rope fastened him to his boat, helped him to descend more rapidly. This was all his apparatus. Reaching the bottom, about five yards deep, he went on his knees and filled his bag with oysters picked up at random. Then he went up, emptied it, pulled up his stone, and began the operation once more, which lasted thirty seconds. - -The diver did not see us. The shadow of the rock hid us from sight. And how should this poor Indian ever dream that men, beings like himself, should be there under the water watching his movements and losing no detail of the fishing? Several times he went up in this way, and dived again. He did not carry away more than ten at each plunge, for he was obliged to pull them from the bank to which they adhered by means of their strong byssus. And how many of those oysters for which he risked his life had no pearl in them! I watched him closely; his manoeuvres were regular; and for the space of half an hour no danger appeared to threaten him. - -I was beginning to accustom myself to the sight of this interesting fishing, when suddenly, as the Indian was on the ground, I saw him make a gesture of terror, rise, and make a spring to return to the surface of the sea. - -I understood his dread. A gigantic shadow appeared just above the unfortunate diver. It was a shark of enormous size advancing diagonally, his eyes on fire, and his jaws open. I was mute with horror and unable to move. - -The voracious creature shot towards the Indian, who threw himself on one side to avoid the shark's fins; but not its tail, for it struck his chest and stretched him on the ground. - -This scene lasted but a few seconds: the shark returned, and, turning on his back, prepared himself for cutting the Indian in two, when I saw Captain Nemo rise suddenly, and then, dagger in hand, walk straight to the monster, ready to fight face to face with him. The very moment the shark was going to snap the unhappy fisherman in two, he perceived his new adversary, and, turning over, made straight towards him. - -I can still see Captain Nemo's position. Holding himself well together, he waited for the shark with admirable coolness; and, when it rushed at him, threw himself on one side with wonderful quickness, avoiding the shock, and burying his dagger deep into its side. But it was not all over. A terrible combat ensued. - -The shark had seemed to roar, if I might say so. The blood rushed in torrents from its wound. The sea was dyed red, and through the opaque liquid I could distinguish nothing more. Nothing more until the moment when, like lightning, I saw the undaunted Captain hanging on to one of the creature's fins, struggling, as it were, hand to hand with the monster, and dealing successive blows at his enemy, yet still unable to give a decisive one. - -The shark's struggles agitated the water with such fury that the rocking threatened to upset me. - -I wanted to go to the Captain's assistance, but, nailed to the spot with horror, I could not stir. - -I saw the haggard eye; I saw the different phases of the fight. The Captain fell to the earth, upset by the enormous mass which leant upon him. The shark's jaws opened wide, like a pair of factory shears, and it would have been all over with the Captain; but, quick as thought, harpoon in hand, Ned Land rushed towards the shark and struck it with its sharp point. - -The waves were impregnated with a mass of blood. They rocked under the shark's movements, which beat them with indescribable fury. Ned Land had not missed his aim. It was the monster's death-rattle. Struck to the heart, it struggled in dreadful convulsions, the shock of which overthrew Conseil. - -But Ned Land had disentangled the Captain, who, getting up without any wound, went straight to the Indian, quickly cut the cord which held him to his stone, took him in his arms, and, with a sharp blow of his heel, mounted to the surface. - -We all three followed in a few seconds, saved by a miracle, and reached the fisherman's boat. - -Captain Nemo's first care was to recall the unfortunate man to life again. I did not think he could succeed. I hoped so, for the poor creature's immersion was not long; but the blow from the shark's tail might have been his death-blow. - -Happily, with the Captain's and Conseil's sharp friction, I saw consciousness return by degrees. He opened his eyes. What was his surprise, his terror even, at seeing four great copper heads leaning over him! And, above all, what must he have thought when Captain Nemo, drawing from the pocket of his dress a bag of pearls, placed it in his hand! This munificent charity from the man of the waters to the poor Cingalese was accepted with a trembling hand. His wondering eyes showed that he knew not to what super-human beings he owed both fortune and life. - -At a sign from the Captain we regained the bank, and, following the road already traversed, came in about half an hour to the anchor which held the canoe of the Nautilus to the earth. - -Once on board, we each, with the help of the sailors, got rid of the heavy copper helmet. - -Captain Nemo's first word was to the Canadian. - -"Thank you, Master Land," said he. - -"It was in revenge, Captain," replied Ned Land. "I owed you that." - -A ghastly smile passed across the Captain's lips, and that was all. - -"To the Nautilus," said he. - -The boat flew over the waves. Some minutes after we met the shark's dead body floating. By the black marking of the extremity of its fins, I recognised the terrible melanopteron of the Indian Seas, of the species of shark so properly called. It was more than twenty-five feet long; its enormous mouth occupied one-third of its body. It was an adult, as was known by its six rows of teeth placed in an isosceles triangle in the upper jaw. - -Whilst I was contemplating this inert mass, a dozen of these voracious beasts appeared round the boat; and, without noticing us, threw themselves upon the dead body and fought with one another for the pieces. - -At half-past eight we were again on board the Nautilus. There I reflected on the incidents which had taken place in our excursion to the Manaar Bank. - -Two conclusions I must inevitably draw from it—one bearing upon the unparalleled courage of Captain Nemo, the other upon his devotion to a human being, a representative of that race from which he fled beneath the sea. Whatever he might say, this strange man had not yet succeeded in entirely crushing his heart. - -When I made this observation to him, he answered in a slightly moved tone: - -"That Indian, sir, is an inhabitant of an oppressed country; and I am still, and shall be, to my last breath, one of them!" - - - - -CHAPTER IV - -THE RED SEA - -In the course of the day of the 29th of January, the island of Ceylon disappeared under the horizon, and the Nautilus, at a speed of twenty miles an hour, slid into the labyrinth of canals which separate the Maldives from the Laccadives. It coasted even the Island of Kiltan, a land originally coraline, discovered by Vasco da Gama in 1499, and one of the nineteen principal islands of the Laccadive Archipelago, situated between 10° and 14° 30' N. lat., and 69° 50' 72" E. long. - -We had made 16,220 miles, or 7,500 (French) leagues from our starting-point in the Japanese Seas. - -The next day (30th January), when the Nautilus went to the surface of the ocean there was no land in sight. Its course was N.N.E., in the direction of the Sea of Oman, between Arabia and the Indian Peninsula, which serves as an outlet to the Persian Gulf. It was evidently a block without any possible egress. Where was Captain Nemo taking us to? I could not say. This, however, did not satisfy the Canadian, who that day came to me asking where we were going. - -"We are going where our Captain's fancy takes us, Master Ned." - -"His fancy cannot take us far, then," said the Canadian. "The Persian Gulf has no outlet: and, if we do go in, it will not be long before we are out again." - -"Very well, then, we will come out again, Master Land; and if, after the Persian Gulf, the Nautilus would like to visit the Red Sea, the Straits of Bab-el-mandeb are there to give us entrance." - -"I need not tell you, sir," said Ned Land, "that the Red Sea is as much closed as the Gulf, as the Isthmus of Suez is not yet cut; and, if it was, a boat as mysterious as ours would not risk itself in a canal cut with sluices. And again, the Red Sea is not the road to take us back to Europe." - -"But I never said we were going back to Europe." - -"What do you suppose, then?" - -"I suppose that, after visiting the curious coasts of Arabia and Egypt, the Nautilus will go down the Indian Ocean again, perhaps cross the Channel of Mozambique, perhaps off the Mascarenhas, so as to gain the Cape of Good Hope." - -"And once at the Cape of Good Hope?" asked the Canadian, with peculiar emphasis. - -"Well, we shall penetrate into that Atlantic which we do not yet know. Ah! friend Ned, you are getting tired of this journey under the sea; you are surfeited with the incessantly varying spectacle of submarine wonders. For my part, I shall be sorry to see the end of a voyage which it is given to so few men to make." - -For four days, till the 3rd of February, the Nautilus scoured the Sea of Oman, at various speeds and at various depths. It seemed to go at random, as if hesitating as to which road it should follow, but we never passed the Tropic of Cancer. - -In quitting this sea we sighted Muscat for an instant, one of the most important towns of the country of Oman. I admired its strange aspect, surrounded by black rocks upon which its white houses and forts stood in relief. I saw the rounded domes of its mosques, the elegant points of its minarets, its fresh and verdant terraces. But it was only a vision! The Nautilus soon sank under the waves of that part of the sea. - -We passed along the Arabian coast of Mahrah and Hadramaut, for a distance of six miles, its undulating line of mountains being occasionally relieved by some ancient ruin. The 5th of February we at last entered the Gulf of Aden, a perfect funnel introduced into the neck of Bab-el-mandeb, through which the Indian waters entered the Red Sea. - -The 6th of February, the Nautilus floated in sight of Aden, perched upon a promontory which a narrow isthmus joins to the mainland, a kind of inaccessible Gibraltar, the fortifications of which were rebuilt by the English after taking possession in 1839. I caught a glimpse of the octagon minarets of this town, which was at one time the richest commercial magazine on the coast. - -I certainly thought that Captain Nemo, arrived at this point, would back out again; but I was mistaken, for he did no such thing, much to my surprise. - -The next day, the 7th of February, we entered the Straits of Bab-el-mandeb, the name of which, in the Arab tongue, means The Gate of Tears. - -To twenty miles in breadth, it is only thirty-two in length. And for the Nautilus, starting at full speed, the crossing was scarcely the work of an hour. But I saw nothing, not even the Island of Perim, with which the British Government has fortified the position of Aden. There were too many English or French steamers of the line of Suez to Bombay, Calcutta to Melbourne, and from Bourbon to the Mauritius, furrowing this narrow passage, for the Nautilus to venture to show itself. So it remained prudently below. At last about noon, we were in the waters of the Red Sea. - -I would not even seek to understand the caprice which had decided Captain Nemo upon entering the gulf. But I quite approved of the Nautilus entering it. Its speed was lessened: sometimes it kept on the surface, sometimes it dived to avoid a vessel, and thus I was able to observe the upper and lower parts of this curious sea. - -The 8th of February, from the first dawn of day, Mocha came in sight, now a ruined town, whose walls would fall at a gunshot, yet which shelters here and there some verdant date-trees; once an important city, containing six public markets, and twenty-six mosques, and whose walls, defended by fourteen forts, formed a girdle of two miles in circumference. - -The Nautilus then approached the African shore, where the depth of the sea was greater. There, between two waters clear as crystal, through the open panels we were allowed to contemplate the beautiful bushes of brilliant coral and large blocks of rock clothed with a splendid fur of green variety of sites and landscapes along these sandbanks and algae and fuci. What an indescribable spectacle, and what variety of sites and landscapes along these sandbanks and volcanic islands which bound the Libyan coast! But where these shrubs appeared in all their beauty was on the eastern coast, which the Nautilus soon gained. It was on the coast of Tehama, for there not only did this display of zoophytes flourish beneath the level of the sea, but they also formed picturesque interlacings which unfolded themselves about sixty feet above the surface, more capricious but less highly coloured than those whose freshness was kept up by the vital power of the waters. - -What charming hours I passed thus at the window of the saloon! What new specimens of submarine flora and fauna did I admire under the brightness of our electric lantern! - -The 9th of February the Nautilus floated in the broadest part of the Red Sea, which is comprised between Souakin, on the west coast, and Komfidah, on the east coast, with a diameter of ninety miles. - -That day at noon, after the bearings were taken, Captain Nemo mounted the platform, where I happened to be, and I was determined not to let him go down again without at least pressing him regarding his ulterior projects. As soon as he saw me he approached and graciously offered me a cigar. - -"Well, sir, does this Red Sea please you? Have you sufficiently observed the wonders it covers, its fishes, its zoophytes, its parterres of sponges, and its forests of coral? Did you catch a glimpse of the towns on its borders?" - -"Yes, Captain Nemo," I replied; "and the Nautilus is wonderfully fitted for such a study. Ah! it is an intelligent boat!" - -"Yes, sir, intelligent and invulnerable. It fears neither the terrible tempests of the Red Sea, nor its currents, nor its sandbanks." - -"Certainly," said I, "this sea is quoted as one of the worst, and in the time of the ancients, if I am not mistaken, its reputation was detestable." - -"Detestable, M. Aronnax. The Greek and Latin historians do not speak favourably of it, and Strabo says it is very dangerous during the Etesian winds and in the rainy season. The Arabian Edrisi portrays it under the name of the Gulf of Colzoum, and relates that vessels perished there in great numbers on the sandbanks and that no one would risk sailing in the night. It is, he pretends, a sea subject to fearful hurricanes, strewn with inhospitable islands, and `which offers nothing good either on its surface or in its depths.'" - -"One may see," I replied, "that these historians never sailed on board the Nautilus." - -"Just so," replied the Captain, smiling; "and in that respect moderns are not more advanced than the ancients. It required many ages to find out the mechanical power of steam. Who knows if, in another hundred years, we may not see a second Nautilus? Progress is slow, M. Aronnax." - -"It is true," I answered; "your boat is at least a century before its time, perhaps an era. What a misfortune that the secret of such an invention should die with its inventor!" - -Captain Nemo did not reply. After some minutes' silence he continued: - -"You were speaking of the opinions of ancient historians upon the dangerous navigation of the Red Sea." - -"It is true," said I; "but were not their fears exaggerated?" - -"Yes and no, M. Aronnax," replied Captain Nemo, who seemed to know the Red Sea by heart. "That which is no longer dangerous for a modern vessel, well rigged, strongly built, and master of its own course, thanks to obedient steam, offered all sorts of perils to the ships of the ancients. Picture to yourself those first navigators venturing in ships made of planks sewn with the cords of the palmtree, saturated with the grease of the seadog, and covered with powdered resin! They had not even instruments wherewith to take their bearings, and they went by guess amongst currents of which they scarcely knew anything. Under such conditions shipwrecks were, and must have been, numerous. But in our time, steamers running between Suez and the South Seas have nothing more to fear from the fury of this gulf, in spite of contrary trade-winds. The captain and passengers do not prepare for their departure by offering propitiatory sacrifices; and, on their return, they no longer go ornamented with wreaths and gilt fillets to thank the gods in the neighbouring temple." - -"I agree with you," said I; "and steam seems to have killed all gratitude in the hearts of sailors. But, Captain, since you seem to have especially studied this sea, can you tell me the origin of its name?" - -"There exist several explanations on the subject, M. Aronnax. Would you like to know the opinion of a chronicler of the fourteenth century?" - -"Willingly." - -"This fanciful writer pretends that its name was given to it after the passage of the Israelites, when Pharaoh perished in the waves which closed at the voice of Moses." - -"A poet's explanation, Captain Nemo," I replied; "but I cannot content myself with that. I ask you for your personal opinion." - -"Here it is, M. Aronnax. According to my idea, we must see in this appellation of the Red Sea a translation of the Hebrew word `Edom'; and if the ancients gave it that name, it was on account of the particular colour of its waters." - -"But up to this time I have seen nothing but transparent waves and without any particular colour." - -"Very likely; but as we advance to the bottom of the gulf, you will see this singular appearance. I remember seeing the Bay of Tor entirely red, like a sea of blood." - -"And you attribute this colour to the presence of a microscopic seaweed?" - -"Yes." - -"So, Captain Nemo, it is not the first time you have overrun the Red Sea on board the Nautilus?" - -"No, sir." - -"As you spoke a while ago of the passage of the Israelites and of the catastrophe to the Egyptians, I will ask whether you have met with the traces under the water of this great historical fact?" - -"No, sir; and for a good reason." - -"What is it?" - -"It is that the spot where Moses and his people passed is now so blocked up with sand that the camels can barely bathe their legs there. You can well understand that there would not be water enough for my Nautilus." - -"And the spot?" I asked. - -"The spot is situated a little above the Isthmus of Suez, in the arm which formerly made a deep estuary, when the Red Sea extended to the Salt Lakes. Now, whether this passage were miraculous or not, the Israelites, nevertheless, crossed there to reach the Promised Land, and Pharaoh's army perished precisely on that spot; and I think that excavations made in the middle of the sand would bring to light a large number of arms and instruments of Egyptian origin." - -"That is evident," I replied; "and for the sake of archaeologists let us hope that these excavations will be made sooner or later, when new towns are established on the isthmus, after the construction of the Suez Canal; a canal, however, very useless to a vessel like the Nautilus." - -"Very likely; but useful to the whole world," said Captain Nemo. "The ancients well understood the utility of a communication between the Red Sea and the Mediterranean for their commercial affairs: but they did not think of digging a canal direct, and took the Nile as an intermediate. Very probably the canal which united the Nile to the Red Sea was begun by Sesostris, if we may believe tradition. One thing is certain, that in the year 615 before Jesus Christ, Necos undertook the works of an alimentary canal to the waters of the Nile across the plain of Egypt, looking towards Arabia. It took four days to go up this canal, and it was so wide that two triremes could go abreast. It was carried on by Darius, the son of Hystaspes, and probably finished by Ptolemy II. Strabo saw it navigated: but its decline from the point of departure, near Bubastes, to the Red Sea was so slight that it was only navigable for a few months in the year. This canal answered all commercial purposes to the age of Antonius, when it was abandoned and blocked up with sand. Restored by order of the Caliph Omar, it was definitely destroyed in 761 or 762 by Caliph Al-Mansor, who wished to prevent the arrival of provisions to Mohammed-ben-Abdallah, who had revolted against him. During the expedition into Egypt, your General Bonaparte discovered traces of the works in the Desert of Suez; and, surprised by the tide, he nearly perished before regaining Hadjaroth, at the very place where Moses had encamped three thousand years before him." - -"Well, Captain, what the ancients dared not undertake, this junction between the two seas, which will shorten the road from Cadiz to India, M. Lesseps has succeeded in doing; and before long he will have changed Africa into an immense island." - -"Yes, M. Aronnax; you have the right to be proud of your countryman. Such a man brings more honour to a nation than great captains. He began, like so many others, with disgust and rebuffs; but he has triumphed, for he has the genius of will. And it is sad to think that a work like that, which ought to have been an international work and which would have sufficed to make a reign illustrious, should have succeeded by the energy of one man. All honour to M. Lesseps!" - -"Yes! honour to the great citizen," I replied, surprised by the manner in which Captain Nemo had just spoken. - -"Unfortunately," he continued, "I cannot take you through the Suez Canal; but you will be able to see the long jetty of Port Said after to-morrow, when we shall be in the Mediterranean." - -"The Mediterranean!" I exclaimed. - -"Yes, sir; does that astonish you?" - -"What astonishes me is to think that we shall be there the day after to-morrow." - -"Indeed?" - -"Yes, Captain, although by this time I ought to have accustomed myself to be surprised at nothing since I have been on board your boat." - -"But the cause of this surprise?" - -"Well! it is the fearful speed you will have to put on the Nautilus, if the day after to-morrow she is to be in the Mediterranean, having made the round of Africa, and doubled the Cape of Good Hope!" - -"Who told you that she would make the round of Africa and double the Cape of Good Hope, sir?" - -"Well, unless the Nautilus sails on dry land, and passes above the isthmus——" - -"Or beneath it, M. Aronnax." - -"Beneath it?" - -"Certainly," replied Captain Nemo quietly. "A long time ago Nature made under this tongue of land what man has this day made on its surface." - -"What! such a passage exists?" - -"Yes; a subterranean passage, which I have named the Arabian Tunnel. It takes us beneath Suez and opens into the Gulf of Pelusium." - -"But this isthmus is composed of nothing but quick sands?" - -"To a certain depth. But at fifty-five yards only there is a solid layer of rock." - -"Did you discover this passage by chance?" I asked more and more surprised. - -"Chance and reasoning, sir; and by reasoning even more than by chance. Not only does this passage exist, but I have profited by it several times. Without that I should not have ventured this day into the impassable Red Sea. I noticed that in the Red Sea and in the Mediterranean there existed a certain number of fishes of a kind perfectly identical. Certain of the fact, I asked myself was it possible that there was no communication between the two seas? If there was, the subterranean current must necessarily run from the Red Sea to the Mediterranean, from the sole cause of difference of level. I caught a large number of fishes in the neighbourhood of Suez. I passed a copper ring through their tails, and threw them back into the sea. Some months later, on the coast of Syria, I caught some of my fish ornamented with the ring. Thus the communication between the two was proved. I then sought for it with my Nautilus; I discovered it, ventured into it, and before long, sir, you too will have passed through my Arabian tunnel!" - - - - -CHAPTER V - -THE ARABIAN TUNNEL - -That same evening, in 21° 30' N. lat., the Nautilus floated on the surface of the sea, approaching the Arabian coast. I saw Djeddah, the most important counting-house of Egypt, Syria, Turkey, and India. I distinguished clearly enough its buildings, the vessels anchored at the quays, and those whose draught of water obliged them to anchor in the roads. The sun, rather low on the horizon, struck full on the houses of the town, bringing out their whiteness. Outside, some wooden cabins, and some made of reeds, showed the quarter inhabited by the Bedouins. Soon Djeddah was shut out from view by the shadows of night, and the Nautilus found herself under water slightly phosphorescent. - -The next day, the 10th of February, we sighted several ships running to windward. The Nautilus returned to its submarine navigation; but at noon, when her bearings were taken, the sea being deserted, she rose again to her waterline. - -Accompanied by Ned and Conseil, I seated myself on the platform. The coast on the eastern side looked like a mass faintly printed upon a damp fog. - -We were leaning on the sides of the pinnace, talking of one thing and another, when Ned Land, stretching out his hand towards a spot on the sea, said: - -"Do you see anything there, sir?" - -"No, Ned," I replied; "but I have not your eyes, you know." - -"Look well," said Ned, "there, on the starboard beam, about the height of the lantern! Do you not see a mass which seems to move?" - -"Certainly," said I, after close attention; "I see something like a long black body on the top of the water." - -And certainly before long the black object was not more than a mile from us. It looked like a great sandbank deposited in the open sea. It was a gigantic dugong! - -Ned Land looked eagerly. His eyes shone with covetousness at the sight of the animal. His hand seemed ready to harpoon it. One would have thought he was awaiting the moment to throw himself into the sea and attack it in its element. - -At this instant Captain Nemo appeared on the platform. He saw the dugong, understood the Canadian's attitude, and, addressing him, said: - -"If you held a harpoon just now, Master Land, would it not burn your hand?" - -"Just so, sir." - -"And you would not be sorry to go back, for one day, to your trade of a fisherman and to add this cetacean to the list of those you have already killed?" - -"I should not, sir." - -"Well, you can try." - -"Thank you, sir," said Ned Land, his eyes flaming. - -"Only," continued the Captain, "I advise you for your own sake not to miss the creature." - -"Is the dugong dangerous to attack?" I asked, in spite of the Canadian's shrug of the shoulders. - -"Yes," replied the Captain; "sometimes the animal turns upon its assailants and overturns their boat. But for Master Land this danger is not to be feared. His eye is prompt, his arm sure." - -At this moment seven men of the crew, mute and immovable as ever, mounted the platform. One carried a harpoon and a line similar to those employed in catching whales. The pinnace was lifted from the bridge, pulled from its socket, and let down into the sea. Six oarsmen took their seats, and the coxswain went to the tiller. Ned, Conseil, and I went to the back of the boat. - -"You are not coming, Captain?" I asked. - -"No, sir; but I wish you good sport." - -The boat put off, and, lifted by the six rowers, drew rapidly towards the dugong, which floated about two miles from the Nautilus. - -Arrived some cables-length from the cetacean, the speed slackened, and the oars dipped noiselessly into the quiet waters. Ned Land, harpoon in hand, stood in the fore part of the boat. The harpoon used for striking the whale is generally attached to a very long cord which runs out rapidly as the wounded creature draws it after him. But here the cord was not more than ten fathoms long, and the extremity was attached to a small barrel which, by floating, was to show the course the dugong took under the water. - -I stood and carefully watched the Canadian's adversary. This dugong, which also bears the name of the halicore, closely resembles the manatee; its oblong body terminated in a lengthened tail, and its lateral fins in perfect fingers. Its difference from the manatee consisted in its upper jaw, which was armed with two long and pointed teeth which formed on each side diverging tusks. - -This dugong which Ned Land was preparing to attack was of colossal dimensions; it was more than seven yards long. It did not move, and seemed to be sleeping on the waves, which circumstance made it easier to capture. - -The boat approached within six yards of the animal. The oars rested on the rowlocks. I half rose. Ned Land, his body thrown a little back, brandished the harpoon in his experienced hand. - -Suddenly a hissing noise was heard, and the dugong disappeared. The harpoon, although thrown with great force; had apparently only struck the water. - -"Curse it!" exclaimed the Canadian furiously; "I have missed it!" - -"No," said I; "the creature is wounded—look at the blood; but your weapon has not stuck in his body." - -"My harpoon! my harpoon!" cried Ned Land. - -The sailors rowed on, and the coxswain made for the floating barrel. The harpoon regained, we followed in pursuit of the animal. - -The latter came now and then to the surface to breathe. Its wound had not weakened it, for it shot onwards with great rapidity. - -The boat, rowed by strong arms, flew on its track. Several times it approached within some few yards, and the Canadian was ready to strike, but the dugong made off with a sudden plunge, and it was impossible to reach it. - -Imagine the passion which excited impatient Ned Land! He hurled at the unfortunate creature the most energetic expletives in the English tongue. For my part, I was only vexed to see the dugong escape all our attacks. - -We pursued it without relaxation for an hour, and I began to think it would prove difficult to capture, when the animal, possessed with the perverse idea of vengeance of which he had cause to repent, turned upon the pinnace and assailed us in its turn. - -This manoeuvre did not escape the Canadian. - -"Look out!" he cried. - -The coxswain said some words in his outlandish tongue, doubtless warning the men to keep on their guard. - -The dugong came within twenty feet of the boat, stopped, sniffed the air briskly with its large nostrils (not pierced at the extremity, but in the upper part of its muzzle). Then, taking a spring, he threw himself upon us. - -The pinnace could not avoid the shock, and half upset, shipped at least two tons of water, which had to be emptied; but, thanks to the coxswain, we caught it sideways, not full front, so we were not quite overturned. While Ned Land, clinging to the bows, belaboured the gigantic animal with blows from his harpoon, the creature's teeth were buried in the gunwale, and it lifted the whole thing out of the water, as a lion does a roebuck. We were upset over one another, and I know not how the adventure would have ended, if the Canadian, still enraged with the beast, had not struck it to the heart. - -I heard its teeth grind on the iron plate, and the dugong disappeared, carrying the harpoon with him. But the barrel soon returned to the surface, and shortly after the body of the animal, turned on its back. The boat came up with it, took it in tow, and made straight for the Nautilus. - -It required tackle of enormous strength to hoist the dugong on to the platform. It weighed 10,000 lb. - -The next day, 11th February, the larder of the Nautilus was enriched by some more delicate game. A flight of sea-swallows rested on the Nautilus. It was a species of the Sterna nilotica, peculiar to Egypt; its beak is black, head grey and pointed, the eye surrounded by white spots, the back, wings, and tail of a greyish colour, the belly and throat white, and claws red. They also took some dozen of Nile ducks, a wild bird of high flavour, its throat and upper part of the head white with black spots. - -About five o'clock in the evening we sighted to the north the Cape of Ras-Mohammed. This cape forms the extremity of Arabia Petraea, comprised between the Gulf of Suez and the Gulf of Acabah. - -The Nautilus penetrated into the Straits of Jubal, which leads to the Gulf of Suez. I distinctly saw a high mountain, towering between the two gulfs of Ras-Mohammed. It was Mount Horeb, that Sinai at the top of which Moses saw God face to face. - -At six o'clock the Nautilus, sometimes floating, sometimes immersed, passed some distance from Tor, situated at the end of the bay, the waters of which seemed tinted with red, an observation already made by Captain Nemo. Then night fell in the midst of a heavy silence, sometimes broken by the cries of the pelican and other night-birds, and the noise of the waves breaking upon the shore, chafing against the rocks, or the panting of some far-off steamer beating the waters of the Gulf with its noisy paddles. - -From eight to nine o'clock the Nautilus remained some fathoms under the water. According to my calculation we must have been very near Suez. Through the panel of the saloon I saw the bottom of the rocks brilliantly lit up by our electric lamp. We seemed to be leaving the Straits behind us more and more. - -At a quarter-past nine, the vessel having returned to the surface, I mounted the platform. Most impatient to pass through Captain Nemo's tunnel, I could not stay in one place, so came to breathe the fresh night air. - -Soon in the shadow I saw a pale light, half discoloured by the fog, shining about a mile from us. - -"A floating lighthouse!" said someone near me. - -I turned, and saw the Captain. - -"It is the floating light of Suez," he continued. "It will not be long before we gain the entrance of the tunnel." - -"The entrance cannot be easy?" - -"No, sir; for that reason I am accustomed to go into the steersman's cage and myself direct our course. And now, if you will go down, M. Aronnax, the Nautilus is going under the waves, and will not return to the surface until we have passed through the Arabian Tunnel." - -Captain Nemo led me towards the central staircase; half way down he opened a door, traversed the upper deck, and landed in the pilot's cage, which it may be remembered rose at the extremity of the platform. It was a cabin measuring six feet square, very much like that occupied by the pilot on the steamboats of the Mississippi or Hudson. In the midst worked a wheel, placed vertically, and caught to the tiller-rope, which ran to the back of the Nautilus. Four light-ports with lenticular glasses, let in a groove in the partition of the cabin, allowed the man at the wheel to see in all directions. - -This cabin was dark; but soon my eyes accustomed themselves to the obscurity, and I perceived the pilot, a strong man, with his hands resting on the spokes of the wheel. Outside, the sea appeared vividly lit up by the lantern, which shed its rays from the back of the cabin to the other extremity of the platform. - -"Now," said Captain Nemo, "let us try to make our passage." - -Electric wires connected the pilot's cage with the machinery room, and from there the Captain could communicate simultaneously to his Nautilus the direction and the speed. He pressed a metal knob, and at once the speed of the screw diminished. - -I looked in silence at the high straight wall we were running by at this moment, the immovable base of a massive sandy coast. We followed it thus for an hour only some few yards off. - -Captain Nemo did not take his eye from the knob, suspended by its two concentric circles in the cabin. At a simple gesture, the pilot modified the course of the Nautilus every instant. - -I had placed myself at the port-scuttle, and saw some magnificent substructures of coral, zoophytes, seaweed, and fucus, agitating their enormous claws, which stretched out from the fissures of the rock. - -At a quarter-past ten, the Captain himself took the helm. A large gallery, black and deep, opened before us. The Nautilus went boldly into it. A strange roaring was heard round its sides. It was the waters of the Red Sea, which the incline of the tunnel precipitated violently towards the Mediterranean. The Nautilus went with the torrent, rapid as an arrow, in spite of the efforts of the machinery, which, in order to offer more effective resistance, beat the waves with reversed screw. - -On the walls of the narrow passage I could see nothing but brilliant rays, straight lines, furrows of fire, traced by the great speed, under the brilliant electric light. My heart beat fast. - -At thirty-five minutes past ten, Captain Nemo quitted the helm, and, turning to me, said: - -"The Mediterranean!" - -In less than twenty minutes, the Nautilus, carried along by the torrent, had passed through the Isthmus of Suez. - - - - -CHAPTER VI - -THE GRECIAN ARCHIPELAGO - -The next day, the 12th of February, at the dawn of day, the Nautilus rose to the surface. I hastened on to the platform. Three miles to the south the dim outline of Pelusium was to be seen. A torrent had carried us from one sea to another. About seven o'clock Ned and Conseil joined me. - -"Well, Sir Naturalist," said the Canadian, in a slightly jovial tone, "and the Mediterranean?" - -"We are floating on its surface, friend Ned." - -"What!" said Conseil, "this very night." - -"Yes, this very night; in a few minutes we have passed this impassable isthmus." - -"I do not believe it," replied the Canadian. - -"Then you are wrong, Master Land," I continued; "this low coast which rounds off to the south is the Egyptian coast. And you who have such good eyes, Ned, you can see the jetty of Port Said stretching into the sea." - -The Canadian looked attentively. - -"Certainly you are right, sir, and your Captain is a first-rate man. We are in the Mediterranean. Good! Now, if you please, let us talk of our own little affair, but so that no one hears us." - -I saw what the Canadian wanted, and, in any case, I thought it better to let him talk, as he wished it; so we all three went and sat down near the lantern, where we were less exposed to the spray of the blades. - -"Now, Ned, we listen; what have you to tell us?" - -"What I have to tell you is very simple. We are in Europe; and before Captain Nemo's caprices drag us once more to the bottom of the Polar Seas, or lead us into Oceania, I ask to leave the Nautilus." - -I wished in no way to shackle the liberty of my companions, but I certainly felt no desire to leave Captain Nemo. - -Thanks to him, and thanks to his apparatus, I was each day nearer the completion of my submarine studies; and I was rewriting my book of submarine depths in its very element. Should I ever again have such an opportunity of observing the wonders of the ocean? No, certainly not! And I could not bring myself to the idea of abandoning the Nautilus before the cycle of investigation was accomplished. - -"Friend Ned, answer me frankly, are you tired of being on board? Are you sorry that destiny has thrown us into Captain Nemo's hands?" - -The Canadian remained some moments without answering. Then, crossing his arms, he said: - -"Frankly, I do not regret this journey under the seas. I shall be glad to have made it; but, now that it is made, let us have done with it. That is my idea." - -"It will come to an end, Ned." - -"Where and when?" - -"Where I do not know—when I cannot say; or, rather, I suppose it will end when these seas have nothing more to teach us." - -"Then what do you hope for?" demanded the Canadian. - -"That circumstances may occur as well six months hence as now by which we may and ought to profit." - -"Oh!" said Ned Land, "and where shall we be in six months, if you please, Sir Naturalist?" - -"Perhaps in China; you know the Nautilus is a rapid traveller. It goes through water as swallows through the air, or as an express on the land. It does not fear frequented seas; who can say that it may not beat the coasts of France, England, or America, on which flight may be attempted as advantageously as here." - -"M. Aronnax," replied the Canadian, "your arguments are rotten at the foundation. You speak in the future, `We shall be there! we shall be here!' I speak in the present, `We are here, and we must profit by it.'" - -Ned Land's logic pressed me hard, and I felt myself beaten on that ground. I knew not what argument would now tell in my favour. - -"Sir," continued Ned, "let us suppose an impossibility: if Captain Nemo should this day offer you your liberty; would you accept it?" - -"I do not know," I answered. - -"And if," he added, "the offer made you this day was never to be renewed, would you accept it?" - -"Friend Ned, this is my answer. Your reasoning is against me. We must not rely on Captain Nemo's good-will. Common prudence forbids him to set us at liberty. On the other side, prudence bids us profit by the first opportunity to leave the Nautilus." - -"Well, M. Aronnax, that is wisely said." - -"Only one observation—just one. The occasion must be serious, and our first attempt must succeed; if it fails, we shall never find another, and Captain Nemo will never forgive us." - -"All that is true," replied the Canadian. "But your observation applies equally to all attempts at flight, whether in two years' time, or in two days'. But the question is still this: If a favourable opportunity presents itself, it must be seized." - -"Agreed! And now, Ned, will you tell me what you mean by a favourable opportunity?" - -"It will be that which, on a dark night, will bring the Nautilus a short distance from some European coast." - -"And you will try and save yourself by swimming?" - -"Yes, if we were near enough to the bank, and if the vessel was floating at the time. Not if the bank was far away, and the boat was under the water." - -"And in that case?" - -"In that case, I should seek to make myself master of the pinnace. I know how it is worked. We must get inside, and the bolts once drawn, we shall come to the surface of the water, without even the pilot, who is in the bows, perceiving our flight." - -"Well, Ned, watch for the opportunity; but do not forget that a hitch will ruin us." - -"I will not forget, sir." - -"And now, Ned, would you like to know what I think of your project?" - -"Certainly, M. Aronnax." - -"Well, I think—I do not say I hope—I think that this favourable opportunity will never present itself." - -"Why not?" - -"Because Captain Nemo cannot hide from himself that we have not given up all hope of regaining our liberty, and he will be on his guard, above all, in the seas and in the sight of European coasts." - -"We shall see," replied Ned Land, shaking his head determinedly. - -"And now, Ned Land," I added, "let us stop here. Not another word on the subject. The day that you are ready, come and let us know, and we will follow you. I rely entirely upon you." - -Thus ended a conversation which, at no very distant time, led to such grave results. I must say here that facts seemed to confirm my foresight, to the Canadian's great despair. Did Captain Nemo distrust us in these frequented seas? or did he only wish to hide himself from the numerous vessels, of all nations, which ploughed the Mediterranean? I could not tell; but we were oftener between waters and far from the coast. Or, if the Nautilus did emerge, nothing was to be seen but the pilot's cage; and sometimes it went to great depths, for, between the Grecian Archipelago and Asia Minor we could not touch the bottom by more than a thousand fathoms. - -Thus I only knew we were near the Island of Carpathos, one of the Sporades, by Captain Nemo reciting these lines from Virgil: - -"Est Carpathio Neptuni gurgite vates, -Caeruleus Proteus," -as he pointed to a spot on the planisphere. - -It was indeed the ancient abode of Proteus, the old shepherd of Neptune's flocks, now the Island of Scarpanto, situated between Rhodes and Crete. I saw nothing but the granite base through the glass panels of the saloon. - -The next day, the 14th of February, I resolved to employ some hours in studying the fishes of the Archipelago; but for some reason or other the panels remained hermetically sealed. Upon taking the course of the Nautilus, I found that we were going towards Candia, the ancient Isle of Crete. At the time I embarked on the Abraham Lincoln, the whole of this island had risen in insurrection against the despotism of the Turks. But how the insurgents had fared since that time I was absolutely ignorant, and it was not Captain Nemo, deprived of all land communications, who could tell me. - -I made no allusion to this event when that night I found myself alone with him in the saloon. Besides, he seemed to be taciturn and preoccupied. Then, contrary to his custom, he ordered both panels to be opened, and, going from one to the other, observed the mass of waters attentively. To what end I could not guess; so, on my side, I employed my time in studying the fish passing before my eyes. - -In the midst of the waters a man appeared, a diver, carrying at his belt a leathern purse. It was not a body abandoned to the waves; it was a living man, swimming with a strong hand, disappearing occasionally to take breath at the surface. - -I turned towards Captain Nemo, and in an agitated voice exclaimed: - -"A man shipwrecked! He must be saved at any price!" - -The Captain did not answer me, but came and leaned against the panel. - -The man had approached, and, with his face flattened against the glass, was looking at us. - -To my great amazement, Captain Nemo signed to him. The diver answered with his hand, mounted immediately to the surface of the water, and did not appear again. - -"Do not be uncomfortable," said Captain Nemo. "It is Nicholas of Cape Matapan, surnamed Pesca. He is well known in all the Cyclades. A bold diver! water is his element, and he lives more in it than on land, going continually from one island to another, even as far as Crete." - -"You know him, Captain?" - -"Why not, M. Aronnax?" - -Saying which, Captain Nemo went towards a piece of furniture standing near the left panel of the saloon. Near this piece of furniture, I saw a chest bound with iron, on the cover of which was a copper plate, bearing the cypher of the Nautilus with its device. - -At that moment, the Captain, without noticing my presence, opened the piece of furniture, a sort of strong box, which held a great many ingots. - -They were ingots of gold. From whence came this precious metal, which represented an enormous sum? Where did the Captain gather this gold from? and what was he going to do with it? - -I did not say one word. I looked. Captain Nemo took the ingots one by one, and arranged them methodically in the chest, which he filled entirely. I estimated the contents at more than 4,000 lb. weight of gold, that is to say, nearly L200,000. - -The chest was securely fastened, and the Captain wrote an address on the lid, in characters which must have belonged to Modern Greece. - -This done, Captain Nemo pressed a knob, the wire of which communicated with the quarters of the crew. Four men appeared, and, not without some trouble, pushed the chest out of the saloon. Then I heard them hoisting it up the iron staircase by means of pulleys. - -At that moment, Captain Nemo turned to me. - -"And you were saying, sir?" said he. - -"I was saying nothing, Captain." - -"Then, sir, if you will allow me, I will wish you good night." - -Whereupon he turned and left the saloon. - -I returned to my room much troubled, as one may believe. I vainly tried to sleep—I sought the connecting link between the apparition of the diver and the chest filled with gold. Soon, I felt by certain movements of pitching and tossing that the Nautilus was leaving the depths and returning to the surface. - -Then I heard steps upon the platform; and I knew they were unfastening the pinnace and launching it upon the waves. For one instant it struck the side of the Nautilus, then all noise ceased. - -Two hours after, the same noise, the same going and coming was renewed; the boat was hoisted on board, replaced in its socket, and the Nautilus again plunged under the waves. - -So these millions had been transported to their address. To what point of the continent? Who was Captain Nemo's correspondent? - -The next day I related to Conseil and the Canadian the events of the night, which had excited my curiosity to the highest degree. My companions were not less surprised than myself. - -"But where does he take his millions to?" asked Ned Land. - -To that there was no possible answer. I returned to the saloon after having breakfast and set to work. Till five o'clock in the evening I employed myself in arranging my notes. At that moment—(ought I to attribute it to some peculiar idiosyncrasy)—I felt so great a heat that I was obliged to take off my coat. It was strange, for we were under low latitudes; and even then the Nautilus, submerged as it was, ought to experience no change of temperature. I looked at the manometer; it showed a depth of sixty feet, to which atmospheric heat could never attain. - -I continued my work, but the temperature rose to such a pitch as to be intolerable. - -"Could there be fire on board?" I asked myself. - -I was leaving the saloon, when Captain Nemo entered; he approached the thermometer, consulted it, and, turning to me, said: - -"Forty-two degrees." - -"I have noticed it, Captain," I replied; "and if it gets much hotter we cannot bear it." - -"Oh, sir, it will not get better if we do not wish it." - -"You can reduce it as you please, then?" - -"No; but I can go farther from the stove which produces it." - -"It is outward, then!" - -"Certainly; we are floating in a current of boiling water." - -"Is it possible!" I exclaimed. - -"Look." - -The panels opened, and I saw the sea entirely white all round. A sulphurous smoke was curling amid the waves, which boiled like water in a copper. I placed my hand on one of the panes of glass, but the heat was so great that I quickly took it off again. - -"Where are we?" I asked. - -"Near the Island of Santorin, sir," replied the Captain. "I wished to give you a sight of the curious spectacle of a submarine eruption." - -"I thought," said I, "that the formation of these new islands was ended." - -"Nothing is ever ended in the volcanic parts of the sea," replied Captain Nemo; "and the globe is always being worked by subterranean fires. Already, in the nineteenth year of our era, according to Cassiodorus and Pliny, a new island, Theia (the divine), appeared in the very place where these islets have recently been formed. Then they sank under the waves, to rise again in the year 69, when they again subsided. Since that time to our days the Plutonian work has been suspended. But on the 3rd of February, 1866, a new island, which they named George Island, emerged from the midst of the sulphurous vapour near Nea Kamenni, and settled again the 6th of the same month. Seven days after, the 13th of February, the Island of Aphroessa appeared, leaving between Nea Kamenni and itself a canal ten yards broad. I was in these seas when the phenomenon occurred, and I was able therefore to observe all the different phases. The Island of Aphroessa, of round form, measured 300 feet in diameter, and 30 feet in height. It was composed of black and vitreous lava, mixed with fragments of felspar. And lastly, on the 10th of March, a smaller island, called Reka, showed itself near Nea Kamenni, and since then these three have joined together, forming but one and the same island." - -"And the canal in which we are at this moment?" I asked. - -"Here it is," replied Captain Nemo, showing me a map of the Archipelago. "You see, I have marked the new islands." - -I returned to the glass. The Nautilus was no longer moving, the heat was becoming unbearable. The sea, which till now had been white, was red, owing to the presence of salts of iron. In spite of the ship's being hermetically sealed, an insupportable smell of sulphur filled the saloon, and the brilliancy of the electricity was entirely extinguished by bright scarlet flames. I was in a bath, I was choking, I was broiled. - -"We can remain no longer in this boiling water," said I to the Captain. - -"It would not be prudent," replied the impassive Captain Nemo. - -An order was given; the Nautilus tacked about and left the furnace it could not brave with impunity. A quarter of an hour after we were breathing fresh air on the surface. The thought then struck me that, if Ned Land had chosen this part of the sea for our flight, we should never have come alive out of this sea of fire. - -The next day, the 16th of February, we left the basin which, between Rhodes and Alexandria, is reckoned about 1,500 fathoms in depth, and the Nautilus, passing some distance from Cerigo, quitted the Grecian Archipelago after having doubled Cape Matapan. - - - - -CHAPTER VII - -THE MEDITERRANEAN IN FORTY-EIGHT HOURS - -The Mediterranean, the blue sea par excellence, "the great sea" of the Hebrews, "the sea" of the Greeks, the "mare nostrum" of the Romans, bordered by orange-trees, aloes, cacti, and sea-pines; embalmed with the perfume of the myrtle, surrounded by rude mountains, saturated with pure and transparent air, but incessantly worked by underground fires; a perfect battlefield in which Neptune and Pluto still dispute the empire of the world! - -It is upon these banks, and on these waters, says Michelet, that man is renewed in one of the most powerful climates of the globe. But, beautiful as it was, I could only take a rapid glance at the basin whose superficial area is two million of square yards. Even Captain Nemo's knowledge was lost to me, for this puzzling person did not appear once during our passage at full speed. I estimated the course which the Nautilus took under the waves of the sea at about six hundred leagues, and it was accomplished in forty-eight hours. Starting on the morning of the 16th of February from the shores of Greece, we had crossed the Straits of Gibraltar by sunrise on the 18th. - -It was plain to me that this Mediterranean, enclosed in the midst of those countries which he wished to avoid, was distasteful to Captain Nemo. Those waves and those breezes brought back too many remembrances, if not too many regrets. Here he had no longer that independence and that liberty of gait which he had when in the open seas, and his Nautilus felt itself cramped between the close shores of Africa and Europe. - -Our speed was now twenty-five miles an hour. It may be well understood that Ned Land, to his great disgust, was obliged to renounce his intended flight. He could not launch the pinnace, going at the rate of twelve or thirteen yards every second. To quit the Nautilus under such conditions would be as bad as jumping from a train going at full speed—an imprudent thing, to say the least of it. Besides, our vessel only mounted to the surface of the waves at night to renew its stock of air; it was steered entirely by the compass and the log. - -I saw no more of the interior of this Mediterranean than a traveller by express train perceives of the landscape which flies before his eyes; that is to say, the distant horizon, and not the nearer objects which pass like a flash of lightning. - -We were then passing between Sicily and the coast of Tunis. In the narrow space between Cape Bon and the Straits of Messina the bottom of the sea rose almost suddenly. There was a perfect bank, on which there was not more than nine fathoms of water, whilst on either side the depth was ninety fathoms. - -The Nautilus had to manoeuvre very carefully so as not to strike against this submarine barrier. - -I showed Conseil, on the map of the Mediterranean, the spot occupied by this reef. - -"But if you please, sir," observed Conseil, "it is like a real isthmus joining Europe to Africa." - -"Yes, my boy, it forms a perfect bar to the Straits of Lybia, and the soundings of Smith have proved that in former times the continents between Cape Boco and Cape Furina were joined." - -"I can well believe it," said Conseil. - -"I will add," I continued, "that a similar barrier exists between Gibraltar and Ceuta, which in geological times formed the entire Mediterranean." - -"What if some volcanic burst should one day raise these two barriers above the waves?" - -"It is not probable, Conseil." - -"Well, but allow me to finish, please, sir; if this phenomenon should take place, it will be troublesome for M. Lesseps, who has taken so much pains to pierce the isthmus." - -"I agree with you; but I repeat, Conseil, this phenomenon will never happen. The violence of subterranean force is ever diminishing. Volcanoes, so plentiful in the first days of the world, are being extinguished by degrees; the internal heat is weakened, the temperature of the lower strata of the globe is lowered by a perceptible quantity every century to the detriment of our globe, for its heat is its life." - -"But the sun?" - -"The sun is not sufficient, Conseil. Can it give heat to a dead body?" - -"Not that I know of." - -"Well, my friend, this earth will one day be that cold corpse; it will become uninhabitable and uninhabited like the moon, which has long since lost all its vital heat." - -"In how many centuries?" - -"In some hundreds of thousands of years, my boy." - -"Then," said Conseil, "we shall have time to finish our journey—that is, if Ned Land does not interfere with it." - -And Conseil, reassured, returned to the study of the bank, which the Nautilus was skirting at a moderate speed. - -During the night of the 16th and 17th February we had entered the second Mediterranean basin, the greatest depth of which was 1,450 fathoms. The Nautilus, by the action of its crew, slid down the inclined planes and buried itself in the lowest depths of the sea. - -On the 18th of February, about three o'clock in the morning, we were at the entrance of the Straits of Gibraltar. There once existed two currents: an upper one, long since recognised, which conveys the waters of the ocean into the basin of the Mediterranean; and a lower counter-current, which reasoning has now shown to exist. Indeed, the volume of water in the Mediterranean, incessantly added to by the waves of the Atlantic and by rivers falling into it, would each year raise the level of this sea, for its evaporation is not sufficient to restore the equilibrium. As it is not so, we must necessarily admit the existence of an under-current, which empties into the basin of the Atlantic through the Straits of Gibraltar the surplus waters of the Mediterranean. A fact indeed; and it was this counter-current by which the Nautilus profited. It advanced rapidly by the narrow pass. For one instant I caught a glimpse of the beautiful ruins of the temple of Hercules, buried in the ground, according to Pliny, and with the low island which supports it; and a few minutes later we were floating on the Atlantic. - - - - -CHAPTER VIII - -VIGO BAY - -The Atlantic! a vast sheet of water whose superficial area covers twenty-five millions of square miles, the length of which is nine thousand miles, with a mean breadth of two thousand seven hundred—an ocean whose parallel winding shores embrace an immense circumference, watered by the largest rivers of the world, the St. Lawrence, the Mississippi, the Amazon, the Plata, the Orinoco, the Niger, the Senegal, the Elbe, the Loire, and the Rhine, which carry water from the most civilised, as well as from the most savage, countries! Magnificent field of water, incessantly ploughed by vessels of every nation, sheltered by the flags of every nation, and which terminates in those two terrible points so dreaded by mariners, Cape Horn and the Cape of Tempests. - -The Nautilus was piercing the water with its sharp spur, after having accomplished nearly ten thousand leagues in three months and a half, a distance greater than the great circle of the earth. Where were we going now, and what was reserved for the future? The Nautilus, leaving the Straits of Gibraltar, had gone far out. It returned to the surface of the waves, and our daily walks on the platform were restored to us. - -I mounted at once, accompanied by Ned Land and Conseil. At a distance of about twelve miles, Cape St. Vincent was dimly to be seen, forming the south-western point of the Spanish peninsula. A strong southerly gale was blowing. The sea was swollen and billowy; it made the Nautilus rock violently. It was almost impossible to keep one's foot on the platform, which the heavy rolls of the sea beat over every instant. So we descended after inhaling some mouthfuls of fresh air. - -I returned to my room, Conseil to his cabin; but the Canadian, with a preoccupied air, followed me. Our rapid passage across the Mediterranean had not allowed him to put his project into execution, and he could not help showing his disappointment. When the door of my room was shut, he sat down and looked at me silently. - -"Friend Ned," said I, "I understand you; but you cannot reproach yourself. To have attempted to leave the Nautilus under the circumstances would have been folly." - -Ned Land did not answer; his compressed lips and frowning brow showed with him the violent possession this fixed idea had taken of his mind. - -"Let us see," I continued; "we need not despair yet. We are going up the coast of Portugal again; France and England are not far off, where we can easily find refuge. Now if the Nautilus, on leaving the Straits of Gibraltar, had gone to the south, if it had carried us towards regions where there were no continents, I should share your uneasiness. But we know now that Captain Nemo does not fly from civilised seas, and in some days I think you can act with security." - -Ned Land still looked at me fixedly; at length his fixed lips parted, and he said, "It is for to-night." - -I drew myself up suddenly. I was, I admit, little prepared for this communication. I wanted to answer the Canadian, but words would not come. - -"We agreed to wait for an opportunity," continued Ned Land, "and the opportunity has arrived. This night we shall be but a few miles from the Spanish coast. It is cloudy. The wind blows freely. I have your word, M. Aronnax, and I rely upon you." - -As I was silent, the Canadian approached me. - -"To-night, at nine o'clock," said he. "I have warned Conseil. At that moment Captain Nemo will be shut up in his room, probably in bed. Neither the engineers nor the ship's crew can see us. Conseil and I will gain the central staircase, and you, M. Aronnax, will remain in the library, two steps from us, waiting my signal. The oars, the mast, and the sail are in the canoe. I have even succeeded in getting some provisions. I have procured an English wrench, to unfasten the bolts which attach it to the shell of the Nautilus. So all is ready, till to-night." - -"The sea is bad." - -"That I allow," replied the Canadian; "but we must risk that. Liberty is worth paying for; besides, the boat is strong, and a few miles with a fair wind to carry us is no great thing. Who knows but by to-morrow we may be a hundred leagues away? Let circumstances only favour us, and by ten or eleven o'clock we shall have landed on some spot of terra firma, alive or dead. But adieu now till to-night." - -With these words the Canadian withdrew, leaving me almost dumb. I had imagined that, the chance gone, I should have time to reflect and discuss the matter. My obstinate companion had given me no time; and, after all, what could I have said to him? Ned Land was perfectly right. There was almost the opportunity to profit by. Could I retract my word, and take upon myself the responsibility of compromising the future of my companions? To-morrow Captain Nemo might take us far from all land. - -At that moment a rather loud hissing noise told me that the reservoirs were filling, and that the Nautilus was sinking under the waves of the Atlantic. - -A sad day I passed, between the desire of regaining my liberty of action and of abandoning the wonderful Nautilus, and leaving my submarine studies incomplete. - -What dreadful hours I passed thus! Sometimes seeing myself and companions safely landed, sometimes wishing, in spite of my reason, that some unforeseen circumstance, would prevent the realisation of Ned Land's project. - -Twice I went to the saloon. I wished to consult the compass. I wished to see if the direction the Nautilus was taking was bringing us nearer or taking us farther from the coast. But no; the Nautilus kept in Portuguese waters. - -I must therefore take my part and prepare for flight. My luggage was not heavy; my notes, nothing more. - -As to Captain Nemo, I asked myself what he would think of our escape; what trouble, what wrong it might cause him and what he might do in case of its discovery or failure. Certainly I had no cause to complain of him; on the contrary, never was hospitality freer than his. In leaving him I could not be taxed with ingratitude. No oath bound us to him. It was on the strength of circumstances he relied, and not upon our word, to fix us for ever. - -I had not seen the Captain since our visit to the Island of Santorin. Would chance bring me to his presence before our departure? I wished it, and I feared it at the same time. I listened if I could hear him walking the room contiguous to mine. No sound reached my ear. I felt an unbearable uneasiness. This day of waiting seemed eternal. Hours struck too slowly to keep pace with my impatience. - -My dinner was served in my room as usual. I ate but little; I was too preoccupied. I left the table at seven o'clock. A hundred and twenty minutes (I counted them) still separated me from the moment in which I was to join Ned Land. My agitation redoubled. My pulse beat violently. I could not remain quiet. I went and came, hoping to calm my troubled spirit by constant movement. The idea of failure in our bold enterprise was the least painful of my anxieties; but the thought of seeing our project discovered before leaving the Nautilus, of being brought before Captain Nemo, irritated, or (what was worse) saddened, at my desertion, made my heart beat. - -I wanted to see the saloon for the last time. I descended the stairs and arrived in the museum, where I had passed so many useful and agreeable hours. I looked at all its riches, all its treasures, like a man on the eve of an eternal exile, who was leaving never to return. - -These wonders of Nature, these masterpieces of art, amongst which for so many days my life had been concentrated, I was going to abandon them for ever! I should like to have taken a last look through the windows of the saloon into the waters of the Atlantic: but the panels were hermetically closed, and a cloak of steel separated me from that ocean which I had not yet explored. - -In passing through the saloon, I came near the door let into the angle which opened into the Captain's room. To my great surprise, this door was ajar. I drew back involuntarily. If Captain Nemo should be in his room, he could see me. But, hearing no sound, I drew nearer. The room was deserted. I pushed open the door and took some steps forward. Still the same monklike severity of aspect. - -Suddenly the clock struck eight. The first beat of the hammer on the bell awoke me from my dreams. I trembled as if an invisible eye had plunged into my most secret thoughts, and I hurried from the room. - -There my eye fell upon the compass. Our course was still north. The log indicated moderate speed, the manometer a depth of about sixty feet. - -I returned to my room, clothed myself warmly—sea boots, an otterskin cap, a great coat of byssus, lined with sealskin; I was ready, I was waiting. The vibration of the screw alone broke the deep silence which reigned on board. I listened attentively. Would no loud voice suddenly inform me that Ned Land had been surprised in his projected flight. A mortal dread hung over me, and I vainly tried to regain my accustomed coolness. - -At a few minutes to nine, I put my ear to the Captain's door. No noise. I left my room and returned to the saloon, which was half in obscurity, but deserted. - -I opened the door communicating with the library. The same insufficient light, the same solitude. I placed myself near the door leading to the central staircase, and there waited for Ned Land's signal. - -At that moment the trembling of the screw sensibly diminished, then it stopped entirely. The silence was now only disturbed by the beatings of my own heart. Suddenly a slight shock was felt; and I knew that the Nautilus had stopped at the bottom of the ocean. My uneasiness increased. The Canadian's signal did not come. I felt inclined to join Ned Land and beg of him to put off his attempt. I felt that we were not sailing under our usual conditions. - -At this moment the door of the large saloon opened, and Captain Nemo appeared. He saw me, and without further preamble began in an amiable tone of voice: - -"Ah, sir! I have been looking for you. Do you know the history of Spain?" - -Now, one might know the history of one's own country by heart; but in the condition I was at the time, with troubled mind and head quite lost, I could not have said a word of it. - -"Well," continued Captain Nemo, "you heard my question! Do you know the history of Spain?" - -"Very slightly," I answered. - -"Well, here are learned men having to learn," said the Captain. "Come, sit down, and I will tell you a curious episode in this history. Sir, listen well," said he; "this history will interest you on one side, for it will answer a question which doubtless you have not been able to solve." - -"I listen, Captain," said I, not knowing what my interlocutor was driving at, and asking myself if this incident was bearing on our projected flight. - -"Sir, if you have no objection, we will go back to 1702. You cannot be ignorant that your king, Louis XIV, thinking that the gesture of a potentate was sufficient to bring the Pyrenees under his yoke, had imposed the Duke of Anjou, his grandson, on the Spaniards. This prince reigned more or less badly under the name of Philip V, and had a strong party against him abroad. Indeed, the preceding year, the royal houses of Holland, Austria, and England had concluded a treaty of alliance at the Hague, with the intention of plucking the crown of Spain from the head of Philip V, and placing it on that of an archduke to whom they prematurely gave the title of Charles III. - -"Spain must resist this coalition; but she was almost entirely unprovided with either soldiers or sailors. However, money would not fail them, provided that their galleons, laden with gold and silver from America, once entered their ports. And about the end of 1702 they expected a rich convoy which France was escorting with a fleet of twenty-three vessels, commanded by Admiral Chateau-Renaud, for the ships of the coalition were already beating the Atlantic. This convoy was to go to Cadiz, but the Admiral, hearing that an English fleet was cruising in those waters, resolved to make for a French port. - -"The Spanish commanders of the convoy objected to this decision. They wanted to be taken to a Spanish port, and, if not to Cadiz, into Vigo Bay, situated on the northwest coast of Spain, and which was not blocked. - -"Admiral Chateau-Renaud had the rashness to obey this injunction, and the galleons entered Vigo Bay. - -"Unfortunately, it formed an open road which could not be defended in any way. They must therefore hasten to unload the galleons before the arrival of the combined fleet; and time would not have failed them had not a miserable question of rivalry suddenly arisen. - -"You are following the chain of events?" asked Captain Nemo. - -"Perfectly," said I, not knowing the end proposed by this historical lesson. - -"I will continue. This is what passed. The merchants of Cadiz had a privilege by which they had the right of receiving all merchandise coming from the West Indies. Now, to disembark these ingots at the port of Vigo was depriving them of their rights. They complained at Madrid, and obtained the consent of the weak-minded Philip that the convoy, without discharging its cargo, should remain sequestered in the roads of Vigo until the enemy had disappeared. - -"But whilst coming to this decision, on the 22nd of October, 1702, the English vessels arrived in Vigo Bay, when Admiral Chateau-Renaud, in spite of inferior forces, fought bravely. But, seeing that the treasure must fall into the enemy's hands, he burnt and scuttled every galleon, which went to the bottom with their immense riches." - -Captain Nemo stopped. I admit I could not see yet why this history should interest me. - -"Well?" I asked. - -"Well, M. Aronnax," replied Captain Nemo, "we are in that Vigo Bay; and it rests with yourself whether you will penetrate its mysteries." - -The Captain rose, telling me to follow him. I had had time to recover. I obeyed. The saloon was dark, but through the transparent glass the waves were sparkling. I looked. - -For half a mile around the Nautilus, the waters seemed bathed in electric light. The sandy bottom was clean and bright. Some of the ship's crew in their diving-dresses were clearing away half-rotten barrels and empty cases from the midst of the blackened wrecks. From these cases and from these barrels escaped ingots of gold and silver, cascades of piastres and jewels. The sand was heaped up with them. Laden with their precious booty, the men returned to the Nautilus, disposed of their burden, and went back to this inexhaustible fishery of gold and silver. - -I understood now. This was the scene of the battle of the 22nd of October, 1702. Here on this very spot the galleons laden for the Spanish Government had sunk. Here Captain Nemo came, according to his wants, to pack up those millions with which he burdened the Nautilus. It was for him and him alone America had given up her precious metals. He was heir direct, without anyone to share, in those treasures torn from the Incas and from the conquered of Ferdinand Cortez. - -"Did you know, sir," he asked, smiling, "that the sea contained such riches?" - -"I knew," I answered, "that they value money held in suspension in these waters at two millions." - -"Doubtless; but to extract this money the expense would be greater than the profit. Here, on the contrary, I have but to pick up what man has lost—and not only in Vigo Bay, but in a thousand other ports where shipwrecks have happened, and which are marked on my submarine map. Can you understand now the source of the millions I am worth?" - -"I understand, Captain. But allow me to tell you that in exploring Vigo Bay you have only been beforehand with a rival society." - -"And which?" - -"A society which has received from the Spanish Government the privilege of seeking those buried galleons. The shareholders are led on by the allurement of an enormous bounty, for they value these rich shipwrecks at five hundred millions." - -"Five hundred millions they were," answered Captain Nemo, "but they are so no longer." - -"Just so," said I; "and a warning to those shareholders would be an act of charity. But who knows if it would be well received? What gamblers usually regret above all is less the loss of their money than of their foolish hopes. After all, I pity them less than the thousands of unfortunates to whom so much riches well-distributed would have been profitable, whilst for them they will be for ever barren." - -I had no sooner expressed this regret than I felt that it must have wounded Captain Nemo. - -"Barren!" he exclaimed, with animation. "Do you think then, sir, that these riches are lost because I gather them? Is it for myself alone, according to your idea, that I take the trouble to collect these treasures? Who told you that I did not make a good use of it? Do you think I am ignorant that there are suffering beings and oppressed races on this earth, miserable creatures to console, victims to avenge? Do you not understand?" - -Captain Nemo stopped at these last words, regretting perhaps that he had spoken so much. But I had guessed that, whatever the motive which had forced him to seek independence under the sea, it had left him still a man, that his heart still beat for the sufferings of humanity, and that his immense charity was for oppressed races as well as individuals. And I then understood for whom those millions were destined which were forwarded by Captain Nemo when the Nautilus was cruising in the waters of Crete. - - - - -CHAPTER IX - -A VANISHED CONTINENT - -The next morning, the 19th of February, I saw the Canadian enter my room. I expected this visit. He looked very disappointed. - -"Well, sir?" said he. - -"Well, Ned, fortune was against us yesterday." - -"Yes; that Captain must needs stop exactly at the hour we intended leaving his vessel." - -"Yes, Ned, he had business at his bankers." - -"His bankers!" - -"Or rather his banking-house; by that I mean the ocean, where his riches are safer than in the chests of the State." - -I then related to the Canadian the incidents of the preceding night, hoping to bring him back to the idea of not abandoning the Captain; but my recital had no other result than an energetically expressed regret from Ned that he had not been able to take a walk on the battlefield of Vigo on his own account. - -"However," said he, "all is not ended. It is only a blow of the harpoon lost. Another time we must succeed; and to-night, if necessary——" - -"In what direction is the Nautilus going?" I asked. - -"I do not know," replied Ned. - -"Well, at noon we shall see the point." - -The Canadian returned to Conseil. As soon as I was dressed, I went into the saloon. The compass was not reassuring. The course of the Nautilus was S.S.W. We were turning our backs on Europe. - -I waited with some impatience till the ship's place was pricked on the chart. At about half-past eleven the reservoirs were emptied, and our vessel rose to the surface of the ocean. I rushed towards the platform. Ned Land had preceded me. No more land in sight. Nothing but an immense sea. Some sails on the horizon, doubtless those going to San Roque in search of favourable winds for doubling the Cape of Good Hope. The weather was cloudy. A gale of wind was preparing. Ned raved, and tried to pierce the cloudy horizon. He still hoped that behind all that fog stretched the land he so longed for. - -At noon the sun showed itself for an instant. The second profited by this brightness to take its height. Then, the sea becoming more billowy, we descended, and the panel closed. - -An hour after, upon consulting the chart, I saw the position of the Nautilus was marked at 16° 17' long., and 33° 22' lat., at 150 leagues from the nearest coast. There was no means of flight, and I leave you to imagine the rage of the Canadian when I informed him of our situation. - -For myself, I was not particularly sorry. I felt lightened of the load which had oppressed me, and was able to return with some degree of calmness to my accustomed work. - -That night, about eleven o'clock, I received a most unexpected visit from Captain Nemo. He asked me very graciously if I felt fatigued from my watch of the preceding night. I answered in the negative. - -"Then, M. Aronnax, I propose a curious excursion." - -"Propose, Captain?" - -"You have hitherto only visited the submarine depths by daylight, under the brightness of the sun. Would it suit you to see them in the darkness of the night?" - -"Most willingly." - -"I warn you, the way will be tiring. We shall have far to walk, and must climb a mountain. The roads are not well kept." - -"What you say, Captain, only heightens my curiosity; I am ready to follow you." - -"Come then, sir, we will put on our diving-dresses." - -Arrived at the robing-room, I saw that neither of my companions nor any of the ship's crew were to follow us on this excursion. Captain Nemo had not even proposed my taking with me either Ned or Conseil. - -In a few moments we had put on our diving-dresses; they placed on our backs the reservoirs, abundantly filled with air, but no electric lamps were prepared. I called the Captain's attention to the fact. - -"They will be useless," he replied. - -I thought I had not heard aright, but I could not repeat my observation, for the Captain's head had already disappeared in its metal case. I finished harnessing myself. I felt them put an iron-pointed stick into my hand, and some minutes later, after going through the usual form, we set foot on the bottom of the Atlantic at a depth of 150 fathoms. Midnight was near. The waters were profoundly dark, but Captain Nemo pointed out in the distance a reddish spot, a sort of large light shining brilliantly about two miles from the Nautilus. What this fire might be, what could feed it, why and how it lit up the liquid mass, I could not say. In any case, it did light our way, vaguely, it is true, but I soon accustomed myself to the peculiar darkness, and I understood, under such circumstances, the uselessness of the Ruhmkorff apparatus. - -As we advanced, I heard a kind of pattering above my head. The noise redoubling, sometimes producing a continual shower, I soon understood the cause. It was rain falling violently, and crisping the surface of the waves. Instinctively the thought flashed across my mind that I should be wet through! By the water! in the midst of the water! I could not help laughing at the odd idea. But, indeed, in the thick diving-dress, the liquid element is no longer felt, and one only seems to be in an atmosphere somewhat denser than the terrestrial atmosphere. Nothing more. - -After half an hour's walk the soil became stony. Medusae, microscopic crustacea, and pennatules lit it slightly with their phosphorescent gleam. I caught a glimpse of pieces of stone covered with millions of zoophytes and masses of sea weed. My feet often slipped upon this sticky carpet of sea weed, and without my iron-tipped stick I should have fallen more than once. In turning round, I could still see the whitish lantern of the Nautilus beginning to pale in the distance. - -But the rosy light which guided us increased and lit up the horizon. The presence of this fire under water puzzled me in the highest degree. Was I going towards a natural phenomenon as yet unknown to the savants of the earth? Or even (for this thought crossed my brain) had the hand of man aught to do with this conflagration? Had he fanned this flame? Was I to meet in these depths companions and friends of Captain Nemo whom he was going to visit, and who, like him, led this strange existence? Should I find down there a whole colony of exiles who, weary of the miseries of this earth, had sought and found independence in the deep ocean? All these foolish and unreasonable ideas pursued me. And in this condition of mind, over-excited by the succession of wonders continually passing before my eyes, I should not have been surprised to meet at the bottom of the sea one of those submarine towns of which Captain Nemo dreamed. - -Our road grew lighter and lighter. The white glimmer came in rays from the summit of a mountain about 800 feet high. But what I saw was simply a reflection, developed by the clearness of the waters. The source of this inexplicable light was a fire on the opposite side of the mountain. - -In the midst of this stony maze furrowing the bottom of the Atlantic, Captain Nemo advanced without hesitation. He knew this dreary road. Doubtless he had often travelled over it, and could not lose himself. I followed him with unshaken confidence. He seemed to me like a genie of the sea; and, as he walked before me, I could not help admiring his stature, which was outlined in black on the luminous horizon. - -It was one in the morning when we arrived at the first slopes of the mountain; but to gain access to them we must venture through the difficult paths of a vast copse. - -Yes; a copse of dead trees, without leaves, without sap, trees petrified by the action of the water and here and there overtopped by gigantic pines. It was like a coal-pit still standing, holding by the roots to the broken soil, and whose branches, like fine black paper cuttings, showed distinctly on the watery ceiling. Picture to yourself a forest in the Hartz hanging on to the sides of the mountain, but a forest swallowed up. The paths were encumbered with seaweed and fucus, between which grovelled a whole world of crustacea. I went along, climbing the rocks, striding over extended trunks, breaking the sea bind-weed which hung from one tree to the other; and frightening the fishes, which flew from branch to branch. Pressing onward, I felt no fatigue. I followed my guide, who was never tired. What a spectacle! How can I express it? how paint the aspect of those woods and rocks in this medium—their under parts dark and wild, the upper coloured with red tints, by that light which the reflecting powers of the waters doubled? We climbed rocks which fell directly after with gigantic bounds and the low growling of an avalanche. To right and left ran long, dark galleries, where sight was lost. Here opened vast glades which the hand of man seemed to have worked; and I sometimes asked myself if some inhabitant of these submarine regions would not suddenly appear to me. - -But Captain Nemo was still mounting. I could not stay behind. I followed boldly. My stick gave me good help. A false step would have been dangerous on the narrow passes sloping down to the sides of the gulfs; but I walked with firm step, without feeling any giddiness. Now I jumped a crevice, the depth of which would have made me hesitate had it been among the glaciers on the land; now I ventured on the unsteady trunk of a tree thrown across from one abyss to the other, without looking under my feet, having only eyes to admire the wild sites of this region. - -There, monumental rocks, leaning on their regularly-cut bases, seemed to defy all laws of equilibrium. From between their stony knees trees sprang, like a jet under heavy pressure, and upheld others which upheld them. Natural towers, large scarps, cut perpendicularly, like a "curtain," inclined at an angle which the laws of gravitation could never have tolerated in terrestrial regions. - -Two hours after quitting the Nautilus we had crossed the line of trees, and a hundred feet above our heads rose the top of the mountain, which cast a shadow on the brilliant irradiation of the opposite slope. Some petrified shrubs ran fantastically here and there. Fishes got up under our feet like birds in the long grass. The massive rocks were rent with impenetrable fractures, deep grottos, and unfathomable holes, at the bottom of which formidable creatures might be heard moving. My blood curdled when I saw enormous antennae blocking my road, or some frightful claw closing with a noise in the shadow of some cavity. Millions of luminous spots shone brightly in the midst of the darkness. They were the eyes of giant crustacea crouched in their holes; giant lobsters setting themselves up like halberdiers, and moving their claws with the clicking sound of pincers; titanic crabs, pointed like a gun on its carriage; and frightful-looking poulps, interweaving their tentacles like a living nest of serpents. - -We had now arrived on the first platform, where other surprises awaited me. Before us lay some picturesque ruins, which betrayed the hand of man and not that of the Creator. There were vast heaps of stone, amongst which might be traced the vague and shadowy forms of castles and temples, clothed with a world of blossoming zoophytes, and over which, instead of ivy, sea-weed and fucus threw a thick vegetable mantle. But what was this portion of the globe which had been swallowed by cataclysms? Who had placed those rocks and stones like cromlechs of prehistoric times? Where was I? Whither had Captain Nemo's fancy hurried me? - -I would fain have asked him; not being able to, I stopped him—I seized his arm. But, shaking his head, and pointing to the highest point of the mountain, he seemed to say: - -"Come, come along; come higher!" - -I followed, and in a few minutes I had climbed to the top, which for a circle of ten yards commanded the whole mass of rock. - -I looked down the side we had just climbed. The mountain did not rise more than seven or eight hundred feet above the level of the plain; but on the opposite side it commanded from twice that height the depths of this part of the Atlantic. My eyes ranged far over a large space lit by a violent fulguration. In fact, the mountain was a volcano. - -At fifty feet above the peak, in the midst of a rain of stones and scoriae, a large crater was vomiting forth torrents of lava which fell in a cascade of fire into the bosom of the liquid mass. Thus situated, this volcano lit the lower plain like an immense torch, even to the extreme limits of the horizon. I said that the submarine crater threw up lava, but no flames. Flames require the oxygen of the air to feed upon and cannot be developed under water; but streams of lava, having in themselves the principles of their incandescence, can attain a white heat, fight vigorously against the liquid element, and turn it to vapour by contact. - -Rapid currents bearing all these gases in diffusion and torrents of lava slid to the bottom of the mountain like an eruption of Vesuvius on another Terra del Greco. - -There indeed under my eyes, ruined, destroyed, lay a town—its roofs open to the sky, its temples fallen, its arches dislocated, its columns lying on the ground, from which one would still recognise the massive character of Tuscan architecture. Further on, some remains of a gigantic aqueduct; here the high base of an Acropolis, with the floating outline of a Parthenon; there traces of a quay, as if an ancient port had formerly abutted on the borders of the ocean, and disappeared with its merchant vessels and its war-galleys. Farther on again, long lines of sunken walls and broad, deserted streets—a perfect Pompeii escaped beneath the waters. Such was the sight that Captain Nemo brought before my eyes! - -Where was I? Where was I? I must know at any cost. I tried to speak, but Captain Nemo stopped me by a gesture, and, picking up a piece of chalk-stone, advanced to a rock of black basalt, and traced the one word: - - -ATLANTIS - - -What a light shot through my mind! Atlantis! the Atlantis of Plato, that continent denied by Origen and Humbolt, who placed its disappearance amongst the legendary tales. I had it there now before my eyes, bearing upon it the unexceptionable testimony of its catastrophe. The region thus engulfed was beyond Europe, Asia, and Lybia, beyond the columns of Hercules, where those powerful people, the Atlantides, lived, against whom the first wars of ancient Greeks were waged. - -Thus, led by the strangest destiny, I was treading under foot the mountains of this continent, touching with my hand those ruins a thousand generations old and contemporary with the geological epochs. I was walking on the very spot where the contemporaries of the first man had walked. - -Whilst I was trying to fix in my mind every detail of this grand landscape, Captain Nemo remained motionless, as if petrified in mute ecstasy, leaning on a mossy stone. Was he dreaming of those generations long since disappeared? Was he asking them the secret of human destiny? Was it here this strange man came to steep himself in historical recollections, and live again this ancient life—he who wanted no modern one? What would I not have given to know his thoughts, to share them, to understand them! We remained for an hour at this place, contemplating the vast plains under the brightness of the lava, which was some times wonderfully intense. Rapid tremblings ran along the mountain caused by internal bubblings, deep noise, distinctly transmitted through the liquid medium were echoed with majestic grandeur. At this moment the moon appeared through the mass of waters and threw her pale rays on the buried continent. It was but a gleam, but what an indescribable effect! The Captain rose, cast one last look on the immense plain, and then bade me follow him. - -We descended the mountain rapidly, and, the mineral forest once passed, I saw the lantern of the Nautilus shining like a star. The Captain walked straight to it, and we got on board as the first rays of light whitened the surface of the ocean. - - - - -CHAPTER X - -THE SUBMARINE COAL-MINES - -The next day, the 20th of February, I awoke very late: the fatigues of the previous night had prolonged my sleep until eleven o'clock. I dressed quickly, and hastened to find the course the Nautilus was taking. The instruments showed it to be still toward the south, with a speed of twenty miles an hour and a depth of fifty fathoms. - -The species of fishes here did not differ much from those already noticed. There were rays of giant size, five yards long, and endowed with great muscular strength, which enabled them to shoot above the waves; sharks of many kinds; amongst others, one fifteen feet long, with triangular sharp teeth, and whose transparency rendered it almost invisible in the water. - -Amongst bony fish Conseil noticed some about three yards long, armed at the upper jaw with a piercing sword; other bright-coloured creatures, known in the time of Aristotle by the name of the sea-dragon, which are dangerous to capture on account of the spikes on their back. - -About four o'clock, the soil, generally composed of a thick mud mixed with petrified wood, changed by degrees, and it became more stony, and seemed strewn with conglomerate and pieces of basalt, with a sprinkling of lava. I thought that a mountainous region was succeeding the long plains; and accordingly, after a few evolutions of the Nautilus, I saw the southerly horizon blocked by a high wall which seemed to close all exit. Its summit evidently passed the level of the ocean. It must be a continent, or at least an island—one of the Canaries, or of the Cape Verde Islands. The bearings not being yet taken, perhaps designedly, I was ignorant of our exact position. In any case, such a wall seemed to me to mark the limits of that Atlantis, of which we had in reality passed over only the smallest part. - -Much longer should I have remained at the window admiring the beauties of sea and sky, but the panels closed. At this moment the Nautilus arrived at the side of this high, perpendicular wall. What it would do, I could not guess. I returned to my room; it no longer moved. I laid myself down with the full intention of waking after a few hours' sleep; but it was eight o'clock the next day when I entered the saloon. I looked at the manometer. It told me that the Nautilus was floating on the surface of the ocean. Besides, I heard steps on the platform. I went to the panel. It was open; but, instead of broad daylight, as I expected, I was surrounded by profound darkness. Where were we? Was I mistaken? Was it still night? No; not a star was shining and night has not that utter darkness. - -I knew not what to think, when a voice near me said: - -"Is that you, Professor?" - -"Ah! Captain," I answered, "where are we?" - -"Underground, sir." - -"Underground!" I exclaimed. "And the Nautilus floating still?" - -"It always floats." - -"But I do not understand." - -"Wait a few minutes, our lantern will be lit, and, if you like light places, you will be satisfied." - -I stood on the platform and waited. The darkness was so complete that I could not even see Captain Nemo; but, looking to the zenith, exactly above my head, I seemed to catch an undecided gleam, a kind of twilight filling a circular hole. At this instant the lantern was lit, and its vividness dispelled the faint light. I closed my dazzled eyes for an instant, and then looked again. The Nautilus was stationary, floating near a mountain which formed a sort of quay. The lake, then, supporting it was a lake imprisoned by a circle of walls, measuring two miles in diameter and six in circumference. Its level (the manometer showed) could only be the same as the outside level, for there must necessarily be a communication between the lake and the sea. The high partitions, leaning forward on their base, grew into a vaulted roof bearing the shape of an immense funnel turned upside down, the height being about five or six hundred yards. At the summit was a circular orifice, by which I had caught the slight gleam of light, evidently daylight. - -"Where are we?" I asked. - -"In the very heart of an extinct volcano, the interior of which has been invaded by the sea, after some great convulsion of the earth. Whilst you were sleeping, Professor, the Nautilus penetrated to this lagoon by a natural canal, which opens about ten yards beneath the surface of the ocean. This is its harbour of refuge, a sure, commodious, and mysterious one, sheltered from all gales. Show me, if you can, on the coasts of any of your continents or islands, a road which can give such perfect refuge from all storms." - -"Certainly," I replied, "you are in safety here, Captain Nemo. Who could reach you in the heart of a volcano? But did I not see an opening at its summit?" - -"Yes; its crater, formerly filled with lava, vapour, and flames, and which now gives entrance to the life-giving air we breathe." - -"But what is this volcanic mountain?" - -"It belongs to one of the numerous islands with which this sea is strewn—to vessels a simple sandbank—to us an immense cavern. Chance led me to discover it, and chance served me well." - -"But of what use is this refuge, Captain? The Nautilus wants no port." - -"No, sir; but it wants electricity to make it move, and the wherewithal to make the electricity—sodium to feed the elements, coal from which to get the sodium, and a coal-mine to supply the coal. And exactly on this spot the sea covers entire forests embedded during the geological periods, now mineralised and transformed into coal; for me they are an inexhaustible mine." - -"Your men follow the trade of miners here, then, Captain?" - -"Exactly so. These mines extend under the waves like the mines of Newcastle. Here, in their diving-dresses, pick axe and shovel in hand, my men extract the coal, which I do not even ask from the mines of the earth. When I burn this combustible for the manufacture of sodium, the smoke, escaping from the crater of the mountain, gives it the appearance of a still-active volcano." - -"And we shall see your companions at work?" - -"No; not this time at least; for I am in a hurry to continue our submarine tour of the earth. So I shall content myself with drawing from the reserve of sodium I already possess. The time for loading is one day only, and we continue our voyage. So, if you wish to go over the cavern and make the round of the lagoon, you must take advantage of to-day, M. Aronnax." - -I thanked the Captain and went to look for my companions, who had not yet left their cabin. I invited them to follow me without saying where we were. They mounted the platform. Conseil, who was astonished at nothing, seemed to look upon it as quite natural that he should wake under a mountain, after having fallen asleep under the waves. But Ned Land thought of nothing but finding whether the cavern had any exit. After breakfast, about ten o'clock, we went down on to the mountain. - -"Here we are, once more on land," said Conseil. - -"I do not call this land," said the Canadian. "And besides, we are not on it, but beneath it." - -Between the walls of the mountains and the waters of the lake lay a sandy shore which, at its greatest breadth, measured five hundred feet. On this soil one might easily make the tour of the lake. But the base of the high partitions was stony ground, with volcanic locks and enormous pumice-stones lying in picturesque heaps. All these detached masses, covered with enamel, polished by the action of the subterraneous fires, shone resplendent by the light of our electric lantern. The mica dust from the shore, rising under our feet, flew like a cloud of sparks. The bottom now rose sensibly, and we soon arrived at long circuitous slopes, or inclined planes, which took us higher by degrees; but we were obliged to walk carefully among these conglomerates, bound by no cement, the feet slipping on the glassy crystal, felspar, and quartz. - -The volcanic nature of this enormous excavation was confirmed on all sides, and I pointed it out to my companions. - -"Picture to yourselves," said I, "what this crater must have been when filled with boiling lava, and when the level of the incandescent liquid rose to the orifice of the mountain, as though melted on the top of a hot plate." - -"I can picture it perfectly," said Conseil. "But, sir, will you tell me why the Great Architect has suspended operations, and how it is that the furnace is replaced by the quiet waters of the lake?" - -"Most probably, Conseil, because some convulsion beneath the ocean produced that very opening which has served as a passage for the Nautilus. Then the waters of the Atlantic rushed into the interior of the mountain. There must have been a terrible struggle between the two elements, a struggle which ended in the victory of Neptune. But many ages have run out since then, and the submerged volcano is now a peaceable grotto." - -"Very well," replied Ned Land; "I accept the explanation, sir; but, in our own interests, I regret that the opening of which you speak was not made above the level of the sea." - -"But, friend Ned," said Conseil, "if the passage had not been under the sea, the Nautilus could not have gone through it." - -We continued ascending. The steps became more and more perpendicular and narrow. Deep excavations, which we were obliged to cross, cut them here and there; sloping masses had to be turned. We slid upon our knees and crawled along. But Conseil's dexterity and the Canadian's strength surmounted all obstacles. At a height of about 31 feet the nature of the ground changed without becoming more practicable. To the conglomerate and trachyte succeeded black basalt, the first dispread in layers full of bubbles, the latter forming regular prisms, placed like a colonnade supporting the spring of the immense vault, an admirable specimen of natural architecture. Between the blocks of basalt wound long streams of lava, long since grown cold, encrusted with bituminous rays; and in some places there were spread large carpets of sulphur. A more powerful light shone through the upper crater, shedding a vague glimmer over these volcanic depressions for ever buried in the bosom of this extinguished mountain. But our upward march was soon stopped at a height of about two hundred and fifty feet by impassable obstacles. There was a complete vaulted arch overhanging us, and our ascent was changed to a circular walk. At the last change vegetable life began to struggle with the mineral. Some shrubs, and even some trees, grew from the fractures of the walls. I recognised some euphorbias, with the caustic sugar coming from them; heliotropes, quite incapable of justifying their name, sadly drooped their clusters of flowers, both their colour and perfume half gone. Here and there some chrysanthemums grew timidly at the foot of an aloe with long, sickly-looking leaves. But between the streams of lava, I saw some little violets still slightly perfumed, and I admit that I smelt them with delight. Perfume is the soul of the flower, and sea-flowers have no soul. - -We had arrived at the foot of some sturdy dragon-trees, which had pushed aside the rocks with their strong roots, when Ned Land exclaimed: - -"Ah! sir, a hive! a hive!" - -"A hive!" I replied, with a gesture of incredulity. - -"Yes, a hive," repeated the Canadian, "and bees humming round it." - -I approached, and was bound to believe my own eyes. There at a hole bored in one of the dragon-trees were some thousands of these ingenious insects, so common in all the Canaries, and whose produce is so much esteemed. Naturally enough, the Canadian wished to gather the honey, and I could not well oppose his wish. A quantity of dry leaves, mixed with sulphur, he lit with a spark from his flint, and he began to smoke out the bees. The humming ceased by degrees, and the hive eventually yielded several pounds of the sweetest honey, with which Ned Land filled his haversack. - -"When I have mixed this honey with the paste of the bread-fruit," said he, "I shall be able to offer you a succulent cake." - -[Transcriber's Note: 'bread-fruit' has been substituted for 'artocarpus' in this ed.] - -"'Pon my word," said Conseil, "it will be gingerbread." - -"Never mind the gingerbread," said I; "let us continue our interesting walk." - -At every turn of the path we were following, the lake appeared in all its length and breadth. The lantern lit up the whole of its peaceable surface, which knew neither ripple nor wave. The Nautilus remained perfectly immovable. On the platform, and on the mountain, the ship's crew were working like black shadows clearly carved against the luminous atmosphere. We were now going round the highest crest of the first layers of rock which upheld the roof. I then saw that bees were not the only representatives of the animal kingdom in the interior of this volcano. Birds of prey hovered here and there in the shadows, or fled from their nests on the top of the rocks. There were sparrow hawks, with white breasts, and kestrels, and down the slopes scampered, with their long legs, several fine fat bustards. I leave anyone to imagine the covetousness of the Canadian at the sight of this savoury game, and whether he did not regret having no gun. But he did his best to replace the lead by stones, and, after several fruitless attempts, he succeeded in wounding a magnificent bird. To say that he risked his life twenty times before reaching it is but the truth; but he managed so well that the creature joined the honey-cakes in his bag. We were now obliged to descend toward the shore, the crest becoming impracticable. Above us the crater seemed to gape like the mouth of a well. From this place the sky could be clearly seen, and clouds, dissipated by the west wind, leaving behind them, even on the summit of the mountain, their misty remnants—certain proof that they were only moderately high, for the volcano did not rise more than eight hundred feet above the level of the ocean. Half an hour after the Canadian's last exploit we had regained the inner shore. Here the flora was represented by large carpets of marine crystal, a little umbelliferous plant very good to pickle, which also bears the name of pierce-stone and sea-fennel. Conseil gathered some bundles of it. As to the fauna, it might be counted by thousands of crustacea of all sorts, lobsters, crabs, spider-crabs, chameleon shrimps, and a large number of shells, rockfish, and limpets. Three-quarters of an hour later we had finished our circuitous walk and were on board. The crew had just finished loading the sodium, and the Nautilus could have left that instant. But Captain Nemo gave no order. Did he wish to wait until night, and leave the submarine passage secretly? Perhaps so. Whatever it might be, the next day, the Nautilus, having left its port, steered clear of all land at a few yards beneath the waves of the Atlantic. - - - - -CHAPTER XI - -THE SARGASSO SEA - -That day the Nautilus crossed a singular part of the Atlantic Ocean. No one can be ignorant of the existence of a current of warm water known by the name of the Gulf Stream. After leaving the Gulf of Florida, we went in the direction of Spitzbergen. But before entering the Gulf of Mexico, about 45° of N. lat., this current divides into two arms, the principal one going towards the coast of Ireland and Norway, whilst the second bends to the south about the height of the Azores; then, touching the African shore, and describing a lengthened oval, returns to the Antilles. This second arm—it is rather a collar than an arm—surrounds with its circles of warm water that portion of the cold, quiet, immovable ocean called the Sargasso Sea, a perfect lake in the open Atlantic: it takes no less than three years for the great current to pass round it. Such was the region the Nautilus was now visiting, a perfect meadow, a close carpet of seaweed, fucus, and tropical berries, so thick and so compact that the stem of a vessel could hardly tear its way through it. And Captain Nemo, not wishing to entangle his screw in this herbaceous mass, kept some yards beneath the surface of the waves. The name Sargasso comes from the Spanish word "sargazzo" which signifies kelp. This kelp, or berry-plant, is the principal formation of this immense bank. And this is the reason why these plants unite in the peaceful basin of the Atlantic. The only explanation which can be given, he says, seems to me to result from the experience known to all the world. Place in a vase some fragments of cork or other floating body, and give to the water in the vase a circular movement, the scattered fragments will unite in a group in the centre of the liquid surface, that is to say, in the part least agitated. In the phenomenon we are considering, the Atlantic is the vase, the Gulf Stream the circular current, and the Sargasso Sea the central point at which the floating bodies unite. - -I share Maury's opinion, and I was able to study the phenomenon in the very midst, where vessels rarely penetrate. Above us floated products of all kinds, heaped up among these brownish plants; trunks of trees torn from the Andes or the Rocky Mountains, and floated by the Amazon or the Mississippi; numerous wrecks, remains of keels, or ships' bottoms, side-planks stove in, and so weighted with shells and barnacles that they could not again rise to the surface. And time will one day justify Maury's other opinion, that these substances thus accumulated for ages will become petrified by the action of the water and will then form inexhaustible coal-mines—a precious reserve prepared by far-seeing Nature for the moment when men shall have exhausted the mines of continents. - -In the midst of this inextricable mass of plants and sea weed, I noticed some charming pink halcyons and actiniae, with their long tentacles trailing after them, and medusae, green, red, and blue. - -All the day of the 22nd of February we passed in the Sargasso Sea, where such fish as are partial to marine plants find abundant nourishment. The next, the ocean had returned to its accustomed aspect. From this time for nineteen days, from the 23rd of February to the 12th of March, the Nautilus kept in the middle of the Atlantic, carrying us at a constant speed of a hundred leagues in twenty-four hours. Captain Nemo evidently intended accomplishing his submarine programme, and I imagined that he intended, after doubling Cape Horn, to return to the Australian seas of the Pacific. Ned Land had cause for fear. In these large seas, void of islands, we could not attempt to leave the boat. Nor had we any means of opposing Captain Nemo's will. Our only course was to submit; but what we could neither gain by force nor cunning, I liked to think might be obtained by persuasion. This voyage ended, would he not consent to restore our liberty, under an oath never to reveal his existence?—an oath of honour which we should have religiously kept. But we must consider that delicate question with the Captain. But was I free to claim this liberty? Had he not himself said from the beginning, in the firmest manner, that the secret of his life exacted from him our lasting imprisonment on board the Nautilus? And would not my four months' silence appear to him a tacit acceptance of our situation? And would not a return to the subject result in raising suspicions which might be hurtful to our projects, if at some future time a favourable opportunity offered to return to them? - -During the nineteen days mentioned above, no incident of any kind happened to signalise our voyage. I saw little of the Captain; he was at work. In the library I often found his books left open, especially those on natural history. My work on submarine depths, conned over by him, was covered with marginal notes, often contradicting my theories and systems; but the Captain contented himself with thus purging my work; it was very rare for him to discuss it with me. Sometimes I heard the melancholy tones of his organ; but only at night, in the midst of the deepest obscurity, when the Nautilus slept upon the deserted ocean. During this part of our voyage we sailed whole days on the surface of the waves. The sea seemed abandoned. A few sailing-vessels, on the road to India, were making for the Cape of Good Hope. One day we were followed by the boats of a whaler, who, no doubt, took us for some enormous whale of great price; but Captain Nemo did not wish the worthy fellows to lose their time and trouble, so ended the chase by plunging under the water. Our navigation continued until the 13th of March; that day the Nautilus was employed in taking soundings, which greatly interested me. We had then made about 13,000 leagues since our departure from the high seas of the Pacific. The bearings gave us 45° 37' S. lat., and 37° 53' W. long. It was the same water in which Captain Denham of the Herald sounded 7,000 fathoms without finding the bottom. There, too, Lieutenant Parker, of the American frigate Congress, could not touch the bottom with 15,140 fathoms. Captain Nemo intended seeking the bottom of the ocean by a diagonal sufficiently lengthened by means of lateral planes placed at an angle of 45° with the water-line of the Nautilus. Then the screw set to work at its maximum speed, its four blades beating the waves with in describable force. Under this powerful pressure, the hull of the Nautilus quivered like a sonorous chord and sank regularly under the water. - -At 7,000 fathoms I saw some blackish tops rising from the midst of the waters; but these summits might belong to high mountains like the Himalayas or Mont Blanc, even higher; and the depth of the abyss remained incalculable. The Nautilus descended still lower, in spite of the great pressure. I felt the steel plates tremble at the fastenings of the bolts; its bars bent, its partitions groaned; the windows of the saloon seemed to curve under the pressure of the waters. And this firm structure would doubtless have yielded, if, as its Captain had said, it had not been capable of resistance like a solid block. We had attained a depth of 16,000 yards (four leagues), and the sides of the Nautilus then bore a pressure of 1,600 atmospheres, that is to say, 3,200 lb. to each square two-fifths of an inch of its surface. - -"What a situation to be in!" I exclaimed. "To overrun these deep regions where man has never trod! Look, Captain, look at these magnificent rocks, these uninhabited grottoes, these lowest receptacles of the globe, where life is no longer possible! What unknown sights are here! Why should we be unable to preserve a remembrance of them?" - -"Would you like to carry away more than the remembrance?" said Captain Nemo. - -"What do you mean by those words?" - -"I mean to say that nothing is easier than to make a photographic view of this submarine region." - -I had not time to express my surprise at this new proposition, when, at Captain Nemo's call, an objective was brought into the saloon. Through the widely-opened panel, the liquid mass was bright with electricity, which was distributed with such uniformity that not a shadow, not a gradation, was to be seen in our manufactured light. The Nautilus remained motionless, the force of its screw subdued by the inclination of its planes: the instrument was propped on the bottom of the oceanic site, and in a few seconds we had obtained a perfect negative. - -But, the operation being over, Captain Nemo said, "Let us go up; we must not abuse our position, nor expose the Nautilus too long to such great pressure." - -"Go up again!" I exclaimed. - -"Hold well on." - -I had not time to understand why the Captain cautioned me thus, when I was thrown forward on to the carpet. At a signal from the Captain, its screw was shipped, and its blades raised vertically; the Nautilus shot into the air like a balloon, rising with stunning rapidity, and cutting the mass of waters with a sonorous agitation. Nothing was visible; and in four minutes it had shot through the four leagues which separated it from the ocean, and, after emerging like a flying-fish, fell, making the waves rebound to an enormous height. - - - - -CHAPTER XII - -CACHALOTS AND WHALES - -During the nights of the 13th and 14th of March, the Nautilus returned to its southerly course. I fancied that, when on a level with Cape Horn, he would turn the helm westward, in order to beat the Pacific seas, and so complete the tour of the world. He did nothing of the kind, but continued on his way to the southern regions. Where was he going to? To the pole? It was madness! I began to think that the Captain's temerity justified Ned Land's fears. For some time past the Canadian had not spoken to me of his projects of flight; he was less communicative, almost silent. I could see that this lengthened imprisonment was weighing upon him, and I felt that rage was burning within him. When he met the Captain, his eyes lit up with suppressed anger; and I feared that his natural violence would lead him into some extreme. That day, the 14th of March, Conseil and he came to me in my room. I inquired the cause of their visit. - -"A simple question to ask you, sir," replied the Canadian. - -"Speak, Ned." - -"How many men are there on board the Nautilus, do you think?" - -"I cannot tell, my friend." - -"I should say that its working does not require a large crew." - -"Certainly, under existing conditions, ten men, at the most, ought to be enough." - -"Well, why should there be any more?" - -"Why?" I replied, looking fixedly at Ned Land, whose meaning was easy to guess. "Because," I added, "if my surmises are correct, and if I have well understood the Captain's existence, the Nautilus is not only a vessel: it is also a place of refuge for those who, like its commander, have broken every tie upon earth." - -"Perhaps so," said Conseil; "but, in any case, the Nautilus can only contain a certain number of men. Could not you, sir, estimate their maximum?" - -"How, Conseil?" - -"By calculation; given the size of the vessel, which you know, sir, and consequently the quantity of air it contains, knowing also how much each man expends at a breath, and comparing these results with the fact that the Nautilus is obliged to go to the surface every twenty-four hours." - -Conseil had not finished the sentence before I saw what he was driving at. - -"I understand," said I; "but that calculation, though simple enough, can give but a very uncertain result." - -"Never mind," said Ned Land urgently. - -"Here it is, then," said I. "In one hour each man consumes the oxygen contained in twenty gallons of air; and in twenty-four, that contained in 480 gallons. We must, therefore find how many times 480 gallons of air the Nautilus contains." - -"Just so," said Conseil. - -"Or," I continued, "the size of the Nautilus being 1,500 tons; and one ton holding 200 gallons, it contains 300,000 gallons of air, which, divided by 480, gives a quotient of 625. Which means to say, strictly speaking, that the air contained in the Nautilus would suffice for 625 men for twenty-four hours." - -"Six hundred and twenty-five!" repeated Ned. - -"But remember that all of us, passengers, sailors, and officers included, would not form a tenth part of that number." - -"Still too many for three men," murmured Conseil. - -The Canadian shook his head, passed his hand across his forehead, and left the room without answering. - -"Will you allow me to make one observation, sir?" said Conseil. "Poor Ned is longing for everything that he can not have. His past life is always present to him; everything that we are forbidden he regrets. His head is full of old recollections. And we must understand him. What has he to do here? Nothing; he is not learned like you, sir; and has not the same taste for the beauties of the sea that we have. He would risk everything to be able to go once more into a tavern in his own country." - -Certainly the monotony on board must seem intolerable to the Canadian, accustomed as he was to a life of liberty and activity. Events were rare which could rouse him to any show of spirit; but that day an event did happen which recalled the bright days of the harpooner. About eleven in the morning, being on the surface of the ocean, the Nautilus fell in with a troop of whales—an encounter which did not astonish me, knowing that these creatures, hunted to death, had taken refuge in high latitudes. - -We were seated on the platform, with a quiet sea. The month of October in those latitudes gave us some lovely autumnal days. It was the Canadian—he could not be mistaken—who signalled a whale on the eastern horizon. Looking attentively, one might see its black back rise and fall with the waves five miles from the Nautilus. - -"Ah!" exclaimed Ned Land, "if I was on board a whaler, now such a meeting would give me pleasure. It is one of large size. See with what strength its blow-holes throw up columns of air an steam! Confound it, why am I bound to these steel plates?" - -"What, Ned," said I, "you have not forgotten your old ideas of fishing?" - -"Can a whale-fisher ever forget his old trade, sir? Can he ever tire of the emotions caused by such a chase?" - -"You have never fished in these seas, Ned?" - -"Never, sir; in the northern only, and as much in Behring as in Davis Straits." - -"Then the southern whale is still unknown to you. It is the Greenland whale you have hunted up to this time, and that would not risk passing through the warm waters of the equator. Whales are localised, according to their kinds, in certain seas which they never leave. And if one of these creatures went from Behring to Davis Straits, it must be simply because there is a passage from one sea to the other, either on the American or the Asiatic side." - -"In that case, as I have never fished in these seas, I do not know the kind of whale frequenting them!" - -"I have told you, Ned." - -"A greater reason for making their acquaintance," said Conseil. - -"Look! look!" exclaimed the Canadian, "they approach: they aggravate me; they know that I cannot get at them!" - -Ned stamped his feet. His hand trembled, as he grasped an imaginary harpoon. - -"Are these cetaceans as large as those of the northern seas?" asked he. - -"Very nearly, Ned." - -"Because I have seen large whales, sir, whales measuring a hundred feet. I have even been told that those of Hullamoch and Umgallick, of the Aleutian Islands, are sometimes a hundred and fifty feet long." - -"That seems to me exaggeration. These creatures are only balaeaopterons, provided with dorsal fins; and, like the cachalots, are generally much smaller than the Greenland whale." - -"Ah!" exclaimed the Canadian, whose eyes had never left the ocean, "they are coming nearer; they are in the same water as the Nautilus." - -Then, returning to the conversation, he said: - -"You spoke of the cachalot as a small creature. I have heard of gigantic ones. They are intelligent cetacea. It is said of some that they cover themselves with seaweed and fucus, and then are taken for islands. People encamp upon them, and settle there; lights a fire——" - -"And build houses," said Conseil. - -"Yes, joker," said Ned Land. "And one fine day the creature plunges, carrying with it all the inhabitants to the bottom of the sea." - -"Something like the travels of Sinbad the Sailor," I replied, laughing. - -"Ah!" suddenly exclaimed Ned Land, "it is not one whale; there are ten—there are twenty—it is a whole troop! And I not able to do anything! hands and feet tied!" - -"But, friend Ned," said Conseil, "why do you not ask Captain Nemo's permission to chase them?" - -Conseil had not finished his sentence when Ned Land had lowered himself through the panel to seek the Captain. A few minutes afterwards the two appeared together on the platform. - -Captain Nemo watched the troop of cetacea playing on the waters about a mile from the Nautilus. - -"They are southern whales," said he; "there goes the fortune of a whole fleet of whalers." - -"Well, sir," asked the Canadian, "can I not chase them, if only to remind me of my old trade of harpooner?" - -"And to what purpose?" replied Captain Nemo; "only to destroy! We have nothing to do with the whale-oil on board." - -"But, sir," continued the Canadian, "in the Red Sea you allowed us to follow the dugong." - -"Then it was to procure fresh meat for my crew. Here it would be killing for killing's sake. I know that is a privilege reserved for man, but I do not approve of such murderous pastime. In destroying the southern whale (like the Greenland whale, an inoffensive creature), your traders do a culpable action, Master Land. They have already depopulated the whole of Baffin's Bay, and are annihilating a class of useful animals. Leave the unfortunate cetacea alone. They have plenty of natural enemies—cachalots, swordfish, and sawfish—without you troubling them." - -The Captain was right. The barbarous and inconsiderate greed of these fishermen will one day cause the disappearance of the last whale in the ocean. Ned Land whistled "Yankee-doodle" between his teeth, thrust his hands into his pockets, and turned his back upon us. But Captain Nemo watched the troop of cetacea, and, addressing me, said: - -"I was right in saying that whales had natural enemies enough, without counting man. These will have plenty to do before long. Do you see, M. Aronnax, about eight miles to leeward, those blackish moving points?" - -"Yes, Captain," I replied. - -"Those are cachalots—terrible animals, which I have met in troops of two or three hundred. As to those, they are cruel, mischievous creatures; they would be right in exterminating them." - -The Canadian turned quickly at the last words. - -"Well, Captain," said he, "it is still time, in the interest of the whales." - -"It is useless to expose one's self, Professor. The Nautilus will disperse them. It is armed with a steel spur as good as Master Land's harpoon, I imagine." - -The Canadian did not put himself out enough to shrug his shoulders. Attack cetacea with blows of a spur! Who had ever heard of such a thing? - -"Wait, M. Aronnax," said Captain Nemo. "We will show you something you have never yet seen. We have no pity for these ferocious creatures. They are nothing but mouth and teeth." - -Mouth and teeth! No one could better describe the macrocephalous cachalot, which is sometimes more than seventy-five feet long. Its enormous head occupies one-third of its entire body. Better armed than the whale, whose upper jaw is furnished only with whalebone, it is supplied with twenty-five large tusks, about eight inches long, cylindrical and conical at the top, each weighing two pounds. It is in the upper part of this enormous head, in great cavities divided by cartilages, that is to be found from six to eight hundred pounds of that precious oil called spermaceti. The cachalot is a disagreeable creature, more tadpole than fish, according to Fredol's description. It is badly formed, the whole of its left side being (if we may say it), a "failure," and being only able to see with its right eye. But the formidable troop was nearing us. They had seen the whales and were preparing to attack them. One could judge beforehand that the cachalots would be victorious, not only because they were better built for attack than their inoffensive adversaries, but also because they could remain longer under water without coming to the surface. There was only just time to go to the help of the whales. The Nautilus went under water. Conseil, Ned Land, and I took our places before the window in the saloon, and Captain Nemo joined the pilot in his cage to work his apparatus as an engine of destruction. Soon I felt the beatings of the screw quicken, and our speed increased. The battle between the cachalots and the whales had already begun when the Nautilus arrived. They did not at first show any fear at the sight of this new monster joining in the conflict. But they soon had to guard against its blows. What a battle! The Nautilus was nothing but a formidable harpoon, brandished by the hand of its Captain. It hurled itself against the fleshy mass, passing through from one part to the other, leaving behind it two quivering halves of the animal. It could not feel the formidable blows from their tails upon its sides, nor the shock which it produced itself, much more. One cachalot killed, it ran at the next, tacked on the spot that it might not miss its prey, going forwards and backwards, answering to its helm, plunging when the cetacean dived into the deep waters, coming up with it when it returned to the surface, striking it front or sideways, cutting or tearing in all directions and at any pace, piercing it with its terrible spur. What carnage! What a noise on the surface of the waves! What sharp hissing, and what snorting peculiar to these enraged animals! In the midst of these waters, generally so peaceful, their tails made perfect billows. For one hour this wholesale massacre continued, from which the cachalots could not escape. Several times ten or twelve united tried to crush the Nautilus by their weight. From the window we could see their enormous mouths, studded with tusks, and their formidable eyes. Ned Land could not contain himself; he threatened and swore at them. We could feel them clinging to our vessel like dogs worrying a wild boar in a copse. But the Nautilus, working its screw, carried them here and there, or to the upper levels of the ocean, without caring for their enormous weight, nor the powerful strain on the vessel. At length the mass of cachalots broke up, the waves became quiet, and I felt that we were rising to the surface. The panel opened, and we hurried on to the platform. The sea was covered with mutilated bodies. A formidable explosion could not have divided and torn this fleshy mass with more violence. We were floating amid gigantic bodies, bluish on the back and white underneath, covered with enormous protuberances. Some terrified cachalots were flying towards the horizon. The waves were dyed red for several miles, and the Nautilus floated in a sea of blood: Captain Nemo joined us. - -"Well, Master Land?" said he. - -"Well, sir," replied the Canadian, whose enthusiasm had somewhat calmed; "it is a terrible spectacle, certainly. But I am not a butcher. I am a hunter, and I call this a butchery." - -"It is a massacre of mischievous creatures," replied the Captain; "and the Nautilus is not a butcher's knife." - -"I like my harpoon better," said the Canadian. - -"Every one to his own," answered the Captain, looking fixedly at Ned Land. - -I feared he would commit some act of violence, which would end in sad consequences. But his anger was turned by the sight of a whale which the Nautilus had just come up with. The creature had not quite escaped from the cachalot's teeth. I recognised the southern whale by its flat head, which is entirely black. Anatomically, it is distinguished from the white whale and the North Cape whale by the seven cervical vertebrae, and it has two more ribs than its congeners. The unfortunate cetacean was lying on its side, riddled with holes from the bites, and quite dead. From its mutilated fin still hung a young whale which it could not save from the massacre. Its open mouth let the water flow in and out, murmuring like the waves breaking on the shore. Captain Nemo steered close to the corpse of the creature. Two of his men mounted its side, and I saw, not without surprise, that they were drawing from its breasts all the milk which they contained, that is to say, about two or three tons. The Captain offered me a cup of the milk, which was still warm. I could not help showing my repugnance to the drink; but he assured me that it was excellent, and not to be distinguished from cow's milk. I tasted it, and was of his opinion. It was a useful reserve to us, for in the shape of salt butter or cheese it would form an agreeable variety from our ordinary food. From that day I noticed with uneasiness that Ned Land's ill-will towards Captain Nemo increased, and I resolved to watch the Canadian's gestures closely. - - - - -CHAPTER XIII - -THE ICEBERG - -The Nautilus was steadily pursuing its southerly course, following the fiftieth meridian with considerable speed. Did he wish to reach the pole? I did not think so, for every attempt to reach that point had hitherto failed. Again, the season was far advanced, for in the Antarctic regions the 13th of March corresponds with the 13th of September of northern regions, which begin at the equinoctial season. On the 14th of March I saw floating ice in latitude 55°, merely pale bits of debris from twenty to twenty-five feet long, forming banks over which the sea curled. The Nautilus remained on the surface of the ocean. Ned Land, who had fished in the Arctic Seas, was familiar with its icebergs; but Conseil and I admired them for the first time. In the atmosphere towards the southern horizon stretched a white dazzling band. English whalers have given it the name of "ice blink." However thick the clouds may be, it is always visible, and announces the presence of an ice pack or bank. Accordingly, larger blocks soon appeared, whose brilliancy changed with the caprices of the fog. Some of these masses showed green veins, as if long undulating lines had been traced with sulphate of copper; others resembled enormous amethysts with the light shining through them. Some reflected the light of day upon a thousand crystal facets. Others shaded with vivid calcareous reflections resembled a perfect town of marble. The more we neared the south the more these floating islands increased both in number and importance. - -At 60° lat. every pass had disappeared. But, seeking carefully, Captain Nemo soon found a narrow opening, through which he boldly slipped, knowing, however, that it would close behind him. Thus, guided by this clever hand, the Nautilus passed through all the ice with a precision which quite charmed Conseil; icebergs or mountains, ice-fields or smooth plains, seeming to have no limits, drift-ice or floating ice-packs, plains broken up, called palchs when they are circular, and streams when they are made up of long strips. The temperature was very low; the thermometer exposed to the air marked 2 deg. or 3° below zero, but we were warmly clad with fur, at the expense of the sea-bear and seal. The interior of the Nautilus, warmed regularly by its electric apparatus, defied the most intense cold. Besides, it would only have been necessary to go some yards beneath the waves to find a more bearable temperature. Two months earlier we should have had perpetual daylight in these latitudes; but already we had had three or four hours of night, and by and by there would be six months of darkness in these circumpolar regions. On the 15th of March we were in the latitude of New Shetland and South Orkney. The Captain told me that formerly numerous tribes of seals inhabited them; but that English and American whalers, in their rage for destruction, massacred both old and young; thus, where there was once life and animation, they had left silence and death. - -About eight o'clock on the morning of the 16th of March the Nautilus, following the fifty-fifth meridian, cut the Antarctic polar circle. Ice surrounded us on all sides, and closed the horizon. But Captain Nemo went from one opening to another, still going higher. I cannot express my astonishment at the beauties of these new regions. The ice took most surprising forms. Here the grouping formed an oriental town, with innumerable mosques and minarets; there a fallen city thrown to the earth, as it were, by some convulsion of nature. The whole aspect was constantly changed by the oblique rays of the sun, or lost in the greyish fog amidst hurricanes of snow. Detonations and falls were heard on all sides, great overthrows of icebergs, which altered the whole landscape like a diorama. Often seeing no exit, I thought we were definitely prisoners; but, instinct guiding him at the slightest indication, Captain Nemo would discover a new pass. He was never mistaken when he saw the thin threads of bluish water trickling along the ice-fields; and I had no doubt that he had already ventured into the midst of these Antarctic seas before. On the 16th of March, however, the ice-fields absolutely blocked our road. It was not the iceberg itself, as yet, but vast fields cemented by the cold. But this obstacle could not stop Captain Nemo: he hurled himself against it with frightful violence. The Nautilus entered the brittle mass like a wedge, and split it with frightful crackings. It was the battering ram of the ancients hurled by infinite strength. The ice, thrown high in the air, fell like hail around us. By its own power of impulsion our apparatus made a canal for itself; some times carried away by its own impetus, it lodged on the ice-field, crushing it with its weight, and sometimes buried beneath it, dividing it by a simple pitching movement, producing large rents in it. Violent gales assailed us at this time, accompanied by thick fogs, through which, from one end of the platform to the other, we could see nothing. The wind blew sharply from all parts of the compass, and the snow lay in such hard heaps that we had to break it with blows of a pickaxe. The temperature was always at 5 deg. below zero; every outward part of the Nautilus was covered with ice. A rigged vessel would have been entangled in the blocked up gorges. A vessel without sails, with electricity for its motive power, and wanting no coal, could alone brave such high latitudes. At length, on the 18th of March, after many useless assaults, the Nautilus was positively blocked. It was no longer either streams, packs, or ice-fields, but an interminable and immovable barrier, formed by mountains soldered together. - -"An iceberg!" said the Canadian to me. - -I knew that to Ned Land, as well as to all other navigators who had preceded us, this was an inevitable obstacle. The sun appearing for an instant at noon, Captain Nemo took an observation as near as possible, which gave our situation at 51° 30' long. and 67° 39' of S. lat. We had advanced one degree more in this Antarctic region. Of the liquid surface of the sea there was no longer a glimpse. Under the spur of the Nautilus lay stretched a vast plain, entangled with confused blocks. Here and there sharp points and slender needles rising to a height of 200 feet; further on a steep shore, hewn as it were with an axe and clothed with greyish tints; huge mirrors, reflecting a few rays of sunshine, half drowned in the fog. And over this desolate face of nature a stern silence reigned, scarcely broken by the flapping of the wings of petrels and puffins. Everything was frozen—even the noise. The Nautilus was then obliged to stop in its adventurous course amid these fields of ice. In spite of our efforts, in spite of the powerful means employed to break up the ice, the Nautilus remained immovable. Generally, when we can proceed no further, we have return still open to us; but here return was as impossible as advance, for every pass had closed behind us; and for the few moments when we were stationary, we were likely to be entirely blocked, which did indeed happen about two o'clock in the afternoon, the fresh ice forming around its sides with astonishing rapidity. I was obliged to admit that Captain Nemo was more than imprudent. I was on the platform at that moment. The Captain had been observing our situation for some time past, when he said to me: - -"Well, sir, what do you think of this?" - -"I think that we are caught, Captain." - -"So, M. Aronnax, you really think that the Nautilus cannot disengage itself?" - -"With difficulty, Captain; for the season is already too far advanced for you to reckon on the breaking of the ice." - -"Ah! sir," said Captain Nemo, in an ironical tone, "you will always be the same. You see nothing but difficulties and obstacles. I affirm that not only can the Nautilus disengage itself, but also that it can go further still." - -"Further to the South?" I asked, looking at the Captain. - -"Yes, sir; it shall go to the pole." - -"To the pole!" I exclaimed, unable to repress a gesture of incredulity. - -"Yes," replied the Captain, coldly, "to the Antarctic pole—to that unknown point from whence springs every meridian of the globe. You know whether I can do as I please with the Nautilus!" - -Yes, I knew that. I knew that this man was bold, even to rashness. But to conquer those obstacles which bristled round the South Pole, rendering it more inaccessible than the North, which had not yet been reached by the boldest navigators—was it not a mad enterprise, one which only a maniac would have conceived? It then came into my head to ask Captain Nemo if he had ever discovered that pole which had never yet been trodden by a human creature? - -"No, sir," he replied; "but we will discover it together. Where others have failed, I will not fail. I have never yet led my Nautilus so far into southern seas; but, I repeat, it shall go further yet." - -"I can well believe you, Captain," said I, in a slightly ironical tone. "I believe you! Let us go ahead! There are no obstacles for us! Let us smash this iceberg! Let us blow it up; and, if it resists, let us give the Nautilus wings to fly over it!" - -"Over it, sir!" said Captain Nemo, quietly; "no, not over it, but under it!" - -"Under it!" I exclaimed, a sudden idea of the Captain's projects flashing upon my mind. I understood; the wonderful qualities of the Nautilus were going to serve us in this superhuman enterprise. - -"I see we are beginning to understand one another, sir," said the Captain, half smiling. "You begin to see the possibility—I should say the success—of this attempt. That which is impossible for an ordinary vessel is easy to the Nautilus. If a continent lies before the pole, it must stop before the continent; but if, on the contrary, the pole is washed by open sea, it will go even to the pole." - -"Certainly," said I, carried away by the Captain's reasoning; "if the surface of the sea is solidified by the ice, the lower depths are free by the Providential law which has placed the maximum of density of the waters of the ocean one degree higher than freezing-point; and, if I am not mistaken, the portion of this iceberg which is above the water is as one to four to that which is below." - -"Very nearly, sir; for one foot of iceberg above the sea there are three below it. If these ice mountains are not more than 300 feet above the surface, they are not more than 900 beneath. And what are 900 feet to the Nautilus?" - -"Nothing, sir." - -"It could even seek at greater depths that uniform temperature of sea-water, and there brave with impunity the thirty or forty degrees of surface cold." - -"Just so, sir—just so," I replied, getting animated. - -"The only difficulty," continued Captain Nemo, "is that of remaining several days without renewing our provision of air." - -"Is that all? The Nautilus has vast reservoirs; we can fill them, and they will supply us with all the oxygen we want." - -"Well thought of, M. Aronnax," replied the Captain, smiling. "But, not wishing you to accuse me of rashness, I will first give you all my objections." - -"Have you any more to make?" - -"Only one. It is possible, if the sea exists at the South Pole, that it may be covered; and, consequently, we shall be unable to come to the surface." - -"Good, sir! but do you forget that the Nautilus is armed with a powerful spur, and could we not send it diagonally against these fields of ice, which would open at the shocks." - -"Ah! sir, you are full of ideas to-day." - -"Besides, Captain," I added, enthusiastically, "why should we not find the sea open at the South Pole as well as at the North? The frozen poles of the earth do not coincide, either in the southern or in the northern regions; and, until it is proved to the contrary, we may suppose either a continent or an ocean free from ice at these two points of the globe." - -"I think so too, M. Aronnax," replied Captain Nemo. "I only wish you to observe that, after having made so many objections to my project, you are now crushing me with arguments in its favour!" - -The preparations for this audacious attempt now began. The powerful pumps of the Nautilus were working air into the reservoirs and storing it at high pressure. About four o'clock, Captain Nemo announced the closing of the panels on the platform. I threw one last look at the massive iceberg which we were going to cross. The weather was clear, the atmosphere pure enough, the cold very great, being 12° below zero; but, the wind having gone down, this temperature was not so unbearable. About ten men mounted the sides of the Nautilus, armed with pickaxes to break the ice around the vessel, which was soon free. The operation was quickly performed, for the fresh ice was still very thin. We all went below. The usual reservoirs were filled with the newly-liberated water, and the Nautilus soon descended. I had taken my place with Conseil in the saloon; through the open window we could see the lower beds of the Southern Ocean. The thermometer went up, the needle of the compass deviated on the dial. At about 900 feet, as Captain Nemo had foreseen, we were floating beneath the undulating bottom of the iceberg. But the Nautilus went lower still—it went to the depth of four hundred fathoms. The temperature of the water at the surface showed twelve degrees, it was now only ten; we had gained two. I need not say the temperature of the Nautilus was raised by its heating apparatus to a much higher degree; every manoeuvre was accomplished with wonderful precision. - -"We shall pass it, if you please, sir," said Conseil. - -"I believe we shall," I said, in a tone of firm conviction. - -In this open sea, the Nautilus had taken its course direct to the pole, without leaving the fifty-second meridian. From 67° 30' to 90 deg., twenty-two degrees and a half of latitude remained to travel; that is, about five hundred leagues. The Nautilus kept up a mean speed of twenty-six miles an hour—the speed of an express train. If that was kept up, in forty hours we should reach the pole. - -For a part of the night the novelty of the situation kept us at the window. The sea was lit with the electric lantern; but it was deserted; fishes did not sojourn in these imprisoned waters; they only found there a passage to take them from the Antarctic Ocean to the open polar sea. Our pace was rapid; we could feel it by the quivering of the long steel body. About two in the morning I took some hours' repose, and Conseil did the same. In crossing the waist I did not meet Captain Nemo: I supposed him to be in the pilot's cage. The next morning, the 19th of March, I took my post once more in the saloon. The electric log told me that the speed of the Nautilus had been slackened. It was then going towards the surface; but prudently emptying its reservoirs very slowly. My heart beat fast. Were we going to emerge and regain the open polar atmosphere? No! A shock told me that the Nautilus had struck the bottom of the iceberg, still very thick, judging from the deadened sound. We had in deed "struck," to use a sea expression, but in an inverse sense, and at a thousand feet deep. This would give three thousand feet of ice above us; one thousand being above the water-mark. The iceberg was then higher than at its borders—not a very reassuring fact. Several times that day the Nautilus tried again, and every time it struck the wall which lay like a ceiling above it. Sometimes it met with but 900 yards, only 200 of which rose above the surface. It was twice the height it was when the Nautilus had gone under the waves. I carefully noted the different depths, and thus obtained a submarine profile of the chain as it was developed under the water. That night no change had taken place in our situation. Still ice between four and five hundred yards in depth! It was evidently diminishing, but, still, what a thickness between us and the surface of the ocean! It was then eight. According to the daily custom on board the Nautilus, its air should have been renewed four hours ago; but I did not suffer much, although Captain Nemo had not yet made any demand upon his reserve of oxygen. My sleep was painful that night; hope and fear besieged me by turns: I rose several times. The groping of the Nautilus continued. About three in the morning, I noticed that the lower surface of the iceberg was only about fifty feet deep. One hundred and fifty feet now separated us from the surface of the waters. The iceberg was by degrees becoming an ice-field, the mountain a plain. My eyes never left the manometer. We were still rising diagonally to the surface, which sparkled under the electric rays. The iceberg was stretching both above and beneath into lengthening slopes; mile after mile it was getting thinner. At length, at six in the morning of that memorable day, the 19th of March, the door of the saloon opened, and Captain Nemo appeared. - -"The sea is open!!" was all he said. - - - - -CHAPTER XIV - -THE SOUTH POLE - -I rushed on to the platform. Yes! the open sea, with but a few scattered pieces of ice and moving icebergs—a long stretch of sea; a world of birds in the air, and myriads of fishes under those waters, which varied from intense blue to olive green, according to the bottom. The thermometer marked 3° C. above zero. It was comparatively spring, shut up as we were behind this iceberg, whose lengthened mass was dimly seen on our northern horizon. - -"Are we at the pole?" I asked the Captain, with a beating heart. - -"I do not know," he replied. "At noon I will take our bearings." - -"But will the sun show himself through this fog?" said I, looking at the leaden sky. - -"However little it shows, it will be enough," replied the Captain. - -About ten miles south a solitary island rose to a height of one hundred and four yards. We made for it, but carefully, for the sea might be strewn with banks. One hour afterwards we had reached it, two hours later we had made the round of it. It measured four or five miles in circumference. A narrow canal separated it from a considerable stretch of land, perhaps a continent, for we could not see its limits. The existence of this land seemed to give some colour to Maury's theory. The ingenious American has remarked that, between the South Pole and the sixtieth parallel, the sea is covered with floating ice of enormous size, which is never met with in the North Atlantic. From this fact he has drawn the conclusion that the Antarctic Circle encloses considerable continents, as icebergs cannot form in open sea, but only on the coasts. According to these calculations, the mass of ice surrounding the southern pole forms a vast cap, the circumference of which must be, at least, 2,500 miles. But the Nautilus, for fear of running aground, had stopped about three cable-lengths from a strand over which reared a superb heap of rocks. The boat was launched; the Captain, two of his men, bearing instruments, Conseil, and myself were in it. It was ten in the morning. I had not seen Ned Land. Doubtless the Canadian did not wish to admit the presence of the South Pole. A few strokes of the oar brought us to the sand, where we ran ashore. Conseil was going to jump on to the land, when I held him back. - -"Sir," said I to Captain Nemo, "to you belongs the honour of first setting foot on this land." - -"Yes, sir," said the Captain, "and if I do not hesitate to tread this South Pole, it is because, up to this time, no human being has left a trace there." - -Saying this, he jumped lightly on to the sand. His heart beat with emotion. He climbed a rock, sloping to a little promontory, and there, with his arms crossed, mute and motionless, and with an eager look, he seemed to take possession of these southern regions. After five minutes passed in this ecstasy, he turned to us. - -"When you like, sir." - -I landed, followed by Conseil, leaving the two men in the boat. For a long way the soil was composed of a reddish sandy stone, something like crushed brick, scoriae, streams of lava, and pumice-stones. One could not mistake its volcanic origin. In some parts, slight curls of smoke emitted a sulphurous smell, proving that the internal fires had lost nothing of their expansive powers, though, having climbed a high acclivity, I could see no volcano for a radius of several miles. We know that in those Antarctic countries, James Ross found two craters, the Erebus and Terror, in full activity, on the 167th meridian, latitude 77° 32'. The vegetation of this desolate continent seemed to me much restricted. Some lichens lay upon the black rocks; some microscopic plants, rudimentary diatomas, a kind of cells placed between two quartz shells; long purple and scarlet weed, supported on little swimming bladders, which the breaking of the waves brought to the shore. These constituted the meagre flora of this region. The shore was strewn with molluscs, little mussels, and limpets. I also saw myriads of northern clios, one-and-a-quarter inches long, of which a whale would swallow a whole world at a mouthful; and some perfect sea-butterflies, animating the waters on the skirts of the shore. - -There appeared on the high bottoms some coral shrubs, of the kind which, according to James Ross, live in the Antarctic seas to the depth of more than 1,000 yards. Then there were little kingfishers and starfish studding the soil. But where life abounded most was in the air. There thousands of birds fluttered and flew of all kinds, deafening us with their cries; others crowded the rock, looking at us as we passed by without fear, and pressing familiarly close by our feet. There were penguins, so agile in the water, heavy and awkward as they are on the ground; they were uttering harsh cries, a large assembly, sober in gesture, but extravagant in clamour. Albatrosses passed in the air, the expanse of their wings being at least four yards and a half, and justly called the vultures of the ocean; some gigantic petrels, and some damiers, a kind of small duck, the underpart of whose body is black and white; then there were a whole series of petrels, some whitish, with brown-bordered wings, others blue, peculiar to the Antarctic seas, and so oily, as I told Conseil, that the inhabitants of the Ferroe Islands had nothing to do before lighting them but to put a wick in. - -"A little more," said Conseil, "and they would be perfect lamps! After that, we cannot expect Nature to have previously furnished them with wicks!" - -About half a mile farther on the soil was riddled with ruffs' nests, a sort of laying-ground, out of which many birds were issuing. Captain Nemo had some hundreds hunted. They uttered a cry like the braying of an ass, were about the size of a goose, slate-colour on the body, white beneath, with a yellow line round their throats; they allowed themselves to be killed with a stone, never trying to escape. But the fog did not lift, and at eleven the sun had not yet shown itself. Its absence made me uneasy. Without it no observations were possible. How, then, could we decide whether we had reached the pole? When I rejoined Captain Nemo, I found him leaning on a piece of rock, silently watching the sky. He seemed impatient and vexed. But what was to be done? This rash and powerful man could not command the sun as he did the sea. Noon arrived without the orb of day showing itself for an instant. We could not even tell its position behind the curtain of fog; and soon the fog turned to snow. - -"Till to-morrow," said the Captain, quietly, and we returned to the Nautilus amid these atmospheric disturbances. - -The tempest of snow continued till the next day. It was impossible to remain on the platform. From the saloon, where I was taking notes of incidents happening during this excursion to the polar continent, I could hear the cries of petrels and albatrosses sporting in the midst of this violent storm. The Nautilus did not remain motionless, but skirted the coast, advancing ten miles more to the south in the half-light left by the sun as it skirted the edge of the horizon. The next day, the 20th of March, the snow had ceased. The cold was a little greater, the thermometer showing 2° below zero. The fog was rising, and I hoped that that day our observations might be taken. Captain Nemo not having yet appeared, the boat took Conseil and myself to land. The soil was still of the same volcanic nature; everywhere were traces of lava, scoriae, and basalt; but the crater which had vomited them I could not see. Here, as lower down, this continent was alive with myriads of birds. But their rule was now divided with large troops of sea-mammals, looking at us with their soft eyes. There were several kinds of seals, some stretched on the earth, some on flakes of ice, many going in and out of the sea. They did not flee at our approach, never having had anything to do with man; and I reckoned that there were provisions there for hundreds of vessels. - -"Sir," said Conseil, "will you tell me the names of these creatures?" - -"They are seals and morses." - -It was now eight in the morning. Four hours remained to us before the sun could be observed with advantage. I directed our steps towards a vast bay cut in the steep granite shore. There, I can aver that earth and ice were lost to sight by the numbers of sea-mammals covering them, and I involuntarily sought for old Proteus, the mythological shepherd who watched these immense flocks of Neptune. There were more seals than anything else, forming distinct groups, male and female, the father watching over his family, the mother suckling her little ones, some already strong enough to go a few steps. When they wished to change their place, they took little jumps, made by the contraction of their bodies, and helped awkwardly enough by their imperfect fin, which, as with the lamantin, their cousins, forms a perfect forearm. I should say that, in the water, which is their element—the spine of these creatures is flexible; with smooth and close skin and webbed feet—they swim admirably. In resting on the earth they take the most graceful attitudes. Thus the ancients, observing their soft and expressive looks, which cannot be surpassed by the most beautiful look a woman can give, their clear voluptuous eyes, their charming positions, and the poetry of their manners, metamorphosed them, the male into a triton and the female into a mermaid. I made Conseil notice the considerable development of the lobes of the brain in these interesting cetaceans. No mammal, except man, has such a quantity of brain matter; they are also capable of receiving a certain amount of education, are easily domesticated, and I think, with other naturalists, that if properly taught they would be of great service as fishing-dogs. The greater part of them slept on the rocks or on the sand. Amongst these seals, properly so called, which have no external ears (in which they differ from the otter, whose ears are prominent), I noticed several varieties of seals about three yards long, with a white coat, bulldog heads, armed with teeth in both jaws, four incisors at the top and four at the bottom, and two large canine teeth in the shape of a fleur-de-lis. Amongst them glided sea-elephants, a kind of seal, with short, flexible trunks. The giants of this species measured twenty feet round and ten yards and a half in length; but they did not move as we approached. - -"These creatures are not dangerous?" asked Conseil. - -"No; not unless you attack them. When they have to defend their young their rage is terrible, and it is not uncommon for them to break the fishing-boats to pieces." - -"They are quite right," said Conseil. - -"I do not say they are not." - -Two miles farther on we were stopped by the promontory which shelters the bay from the southerly winds. Beyond it we heard loud bellowings such as a troop of ruminants would produce. - -"Good!" said Conseil; "a concert of bulls!" - -"No; a concert of morses." - -"They are fighting!" - -"They are either fighting or playing." - -We now began to climb the blackish rocks, amid unforeseen stumbles, and over stones which the ice made slippery. More than once I rolled over at the expense of my loins. Conseil, more prudent or more steady, did not stumble, and helped me up, saying: - -"If, sir, you would have the kindness to take wider steps, you would preserve your equilibrium better." - -Arrived at the upper ridge of the promontory, I saw a vast white plain covered with morses. They were playing amongst themselves, and what we heard were bellowings of pleasure, not of anger. - -As I passed these curious animals I could examine them leisurely, for they did not move. Their skins were thick and rugged, of a yellowish tint, approaching to red; their hair was short and scant. Some of them were four yards and a quarter long. Quieter and less timid than their cousins of the north, they did not, like them, place sentinels round the outskirts of their encampment. After examining this city of morses, I began to think of returning. It was eleven o'clock, and, if Captain Nemo found the conditions favourable for observations, I wished to be present at the operation. We followed a narrow pathway running along the summit of the steep shore. At half-past eleven we had reached the place where we landed. The boat had run aground, bringing the Captain. I saw him standing on a block of basalt, his instruments near him, his eyes fixed on the northern horizon, near which the sun was then describing a lengthened curve. I took my place beside him, and waited without speaking. Noon arrived, and, as before, the sun did not appear. It was a fatality. Observations were still wanting. If not accomplished to-morrow, we must give up all idea of taking any. We were indeed exactly at the 20th of March. To-morrow, the 21st, would be the equinox; the sun would disappear behind the horizon for six months, and with its disappearance the long polar night would begin. Since the September equinox it had emerged from the northern horizon, rising by lengthened spirals up to the 21st of December. At this period, the summer solstice of the northern regions, it had begun to descend; and to-morrow was to shed its last rays upon them. I communicated my fears and observations to Captain Nemo. - -"You are right, M. Aronnax," said he; "if to-morrow I cannot take the altitude of the sun, I shall not be able to do it for six months. But precisely because chance has led me into these seas on the 21st of March, my bearings will be easy to take, if at twelve we can see the sun." - -"Why, Captain?" - -"Because then the orb of day described such lengthened curves that it is difficult to measure exactly its height above the horizon, and grave errors may be made with instruments." - -"What will you do then?" - -"I shall only use my chronometer," replied Captain Nemo. "If to-morrow, the 21st of March, the disc of the sun, allowing for refraction, is exactly cut by the northern horizon, it will show that I am at the South Pole." - -"Just so," said I. "But this statement is not mathematically correct, because the equinox does not necessarily begin at noon." - -"Very likely, sir; but the error will not be a hundred yards and we do not want more. Till to-morrow, then!" - -Captain Nemo returned on board. Conseil and I remained to survey the shore, observing and studying until five o'clock. Then I went to bed, not, however, without invoking, like the Indian, the favour of the radiant orb. The next day, the 21st of March, at five in the morning, I mounted the platform. I found Captain Nemo there. - -"The weather is lightening a little," said he. "I have some hope. After breakfast we will go on shore and choose a post for observation." - -That point settled, I sought Ned Land. I wanted to take him with me. But the obstinate Canadian refused, and I saw that his taciturnity and his bad humour grew day by day. After all, I was not sorry for his obstinacy under the circumstances. Indeed, there were too many seals on shore, and we ought not to lay such temptation in this unreflecting fisherman's way. Breakfast over, we went on shore. The Nautilus had gone some miles further up in the night. It was a whole league from the coast, above which reared a sharp peak about five hundred yards high. The boat took with me Captain Nemo, two men of the crew, and the instruments, which consisted of a chronometer, a telescope, and a barometer. While crossing, I saw numerous whales belonging to the three kinds peculiar to the southern seas; the whale, or the English "right whale," which has no dorsal fin; the "humpback," with reeved chest and large, whitish fins, which, in spite of its name, do not form wings; and the fin-back, of a yellowish brown, the liveliest of all the cetacea. This powerful creature is heard a long way off when he throws to a great height columns of air and vapour, which look like whirlwinds of smoke. These different mammals were disporting themselves in troops in the quiet waters; and I could see that this basin of the Antarctic Pole serves as a place of refuge to the cetacea too closely tracked by the hunters. I also noticed large medusae floating between the reeds. - -At nine we landed; the sky was brightening, the clouds were flying to the south, and the fog seemed to be leaving the cold surface of the waters. Captain Nemo went towards the peak, which he doubtless meant to be his observatory. It was a painful ascent over the sharp lava and the pumice-stones, in an atmosphere often impregnated with a sulphurous smell from the smoking cracks. For a man unaccustomed to walk on land, the Captain climbed the steep slopes with an agility I never saw equalled and which a hunter would have envied. We were two hours getting to the summit of this peak, which was half porphyry and half basalt. From thence we looked upon a vast sea which, towards the north, distinctly traced its boundary line upon the sky. At our feet lay fields of dazzling whiteness. Over our heads a pale azure, free from fog. To the north the disc of the sun seemed like a ball of fire, already horned by the cutting of the horizon. From the bosom of the water rose sheaves of liquid jets by hundreds. In the distance lay the Nautilus like a cetacean asleep on the water. Behind us, to the south and east, an immense country and a chaotic heap of rocks and ice, the limits of which were not visible. On arriving at the summit Captain Nemo carefully took the mean height of the barometer, for he would have to consider that in taking his observations. At a quarter to twelve the sun, then seen only by refraction, looked like a golden disc shedding its last rays upon this deserted continent and seas which never man had yet ploughed. Captain Nemo, furnished with a lenticular glass which, by means of a mirror, corrected the refraction, watched the orb sinking below the horizon by degrees, following a lengthened diagonal. I held the chronometer. My heart beat fast. If the disappearance of the half-disc of the sun coincided with twelve o'clock on the chronometer, we were at the pole itself. - -"Twelve!" I exclaimed. - -"The South Pole!" replied Captain Nemo, in a grave voice, handing me the glass, which showed the orb cut in exactly equal parts by the horizon. - -I looked at the last rays crowning the peak, and the shadows mounting by degrees up its slopes. At that moment Captain Nemo, resting with his hand on my shoulder, said: - -"I, Captain Nemo, on this 21st day of March, 1868, have reached the South Pole on the ninetieth degree; and I take possession of this part of the globe, equal to one-sixth of the known continents." - -"In whose name, Captain?" - -"In my own, sir!" - -Saying which, Captain Nemo unfurled a black banner, bearing an "N" in gold quartered on its bunting. Then, turning towards the orb of day, whose last rays lapped the horizon of the sea, he exclaimed: - -"Adieu, sun! Disappear, thou radiant orb! rest beneath this open sea, and let a night of six months spread its shadows over my new domains!" - - - - -CHAPTER XV - -ACCIDENT OR INCIDENT? - -The next day, the 22nd of March, at six in the morning, preparations for departure were begun. The last gleams of twilight were melting into night. The cold was great, the constellations shone with wonderful intensity. In the zenith glittered that wondrous Southern Cross—the polar bear of Antarctic regions. The thermometer showed 120 below zero, and when the wind freshened it was most biting. Flakes of ice increased on the open water. The sea seemed everywhere alike. Numerous blackish patches spread on the surface, showing the formation of fresh ice. Evidently the southern basin, frozen during the six winter months, was absolutely inaccessible. What became of the whales in that time? Doubtless they went beneath the icebergs, seeking more practicable seas. As to the seals and morses, accustomed to live in a hard climate, they remained on these icy shores. These creatures have the instinct to break holes in the ice-field and to keep them open. To these holes they come for breath; when the birds, driven away by the cold, have emigrated to the north, these sea mammals remain sole masters of the polar continent. But the reservoirs were filling with water, and the Nautilus was slowly descending. At 1,000 feet deep it stopped; its screw beat the waves, and it advanced straight towards the north at a speed of fifteen miles an hour. Towards night it was already floating under the immense body of the iceberg. At three in the morning I was awakened by a violent shock. I sat up in my bed and listened in the darkness, when I was thrown into the middle of the room. The Nautilus, after having struck, had rebounded violently. I groped along the partition, and by the staircase to the saloon, which was lit by the luminous ceiling. The furniture was upset. Fortunately the windows were firmly set, and had held fast. The pictures on the starboard side, from being no longer vertical, were clinging to the paper, whilst those of the port side were hanging at least a foot from the wall. The Nautilus was lying on its starboard side perfectly motionless. I heard footsteps, and a confusion of voices; but Captain Nemo did not appear. As I was leaving the saloon, Ned Land and Conseil entered. - -"What is the matter?" said I, at once. - -"I came to ask you, sir," replied Conseil. - -"Confound it!" exclaimed the Canadian, "I know well enough! The Nautilus has struck; and, judging by the way she lies, I do not think she will right herself as she did the first time in Torres Straits." - -"But," I asked, "has she at least come to the surface of the sea?" - -"We do not know," said Conseil. - -"It is easy to decide," I answered. I consulted the manometer. To my great surprise, it showed a depth of more than 180 fathoms. "What does that mean?" I exclaimed. - -"We must ask Captain Nemo," said Conseil. - -"But where shall we find him?" said Ned Land. - -"Follow me," said I, to my companions. - -We left the saloon. There was no one in the library. At the centre staircase, by the berths of the ship's crew, there was no one. I thought that Captain Nemo must be in the pilot's cage. It was best to wait. We all returned to the saloon. For twenty minutes we remained thus, trying to hear the slightest noise which might be made on board the Nautilus, when Captain Nemo entered. He seemed not to see us; his face, generally so impassive, showed signs of uneasiness. He watched the compass silently, then the manometer; and, going to the planisphere, placed his finger on a spot representing the southern seas. I would not interrupt him; but, some minutes later, when he turned towards me, I said, using one of his own expressions in the Torres Straits: - -"An incident, Captain?" - -"No, sir; an accident this time." - -"Serious?" - -"Perhaps." - -"Is the danger immediate?" - -"No." - -"The Nautilus has stranded?" - -"Yes." - -"And this has happened—how?" - -"From a caprice of nature, not from the ignorance of man. Not a mistake has been made in the working. But we cannot prevent equilibrium from producing its effects. We may brave human laws, but we cannot resist natural ones." - -Captain Nemo had chosen a strange moment for uttering this philosophical reflection. On the whole, his answer helped me little. - -"May I ask, sir, the cause of this accident?" - -"An enormous block of ice, a whole mountain, has turned over," he replied. "When icebergs are undermined at their base by warmer water or reiterated shocks their centre of gravity rises, and the whole thing turns over. This is what has happened; one of these blocks, as it fell, struck the Nautilus, then, gliding under its hull, raised it with irresistible force, bringing it into beds which are not so thick, where it is lying on its side." - -"But can we not get the Nautilus off by emptying its reservoirs, that it might regain its equilibrium?" - -"That, sir, is being done at this moment. You can hear the pump working. Look at the needle of the manometer; it shows that the Nautilus is rising, but the block of ice is floating with it; and, until some obstacle stops its ascending motion, our position cannot be altered." - -Indeed, the Nautilus still held the same position to starboard; doubtless it would right itself when the block stopped. But at this moment who knows if we may not be frightfully crushed between the two glassy surfaces? I reflected on all the consequences of our position. Captain Nemo never took his eyes off the manometer. Since the fall of the iceberg, the Nautilus had risen about a hundred and fifty feet, but it still made the same angle with the perpendicular. Suddenly a slight movement was felt in the hold. Evidently it was righting a little. Things hanging in the saloon were sensibly returning to their normal position. The partitions were nearing the upright. No one spoke. With beating hearts we watched and felt the straightening. The boards became horizontal under our feet. Ten minutes passed. - -"At last we have righted!" I exclaimed. - -"Yes," said Captain Nemo, going to the door of the saloon. - -"But are we floating?" I asked. - -"Certainly," he replied; "since the reservoirs are not empty; and, when empty, the Nautilus must rise to the surface of the sea." - -We were in open sea; but at a distance of about ten yards, on either side of the Nautilus, rose a dazzling wall of ice. Above and beneath the same wall. Above, because the lower surface of the iceberg stretched over us like an immense ceiling. Beneath, because the overturned block, having slid by degrees, had found a resting-place on the lateral walls, which kept it in that position. The Nautilus was really imprisoned in a perfect tunnel of ice more than twenty yards in breadth, filled with quiet water. It was easy to get out of it by going either forward or backward, and then make a free passage under the iceberg, some hundreds of yards deeper. The luminous ceiling had been extinguished, but the saloon was still resplendent with intense light. It was the powerful reflection from the glass partition sent violently back to the sheets of the lantern. I cannot describe the effect of the voltaic rays upon the great blocks so capriciously cut; upon every angle, every ridge, every facet was thrown a different light, according to the nature of the veins running through the ice; a dazzling mine of gems, particularly of sapphires, their blue rays crossing with the green of the emerald. Here and there were opal shades of wonderful softness, running through bright spots like diamonds of fire, the brilliancy of which the eye could not bear. The power of the lantern seemed increased a hundredfold, like a lamp through the lenticular plates of a first-class lighthouse. - -"How beautiful! how beautiful!" cried Conseil. - -"Yes," I said, "it is a wonderful sight. Is it not, Ned?" - -"Yes, confound it! Yes," answered Ned Land, "it is superb! I am mad at being obliged to admit it. No one has ever seen anything like it; but the sight may cost us dear. And, if I must say all, I think we are seeing here things which God never intended man to see." - -Ned was right, it was too beautiful. Suddenly a cry from Conseil made me turn. - -"What is it?" I asked. - -"Shut your eyes, sir! Do not look, sir!" Saying which, Conseil clapped his hands over his eyes. - -"But what is the matter, my boy?" - -"I am dazzled, blinded." - -My eyes turned involuntarily towards the glass, but I could not stand the fire which seemed to devour them. I understood what had happened. The Nautilus had put on full speed. All the quiet lustre of the ice-walls was at once changed into flashes of lightning. The fire from these myriads of diamonds was blinding. It required some time to calm our troubled looks. At last the hands were taken down. - -"Faith, I should never have believed it," said Conseil. - -It was then five in the morning; and at that moment a shock was felt at the bows of the Nautilus. I knew that its spur had struck a block of ice. It must have been a false manoeuvre, for this submarine tunnel, obstructed by blocks, was not very easy navigation. I thought that Captain Nemo, by changing his course, would either turn these obstacles or else follow the windings of the tunnel. In any case, the road before us could not be entirely blocked. But, contrary to my expectations, the Nautilus took a decided retrograde motion. - -"We are going backwards?" said Conseil. - -"Yes," I replied. "This end of the tunnel can have no egress." - -"And then?" - -"Then," said I, "the working is easy. We must go back again, and go out at the southern opening. That is all." - -In speaking thus, I wished to appear more confident than I really was. But the retrograde motion of the Nautilus was increasing; and, reversing the screw, it carried us at great speed. - -"It will be a hindrance," said Ned. - -"What does it matter, some hours more or less, provided we get out at last?" - -"Yes," repeated Ned Land, "provided we do get out at last!" - -For a short time I walked from the saloon to the library. My companions were silent. I soon threw myself on an ottoman, and took a book, which my eyes overran mechanically. A quarter of an hour after, Conseil, approaching me, said, "Is what you are reading very interesting, sir?" - -"Very interesting!" I replied. - -"I should think so, sir. It is your own book you are reading." - -"My book?" - -And indeed I was holding in my hand the work on the Great Submarine Depths. I did not even dream of it. I closed the book and returned to my walk. Ned and Conseil rose to go. - -"Stay here, my friends," said I, detaining them. "Let us remain together until we are out of this block." - -"As you please, sir," Conseil replied. - -Some hours passed. I often looked at the instruments hanging from the partition. The manometer showed that the Nautilus kept at a constant depth of more than three hundred yards; the compass still pointed to south; the log indicated a speed of twenty miles an hour, which, in such a cramped space, was very great. But Captain Nemo knew that he could not hasten too much, and that minutes were worth ages to us. At twenty-five minutes past eight a second shock took place, this time from behind. I turned pale. My companions were close by my side. I seized Conseil's hand. Our looks expressed our feelings better than words. At this moment the Captain entered the saloon. I went up to him. - -"Our course is barred southward?" I asked. - -"Yes, sir. The iceberg has shifted and closed every outlet." - -"We are blocked up then?" - -"Yes." - - - - -CHAPTER XVI - -WANT OF AIR - -Thus around the Nautilus, above and below, was an impenetrable wall of ice. We were prisoners to the iceberg. I watched the Captain. His countenance had resumed its habitual imperturbability. - -"Gentlemen," he said calmly, "there are two ways of dying in the circumstances in which we are placed." (This puzzling person had the air of a mathematical professor lecturing to his pupils.) "The first is to be crushed; the second is to die of suffocation. I do not speak of the possibility of dying of hunger, for the supply of provisions in the Nautilus will certainly last longer than we shall. Let us, then, calculate our chances." - -"As to suffocation, Captain," I replied, "that is not to be feared, because our reservoirs are full." - -"Just so; but they will only yield two days' supply of air. Now, for thirty-six hours we have been hidden under the water, and already the heavy atmosphere of the Nautilus requires renewal. In forty-eight hours our reserve will be exhausted." - -"Well, Captain, can we be delivered before forty-eight hours?" - -"We will attempt it, at least, by piercing the wall that surrounds us." - -"On which side?" - -"Sound will tell us. I am going to run the Nautilus aground on the lower bank, and my men will attack the iceberg on the side that is least thick." - -Captain Nemo went out. Soon I discovered by a hissing noise that the water was entering the reservoirs. The Nautilus sank slowly, and rested on the ice at a depth of 350 yards, the depth at which the lower bank was immersed. - -"My friends," I said, "our situation is serious, but I rely on your courage and energy." - -"Sir," replied the Canadian, "I am ready to do anything for the general safety." - -"Good! Ned," and I held out my hand to the Canadian. - -"I will add," he continued, "that, being as handy with the pickaxe as with the harpoon, if I can be useful to the Captain, he can command my services." - -"He will not refuse your help. Come, Ned!" - -I led him to the room where the crew of the Nautilus were putting on their cork-jackets. I told the Captain of Ned's proposal, which he accepted. The Canadian put on his sea-costume, and was ready as soon as his companions. When Ned was dressed, I re-entered the drawing-room, where the panes of glass were open, and, posted near Conseil, I examined the ambient beds that supported the Nautilus. Some instants after, we saw a dozen of the crew set foot on the bank of ice, and among them Ned Land, easily known by his stature. Captain Nemo was with them. Before proceeding to dig the walls, he took the soundings, to be sure of working in the right direction. Long sounding lines were sunk in the side walls, but after fifteen yards they were again stopped by the thick wall. It was useless to attack it on the ceiling-like surface, since the iceberg itself measured more than 400 yards in height. Captain Nemo then sounded the lower surface. There ten yards of wall separated us from the water, so great was the thickness of the ice-field. It was necessary, therefore, to cut from it a piece equal in extent to the waterline of the Nautilus. There were about 6,000 cubic yards to detach, so as to dig a hole by which we could descend to the ice-field. The work had begun immediately and carried on with indefatigable energy. Instead of digging round the Nautilus which would have involved greater difficulty, Captain Nemo had an immense trench made at eight yards from the port-quarter. Then the men set to work simultaneously with their screws on several points of its circumference. Presently the pickaxe attacked this compact matter vigorously, and large blocks were detached from the mass. By a curious effect of specific gravity, these blocks, lighter than water, fled, so to speak, to the vault of the tunnel, that increased in thickness at the top in proportion as it diminished at the base. But that mattered little, so long as the lower part grew thinner. After two hours' hard work, Ned Land came in exhausted. He and his comrades were replaced by new workers, whom Conseil and I joined. The second lieutenant of the Nautilus superintended us. The water seemed singularly cold, but I soon got warm handling the pickaxe. My movements were free enough, although they were made under a pressure of thirty atmospheres. When I re-entered, after working two hours, to take some food and rest, I found a perceptible difference between the pure fluid with which the Rouquayrol engine supplied me and the atmosphere of the Nautilus, already charged with carbonic acid. The air had not been renewed for forty-eight hours, and its vivifying qualities were considerably enfeebled. However, after a lapse of twelve hours, we had only raised a block of ice one yard thick, on the marked surface, which was about 600 cubic yards! Reckoning that it took twelve hours to accomplish this much it would take five nights and four days to bring this enterprise to a satisfactory conclusion. Five nights and four days! And we have only air enough for two days in the reservoirs! "Without taking into account," said Ned, "that, even if we get out of this infernal prison, we shall also be imprisoned under the iceberg, shut out from all possible communication with the atmosphere." True enough! Who could then foresee the minimum of time necessary for our deliverance? We might be suffocated before the Nautilus could regain the surface of the waves? Was it destined to perish in this ice-tomb, with all those it enclosed? The situation was terrible. But everyone had looked the danger in the face, and each was determined to do his duty to the last. - -As I expected, during the night a new block a yard square was carried away, and still further sank the immense hollow. But in the morning when, dressed in my cork-jacket, I traversed the slushy mass at a temperature of six or seven degrees below zero, I remarked that the side walls were gradually closing in. The beds of water farthest from the trench, that were not warmed by the men's work, showed a tendency to solidification. In presence of this new and imminent danger, what would become of our chances of safety, and how hinder the solidification of this liquid medium, that would burst the partitions of the Nautilus like glass? - -I did not tell my companions of this new danger. What was the good of damping the energy they displayed in the painful work of escape? But when I went on board again, I told Captain Nemo of this grave complication. - -"I know it," he said, in that calm tone which could counteract the most terrible apprehensions. "It is one danger more; but I see no way of escaping it; the only chance of safety is to go quicker than solidification. We must be beforehand with it, that is all." - -On this day for several hours I used my pickaxe vigorously. The work kept me up. Besides, to work was to quit the Nautilus, and breathe directly the pure air drawn from the reservoirs, and supplied by our apparatus, and to quit the impoverished and vitiated atmosphere. Towards evening the trench was dug one yard deeper. When I returned on board, I was nearly suffocated by the carbonic acid with which the air was filled—ah! if we had only the chemical means to drive away this deleterious gas. We had plenty of oxygen; all this water contained a considerable quantity, and by dissolving it with our powerful piles, it would restore the vivifying fluid. I had thought well over it; but of what good was that, since the carbonic acid produced by our respiration had invaded every part of the vessel? To absorb it, it was necessary to fill some jars with caustic potash, and to shake them incessantly. Now this substance was wanting on board, and nothing could replace it. On that evening, Captain Nemo ought to open the taps of his reservoirs, and let some pure air into the interior of the Nautilus; without this precaution we could not get rid of the sense of suffocation. The next day, March 26th, I resumed my miner's work in beginning the fifth yard. The side walls and the lower surface of the iceberg thickened visibly. It was evident that they would meet before the Nautilus was able to disengage itself. Despair seized me for an instant; my pickaxe nearly fell from my hands. What was the good of digging if I must be suffocated, crushed by the water that was turning into stone?—a punishment that the ferocity of the savages even would not have invented! Just then Captain Nemo passed near me. I touched his hand and showed him the walls of our prison. The wall to port had advanced to at least four yards from the hull of the Nautilus. The Captain understood me, and signed me to follow him. We went on board. I took off my cork-jacket and accompanied him into the drawing-room. - -"M. Aronnax, we must attempt some desperate means, or we shall be sealed up in this solidified water as in cement." - -"Yes; but what is to be done?" - -"Ah! if my Nautilus were strong enough to bear this pressure without being crushed!" - -"Well?" I asked, not catching the Captain's idea. - -"Do you not understand," he replied, "that this congelation of water will help us? Do you not see that by its solidification, it would burst through this field of ice that imprisons us, as, when it freezes, it bursts the hardest stones? Do you not perceive that it would be an agent of safety instead of destruction?" - -"Yes, Captain, perhaps. But, whatever resistance to crushing the Nautilus possesses, it could not support this terrible pressure, and would be flattened like an iron plate." - -"I know it, sir. Therefore we must not reckon on the aid of nature, but on our own exertions. We must stop this solidification. Not only will the side walls be pressed together; but there is not ten feet of water before or behind the Nautilus. The congelation gains on us on all sides." - -"How long will the air in the reservoirs last for us to breathe on board?" - -The Captain looked in my face. "After to-morrow they will be empty!" - -A cold sweat came over me. However, ought I to have been astonished at the answer? On March 22, the Nautilus was in the open polar seas. We were at 26°. For five days we had lived on the reserve on board. And what was left of the respirable air must be kept for the workers. Even now, as I write, my recollection is still so vivid that an involuntary terror seizes me and my lungs seem to be without air. Meanwhile, Captain Nemo reflected silently, and evidently an idea had struck him; but he seemed to reject it. At last, these words escaped his lips: - -"Boiling water!" he muttered. - -"Boiling water?" I cried. - -"Yes, sir. We are enclosed in a space that is relatively confined. Would not jets of boiling water, constantly injected by the pumps, raise the temperature in this part and stay the congelation?" - -"Let us try it," I said resolutely. - -"Let us try it, Professor." - -The thermometer then stood at 7° outside. Captain Nemo took me to the galleys, where the vast distillatory machines stood that furnished the drinkable water by evaporation. They filled these with water, and all the electric heat from the piles was thrown through the worms bathed in the liquid. In a few minutes this water reached 100°. It was directed towards the pumps, while fresh water replaced it in proportion. The heat developed by the troughs was such that cold water, drawn up from the sea after only having gone through the machines, came boiling into the body of the pump. The injection was begun, and three hours after the thermometer marked 6° below zero outside. One degree was gained. Two hours later the thermometer only marked 4°. - -"We shall succeed," I said to the Captain, after having anxiously watched the result of the operation. - -"I think," he answered, "that we shall not be crushed. We have no more suffocation to fear." - -During the night the temperature of the water rose to 1° below zero. The injections could not carry it to a higher point. But, as the congelation of the sea-water produces at least 2°, I was at least reassured against the dangers of solidification. - -The next day, March 27th, six yards of ice had been cleared, twelve feet only remaining to be cleared away. There was yet forty-eight hours' work. The air could not be renewed in the interior of the Nautilus. And this day would make it worse. An intolerable weight oppressed me. Towards three o'clock in the evening this feeling rose to a violent degree. Yawns dislocated my jaws. My lungs panted as they inhaled this burning fluid, which became rarefied more and more. A moral torpor took hold of me. I was powerless, almost unconscious. My brave Conseil, though exhibiting the same symptoms and suffering in the same manner, never left me. He took my hand and encouraged me, and I heard him murmur, "Oh! if I could only not breathe, so as to leave more air for my master!" - -Tears came into my eyes on hearing him speak thus. If our situation to all was intolerable in the interior, with what haste and gladness would we put on our cork-jackets to work in our turn! Pickaxes sounded on the frozen ice-beds. Our arms ached, the skin was torn off our hands. But what were these fatigues, what did the wounds matter? Vital air came to the lungs! We breathed! we breathed! - -All this time no one prolonged his voluntary task beyond the prescribed time. His task accomplished, each one handed in turn to his panting companions the apparatus that supplied him with life. Captain Nemo set the example, and submitted first to this severe discipline. When the time came, he gave up his apparatus to another and returned to the vitiated air on board, calm, unflinching, unmurmuring. - -On that day the ordinary work was accomplished with unusual vigour. Only two yards remained to be raised from the surface. Two yards only separated us from the open sea. But the reservoirs were nearly emptied of air. The little that remained ought to be kept for the workers; not a particle for the Nautilus. When I went back on board, I was half suffocated. What a night! I know not how to describe it. The next day my breathing was oppressed. Dizziness accompanied the pain in my head and made me like a drunken man. My companions showed the same symptoms. Some of the crew had rattling in the throat. - -On that day, the sixth of our imprisonment, Captain Nemo, finding the pickaxes work too slowly, resolved to crush the ice-bed that still separated us from the liquid sheet. This man's coolness and energy never forsook him. He subdued his physical pains by moral force. - -By his orders the vessel was lightened, that is to say, raised from the ice-bed by a change of specific gravity. When it floated they towed it so as to bring it above the immense trench made on the level of the water-line. Then, filling his reservoirs of water, he descended and shut himself up in the hole. - -Just then all the crew came on board, and the double door of communication was shut. The Nautilus then rested on the bed of ice, which was not one yard thick, and which the sounding leads had perforated in a thousand places. The taps of the reservoirs were then opened, and a hundred cubic yards of water was let in, increasing the weight of the Nautilus to 1,800 tons. We waited, we listened, forgetting our sufferings in hope. Our safety depended on this last chance. Notwithstanding the buzzing in my head, I soon heard the humming sound under the hull of the Nautilus. The ice cracked with a singular noise, like tearing paper, and the Nautilus sank. - -"We are off!" murmured Conseil in my ear. - -I could not answer him. I seized his hand, and pressed it convulsively. All at once, carried away by its frightful overcharge, the Nautilus sank like a bullet under the waters, that is to say, it fell as if it was in a vacuum. Then all the electric force was put on the pumps, that soon began to let the water out of the reservoirs. After some minutes, our fall was stopped. Soon, too, the manometer indicated an ascending movement. The screw, going at full speed, made the iron hull tremble to its very bolts and drew us towards the north. But if this floating under the iceberg is to last another day before we reach the open sea, I shall be dead first. - -Half stretched upon a divan in the library, I was suffocating. My face was purple, my lips blue, my faculties suspended. I neither saw nor heard. All notion of time had gone from my mind. My muscles could not contract. I do not know how many hours passed thus, but I was conscious of the agony that was coming over me. I felt as if I was going to die. Suddenly I came to. Some breaths of air penetrated my lungs. Had we risen to the surface of the waves? Were we free of the iceberg? No! Ned and Conseil, my two brave friends, were sacrificing themselves to save me. Some particles of air still remained at the bottom of one apparatus. Instead of using it, they had kept it for me, and, while they were being suffocated, they gave me life, drop by drop. I wanted to push back the thing; they held my hands, and for some moments I breathed freely. I looked at the clock; it was eleven in the morning. It ought to be the 28th of March. The Nautilus went at a frightful pace, forty miles an hour. It literally tore through the water. Where was Captain Nemo? Had he succumbed? Were his companions dead with him? At the moment the manometer indicated that we were not more than twenty feet from the surface. A mere plate of ice separated us from the atmosphere. Could we not break it? Perhaps. In any case the Nautilus was going to attempt it. I felt that it was in an oblique position, lowering the stern, and raising the bows. The introduction of water had been the means of disturbing its equilibrium. Then, impelled by its powerful screw, it attacked the ice-field from beneath like a formidable battering-ram. It broke it by backing and then rushing forward against the field, which gradually gave way; and at last, dashing suddenly against it, shot forwards on the ice-field, that crushed beneath its weight. The panel was opened—one might say torn off—and the pure air came in in abundance to all parts of the Nautilus. - - - - -CHAPTER XVII - -FROM CAPE HORN TO THE AMAZON - -How I got on to the platform, I have no idea; perhaps the Canadian had carried me there. But I breathed, I inhaled the vivifying sea-air. My two companions were getting drunk with the fresh particles. The other unhappy men had been so long without food, that they could not with impunity indulge in the simplest aliments that were given them. We, on the contrary, had no end to restrain ourselves; we could draw this air freely into our lungs, and it was the breeze, the breeze alone, that filled us with this keen enjoyment. - -"Ah!" said Conseil, "how delightful this oxygen is! Master need not fear to breathe it. There is enough for everybody." - -Ned Land did not speak, but he opened his jaws wide enough to frighten a shark. Our strength soon returned, and, when I looked round me, I saw we were alone on the platform. The foreign seamen in the Nautilus were contented with the air that circulated in the interior; none of them had come to drink in the open air. - -The first words I spoke were words of gratitude and thankfulness to my two companions. Ned and Conseil had prolonged my life during the last hours of this long agony. All my gratitude could not repay such devotion. - -"My friends," said I, "we are bound one to the other for ever, and I am under infinite obligations to you." - -"Which I shall take advantage of," exclaimed the Canadian. - -"What do you mean?" said Conseil. - -"I mean that I shall take you with me when I leave this infernal Nautilus." - -"Well," said Conseil, "after all this, are we going right?" - -"Yes," I replied, "for we are going the way of the sun, and here the sun is in the north." - -"No doubt," said Ned Land; "but it remains to be seen whether he will bring the ship into the Pacific or the Atlantic Ocean, that is, into frequented or deserted seas." - -I could not answer that question, and I feared that Captain Nemo would rather take us to the vast ocean that touches the coasts of Asia and America at the same time. He would thus complete the tour round the submarine world, and return to those waters in which the Nautilus could sail freely. We ought, before long, to settle this important point. The Nautilus went at a rapid pace. The polar circle was soon passed, and the course shaped for Cape Horn. We were off the American point, March 31st, at seven o'clock in the evening. Then all our past sufferings were forgotten. The remembrance of that imprisonment in the ice was effaced from our minds. We only thought of the future. Captain Nemo did not appear again either in the drawing-room or on the platform. The point shown each day on the planisphere, and, marked by the lieutenant, showed me the exact direction of the Nautilus. Now, on that evening, it was evident, to, my great satisfaction, that we were going back to the North by the Atlantic. The next day, April 1st, when the Nautilus ascended to the surface some minutes before noon, we sighted land to the west. It was Terra del Fuego, which the first navigators named thus from seeing the quantity of smoke that rose from the natives' huts. The coast seemed low to me, but in the distance rose high mountains. I even thought I had a glimpse of Mount Sarmiento, that rises 2,070 yards above the level of the sea, with a very pointed summit, which, according as it is misty or clear, is a sign of fine or of wet weather. At this moment the peak was clearly defined against the sky. The Nautilus, diving again under the water, approached the coast, which was only some few miles off. From the glass windows in the drawing-room, I saw long seaweeds and gigantic fuci and varech, of which the open polar sea contains so many specimens, with their sharp polished filaments; they measured about 300 yards in length—real cables, thicker than one's thumb; and, having great tenacity, they are often used as ropes for vessels. Another weed known as velp, with leaves four feet long, buried in the coral concretions, hung at the bottom. It served as nest and food for myriads of crustacea and molluscs, crabs, and cuttlefish. There seals and otters had splendid repasts, eating the flesh of fish with sea-vegetables, according to the English fashion. Over this fertile and luxuriant ground the Nautilus passed with great rapidity. Towards evening it approached the Falkland group, the rough summits of which I recognised the following day. The depth of the sea was moderate. On the shores our nets brought in beautiful specimens of sea weed, and particularly a certain fucus, the roots of which were filled with the best mussels in the world. Geese and ducks fell by dozens on the platform, and soon took their places in the pantry on board. - -When the last heights of the Falklands had disappeared from the horizon, the Nautilus sank to between twenty and twenty-five yards, and followed the American coast. Captain Nemo did not show himself. Until the 3rd of April we did not quit the shores of Patagonia, sometimes under the ocean, sometimes at the surface. The Nautilus passed beyond the large estuary formed by the Uraguay. Its direction was northwards, and followed the long windings of the coast of South America. We had then made 1,600 miles since our embarkation in the seas of Japan. About eleven o'clock in the morning the Tropic of Capricorn was crossed on the thirty-seventh meridian, and we passed Cape Frio standing out to sea. Captain Nemo, to Ned Land's great displeasure, did not like the neighbourhood of the inhabited coasts of Brazil, for we went at a giddy speed. Not a fish, not a bird of the swiftest kind could follow us, and the natural curiosities of these seas escaped all observation. - -This speed was kept up for several days, and in the evening of the 9th of April we sighted the most westerly point of South America that forms Cape San Roque. But then the Nautilus swerved again, and sought the lowest depth of a submarine valley which is between this Cape and Sierra Leone on the African coast. This valley bifurcates to the parallel of the Antilles, and terminates at the mouth by the enormous depression of 9,000 yards. In this place, the geological basin of the ocean forms, as far as the Lesser Antilles, a cliff to three and a half miles perpendicular in height, and, at the parallel of the Cape Verde Islands, an other wall not less considerable, that encloses thus all the sunk continent of the Atlantic. The bottom of this immense valley is dotted with some mountains, that give to these submarine places a picturesque aspect. I speak, moreover, from the manuscript charts that were in the library of the Nautilus—charts evidently due to Captain Nemo's hand, and made after his personal observations. For two days the desert and deep waters were visited by means of the inclined planes. The Nautilus was furnished with long diagonal broadsides which carried it to all elevations. But on the 11th of April it rose suddenly, and land appeared at the mouth of the Amazon River, a vast estuary, the embouchure of which is so considerable that it freshens the sea-water for the distance of several leagues. - -The equator was crossed. Twenty miles to the west were the Guianas, a French territory, on which we could have found an easy refuge; but a stiff breeze was blowing, and the furious waves would not have allowed a single boat to face them. Ned Land understood that, no doubt, for he spoke not a word about it. For my part, I made no allusion to his schemes of flight, for I would not urge him to make an attempt that must inevitably fail. I made the time pass pleasantly by interesting studies. During the days of April 11th and 12th, the Nautilus did not leave the surface of the sea, and the net brought in a marvellous haul of Zoophytes, fish and reptiles. Some zoophytes had been fished up by the chain of the nets; they were for the most part beautiful phyctallines, belonging to the actinidian family, and among other species the phyctalis protexta, peculiar to that part of the ocean, with a little cylindrical trunk, ornamented With vertical lines, speckled with red dots, crowning a marvellous blossoming of tentacles. As to the molluscs, they consisted of some I had already observed—turritellas, olive porphyras, with regular lines intercrossed, with red spots standing out plainly against the flesh; odd pteroceras, like petrified scorpions; translucid hyaleas, argonauts, cuttle-fish (excellent eating), and certain species of calmars that naturalists of antiquity have classed amongst the flying-fish, and that serve principally for bait for cod-fishing. I had now an opportunity of studying several species of fish on these shores. Amongst the cartilaginous ones, petromyzons-pricka, a sort of eel, fifteen inches long, with a greenish head, violet fins, grey-blue back, brown belly, silvered and sown with bright spots, the pupil of the eye encircled with gold—a curious animal, that the current of the Amazon had drawn to the sea, for they inhabit fresh waters—tuberculated streaks, with pointed snouts, and a long loose tail, armed with a long jagged sting; little sharks, a yard long, grey and whitish skin, and several rows of teeth, bent back, that are generally known by the name of pantouffles; vespertilios, a kind of red isosceles triangle, half a yard long, to which pectorals are attached by fleshy prolongations that make them look like bats, but that their horny appendage, situated near the nostrils, has given them the name of sea-unicorns; lastly, some species of balistae, the curassavian, whose spots were of a brilliant gold colour, and the capriscus of clear violet, and with varying shades like a pigeon's throat. - -I end here this catalogue, which is somewhat dry perhaps, but very exact, with a series of bony fish that I observed in passing belonging to the apteronotes, and whose snout is white as snow, the body of a beautiful black, marked with a very long loose fleshy strip; odontognathes, armed with spikes; sardines nine inches long, glittering with a bright silver light; a species of mackerel provided with two anal fins; centronotes of a blackish tint, that are fished for with torches, long fish, two yards in length, with fat flesh, white and firm, which, when they arc fresh, taste like eel, and when dry, like smoked salmon; labres, half red, covered with scales only at the bottom of the dorsal and anal fins; chrysoptera, on which gold and silver blend their brightness with that of the ruby and topaz; golden-tailed spares, the flesh of which is extremely delicate, and whose phosphorescent properties betray them in the midst of the waters; orange-coloured spares with long tongues; maigres, with gold caudal fins, dark thorn-tails, anableps of Surinam, etc. - -Notwithstanding this "et cetera," I must not omit to mention fish that Conseil will long remember, and with good reason. One of our nets had hauled up a sort of very flat ray fish, which, with the tail cut off, formed a perfect disc, and weighed twenty ounces. It was white underneath, red above, with large round spots of dark blue encircled with black, very glossy skin, terminating in a bilobed fin. Laid out on the platform, it struggled, tried to turn itself by convulsive movements, and made so many efforts, that one last turn had nearly sent it into the sea. But Conseil, not wishing to let the fish go, rushed to it, and, before I could prevent him, had seized it with both hands. In a moment he was overthrown, his legs in the air, and half his body paralysed, crying— - -"Oh! master, master! help me!" - -It was the first time the poor boy had spoken to me so familiarly. The Canadian and I took him up, and rubbed his contracted arms till he became sensible. The unfortunate Conseil had attacked a cramp-fish of the most dangerous kind, the cumana. This odd animal, in a medium conductor like water, strikes fish at several yards' distance, so great is the power of its electric organ, the two principal surfaces of which do not measure less than twenty-seven square feet. The next day, April 12th, the Nautilus approached the Dutch coast, near the mouth of the Maroni. There several groups of sea-cows herded together; they were manatees, that, like the dugong and the stellera, belong to the skenian order. These beautiful animals, peaceable and inoffensive, from eighteen to twenty-one feet in length, weigh at least sixteen hundredweight. I told Ned Land and Conseil that provident nature had assigned an important role to these mammalia. Indeed, they, like the seals, are designed to graze on the submarine prairies, and thus destroy the accumulation of weed that obstructs the tropical rivers. - -"And do you know," I added, "what has been the result since men have almost entirely annihilated this useful race? That the putrefied weeds have poisoned the air, and the poisoned air causes the yellow fever, that desolates these beautiful countries. Enormous vegetations are multiplied under the torrid seas, and the evil is irresistibly developed from the mouth of the Rio de la Plata to Florida. If we are to believe Toussenel, this plague is nothing to what it would be if the seas were cleaned of whales and seals. Then, infested with poulps, medusae, and cuttle-fish, they would become immense centres of infection, since their waves would not possess 'these vast stomachs that God had charged to infest the surface of the seas.'" - - - - -CHAPTER XVIII - -THE POULPS - -For several days the Nautilus kept off from the American coast. Evidently it did not wish to risk the tides of the Gulf of Mexico or of the sea of the Antilles. April 16th, we sighted Martinique and Guadaloupe from a distance of about thirty miles. I saw their tall peaks for an instant. The Canadian, who counted on carrying out his projects in the Gulf, by either landing or hailing one of the numerous boats that coast from one island to another, was quite disheartened. Flight would have been quite practicable, if Ned Land had been able to take possession of the boat without the Captain's knowledge. But in the open sea it could not be thought of. The Canadian, Conseil, and I had a long conversation on this subject. For six months we had been prisoners on board the Nautilus. We had travelled 17,000 leagues; and, as Ned Land said, there was no reason why it should come to an end. We could hope nothing from the Captain of the Nautilus, but only from ourselves. Besides, for some time past he had become graver, more retired, less sociable. He seemed to shun me. I met him rarely. Formerly he was pleased to explain the submarine marvels to me; now he left me to my studies, and came no more to the saloon. What change had come over him? For what cause? For my part, I did not wish to bury with me my curious and novel studies. I had now the power to write the true book of the sea; and this book, sooner or later, I wished to see daylight. The land nearest us was the archipelago of the Bahamas. There rose high submarine cliffs covered with large weeds. It was about eleven o'clock when Ned Land drew my attention to a formidable pricking, like the sting of an ant, which was produced by means of large seaweeds. - -"Well," I said, "these are proper caverns for poulps, and I should not be astonished to see some of these monsters." - -"What!" said Conseil; "cuttlefish, real cuttlefish of the cephalopod class?" - -"No," I said, "poulps of huge dimensions." - -"I will never believe that such animals exist," said Ned. - -"Well," said Conseil, with the most serious air in the world, "I remember perfectly to have seen a large vessel drawn under the waves by an octopus's arm." - -"You saw that?" said the Canadian. - -"Yes, Ned." - -"With your own eyes?" - -"With my own eyes." - -"Where, pray, might that be?" - -"At St. Malo," answered Conseil. - -"In the port?" said Ned, ironically. - -"No; in a church," replied Conseil. - -"In a church!" cried the Canadian. - -"Yes; friend Ned. In a picture representing the poulp in question." - -"Good!" said Ned Land, bursting out laughing. - -"He is quite right," I said. "I have heard of this picture; but the subject represented is taken from a legend, and you know what to think of legends in the matter of natural history. Besides, when it is a question of monsters, the imagination is apt to run wild. Not only is it supposed that these poulps can draw down vessels, but a certain Olaus Magnus speaks of an octopus a mile long that is more like an island than an animal. It is also said that the Bishop of Nidros was building an altar on an immense rock. Mass finished, the rock began to walk, and returned to the sea. The rock was a poulp. Another Bishop, Pontoppidan, speaks also of a poulp on which a regiment of cavalry could manoeuvre. Lastly, the ancient naturalists speak of monsters whose mouths were like gulfs, and which were too large to pass through the Straits of Gibraltar." - -"But how much is true of these stories?" asked Conseil. - -"Nothing, my friends; at least of that which passes the limit of truth to get to fable or legend. Nevertheless, there must be some ground for the imagination of the story-tellers. One cannot deny that poulps and cuttlefish exist of a large species, inferior, however, to the cetaceans. Aristotle has stated the dimensions of a cuttlefish as five cubits, or nine feet two inches. Our fishermen frequently see some that are more than four feet long. Some skeletons of poulps are preserved in the museums of Trieste and Montpelier, that measure two yards in length. Besides, according to the calculations of some naturalists, one of these animals only six feet long would have tentacles twenty-seven feet long. That would suffice to make a formidable monster." - -"Do they fish for them in these days?" asked Ned. - -"If they do not fish for them, sailors see them at least. One of my friends, Captain Paul Bos of Havre, has often affirmed that he met one of these monsters of colossal dimensions in the Indian seas. But the most astonishing fact, and which does not permit of the denial of the existence of these gigantic animals, happened some years ago, in 1861." - -"What is the fact?" asked Ned Land. - -"This is it. In 1861, to the north-east of Teneriffe, very nearly in the same latitude we are in now, the crew of the despatch-boat Alector perceived a monstrous cuttlefish swimming in the waters. Captain Bouguer went near to the animal, and attacked it with harpoon and guns, without much success, for balls and harpoons glided over the soft flesh. After several fruitless attempts the crew tried to pass a slip-knot round the body of the mollusc. The noose slipped as far as the tail fins and there stopped. They tried then to haul it on board, but its weight was so considerable that the tightness of the cord separated the tail from the body, and, deprived of this ornament, he disappeared under the water." - -"Indeed! is that a fact?" - -"An indisputable fact, my good Ned. They proposed to name this poulp `Bouguer's cuttlefish.'" - -"What length was it?" asked the Canadian. - -"Did it not measure about six yards?" said Conseil, who, posted at the window, was examining again the irregular windings of the cliff. - -"Precisely," I replied. - -"Its head," rejoined Conseil, "was it not crowned with eight tentacles, that beat the water like a nest of serpents?" - -"Precisely." - -"Had not its eyes, placed at the back of its head, considerable development?" - -"Yes, Conseil." - -"And was not its mouth like a parrot's beak?" - -"Exactly, Conseil." - -"Very well! no offence to master," he replied, quietly; "if this is not Bouguer's cuttlefish, it is, at least, one of its brothers." - -I looked at Conseil. Ned Land hurried to the window. - -"What a horrible beast!" he cried. - -I looked in my turn, and could not repress a gesture of disgust. Before my eyes was a horrible monster worthy to figure in the legends of the marvellous. It was an immense cuttlefish, being eight yards long. It swam crossways in the direction of the Nautilus with great speed, watching us with its enormous staring green eyes. Its eight arms, or rather feet, fixed to its head, that have given the name of cephalopod to these animals, were twice as long as its body, and were twisted like the furies' hair. One could see the 250 air holes on the inner side of the tentacles. The monster's mouth, a horned beak like a parrot's, opened and shut vertically. Its tongue, a horned substance, furnished with several rows of pointed teeth, came out quivering from this veritable pair of shears. What a freak of nature, a bird's beak on a mollusc! Its spindle-like body formed a fleshy mass that might weigh 4,000 to 5,000 lb.; the, varying colour changing with great rapidity, according to the irritation of the animal, passed successively from livid grey to reddish brown. What irritated this mollusc? No doubt the presence of the Nautilus, more formidable than itself, and on which its suckers or its jaws had no hold. Yet, what monsters these poulps are! what vitality the Creator has given them! what vigour in their movements! and they possess three hearts! Chance had brought us in presence of this cuttlefish, and I did not wish to lose the opportunity of carefully studying this specimen of cephalopods. I overcame the horror that inspired me, and, taking a pencil, began to draw it. - -"Perhaps this is the same which the Alector saw," said Conseil. - -"No," replied the Canadian; "for this is whole, and the other had lost its tail." - -"That is no reason," I replied. "The arms and tails of these animals are re-formed by renewal; and in seven years the tail of Bouguer's cuttlefish has no doubt had time to grow." - -By this time other poulps appeared at the port light. I counted seven. They formed a procession after the Nautilus, and I heard their beaks gnashing against the iron hull. I continued my work. These monsters kept in the water with such precision that they seemed immovable. Suddenly the Nautilus stopped. A shock made it tremble in every plate. - -"Have we struck anything?" I asked. - -"In any case," replied the Canadian, "we shall be free, for we are floating." - -The Nautilus was floating, no doubt, but it did not move. A minute passed. Captain Nemo, followed by his lieutenant, entered the drawing-room. I had not seen him for some time. He seemed dull. Without noticing or speaking to us, he went to the panel, looked at the poulps, and said something to his lieutenant. The latter went out. Soon the panels were shut. The ceiling was lighted. I went towards the Captain. - -"A curious collection of poulps?" I said. - -"Yes, indeed, Mr. Naturalist," he replied; "and we are going to fight them, man to beast." - -I looked at him. I thought I had not heard aright. - -"Man to beast?" I repeated. - -"Yes, sir. The screw is stopped. I think that the horny jaws of one of the cuttlefish is entangled in the blades. That is what prevents our moving." - -"What are you going to do?" - -"Rise to the surface, and slaughter this vermin." - -"A difficult enterprise." - -"Yes, indeed. The electric bullets are powerless against the soft flesh, where they do not find resistance enough to go off. But we shall attack them with the hatchet." - -"And the harpoon, sir," said the Canadian, "if you do not refuse my help." - -"I will accept it, Master Land." - -"We will follow you," I said, and, following Captain Nemo, we went towards the central staircase. - -There, about ten men with boarding-hatchets were ready for the attack. Conseil and I took two hatchets; Ned Land seized a harpoon. The Nautilus had then risen to the surface. One of the sailors, posted on the top ladderstep, unscrewed the bolts of the panels. But hardly were the screws loosed, when the panel rose with great violence, evidently drawn by the suckers of a poulp's arm. Immediately one of these arms slid like a serpent down the opening and twenty others were above. With one blow of the axe, Captain Nemo cut this formidable tentacle, that slid wriggling down the ladder. Just as we were pressing one on the other to reach the platform, two other arms, lashing the air, came down on the seaman placed before Captain Nemo, and lifted him up with irresistible power. Captain Nemo uttered a cry, and rushed out. We hurried after him. - -What a scene! The unhappy man, seized by the tentacle and fixed to the suckers, was balanced in the air at the caprice of this enormous trunk. He rattled in his throat, he was stifled, he cried, "Help! help!" These words, spoken in French, startled me! I had a fellow-countryman on board, perhaps several! That heart-rending cry! I shall hear it all my life. The unfortunate man was lost. Who could rescue him from that powerful pressure? However, Captain Nemo had rushed to the poulp, and with one blow of the axe had cut through one arm. His lieutenant struggled furiously against other monsters that crept on the flanks of the Nautilus. The crew fought with their axes. The Canadian, Conseil, and I buried our weapons in the fleshy masses; a strong smell of musk penetrated the atmosphere. It was horrible! - -For one instant, I thought the unhappy man, entangled with the poulp, would be torn from its powerful suction. Seven of the eight arms had been cut off. One only wriggled in the air, brandishing the victim like a feather. But just as Captain Nemo and his lieutenant threw themselves on it, the animal ejected a stream of black liquid. We were blinded with it. When the cloud dispersed, the cuttlefish had disappeared, and my unfortunate countryman with it. Ten or twelve poulps now invaded the platform and sides of the Nautilus. We rolled pell-mell into the midst of this nest of serpents, that wriggled on the platform in the waves of blood and ink. It seemed as though these slimy tentacles sprang up like the hydra's heads. Ned Land's harpoon, at each stroke, was plunged into the staring eyes of the cuttle fish. But my bold companion was suddenly overturned by the tentacles of a monster he had not been able to avoid. - -Ah! how my heart beat with emotion and horror! The formidable beak of a cuttlefish was open over Ned Land. The unhappy man would be cut in two. I rushed to his succour. But Captain Nemo was before me; his axe disappeared between the two enormous jaws, and, miraculously saved, the Canadian, rising, plunged his harpoon deep into the triple heart of the poulp. - -"I owed myself this revenge!" said the Captain to the Canadian. - -Ned bowed without replying. The combat had lasted a quarter of an hour. The monsters, vanquished and mutilated, left us at last, and disappeared under the waves. Captain Nemo, covered with blood, nearly exhausted, gazed upon the sea that had swallowed up one of his companions, and great tears gathered in his eyes. - - - - -CHAPTER XIX - -THE GULF STREAM - -This terrible scene of the 20th of April none of us can ever forget. I have written it under the influence of violent emotion. Since then I have revised the recital; I have read it to Conseil and to the Canadian. They found it exact as to facts, but insufficient as to effect. To paint such pictures, one must have the pen of the most illustrious of our poets, the author of The Toilers of the Deep. - -I have said that Captain Nemo wept while watching the waves; his grief was great. It was the second companion he had lost since our arrival on board, and what a death! That friend, crushed, stifled, bruised by the dreadful arms of a poulp, pounded by his iron jaws, would not rest with his comrades in the peaceful coral cemetery! In the midst of the struggle, it was the despairing cry uttered by the unfortunate man that had torn my heart. The poor Frenchman, forgetting his conventional language, had taken to his own mother tongue, to utter a last appeal! Amongst the crew of the Nautilus, associated with the body and soul of the Captain, recoiling like him from all contact with men, I had a fellow-countryman. Did he alone represent France in this mysterious association, evidently composed of individuals of divers nationalities? It was one of these insoluble problems that rose up unceasingly before my mind! - -Captain Nemo entered his room, and I saw him no more for some time. But that he was sad and irresolute I could see by the vessel, of which he was the soul, and which received all his impressions. The Nautilus did not keep on in its settled course; it floated about like a corpse at the will of the waves. It went at random. He could not tear himself away from the scene of the last struggle, from this sea that had devoured one of his men. Ten days passed thus. It was not till the 1st of May that the Nautilus resumed its northerly course, after having sighted the Bahamas at the mouth of the Bahama Canal. We were then following the current from the largest river to the sea, that has its banks, its fish, and its proper temperatures. I mean the Gulf Stream. It is really a river, that flows freely to the middle of the Atlantic, and whose waters do not mix with the ocean waters. It is a salt river, salter than the surrounding sea. Its mean depth is 1,500 fathoms, its mean breadth ten miles. In certain places the current flows with the speed of two miles and a half an hour. The body of its waters is more considerable than that of all the rivers in the globe. It was on this ocean river that the Nautilus then sailed. - -I must add that, during the night, the phosphorescent waters of the Gulf Stream rivalled the electric power of our watch-light, especially in the stormy weather that threatened us so frequently. May 8th, we were still crossing Cape Hatteras, at the height of the North Caroline. The width of the Gulf Stream there is seventy-five miles, and its depth 210 yards. The Nautilus still went at random; all supervision seemed abandoned. I thought that, under these circumstances, escape would be possible. Indeed, the inhabited shores offered anywhere an easy refuge. The sea was incessantly ploughed by the steamers that ply between New York or Boston and the Gulf of Mexico, and overrun day and night by the little schooners coasting about the several parts of the American coast. We could hope to be picked up. It was a favourable opportunity, notwithstanding the thirty miles that separated the Nautilus from the coasts of the Union. One unfortunate circumstance thwarted the Canadian's plans. The weather was very bad. We were nearing those shores where tempests are so frequent, that country of waterspouts and cyclones actually engendered by the current of the Gulf Stream. To tempt the sea in a frail boat was certain destruction. Ned Land owned this himself. He fretted, seized with nostalgia that flight only could cure. - -"Master," he said that day to me, "this must come to an end. I must make a clean breast of it. This Nemo is leaving land and going up to the north. But I declare to you that I have had enough of the South Pole, and I will not follow him to the North." - -"What is to be done, Ned, since flight is impracticable just now?" - -"We must speak to the Captain," said he; "you said nothing when we were in your native seas. I will speak, now we are in mine. When I think that before long the Nautilus will be by Nova Scotia, and that there near New foundland is a large bay, and into that bay the St. Lawrence empties itself, and that the St. Lawrence is my river, the river by Quebec, my native town—when I think of this, I feel furious, it makes my hair stand on end. Sir, I would rather throw myself into the sea! I will not stay here! I am stifled!" - -The Canadian was evidently losing all patience. His vigorous nature could not stand this prolonged imprisonment. His face altered daily; his temper became more surly. I knew what he must suffer, for I was seized with home-sickness myself. Nearly seven months had passed without our having had any news from land; Captain Nemo's isolation, his altered spirits, especially since the fight with the poulps, his taciturnity, all made me view things in a different light. - -"Well, sir?" said Ned, seeing I did not reply. - -"Well, Ned, do you wish me to ask Captain Nemo his intentions concerning us?" - -"Yes, sir." - -"Although he has already made them known?" - -"Yes; I wish it settled finally. Speak for me, in my name only, if you like." - -"But I so seldom meet him. He avoids me." - -"That is all the more reason for you to go to see him." - -I went to my room. From thence I meant to go to Captain Nemo's. It would not do to let this opportunity of meeting him slip. I knocked at the door. No answer. I knocked again, then turned the handle. The door opened, I went in. The Captain was there. Bending over his work-table, he had not heard me. Resolved not to go without having spoken, I approached him. He raised his head quickly, frowned, and said roughly, "You here! What do you want?" - -"To speak to you, Captain." - -"But I am busy, sir; I am working. I leave you at liberty to shut yourself up; cannot I be allowed the same?" - -This reception was not encouraging; but I was determined to hear and answer everything. - -"Sir," I said coldly, "I have to speak to you on a matter that admits of no delay." - -"What is that, sir?" he replied, ironically. "Have you discovered something that has escaped me, or has the sea delivered up any new secrets?" - -We were at cross-purposes. But, before I could reply, he showed me an open manuscript on his table, and said, in a more serious tone, "Here, M. Aronnax, is a manuscript written in several languages. It contains the sum of my studies of the sea; and, if it please God, it shall not perish with me. This manuscript, signed with my name, complete with the history of my life, will be shut up in a little floating case. The last survivor of all of us on board the Nautilus will throw this case into the sea, and it will go whither it is borne by the waves." - -This man's name! his history written by himself! His mystery would then be revealed some day. - -"Captain," I said, "I can but approve of the idea that makes you act thus. The result of your studies must not be lost. But the means you employ seem to me to be primitive. Who knows where the winds will carry this case, and in whose hands it will fall? Could you not use some other means? Could not you, or one of yours——" - -"Never, sir!" he said, hastily interrupting me. - -"But I and my companions are ready to keep this manuscript in store; and, if you will put us at liberty——" - -"At liberty?" said the Captain, rising. - -"Yes, sir; that is the subject on which I wish to question you. For seven months we have been here on board, and I ask you to-day, in the name of my companions and in my own, if your intention is to keep us here always?" - -"M. Aronnax, I will answer you to-day as I did seven months ago: Whoever enters the Nautilus, must never quit it." - -"You impose actual slavery upon us!" - -"Give it what name you please." - -"But everywhere the slave has the right to regain his liberty." - -"Who denies you this right? Have I ever tried to chain you with an oath?" - -He looked at me with his arms crossed. - -"Sir," I said, "to return a second time to this subject will be neither to your nor to my taste; but, as we have entered upon it, let us go through with it. I repeat, it is not only myself whom it concerns. Study is to me a relief, a diversion, a passion that could make me forget everything. Like you, I am willing to live obscure, in the frail hope of bequeathing one day, to future time, the result of my labours. But it is otherwise with Ned Land. Every man, worthy of the name, deserves some consideration. Have you thought that love of liberty, hatred of slavery, can give rise to schemes of revenge in a nature like the Canadian's; that he could think, attempt, and try——" - -I was silenced; Captain Nemo rose. - -"Whatever Ned Land thinks of, attempts, or tries, what does it matter to me? I did not seek him! It is not for my pleasure that I keep him on board! As for you, M. Aronnax, you are one of those who can understand everything, even silence. I have nothing more to say to you. Let this first time you have come to treat of this subject be the last, for a second time I will not listen to you." - -I retired. Our situation was critical. I related my conversation to my two companions. - -"We know now," said Ned, "that we can expect nothing from this man. The Nautilus is nearing Long Island. We will escape, whatever the weather may be." - -But the sky became more and more threatening. Symptoms of a hurricane became manifest. The atmosphere was becoming white and misty. On the horizon fine streaks of cirrhous clouds were succeeded by masses of cumuli. Other low clouds passed swiftly by. The swollen sea rose in huge billows. The birds disappeared with the exception of the petrels, those friends of the storm. The barometer fell sensibly, and indicated an extreme extension of the vapours. The mixture of the storm glass was decomposed under the influence of the electricity that pervaded the atmosphere. The tempest burst on the 18th of May, just as the Nautilus was floating off Long Island, some miles from the port of New York. I can describe this strife of the elements! for, instead of fleeing to the depths of the sea, Captain Nemo, by an unaccountable caprice, would brave it at the surface. The wind blew from the south-west at first. Captain Nemo, during the squalls, had taken his place on the platform. He had made himself fast, to prevent being washed overboard by the monstrous waves. I had hoisted myself up, and made myself fast also, dividing my admiration between the tempest and this extraordinary man who was coping with it. The raging sea was swept by huge cloud-drifts, which were actually saturated with the waves. The Nautilus, sometimes lying on its side, sometimes standing up like a mast, rolled and pitched terribly. About five o'clock a torrent of rain fell, that lulled neither sea nor wind. The hurri cane blew nearly forty leagues an hour. It is under these conditions that it overturns houses, breaks iron gates, displaces twenty-four pounders. However, the Nautilus, in the midst of the tempest, confirmed the words of a clever engineer, "There is no well-constructed hull that cannot defy the sea." This was not a resisting rock; it was a steel spindle, obedient and movable, without rigging or masts, that braved its fury with impunity. However, I watched these raging waves attentively. They measured fifteen feet in height, and 150 to 175 yards long, and their speed of propagation was thirty feet per second. Their bulk and power increased with the depth of the water. Such waves as these, at the Hebrides, have displaced a mass weighing 8,400 lb. They are they which, in the tempest of December 23rd, 1864, after destroying the town of Yeddo, in Japan, broke the same day on the shores of America. The intensity of the tempest increased with the night. The barometer, as in 1860 at Reunion during a cyclone, fell seven-tenths at the close of day. I saw a large vessel pass the horizon struggling painfully. She was trying to lie to under half steam, to keep up above the waves. It was probably one of the steamers of the line from New York to Liverpool, or Havre. It soon disappeared in the gloom. At ten o'clock in the evening the sky was on fire. The atmosphere was streaked with vivid lightning. I could not bear the brightness of it; while the captain, looking at it, seemed to envy the spirit of the tempest. A terrible noise filled the air, a complex noise, made up of the howls of the crushed waves, the roaring of the wind, and the claps of thunder. The wind veered suddenly to all points of the horizon; and the cyclone, rising in the east, returned after passing by the north, west, and south, in the inverse course pursued by the circular storm of the southern hemisphere. Ah, that Gulf Stream! It deserves its name of the King of Tempests. It is that which causes those formidable cyclones, by the difference of temperature between its air and its currents. A shower of fire had succeeded the rain. The drops of water were changed to sharp spikes. One would have thought that Captain Nemo was courting a death worthy of himself, a death by lightning. As the Nautilus, pitching dreadfully, raised its steel spur in the air, it seemed to act as a conductor, and I saw long sparks burst from it. Crushed and without strength I crawled to the panel, opened it, and descended to the saloon. The storm was then at its height. It was impossible to stand upright in the interior of the Nautilus. Captain Nemo came down about twelve. I heard the reservoirs filling by degrees, and the Nautilus sank slowly beneath the waves. Through the open windows in the saloon I saw large fish terrified, passing like phantoms in the water. Some were struck before my eyes. The Nautilus was still descending. I thought that at about eight fathoms deep we should find a calm. But no! the upper beds were too violently agitated for that. We had to seek repose at more than twenty-five fathoms in the bowels of the deep. But there, what quiet, what silence, what peace! Who could have told that such a hurricane had been let loose on the surface of that ocean? - - - - -CHAPTER XX - -FROM LATITUDE 47° 24' TO LONGITUDE 17° 28' - -In consequence of the storm, we had been thrown eastward once more. All hope of escape on the shores of New York or St. Lawrence had faded away; and poor Ned, in despair, had isolated himself like Captain Nemo. Conseil and I, however, never left each other. I said that the Nautilus had gone aside to the east. I should have said (to be more exact) the north-east. For some days, it wandered first on the surface, and then beneath it, amid those fogs so dreaded by sailors. What accidents are due to these thick fogs! What shocks upon these reefs when the wind drowns the breaking of the waves! What collisions between vessels, in spite of their warning lights, whistles, and alarm bells! And the bottoms of these seas look like a field of battle, where still lie all the conquered of the ocean; some old and already encrusted, others fresh and reflecting from their iron bands and copper plates the brilliancy of our lantern. - -On the 15th of May we were at the extreme south of the Bank of Newfoundland. This bank consists of alluvia, or large heaps of organic matter, brought either from the Equator by the Gulf Stream, or from the North Pole by the counter-current of cold water which skirts the American coast. There also are heaped up those erratic blocks which are carried along by the broken ice; and close by, a vast charnel-house of molluscs, which perish here by millions. The depth of the sea is not great at Newfoundland—not more than some hundreds of fathoms; but towards the south is a depression of 1,500 fathoms. There the Gulf Stream widens. It loses some of its speed and some of its temperature, but it becomes a sea. - -It was on the 17th of May, about 500 miles from Heart's Content, at a depth of more than 1,400 fathoms, that I saw the electric cable lying on the bottom. Conseil, to whom I had not mentioned it, thought at first that it was a gigantic sea-serpent. But I undeceived the worthy fellow, and by way of consolation related several particulars in the laying of this cable. The first one was laid in the years 1857 and 1858; but, after transmitting about 400 telegrams, would not act any longer. In 1863 the engineers constructed an other one, measuring 2,000 miles in length, and weighing 4,500 tons, which was embarked on the Great Eastern. This attempt also failed. - -On the 25th of May the Nautilus, being at a depth of more than 1,918 fathoms, was on the precise spot where the rupture occurred which ruined the enterprise. It was within 638 miles of the coast of Ireland; and at half-past two in the afternoon they discovered that communication with Europe had ceased. The electricians on board resolved to cut the cable before fishing it up, and at eleven o'clock at night they had recovered the damaged part. They made another point and spliced it, and it was once more submerged. But some days after it broke again, and in the depths of the ocean could not be recaptured. The Americans, however, were not discouraged. Cyrus Field, the bold promoter of the enterprise, as he had sunk all his own fortune, set a new subscription on foot, which was at once answered, and another cable was constructed on better principles. The bundles of conducting wires were each enveloped in gutta-percha, and protected by a wadding of hemp, contained in a metallic covering. The Great Eastern sailed on the 13th of July, 1866. The operation worked well. But one incident occurred. Several times in unrolling the cable they observed that nails had recently been forced into it, evidently with the motive of destroying it. Captain Anderson, the officers, and engineers consulted together, and had it posted up that, if the offender was surprised on board, he would be thrown without further trial into the sea. From that time the criminal attempt was never repeated. - -On the 23rd of July the Great Eastern was not more than 500 miles from Newfoundland, when they telegraphed from Ireland the news of the armistice concluded between Prussia and Austria after Sadowa. On the 27th, in the midst of heavy fogs, they reached the port of Heart's Content. The enterprise was successfully terminated; and for its first despatch, young America addressed old Europe in these words of wisdom, so rarely understood: "Glory to God in the highest, and on earth peace, goodwill towards men." - -I did not expect to find the electric cable in its primitive state, such as it was on leaving the manufactory. The long serpent, covered with the remains of shells, bristling with foraminiferae, was encrusted with a strong coating which served as a protection against all boring molluscs. It lay quietly sheltered from the motions of the sea, and under a favourable pressure for the transmission of the electric spark which passes from Europe to America in .32 of a second. Doubtless this cable will last for a great length of time, for they find that the gutta-percha covering is improved by the sea-water. Besides, on this level, so well chosen, the cable is never so deeply submerged as to cause it to break. The Nautilus followed it to the lowest depth, which was more than 2,212 fathoms, and there it lay without any anchorage; and then we reached the spot where the accident had taken place in 1863. The bottom of the ocean then formed a valley about 100 miles broad, in which Mont Blanc might have been placed without its summit appearing above the waves. This valley is closed at the east by a perpendicular wall more than 2,000 yards high. We arrived there on the 28th of May, and the Nautilus was then not more than 120 miles from Ireland. - -Was Captain Nemo going to land on the British Isles? No. To my great surprise he made for the south, once more coming back towards European seas. In rounding the Emerald Isle, for one instant I caught sight of Cape Clear, and the light which guides the thousands of vessels leaving Glasgow or Liverpool. An important question then arose in my mind. Did the Nautilus dare entangle itself in the Manche? Ned Land, who had re-appeared since we had been nearing land, did not cease to question me. How could I answer? Captain Nemo remained invisible. After having shown the Canadian a glimpse of American shores, was he going to show me the coast of France? - -But the Nautilus was still going southward. On the 30th of May, it passed in sight of Land's End, between the extreme point of England and the Scilly Isles, which were left to starboard. If we wished to enter the Manche, he must go straight to the east. He did not do so. - -During the whole of the 31st of May, the Nautilus described a series of circles on the water, which greatly interested me. It seemed to be seeking a spot it had some trouble in finding. At noon, Captain Nemo himself came to work the ship's log. He spoke no word to me, but seemed gloomier than ever. What could sadden him thus? Was it his proxim ity to European shores? Had he some recollections of his abandoned country? If not, what did he feel? Remorse or regret? For a long while this thought haunted my mind, and I had a kind of presentiment that before long chance would betray the captain's secrets. - -The next day, the 1st of June, the Nautilus continued the same process. It was evidently seeking some particular spot in the ocean. Captain Nemo took the sun's altitude as he had done the day before. The sea was beautiful, the sky clear. About eight miles to the east, a large steam vessel could be discerned on the horizon. No flag fluttered from its mast, and I could not discover its nationality. Some minutes before the sun passed the meridian, Captain Nemo took his sextant, and watched with great attention. The perfect rest of the water greatly helped the operation. The Nautilus was motionless; it neither rolled nor pitched. - -I was on the platform when the altitude was taken, and the Captain pronounced these words: "It is here." - -He turned and went below. Had he seen the vessel which was changing its course and seemed to be nearing us? I could not tell. I returned to the saloon. The panels closed, I heard the hissing of the water in the reservoirs. The Nautilus began to sink, following a vertical line, for its screw communicated no motion to it. Some minutes later it stopped at a depth of more than 420 fathoms, resting on the ground. The luminous ceiling was darkened, then the panels were opened, and through the glass I saw the sea brilliantly illuminated by the rays of our lantern for at least half a mile round us. - -I looked to the port side, and saw nothing but an immensity of quiet waters. But to starboard, on the bottom appeared a large protuberance, which at once attracted my attention. One would have thought it a ruin buried under a coating of white shells, much resembling a covering of snow. Upon examining the mass attentively, I could recognise the ever-thickening form of a vessel bare of its masts, which must have sunk. It certainly belonged to past times. This wreck, to be thus encrusted with the lime of the water, must already be able to count many years passed at the bottom of the ocean. - -What was this vessel? Why did the Nautilus visit its tomb? Could it have been aught but a shipwreck which had drawn it under the water? I knew not what to think, when near me in a slow voice I heard Captain Nemo say: - -"At one time this ship was called the Marseillais. It carried seventy-four guns, and was launched in 1762. In 1778, the 13th of August, commanded by La Poype-Ver trieux, it fought boldly against the Preston. In 1779, on the 4th of July, it was at the taking of Grenada, with the squadron of Admiral Estaing. In 1781, on the 5th of September, it took part in the battle of Comte de Grasse, in Chesapeake Bay. In 1794, the French Republic changed its name. On the 16th of April, in the same year, it joined the squadron of Villaret Joyeuse, at Brest, being entrusted with the escort of a cargo of corn coming from America, under the command of Admiral Van Stebel. On the 11th and 12th Prairal of the second year, this squadron fell in with an English vessel. Sir, to-day is the 13th Prairal, the first of June, 1868. It is now seventy-four years ago, day for day on this very spot, in latitude 47° 24', longitude 17° 28', that this vessel, after fighting heroically, losing its three masts, with the water in its hold, and the third of its crew disabled, preferred sinking with its 356 sailors to surrendering; and, nailing its colours to the poop, disappeared under the waves to the cry of `Long live the Republic!'" - -"The Avenger!" I exclaimed. - -"Yes, sir, the Avenger! A good name!" muttered Captain Nemo, crossing his arms. - - - - -CHAPTER XXI - -A HECATOMB - -The way of describing this unlooked-for scene, the history of the patriot ship, told at first so coldly, and the emotion with which this strange man pronounced the last words, the name of the Avenger, the significance of which could not escape me, all impressed itself deeply on my mind. My eyes did not leave the Captain, who, with his hand stretched out to sea, was watching with a glowing eye the glorious wreck. Perhaps I was never to know who he was, from whence he came, or where he was going to, but I saw the man move, and apart from the savant. It was no common misanthropy which had shut Captain Nemo and his companions within the Nautilus, but a hatred, either monstrous or sublime, which time could never weaken. Did this hatred still seek for vengeance? The future would soon teach me that. But the Nautilus was rising slowly to the surface of the sea, and the form of the Avenger disappeared by degrees from my sight. Soon a slight rolling told me that we were in the open air. At that moment a dull boom was heard. I looked at the Captain. He did not move. - -"Captain?" said I. - -He did not answer. I left him and mounted the platform. Conseil and the Canadian were already there. - -"Where did that sound come from?" I asked. - -"It was a gunshot," replied Ned Land. - -I looked in the direction of the vessel I had already seen. It was nearing the Nautilus, and we could see that it was putting on steam. It was within six miles of us. - -"What is that ship, Ned?" - -"By its rigging, and the height of its lower masts," said the Canadian, "I bet she is a ship-of-war. May it reach us; and, if necessary, sink this cursed Nautilus." - -"Friend Ned," replied Conseil, "what harm can it do to the Nautilus? Can it attack it beneath the waves? Can its cannonade us at the bottom of the sea?" - -"Tell me, Ned," said I, "can you recognise what country she belongs to?" - -The Canadian knitted his eyebrows, dropped his eyelids, and screwed up the corners of his eyes, and for a few moments fixed a piercing look upon the vessel. - -"No, sir," he replied; "I cannot tell what nation she belongs to, for she shows no colours. But I can declare she is a man-of-war, for a long pennant flutters from her main mast." - -For a quarter of an hour we watched the ship which was steaming towards us. I could not, however, believe that she could see the Nautilus from that distance; and still less that she could know what this submarine engine was. Soon the Canadian informed me that she was a large, armoured, two-decker ram. A thick black smoke was pouring from her two funnels. Her closely-furled sails were stopped to her yards. She hoisted no flag at her mizzen-peak. The distance prevented us from distinguishing the colours of her pennant, which floated like a thin ribbon. She advanced rapidly. If Captain Nemo allowed her to approach, there was a chance of salvation for us. - -"Sir," said Ned Land, "if that vessel passes within a mile of us I shall throw myself into the sea, and I should advise you to do the same." - -I did not reply to the Canadian's suggestion, but continued watching the ship. Whether English, French, American, or Russian, she would be sure to take us in if we could only reach her. Presently a white smoke burst from the fore part of the vessel; some seconds after, the water, agitated by the fall of a heavy body, splashed the stern of the Nautilus, and shortly afterwards a loud explosion struck my ear. - -"What! they are firing at us!" I exclaimed. - -"So please you, sir," said Ned, "they have recognised the unicorn, and they are firing at us." - -"But," I exclaimed, "surely they can see that there are men in the case?" - -"It is, perhaps, because of that," replied Ned Land, looking at me. - -A whole flood of light burst upon my mind. Doubtless they knew now how to believe the stories of the pretended monster. No doubt, on board the Abraham Lincoln, when the Canadian struck it with the harpoon, Commander Farragut had recognised in the supposed narwhal a submarine vessel, more dangerous than a supernatural cetacean. Yes, it must have been so; and on every sea they were now seeking this engine of destruction. Terrible indeed! if, as we supposed, Captain Nemo employed the Nautilus in works of vengeance. On the night when we were imprisoned in that cell, in the midst of the Indian Ocean, had he not attacked some vessel? The man buried in the coral cemetery, had he not been a victim to the shock caused by the Nautilus? Yes, I repeat it, it must be so. One part of the mysterious existence of Captain Nemo had been unveiled; and, if his identity had not been recognised, at least, the nations united against him were no longer hunting a chimerical creature, but a man who had vowed a deadly hatred against them. All the formidable past rose before me. Instead of meeting friends on board the approaching ship, we could only expect pitiless enemies. But the shot rattled about us. Some of them struck the sea and ricochetted, losing themselves in the distance. But none touched the Nautilus. The vessel was not more than three miles from us. In spite of the serious cannonade, Captain Nemo did not appear on the platform; but, if one of the conical projectiles had struck the shell of the Nautilus, it would have been fatal. The Canadian then said, "Sir, we must do all we can to get out of this dilemma. Let us signal them. They will then, perhaps, understand that we are honest folks." - -Ned Land took his handkerchief to wave in the air; but he had scarcely displayed it, when he was struck down by an iron hand, and fell, in spite of his great strength, upon the deck. - -"Fool!" exclaimed the Captain, "do you wish to be pierced by the spur of the Nautilus before it is hurled at this vessel?" - -Captain Nemo was terrible to hear; he was still more terrible to see. His face was deadly pale, with a spasm at his heart. For an instant it must have ceased to beat. His pupils were fearfully contracted. He did not speak, he roared, as, with his body thrown forward, he wrung the Canadian's shoulders. Then, leaving him, and turning to the ship of war, whose shot was still raining around him, he exclaimed, with a powerful voice, "Ah, ship of an accursed nation, you know who I am! I do not want your colours to know you by! Look! and I will show you mine!" - -And on the fore part of the platform Captain Nemo unfurled a black flag, similar to the one he had placed at the South Pole. At that moment a shot struck the shell of the Nautilus obliquely, without piercing it; and, rebounding near the Captain, was lost in the sea. He shrugged his shoulders; and, addressing me, said shortly, "Go down, you and your companions, go down!" - -"Sir," I cried, "are you going to attack this vessel?" - -"Sir, I am going to sink it." - -"You will not do that?" - -"I shall do it," he replied coldly. "And I advise you not to judge me, sir. Fate has shown you what you ought not to have seen. The attack has begun; go down." - -"What is this vessel?" - -"You do not know? Very well! so much the better! Its nationality to you, at least, will be a secret. Go down!" - -We could but obey. About fifteen of the sailors surrounded the Captain, looking with implacable hatred at the vessel nearing them. One could feel that the same desire of vengeance animated every soul. I went down at the moment another projectile struck the Nautilus, and I heard the Captain exclaim: - -"Strike, mad vessel! Shower your useless shot! And then, you will not escape the spur of the Nautilus. But it is not here that you shall perish! I would not have your ruins mingle with those of the Avenger!" - -I reached my room. The Captain and his second had remained on the platform. The screw was set in motion, and the Nautilus, moving with speed, was soon beyond the reach of the ship's guns. But the pursuit continued, and Captain Nemo contented himself with keeping his distance. - -About four in the afternoon, being no longer able to contain my impatience, I went to the central staircase. The panel was open, and I ventured on to the platform. The Captain was still walking up and down with an agitated step. He was looking at the ship, which was five or six miles to leeward. - -He was going round it like a wild beast, and, drawing it eastward, he allowed them to pursue. But he did not attack. Perhaps he still hesitated? I wished to mediate once more. But I had scarcely spoken, when Captain Nemo imposed silence, saying: - -"I am the law, and I am the judge! I am the oppressed, and there is the oppressor! Through him I have lost all that I loved, cherished, and venerated—country, wife, children, father, and mother. I saw all perish! All that I hate is there! Say no more!" - -I cast a last look at the man-of-war, which was putting on steam, and rejoined Ned and Conseil. - -"We will fly!" I exclaimed. - -"Good!" said Ned. "What is this vessel?" - -"I do not know; but, whatever it is, it will be sunk before night. In any case, it is better to perish with it, than be made accomplices in a retaliation the justice of which we cannot judge." - -"That is my opinion too," said Ned Land, coolly. "Let us wait for night." - -Night arrived. Deep silence reigned on board. The compass showed that the Nautilus had not altered its course. It was on the surface, rolling slightly. My companions and I resolved to fly when the vessel should be near enough either to hear us or to see us; for the moon, which would be full in two or three days, shone brightly. Once on board the ship, if we could not prevent the blow which threatened it, we could, at least we would, do all that circumstances would allow. Several times I thought the Nautilus was preparing for attack; but Captain Nemo contented himself with allowing his adversary to approach, and then fled once more before it. - -Part of the night passed without any incident. We watched the opportunity for action. We spoke little, for we were too much moved. Ned Land would have thrown himself into the sea, but I forced him to wait. According to my idea, the Nautilus would attack the ship at her waterline, and then it would not only be possible, but easy to fly. - -At three in the morning, full of uneasiness, I mounted the platform. Captain Nemo had not left it. He was standing at the fore part near his flag, which a slight breeze displayed above his head. He did not take his eyes from the vessel. The intensity of his look seemed to attract, and fascinate, and draw it onward more surely than if he had been towing it. The moon was then passing the meridian. Jupiter was rising in the east. Amid this peaceful scene of nature, sky and ocean rivalled each other in tranquillity, the sea offering to the orbs of night the finest mirror they could ever have in which to reflect their image. As I thought of the deep calm of these elements, compared with all those passions brooding imperceptibly within the Nautilus, I shuddered. - -The vessel was within two miles of us. It was ever nearing that phosphorescent light which showed the presence of the Nautilus. I could see its green and red lights, and its white lantern hanging from the large foremast. An indistinct vibration quivered through its rigging, showing that the furnaces were heated to the uttermost. Sheaves of sparks and red ashes flew from the funnels, shining in the atmosphere like stars. - -I remained thus until six in the morning, without Captain Nemo noticing me. The ship stood about a mile and a half from us, and with the first dawn of day the firing began afresh. The moment could not be far off when, the Nautilus attacking its adversary, my companions and myself should for ever leave this man. I was preparing to go down to remind them, when the second mounted the platform, accompanied by several sailors. Captain Nemo either did not or would not see them. Some steps were taken which might be called the signal for action. They were very simple. The iron balustrade around the platform was lowered, and the lantern and pilot cages were pushed within the shell until they were flush with the deck. The long surface of the steel cigar no longer offered a single point to check its manoeuvres. I returned to the saloon. The Nautilus still floated; some streaks of light were filtering through the liquid beds. With the undulations of the waves the windows were brightened by the red streaks of the rising sun, and this dreadful day of the 2nd of June had dawned. - -At five o'clock, the log showed that the speed of the Nautilus was slackening, and I knew that it was allowing them to draw nearer. Besides, the reports were heard more distinctly, and the projectiles, labouring through the ambient water, were extinguished with a strange hissing noise. - -"My friends," said I, "the moment is come. One grasp of the hand, and may God protect us!" - -Ned Land was resolute, Conseil calm, myself so nervous that I knew not how to contain myself. We all passed into the library; but the moment I pushed the door opening on to the central staircase, I heard the upper panel close sharply. The Canadian rushed on to the stairs, but I stopped him. A well-known hissing noise told me that the water was running into the reservoirs, and in a few minutes the Nautilus was some yards beneath the surface of the waves. I understood the manoeuvre. It was too late to act. The Nautilus did not wish to strike at the impenetrable cuirass, but below the water-line, where the metallic covering no longer protected it. - -We were again imprisoned, unwilling witnesses of the dreadful drama that was preparing. We had scarcely time to reflect; taking refuge in my room, we looked at each other without speaking. A deep stupor had taken hold of my mind: thought seemed to stand still. I was in that painful state of expectation preceding a dreadful report. I waited, I listened, every sense was merged in that of hearing! The speed of the Nautilus was accelerated. It was preparing to rush. The whole ship trembled. Suddenly I screamed. I felt the shock, but comparatively light. I felt the penetrating power of the steel spur. I heard rattlings and scrapings. But the Nautilus, carried along by its propelling power, passed through the mass of the vessel like a needle through sailcloth! - -I could stand it no longer. Mad, out of my mind, I rushed from my room into the saloon. Captain Nemo was there, mute, gloomy, implacable; he was looking through the port panel. A large mass cast a shadow on the water; and, that it might lose nothing of her agony, the Nautilus was going down into the abyss with her. Ten yards from me I saw the open shell, through which the water was rushing with the noise of thunder, then the double line of guns and the netting. The bridge was covered with black, agitated shadows. - -The water was rising. The poor creatures were crowding the ratlines, clinging to the masts, struggling under the water. It was a human ant-heap overtaken by the sea. Paralysed, stiffened with anguish, my hair standing on end, with eyes wide open, panting, without breath, and without voice, I too was watching! An irresistible attraction glued me to the glass! Suddenly an explosion took place. The compressed air blew up her decks, as if the magazines had caught fire. Then the unfortunate vessel sank more rapidly. Her topmast, laden with victims, now appeared; then her spars, bending under the weight of men; and, last of all, the top of her mainmast. Then the dark mass disappeared, and with it the dead crew, drawn down by the strong eddy. - -I turned to Captain Nemo. That terrible avenger, a perfect archangel of hatred, was still looking. When all was over, he turned to his room, opened the door, and entered. I followed him with my eyes. On the end wall beneath his heroes, I saw the portrait of a woman, still young, and two little children. Captain Nemo looked at them for some moments, stretched his arms towards them, and, kneeling down, burst into deep sobs. - - - - -CHAPTER XXII - -THE LAST WORDS OF CAPTAIN NEMO - -The panels had closed on this dreadful vision, but light had not returned to the saloon: all was silence and darkness within the Nautilus. At wonderful speed, a hundred feet beneath the water, it was leaving this desolate spot. Whither was it going? To the north or south? Where was the man flying to after such dreadful retaliation? I had returned to my room, where Ned and Conseil had remained silent enough. I felt an insurmountable horror for Captain Nemo. Whatever he had suffered at the hands of these men, he had no right to punish thus. He had made me, if not an accomplice, at least a witness of his vengeance. At eleven the electric light reappeared. I passed into the saloon. It was deserted. I consulted the different instruments. The Nautilus was flying northward at the rate of twenty-five miles an hour, now on the surface, and now thirty feet below it. On taking the bearings by the chart, I saw that we were passing the mouth of the Manche, and that our course was hurrying us towards the northern seas at a frightful speed. That night we had crossed two hundred leagues of the Atlantic. The shadows fell, and the sea was covered with darkness until the rising of the moon. I went to my room, but could not sleep. I was troubled with dreadful nightmare. The horrible scene of destruction was continually before my eyes. From that day, who could tell into what part of the North Atlantic basin the Nautilus would take us? Still with unaccountable speed. Still in the midst of these northern fogs. Would it touch at Spitzbergen, or on the shores of Nova Zembla? Should we explore those unknown seas, the White Sea, the Sea of Kara, the Gulf of Obi, the Archipelago of Liarrov, and the unknown coast of Asia? I could not say. I could no longer judge of the time that was passing. The clocks had been stopped on board. It seemed, as in polar countries, that night and day no longer followed their regular course. I felt myself being drawn into that strange region where the foundered imagination of Edgar Poe roamed at will. Like the fabulous Gordon Pym, at every moment I expected to see "that veiled human figure, of larger proportions than those of any inhabitant of the earth, thrown across the cataract which defends the approach to the pole." I estimated (though, perhaps, I may be mistaken)—I estimated this adventurous course of the Nautilus to have lasted fifteen or twenty days. And I know not how much longer it might have lasted, had it not been for the catastrophe which ended this voyage. Of Captain Nemo I saw nothing whatever now, nor of his second. Not a man of the crew was visible for an instant. The Nautilus was almost incessantly under water. When we came to the surface to renew the air, the panels opened and shut mechanically. There were no more marks on the planisphere. I knew not where we were. And the Canadian, too, his strength and patience at an end, appeared no more. Conseil could not draw a word from him; and, fearing that, in a dreadful fit of madness, he might kill himself, watched him with constant devotion. One morning (what date it was I could not say) I had fallen into a heavy sleep towards the early hours, a sleep both painful and unhealthy, when I suddenly awoke. Ned Land was leaning over me, saying, in a low voice, "We are going to fly." I sat up. - -"When shall we go?" I asked. - -"To-night. All inspection on board the Nautilus seems to have ceased. All appear to be stupefied. You will be ready, sir?" - -"Yes; where are we?" - -"In sight of land. I took the reckoning this morning in the fog—twenty miles to the east." - -"What country is it?" - -"I do not know; but, whatever it is, we will take refuge there." - -"Yes, Ned, yes. We will fly to-night, even if the sea should swallow us up." - -"The sea is bad, the wind violent, but twenty miles in that light boat of the Nautilus does not frighten me. Unknown to the crew, I have been able to procure food and some bottles of water." - -"I will follow you." - -"But," continued the Canadian, "if I am surprised, I will defend myself; I will force them to kill me." - -"We will die together, friend Ned." - -I had made up my mind to all. The Canadian left me. I reached the platform, on which I could with difficulty support myself against the shock of the waves. The sky was threatening; but, as land was in those thick brown shadows, we must fly. I returned to the saloon, fearing and yet hoping to see Captain Nemo, wishing and yet not wishing to see him. What could I have said to him? Could I hide the involuntary horror with which he inspired me? No. It was better that I should not meet him face to face; better to forget him. And yet—— How long seemed that day, the last that I should pass in the Nautilus. I remained alone. Ned Land and Conseil avoided speaking, for fear of betraying themselves. At six I dined, but I was not hungry; I forced myself to eat in spite of my disgust, that I might not weaken myself. At half-past six Ned Land came to my room, saying, "We shall not see each other again before our departure. At ten the moon will not be risen. We will profit by the darkness. Come to the boat; Conseil and I will wait for you." - -The Canadian went out without giving me time to answer. Wishing to verify the course of the Nautilus, I went to the saloon. We were running N.N.E. at frightful speed, and more than fifty yards deep. I cast a last look on these wonders of nature, on the riches of art heaped up in this museum, upon the unrivalled collection destined to perish at the bottom of the sea, with him who had formed it. I wished to fix an indelible impression of it in my mind. I remained an hour thus, bathed in the light of that luminous ceiling, and passing in review those treasures shining under their glasses. Then I returned to my room. - -I dressed myself in strong sea clothing. I collected my notes, placing them carefully about me. My heart beat loudly. I could not check its pulsations. Certainly my trouble and agitation would have betrayed me to Captain Nemo's eyes. What was he doing at this moment? I listened at the door of his room. I heard steps. Captain Nemo was there. He had not gone to rest. At every moment I expected to see him appear, and ask me why I wished to fly. I was constantly on the alert. My imagination magnified everything. The impression became at last so poignant that I asked myself if it would not be better to go to the Captain's room, see him face to face, and brave him with look and gesture. - -It was the inspiration of a madman; fortunately I resisted the desire, and stretched myself on my bed to quiet my bodily agitation. My nerves were somewhat calmer, but in my excited brain I saw over again all my existence on board the Nautilus; every incident, either happy or unfortunate, which had happened since my disappearance from the Abraham Lincoln—the submarine hunt, the Torres Straits, the savages of Papua, the running ashore, the coral cemetery, the passage of Suez, the Island of Santorin, the Cretan diver, Vigo Bay, Atlantis, the iceberg, the South Pole, the imprisonment in the ice, the fight among the poulps, the storm in the Gulf Stream, the Avenger, and the horrible scene of the vessel sunk with all her crew. All these events passed before my eyes like scenes in a drama. Then Captain Nemo seemed to grow enormously, his features to assume superhuman proportions. He was no longer my equal, but a man of the waters, the genie of the sea. - -It was then half-past nine. I held my head between my hands to keep it from bursting. I closed my eyes; I would not think any longer. There was another half-hour to wait, another half-hour of a nightmare, which might drive me mad. - -At that moment I heard the distant strains of the organ, a sad harmony to an undefinable chant, the wail of a soul longing to break these earthly bonds. I listened with every sense, scarcely breathing; plunged, like Captain Nemo, in that musical ecstasy, which was drawing him in spirit to the end of life. - -Then a sudden thought terrified me. Captain Nemo had left his room. He was in the saloon, which I must cross to fly. There I should meet him for the last time. He would see me, perhaps speak to me. A gesture of his might destroy me, a single word chain me on board. - -But ten was about to strike. The moment had come for me to leave my room, and join my companions. - -I must not hesitate, even if Captain Nemo himself should rise before me. I opened my door carefully; and even then, as it turned on its hinges, it seemed to me to make a dreadful noise. Perhaps it only existed in my own imagination. - -I crept along the dark stairs of the Nautilus, stopping at each step to check the beating of my heart. I reached the door of the saloon, and opened it gently. It was plunged in profound darkness. The strains of the organ sounded faintly. Captain Nemo was there. He did not see me. In the full light I do not think he would have noticed me, so entirely was he absorbed in the ecstasy. - -I crept along the carpet, avoiding the slightest sound which might betray my presence. I was at least five minutes reaching the door, at the opposite side, opening into the library. - -I was going to open it, when a sigh from Captain Nemo nailed me to the spot. I knew that he was rising. I could even see him, for the light from the library came through to the saloon. He came towards me silently, with his arms crossed, gliding like a spectre rather than walking. His breast was swelling with sobs; and I heard him murmur these words (the last which ever struck my ear): - -"Almighty God! enough! enough!" - -Was it a confession of remorse which thus escaped from this man's conscience? - -In desperation, I rushed through the library, mounted the central staircase, and, following the upper flight, reached the boat. I crept through the opening, which had already admitted my two companions. - -"Let us go! let us go!" I exclaimed. - -"Directly!" replied the Canadian. - -The orifice in the plates of the Nautilus was first closed, and fastened down by means of a false key, with which Ned Land had provided himself; the opening in the boat was also closed. The Canadian began to loosen the bolts which still held us to the submarine boat. - -Suddenly a noise was heard. Voices were answering each other loudly. What was the matter? Had they discovered our flight? I felt Ned Land slipping a dagger into my hand. - -"Yes," I murmured, "we know how to die!" - -The Canadian had stopped in his work. But one word many times repeated, a dreadful word, revealed the cause of the agitation spreading on board the Nautilus. It was not we the crew were looking after! - -"The maelstrom! the maelstrom!" Could a more dreadful word in a more dreadful situation have sounded in our ears! We were then upon the dangerous coast of Norway. Was the Nautilus being drawn into this gulf at the moment our boat was going to leave its sides? We knew that at the tide the pent-up waters between the islands of Ferroe and Loffoden rush with irresistible violence, forming a whirlpool from which no vessel ever escapes. From every point of the horizon enormous waves were meeting, forming a gulf justly called the "Navel of the Ocean," whose power of attraction extends to a distance of twelve miles. There, not only vessels, but whales are sacrificed, as well as white bears from the northern regions. - -It is thither that the Nautilus, voluntarily or involuntarily, had been run by the Captain. - -It was describing a spiral, the circumference of which was lessening by degrees, and the boat, which was still fastened to its side, was carried along with giddy speed. I felt that sickly giddiness which arises from long-continued whirling round. - -We were in dread. Our horror was at its height, circulation had stopped, all nervous influence was annihilated, and we were covered with cold sweat, like a sweat of agony! And what noise around our frail bark! What roarings repeated by the echo miles away! What an uproar was that of the waters broken on the sharp rocks at the bottom, where the hardest bodies are crushed, and trees worn away, "with all the fur rubbed off," according to the Norwegian phrase! - -What a situation to be in! We rocked frightfully. The Nautilus defended itself like a human being. Its steel muscles cracked. Sometimes it seemed to stand upright, and we with it! - -"We must hold on," said Ned, "and look after the bolts. We may still be saved if we stick to the Nautilus." - -He had not finished the words, when we heard a crashing noise, the bolts gave way, and the boat, torn from its groove, was hurled like a stone from a sling into the midst of the whirlpool. - -My head struck on a piece of iron, and with the violent shock I lost all consciousness. - - - - -CHAPTER XXIII - -CONCLUSION - -Thus ends the voyage under the seas. What passed during that night—how the boat escaped from the eddies of the maelstrom—how Ned Land, Conseil, and myself ever came out of the gulf, I cannot tell. - -But when I returned to consciousness, I was lying in a fisherman's hut, on the Loffoden Isles. My two companions, safe and sound, were near me holding my hands. We embraced each other heartily. - -At that moment we could not think of returning to France. The means of communication between the north of Norway and the south are rare. And I am therefore obliged to wait for the steamboat running monthly from Cape North. - -And, among the worthy people who have so kindly received us, I revise my record of these adventures once more. Not a fact has been omitted, not a detail exaggerated. It is a faithful narrative of this incredible expedition in an element inaccessible to man, but to which Progress will one day open a road. - -Shall I be believed? I do not know. And it matters little, after all. What I now affirm is, that I have a right to speak of these seas, under which, in less than ten months, I have crossed 20,000 leagues in that submarine tour of the world, which has revealed so many wonders. - -But what has become of the Nautilus? Did it resist the pressure of the maelstrom? Does Captain Nemo still live? And does he still follow under the ocean those frightful retaliations? Or, did he stop after the last hecatomb? - -Will the waves one day carry to him this manuscript containing the history of his life? Shall I ever know the name of this man? Will the missing vessel tell us by its nationality that of Captain Nemo? - -I hope so. And I also hope that his powerful vessel has conquered the sea at its most terrible gulf, and that the Nautilus has survived where so many other vessels have been lost! If it be so—if Captain Nemo still inhabits the ocean, his adopted country, may hatred be appeased in that savage heart! May the contemplation of so many wonders extinguish for ever the spirit of vengeance! May the judge disappear, and the philosopher continue the peaceful exploration of the sea! If his destiny be strange, it is also sublime. Have I not understood it myself? Have I not lived ten months of this unnatural life? And to the question asked by Ecclesiastes three thousand years ago, "That which is far off and exceeding deep, who can find it out?" two men alone of all now living have the right to give an answer—— - -CAPTAIN NEMO AND MYSELF. - - - - - - - - - - -End of the Project Gutenberg EBook of Twenty Thousand Leagues under the Sea, by -Jules Verne - -*** END OF THIS PROJECT GUTENBERG EBOOK 20000 LEAGUES UNDER THE SEA *** - -***** This file should be named 164-h.htm or 164-h.zip ***** -This and all associated files of various formats will be found in: - http://www.gutenberg.org/1/6/164/ - - - -Updated editions will replace the previous one--the old editions -will be renamed. - -Creating the works from public domain print editions means that no -one owns a United States copyright in these works, so the Foundation -(and you!) can copy and distribute it in the United States without -permission and without paying copyright royalties. Special rules, -set forth in the General Terms of Use part of this license, apply to -copying and distributing Project Gutenberg-tm electronic works to -protect the PROJECT GUTENBERG-tm concept and trademark. Project -Gutenberg is a registered trademark, and may not be used if you -charge for the eBooks, unless you receive specific permission. If you -do not charge anything for copies of this eBook, complying with the -rules is very easy. You may use this eBook for nearly any purpose -such as creation of derivative works, reports, performances and -research. They may be modified and printed and given away--you may do -practically ANYTHING with public domain eBooks. Redistribution is -subject to the trademark license, especially commercial -redistribution. - - - -*** START: FULL LICENSE *** - -THE FULL PROJECT GUTENBERG LICENSE -PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK - -To protect the Project Gutenberg-tm mission of promoting the free -distribution of electronic works, by using or distributing this work -(or any other work associated in any way with the phrase "Project -Gutenberg"), you agree to comply with all the terms of the Full Project -Gutenberg-tm License (available with this file or online at -http://gutenberg.net/license). - - -Section 1. General Terms of Use and Redistributing Project Gutenberg-tm -electronic works - -1.A. By reading or using any part of this Project Gutenberg-tm -electronic work, you indicate that you have read, understand, agree to -and accept all the terms of this license and intellectual property -(trademark/copyright) agreement. If you do not agree to abide by all -the terms of this agreement, you must cease using and return or destroy -all copies of Project Gutenberg-tm electronic works in your possession. -If you paid a fee for obtaining a copy of or access to a Project -Gutenberg-tm electronic work and you do not agree to be bound by the -terms of this agreement, you may obtain a refund from the person or -entity to whom you paid the fee as set forth in paragraph 1.E.8. - -1.B. "Project Gutenberg" is a registered trademark. It may only be -used on or associated in any way with an electronic work by people who -agree to be bound by the terms of this agreement. There are a few -things that you can do with most Project Gutenberg-tm electronic works -even without complying with the full terms of this agreement. See -paragraph 1.C below. There are a lot of things you can do with Project -Gutenberg-tm electronic works if you follow the terms of this agreement -and help preserve free future access to Project Gutenberg-tm electronic -works. See paragraph 1.E below. - -1.C. The Project Gutenberg Literary Archive Foundation ("the Foundation" -or PGLAF), owns a compilation copyright in the collection of Project -Gutenberg-tm electronic works. Nearly all the individual works in the -collection are in the public domain in the United States. If an -individual work is in the public domain in the United States and you are -located in the United States, we do not claim a right to prevent you from -copying, distributing, performing, displaying or creating derivative -works based on the work as long as all references to Project Gutenberg -are removed. Of course, we hope that you will support the Project -Gutenberg-tm mission of promoting free access to electronic works by -freely sharing Project Gutenberg-tm works in compliance with the terms of -this agreement for keeping the Project Gutenberg-tm name associated with -the work. You can easily comply with the terms of this agreement by -keeping this work in the same format with its attached full Project -Gutenberg-tm License when you share it without charge with others. - -1.D. The copyright laws of the place where you are located also govern -what you can do with this work. Copyright laws in most countries are in -a constant state of change. If you are outside the United States, check -the laws of your country in addition to the terms of this agreement -before downloading, copying, displaying, performing, distributing or -creating derivative works based on this work or any other Project -Gutenberg-tm work. The Foundation makes no representations concerning -the copyright status of any work in any country outside the United -States. - -1.E. Unless you have removed all references to Project Gutenberg: - -1.E.1. The following sentence, with active links to, or other immediate -access to, the full Project Gutenberg-tm License must appear prominently -whenever any copy of a Project Gutenberg-tm work (any work on which the -phrase "Project Gutenberg" appears, or with which the phrase "Project -Gutenberg" is associated) is accessed, displayed, performed, viewed, -copied or distributed: - -This eBook is for the use of anyone anywhere at no cost and with -almost no restrictions whatsoever. You may copy it, give it away or -re-use it under the terms of the Project Gutenberg License included -with this eBook or online at www.gutenberg.net - -1.E.2. If an individual Project Gutenberg-tm electronic work is derived -from the public domain (does not contain a notice indicating that it is -posted with permission of the copyright holder), the work can be copied -and distributed to anyone in the United States without paying any fees -or charges. If you are redistributing or providing access to a work -with the phrase "Project Gutenberg" associated with or appearing on the -work, you must comply either with the requirements of paragraphs 1.E.1 -through 1.E.7 or obtain permission for the use of the work and the -Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or -1.E.9. - -1.E.3. If an individual Project Gutenberg-tm electronic work is posted -with the permission of the copyright holder, your use and distribution -must comply with both paragraphs 1.E.1 through 1.E.7 and any additional -terms imposed by the copyright holder. Additional terms will be linked -to the Project Gutenberg-tm License for all works posted with the -permission of the copyright holder found at the beginning of this work. - -1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm -License terms from this work, or any files containing a part of this -work or any other work associated with Project Gutenberg-tm. - -1.E.5. Do not copy, display, perform, distribute or redistribute this -electronic work, or any part of this electronic work, without -prominently displaying the sentence set forth in paragraph 1.E.1 with -active links or immediate access to the full terms of the Project -Gutenberg-tm License. - -1.E.6. You may convert to and distribute this work in any binary, -compressed, marked up, nonproprietary or proprietary form, including any -word processing or hypertext form. However, if you provide access to or -distribute copies of a Project Gutenberg-tm work in a format other than -"Plain Vanilla ASCII" or other format used in the official version -posted on the official Project Gutenberg-tm web site (www.gutenberg.net), -you must, at no additional cost, fee or expense to the user, provide a -copy, a means of exporting a copy, or a means of obtaining a copy upon -request, of the work in its original "Plain Vanilla ASCII" or other -form. Any alternate format must include the full Project Gutenberg-tm -License as specified in paragraph 1.E.1. - -1.E.7. Do not charge a fee for access to, viewing, displaying, -performing, copying or distributing any Project Gutenberg-tm works -unless you comply with paragraph 1.E.8 or 1.E.9. - -1.E.8. You may charge a reasonable fee for copies of or providing -access to or distributing Project Gutenberg-tm electronic works provided -that - -- You pay a royalty fee of 20% of the gross profits you derive from - the use of Project Gutenberg-tm works calculated using the method - you already use to calculate your applicable taxes. The fee is - owed to the owner of the Project Gutenberg-tm trademark, but he - has agreed to donate royalties under this paragraph to the - Project Gutenberg Literary Archive Foundation. Royalty payments - must be paid within 60 days following each date on which you - prepare (or are legally required to prepare) your periodic tax - returns. Royalty payments should be clearly marked as such and - sent to the Project Gutenberg Literary Archive Foundation at the - address specified in Section 4, "Information about donations to - the Project Gutenberg Literary Archive Foundation." - -- You provide a full refund of any money paid by a user who notifies - you in writing (or by e-mail) within 30 days of receipt that s/he - does not agree to the terms of the full Project Gutenberg-tm - License. You must require such a user to return or - destroy all copies of the works possessed in a physical medium - and discontinue all use of and all access to other copies of - Project Gutenberg-tm works. - -- You provide, in accordance with paragraph 1.F.3, a full refund of any - money paid for a work or a replacement copy, if a defect in the - electronic work is discovered and reported to you within 90 days - of receipt of the work. - -- You comply with all other terms of this agreement for free - distribution of Project Gutenberg-tm works. - -1.E.9. If you wish to charge a fee or distribute a Project Gutenberg-tm -electronic work or group of works on different terms than are set -forth in this agreement, you must obtain permission in writing from -both the Project Gutenberg Literary Archive Foundation and Michael -Hart, the owner of the Project Gutenberg-tm trademark. Contact the -Foundation as set forth in Section 3 below. - -1.F. - -1.F.1. Project Gutenberg volunteers and employees expend considerable -effort to identify, do copyright research on, transcribe and proofread -public domain works in creating the Project Gutenberg-tm -collection. Despite these efforts, Project Gutenberg-tm electronic -works, and the medium on which they may be stored, may contain -"Defects," such as, but not limited to, incomplete, inaccurate or -corrupt data, transcription errors, a copyright or other intellectual -property infringement, a defective or damaged disk or other medium, a -computer virus, or computer codes that damage or cannot be read by -your equipment. - -1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right -of Replacement or Refund" described in paragraph 1.F.3, the Project -Gutenberg Literary Archive Foundation, the owner of the Project -Gutenberg-tm trademark, and any other party distributing a Project -Gutenberg-tm electronic work under this agreement, disclaim all -liability to you for damages, costs and expenses, including legal -fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT -LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE -PROVIDED IN PARAGRAPH F3. YOU AGREE THAT THE FOUNDATION, THE -TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE -LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR -INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH -DAMAGE. - -1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a -defect in this electronic work within 90 days of receiving it, you can -receive a refund of the money (if any) you paid for it by sending a -written explanation to the person you received the work from. If you -received the work on a physical medium, you must return the medium with -your written explanation. The person or entity that provided you with -the defective work may elect to provide a replacement copy in lieu of a -refund. If you received the work electronically, the person or entity -providing it to you may choose to give you a second opportunity to -receive the work electronically in lieu of a refund. If the second copy -is also defective, you may demand a refund in writing without further -opportunities to fix the problem. - -1.F.4. Except for the limited right of replacement or refund set forth -in paragraph 1.F.3, this work is provided to you 'AS-IS' WITH NO OTHER -WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE. - -1.F.5. Some states do not allow disclaimers of certain implied -warranties or the exclusion or limitation of certain types of damages. -If any disclaimer or limitation set forth in this agreement violates the -law of the state applicable to this agreement, the agreement shall be -interpreted to make the maximum disclaimer or limitation permitted by -the applicable state law. The invalidity or unenforceability of any -provision of this agreement shall not void the remaining provisions. - -1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the -trademark owner, any agent or employee of the Foundation, anyone -providing copies of Project Gutenberg-tm electronic works in accordance -with this agreement, and any volunteers associated with the production, -promotion and distribution of Project Gutenberg-tm electronic works, -harmless from all liability, costs and expenses, including legal fees, -that arise directly or indirectly from any of the following which you do -or cause to occur: (a) distribution of this or any Project Gutenberg-tm -work, (b) alteration, modification, or additions or deletions to any -Project Gutenberg-tm work, and (c) any Defect you cause. - - -Section 2. Information about the Mission of Project Gutenberg-tm - -Project Gutenberg-tm is synonymous with the free distribution of -electronic works in formats readable by the widest variety of computers -including obsolete, old, middle-aged and new computers. It exists -because of the efforts of hundreds of volunteers and donations from -people in all walks of life. - -Volunteers and financial support to provide volunteers with the -assistance they need, is critical to reaching Project Gutenberg-tm's -goals and ensuring that the Project Gutenberg-tm collection will -remain freely available for generations to come. In 2001, the Project -Gutenberg Literary Archive Foundation was created to provide a secure -and permanent future for Project Gutenberg-tm and future generations. -To learn more about the Project Gutenberg Literary Archive Foundation -and how your efforts and donations can help, see Sections 3 and 4 -and the Foundation web page at http://www.pglaf.org. - - -Section 3. Information about the Project Gutenberg Literary Archive -Foundation - -The Project Gutenberg Literary Archive Foundation is a non profit -501(c)(3) educational corporation organized under the laws of the -state of Mississippi and granted tax exempt status by the Internal -Revenue Service. The Foundation's EIN or federal tax identification -number is 64-6221541. Its 501(c)(3) letter is posted at -http://pglaf.org/fundraising. Contributions to the Project Gutenberg -Literary Archive Foundation are tax deductible to the full extent -permitted by U.S. federal laws and your state's laws. - -The Foundation's principal office is located at 4557 Melan Dr. S. -Fairbanks, AK, 99712., but its volunteers and employees are scattered -throughout numerous locations. Its business office is located at -809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887, email -business@pglaf.org. Email contact links and up to date contact -information can be found at the Foundation's web site and official -page at http://pglaf.org - -For additional contact information: - Dr. Gregory B. Newby - Chief Executive and Director - gbnewby@pglaf.org - - -Section 4. Information about Donations to the Project Gutenberg -Literary Archive Foundation - -Project Gutenberg-tm depends upon and cannot survive without wide -spread public support and donations to carry out its mission of -increasing the number of public domain and licensed works that can be -freely distributed in machine readable form accessible by the widest -array of equipment including outdated equipment. Many small donations -($1 to $5,000) are particularly important to maintaining tax exempt -status with the IRS. - -The Foundation is committed to complying with the laws regulating -charities and charitable donations in all 50 states of the United -States. Compliance requirements are not uniform and it takes a -considerable effort, much paperwork and many fees to meet and keep up -with these requirements. We do not solicit donations in locations -where we have not received written confirmation of compliance. To -SEND DONATIONS or determine the status of compliance for any -particular state visit http://pglaf.org - -While we cannot and do not solicit contributions from states where we -have not met the solicitation requirements, we know of no prohibition -against accepting unsolicited donations from donors in such states who -approach us with offers to donate. - -International donations are gratefully accepted, but we cannot make -any statements concerning tax treatment of donations received from -outside the United States. U.S. laws alone swamp our small staff. - -Please check the Project Gutenberg Web pages for current donation -methods and addresses. Donations are accepted in a number of other -ways including including checks, online payments and credit card -donations. To donate, please visit: http://pglaf.org/donate - - -Section 5. General Information About Project Gutenberg-tm electronic -works. - -Professor Michael S. Hart is the originator of the Project Gutenberg-tm -concept of a library of electronic works that could be freely shared -with anyone. For thirty years, he produced and distributed Project -Gutenberg-tm eBooks with only a loose network of volunteer support. - - -Project Gutenberg-tm eBooks are often created from several printed -editions, all of which are confirmed as Public Domain in the U.S. -unless a copyright notice is included. Thus, we do not necessarily -keep eBooks in compliance with any particular paper edition. - - -Most people start at our Web site which has the main PG search facility: - - http://www.gutenberg.net - -This Web site includes information about Project Gutenberg-tm, -including how to make donations to the Project Gutenberg Literary -Archive Foundation, how to help produce our new eBooks, and how to -subscribe to our email newsletter to hear about new eBooks. - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/run.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/run.js deleted file mode 100644 index 77cc3927ed1..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/benchmark/run.js +++ /dev/null @@ -1,85 +0,0 @@ -var mimelib = require("../index"), - longTextSource = require("fs").readFileSync(__dirname + "/20000.txt"), - textLength = longTextSource.length, - longText = longTextSource.toString("utf-8").replace(/\r?\n|\r/g, "\r\n"), - encoded, decoded; - - -console.log("Benchmarking Quoted Printable encoding/decoding speed"); -console.log("====================================================="); -console.log(""); -console.log("Encoding..."); -var encodeStart = Date.now(); -encoded = mimelib.encodeQuotedPrintable(longText); -var encodeEnd = Date.now(); -var encodeTime = (encodeEnd - encodeStart)/1000; - -console.log("Decoding..."); -var decodeStart = Date.now(); -decoded = mimelib.decodeQuotedPrintable(encoded); -var decodeEnd = Date.now(); -var decodeTime = (decodeEnd - decodeStart)/1000; -console.log("Ready."); -console.log(""); -console.log("Results:"); -console.log("--------"); -console.log("Source file size: " + textLength + " bytes"); -console.log("Encoded file size: " + encoded.length+ " bytes"); -console.log("Decoded == Source: " + (decoded == longText?"Yes":"No")); -console.log("Encoding speed: " + encodeTime + " sec. ("+((textLength/encodeTime)/1024)+" kbytes/sec.)"); -console.log("Decoding speed: " + decodeTime + " sec. ("+((encoded.length/decodeTime)/1024)+" kbytes/sec.)"); - -console.log(""); -console.log(""); - -console.log("Benchmarking Quoted Printable non utf-8 speed"); -console.log("============================================="); -console.log(""); -console.log("Encoding..."); -var encodeStart = Date.now(); -encoded = mimelib.encodeQuotedPrintable(longText, false, "latin-13"); -var encodeEnd = Date.now(); -var encodeTime = (encodeEnd - encodeStart)/1000; - -console.log("Decoding..."); -var decodeStart = Date.now(); -decoded = mimelib.decodeQuotedPrintable(encoded, false, "latin-13"); -var decodeEnd = Date.now(); -var decodeTime = (decodeEnd - decodeStart)/1000; -console.log("Ready."); -console.log(""); -console.log("Results:"); -console.log("--------"); -console.log("Source file size: " + textLength + " bytes"); -console.log("Encoded file size: " + encoded.length+ " bytes"); -console.log("Decoded == Source: " + (decoded == longText?"Yes":"No")+" (\"No\" is OK)"); -console.log("Encoding speed: " + encodeTime + " sec. ("+((textLength/encodeTime)/1024)+" kbytes/sec.)"); -console.log("Decoding speed: " + decodeTime + " sec. ("+((encoded.length/decodeTime)/1024)+" kbytes/sec.)"); - -console.log(""); -console.log(""); - -console.log("Benchmarking Base64 encoding/decoding speed"); -console.log("====================================================="); -console.log(""); -console.log("Encoding..."); -var encodeStart = Date.now(); -encoded = mimelib.encodeBase64(longText); -var encodeEnd = Date.now(); -var encodeTime = (encodeEnd - encodeStart)/1000; - -console.log("Decoding..."); -var decodeStart = Date.now(); -decoded = mimelib.decodeBase64(encoded); -var decodeEnd = Date.now(); -var decodeTime = (decodeEnd - decodeStart)/1000; -console.log("Ready."); -console.log(""); - -console.log("Results:"); -console.log("--------"); -console.log("Source file size: " + textLength + " bytes"); -console.log("Encoded file size: " + encoded.length+ " bytes"); -console.log("Decoded == Source: " + (decoded == longText?"Yes":"No")); -console.log("Encoding speed: " + encodeTime + " sec. ("+((textLength/encodeTime)/1024)+" kbytes/sec.)"); -console.log("Decoding speed: " + decodeTime + " sec. ("+((encoded.length/decodeTime)/1024)+" kbytes/sec.)"); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/index.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/index.js deleted file mode 100644 index 168c72b5bc8..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = require("./lib/mimelib"); -module.exports.contentTypes = require("./lib/content-types"); -module.exports.contentTypesReversed = require("./lib/content-types-reversed"); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types-reversed.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types-reversed.js deleted file mode 100644 index 77802f77ab9..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types-reversed.js +++ /dev/null @@ -1,40 +0,0 @@ -// list of mime types -module.exports = { - "application/msword": "doc", - "application/pdf": "pdf", - "application/rss+xml": "rss", - "application/vnd.ms-excel": "xls", - "application/vnd.ms-powerpoint": "ppt", - "application/vnd.oasis.opendocument.presentation": "odp", - "application/vnd.oasis.opendocument.spreadsheet": "ods", - "application/vnd.oasis.opendocument.text": "odt", - "application/vnd.sun.xml.calc": "sxc", - "application/vnd.sun.xml.writer": "sxw", - "audio/basic": "au", - "audio/flac": "flac", - "audio/mid": "mid", - "audio/mp4": "m4a", - "audio/mpeg": "mp3", - "audio/ogg": "ogg", - "audio/x-aiff": "aif", - "audio/x-wav": "wav", - "image/gif": "gif", - "image/jpeg": "jpg", - "image/png": "png", - "image/tiff": "tif", - "image/vnd.wap.wbmp": "wbmp", - "image/x-ms-bmp": "bmp", - "text/calendar": "ics", - "text/comma-separated-values": "csv", - "text/css": "css", - "text/html": "html", - "text/plain": "txt", - "text/x-vcard": "vcf", - "video/mp4": "mp4", - "video/mpeg": "mpeg", - "video/ogg": "ogv", - "video/quicktime": "mov", - "video/x-msvideo": "avi", - "application/zip": "zip", - "application/x-rar-compressed": "rar" -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types.js deleted file mode 100644 index cbf0d800a87..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/content-types.js +++ /dev/null @@ -1,60 +0,0 @@ -// list of mime types -module.exports = { - "doc": "application/msword", - "docx": "application/msword", - "pdf": "application/pdf", - "rss": "application/rss+xml", - "xls": "application/vnd.ms-excel", - "xlsx": "application/vnd.ms-excel", - "pps": "application/vnd.ms-powerpoint", - "ppt": "application/vnd.ms-powerpoint", - "pptx": "application/vnd.ms-powerpoint", - "odp": "application/vnd.oasis.opendocument.presentation", - "ods": "application/vnd.oasis.opendocument.spreadsheet", - "odt": "application/vnd.oasis.opendocument.text", - "sxc": "application/vnd.sun.xml.calc", - "sxw": "application/vnd.sun.xml.writer", - "au": "audio/basic", - "snd": "audio/basic", - "flac": "audio/flac", - "mid": "audio/mid", - "rmi": "audio/mid", - "m4a": "audio/mp4", - "mp3": "audio/mpeg", - "oga": "audio/ogg", - "ogg": "audio/ogg", - "aif": "audio/x-aiff", - "aifc": "audio/x-aiff", - "aiff": "audio/x-aiff", - "wav": "audio/x-wav", - "gif": "image/gif", - "jpeg": "image/jpeg", - "jpg": "image/jpeg", - "jpe": "image/jpeg", - "png": "image/png", - "tiff": "image/tiff", - "tif": "image/tiff", - "wbmp": "image/vnd.wap.wbmp", - "bmp": "image/x-ms-bmp", - "ics": "text/calendar", - "csv": "text/comma-separated-values", - "css": "text/css", - "htm": "text/html", - "html": "text/html", - "text": "text/plain", - "txt": "text/plain", - "asc": "text/plain", - "diff": "text/plain", - "pot": "text/plain", - "vcf": "text/x-vcard", - "mp4": "video/mp4", - "mpeg": "video/mpeg", - "mpg": "video/mpeg", - "mpe": "video/mpeg", - "ogv": "video/ogg", - "qt": "video/quicktime", - "mov": "video/quicktime", - "avi": "video/x-msvideo", - "zip": "application/zip", - "rar": "application/x-rar-compressed" -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/mimelib.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/mimelib.js deleted file mode 100644 index 79adee7c4a4..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/lib/mimelib.js +++ /dev/null @@ -1,571 +0,0 @@ -var convert = require("encoding").convert, - addressparser = require("addressparser"); - -/** - * Folds a long line according to the RFC 5322 http://tools.ietf.org/html/rfc5322#section-2.1.1 - * - * @param {String} str Mime string that might need folding - * @param {Number} [maxLength=76] max length for a line - * @param {Boolean} [foldAnywhere] If true, can fold at any location (ie. in base64) - * @param {Boolean} [afterSpace] If true fold after the space (default is before) - * @return {String} Folded string - */ -this.foldLine = function(str, maxLength, foldAnywhere, afterSpace, lineMargin){ - if(foldAnywhere){ - return addBase64SoftLinebreaks(str, maxLength || 76); - } - return module.exports.mimeFunctions.foldLine(str, maxLength, !!afterSpace, lineMargin); -}; - -/** - * Encodes a string into mime encoded word format http://en.wikipedia.org/wiki/MIME#Encoded-Word - * - * @param {String} str String to be encoded - * @param {String} encoding Encoding Q for quoted printable or B for base64 - * @param {String} [charset="UTF-8"] Charset to be used - * @param {Number} [maxLength] If set, split on maxLength - * @return {String} Mime word encoded string - */ -module.exports.encodeMimeWord = function(str, encoding, charset, maxLength){ - return module.exports.mimeFunctions.encodeMimeWord(str, encoding, maxLength || 0, charset); -}; - -/** - * Encodes need parts of a string to mime word format - * - * @param {String} str String to be encoded - * @param {String} encoding Encoding Q for quoted printable or B for base64 - * @param {Number} [maxLength] If set, split on maxLength - * @param {String} [charset="UTF-8"] Charset to be used - * @return {String} String with possible mime word encoded parts - */ -module.exports.encodeMimeWords = function(str, encoding, maxLength, charset){ - return module.exports.mimeFunctions.encodeMimeWords(str, encoding, maxLength || 0, charset); -}; - -/** - * Decodes a string from mime encoded word - * - * @param {String} str Mime word encoded string - * @return {String} Decoded string - */ -module.exports.decodeMimeWord = function(str){ - return module.exports.mimeFunctions.decodeMimeWord(str).toString("utf-8"); -}; - -/** - * Decodes all mime words from a string to an unencoded string - * - * @param {String} str String that may include mime words - * @return {String} Unencoded string - */ -module.exports.parseMimeWords = function(str){ - return module.exports.mimeFunctions.decodeMimeWords(str).toString("utf-8"); -}; - -/** - * Encodes a string into Quoted-printable format. Maximum line length for the - * encoded string is always 76+2 bytes - * - * @param {String} str String to be encoded into Quoted-printable - * @param {Boolean} [mimeWord] legacy parameter, not used - * @param {String} [charset="UTF-8"] Destination charset - * @return {String} Quoted printable encoded string - */ -module.exports.encodeQuotedPrintable = function(str, mimeWord, charset){ - if(typeof mimeWord == "string" && !charset){ - charset = mimeWord; - mimeWord = undefined; - } - return module.exports.mimeFunctions.encodeQuotedPrintable(str, charset); -}; - -/** - * Decodes a string from Quoted-printable format - * - * @param {String} str String to be decoded from Quoted-printable - * @param {Boolean} [mimeWord] legacy parameter, not used - * @param {String} [charset="UTF-8"] Source charset - * @return {String} Decoded string - */ -module.exports.decodeQuotedPrintable = function(str, mimeWord, charset){ - if(typeof mimeWord == "string" && !charset){ - charset = mimeWord; - mimeWord = undefined; - } - charset = (charset || "").toString().toUpperCase().trim(); - var decodedString = module.exports.mimeFunctions.decodeQuotedPrintable(str, "utf-8", charset); - return charset == "BINARY" ? decodedString : decodedString.toString("utf-8"); -}; - -/** - * Encodes a string into Base64 format. Base64 is mime-word safe - * - * @param {String} str String to be encoded into Base64 - * @param {String} [charset="UTF-8"] Destination charset - * @return {String} Base64 encoded string - */ -module.exports.encodeBase64 = function(str, charset){ - return module.exports.mimeFunctions.encodeBase64(str, charset); -}; - -/** - * Decodes a string from Base64 format - * - * @param {String} str String to be decoded from Base64 - * @param {String} [charset="UTF-8"] Source charset - * @return {String} Decoded string - */ -module.exports.decodeBase64 = function(str, charset){ - return module.exports.mimeFunctions.decodeBase64(str, "utf-8", charset).toString("utf-8"); -}; - -/** - * Parses names and addresses from a from, to, cc or bcc line - * For example: 'Andris Reinman , someone@else.com' - * will be parsed into: [{name:"Andris Reinman", address:"andris@tr.ee"}, {address: "someone@else.com"}] - * - * @param {String|Array} addresses Address line string or an array of strings - * @return {Array} An array of parsed e-mails addresses in the form of [{name, address}] - */ -module.exports.parseAddresses = function(addresses){ - return [].concat.apply([], [].concat(addresses).map(addressparser)).map(function(address){ - address.name = module.exports.parseMimeWords(address.name); - return address; - }); -}; - -/** - * Parses header lines into an array of objects. Output: {'x-header': ['value']} - * - * @param {String} headers Full header part to be parsed - * @return {Object} Parsed headers - */ -module.exports.parseHeaders = function(headers){ - return module.exports.mimeFunctions.parseHeaderLines(headers); -}; - -/** - * Parses a header line to search for additional parameters. For example - * parseHeaderLine('text/plain; charset=utf-8') - * will be parsed into - * {defaultValue: 'text/plain', charset: 'utf-8'} - * - * @param {String} line Single header value without key part to be parsed - * @return {Object} Parsed value - */ -module.exports.parseHeaderLine = function(line){ - if(!line) - return {}; - var result = {}, parts = line.split(";"), pos; - for(var i=0, len = parts.length; i 7 + toCharset.length){ - maxLength -= (7 + toCharset.length); - } - - if(encoding == "Q"){ - encodedStr = this.mimeEncode(str, toCharset, fromCharset); - encodedStr = encodedStr.replace(/[\r\n\t_]/g, function(chr){ - var code = chr.charCodeAt(0); - return "=" + (code<0x10?"0":"") + code.toString(16).toUpperCase(); - }).replace(/\s/g, "_"); - }else if(encoding == "B"){ - encodedStr = convert(str || "", toCharset, fromCharset).toString("base64").trim(); - } - - if(maxLength && encodedStr.length > maxLength){ - if(encoding == "Q"){ - encodedStr = this.splitEncodedString(encodedStr, maxLength).join("?= =?"+toCharset+"?"+encoding+"?"); - }else{ - encodedStr = encodedStr.replace(new RegExp(".{"+maxLength+"}","g"),"$&?= =?"+toCharset+"?"+encoding+"?"); - if(encodedStr.substr(-(" =?"+toCharset+"?"+encoding+"?=").length) == " =?"+toCharset+"?"+encoding+"?="){ - encodedStr = encodedStr.substr(0, encodedStr.length -(" =?"+toCharset+"?"+encoding+"?=").length); - } - if(encodedStr.substr(-(" =?"+toCharset+"?"+encoding+"?").length) == " =?"+toCharset+"?"+encoding+"?"){ - encodedStr = encodedStr.substr(0, encodedStr.length -(" =?"+toCharset+"?"+encoding+"?").length); - } - } - } - - return "=?"+toCharset+"?"+encoding+"?"+encodedStr+ (encodedStr.substr(-2)=="?="?"":"?="); - }, - - decodeMimeWord: function(str, toCharset){ - str = (str || "").toString().trim(); - - var fromCharset, encoding, match; - - match = str.match(/^\=\?([\w_\-]+)\?([QqBb])\?([^\?]+)\?\=$/i); - if(!match){ - return convert(str, toCharset); - } - - fromCharset = match[1]; - encoding = (match[2] || "Q").toString().toUpperCase(); - str = (match[3] || "").replace(/_/g, " "); - - if(encoding == "B"){ - return this.decodeBase64(str, toCharset, fromCharset); - }else if(encoding == "Q"){ - return this.mimeDecode(str, toCharset, fromCharset); - }else{ - return str; - } - - - }, - - decodeMimeWords: function(str, toCharset){ - var remainder = "", lastCharset, curCharset; - str = (str || "").toString(); - - str = str. - replace(/(=\?[^?]+\?[QqBb]\?[^?]+\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]+\?=)/g, "$1"). - replace(/\=\?([\w_\-]+)\?([QqBb])\?[^\?]+\?\=/g, (function(mimeWord, charset, encoding){ - - curCharset = charset + encoding; - - return this.decodeMimeWord(mimeWord); - }).bind(this)); - - return convert(str, toCharset); - }, - - foldLine: function(str, lineLengthMax, afterSpace, lineMargin){ - lineLengthMax = lineLengthMax || 76; - lineMargin = lineMargin || Math.floor(lineLengthMax/5); - str = (str || "").toString().trim(); - - var pos = 0, len = str.length, result = "", line, match; - - while(pos < len){ - line = str.substr(pos, lineLengthMax); - if(line.length < lineLengthMax){ - result += line; - break; - } - if((match = line.match(/^[^\n\r]*(\r?\n|\r)/))){ - line = match[0]; - result += line; - pos += line.length; - continue; - }else if((match = line.substr(-lineMargin).match(/(\s+)[^\s]*$/))){ - line = line.substr(0, line.length - (match[0].length - (!!afterSpace ? (match[1] || "").length : 0))); - }else if((match = str.substr(pos + line.length).match(/^[^\s]+(\s*)/))){ - line = line + match[0].substr(0, match[0].length - (!afterSpace ? (match[1] || "").length : 0)); - } - result += line; - pos += line.length; - if(pos < len){ - result += "\r\n"; - } - } - - return result; - }, - - encodeMimeWords: function(value, encoding, maxLength, toCharset, fromCharset){ - var decodedValue = convert((value || ""), "utf-8", fromCharset).toString("utf-8"), - encodedValue; - - encodedValue = decodedValue.replace(/([^\s\u0080-\uFFFF]*[\u0080-\uFFFF]+[^\s\u0080-\uFFFF]*(?:\s+[^\s\u0080-\uFFFF]*[\u0080-\uFFFF]+[^\s\u0080-\uFFFF]*\s*)?)+/g, (function(str, o){ - return str.length?this.encodeMimeWord(str, encoding || "Q", maxLength, toCharset):""; - }).bind(this)); - - return encodedValue; - }, - - encodeHeaderLine: function(key, value, toCharset, fromCharset){ - var encodedValue = this.encodeMimeWords(value, 52, toCharset, fromCharset); - return this.foldLine(key+": "+encodedValue, 76); - }, - - parseHeaderLines: function(headers, toCharset){ - var lines = headers.split(/\r?\n|\r/), - headersObj = {}, - key, value, - header, - i, len; - - for(i=lines.length-1; i>=0; i--){ - if(i && lines[i].match(/^\s/)){ - lines[i-1] += "\r\n" + lines[i]; - lines.splice(i, 1); - } - } - - for(i=0, len = lines.length; i 0x7F){ - curLine = curLine.substr(0, curLine.length-3); - done = false; - } - } - } - - if(curLine.length){ - lines.push(curLine); - } - str = str.substr(curLine.length); - } - - return lines; - }, - - parseAddresses: addressparser - -}; - -// Lines can't be longer that 76 + = 78 bytes -// http://tools.ietf.org/html/rfc2045#section-6.7 -function addSoftLinebreaks(str, encoding){ - var lineLengthMax = 76; - - encoding = (encoding || "base64").toString().toLowerCase().trim(); - - if(encoding == "qp"){ - return addQPSoftLinebreaks(str, lineLengthMax); - }else{ - return addBase64SoftLinebreaks(str, lineLengthMax); - } -} - -function addBase64SoftLinebreaks(base64EncodedStr, lineLengthMax){ - base64EncodedStr = (base64EncodedStr || "").toString().trim(); - return base64EncodedStr.replace(new RegExp(".{" +lineLengthMax+ "}", "g"),"$&\r\n").trim(); -} - -function addQPSoftLinebreaks(mimeEncodedStr, lineLengthMax){ - var pos = 0, len = mimeEncodedStr.length, - match, code, line, - lineMargin = Math.floor(lineLengthMax/3), - result = ""; - - // insert soft linebreaks where needed - while(pos < len){ - line = mimeEncodedStr.substr(pos, lineLengthMax); - if((match = line.match(/\r\n/))){ - line = line.substr(0, match.index + match[0].length); - result += line; - pos += line.length; - continue; - } - - if(line.substr(-1)=="\n"){ - // nothing to change here - result += line; - pos += line.length; - continue; - }else if((match = line.substr(-lineMargin).match(/\n.*?$/))){ - // truncate to nearest line break - line = line.substr(0, line.length - (match[0].length - 1)); - result += line; - pos += line.length; - continue; - }else if(line.length > lineLengthMax - lineMargin && (match = line.substr(-lineMargin).match(/[ \t\.,!\?][^ \t\.,!\?]*$/))){ - // truncate to nearest space - line = line.substr(0, line.length - (match[0].length - 1)); - }else if(line.substr(-1)=="\r"){ - line = line.substr(0, line.length-1); - }else{ - if(line.match(/\=[\da-f]{0,2}$/i)){ - - // push incomplete encoding sequences to the next line - if((match = line.match(/\=[\da-f]{0,1}$/i))){ - line = line.substr(0, line.length - match[0].length); - } - - // ensure that utf-8 sequences are not split - while(line.length>3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/\=[\da-f]{2}$/ig))){ - code = parseInt(match[0].substr(1,2), 16); - if(code<128){ - break; - } - - line = line.substr(0, line.length-3); - - if(code >=0xC0){ - break; - } - } - - } - } - - if(pos + line.length < len && line.substr(-1)!="\n"){ - if(line.length==76 && line.match(/\=[\da-f]{2}$/i)){ - line = line.substr(0, line.length-3); - } - else if(line.length==76){ - line = line.substr(0, line.length-1); - } - pos += line.length; - line += "=\r\n"; - }else{ - pos += line.length; - } - - result += line; - } - - return result; -} - -function checkRanges(nr, ranges){ - for(var i = ranges.length - 1; i >= 0; i--){ - if(!ranges[i].length){ - continue; - } - if(ranges[i].length == 1 && nr == ranges[i][0]){ - return true; - } - if(ranges[i].length == 2 && nr >= ranges[i][0] && nr <= ranges[i][1]){ - return true; - } - } - return false; -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/.npmignore b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/.npmignore deleted file mode 100644 index b512c09d476..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/README.md deleted file mode 100644 index 6ee824934ab..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# addressparser - -Parse e-mail address fields - -## Installation - -Install with npm - - npm install addressparser - -## Usage - -Include the module - - var addressparser = require("addressparser"); - -Parse some address strings with addressparser(field) - - var addresses = addressparser("andris "); - console.log(addresses); // [{name: "andris", address:"andris@tr.ee"}] - -Even complex address fields are supported - - addressparser('"Bach, Sebastian" , mozart@example.com (Mozzie)'); - // [{name: "Bach, Sebastian", address: "sebu@example.com"}, - // {name: "Mozzie", address: "mozart@example.com"}] - - addressparser("Music Group: sebu@example.com, mozart@example.com;"); - // [{name: "Music Group", address: "sebu@example.com"}, - // {name: "Music Group", address: "mozart@example.com"}] - -## Notes - - * **NB!** this module does not decode any mime-word or punycode encoded strings, it is only a basic parser for parsing the base data, you need to decode the encoded parts later by yourself - -## License - -**MIT** \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/index.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/index.js deleted file mode 100644 index 444d28fdb2a..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/index.js +++ /dev/null @@ -1,282 +0,0 @@ - -// expose to the world -module.exports = parser; - -/** - * Parses structured e-mail addresses from an address field - * - * Example: - * - * "Name " - * - * will be converted to - * - * [{name: "Name", address: "address@domain"}] - * - * @param {String} str Address field - * @return {Array} An array of address objects - */ -function parser(str){ - var tokenizer = new Tokenizer(str), - tokens = tokenizer.tokenize(); - - - var addresses = [], - address = [], - parsedAddresses = []; - - tokens.forEach(function(token){ - if(token.type == "operator" && (token.value =="," || token.value ==";")){ - addresses.push(address); - address = []; - }else{ - address.push(token); - } - }); - - if(address.length){ - addresses.push(address); - } - - addresses.forEach(function(address){ - address = handleAddress(address); - if(address.length){ - parsedAddresses = parsedAddresses.concat(address); - } - }); - - return parsedAddresses; -} - -/** - * Converts tokens for a single address into an address object - * - * @param {Array} tokens Tokens object - * @return {Object} Address object - */ -function handleAddress(tokens){ - var token, - isGroup = false, - state = "text", - address, - addresses = [], - data = { - address: [], - comment: [], - group: [], - text: [] - }, - i, len; - - // Filter out , (comments) and regular text - for(i=0, len = tokens.length; i=0; i--){ - if(data.text[i].match(/^[^@\s]+@[^@\s]+$/)){ - data.address = data.text.splice(i,1); - break; - } - } - - // still no address - if(!data.address.length){ - for(i = data.text.length - 1; i>=0; i--){ - data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, function(address){ - if(!data.address.length){ - data.address = [address.trim()]; - return " "; - }else{ - return address; - } - }).trim(); - if(data.address.length){ - break; - } - } - } - } - - // If there's still is no text but a comment exixts, replace the two - if(!data.text.length && data.comment.length){ - data.text = data.comment; - data.comment = []; - } - - // Keep only the first address occurence, push others to regular text - if(data.address.length > 1){ - data.text = data.text.concat(data.address.splice(1)); - } - - // Join values with spaces - data.text = data.text.join(" "); - data.address = data.address.join(" "); - - if(!data.address && isGroup){ - return []; - }else{ - address = { - address: data.address || data.text || "", - name: data.text || data.address || "" - }; - - if(address.address == address.name){ - if((address.address || "").match(/@/)){ - address.name = ""; - }else{ - address.address = ""; - } - - } - - addresses.push(address); - } - } - - return addresses; -} - - -/** - * Creates a TOkenizer object for tokenizing address field strings - * - * @constructor - * @param {String} str Address field string - */ -function Tokenizer(str){ - - this.str = (str || "").toString(); - this.operatorCurrent = ""; - this.operatorExpecting = ""; - this.node = null; - this.escaped = false; - - this.list = []; - -} - -/** - * Operator tokens and which tokens are expected to end the sequence - */ -Tokenizer.prototype.operators = { - "\"": "\"", - "(": ")", - "<": ">", - ",": "", - ":": ";" -}; - -/** - * Tokenizes the original input string - * - * @return {Array} An array of operator|text tokens - */ -Tokenizer.prototype.tokenize = function(){ - var chr, list = []; - for(var i=0, len = this.str.length; i\");\n console.log(addresses); // [{name: \"andris\", address:\"andris@tr.ee\"}]\n\nEven complex address fields are supported\n\n addressparser('\"Bach, Sebastian\" , mozart@example.com (Mozzie)');\n // [{name: \"Bach, Sebastian\", address: \"sebu@example.com\"},\n // {name: \"Mozzie\", address: \"mozart@example.com\"}]\n\n addressparser(\"Music Group: sebu@example.com, mozart@example.com;\");\n // [{name: \"Music Group\", address: \"sebu@example.com\"},\n // {name: \"Music Group\", address: \"mozart@example.com\"}]\n\n## Notes\n\n * **NB!** this module does not decode any mime-word or punycode encoded strings, it is only a basic parser for parsing the base data, you need to decode the encoded parts later by yourself\n\n## License\n\n**MIT**", - "readmeFilename": "README.md", - "_id": "addressparser@0.1.3", - "_from": "addressparser@~0.1" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/test.js deleted file mode 100644 index c2b33a69885..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/addressparser/test.js +++ /dev/null @@ -1,71 +0,0 @@ -var testCase = require('nodeunit').testCase, - addressparser = require("./index"); - -exports["General tests"] = { - "Single address": function(test){ - var input = "andris@tr.ee", - expected = [{address:"andris@tr.ee", name:""}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Multiple addresses": function(test){ - var input = "andris@tr.ee, andris@example.com", - expected = [{address:"andris@tr.ee", name:""}, {address:"andris@example.com", name:""}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "With unquoted name": function(test){ - var input = "andris ", - expected = [{name: "andris", address:"andris@tr.ee"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "With quoted name": function(test){ - var input = "\"reinman, andris\" ", - expected = [{name: "reinman, andris", address:"andris@tr.ee"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Unquoted name, unquoted address": function(test){ - var input = "andris andris@tr.ee", - expected = [{name: "andris", address:"andris@tr.ee"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Emtpy group": function(test){ - var input = "Undisclosed:;", - expected = []; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Address group": function(test){ - var input = "Disclosed:andris@tr.ee, andris@example.com;", - expected = [{name: "Disclosed", address:"andris@tr.ee"}, {name: "Disclosed", address:"andris@example.com"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Name from comment": function(test){ - var input = "andris@tr.ee (andris)", - expected = [{name: "andris", address:"andris@tr.ee"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Skip comment": function(test){ - var input = "andris@tr.ee (reinman) andris", - expected = [{name: "andris", address:"andris@tr.ee"}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "No address": function(test){ - var input = "andris", - expected = [{name: "andris", address:""}]; - test.deepEqual(addressparser(input), expected); - test.done(); - }, - "Apostophe in name": function(test){ - var input = "O'Neill", - expected = [{name: "O'Neill", address:""}]; - test.deepEqual(addressparser(input), expected); - test.done(); - } -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/.npmignore b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/.npmignore deleted file mode 100644 index b512c09d476..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/README.md deleted file mode 100644 index 8b0b899897a..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Encoding - -**encoding** is a simple wrapper around [node-iconv](https://github.com/bnoordhuis/node-iconv) and [iconv-lite](https://github.com/ashtuchkin/iconv-lite/) to convert strings from one encoding to another. If node-iconv is not available for some reason, -iconv-lite will be used instead of it as a fallback. - -## Install - -Install through npm - - npm install encoding - -## Usage - -Require the module - - var encoding = require("encoding"); - -Convert with encoding.convert() - - var resultBuffer = encoding.convert(text, toCharset, fromCharset); - -Where - - * **text** is either a Buffer or a String to be converted - * **toCharset** is the characterset to convert the string - * **fromCharset** (*optional*, defaults to UTF-8) is the source charset - -Output of the conversion is always a Buffer object. - -Example - - var result = encoding.convert("ÕÄÖÜ", "Latin_1"); - console.log(result); // - -## iconv support - -By default only iconv-lite is bundled. If you need node-iconv support, you need to add it -as an additional dependency for your project: - - ..., - "dependencies":{ - "encoding": "*", - "iconv": "*" - }, - ... - -## License - -**MIT** \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/index.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/index.js deleted file mode 100644 index aa3bc1b10b5..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/index.js +++ /dev/null @@ -1,107 +0,0 @@ -var Iconv, iconvLite = require("iconv-lite"); - -try{ - Iconv = require("iconv").Iconv; -}catch(E){} - -// Expose to the world -module.exports.convert = convert; - -/** - * Convert encoding of an UTF-8 string or a buffer - * - * @param {String|Buffer} str String to be converted - * @param {String} to Encoding to be converted to - * @param {String} [from="UTF-8"] Encoding to be converted from - * @param {Boolean} useLite If set to ture, force to use iconvLite - * @return {Buffer} Encoded string - */ -function convert(str, to, from, useLite){ - from = checkEncoding(from || "UTF-8"); - to = checkEncoding(to || "UTF-8"); - str = str || ""; - - var result; - - if(from != "UTF-8" && typeof str == "string"){ - str = new Buffer(str, "binary"); - } - - if(from == to){ - result = str; - }else{ - if(Iconv && !useLite){ - try{ - result = convertIconv(str, to, from); - }catch(E){ - try{ - result = convertIconvLite(str, to, from); - }catch(E){ - result = str; - } - } - }else{ - try{ - result = convertIconvLite(str, to, from); - }catch(E){ - result = str; - } - } - } - - if(typeof result == "string"){ - result = new Buffer(result, "utf-8"); - } - - return result; -} - -/** - * Convert encoding of astring with node-iconv (if available) - * - * @param {String|Buffer} str String to be converted - * @param {String} to Encoding to be converted to - * @param {String} [from="UTF-8"] Encoding to be converted from - * @return {Buffer} Encoded string - */ -function convertIconv(str, to, from){ - var response, iconv; - iconv = new Iconv(from, to + "//TRANSLIT//IGNORE"); - response = iconv.convert(str); - return response.slice(0, response.length); -} - -/** - * Convert encoding of astring with iconv-lite (if node-iconv is not available) - * - * @param {String|Buffer} str String to be converted - * @param {String} to Encoding to be converted to - * @param {String} [from="UTF-8"] Encoding to be converted from - * @return {Buffer} Encoded string - */ -function convertIconvLite(str, to, from){ - if(to == "UTF-8"){ - return iconvLite.decode(str, from); - }else if(from == "UTF-8"){ - return iconvLite.encode(str, to); - }else{ - return iconvLite.encode(iconvLite.decode(str, from), to); - } -} - -/** - * Converts charset name if needed - * - * @param {String} name Character set - * @return {String} Character set name - */ -function checkEncoding(name){ - name = (name || "").toString().trim(). - replace(/^latin[\-_]?(\d+)$/i, "ISO-8859-$1"). - replace(/^win(?:dows)?[\-_]?(\d+)$/i, "WINDOWS-$1"). - replace(/^utf[\-_]?(\d+)$/i, "UTF-$1"). - replace(/^ks_c_5601\-1987$/i, "CP949"). - replace(/^us[\-_]?ascii$/i, "ASCII"). - toUpperCase(); - return name; -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.npmignore b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.npmignore deleted file mode 100644 index fe46877a3d6..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -*~ -*sublime-* diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.travis.yml b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.travis.yml deleted file mode 100644 index 0bab9cd8854..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ - language: node_js - node_js: - - 0.4 - - 0.6 - - 0.8 diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/LICENSE b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/LICENSE deleted file mode 100644 index d518d8376af..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2011 Alexander Shtuchkin - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/README.md b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/README.md deleted file mode 100644 index c6251b1df82..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/README.md +++ /dev/null @@ -1,65 +0,0 @@ -iconv-lite - pure javascript character encoding conversion -====================================================================== - -[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite) - -## Features - -* Pure javascript. Doesn't need native code compilation. -* Easy API. -* Works on Windows and in sandboxed environments like [Cloud9](http://c9.io). -* Encoding is much faster than node-iconv (see below for performance comparison). - -## Usage - - var iconv = require('iconv-lite'); - - // Convert from an encoded buffer to string. - str = iconv.decode(buf, 'win1251'); - - // Convert from string to an encoded buffer. - buf = iconv.encode("Sample input string", 'win1251'); - -## Supported encodings - -* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64' -* All widespread single byte encodings: Windows 125x family, ISO-8859 family, - IBM/DOS codepages, Macintosh family, KOI8 family. - Aliases like 'latin1', 'us-ascii' also supported. -* Multibyte encodings: 'gbk', 'gb2313'. - -Others are easy to add, see the source. Please, participate. -Most encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors! - -Not supported yet: Big5, EUC family, Shift_JIS. - - -## Encoding/decoding speed - -Comparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). -Note: your results may vary, so please always check on your hardware. - - operation iconv@1.2.4 iconv-lite@0.2.4 - ---------------------------------------------------------- - encode('win1251') ~115 Mb/s ~230 Mb/s - decode('win1251') ~95 Mb/s ~130 Mb/s - - -## Notes - -Untranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome. - -## Testing - - npm install --dev iconv-lite - vows - - # To view performance: - node test/performance.js - -## TODO - -* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')). -* Add more encodings. -* Add transliteration (best fit char). -* Add tests and correct support of variable-byte encodings (currently work is delegated to node). diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/gbk.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/gbk.js deleted file mode 100644 index 78a63ec5e24..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/gbk.js +++ /dev/null @@ -1,9 +0,0 @@ -var gbkTable = require('./table/gbk.js'); -module.exports = { - 'windows936': 'gbk', - 'gb2312': 'gbk', - 'gbk': { - type: 'table', - table: gbkTable - } -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/singlebyte.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/singlebyte.js deleted file mode 100644 index 10d72e4d280..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/singlebyte.js +++ /dev/null @@ -1,330 +0,0 @@ -module.exports = { - "437": "cp437", - "737": "cp737", - "775": "cp775", - "850": "cp850", - "852": "cp852", - "855": "cp855", - "857": "cp857", - "858": "cp858", - "860": "cp860", - "861": "cp861", - "862": "cp862", - "863": "cp863", - "864": "cp864", - "865": "cp865", - "866": "cp866", - "869": "cp869", - "874": "iso885911", - "1250": "windows1250", - "1251": "windows1251", - "1252": "windows1252", - "1253": "windows1253", - "1254": "windows1254", - "1255": "windows1255", - "1256": "windows1256", - "1257": "windows1257", - "1258": "windows1258", - "20866": "koi8r", - "21866": "koi8u", - "28591": "iso88591", - "28592": "iso88592", - "28593": "iso88593", - "28594": "iso88594", - "28595": "iso88595", - "28596": "iso88596", - "28597": "iso88597", - "28598": "iso88598", - "28599": "iso88599", - "28600": "iso885910", - "28601": "iso885911", - "28603": "iso885913", - "28604": "iso885914", - "28605": "iso885915", - "28606": "iso885916", - "ascii8bit": "ascii", - "usascii": "ascii", - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", - "cp819": "iso88951", - "arabic": "iso88596", - "arabic8": "iso88596", - "greek": "iso88597", - "greek8": "iso88597", - "hebrew": "iso88598", - "hebrew8": "iso88598", - "turkish": "iso88599", - "turkish8": "iso88599", - "thai": "iso885911", - "thai8": "iso885911", - "tis620": "iso885911", - "windows874": "iso885911", - "win874": "iso885911", - "cp874": "iso885911", - "celtic": "iso885914", - "celtic8": "iso885914", - "cp20866": "koi8r", - "ibm878": "koi8r", - "cp21866": "koi8u", - "ibm1168": "koi8u", - "windows1250": { - "type": "singlebyte", - "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“â€â€¢â€“—�™š›śťžź ˇ˘Å¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»ĽËľżŔÃÂĂÄĹĆÇČÉĘËĚÃÃŽÄŽÄŃŇÓÔÅÖ×ŘŮÚŰÜÃŢßŕáâăäĺćçÄéęëěíîÄđńňóôőö÷řůúűüýţ˙" - }, - "win1250": "windows1250", - "cp1250": "windows1250", - "windows1251": { - "type": "singlebyte", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋÐђ‘’“â€â€¢â€“—�™љ›њќћџ ЎўЈ¤Ò¦§Ð©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ" - }, - "win1251": "windows1251", - "cp1251": "windows1251", - "windows1252": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“â€â€¢â€“—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "win1252": "windows1252", - "cp1252": "windows1252", - "windows1253": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“â€â€¢â€“—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎÎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏώ�" - }, - "win1253": "windows1253", - "cp1253": "windows1253", - "windows1254": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“â€â€¢â€“—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "win1254": "windows1254", - "cp1254": "windows1254", - "windows1255": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“â€â€¢â€“—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ�ֻּֽ־ֿ׀×ׂ׃װױײ׳״�������×בגדהוזחטיךכל×מןנסעףפץצקרשת��‎â€ï¿½" - }, - "win1255": "windows1255", - "cp1255": "windows1255", - "windows1256": { - "type": "singlebyte", - "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“â€â€¢â€“—ک™ڑ›œ‌â€ÚºÂ ØŒÂ¢Â£Â¤Â¥Â¦Â§Â¨Â©Ú¾Â«Â¬Â­Â®Â¯Â°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Ø›Â»Â¼Â½Â¾ØŸÛءآأؤإئابةتثجحخدذرزسشصض×طظعغـÙقكàلâمنهوçèéêëىيîïًٌÙَôÙÙ÷ّùْûü‎â€Û’" - }, - "win1256": "windows1256", - "cp1256": "windows1256", - "windows1257": { - "type": "singlebyte", - "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“â€â€¢â€“—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲÅŚŪÜŻŽßąįÄćäåęēÄéźėģķīļšńņóÅõö÷ųłśūüżž˙" - }, - "win1257": "windows1257", - "cp1257": "windows1257", - "windows1258": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“â€â€¢â€“—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂĂÄÅÆÇÈÉÊË̀ÃÃŽÃÄÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêëÌíîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "win1258": "windows1258", - "cp1258": "windows1258", - "iso88591": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28591": "iso88591", - "iso88592": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ą˘Å¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťźËžżŔÃÂĂÄĹĆÇČÉĘËĚÃÃŽÄŽÄŃŇÓÔÅÖ×ŘŮÚŰÜÃŢßŕáâăäĺćçÄéęëěíîÄđńňóôőö÷řůúűüýţ˙" - }, - "cp28592": "iso88592", - "iso88593": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÃÂ�ÄĊĈÇÈÉÊËÌÃÃŽÃ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ÄùúûüŭÅË™" - }, - "cp28593": "iso88593", - "iso88594": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÃÂÃÄÅÆĮČÉĘËĖÃÎĪÄŅŌĶÔÕÖ×ØŲÚÛÜŨŪßÄáâãäåæįÄéęëėíîīđņÅķôõö÷øųúûüũū˙" - }, - "cp28594": "iso88594", - "iso88595": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ÐЂЃЄЅІЇЈЉЊЋЌ­ЎÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ№ёђѓєѕіїјљњћќ§ўџ" - }, - "cp28595": "iso88595", - "iso88596": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـÙقكلمنهوىيًٌÙÙŽÙÙّْ�������������" - }, - "cp28596": "iso88596", - "iso88597": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎÎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏώ�" - }, - "cp28597": "iso88597", - "iso88598": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗×בגדהוזחטיךכל×מןנסעףפץצקרשת��‎â€ï¿½" - }, - "cp28598": "iso88598", - "iso88599": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "cp28599": "iso88599", - "iso885910": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄĒĢĪĨĶ§ĻÄŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÃÂÃÄÅÆĮČÉĘËĖÃÃŽÃÃŅŌÓÔÕÖŨØŲÚÛÜÃÞßÄáâãäåæįÄéęëėíîïðņÅóôõöũøųúûüýþĸ" - }, - "cp28600": "iso885910", - "iso885911": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸¸à¸¹à¸ºï¿½ï¿½ï¿½ï¿½à¸¿à¹€à¹à¹‚ใไๅๆ็่้๊๋์à¹à¹Žà¹à¹à¹‘๒๓๔๕๖๗๘๙๚๛����" - }, - "cp28601": "iso885911", - "iso885913": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ â€Â¢Â£Â¤â€žÂ¦Â§Ã˜Â©Å–«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲÅŚŪÜŻŽßąįÄćäåęēÄéźėģķīļšńņóÅõö÷ųłśūüżž’" - }, - "cp28603": "iso885913", - "iso885914": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀá¹Â¶á¹–áºá¹—ẃṠỳẄẅṡÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃŴÑÒÓÔÕÖṪØÙÚÛÜÃŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" - }, - "cp28604": "iso885914", - "iso885915": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28605": "iso885915", - "iso885916": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄąÅ€„Š§š©Ș«Ź­źŻ°±ČłŽâ€Â¶Â·Å¾Äș»ŒœŸżÀÃÂĂÄĆÆÇÈÉÊËÌÃÃŽÃÄŃÒÓÔÅÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" - }, - "cp28606": "iso885916", - "cp437": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm437": "cp437", - "cp737": { - "type": "singlebyte", - "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπÏσςτυφχψ░▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀ωάέήϊίόÏϋώΆΈΉΊΌΎÎ±≥≤ΪΫ÷≈°∙·√â¿Â²â– Â " - }, - "ibm737": "cp737", - "cp775": { - "type": "singlebyte", - "chars": "ĆüéÄäģåćłēŖŗīŹÄÅÉæÆÅöĢ¢ŚśÖÜø£ØפĀĪóŻżźâ€Â¦Â©Â®Â¬Â½Â¼Å«»░▒▓│┤ĄČĘĖ╣║╗â•Ä®Å â”└┴┬├─┼ŲŪ╚╔╩╦╠â•â•¬Å½Ä…Äęėįšųūž┘┌█▄▌â–▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " - }, - "ibm775": "cp775", - "cp850": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•Â¢Â¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•â•¬Â¤Ã°ÃÊËÈıÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýï´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm850": "cp850", - "cp852": { - "type": "singlebyte", - "chars": "ÇüéâäůćçłëÅőîŹÄĆÉĹĺôöĽľŚśÖÜŤťÅ×ÄáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÃÂĚŞ╣║╗â•Å»Å¼â”└┴┬├─┼Ăă╚╔╩╦╠â•â•¬Â¤Ä‘ÄĎËÄŇÃÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÃţ´­Ë˛ˇ˘§÷¸°¨˙űŘř■ " - }, - "ibm852": "cp852", - "cp855": { - "type": "singlebyte", - "chars": "ђЂѓЃёÐєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџÐюЮъЪаÐбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗â•Ð¹Ð™â”└┴┬├─┼кК╚╔╩╦╠â•â•¬Â¤Ð»Ð›Ð¼ÐœÐ½ÐоОп┘┌█▄ПÑ▀ЯрРÑСтТуУжЖвВьЬ№­ыЫзЗшШÑЭщЩчЧ§■ " - }, - "ibm855": "cp855", - "cp857": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•Â¢Â¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•â•¬Â¤ÂºÂªÃŠÃ‹Ãˆï¿½ÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " - }, - "ibm857": "cp857", - "cp858": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•Â¢Â¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•â•¬Â¤Ã°ÃÊËÈ€ÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýï´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm858": "cp858", - "cp860": { - "type": "singlebyte", - "chars": "ÇüéâãàÃçêÊèÃÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm860": "cp860", - "cp861": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèÃðÞÄÅÉæÆôöþûÃýÖÜø£Ø₧ƒáíóúÃÃÓÚ¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm861": "cp861", - "cp862": { - "type": "singlebyte", - "chars": "×בגדהוזחטיךכל×מןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm862": "cp862", - "cp863": { - "type": "singlebyte", - "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÃûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯ÎâŒÂ¬Â½Â¼Â¾Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm863": "cp863", - "cp864": { - "type": "singlebyte", - "chars": "°·∙√▒─│┼┤┬├┴â”┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎïºïº•ïº™ØŒïºïº¡ïº¥Ù Ù¡Ù¢Ù£Ù¤Ù¥Ù¦Ù§Ù¨Ù©ï»‘؛ﺱﺵﺹ؟¢ﺀïºïºƒïº…ﻊﺋïºïº‘ﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿï»ï»…ﻋï»Â¦Â¬Ã·Ã—ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎï»ï»¡ï¹½Ù‘ﻥﻩﻬﻰﻲï»ï»•ï»µï»¶ï»ï»™ï»±â– ï¿½" - }, - "ibm864": "cp864", - "cp865": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â¤â–‘▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm865": "cp865", - "cp866": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗â•â•œâ•›â”└┴┬├─┼╞╟╚╔╩╦╠â•â•¬â•§â•¨â•¤â•¥â•™â•˜â•’╓╫╪┘┌█▄▌â–▀рÑтуфхцчшщъыьÑÑŽÑÐёЄєЇїЎў°∙·√№¤■ " - }, - "ibm866": "cp866", - "cp869": { - "type": "singlebyte", - "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Î²³ά£έήίϊÎÏŒÏΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜÎ╣║╗â•ÎžÎŸâ”└┴┬├─┼ΠΡ╚╔╩╦╠â•â•¬Î£Î¤Î¥Î¦Î§Î¨Î©Î±Î²Î³â”˜â”Œâ–ˆâ–„δε▀ζηθικλμνξοπÏσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " - }, - "ibm869": "cp869", - "maccroatian": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑âˆÅ¡âˆ«ÂªÂºâ„¦Å¾Ã¸Â¿Â¡Â¬âˆšÆ’≈Ć«Č… ÀÃÕŒœÄ—“â€â€˜â€™Ã·â—Šï¿½Â©â„¤‹›Æ»–·‚„‰ÂćÃÄÈÃÃŽÃÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" - }, - "maccyrillic": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“â€â€˜â€™Ã·â€žÐŽÑžÐÑŸâ„–ÐÑ‘ÑабвгдежзийклмнопрÑтуфхцчшщъыьÑю¤" - }, - "macgreek": { - "type": "singlebyte", - "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάάΟΡ≈Τ«»… ΥΧΆΈœ–―“â€â€˜â€™Ã·Î‰ÎŠÎŒÎŽÎ­Î®Î¯ÏŒÎÏαβψδεφγηιξκλμνοπώÏστθωςχυζϊϋÎΰ�" - }, - "maciceland": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü𢣧•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤ÃðÞþý·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macroman": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤‹›ï¬ï¬‚‡·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macromania": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦ÄƒÅŸÂ¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤‹›Ţţ‡·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macthai": { - "type": "singlebyte", - "chars": "«»…ï¢ï¢’“â€ï¢™ï¿½â€¢ï¢„ï¢ï¢ï¢“‘’� à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸¸à¸¹à¸ºï»¿â€‹â€“—฿เà¹à¹‚ใไๅๆ็่้๊๋์à¹â„¢à¹à¹à¹‘๒๓๔๕๖๗๘๙®©����" - }, - "macturkish": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸ÄžÄŸÄ°Ä±ÅžÅŸâ€¡Â·â€šâ€žâ€°Ã‚ÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macukraine": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ò£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“â€â€˜â€™Ã·â€žÐŽÑžÐÑŸâ„–ÐÑ‘ÑабвгдежзийклмнопрÑтуфхцчшщъыьÑю¤" - }, - "koi8r": { - "type": "singlebyte", - "chars": "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•â•‘╒ё╓╔╕╖╗╘╙╚╛╜â•â•žâ•Ÿâ• â•¡Ð╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопÑÑ€ÑтужвьызшÑщчъЮÐБЦДЕФГХИЙКЛМÐОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8u": { - "type": "singlebyte", - "chars": "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•â•‘╒ёє╔ії╗╘╙╚╛ґâ•â•žâ•Ÿâ• â•¡ÐЄ╣ІЇ╦╧╨╩╪Ò╬©юабцдефгхийклмнопÑÑ€ÑтужвьызшÑщчъЮÐБЦДЕФГХИЙКЛМÐОПЯРСТУЖВЬЫЗШЭЩЧЪ" - } -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/table/gbk.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/table/gbk.js deleted file mode 100644 index c464623e534..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/table/gbk.js +++ /dev/null @@ -1 +0,0 @@ -module.exports={33088:19970,33089:19972,33090:19973,33091:19974,33092:19983,33093:19986,33094:19991,33095:19999,33096:20000,33097:20001,33098:20003,33099:20006,33100:20009,33101:20014,33102:20015,33103:20017,33104:20019,33105:20021,33106:20023,33107:20028,33108:20032,33109:20033,33110:20034,33111:20036,33112:20038,33113:20042,33114:20049,33115:20053,33116:20055,33117:20058,33118:20059,33119:20066,33120:20067,33121:20068,33122:20069,33123:20071,33124:20072,33125:20074,33126:20075,33127:20076,33128:20077,33129:20078,33130:20079,33131:20082,33132:20084,33133:20085,33134:20086,33135:20087,33136:20088,33137:20089,33138:20090,33139:20091,33140:20092,33141:20093,33142:20095,33143:20096,33144:20097,33145:20098,33146:20099,33147:20100,33148:20101,33149:20103,33150:20106,33152:20112,33153:20118,33154:20119,33155:20121,33156:20124,33157:20125,33158:20126,33159:20131,33160:20138,33161:20143,33162:20144,33163:20145,33164:20148,33165:20150,33166:20151,33167:20152,33168:20153,33169:20156,33170:20157,33171:20158,33172:20168,33173:20172,33174:20175,33175:20176,33176:20178,33177:20186,33178:20187,33179:20188,33180:20192,33181:20194,33182:20198,33183:20199,33184:20201,33185:20205,33186:20206,33187:20207,33188:20209,33189:20212,33190:20216,33191:20217,33192:20218,33193:20220,33194:20222,33195:20224,33196:20226,33197:20227,33198:20228,33199:20229,33200:20230,33201:20231,33202:20232,33203:20235,33204:20236,33205:20242,33206:20243,33207:20244,33208:20245,33209:20246,33210:20252,33211:20253,33212:20257,33213:20259,33214:20264,33215:20265,33216:20268,33217:20269,33218:20270,33219:20273,33220:20275,33221:20277,33222:20279,33223:20281,33224:20283,33225:20286,33226:20287,33227:20288,33228:20289,33229:20290,33230:20292,33231:20293,33232:20295,33233:20296,33234:20297,33235:20298,33236:20299,33237:20300,33238:20306,33239:20308,33240:20310,33241:20321,33242:20322,33243:20326,33244:20328,33245:20330,33246:20331,33247:20333,33248:20334,33249:20337,33250:20338,33251:20341,33252:20343,33253:20344,33254:20345,33255:20346,33256:20349,33257:20352,33258:20353,33259:20354,33260:20357,33261:20358,33262:20359,33263:20362,33264:20364,33265:20366,33266:20368,33267:20370,33268:20371,33269:20373,33270:20374,33271:20376,33272:20377,33273:20378,33274:20380,33275:20382,33276:20383,33277:20385,33278:20386,33344:20388,33345:20395,33346:20397,33347:20400,33348:20401,33349:20402,33350:20403,33351:20404,33352:20406,33353:20407,33354:20408,33355:20409,33356:20410,33357:20411,33358:20412,33359:20413,33360:20414,33361:20416,33362:20417,33363:20418,33364:20422,33365:20423,33366:20424,33367:20425,33368:20427,33369:20428,33370:20429,33371:20434,33372:20435,33373:20436,33374:20437,33375:20438,33376:20441,33377:20443,33378:20448,33379:20450,33380:20452,33381:20453,33382:20455,33383:20459,33384:20460,33385:20464,33386:20466,33387:20468,33388:20469,33389:20470,33390:20471,33391:20473,33392:20475,33393:20476,33394:20477,33395:20479,33396:20480,33397:20481,33398:20482,33399:20483,33400:20484,33401:20485,33402:20486,33403:20487,33404:20488,33405:20489,33406:20490,33408:20491,33409:20494,33410:20496,33411:20497,33412:20499,33413:20501,33414:20502,33415:20503,33416:20507,33417:20509,33418:20510,33419:20512,33420:20514,33421:20515,33422:20516,33423:20519,33424:20523,33425:20527,33426:20528,33427:20529,33428:20530,33429:20531,33430:20532,33431:20533,33432:20534,33433:20535,33434:20536,33435:20537,33436:20539,33437:20541,33438:20543,33439:20544,33440:20545,33441:20546,33442:20548,33443:20549,33444:20550,33445:20553,33446:20554,33447:20555,33448:20557,33449:20560,33450:20561,33451:20562,33452:20563,33453:20564,33454:20566,33455:20567,33456:20568,33457:20569,33458:20571,33459:20573,33460:20574,33461:20575,33462:20576,33463:20577,33464:20578,33465:20579,33466:20580,33467:20582,33468:20583,33469:20584,33470:20585,33471:20586,33472:20587,33473:20589,33474:20590,33475:20591,33476:20592,33477:20593,33478:20594,33479:20595,33480:20596,33481:20597,33482:20600,33483:20601,33484:20602,33485:20604,33486:20605,33487:20609,33488:20610,33489:20611,33490:20612,33491:20614,33492:20615,33493:20617,33494:20618,33495:20619,33496:20620,33497:20622,33498:20623,33499:20624,33500:20625,33501:20626,33502:20627,33503:20628,33504:20629,33505:20630,33506:20631,33507:20632,33508:20633,33509:20634,33510:20635,33511:20636,33512:20637,33513:20638,33514:20639,33515:20640,33516:20641,33517:20642,33518:20644,33519:20646,33520:20650,33521:20651,33522:20653,33523:20654,33524:20655,33525:20656,33526:20657,33527:20659,33528:20660,33529:20661,33530:20662,33531:20663,33532:20664,33533:20665,33534:20668,33600:20669,33601:20670,33602:20671,33603:20672,33604:20673,33605:20674,33606:20675,33607:20676,33608:20677,33609:20678,33610:20679,33611:20680,33612:20681,33613:20682,33614:20683,33615:20684,33616:20685,33617:20686,33618:20688,33619:20689,33620:20690,33621:20691,33622:20692,33623:20693,33624:20695,33625:20696,33626:20697,33627:20699,33628:20700,33629:20701,33630:20702,33631:20703,33632:20704,33633:20705,33634:20706,33635:20707,33636:20708,33637:20709,33638:20712,33639:20713,33640:20714,33641:20715,33642:20719,33643:20720,33644:20721,33645:20722,33646:20724,33647:20726,33648:20727,33649:20728,33650:20729,33651:20730,33652:20732,33653:20733,33654:20734,33655:20735,33656:20736,33657:20737,33658:20738,33659:20739,33660:20740,33661:20741,33662:20744,33664:20745,33665:20746,33666:20748,33667:20749,33668:20750,33669:20751,33670:20752,33671:20753,33672:20755,33673:20756,33674:20757,33675:20758,33676:20759,33677:20760,33678:20761,33679:20762,33680:20763,33681:20764,33682:20765,33683:20766,33684:20767,33685:20768,33686:20770,33687:20771,33688:20772,33689:20773,33690:20774,33691:20775,33692:20776,33693:20777,33694:20778,33695:20779,33696:20780,33697:20781,33698:20782,33699:20783,33700:20784,33701:20785,33702:20786,33703:20787,33704:20788,33705:20789,33706:20790,33707:20791,33708:20792,33709:20793,33710:20794,33711:20795,33712:20796,33713:20797,33714:20798,33715:20802,33716:20807,33717:20810,33718:20812,33719:20814,33720:20815,33721:20816,33722:20818,33723:20819,33724:20823,33725:20824,33726:20825,33727:20827,33728:20829,33729:20830,33730:20831,33731:20832,33732:20833,33733:20835,33734:20836,33735:20838,33736:20839,33737:20841,33738:20842,33739:20847,33740:20850,33741:20858,33742:20862,33743:20863,33744:20867,33745:20868,33746:20870,33747:20871,33748:20874,33749:20875,33750:20878,33751:20879,33752:20880,33753:20881,33754:20883,33755:20884,33756:20888,33757:20890,33758:20893,33759:20894,33760:20895,33761:20897,33762:20899,33763:20902,33764:20903,33765:20904,33766:20905,33767:20906,33768:20909,33769:20910,33770:20916,33771:20920,33772:20921,33773:20922,33774:20926,33775:20927,33776:20929,33777:20930,33778:20931,33779:20933,33780:20936,33781:20938,33782:20941,33783:20942,33784:20944,33785:20946,33786:20947,33787:20948,33788:20949,33789:20950,33790:20951,33856:20952,33857:20953,33858:20954,33859:20956,33860:20958,33861:20959,33862:20962,33863:20963,33864:20965,33865:20966,33866:20967,33867:20968,33868:20969,33869:20970,33870:20972,33871:20974,33872:20977,33873:20978,33874:20980,33875:20983,33876:20990,33877:20996,33878:20997,33879:21001,33880:21003,33881:21004,33882:21007,33883:21008,33884:21011,33885:21012,33886:21013,33887:21020,33888:21022,33889:21023,33890:21025,33891:21026,33892:21027,33893:21029,33894:21030,33895:21031,33896:21034,33897:21036,33898:21039,33899:21041,33900:21042,33901:21044,33902:21045,33903:21052,33904:21054,33905:21060,33906:21061,33907:21062,33908:21063,33909:21064,33910:21065,33911:21067,33912:21070,33913:21071,33914:21074,33915:21075,33916:21077,33917:21079,33918:21080,33920:21081,33921:21082,33922:21083,33923:21085,33924:21087,33925:21088,33926:21090,33927:21091,33928:21092,33929:21094,33930:21096,33931:21099,33932:21100,33933:21101,33934:21102,33935:21104,33936:21105,33937:21107,33938:21108,33939:21109,33940:21110,33941:21111,33942:21112,33943:21113,33944:21114,33945:21115,33946:21116,33947:21118,33948:21120,33949:21123,33950:21124,33951:21125,33952:21126,33953:21127,33954:21129,33955:21130,33956:21131,33957:21132,33958:21133,33959:21134,33960:21135,33961:21137,33962:21138,33963:21140,33964:21141,33965:21142,33966:21143,33967:21144,33968:21145,33969:21146,33970:21148,33971:21156,33972:21157,33973:21158,33974:21159,33975:21166,33976:21167,33977:21168,33978:21172,33979:21173,33980:21174,33981:21175,33982:21176,33983:21177,33984:21178,33985:21179,33986:21180,33987:21181,33988:21184,33989:21185,33990:21186,33991:21188,33992:21189,33993:21190,33994:21192,33995:21194,33996:21196,33997:21197,33998:21198,33999:21199,34000:21201,34001:21203,34002:21204,34003:21205,34004:21207,34005:21209,34006:21210,34007:21211,34008:21212,34009:21213,34010:21214,34011:21216,34012:21217,34013:21218,34014:21219,34015:21221,34016:21222,34017:21223,34018:21224,34019:21225,34020:21226,34021:21227,34022:21228,34023:21229,34024:21230,34025:21231,34026:21233,34027:21234,34028:21235,34029:21236,34030:21237,34031:21238,34032:21239,34033:21240,34034:21243,34035:21244,34036:21245,34037:21249,34038:21250,34039:21251,34040:21252,34041:21255,34042:21257,34043:21258,34044:21259,34045:21260,34046:21262,34112:21265,34113:21266,34114:21267,34115:21268,34116:21272,34117:21275,34118:21276,34119:21278,34120:21279,34121:21282,34122:21284,34123:21285,34124:21287,34125:21288,34126:21289,34127:21291,34128:21292,34129:21293,34130:21295,34131:21296,34132:21297,34133:21298,34134:21299,34135:21300,34136:21301,34137:21302,34138:21303,34139:21304,34140:21308,34141:21309,34142:21312,34143:21314,34144:21316,34145:21318,34146:21323,34147:21324,34148:21325,34149:21328,34150:21332,34151:21336,34152:21337,34153:21339,34154:21341,34155:21349,34156:21352,34157:21354,34158:21356,34159:21357,34160:21362,34161:21366,34162:21369,34163:21371,34164:21372,34165:21373,34166:21374,34167:21376,34168:21377,34169:21379,34170:21383,34171:21384,34172:21386,34173:21390,34174:21391,34176:21392,34177:21393,34178:21394,34179:21395,34180:21396,34181:21398,34182:21399,34183:21401,34184:21403,34185:21404,34186:21406,34187:21408,34188:21409,34189:21412,34190:21415,34191:21418,34192:21419,34193:21420,34194:21421,34195:21423,34196:21424,34197:21425,34198:21426,34199:21427,34200:21428,34201:21429,34202:21431,34203:21432,34204:21433,34205:21434,34206:21436,34207:21437,34208:21438,34209:21440,34210:21443,34211:21444,34212:21445,34213:21446,34214:21447,34215:21454,34216:21455,34217:21456,34218:21458,34219:21459,34220:21461,34221:21466,34222:21468,34223:21469,34224:21470,34225:21473,34226:21474,34227:21479,34228:21492,34229:21498,34230:21502,34231:21503,34232:21504,34233:21506,34234:21509,34235:21511,34236:21515,34237:21524,34238:21528,34239:21529,34240:21530,34241:21532,34242:21538,34243:21540,34244:21541,34245:21546,34246:21552,34247:21555,34248:21558,34249:21559,34250:21562,34251:21565,34252:21567,34253:21569,34254:21570,34255:21572,34256:21573,34257:21575,34258:21577,34259:21580,34260:21581,34261:21582,34262:21583,34263:21585,34264:21594,34265:21597,34266:21598,34267:21599,34268:21600,34269:21601,34270:21603,34271:21605,34272:21607,34273:21609,34274:21610,34275:21611,34276:21612,34277:21613,34278:21614,34279:21615,34280:21616,34281:21620,34282:21625,34283:21626,34284:21630,34285:21631,34286:21633,34287:21635,34288:21637,34289:21639,34290:21640,34291:21641,34292:21642,34293:21645,34294:21649,34295:21651,34296:21655,34297:21656,34298:21660,34299:21662,34300:21663,34301:21664,34302:21665,34368:21666,34369:21669,34370:21678,34371:21680,34372:21682,34373:21685,34374:21686,34375:21687,34376:21689,34377:21690,34378:21692,34379:21694,34380:21699,34381:21701,34382:21706,34383:21707,34384:21718,34385:21720,34386:21723,34387:21728,34388:21729,34389:21730,34390:21731,34391:21732,34392:21739,34393:21740,34394:21743,34395:21744,34396:21745,34397:21748,34398:21749,34399:21750,34400:21751,34401:21752,34402:21753,34403:21755,34404:21758,34405:21760,34406:21762,34407:21763,34408:21764,34409:21765,34410:21768,34411:21770,34412:21771,34413:21772,34414:21773,34415:21774,34416:21778,34417:21779,34418:21781,34419:21782,34420:21783,34421:21784,34422:21785,34423:21786,34424:21788,34425:21789,34426:21790,34427:21791,34428:21793,34429:21797,34430:21798,34432:21800,34433:21801,34434:21803,34435:21805,34436:21810,34437:21812,34438:21813,34439:21814,34440:21816,34441:21817,34442:21818,34443:21819,34444:21821,34445:21824,34446:21826,34447:21829,34448:21831,34449:21832,34450:21835,34451:21836,34452:21837,34453:21838,34454:21839,34455:21841,34456:21842,34457:21843,34458:21844,34459:21847,34460:21848,34461:21849,34462:21850,34463:21851,34464:21853,34465:21854,34466:21855,34467:21856,34468:21858,34469:21859,34470:21864,34471:21865,34472:21867,34473:21871,34474:21872,34475:21873,34476:21874,34477:21875,34478:21876,34479:21881,34480:21882,34481:21885,34482:21887,34483:21893,34484:21894,34485:21900,34486:21901,34487:21902,34488:21904,34489:21906,34490:21907,34491:21909,34492:21910,34493:21911,34494:21914,34495:21915,34496:21918,34497:21920,34498:21921,34499:21922,34500:21923,34501:21924,34502:21925,34503:21926,34504:21928,34505:21929,34506:21930,34507:21931,34508:21932,34509:21933,34510:21934,34511:21935,34512:21936,34513:21938,34514:21940,34515:21942,34516:21944,34517:21946,34518:21948,34519:21951,34520:21952,34521:21953,34522:21954,34523:21955,34524:21958,34525:21959,34526:21960,34527:21962,34528:21963,34529:21966,34530:21967,34531:21968,34532:21973,34533:21975,34534:21976,34535:21977,34536:21978,34537:21979,34538:21982,34539:21984,34540:21986,34541:21991,34542:21993,34543:21997,34544:21998,34545:22000,34546:22001,34547:22004,34548:22006,34549:22008,34550:22009,34551:22010,34552:22011,34553:22012,34554:22015,34555:22018,34556:22019,34557:22020,34558:22021,34624:22022,34625:22023,34626:22026,34627:22027,34628:22029,34629:22032,34630:22033,34631:22034,34632:22035,34633:22036,34634:22037,34635:22038,34636:22039,34637:22041,34638:22042,34639:22044,34640:22045,34641:22048,34642:22049,34643:22050,34644:22053,34645:22054,34646:22056,34647:22057,34648:22058,34649:22059,34650:22062,34651:22063,34652:22064,34653:22067,34654:22069,34655:22071,34656:22072,34657:22074,34658:22076,34659:22077,34660:22078,34661:22080,34662:22081,34663:22082,34664:22083,34665:22084,34666:22085,34667:22086,34668:22087,34669:22088,34670:22089,34671:22090,34672:22091,34673:22095,34674:22096,34675:22097,34676:22098,34677:22099,34678:22101,34679:22102,34680:22106,34681:22107,34682:22109,34683:22110,34684:22111,34685:22112,34686:22113,34688:22115,34689:22117,34690:22118,34691:22119,34692:22125,34693:22126,34694:22127,34695:22128,34696:22130,34697:22131,34698:22132,34699:22133,34700:22135,34701:22136,34702:22137,34703:22138,34704:22141,34705:22142,34706:22143,34707:22144,34708:22145,34709:22146,34710:22147,34711:22148,34712:22151,34713:22152,34714:22153,34715:22154,34716:22155,34717:22156,34718:22157,34719:22160,34720:22161,34721:22162,34722:22164,34723:22165,34724:22166,34725:22167,34726:22168,34727:22169,34728:22170,34729:22171,34730:22172,34731:22173,34732:22174,34733:22175,34734:22176,34735:22177,34736:22178,34737:22180,34738:22181,34739:22182,34740:22183,34741:22184,34742:22185,34743:22186,34744:22187,34745:22188,34746:22189,34747:22190,34748:22192,34749:22193,34750:22194,34751:22195,34752:22196,34753:22197,34754:22198,34755:22200,34756:22201,34757:22202,34758:22203,34759:22205,34760:22206,34761:22207,34762:22208,34763:22209,34764:22210,34765:22211,34766:22212,34767:22213,34768:22214,34769:22215,34770:22216,34771:22217,34772:22219,34773:22220,34774:22221,34775:22222,34776:22223,34777:22224,34778:22225,34779:22226,34780:22227,34781:22229,34782:22230,34783:22232,34784:22233,34785:22236,34786:22243,34787:22245,34788:22246,34789:22247,34790:22248,34791:22249,34792:22250,34793:22252,34794:22254,34795:22255,34796:22258,34797:22259,34798:22262,34799:22263,34800:22264,34801:22267,34802:22268,34803:22272,34804:22273,34805:22274,34806:22277,34807:22279,34808:22283,34809:22284,34810:22285,34811:22286,34812:22287,34813:22288,34814:22289,34880:22290,34881:22291,34882:22292,34883:22293,34884:22294,34885:22295,34886:22296,34887:22297,34888:22298,34889:22299,34890:22301,34891:22302,34892:22304,34893:22305,34894:22306,34895:22308,34896:22309,34897:22310,34898:22311,34899:22315,34900:22321,34901:22322,34902:22324,34903:22325,34904:22326,34905:22327,34906:22328,34907:22332,34908:22333,34909:22335,34910:22337,34911:22339,34912:22340,34913:22341,34914:22342,34915:22344,34916:22345,34917:22347,34918:22354,34919:22355,34920:22356,34921:22357,34922:22358,34923:22360,34924:22361,34925:22370,34926:22371,34927:22373,34928:22375,34929:22380,34930:22382,34931:22384,34932:22385,34933:22386,34934:22388,34935:22389,34936:22392,34937:22393,34938:22394,34939:22397,34940:22398,34941:22399,34942:22400,34944:22401,34945:22407,34946:22408,34947:22409,34948:22410,34949:22413,34950:22414,34951:22415,34952:22416,34953:22417,34954:22420,34955:22421,34956:22422,34957:22423,34958:22424,34959:22425,34960:22426,34961:22428,34962:22429,34963:22430,34964:22431,34965:22437,34966:22440,34967:22442,34968:22444,34969:22447,34970:22448,34971:22449,34972:22451,34973:22453,34974:22454,34975:22455,34976:22457,34977:22458,34978:22459,34979:22460,34980:22461,34981:22462,34982:22463,34983:22464,34984:22465,34985:22468,34986:22469,34987:22470,34988:22471,34989:22472,34990:22473,34991:22474,34992:22476,34993:22477,34994:22480,34995:22481,34996:22483,34997:22486,34998:22487,34999:22491,35000:22492,35001:22494,35002:22497,35003:22498,35004:22499,35005:22501,35006:22502,35007:22503,35008:22504,35009:22505,35010:22506,35011:22507,35012:22508,35013:22510,35014:22512,35015:22513,35016:22514,35017:22515,35018:22517,35019:22518,35020:22519,35021:22523,35022:22524,35023:22526,35024:22527,35025:22529,35026:22531,35027:22532,35028:22533,35029:22536,35030:22537,35031:22538,35032:22540,35033:22542,35034:22543,35035:22544,35036:22546,35037:22547,35038:22548,35039:22550,35040:22551,35041:22552,35042:22554,35043:22555,35044:22556,35045:22557,35046:22559,35047:22562,35048:22563,35049:22565,35050:22566,35051:22567,35052:22568,35053:22569,35054:22571,35055:22572,35056:22573,35057:22574,35058:22575,35059:22577,35060:22578,35061:22579,35062:22580,35063:22582,35064:22583,35065:22584,35066:22585,35067:22586,35068:22587,35069:22588,35070:22589,35136:22590,35137:22591,35138:22592,35139:22593,35140:22594,35141:22595,35142:22597,35143:22598,35144:22599,35145:22600,35146:22601,35147:22602,35148:22603,35149:22606,35150:22607,35151:22608,35152:22610,35153:22611,35154:22613,35155:22614,35156:22615,35157:22617,35158:22618,35159:22619,35160:22620,35161:22621,35162:22623,35163:22624,35164:22625,35165:22626,35166:22627,35167:22628,35168:22630,35169:22631,35170:22632,35171:22633,35172:22634,35173:22637,35174:22638,35175:22639,35176:22640,35177:22641,35178:22642,35179:22643,35180:22644,35181:22645,35182:22646,35183:22647,35184:22648,35185:22649,35186:22650,35187:22651,35188:22652,35189:22653,35190:22655,35191:22658,35192:22660,35193:22662,35194:22663,35195:22664,35196:22666,35197:22667,35198:22668,35200:22669,35201:22670,35202:22671,35203:22672,35204:22673,35205:22676,35206:22677,35207:22678,35208:22679,35209:22680,35210:22683,35211:22684,35212:22685,35213:22688,35214:22689,35215:22690,35216:22691,35217:22692,35218:22693,35219:22694,35220:22695,35221:22698,35222:22699,35223:22700,35224:22701,35225:22702,35226:22703,35227:22704,35228:22705,35229:22706,35230:22707,35231:22708,35232:22709,35233:22710,35234:22711,35235:22712,35236:22713,35237:22714,35238:22715,35239:22717,35240:22718,35241:22719,35242:22720,35243:22722,35244:22723,35245:22724,35246:22726,35247:22727,35248:22728,35249:22729,35250:22730,35251:22731,35252:22732,35253:22733,35254:22734,35255:22735,35256:22736,35257:22738,35258:22739,35259:22740,35260:22742,35261:22743,35262:22744,35263:22745,35264:22746,35265:22747,35266:22748,35267:22749,35268:22750,35269:22751,35270:22752,35271:22753,35272:22754,35273:22755,35274:22757,35275:22758,35276:22759,35277:22760,35278:22761,35279:22762,35280:22765,35281:22767,35282:22769,35283:22770,35284:22772,35285:22773,35286:22775,35287:22776,35288:22778,35289:22779,35290:22780,35291:22781,35292:22782,35293:22783,35294:22784,35295:22785,35296:22787,35297:22789,35298:22790,35299:22792,35300:22793,35301:22794,35302:22795,35303:22796,35304:22798,35305:22800,35306:22801,35307:22802,35308:22803,35309:22807,35310:22808,35311:22811,35312:22813,35313:22814,35314:22816,35315:22817,35316:22818,35317:22819,35318:22822,35319:22824,35320:22828,35321:22832,35322:22834,35323:22835,35324:22837,35325:22838,35326:22843,35392:22845,35393:22846,35394:22847,35395:22848,35396:22851,35397:22853,35398:22854,35399:22858,35400:22860,35401:22861,35402:22864,35403:22866,35404:22867,35405:22873,35406:22875,35407:22876,35408:22877,35409:22878,35410:22879,35411:22881,35412:22883,35413:22884,35414:22886,35415:22887,35416:22888,35417:22889,35418:22890,35419:22891,35420:22892,35421:22893,35422:22894,35423:22895,35424:22896,35425:22897,35426:22898,35427:22901,35428:22903,35429:22906,35430:22907,35431:22908,35432:22910,35433:22911,35434:22912,35435:22917,35436:22921,35437:22923,35438:22924,35439:22926,35440:22927,35441:22928,35442:22929,35443:22932,35444:22933,35445:22936,35446:22938,35447:22939,35448:22940,35449:22941,35450:22943,35451:22944,35452:22945,35453:22946,35454:22950,35456:22951,35457:22956,35458:22957,35459:22960,35460:22961,35461:22963,35462:22964,35463:22965,35464:22966,35465:22967,35466:22968,35467:22970,35468:22972,35469:22973,35470:22975,35471:22976,35472:22977,35473:22978,35474:22979,35475:22980,35476:22981,35477:22983,35478:22984,35479:22985,35480:22988,35481:22989,35482:22990,35483:22991,35484:22997,35485:22998,35486:23001,35487:23003,35488:23006,35489:23007,35490:23008,35491:23009,35492:23010,35493:23012,35494:23014,35495:23015,35496:23017,35497:23018,35498:23019,35499:23021,35500:23022,35501:23023,35502:23024,35503:23025,35504:23026,35505:23027,35506:23028,35507:23029,35508:23030,35509:23031,35510:23032,35511:23034,35512:23036,35513:23037,35514:23038,35515:23040,35516:23042,35517:23050,35518:23051,35519:23053,35520:23054,35521:23055,35522:23056,35523:23058,35524:23060,35525:23061,35526:23062,35527:23063,35528:23065,35529:23066,35530:23067,35531:23069,35532:23070,35533:23073,35534:23074,35535:23076,35536:23078,35537:23079,35538:23080,35539:23082,35540:23083,35541:23084,35542:23085,35543:23086,35544:23087,35545:23088,35546:23091,35547:23093,35548:23095,35549:23096,35550:23097,35551:23098,35552:23099,35553:23101,35554:23102,35555:23103,35556:23105,35557:23106,35558:23107,35559:23108,35560:23109,35561:23111,35562:23112,35563:23115,35564:23116,35565:23117,35566:23118,35567:23119,35568:23120,35569:23121,35570:23122,35571:23123,35572:23124,35573:23126,35574:23127,35575:23128,35576:23129,35577:23131,35578:23132,35579:23133,35580:23134,35581:23135,35582:23136,35648:23137,35649:23139,35650:23140,35651:23141,35652:23142,35653:23144,35654:23145,35655:23147,35656:23148,35657:23149,35658:23150,35659:23151,35660:23152,35661:23153,35662:23154,35663:23155,35664:23160,35665:23161,35666:23163,35667:23164,35668:23165,35669:23166,35670:23168,35671:23169,35672:23170,35673:23171,35674:23172,35675:23173,35676:23174,35677:23175,35678:23176,35679:23177,35680:23178,35681:23179,35682:23180,35683:23181,35684:23182,35685:23183,35686:23184,35687:23185,35688:23187,35689:23188,35690:23189,35691:23190,35692:23191,35693:23192,35694:23193,35695:23196,35696:23197,35697:23198,35698:23199,35699:23200,35700:23201,35701:23202,35702:23203,35703:23204,35704:23205,35705:23206,35706:23207,35707:23208,35708:23209,35709:23211,35710:23212,35712:23213,35713:23214,35714:23215,35715:23216,35716:23217,35717:23220,35718:23222,35719:23223,35720:23225,35721:23226,35722:23227,35723:23228,35724:23229,35725:23231,35726:23232,35727:23235,35728:23236,35729:23237,35730:23238,35731:23239,35732:23240,35733:23242,35734:23243,35735:23245,35736:23246,35737:23247,35738:23248,35739:23249,35740:23251,35741:23253,35742:23255,35743:23257,35744:23258,35745:23259,35746:23261,35747:23262,35748:23263,35749:23266,35750:23268,35751:23269,35752:23271,35753:23272,35754:23274,35755:23276,35756:23277,35757:23278,35758:23279,35759:23280,35760:23282,35761:23283,35762:23284,35763:23285,35764:23286,35765:23287,35766:23288,35767:23289,35768:23290,35769:23291,35770:23292,35771:23293,35772:23294,35773:23295,35774:23296,35775:23297,35776:23298,35777:23299,35778:23300,35779:23301,35780:23302,35781:23303,35782:23304,35783:23306,35784:23307,35785:23308,35786:23309,35787:23310,35788:23311,35789:23312,35790:23313,35791:23314,35792:23315,35793:23316,35794:23317,35795:23320,35796:23321,35797:23322,35798:23323,35799:23324,35800:23325,35801:23326,35802:23327,35803:23328,35804:23329,35805:23330,35806:23331,35807:23332,35808:23333,35809:23334,35810:23335,35811:23336,35812:23337,35813:23338,35814:23339,35815:23340,35816:23341,35817:23342,35818:23343,35819:23344,35820:23345,35821:23347,35822:23349,35823:23350,35824:23352,35825:23353,35826:23354,35827:23355,35828:23356,35829:23357,35830:23358,35831:23359,35832:23361,35833:23362,35834:23363,35835:23364,35836:23365,35837:23366,35838:23367,35904:23368,35905:23369,35906:23370,35907:23371,35908:23372,35909:23373,35910:23374,35911:23375,35912:23378,35913:23382,35914:23390,35915:23392,35916:23393,35917:23399,35918:23400,35919:23403,35920:23405,35921:23406,35922:23407,35923:23410,35924:23412,35925:23414,35926:23415,35927:23416,35928:23417,35929:23419,35930:23420,35931:23422,35932:23423,35933:23426,35934:23430,35935:23434,35936:23437,35937:23438,35938:23440,35939:23441,35940:23442,35941:23444,35942:23446,35943:23455,35944:23463,35945:23464,35946:23465,35947:23468,35948:23469,35949:23470,35950:23471,35951:23473,35952:23474,35953:23479,35954:23482,35955:23483,35956:23484,35957:23488,35958:23489,35959:23491,35960:23496,35961:23497,35962:23498,35963:23499,35964:23501,35965:23502,35966:23503,35968:23505,35969:23508,35970:23509,35971:23510,35972:23511,35973:23512,35974:23513,35975:23514,35976:23515,35977:23516,35978:23520,35979:23522,35980:23523,35981:23526,35982:23527,35983:23529,35984:23530,35985:23531,35986:23532,35987:23533,35988:23535,35989:23537,35990:23538,35991:23539,35992:23540,35993:23541,35994:23542,35995:23543,35996:23549,35997:23550,35998:23552,35999:23554,36000:23555,36001:23557,36002:23559,36003:23560,36004:23563,36005:23564,36006:23565,36007:23566,36008:23568,36009:23570,36010:23571,36011:23575,36012:23577,36013:23579,36014:23582,36015:23583,36016:23584,36017:23585,36018:23587,36019:23590,36020:23592,36021:23593,36022:23594,36023:23595,36024:23597,36025:23598,36026:23599,36027:23600,36028:23602,36029:23603,36030:23605,36031:23606,36032:23607,36033:23619,36034:23620,36035:23622,36036:23623,36037:23628,36038:23629,36039:23634,36040:23635,36041:23636,36042:23638,36043:23639,36044:23640,36045:23642,36046:23643,36047:23644,36048:23645,36049:23647,36050:23650,36051:23652,36052:23655,36053:23656,36054:23657,36055:23658,36056:23659,36057:23660,36058:23661,36059:23664,36060:23666,36061:23667,36062:23668,36063:23669,36064:23670,36065:23671,36066:23672,36067:23675,36068:23676,36069:23677,36070:23678,36071:23680,36072:23683,36073:23684,36074:23685,36075:23686,36076:23687,36077:23689,36078:23690,36079:23691,36080:23694,36081:23695,36082:23698,36083:23699,36084:23701,36085:23709,36086:23710,36087:23711,36088:23712,36089:23713,36090:23716,36091:23717,36092:23718,36093:23719,36094:23720,36160:23722,36161:23726,36162:23727,36163:23728,36164:23730,36165:23732,36166:23734,36167:23737,36168:23738,36169:23739,36170:23740,36171:23742,36172:23744,36173:23746,36174:23747,36175:23749,36176:23750,36177:23751,36178:23752,36179:23753,36180:23754,36181:23756,36182:23757,36183:23758,36184:23759,36185:23760,36186:23761,36187:23763,36188:23764,36189:23765,36190:23766,36191:23767,36192:23768,36193:23770,36194:23771,36195:23772,36196:23773,36197:23774,36198:23775,36199:23776,36200:23778,36201:23779,36202:23783,36203:23785,36204:23787,36205:23788,36206:23790,36207:23791,36208:23793,36209:23794,36210:23795,36211:23796,36212:23797,36213:23798,36214:23799,36215:23800,36216:23801,36217:23802,36218:23804,36219:23805,36220:23806,36221:23807,36222:23808,36224:23809,36225:23812,36226:23813,36227:23816,36228:23817,36229:23818,36230:23819,36231:23820,36232:23821,36233:23823,36234:23824,36235:23825,36236:23826,36237:23827,36238:23829,36239:23831,36240:23832,36241:23833,36242:23834,36243:23836,36244:23837,36245:23839,36246:23840,36247:23841,36248:23842,36249:23843,36250:23845,36251:23848,36252:23850,36253:23851,36254:23852,36255:23855,36256:23856,36257:23857,36258:23858,36259:23859,36260:23861,36261:23862,36262:23863,36263:23864,36264:23865,36265:23866,36266:23867,36267:23868,36268:23871,36269:23872,36270:23873,36271:23874,36272:23875,36273:23876,36274:23877,36275:23878,36276:23880,36277:23881,36278:23885,36279:23886,36280:23887,36281:23888,36282:23889,36283:23890,36284:23891,36285:23892,36286:23893,36287:23894,36288:23895,36289:23897,36290:23898,36291:23900,36292:23902,36293:23903,36294:23904,36295:23905,36296:23906,36297:23907,36298:23908,36299:23909,36300:23910,36301:23911,36302:23912,36303:23914,36304:23917,36305:23918,36306:23920,36307:23921,36308:23922,36309:23923,36310:23925,36311:23926,36312:23927,36313:23928,36314:23929,36315:23930,36316:23931,36317:23932,36318:23933,36319:23934,36320:23935,36321:23936,36322:23937,36323:23939,36324:23940,36325:23941,36326:23942,36327:23943,36328:23944,36329:23945,36330:23946,36331:23947,36332:23948,36333:23949,36334:23950,36335:23951,36336:23952,36337:23953,36338:23954,36339:23955,36340:23956,36341:23957,36342:23958,36343:23959,36344:23960,36345:23962,36346:23963,36347:23964,36348:23966,36349:23967,36350:23968,36416:23969,36417:23970,36418:23971,36419:23972,36420:23973,36421:23974,36422:23975,36423:23976,36424:23977,36425:23978,36426:23979,36427:23980,36428:23981,36429:23982,36430:23983,36431:23984,36432:23985,36433:23986,36434:23987,36435:23988,36436:23989,36437:23990,36438:23992,36439:23993,36440:23994,36441:23995,36442:23996,36443:23997,36444:23998,36445:23999,36446:24000,36447:24001,36448:24002,36449:24003,36450:24004,36451:24006,36452:24007,36453:24008,36454:24009,36455:24010,36456:24011,36457:24012,36458:24014,36459:24015,36460:24016,36461:24017,36462:24018,36463:24019,36464:24020,36465:24021,36466:24022,36467:24023,36468:24024,36469:24025,36470:24026,36471:24028,36472:24031,36473:24032,36474:24035,36475:24036,36476:24042,36477:24044,36478:24045,36480:24048,36481:24053,36482:24054,36483:24056,36484:24057,36485:24058,36486:24059,36487:24060,36488:24063,36489:24064,36490:24068,36491:24071,36492:24073,36493:24074,36494:24075,36495:24077,36496:24078,36497:24082,36498:24083,36499:24087,36500:24094,36501:24095,36502:24096,36503:24097,36504:24098,36505:24099,36506:24100,36507:24101,36508:24104,36509:24105,36510:24106,36511:24107,36512:24108,36513:24111,36514:24112,36515:24114,36516:24115,36517:24116,36518:24117,36519:24118,36520:24121,36521:24122,36522:24126,36523:24127,36524:24128,36525:24129,36526:24131,36527:24134,36528:24135,36529:24136,36530:24137,36531:24138,36532:24139,36533:24141,36534:24142,36535:24143,36536:24144,36537:24145,36538:24146,36539:24147,36540:24150,36541:24151,36542:24152,36543:24153,36544:24154,36545:24156,36546:24157,36547:24159,36548:24160,36549:24163,36550:24164,36551:24165,36552:24166,36553:24167,36554:24168,36555:24169,36556:24170,36557:24171,36558:24172,36559:24173,36560:24174,36561:24175,36562:24176,36563:24177,36564:24181,36565:24183,36566:24185,36567:24190,36568:24193,36569:24194,36570:24195,36571:24197,36572:24200,36573:24201,36574:24204,36575:24205,36576:24206,36577:24210,36578:24216,36579:24219,36580:24221,36581:24225,36582:24226,36583:24227,36584:24228,36585:24232,36586:24233,36587:24234,36588:24235,36589:24236,36590:24238,36591:24239,36592:24240,36593:24241,36594:24242,36595:24244,36596:24250,36597:24251,36598:24252,36599:24253,36600:24255,36601:24256,36602:24257,36603:24258,36604:24259,36605:24260,36606:24261,36672:24262,36673:24263,36674:24264,36675:24267,36676:24268,36677:24269,36678:24270,36679:24271,36680:24272,36681:24276,36682:24277,36683:24279,36684:24280,36685:24281,36686:24282,36687:24284,36688:24285,36689:24286,36690:24287,36691:24288,36692:24289,36693:24290,36694:24291,36695:24292,36696:24293,36697:24294,36698:24295,36699:24297,36700:24299,36701:24300,36702:24301,36703:24302,36704:24303,36705:24304,36706:24305,36707:24306,36708:24307,36709:24309,36710:24312,36711:24313,36712:24315,36713:24316,36714:24317,36715:24325,36716:24326,36717:24327,36718:24329,36719:24332,36720:24333,36721:24334,36722:24336,36723:24338,36724:24340,36725:24342,36726:24345,36727:24346,36728:24348,36729:24349,36730:24350,36731:24353,36732:24354,36733:24355,36734:24356,36736:24360,36737:24363,36738:24364,36739:24366,36740:24368,36741:24370,36742:24371,36743:24372,36744:24373,36745:24374,36746:24375,36747:24376,36748:24379,36749:24381,36750:24382,36751:24383,36752:24385,36753:24386,36754:24387,36755:24388,36756:24389,36757:24390,36758:24391,36759:24392,36760:24393,36761:24394,36762:24395,36763:24396,36764:24397,36765:24398,36766:24399,36767:24401,36768:24404,36769:24409,36770:24410,36771:24411,36772:24412,36773:24414,36774:24415,36775:24416,36776:24419,36777:24421,36778:24423,36779:24424,36780:24427,36781:24430,36782:24431,36783:24434,36784:24436,36785:24437,36786:24438,36787:24440,36788:24442,36789:24445,36790:24446,36791:24447,36792:24451,36793:24454,36794:24461,36795:24462,36796:24463,36797:24465,36798:24467,36799:24468,36800:24470,36801:24474,36802:24475,36803:24477,36804:24478,36805:24479,36806:24480,36807:24482,36808:24483,36809:24484,36810:24485,36811:24486,36812:24487,36813:24489,36814:24491,36815:24492,36816:24495,36817:24496,36818:24497,36819:24498,36820:24499,36821:24500,36822:24502,36823:24504,36824:24505,36825:24506,36826:24507,36827:24510,36828:24511,36829:24512,36830:24513,36831:24514,36832:24519,36833:24520,36834:24522,36835:24523,36836:24526,36837:24531,36838:24532,36839:24533,36840:24538,36841:24539,36842:24540,36843:24542,36844:24543,36845:24546,36846:24547,36847:24549,36848:24550,36849:24552,36850:24553,36851:24556,36852:24559,36853:24560,36854:24562,36855:24563,36856:24564,36857:24566,36858:24567,36859:24569,36860:24570,36861:24572,36862:24583,36928:24584,36929:24585,36930:24587,36931:24588,36932:24592,36933:24593,36934:24595,36935:24599,36936:24600,36937:24602,36938:24606,36939:24607,36940:24610,36941:24611,36942:24612,36943:24620,36944:24621,36945:24622,36946:24624,36947:24625,36948:24626,36949:24627,36950:24628,36951:24630,36952:24631,36953:24632,36954:24633,36955:24634,36956:24637,36957:24638,36958:24640,36959:24644,36960:24645,36961:24646,36962:24647,36963:24648,36964:24649,36965:24650,36966:24652,36967:24654,36968:24655,36969:24657,36970:24659,36971:24660,36972:24662,36973:24663,36974:24664,36975:24667,36976:24668,36977:24670,36978:24671,36979:24672,36980:24673,36981:24677,36982:24678,36983:24686,36984:24689,36985:24690,36986:24692,36987:24693,36988:24695,36989:24702,36990:24704,36992:24705,36993:24706,36994:24709,36995:24710,36996:24711,36997:24712,36998:24714,36999:24715,37000:24718,37001:24719,37002:24720,37003:24721,37004:24723,37005:24725,37006:24727,37007:24728,37008:24729,37009:24732,37010:24734,37011:24737,37012:24738,37013:24740,37014:24741,37015:24743,37016:24745,37017:24746,37018:24750,37019:24752,37020:24755,37021:24757,37022:24758,37023:24759,37024:24761,37025:24762,37026:24765,37027:24766,37028:24767,37029:24768,37030:24769,37031:24770,37032:24771,37033:24772,37034:24775,37035:24776,37036:24777,37037:24780,37038:24781,37039:24782,37040:24783,37041:24784,37042:24786,37043:24787,37044:24788,37045:24790,37046:24791,37047:24793,37048:24795,37049:24798,37050:24801,37051:24802,37052:24803,37053:24804,37054:24805,37055:24810,37056:24817,37057:24818,37058:24821,37059:24823,37060:24824,37061:24827,37062:24828,37063:24829,37064:24830,37065:24831,37066:24834,37067:24835,37068:24836,37069:24837,37070:24839,37071:24842,37072:24843,37073:24844,37074:24848,37075:24849,37076:24850,37077:24851,37078:24852,37079:24854,37080:24855,37081:24856,37082:24857,37083:24859,37084:24860,37085:24861,37086:24862,37087:24865,37088:24866,37089:24869,37090:24872,37091:24873,37092:24874,37093:24876,37094:24877,37095:24878,37096:24879,37097:24880,37098:24881,37099:24882,37100:24883,37101:24884,37102:24885,37103:24886,37104:24887,37105:24888,37106:24889,37107:24890,37108:24891,37109:24892,37110:24893,37111:24894,37112:24896,37113:24897,37114:24898,37115:24899,37116:24900,37117:24901,37118:24902,37184:24903,37185:24905,37186:24907,37187:24909,37188:24911,37189:24912,37190:24914,37191:24915,37192:24916,37193:24918,37194:24919,37195:24920,37196:24921,37197:24922,37198:24923,37199:24924,37200:24926,37201:24927,37202:24928,37203:24929,37204:24931,37205:24932,37206:24933,37207:24934,37208:24937,37209:24938,37210:24939,37211:24940,37212:24941,37213:24942,37214:24943,37215:24945,37216:24946,37217:24947,37218:24948,37219:24950,37220:24952,37221:24953,37222:24954,37223:24955,37224:24956,37225:24957,37226:24958,37227:24959,37228:24960,37229:24961,37230:24962,37231:24963,37232:24964,37233:24965,37234:24966,37235:24967,37236:24968,37237:24969,37238:24970,37239:24972,37240:24973,37241:24975,37242:24976,37243:24977,37244:24978,37245:24979,37246:24981,37248:24982,37249:24983,37250:24984,37251:24985,37252:24986,37253:24987,37254:24988,37255:24990,37256:24991,37257:24992,37258:24993,37259:24994,37260:24995,37261:24996,37262:24997,37263:24998,37264:25002,37265:25003,37266:25005,37267:25006,37268:25007,37269:25008,37270:25009,37271:25010,37272:25011,37273:25012,37274:25013,37275:25014,37276:25016,37277:25017,37278:25018,37279:25019,37280:25020,37281:25021,37282:25023,37283:25024,37284:25025,37285:25027,37286:25028,37287:25029,37288:25030,37289:25031,37290:25033,37291:25036,37292:25037,37293:25038,37294:25039,37295:25040,37296:25043,37297:25045,37298:25046,37299:25047,37300:25048,37301:25049,37302:25050,37303:25051,37304:25052,37305:25053,37306:25054,37307:25055,37308:25056,37309:25057,37310:25058,37311:25059,37312:25060,37313:25061,37314:25063,37315:25064,37316:25065,37317:25066,37318:25067,37319:25068,37320:25069,37321:25070,37322:25071,37323:25072,37324:25073,37325:25074,37326:25075,37327:25076,37328:25078,37329:25079,37330:25080,37331:25081,37332:25082,37333:25083,37334:25084,37335:25085,37336:25086,37337:25088,37338:25089,37339:25090,37340:25091,37341:25092,37342:25093,37343:25095,37344:25097,37345:25107,37346:25108,37347:25113,37348:25116,37349:25117,37350:25118,37351:25120,37352:25123,37353:25126,37354:25127,37355:25128,37356:25129,37357:25131,37358:25133,37359:25135,37360:25136,37361:25137,37362:25138,37363:25141,37364:25142,37365:25144,37366:25145,37367:25146,37368:25147,37369:25148,37370:25154,37371:25156,37372:25157,37373:25158,37374:25162,37440:25167,37441:25168,37442:25173,37443:25174,37444:25175,37445:25177,37446:25178,37447:25180,37448:25181,37449:25182,37450:25183,37451:25184,37452:25185,37453:25186,37454:25188,37455:25189,37456:25192,37457:25201,37458:25202,37459:25204,37460:25205,37461:25207,37462:25208,37463:25210,37464:25211,37465:25213,37466:25217,37467:25218,37468:25219,37469:25221,37470:25222,37471:25223,37472:25224,37473:25227,37474:25228,37475:25229,37476:25230,37477:25231,37478:25232,37479:25236,37480:25241,37481:25244,37482:25245,37483:25246,37484:25251,37485:25254,37486:25255,37487:25257,37488:25258,37489:25261,37490:25262,37491:25263,37492:25264,37493:25266,37494:25267,37495:25268,37496:25270,37497:25271,37498:25272,37499:25274,37500:25278,37501:25280,37502:25281,37504:25283,37505:25291,37506:25295,37507:25297,37508:25301,37509:25309,37510:25310,37511:25312,37512:25313,37513:25316,37514:25322,37515:25323,37516:25328,37517:25330,37518:25333,37519:25336,37520:25337,37521:25338,37522:25339,37523:25344,37524:25347,37525:25348,37526:25349,37527:25350,37528:25354,37529:25355,37530:25356,37531:25357,37532:25359,37533:25360,37534:25362,37535:25363,37536:25364,37537:25365,37538:25367,37539:25368,37540:25369,37541:25372,37542:25382,37543:25383,37544:25385,37545:25388,37546:25389,37547:25390,37548:25392,37549:25393,37550:25395,37551:25396,37552:25397,37553:25398,37554:25399,37555:25400,37556:25403,37557:25404,37558:25406,37559:25407,37560:25408,37561:25409,37562:25412,37563:25415,37564:25416,37565:25418,37566:25425,37567:25426,37568:25427,37569:25428,37570:25430,37571:25431,37572:25432,37573:25433,37574:25434,37575:25435,37576:25436,37577:25437,37578:25440,37579:25444,37580:25445,37581:25446,37582:25448,37583:25450,37584:25451,37585:25452,37586:25455,37587:25456,37588:25458,37589:25459,37590:25460,37591:25461,37592:25464,37593:25465,37594:25468,37595:25469,37596:25470,37597:25471,37598:25473,37599:25475,37600:25476,37601:25477,37602:25478,37603:25483,37604:25485,37605:25489,37606:25491,37607:25492,37608:25493,37609:25495,37610:25497,37611:25498,37612:25499,37613:25500,37614:25501,37615:25502,37616:25503,37617:25505,37618:25508,37619:25510,37620:25515,37621:25519,37622:25521,37623:25522,37624:25525,37625:25526,37626:25529,37627:25531,37628:25533,37629:25535,37630:25536,37696:25537,37697:25538,37698:25539,37699:25541,37700:25543,37701:25544,37702:25546,37703:25547,37704:25548,37705:25553,37706:25555,37707:25556,37708:25557,37709:25559,37710:25560,37711:25561,37712:25562,37713:25563,37714:25564,37715:25565,37716:25567,37717:25570,37718:25572,37719:25573,37720:25574,37721:25575,37722:25576,37723:25579,37724:25580,37725:25582,37726:25583,37727:25584,37728:25585,37729:25587,37730:25589,37731:25591,37732:25593,37733:25594,37734:25595,37735:25596,37736:25598,37737:25603,37738:25604,37739:25606,37740:25607,37741:25608,37742:25609,37743:25610,37744:25613,37745:25614,37746:25617,37747:25618,37748:25621,37749:25622,37750:25623,37751:25624,37752:25625,37753:25626,37754:25629,37755:25631,37756:25634,37757:25635,37758:25636,37760:25637,37761:25639,37762:25640,37763:25641,37764:25643,37765:25646,37766:25647,37767:25648,37768:25649,37769:25650,37770:25651,37771:25653,37772:25654,37773:25655,37774:25656,37775:25657,37776:25659,37777:25660,37778:25662,37779:25664,37780:25666,37781:25667,37782:25673,37783:25675,37784:25676,37785:25677,37786:25678,37787:25679,37788:25680,37789:25681,37790:25683,37791:25685,37792:25686,37793:25687,37794:25689,37795:25690,37796:25691,37797:25692,37798:25693,37799:25695,37800:25696,37801:25697,37802:25698,37803:25699,37804:25700,37805:25701,37806:25702,37807:25704,37808:25706,37809:25707,37810:25708,37811:25710,37812:25711,37813:25712,37814:25713,37815:25714,37816:25715,37817:25716,37818:25717,37819:25718,37820:25719,37821:25723,37822:25724,37823:25725,37824:25726,37825:25727,37826:25728,37827:25729,37828:25731,37829:25734,37830:25736,37831:25737,37832:25738,37833:25739,37834:25740,37835:25741,37836:25742,37837:25743,37838:25744,37839:25747,37840:25748,37841:25751,37842:25752,37843:25754,37844:25755,37845:25756,37846:25757,37847:25759,37848:25760,37849:25761,37850:25762,37851:25763,37852:25765,37853:25766,37854:25767,37855:25768,37856:25770,37857:25771,37858:25775,37859:25777,37860:25778,37861:25779,37862:25780,37863:25782,37864:25785,37865:25787,37866:25789,37867:25790,37868:25791,37869:25793,37870:25795,37871:25796,37872:25798,37873:25799,37874:25800,37875:25801,37876:25802,37877:25803,37878:25804,37879:25807,37880:25809,37881:25811,37882:25812,37883:25813,37884:25814,37885:25817,37886:25818,37952:25819,37953:25820,37954:25821,37955:25823,37956:25824,37957:25825,37958:25827,37959:25829,37960:25831,37961:25832,37962:25833,37963:25834,37964:25835,37965:25836,37966:25837,37967:25838,37968:25839,37969:25840,37970:25841,37971:25842,37972:25843,37973:25844,37974:25845,37975:25846,37976:25847,37977:25848,37978:25849,37979:25850,37980:25851,37981:25852,37982:25853,37983:25854,37984:25855,37985:25857,37986:25858,37987:25859,37988:25860,37989:25861,37990:25862,37991:25863,37992:25864,37993:25866,37994:25867,37995:25868,37996:25869,37997:25870,37998:25871,37999:25872,38000:25873,38001:25875,38002:25876,38003:25877,38004:25878,38005:25879,38006:25881,38007:25882,38008:25883,38009:25884,38010:25885,38011:25886,38012:25887,38013:25888,38014:25889,38016:25890,38017:25891,38018:25892,38019:25894,38020:25895,38021:25896,38022:25897,38023:25898,38024:25900,38025:25901,38026:25904,38027:25905,38028:25906,38029:25907,38030:25911,38031:25914,38032:25916,38033:25917,38034:25920,38035:25921,38036:25922,38037:25923,38038:25924,38039:25926,38040:25927,38041:25930,38042:25931,38043:25933,38044:25934,38045:25936,38046:25938,38047:25939,38048:25940,38049:25943,38050:25944,38051:25946,38052:25948,38053:25951,38054:25952,38055:25953,38056:25956,38057:25957,38058:25959,38059:25960,38060:25961,38061:25962,38062:25965,38063:25966,38064:25967,38065:25969,38066:25971,38067:25973,38068:25974,38069:25976,38070:25977,38071:25978,38072:25979,38073:25980,38074:25981,38075:25982,38076:25983,38077:25984,38078:25985,38079:25986,38080:25987,38081:25988,38082:25989,38083:25990,38084:25992,38085:25993,38086:25994,38087:25997,38088:25998,38089:25999,38090:26002,38091:26004,38092:26005,38093:26006,38094:26008,38095:26010,38096:26013,38097:26014,38098:26016,38099:26018,38100:26019,38101:26022,38102:26024,38103:26026,38104:26028,38105:26030,38106:26033,38107:26034,38108:26035,38109:26036,38110:26037,38111:26038,38112:26039,38113:26040,38114:26042,38115:26043,38116:26046,38117:26047,38118:26048,38119:26050,38120:26055,38121:26056,38122:26057,38123:26058,38124:26061,38125:26064,38126:26065,38127:26067,38128:26068,38129:26069,38130:26072,38131:26073,38132:26074,38133:26075,38134:26076,38135:26077,38136:26078,38137:26079,38138:26081,38139:26083,38140:26084,38141:26090,38142:26091,38208:26098,38209:26099,38210:26100,38211:26101,38212:26104,38213:26105,38214:26107,38215:26108,38216:26109,38217:26110,38218:26111,38219:26113,38220:26116,38221:26117,38222:26119,38223:26120,38224:26121,38225:26123,38226:26125,38227:26128,38228:26129,38229:26130,38230:26134,38231:26135,38232:26136,38233:26138,38234:26139,38235:26140,38236:26142,38237:26145,38238:26146,38239:26147,38240:26148,38241:26150,38242:26153,38243:26154,38244:26155,38245:26156,38246:26158,38247:26160,38248:26162,38249:26163,38250:26167,38251:26168,38252:26169,38253:26170,38254:26171,38255:26173,38256:26175,38257:26176,38258:26178,38259:26180,38260:26181,38261:26182,38262:26183,38263:26184,38264:26185,38265:26186,38266:26189,38267:26190,38268:26192,38269:26193,38270:26200,38272:26201,38273:26203,38274:26204,38275:26205,38276:26206,38277:26208,38278:26210,38279:26211,38280:26213,38281:26215,38282:26217,38283:26218,38284:26219,38285:26220,38286:26221,38287:26225,38288:26226,38289:26227,38290:26229,38291:26232,38292:26233,38293:26235,38294:26236,38295:26237,38296:26239,38297:26240,38298:26241,38299:26243,38300:26245,38301:26246,38302:26248,38303:26249,38304:26250,38305:26251,38306:26253,38307:26254,38308:26255,38309:26256,38310:26258,38311:26259,38312:26260,38313:26261,38314:26264,38315:26265,38316:26266,38317:26267,38318:26268,38319:26270,38320:26271,38321:26272,38322:26273,38323:26274,38324:26275,38325:26276,38326:26277,38327:26278,38328:26281,38329:26282,38330:26283,38331:26284,38332:26285,38333:26287,38334:26288,38335:26289,38336:26290,38337:26291,38338:26293,38339:26294,38340:26295,38341:26296,38342:26298,38343:26299,38344:26300,38345:26301,38346:26303,38347:26304,38348:26305,38349:26306,38350:26307,38351:26308,38352:26309,38353:26310,38354:26311,38355:26312,38356:26313,38357:26314,38358:26315,38359:26316,38360:26317,38361:26318,38362:26319,38363:26320,38364:26321,38365:26322,38366:26323,38367:26324,38368:26325,38369:26326,38370:26327,38371:26328,38372:26330,38373:26334,38374:26335,38375:26336,38376:26337,38377:26338,38378:26339,38379:26340,38380:26341,38381:26343,38382:26344,38383:26346,38384:26347,38385:26348,38386:26349,38387:26350,38388:26351,38389:26353,38390:26357,38391:26358,38392:26360,38393:26362,38394:26363,38395:26365,38396:26369,38397:26370,38398:26371,38464:26372,38465:26373,38466:26374,38467:26375,38468:26380,38469:26382,38470:26383,38471:26385,38472:26386,38473:26387,38474:26390,38475:26392,38476:26393,38477:26394,38478:26396,38479:26398,38480:26400,38481:26401,38482:26402,38483:26403,38484:26404,38485:26405,38486:26407,38487:26409,38488:26414,38489:26416,38490:26418,38491:26419,38492:26422,38493:26423,38494:26424,38495:26425,38496:26427,38497:26428,38498:26430,38499:26431,38500:26433,38501:26436,38502:26437,38503:26439,38504:26442,38505:26443,38506:26445,38507:26450,38508:26452,38509:26453,38510:26455,38511:26456,38512:26457,38513:26458,38514:26459,38515:26461,38516:26466,38517:26467,38518:26468,38519:26470,38520:26471,38521:26475,38522:26476,38523:26478,38524:26481,38525:26484,38526:26486,38528:26488,38529:26489,38530:26490,38531:26491,38532:26493,38533:26496,38534:26498,38535:26499,38536:26501,38537:26502,38538:26504,38539:26506,38540:26508,38541:26509,38542:26510,38543:26511,38544:26513,38545:26514,38546:26515,38547:26516,38548:26518,38549:26521,38550:26523,38551:26527,38552:26528,38553:26529,38554:26532,38555:26534,38556:26537,38557:26540,38558:26542,38559:26545,38560:26546,38561:26548,38562:26553,38563:26554,38564:26555,38565:26556,38566:26557,38567:26558,38568:26559,38569:26560,38570:26562,38571:26565,38572:26566,38573:26567,38574:26568,38575:26569,38576:26570,38577:26571,38578:26572,38579:26573,38580:26574,38581:26581,38582:26582,38583:26583,38584:26587,38585:26591,38586:26593,38587:26595,38588:26596,38589:26598,38590:26599,38591:26600,38592:26602,38593:26603,38594:26605,38595:26606,38596:26610,38597:26613,38598:26614,38599:26615,38600:26616,38601:26617,38602:26618,38603:26619,38604:26620,38605:26622,38606:26625,38607:26626,38608:26627,38609:26628,38610:26630,38611:26637,38612:26640,38613:26642,38614:26644,38615:26645,38616:26648,38617:26649,38618:26650,38619:26651,38620:26652,38621:26654,38622:26655,38623:26656,38624:26658,38625:26659,38626:26660,38627:26661,38628:26662,38629:26663,38630:26664,38631:26667,38632:26668,38633:26669,38634:26670,38635:26671,38636:26672,38637:26673,38638:26676,38639:26677,38640:26678,38641:26682,38642:26683,38643:26687,38644:26695,38645:26699,38646:26701,38647:26703,38648:26706,38649:26710,38650:26711,38651:26712,38652:26713,38653:26714,38654:26715,38720:26716,38721:26717,38722:26718,38723:26719,38724:26730,38725:26732,38726:26733,38727:26734,38728:26735,38729:26736,38730:26737,38731:26738,38732:26739,38733:26741,38734:26744,38735:26745,38736:26746,38737:26747,38738:26748,38739:26749,38740:26750,38741:26751,38742:26752,38743:26754,38744:26756,38745:26759,38746:26760,38747:26761,38748:26762,38749:26763,38750:26764,38751:26765,38752:26766,38753:26768,38754:26769,38755:26770,38756:26772,38757:26773,38758:26774,38759:26776,38760:26777,38761:26778,38762:26779,38763:26780,38764:26781,38765:26782,38766:26783,38767:26784,38768:26785,38769:26787,38770:26788,38771:26789,38772:26793,38773:26794,38774:26795,38775:26796,38776:26798,38777:26801,38778:26802,38779:26804,38780:26806,38781:26807,38782:26808,38784:26809,38785:26810,38786:26811,38787:26812,38788:26813,38789:26814,38790:26815,38791:26817,38792:26819,38793:26820,38794:26821,38795:26822,38796:26823,38797:26824,38798:26826,38799:26828,38800:26830,38801:26831,38802:26832,38803:26833,38804:26835,38805:26836,38806:26838,38807:26839,38808:26841,38809:26843,38810:26844,38811:26845,38812:26846,38813:26847,38814:26849,38815:26850,38816:26852,38817:26853,38818:26854,38819:26855,38820:26856,38821:26857,38822:26858,38823:26859,38824:26860,38825:26861,38826:26863,38827:26866,38828:26867,38829:26868,38830:26870,38831:26871,38832:26872,38833:26875,38834:26877,38835:26878,38836:26879,38837:26880,38838:26882,38839:26883,38840:26884,38841:26886,38842:26887,38843:26888,38844:26889,38845:26890,38846:26892,38847:26895,38848:26897,38849:26899,38850:26900,38851:26901,38852:26902,38853:26903,38854:26904,38855:26905,38856:26906,38857:26907,38858:26908,38859:26909,38860:26910,38861:26913,38862:26914,38863:26915,38864:26917,38865:26918,38866:26919,38867:26920,38868:26921,38869:26922,38870:26923,38871:26924,38872:26926,38873:26927,38874:26929,38875:26930,38876:26931,38877:26933,38878:26934,38879:26935,38880:26936,38881:26938,38882:26939,38883:26940,38884:26942,38885:26944,38886:26945,38887:26947,38888:26948,38889:26949,38890:26950,38891:26951,38892:26952,38893:26953,38894:26954,38895:26955,38896:26956,38897:26957,38898:26958,38899:26959,38900:26960,38901:26961,38902:26962,38903:26963,38904:26965,38905:26966,38906:26968,38907:26969,38908:26971,38909:26972,38910:26975,38976:26977,38977:26978,38978:26980,38979:26981,38980:26983,38981:26984,38982:26985,38983:26986,38984:26988,38985:26989,38986:26991,38987:26992,38988:26994,38989:26995,38990:26996,38991:26997,38992:26998,38993:27002,38994:27003,38995:27005,38996:27006,38997:27007,38998:27009,38999:27011,39000:27013,39001:27018,39002:27019,39003:27020,39004:27022,39005:27023,39006:27024,39007:27025,39008:27026,39009:27027,39010:27030,39011:27031,39012:27033,39013:27034,39014:27037,39015:27038,39016:27039,39017:27040,39018:27041,39019:27042,39020:27043,39021:27044,39022:27045,39023:27046,39024:27049,39025:27050,39026:27052,39027:27054,39028:27055,39029:27056,39030:27058,39031:27059,39032:27061,39033:27062,39034:27064,39035:27065,39036:27066,39037:27068,39038:27069,39040:27070,39041:27071,39042:27072,39043:27074,39044:27075,39045:27076,39046:27077,39047:27078,39048:27079,39049:27080,39050:27081,39051:27083,39052:27085,39053:27087,39054:27089,39055:27090,39056:27091,39057:27093,39058:27094,39059:27095,39060:27096,39061:27097,39062:27098,39063:27100,39064:27101,39065:27102,39066:27105,39067:27106,39068:27107,39069:27108,39070:27109,39071:27110,39072:27111,39073:27112,39074:27113,39075:27114,39076:27115,39077:27116,39078:27118,39079:27119,39080:27120,39081:27121,39082:27123,39083:27124,39084:27125,39085:27126,39086:27127,39087:27128,39088:27129,39089:27130,39090:27131,39091:27132,39092:27134,39093:27136,39094:27137,39095:27138,39096:27139,39097:27140,39098:27141,39099:27142,39100:27143,39101:27144,39102:27145,39103:27147,39104:27148,39105:27149,39106:27150,39107:27151,39108:27152,39109:27153,39110:27154,39111:27155,39112:27156,39113:27157,39114:27158,39115:27161,39116:27162,39117:27163,39118:27164,39119:27165,39120:27166,39121:27168,39122:27170,39123:27171,39124:27172,39125:27173,39126:27174,39127:27175,39128:27177,39129:27179,39130:27180,39131:27181,39132:27182,39133:27184,39134:27186,39135:27187,39136:27188,39137:27190,39138:27191,39139:27192,39140:27193,39141:27194,39142:27195,39143:27196,39144:27199,39145:27200,39146:27201,39147:27202,39148:27203,39149:27205,39150:27206,39151:27208,39152:27209,39153:27210,39154:27211,39155:27212,39156:27213,39157:27214,39158:27215,39159:27217,39160:27218,39161:27219,39162:27220,39163:27221,39164:27222,39165:27223,39166:27226,39232:27228,39233:27229,39234:27230,39235:27231,39236:27232,39237:27234,39238:27235,39239:27236,39240:27238,39241:27239,39242:27240,39243:27241,39244:27242,39245:27243,39246:27244,39247:27245,39248:27246,39249:27247,39250:27248,39251:27250,39252:27251,39253:27252,39254:27253,39255:27254,39256:27255,39257:27256,39258:27258,39259:27259,39260:27261,39261:27262,39262:27263,39263:27265,39264:27266,39265:27267,39266:27269,39267:27270,39268:27271,39269:27272,39270:27273,39271:27274,39272:27275,39273:27276,39274:27277,39275:27279,39276:27282,39277:27283,39278:27284,39279:27285,39280:27286,39281:27288,39282:27289,39283:27290,39284:27291,39285:27292,39286:27293,39287:27294,39288:27295,39289:27297,39290:27298,39291:27299,39292:27300,39293:27301,39294:27302,39296:27303,39297:27304,39298:27306,39299:27309,39300:27310,39301:27311,39302:27312,39303:27313,39304:27314,39305:27315,39306:27316,39307:27317,39308:27318,39309:27319,39310:27320,39311:27321,39312:27322,39313:27323,39314:27324,39315:27325,39316:27326,39317:27327,39318:27328,39319:27329,39320:27330,39321:27331,39322:27332,39323:27333,39324:27334,39325:27335,39326:27336,39327:27337,39328:27338,39329:27339,39330:27340,39331:27341,39332:27342,39333:27343,39334:27344,39335:27345,39336:27346,39337:27347,39338:27348,39339:27349,39340:27350,39341:27351,39342:27352,39343:27353,39344:27354,39345:27355,39346:27356,39347:27357,39348:27358,39349:27359,39350:27360,39351:27361,39352:27362,39353:27363,39354:27364,39355:27365,39356:27366,39357:27367,39358:27368,39359:27369,39360:27370,39361:27371,39362:27372,39363:27373,39364:27374,39365:27375,39366:27376,39367:27377,39368:27378,39369:27379,39370:27380,39371:27381,39372:27382,39373:27383,39374:27384,39375:27385,39376:27386,39377:27387,39378:27388,39379:27389,39380:27390,39381:27391,39382:27392,39383:27393,39384:27394,39385:27395,39386:27396,39387:27397,39388:27398,39389:27399,39390:27400,39391:27401,39392:27402,39393:27403,39394:27404,39395:27405,39396:27406,39397:27407,39398:27408,39399:27409,39400:27410,39401:27411,39402:27412,39403:27413,39404:27414,39405:27415,39406:27416,39407:27417,39408:27418,39409:27419,39410:27420,39411:27421,39412:27422,39413:27423,39414:27429,39415:27430,39416:27432,39417:27433,39418:27434,39419:27435,39420:27436,39421:27437,39422:27438,39488:27439,39489:27440,39490:27441,39491:27443,39492:27444,39493:27445,39494:27446,39495:27448,39496:27451,39497:27452,39498:27453,39499:27455,39500:27456,39501:27457,39502:27458,39503:27460,39504:27461,39505:27464,39506:27466,39507:27467,39508:27469,39509:27470,39510:27471,39511:27472,39512:27473,39513:27474,39514:27475,39515:27476,39516:27477,39517:27478,39518:27479,39519:27480,39520:27482,39521:27483,39522:27484,39523:27485,39524:27486,39525:27487,39526:27488,39527:27489,39528:27496,39529:27497,39530:27499,39531:27500,39532:27501,39533:27502,39534:27503,39535:27504,39536:27505,39537:27506,39538:27507,39539:27508,39540:27509,39541:27510,39542:27511,39543:27512,39544:27514,39545:27517,39546:27518,39547:27519,39548:27520,39549:27525,39550:27528,39552:27532,39553:27534,39554:27535,39555:27536,39556:27537,39557:27540,39558:27541,39559:27543,39560:27544,39561:27545,39562:27548,39563:27549,39564:27550,39565:27551,39566:27552,39567:27554,39568:27555,39569:27556,39570:27557,39571:27558,39572:27559,39573:27560,39574:27561,39575:27563,39576:27564,39577:27565,39578:27566,39579:27567,39580:27568,39581:27569,39582:27570,39583:27574,39584:27576,39585:27577,39586:27578,39587:27579,39588:27580,39589:27581,39590:27582,39591:27584,39592:27587,39593:27588,39594:27590,39595:27591,39596:27592,39597:27593,39598:27594,39599:27596,39600:27598,39601:27600,39602:27601,39603:27608,39604:27610,39605:27612,39606:27613,39607:27614,39608:27615,39609:27616,39610:27618,39611:27619,39612:27620,39613:27621,39614:27622,39615:27623,39616:27624,39617:27625,39618:27628,39619:27629,39620:27630,39621:27632,39622:27633,39623:27634,39624:27636,39625:27638,39626:27639,39627:27640,39628:27642,39629:27643,39630:27644,39631:27646,39632:27647,39633:27648,39634:27649,39635:27650,39636:27651,39637:27652,39638:27656,39639:27657,39640:27658,39641:27659,39642:27660,39643:27662,39644:27666,39645:27671,39646:27676,39647:27677,39648:27678,39649:27680,39650:27683,39651:27685,39652:27691,39653:27692,39654:27693,39655:27697,39656:27699,39657:27702,39658:27703,39659:27705,39660:27706,39661:27707,39662:27708,39663:27710,39664:27711,39665:27715,39666:27716,39667:27717,39668:27720,39669:27723,39670:27724,39671:27725,39672:27726,39673:27727,39674:27729,39675:27730,39676:27731,39677:27734,39678:27736,39744:27737,39745:27738,39746:27746,39747:27747,39748:27749,39749:27750,39750:27751,39751:27755,39752:27756,39753:27757,39754:27758,39755:27759,39756:27761,39757:27763,39758:27765,39759:27767,39760:27768,39761:27770,39762:27771,39763:27772,39764:27775,39765:27776,39766:27780,39767:27783,39768:27786,39769:27787,39770:27789,39771:27790,39772:27793,39773:27794,39774:27797,39775:27798,39776:27799,39777:27800,39778:27802,39779:27804,39780:27805,39781:27806,39782:27808,39783:27810,39784:27816,39785:27820,39786:27823,39787:27824,39788:27828,39789:27829,39790:27830,39791:27831,39792:27834,39793:27840,39794:27841,39795:27842,39796:27843,39797:27846,39798:27847,39799:27848,39800:27851,39801:27853,39802:27854,39803:27855,39804:27857,39805:27858,39806:27864,39808:27865,39809:27866,39810:27868,39811:27869,39812:27871,39813:27876,39814:27878,39815:27879,39816:27881,39817:27884,39818:27885,39819:27890,39820:27892,39821:27897,39822:27903,39823:27904,39824:27906,39825:27907,39826:27909,39827:27910,39828:27912,39829:27913,39830:27914,39831:27917,39832:27919,39833:27920,39834:27921,39835:27923,39836:27924,39837:27925,39838:27926,39839:27928,39840:27932,39841:27933,39842:27935,39843:27936,39844:27937,39845:27938,39846:27939,39847:27940,39848:27942,39849:27944,39850:27945,39851:27948,39852:27949,39853:27951,39854:27952,39855:27956,39856:27958,39857:27959,39858:27960,39859:27962,39860:27967,39861:27968,39862:27970,39863:27972,39864:27977,39865:27980,39866:27984,39867:27989,39868:27990,39869:27991,39870:27992,39871:27995,39872:27997,39873:27999,39874:28001,39875:28002,39876:28004,39877:28005,39878:28007,39879:28008,39880:28011,39881:28012,39882:28013,39883:28016,39884:28017,39885:28018,39886:28019,39887:28021,39888:28022,39889:28025,39890:28026,39891:28027,39892:28029,39893:28030,39894:28031,39895:28032,39896:28033,39897:28035,39898:28036,39899:28038,39900:28039,39901:28042,39902:28043,39903:28045,39904:28047,39905:28048,39906:28050,39907:28054,39908:28055,39909:28056,39910:28057,39911:28058,39912:28060,39913:28066,39914:28069,39915:28076,39916:28077,39917:28080,39918:28081,39919:28083,39920:28084,39921:28086,39922:28087,39923:28089,39924:28090,39925:28091,39926:28092,39927:28093,39928:28094,39929:28097,39930:28098,39931:28099,39932:28104,39933:28105,39934:28106,40000:28109,40001:28110,40002:28111,40003:28112,40004:28114,40005:28115,40006:28116,40007:28117,40008:28119,40009:28122,40010:28123,40011:28124,40012:28127,40013:28130,40014:28131,40015:28133,40016:28135,40017:28136,40018:28137,40019:28138,40020:28141,40021:28143,40022:28144,40023:28146,40024:28148,40025:28149,40026:28150,40027:28152,40028:28154,40029:28157,40030:28158,40031:28159,40032:28160,40033:28161,40034:28162,40035:28163,40036:28164,40037:28166,40038:28167,40039:28168,40040:28169,40041:28171,40042:28175,40043:28178,40044:28179,40045:28181,40046:28184,40047:28185,40048:28187,40049:28188,40050:28190,40051:28191,40052:28194,40053:28198,40054:28199,40055:28200,40056:28202,40057:28204,40058:28206,40059:28208,40060:28209,40061:28211,40062:28213,40064:28214,40065:28215,40066:28217,40067:28219,40068:28220,40069:28221,40070:28222,40071:28223,40072:28224,40073:28225,40074:28226,40075:28229,40076:28230,40077:28231,40078:28232,40079:28233,40080:28234,40081:28235,40082:28236,40083:28239,40084:28240,40085:28241,40086:28242,40087:28245,40088:28247,40089:28249,40090:28250,40091:28252,40092:28253,40093:28254,40094:28256,40095:28257,40096:28258,40097:28259,40098:28260,40099:28261,40100:28262,40101:28263,40102:28264,40103:28265,40104:28266,40105:28268,40106:28269,40107:28271,40108:28272,40109:28273,40110:28274,40111:28275,40112:28276,40113:28277,40114:28278,40115:28279,40116:28280,40117:28281,40118:28282,40119:28283,40120:28284,40121:28285,40122:28288,40123:28289,40124:28290,40125:28292,40126:28295,40127:28296,40128:28298,40129:28299,40130:28300,40131:28301,40132:28302,40133:28305,40134:28306,40135:28307,40136:28308,40137:28309,40138:28310,40139:28311,40140:28313,40141:28314,40142:28315,40143:28317,40144:28318,40145:28320,40146:28321,40147:28323,40148:28324,40149:28326,40150:28328,40151:28329,40152:28331,40153:28332,40154:28333,40155:28334,40156:28336,40157:28339,40158:28341,40159:28344,40160:28345,40161:28348,40162:28350,40163:28351,40164:28352,40165:28355,40166:28356,40167:28357,40168:28358,40169:28360,40170:28361,40171:28362,40172:28364,40173:28365,40174:28366,40175:28368,40176:28370,40177:28374,40178:28376,40179:28377,40180:28379,40181:28380,40182:28381,40183:28387,40184:28391,40185:28394,40186:28395,40187:28396,40188:28397,40189:28398,40190:28399,40256:28400,40257:28401,40258:28402,40259:28403,40260:28405,40261:28406,40262:28407,40263:28408,40264:28410,40265:28411,40266:28412,40267:28413,40268:28414,40269:28415,40270:28416,40271:28417,40272:28419,40273:28420,40274:28421,40275:28423,40276:28424,40277:28426,40278:28427,40279:28428,40280:28429,40281:28430,40282:28432,40283:28433,40284:28434,40285:28438,40286:28439,40287:28440,40288:28441,40289:28442,40290:28443,40291:28444,40292:28445,40293:28446,40294:28447,40295:28449,40296:28450,40297:28451,40298:28453,40299:28454,40300:28455,40301:28456,40302:28460,40303:28462,40304:28464,40305:28466,40306:28468,40307:28469,40308:28471,40309:28472,40310:28473,40311:28474,40312:28475,40313:28476,40314:28477,40315:28479,40316:28480,40317:28481,40318:28482,40320:28483,40321:28484,40322:28485,40323:28488,40324:28489,40325:28490,40326:28492,40327:28494,40328:28495,40329:28496,40330:28497,40331:28498,40332:28499,40333:28500,40334:28501,40335:28502,40336:28503,40337:28505,40338:28506,40339:28507,40340:28509,40341:28511,40342:28512,40343:28513,40344:28515,40345:28516,40346:28517,40347:28519,40348:28520,40349:28521,40350:28522,40351:28523,40352:28524,40353:28527,40354:28528,40355:28529,40356:28531,40357:28533,40358:28534,40359:28535,40360:28537,40361:28539,40362:28541,40363:28542,40364:28543,40365:28544,40366:28545,40367:28546,40368:28547,40369:28549,40370:28550,40371:28551,40372:28554,40373:28555,40374:28559,40375:28560,40376:28561,40377:28562,40378:28563,40379:28564,40380:28565,40381:28566,40382:28567,40383:28568,40384:28569,40385:28570,40386:28571,40387:28573,40388:28574,40389:28575,40390:28576,40391:28578,40392:28579,40393:28580,40394:28581,40395:28582,40396:28584,40397:28585,40398:28586,40399:28587,40400:28588,40401:28589,40402:28590,40403:28591,40404:28592,40405:28593,40406:28594,40407:28596,40408:28597,40409:28599,40410:28600,40411:28602,40412:28603,40413:28604,40414:28605,40415:28606,40416:28607,40417:28609,40418:28611,40419:28612,40420:28613,40421:28614,40422:28615,40423:28616,40424:28618,40425:28619,40426:28620,40427:28621,40428:28622,40429:28623,40430:28624,40431:28627,40432:28628,40433:28629,40434:28630,40435:28631,40436:28632,40437:28633,40438:28634,40439:28635,40440:28636,40441:28637,40442:28639,40443:28642,40444:28643,40445:28644,40446:28645,40512:28646,40513:28647,40514:28648,40515:28649,40516:28650,40517:28651,40518:28652,40519:28653,40520:28656,40521:28657,40522:28658,40523:28659,40524:28660,40525:28661,40526:28662,40527:28663,40528:28664,40529:28665,40530:28666,40531:28667,40532:28668,40533:28669,40534:28670,40535:28671,40536:28672,40537:28673,40538:28674,40539:28675,40540:28676,40541:28677,40542:28678,40543:28679,40544:28680,40545:28681,40546:28682,40547:28683,40548:28684,40549:28685,40550:28686,40551:28687,40552:28688,40553:28690,40554:28691,40555:28692,40556:28693,40557:28694,40558:28695,40559:28696,40560:28697,40561:28700,40562:28701,40563:28702,40564:28703,40565:28704,40566:28705,40567:28706,40568:28708,40569:28709,40570:28710,40571:28711,40572:28712,40573:28713,40574:28714,40576:28715,40577:28716,40578:28717,40579:28718,40580:28719,40581:28720,40582:28721,40583:28722,40584:28723,40585:28724,40586:28726,40587:28727,40588:28728,40589:28730,40590:28731,40591:28732,40592:28733,40593:28734,40594:28735,40595:28736,40596:28737,40597:28738,40598:28739,40599:28740,40600:28741,40601:28742,40602:28743,40603:28744,40604:28745,40605:28746,40606:28747,40607:28749,40608:28750,40609:28752,40610:28753,40611:28754,40612:28755,40613:28756,40614:28757,40615:28758,40616:28759,40617:28760,40618:28761,40619:28762,40620:28763,40621:28764,40622:28765,40623:28767,40624:28768,40625:28769,40626:28770,40627:28771,40628:28772,40629:28773,40630:28774,40631:28775,40632:28776,40633:28777,40634:28778,40635:28782,40636:28785,40637:28786,40638:28787,40639:28788,40640:28791,40641:28793,40642:28794,40643:28795,40644:28797,40645:28801,40646:28802,40647:28803,40648:28804,40649:28806,40650:28807,40651:28808,40652:28811,40653:28812,40654:28813,40655:28815,40656:28816,40657:28817,40658:28819,40659:28823,40660:28824,40661:28826,40662:28827,40663:28830,40664:28831,40665:28832,40666:28833,40667:28834,40668:28835,40669:28836,40670:28837,40671:28838,40672:28839,40673:28840,40674:28841,40675:28842,40676:28848,40677:28850,40678:28852,40679:28853,40680:28854,40681:28858,40682:28862,40683:28863,40684:28868,40685:28869,40686:28870,40687:28871,40688:28873,40689:28875,40690:28876,40691:28877,40692:28878,40693:28879,40694:28880,40695:28881,40696:28882,40697:28883,40698:28884,40699:28885,40700:28886,40701:28887,40702:28890,40768:28892,40769:28893,40770:28894,40771:28896,40772:28897,40773:28898,40774:28899,40775:28901,40776:28906,40777:28910,40778:28912,40779:28913,40780:28914,40781:28915,40782:28916,40783:28917,40784:28918,40785:28920,40786:28922,40787:28923,40788:28924,40789:28926,40790:28927,40791:28928,40792:28929,40793:28930,40794:28931,40795:28932,40796:28933,40797:28934,40798:28935,40799:28936,40800:28939,40801:28940,40802:28941,40803:28942,40804:28943,40805:28945,40806:28946,40807:28948,40808:28951,40809:28955,40810:28956,40811:28957,40812:28958,40813:28959,40814:28960,40815:28961,40816:28962,40817:28963,40818:28964,40819:28965,40820:28967,40821:28968,40822:28969,40823:28970,40824:28971,40825:28972,40826:28973,40827:28974,40828:28978,40829:28979,40830:28980,40832:28981,40833:28983,40834:28984,40835:28985,40836:28986,40837:28987,40838:28988,40839:28989,40840:28990,40841:28991,40842:28992,40843:28993,40844:28994,40845:28995,40846:28996,40847:28998,40848:28999,40849:29000,40850:29001,40851:29003,40852:29005,40853:29007,40854:29008,40855:29009,40856:29010,40857:29011,40858:29012,40859:29013,40860:29014,40861:29015,40862:29016,40863:29017,40864:29018,40865:29019,40866:29021,40867:29023,40868:29024,40869:29025,40870:29026,40871:29027,40872:29029,40873:29033,40874:29034,40875:29035,40876:29036,40877:29037,40878:29039,40879:29040,40880:29041,40881:29044,40882:29045,40883:29046,40884:29047,40885:29049,40886:29051,40887:29052,40888:29054,40889:29055,40890:29056,40891:29057,40892:29058,40893:29059,40894:29061,40895:29062,40896:29063,40897:29064,40898:29065,40899:29067,40900:29068,40901:29069,40902:29070,40903:29072,40904:29073,40905:29074,40906:29075,40907:29077,40908:29078,40909:29079,40910:29082,40911:29083,40912:29084,40913:29085,40914:29086,40915:29089,40916:29090,40917:29091,40918:29092,40919:29093,40920:29094,40921:29095,40922:29097,40923:29098,40924:29099,40925:29101,40926:29102,40927:29103,40928:29104,40929:29105,40930:29106,40931:29108,40932:29110,40933:29111,40934:29112,40935:29114,40936:29115,40937:29116,40938:29117,40939:29118,40940:29119,40941:29120,40942:29121,40943:29122,40944:29124,40945:29125,40946:29126,40947:29127,40948:29128,40949:29129,40950:29130,40951:29131,40952:29132,40953:29133,40954:29135,40955:29136,40956:29137,40957:29138,40958:29139,41024:29142,41025:29143,41026:29144,41027:29145,41028:29146,41029:29147,41030:29148,41031:29149,41032:29150,41033:29151,41034:29153,41035:29154,41036:29155,41037:29156,41038:29158,41039:29160,41040:29161,41041:29162,41042:29163,41043:29164,41044:29165,41045:29167,41046:29168,41047:29169,41048:29170,41049:29171,41050:29172,41051:29173,41052:29174,41053:29175,41054:29176,41055:29178,41056:29179,41057:29180,41058:29181,41059:29182,41060:29183,41061:29184,41062:29185,41063:29186,41064:29187,41065:29188,41066:29189,41067:29191,41068:29192,41069:29193,41070:29194,41071:29195,41072:29196,41073:29197,41074:29198,41075:29199,41076:29200,41077:29201,41078:29202,41079:29203,41080:29204,41081:29205,41082:29206,41083:29207,41084:29208,41085:29209,41086:29210,41088:29211,41089:29212,41090:29214,41091:29215,41092:29216,41093:29217,41094:29218,41095:29219,41096:29220,41097:29221,41098:29222,41099:29223,41100:29225,41101:29227,41102:29229,41103:29230,41104:29231,41105:29234,41106:29235,41107:29236,41108:29242,41109:29244,41110:29246,41111:29248,41112:29249,41113:29250,41114:29251,41115:29252,41116:29253,41117:29254,41118:29257,41119:29258,41120:29259,41121:29262,41122:29263,41123:29264,41124:29265,41125:29267,41126:29268,41127:29269,41128:29271,41129:29272,41130:29274,41131:29276,41132:29278,41133:29280,41134:29283,41135:29284,41136:29285,41137:29288,41138:29290,41139:29291,41140:29292,41141:29293,41142:29296,41143:29297,41144:29299,41145:29300,41146:29302,41147:29303,41148:29304,41149:29307,41150:29308,41151:29309,41152:29314,41153:29315,41154:29317,41155:29318,41156:29319,41157:29320,41158:29321,41159:29324,41160:29326,41161:29328,41162:29329,41163:29331,41164:29332,41165:29333,41166:29334,41167:29335,41168:29336,41169:29337,41170:29338,41171:29339,41172:29340,41173:29341,41174:29342,41175:29344,41176:29345,41177:29346,41178:29347,41179:29348,41180:29349,41181:29350,41182:29351,41183:29352,41184:29353,41185:29354,41186:29355,41187:29358,41188:29361,41189:29362,41190:29363,41191:29365,41192:29370,41193:29371,41194:29372,41195:29373,41196:29374,41197:29375,41198:29376,41199:29381,41200:29382,41201:29383,41202:29385,41203:29386,41204:29387,41205:29388,41206:29391,41207:29393,41208:29395,41209:29396,41210:29397,41211:29398,41212:29400,41213:29402,41214:29403,41280:58566,41281:58567,41282:58568,41283:58569,41284:58570,41285:58571,41286:58572,41287:58573,41288:58574,41289:58575,41290:58576,41291:58577,41292:58578,41293:58579,41294:58580,41295:58581,41296:58582,41297:58583,41298:58584,41299:58585,41300:58586,41301:58587,41302:58588,41303:58589,41304:58590,41305:58591,41306:58592,41307:58593,41308:58594,41309:58595,41310:58596,41311:58597,41312:58598,41313:58599,41314:58600,41315:58601,41316:58602,41317:58603,41318:58604,41319:58605,41320:58606,41321:58607,41322:58608,41323:58609,41324:58610,41325:58611,41326:58612,41327:58613,41328:58614,41329:58615,41330:58616,41331:58617,41332:58618,41333:58619,41334:58620,41335:58621,41336:58622,41337:58623,41338:58624,41339:58625,41340:58626,41341:58627,41342:58628,41344:58629,41345:58630,41346:58631,41347:58632,41348:58633,41349:58634,41350:58635,41351:58636,41352:58637,41353:58638,41354:58639,41355:58640,41356:58641,41357:58642,41358:58643,41359:58644,41360:58645,41361:58646,41362:58647,41363:58648,41364:58649,41365:58650,41366:58651,41367:58652,41368:58653,41369:58654,41370:58655,41371:58656,41372:58657,41373:58658,41374:58659,41375:58660,41376:58661,41377:12288,41378:12289,41379:12290,41380:183,41381:713,41382:711,41383:168,41384:12291,41385:12293,41386:8212,41387:65374,41388:8214,41389:8230,41390:8216,41391:8217,41392:8220,41393:8221,41394:12308,41395:12309,41396:12296,41397:12297,41398:12298,41399:12299,41400:12300,41401:12301,41402:12302,41403:12303,41404:12310,41405:12311,41406:12304,41407:12305,41408:177,41409:215,41410:247,41411:8758,41412:8743,41413:8744,41414:8721,41415:8719,41416:8746,41417:8745,41418:8712,41419:8759,41420:8730,41421:8869,41422:8741,41423:8736,41424:8978,41425:8857,41426:8747,41427:8750,41428:8801,41429:8780,41430:8776,41431:8765,41432:8733,41433:8800,41434:8814,41435:8815,41436:8804,41437:8805,41438:8734,41439:8757,41440:8756,41441:9794,41442:9792,41443:176,41444:8242,41445:8243,41446:8451,41447:65284,41448:164,41449:65504,41450:65505,41451:8240,41452:167,41453:8470,41454:9734,41455:9733,41456:9675,41457:9679,41458:9678,41459:9671,41460:9670,41461:9633,41462:9632,41463:9651,41464:9650,41465:8251,41466:8594,41467:8592,41468:8593,41469:8595,41470:12307,41536:58662,41537:58663,41538:58664,41539:58665,41540:58666,41541:58667,41542:58668,41543:58669,41544:58670,41545:58671,41546:58672,41547:58673,41548:58674,41549:58675,41550:58676,41551:58677,41552:58678,41553:58679,41554:58680,41555:58681,41556:58682,41557:58683,41558:58684,41559:58685,41560:58686,41561:58687,41562:58688,41563:58689,41564:58690,41565:58691,41566:58692,41567:58693,41568:58694,41569:58695,41570:58696,41571:58697,41572:58698,41573:58699,41574:58700,41575:58701,41576:58702,41577:58703,41578:58704,41579:58705,41580:58706,41581:58707,41582:58708,41583:58709,41584:58710,41585:58711,41586:58712,41587:58713,41588:58714,41589:58715,41590:58716,41591:58717,41592:58718,41593:58719,41594:58720,41595:58721,41596:58722,41597:58723,41598:58724,41600:58725,41601:58726,41602:58727,41603:58728,41604:58729,41605:58730,41606:58731,41607:58732,41608:58733,41609:58734,41610:58735,41611:58736,41612:58737,41613:58738,41614:58739,41615:58740,41616:58741,41617:58742,41618:58743,41619:58744,41620:58745,41621:58746,41622:58747,41623:58748,41624:58749,41625:58750,41626:58751,41627:58752,41628:58753,41629:58754,41630:58755,41631:58756,41632:58757,41633:8560,41634:8561,41635:8562,41636:8563,41637:8564,41638:8565,41639:8566,41640:8567,41641:8568,41642:8569,41643:59238,41644:59239,41645:59240,41646:59241,41647:59242,41648:59243,41649:9352,41650:9353,41651:9354,41652:9355,41653:9356,41654:9357,41655:9358,41656:9359,41657:9360,41658:9361,41659:9362,41660:9363,41661:9364,41662:9365,41663:9366,41664:9367,41665:9368,41666:9369,41667:9370,41668:9371,41669:9332,41670:9333,41671:9334,41672:9335,41673:9336,41674:9337,41675:9338,41676:9339,41677:9340,41678:9341,41679:9342,41680:9343,41681:9344,41682:9345,41683:9346,41684:9347,41685:9348,41686:9349,41687:9350,41688:9351,41689:9312,41690:9313,41691:9314,41692:9315,41693:9316,41694:9317,41695:9318,41696:9319,41697:9320,41698:9321,41699:8364,41700:59245,41701:12832,41702:12833,41703:12834,41704:12835,41705:12836,41706:12837,41707:12838,41708:12839,41709:12840,41710:12841,41711:59246,41712:59247,41713:8544,41714:8545,41715:8546,41716:8547,41717:8548,41718:8549,41719:8550,41720:8551,41721:8552,41722:8553,41723:8554,41724:8555,41725:59248,41726:59249,41792:58758,41793:58759,41794:58760,41795:58761,41796:58762,41797:58763,41798:58764,41799:58765,41800:58766,41801:58767,41802:58768,41803:58769,41804:58770,41805:58771,41806:58772,41807:58773,41808:58774,41809:58775,41810:58776,41811:58777,41812:58778,41813:58779,41814:58780,41815:58781,41816:58782,41817:58783,41818:58784,41819:58785,41820:58786,41821:58787,41822:58788,41823:58789,41824:58790,41825:58791,41826:58792,41827:58793,41828:58794,41829:58795,41830:58796,41831:58797,41832:58798,41833:58799,41834:58800,41835:58801,41836:58802,41837:58803,41838:58804,41839:58805,41840:58806,41841:58807,41842:58808,41843:58809,41844:58810,41845:58811,41846:58812,41847:58813,41848:58814,41849:58815,41850:58816,41851:58817,41852:58818,41853:58819,41854:58820,41856:58821,41857:58822,41858:58823,41859:58824,41860:58825,41861:58826,41862:58827,41863:58828,41864:58829,41865:58830,41866:58831,41867:58832,41868:58833,41869:58834,41870:58835,41871:58836,41872:58837,41873:58838,41874:58839,41875:58840,41876:58841,41877:58842,41878:58843,41879:58844,41880:58845,41881:58846,41882:58847,41883:58848,41884:58849,41885:58850,41886:58851,41887:58852,41888:58853,41889:65281,41890:65282,41891:65283,41892:65509,41893:65285,41894:65286,41895:65287,41896:65288,41897:65289,41898:65290,41899:65291,41900:65292,41901:65293,41902:65294,41903:65295,41904:65296,41905:65297,41906:65298,41907:65299,41908:65300,41909:65301,41910:65302,41911:65303,41912:65304,41913:65305,41914:65306,41915:65307,41916:65308,41917:65309,41918:65310,41919:65311,41920:65312,41921:65313,41922:65314,41923:65315,41924:65316,41925:65317,41926:65318,41927:65319,41928:65320,41929:65321,41930:65322,41931:65323,41932:65324,41933:65325,41934:65326,41935:65327,41936:65328,41937:65329,41938:65330,41939:65331,41940:65332,41941:65333,41942:65334,41943:65335,41944:65336,41945:65337,41946:65338,41947:65339,41948:65340,41949:65341,41950:65342,41951:65343,41952:65344,41953:65345,41954:65346,41955:65347,41956:65348,41957:65349,41958:65350,41959:65351,41960:65352,41961:65353,41962:65354,41963:65355,41964:65356,41965:65357,41966:65358,41967:65359,41968:65360,41969:65361,41970:65362,41971:65363,41972:65364,41973:65365,41974:65366,41975:65367,41976:65368,41977:65369,41978:65370,41979:65371,41980:65372,41981:65373,41982:65507,42048:58854,42049:58855,42050:58856,42051:58857,42052:58858,42053:58859,42054:58860,42055:58861,42056:58862,42057:58863,42058:58864,42059:58865,42060:58866,42061:58867,42062:58868,42063:58869,42064:58870,42065:58871,42066:58872,42067:58873,42068:58874,42069:58875,42070:58876,42071:58877,42072:58878,42073:58879,42074:58880,42075:58881,42076:58882,42077:58883,42078:58884,42079:58885,42080:58886,42081:58887,42082:58888,42083:58889,42084:58890,42085:58891,42086:58892,42087:58893,42088:58894,42089:58895,42090:58896,42091:58897,42092:58898,42093:58899,42094:58900,42095:58901,42096:58902,42097:58903,42098:58904,42099:58905,42100:58906,42101:58907,42102:58908,42103:58909,42104:58910,42105:58911,42106:58912,42107:58913,42108:58914,42109:58915,42110:58916,42112:58917,42113:58918,42114:58919,42115:58920,42116:58921,42117:58922,42118:58923,42119:58924,42120:58925,42121:58926,42122:58927,42123:58928,42124:58929,42125:58930,42126:58931,42127:58932,42128:58933,42129:58934,42130:58935,42131:58936,42132:58937,42133:58938,42134:58939,42135:58940,42136:58941,42137:58942,42138:58943,42139:58944,42140:58945,42141:58946,42142:58947,42143:58948,42144:58949,42145:12353,42146:12354,42147:12355,42148:12356,42149:12357,42150:12358,42151:12359,42152:12360,42153:12361,42154:12362,42155:12363,42156:12364,42157:12365,42158:12366,42159:12367,42160:12368,42161:12369,42162:12370,42163:12371,42164:12372,42165:12373,42166:12374,42167:12375,42168:12376,42169:12377,42170:12378,42171:12379,42172:12380,42173:12381,42174:12382,42175:12383,42176:12384,42177:12385,42178:12386,42179:12387,42180:12388,42181:12389,42182:12390,42183:12391,42184:12392,42185:12393,42186:12394,42187:12395,42188:12396,42189:12397,42190:12398,42191:12399,42192:12400,42193:12401,42194:12402,42195:12403,42196:12404,42197:12405,42198:12406,42199:12407,42200:12408,42201:12409,42202:12410,42203:12411,42204:12412,42205:12413,42206:12414,42207:12415,42208:12416,42209:12417,42210:12418,42211:12419,42212:12420,42213:12421,42214:12422,42215:12423,42216:12424,42217:12425,42218:12426,42219:12427,42220:12428,42221:12429,42222:12430,42223:12431,42224:12432,42225:12433,42226:12434,42227:12435,42228:59250,42229:59251,42230:59252,42231:59253,42232:59254,42233:59255,42234:59256,42235:59257,42236:59258,42237:59259,42238:59260,42304:58950,42305:58951,42306:58952,42307:58953,42308:58954,42309:58955,42310:58956,42311:58957,42312:58958,42313:58959,42314:58960,42315:58961,42316:58962,42317:58963,42318:58964,42319:58965,42320:58966,42321:58967,42322:58968,42323:58969,42324:58970,42325:58971,42326:58972,42327:58973,42328:58974,42329:58975,42330:58976,42331:58977,42332:58978,42333:58979,42334:58980,42335:58981,42336:58982,42337:58983,42338:58984,42339:58985,42340:58986,42341:58987,42342:58988,42343:58989,42344:58990,42345:58991,42346:58992,42347:58993,42348:58994,42349:58995,42350:58996,42351:58997,42352:58998,42353:58999,42354:59000,42355:59001,42356:59002,42357:59003,42358:59004,42359:59005,42360:59006,42361:59007,42362:59008,42363:59009,42364:59010,42365:59011,42366:59012,42368:59013,42369:59014,42370:59015,42371:59016,42372:59017,42373:59018,42374:59019,42375:59020,42376:59021,42377:59022,42378:59023,42379:59024,42380:59025,42381:59026,42382:59027,42383:59028,42384:59029,42385:59030,42386:59031,42387:59032,42388:59033,42389:59034,42390:59035,42391:59036,42392:59037,42393:59038,42394:59039,42395:59040,42396:59041,42397:59042,42398:59043,42399:59044,42400:59045,42401:12449,42402:12450,42403:12451,42404:12452,42405:12453,42406:12454,42407:12455,42408:12456,42409:12457,42410:12458,42411:12459,42412:12460,42413:12461,42414:12462,42415:12463,42416:12464,42417:12465,42418:12466,42419:12467,42420:12468,42421:12469,42422:12470,42423:12471,42424:12472,42425:12473,42426:12474,42427:12475,42428:12476,42429:12477,42430:12478,42431:12479,42432:12480,42433:12481,42434:12482,42435:12483,42436:12484,42437:12485,42438:12486,42439:12487,42440:12488,42441:12489,42442:12490,42443:12491,42444:12492,42445:12493,42446:12494,42447:12495,42448:12496,42449:12497,42450:12498,42451:12499,42452:12500,42453:12501,42454:12502,42455:12503,42456:12504,42457:12505,42458:12506,42459:12507,42460:12508,42461:12509,42462:12510,42463:12511,42464:12512,42465:12513,42466:12514,42467:12515,42468:12516,42469:12517,42470:12518,42471:12519,42472:12520,42473:12521,42474:12522,42475:12523,42476:12524,42477:12525,42478:12526,42479:12527,42480:12528,42481:12529,42482:12530,42483:12531,42484:12532,42485:12533,42486:12534,42487:59261,42488:59262,42489:59263,42490:59264,42491:59265,42492:59266,42493:59267,42494:59268,42560:59046,42561:59047,42562:59048,42563:59049,42564:59050,42565:59051,42566:59052,42567:59053,42568:59054,42569:59055,42570:59056,42571:59057,42572:59058,42573:59059,42574:59060,42575:59061,42576:59062,42577:59063,42578:59064,42579:59065,42580:59066,42581:59067,42582:59068,42583:59069,42584:59070,42585:59071,42586:59072,42587:59073,42588:59074,42589:59075,42590:59076,42591:59077,42592:59078,42593:59079,42594:59080,42595:59081,42596:59082,42597:59083,42598:59084,42599:59085,42600:59086,42601:59087,42602:59088,42603:59089,42604:59090,42605:59091,42606:59092,42607:59093,42608:59094,42609:59095,42610:59096,42611:59097,42612:59098,42613:59099,42614:59100,42615:59101,42616:59102,42617:59103,42618:59104,42619:59105,42620:59106,42621:59107,42622:59108,42624:59109,42625:59110,42626:59111,42627:59112,42628:59113,42629:59114,42630:59115,42631:59116,42632:59117,42633:59118,42634:59119,42635:59120,42636:59121,42637:59122,42638:59123,42639:59124,42640:59125,42641:59126,42642:59127,42643:59128,42644:59129,42645:59130,42646:59131,42647:59132,42648:59133,42649:59134,42650:59135,42651:59136,42652:59137,42653:59138,42654:59139,42655:59140,42656:59141,42657:913,42658:914,42659:915,42660:916,42661:917,42662:918,42663:919,42664:920,42665:921,42666:922,42667:923,42668:924,42669:925,42670:926,42671:927,42672:928,42673:929,42674:931,42675:932,42676:933,42677:934,42678:935,42679:936,42680:937,42681:59269,42682:59270,42683:59271,42684:59272,42685:59273,42686:59274,42687:59275,42688:59276,42689:945,42690:946,42691:947,42692:948,42693:949,42694:950,42695:951,42696:952,42697:953,42698:954,42699:955,42700:956,42701:957,42702:958,42703:959,42704:960,42705:961,42706:963,42707:964,42708:965,42709:966,42710:967,42711:968,42712:969,42713:59277,42714:59278,42715:59279,42716:59280,42717:59281,42718:59282,42719:59283,42720:65077,42721:65078,42722:65081,42723:65082,42724:65087,42725:65088,42726:65085,42727:65086,42728:65089,42729:65090,42730:65091,42731:65092,42732:59284,42733:59285,42734:65083,42735:65084,42736:65079,42737:65080,42738:65073,42739:59286,42740:65075,42741:65076,42742:59287,42743:59288,42744:59289,42745:59290,42746:59291,42747:59292,42748:59293,42749:59294,42750:59295,42816:59142,42817:59143,42818:59144,42819:59145,42820:59146,42821:59147,42822:59148,42823:59149,42824:59150,42825:59151,42826:59152,42827:59153,42828:59154,42829:59155,42830:59156,42831:59157,42832:59158,42833:59159,42834:59160,42835:59161,42836:59162,42837:59163,42838:59164,42839:59165,42840:59166,42841:59167,42842:59168,42843:59169,42844:59170,42845:59171,42846:59172,42847:59173,42848:59174,42849:59175,42850:59176,42851:59177,42852:59178,42853:59179,42854:59180,42855:59181,42856:59182,42857:59183,42858:59184,42859:59185,42860:59186,42861:59187,42862:59188,42863:59189,42864:59190,42865:59191,42866:59192,42867:59193,42868:59194,42869:59195,42870:59196,42871:59197,42872:59198,42873:59199,42874:59200,42875:59201,42876:59202,42877:59203,42878:59204,42880:59205,42881:59206,42882:59207,42883:59208,42884:59209,42885:59210,42886:59211,42887:59212,42888:59213,42889:59214,42890:59215,42891:59216,42892:59217,42893:59218,42894:59219,42895:59220,42896:59221,42897:59222,42898:59223,42899:59224,42900:59225,42901:59226,42902:59227,42903:59228,42904:59229,42905:59230,42906:59231,42907:59232,42908:59233,42909:59234,42910:59235,42911:59236,42912:59237,42913:1040,42914:1041,42915:1042,42916:1043,42917:1044,42918:1045,42919:1025,42920:1046,42921:1047,42922:1048,42923:1049,42924:1050,42925:1051,42926:1052,42927:1053,42928:1054,42929:1055,42930:1056,42931:1057,42932:1058,42933:1059,42934:1060,42935:1061,42936:1062,42937:1063,42938:1064,42939:1065,42940:1066,42941:1067,42942:1068,42943:1069,42944:1070,42945:1071,42946:59296,42947:59297,42948:59298,42949:59299,42950:59300,42951:59301,42952:59302,42953:59303,42954:59304,42955:59305,42956:59306,42957:59307,42958:59308,42959:59309,42960:59310,42961:1072,42962:1073,42963:1074,42964:1075,42965:1076,42966:1077,42967:1105,42968:1078,42969:1079,42970:1080,42971:1081,42972:1082,42973:1083,42974:1084,42975:1085,42976:1086,42977:1087,42978:1088,42979:1089,42980:1090,42981:1091,42982:1092,42983:1093,42984:1094,42985:1095,42986:1096,42987:1097,42988:1098,42989:1099,42990:1100,42991:1101,42992:1102,42993:1103,42994:59311,42995:59312,42996:59313,42997:59314,42998:59315,42999:59316,43000:59317,43001:59318,43002:59319,43003:59320,43004:59321,43005:59322,43006:59323,43072:714,43073:715,43074:729,43075:8211,43076:8213,43077:8229,43078:8245,43079:8453,43080:8457,43081:8598,43082:8599,43083:8600,43084:8601,43085:8725,43086:8735,43087:8739,43088:8786,43089:8806,43090:8807,43091:8895,43092:9552,43093:9553,43094:9554,43095:9555,43096:9556,43097:9557,43098:9558,43099:9559,43100:9560,43101:9561,43102:9562,43103:9563,43104:9564,43105:9565,43106:9566,43107:9567,43108:9568,43109:9569,43110:9570,43111:9571,43112:9572,43113:9573,43114:9574,43115:9575,43116:9576,43117:9577,43118:9578,43119:9579,43120:9580,43121:9581,43122:9582,43123:9583,43124:9584,43125:9585,43126:9586,43127:9587,43128:9601,43129:9602,43130:9603,43131:9604,43132:9605,43133:9606,43134:9607,43136:9608,43137:9609,43138:9610,43139:9611,43140:9612,43141:9613,43142:9614,43143:9615,43144:9619,43145:9620,43146:9621,43147:9660,43148:9661,43149:9698,43150:9699,43151:9700,43152:9701,43153:9737,43154:8853,43155:12306,43156:12317,43157:12318,43158:59324,43159:59325,43160:59326,43161:59327,43162:59328,43163:59329,43164:59330,43165:59331,43166:59332,43167:59333,43168:59334,43169:257,43170:225,43171:462,43172:224,43173:275,43174:233,43175:283,43176:232,43177:299,43178:237,43179:464,43180:236,43181:333,43182:243,43183:466,43184:242,43185:363,43186:250,43187:468,43188:249,43189:470,43190:472,43191:474,43192:476,43193:252,43194:234,43195:593,43196:59335,43197:324,43198:328,43199:505,43200:609,43201:59337,43202:59338,43203:59339,43204:59340,43205:12549,43206:12550,43207:12551,43208:12552,43209:12553,43210:12554,43211:12555,43212:12556,43213:12557,43214:12558,43215:12559,43216:12560,43217:12561,43218:12562,43219:12563,43220:12564,43221:12565,43222:12566,43223:12567,43224:12568,43225:12569,43226:12570,43227:12571,43228:12572,43229:12573,43230:12574,43231:12575,43232:12576,43233:12577,43234:12578,43235:12579,43236:12580,43237:12581,43238:12582,43239:12583,43240:12584,43241:12585,43242:59341,43243:59342,43244:59343,43245:59344,43246:59345,43247:59346,43248:59347,43249:59348,43250:59349,43251:59350,43252:59351,43253:59352,43254:59353,43255:59354,43256:59355,43257:59356,43258:59357,43259:59358,43260:59359,43261:59360,43262:59361,43328:12321,43329:12322,43330:12323,43331:12324,43332:12325,43333:12326,43334:12327,43335:12328,43336:12329,43337:12963,43338:13198,43339:13199,43340:13212,43341:13213,43342:13214,43343:13217,43344:13252,43345:13262,43346:13265,43347:13266,43348:13269,43349:65072,43350:65506,43351:65508,43352:59362,43353:8481,43354:12849,43355:59363,43356:8208,43357:59364,43358:59365,43359:59366,43360:12540,43361:12443,43362:12444,43363:12541,43364:12542,43365:12294,43366:12445,43367:12446,43368:65097,43369:65098,43370:65099,43371:65100,43372:65101,43373:65102,43374:65103,43375:65104,43376:65105,43377:65106,43378:65108,43379:65109,43380:65110,43381:65111,43382:65113,43383:65114,43384:65115,43385:65116,43386:65117,43387:65118,43388:65119,43389:65120,43390:65121,43392:65122,43393:65123,43394:65124,43395:65125,43396:65126,43397:65128,43398:65129,43399:65130,43400:65131,43401:12350,43402:12272,43403:12273,43404:12274,43405:12275,43406:12276,43407:12277,43408:12278,43409:12279,43410:12280,43411:12281,43412:12282,43413:12283,43414:12295,43415:59380,43416:59381,43417:59382,43418:59383,43419:59384,43420:59385,43421:59386,43422:59387,43423:59388,43424:59389,43425:59390,43426:59391,43427:59392,43428:9472,43429:9473,43430:9474,43431:9475,43432:9476,43433:9477,43434:9478,43435:9479,43436:9480,43437:9481,43438:9482,43439:9483,43440:9484,43441:9485,43442:9486,43443:9487,43444:9488,43445:9489,43446:9490,43447:9491,43448:9492,43449:9493,43450:9494,43451:9495,43452:9496,43453:9497,43454:9498,43455:9499,43456:9500,43457:9501,43458:9502,43459:9503,43460:9504,43461:9505,43462:9506,43463:9507,43464:9508,43465:9509,43466:9510,43467:9511,43468:9512,43469:9513,43470:9514,43471:9515,43472:9516,43473:9517,43474:9518,43475:9519,43476:9520,43477:9521,43478:9522,43479:9523,43480:9524,43481:9525,43482:9526,43483:9527,43484:9528,43485:9529,43486:9530,43487:9531,43488:9532,43489:9533,43490:9534,43491:9535,43492:9536,43493:9537,43494:9538,43495:9539,43496:9540,43497:9541,43498:9542,43499:9543,43500:9544,43501:9545,43502:9546,43503:9547,43504:59393,43505:59394,43506:59395,43507:59396,43508:59397,43509:59398,43510:59399,43511:59400,43512:59401,43513:59402,43514:59403,43515:59404,43516:59405,43517:59406,43518:59407,43584:29404,43585:29405,43586:29407,43587:29410,43588:29411,43589:29412,43590:29413,43591:29414,43592:29415,43593:29418,43594:29419,43595:29429,43596:29430,43597:29433,43598:29437,43599:29438,43600:29439,43601:29440,43602:29442,43603:29444,43604:29445,43605:29446,43606:29447,43607:29448,43608:29449,43609:29451,43610:29452,43611:29453,43612:29455,43613:29456,43614:29457,43615:29458,43616:29460,43617:29464,43618:29465,43619:29466,43620:29471,43621:29472,43622:29475,43623:29476,43624:29478,43625:29479,43626:29480,43627:29485,43628:29487,43629:29488,43630:29490,43631:29491,43632:29493,43633:29494,43634:29498,43635:29499,43636:29500,43637:29501,43638:29504,43639:29505,43640:29506,43641:29507,43642:29508,43643:29509,43644:29510,43645:29511,43646:29512,43648:29513,43649:29514,43650:29515,43651:29516,43652:29518,43653:29519,43654:29521,43655:29523,43656:29524,43657:29525,43658:29526,43659:29528,43660:29529,43661:29530,43662:29531,43663:29532,43664:29533,43665:29534,43666:29535,43667:29537,43668:29538,43669:29539,43670:29540,43671:29541,43672:29542,43673:29543,43674:29544,43675:29545,43676:29546,43677:29547,43678:29550,43679:29552,43680:29553,43681:57344,43682:57345,43683:57346,43684:57347,43685:57348,43686:57349,43687:57350,43688:57351,43689:57352,43690:57353,43691:57354,43692:57355,43693:57356,43694:57357,43695:57358,43696:57359,43697:57360,43698:57361,43699:57362,43700:57363,43701:57364,43702:57365,43703:57366,43704:57367,43705:57368,43706:57369,43707:57370,43708:57371,43709:57372,43710:57373,43711:57374,43712:57375,43713:57376,43714:57377,43715:57378,43716:57379,43717:57380,43718:57381,43719:57382,43720:57383,43721:57384,43722:57385,43723:57386,43724:57387,43725:57388,43726:57389,43727:57390,43728:57391,43729:57392,43730:57393,43731:57394,43732:57395,43733:57396,43734:57397,43735:57398,43736:57399,43737:57400,43738:57401,43739:57402,43740:57403,43741:57404,43742:57405,43743:57406,43744:57407,43745:57408,43746:57409,43747:57410,43748:57411,43749:57412,43750:57413,43751:57414,43752:57415,43753:57416,43754:57417,43755:57418,43756:57419,43757:57420,43758:57421,43759:57422,43760:57423,43761:57424,43762:57425,43763:57426,43764:57427,43765:57428,43766:57429,43767:57430,43768:57431,43769:57432,43770:57433,43771:57434,43772:57435,43773:57436,43774:57437,43840:29554,43841:29555,43842:29556,43843:29557,43844:29558,43845:29559,43846:29560,43847:29561,43848:29562,43849:29563,43850:29564,43851:29565,43852:29567,43853:29568,43854:29569,43855:29570,43856:29571,43857:29573,43858:29574,43859:29576,43860:29578,43861:29580,43862:29581,43863:29583,43864:29584,43865:29586,43866:29587,43867:29588,43868:29589,43869:29591,43870:29592,43871:29593,43872:29594,43873:29596,43874:29597,43875:29598,43876:29600,43877:29601,43878:29603,43879:29604,43880:29605,43881:29606,43882:29607,43883:29608,43884:29610,43885:29612,43886:29613,43887:29617,43888:29620,43889:29621,43890:29622,43891:29624,43892:29625,43893:29628,43894:29629,43895:29630,43896:29631,43897:29633,43898:29635,43899:29636,43900:29637,43901:29638,43902:29639,43904:29643,43905:29644,43906:29646,43907:29650,43908:29651,43909:29652,43910:29653,43911:29654,43912:29655,43913:29656,43914:29658,43915:29659,43916:29660,43917:29661,43918:29663,43919:29665,43920:29666,43921:29667,43922:29668,43923:29670,43924:29672,43925:29674,43926:29675,43927:29676,43928:29678,43929:29679,43930:29680,43931:29681,43932:29683,43933:29684,43934:29685,43935:29686,43936:29687,43937:57438,43938:57439,43939:57440,43940:57441,43941:57442,43942:57443,43943:57444,43944:57445,43945:57446,43946:57447,43947:57448,43948:57449,43949:57450,43950:57451,43951:57452,43952:57453,43953:57454,43954:57455,43955:57456,43956:57457,43957:57458,43958:57459,43959:57460,43960:57461,43961:57462,43962:57463,43963:57464,43964:57465,43965:57466,43966:57467,43967:57468,43968:57469,43969:57470,43970:57471,43971:57472,43972:57473,43973:57474,43974:57475,43975:57476,43976:57477,43977:57478,43978:57479,43979:57480,43980:57481,43981:57482,43982:57483,43983:57484,43984:57485,43985:57486,43986:57487,43987:57488,43988:57489,43989:57490,43990:57491,43991:57492,43992:57493,43993:57494,43994:57495,43995:57496,43996:57497,43997:57498,43998:57499,43999:57500,44000:57501,44001:57502,44002:57503,44003:57504,44004:57505,44005:57506,44006:57507,44007:57508,44008:57509,44009:57510,44010:57511,44011:57512,44012:57513,44013:57514,44014:57515,44015:57516,44016:57517,44017:57518,44018:57519,44019:57520,44020:57521,44021:57522,44022:57523,44023:57524,44024:57525,44025:57526,44026:57527,44027:57528,44028:57529,44029:57530,44030:57531,44096:29688,44097:29689,44098:29690,44099:29691,44100:29692,44101:29693,44102:29694,44103:29695,44104:29696,44105:29697,44106:29698,44107:29700,44108:29703,44109:29704,44110:29707,44111:29708,44112:29709,44113:29710,44114:29713,44115:29714,44116:29715,44117:29716,44118:29717,44119:29718,44120:29719,44121:29720,44122:29721,44123:29724,44124:29725,44125:29726,44126:29727,44127:29728,44128:29729,44129:29731,44130:29732,44131:29735,44132:29737,44133:29739,44134:29741,44135:29743,44136:29745,44137:29746,44138:29751,44139:29752,44140:29753,44141:29754,44142:29755,44143:29757,44144:29758,44145:29759,44146:29760,44147:29762,44148:29763,44149:29764,44150:29765,44151:29766,44152:29767,44153:29768,44154:29769,44155:29770,44156:29771,44157:29772,44158:29773,44160:29774,44161:29775,44162:29776,44163:29777,44164:29778,44165:29779,44166:29780,44167:29782,44168:29784,44169:29789,44170:29792,44171:29793,44172:29794,44173:29795,44174:29796,44175:29797,44176:29798,44177:29799,44178:29800,44179:29801,44180:29802,44181:29803,44182:29804,44183:29806,44184:29807,44185:29809,44186:29810,44187:29811,44188:29812,44189:29813,44190:29816,44191:29817,44192:29818,44193:57532,44194:57533,44195:57534,44196:57535,44197:57536,44198:57537,44199:57538,44200:57539,44201:57540,44202:57541,44203:57542,44204:57543,44205:57544,44206:57545,44207:57546,44208:57547,44209:57548,44210:57549,44211:57550,44212:57551,44213:57552,44214:57553,44215:57554,44216:57555,44217:57556,44218:57557,44219:57558,44220:57559,44221:57560,44222:57561,44223:57562,44224:57563,44225:57564,44226:57565,44227:57566,44228:57567,44229:57568,44230:57569,44231:57570,44232:57571,44233:57572,44234:57573,44235:57574,44236:57575,44237:57576,44238:57577,44239:57578,44240:57579,44241:57580,44242:57581,44243:57582,44244:57583,44245:57584,44246:57585,44247:57586,44248:57587,44249:57588,44250:57589,44251:57590,44252:57591,44253:57592,44254:57593,44255:57594,44256:57595,44257:57596,44258:57597,44259:57598,44260:57599,44261:57600,44262:57601,44263:57602,44264:57603,44265:57604,44266:57605,44267:57606,44268:57607,44269:57608,44270:57609,44271:57610,44272:57611,44273:57612,44274:57613,44275:57614,44276:57615,44277:57616,44278:57617,44279:57618,44280:57619,44281:57620,44282:57621,44283:57622,44284:57623,44285:57624,44286:57625,44352:29819,44353:29820,44354:29821,44355:29823,44356:29826,44357:29828,44358:29829,44359:29830,44360:29832,44361:29833,44362:29834,44363:29836,44364:29837,44365:29839,44366:29841,44367:29842,44368:29843,44369:29844,44370:29845,44371:29846,44372:29847,44373:29848,44374:29849,44375:29850,44376:29851,44377:29853,44378:29855,44379:29856,44380:29857,44381:29858,44382:29859,44383:29860,44384:29861,44385:29862,44386:29866,44387:29867,44388:29868,44389:29869,44390:29870,44391:29871,44392:29872,44393:29873,44394:29874,44395:29875,44396:29876,44397:29877,44398:29878,44399:29879,44400:29880,44401:29881,44402:29883,44403:29884,44404:29885,44405:29886,44406:29887,44407:29888,44408:29889,44409:29890,44410:29891,44411:29892,44412:29893,44413:29894,44414:29895,44416:29896,44417:29897,44418:29898,44419:29899,44420:29900,44421:29901,44422:29902,44423:29903,44424:29904,44425:29905,44426:29907,44427:29908,44428:29909,44429:29910,44430:29911,44431:29912,44432:29913,44433:29914,44434:29915,44435:29917,44436:29919,44437:29921,44438:29925,44439:29927,44440:29928,44441:29929,44442:29930,44443:29931,44444:29932,44445:29933,44446:29936,44447:29937,44448:29938,44449:57626,44450:57627,44451:57628,44452:57629,44453:57630,44454:57631,44455:57632,44456:57633,44457:57634,44458:57635,44459:57636,44460:57637,44461:57638,44462:57639,44463:57640,44464:57641,44465:57642,44466:57643,44467:57644,44468:57645,44469:57646,44470:57647,44471:57648,44472:57649,44473:57650,44474:57651,44475:57652,44476:57653,44477:57654,44478:57655,44479:57656,44480:57657,44481:57658,44482:57659,44483:57660,44484:57661,44485:57662,44486:57663,44487:57664,44488:57665,44489:57666,44490:57667,44491:57668,44492:57669,44493:57670,44494:57671,44495:57672,44496:57673,44497:57674,44498:57675,44499:57676,44500:57677,44501:57678,44502:57679,44503:57680,44504:57681,44505:57682,44506:57683,44507:57684,44508:57685,44509:57686,44510:57687,44511:57688,44512:57689,44513:57690,44514:57691,44515:57692,44516:57693,44517:57694,44518:57695,44519:57696,44520:57697,44521:57698,44522:57699,44523:57700,44524:57701,44525:57702,44526:57703,44527:57704,44528:57705,44529:57706,44530:57707,44531:57708,44532:57709,44533:57710,44534:57711,44535:57712,44536:57713,44537:57714,44538:57715,44539:57716,44540:57717,44541:57718,44542:57719,44608:29939,44609:29941,44610:29944,44611:29945,44612:29946,44613:29947,44614:29948,44615:29949,44616:29950,44617:29952,44618:29953,44619:29954,44620:29955,44621:29957,44622:29958,44623:29959,44624:29960,44625:29961,44626:29962,44627:29963,44628:29964,44629:29966,44630:29968,44631:29970,44632:29972,44633:29973,44634:29974,44635:29975,44636:29979,44637:29981,44638:29982,44639:29984,44640:29985,44641:29986,44642:29987,44643:29988,44644:29990,44645:29991,44646:29994,44647:29998,44648:30004,44649:30006,44650:30009,44651:30012,44652:30013,44653:30015,44654:30017,44655:30018,44656:30019,44657:30020,44658:30022,44659:30023,44660:30025,44661:30026,44662:30029,44663:30032,44664:30033,44665:30034,44666:30035,44667:30037,44668:30038,44669:30039,44670:30040,44672:30045,44673:30046,44674:30047,44675:30048,44676:30049,44677:30050,44678:30051,44679:30052,44680:30055,44681:30056,44682:30057,44683:30059,44684:30060,44685:30061,44686:30062,44687:30063,44688:30064,44689:30065,44690:30067,44691:30069,44692:30070,44693:30071,44694:30074,44695:30075,44696:30076,44697:30077,44698:30078,44699:30080,44700:30081,44701:30082,44702:30084,44703:30085,44704:30087,44705:57720,44706:57721,44707:57722,44708:57723,44709:57724,44710:57725,44711:57726,44712:57727,44713:57728,44714:57729,44715:57730,44716:57731,44717:57732,44718:57733,44719:57734,44720:57735,44721:57736,44722:57737,44723:57738,44724:57739,44725:57740,44726:57741,44727:57742,44728:57743,44729:57744,44730:57745,44731:57746,44732:57747,44733:57748,44734:57749,44735:57750,44736:57751,44737:57752,44738:57753,44739:57754,44740:57755,44741:57756,44742:57757,44743:57758,44744:57759,44745:57760,44746:57761,44747:57762,44748:57763,44749:57764,44750:57765,44751:57766,44752:57767,44753:57768,44754:57769,44755:57770,44756:57771,44757:57772,44758:57773,44759:57774,44760:57775,44761:57776,44762:57777,44763:57778,44764:57779,44765:57780,44766:57781,44767:57782,44768:57783,44769:57784,44770:57785,44771:57786,44772:57787,44773:57788,44774:57789,44775:57790,44776:57791,44777:57792,44778:57793,44779:57794,44780:57795,44781:57796,44782:57797,44783:57798,44784:57799,44785:57800,44786:57801,44787:57802,44788:57803,44789:57804,44790:57805,44791:57806,44792:57807,44793:57808,44794:57809,44795:57810,44796:57811,44797:57812,44798:57813,44864:30088,44865:30089,44866:30090,44867:30092,44868:30093,44869:30094,44870:30096,44871:30099,44872:30101,44873:30104,44874:30107,44875:30108,44876:30110,44877:30114,44878:30118,44879:30119,44880:30120,44881:30121,44882:30122,44883:30125,44884:30134,44885:30135,44886:30138,44887:30139,44888:30143,44889:30144,44890:30145,44891:30150,44892:30155,44893:30156,44894:30158,44895:30159,44896:30160,44897:30161,44898:30163,44899:30167,44900:30169,44901:30170,44902:30172,44903:30173,44904:30175,44905:30176,44906:30177,44907:30181,44908:30185,44909:30188,44910:30189,44911:30190,44912:30191,44913:30194,44914:30195,44915:30197,44916:30198,44917:30199,44918:30200,44919:30202,44920:30203,44921:30205,44922:30206,44923:30210,44924:30212,44925:30214,44926:30215,44928:30216,44929:30217,44930:30219,44931:30221,44932:30222,44933:30223,44934:30225,44935:30226,44936:30227,44937:30228,44938:30230,44939:30234,44940:30236,44941:30237,44942:30238,44943:30241,44944:30243,44945:30247,44946:30248,44947:30252,44948:30254,44949:30255,44950:30257,44951:30258,44952:30262,44953:30263,44954:30265,44955:30266,44956:30267,44957:30269,44958:30273,44959:30274,44960:30276,44961:57814,44962:57815,44963:57816,44964:57817,44965:57818,44966:57819,44967:57820,44968:57821,44969:57822,44970:57823,44971:57824,44972:57825,44973:57826,44974:57827,44975:57828,44976:57829,44977:57830,44978:57831,44979:57832,44980:57833,44981:57834,44982:57835,44983:57836,44984:57837,44985:57838,44986:57839,44987:57840,44988:57841,44989:57842,44990:57843,44991:57844,44992:57845,44993:57846,44994:57847,44995:57848,44996:57849,44997:57850,44998:57851,44999:57852,45000:57853,45001:57854,45002:57855,45003:57856,45004:57857,45005:57858,45006:57859,45007:57860,45008:57861,45009:57862,45010:57863,45011:57864,45012:57865,45013:57866,45014:57867,45015:57868,45016:57869,45017:57870,45018:57871,45019:57872,45020:57873,45021:57874,45022:57875,45023:57876,45024:57877,45025:57878,45026:57879,45027:57880,45028:57881,45029:57882,45030:57883,45031:57884,45032:57885,45033:57886,45034:57887,45035:57888,45036:57889,45037:57890,45038:57891,45039:57892,45040:57893,45041:57894,45042:57895,45043:57896,45044:57897,45045:57898,45046:57899,45047:57900,45048:57901,45049:57902,45050:57903,45051:57904,45052:57905,45053:57906,45054:57907,45120:30277,45121:30278,45122:30279,45123:30280,45124:30281,45125:30282,45126:30283,45127:30286,45128:30287,45129:30288,45130:30289,45131:30290,45132:30291,45133:30293,45134:30295,45135:30296,45136:30297,45137:30298,45138:30299,45139:30301,45140:30303,45141:30304,45142:30305,45143:30306,45144:30308,45145:30309,45146:30310,45147:30311,45148:30312,45149:30313,45150:30314,45151:30316,45152:30317,45153:30318,45154:30320,45155:30321,45156:30322,45157:30323,45158:30324,45159:30325,45160:30326,45161:30327,45162:30329,45163:30330,45164:30332,45165:30335,45166:30336,45167:30337,45168:30339,45169:30341,45170:30345,45171:30346,45172:30348,45173:30349,45174:30351,45175:30352,45176:30354,45177:30356,45178:30357,45179:30359,45180:30360,45181:30362,45182:30363,45184:30364,45185:30365,45186:30366,45187:30367,45188:30368,45189:30369,45190:30370,45191:30371,45192:30373,45193:30374,45194:30375,45195:30376,45196:30377,45197:30378,45198:30379,45199:30380,45200:30381,45201:30383,45202:30384,45203:30387,45204:30389,45205:30390,45206:30391,45207:30392,45208:30393,45209:30394,45210:30395,45211:30396,45212:30397,45213:30398,45214:30400,45215:30401,45216:30403,45217:21834,45218:38463,45219:22467,45220:25384,45221:21710,45222:21769,45223:21696,45224:30353,45225:30284,45226:34108,45227:30702,45228:33406,45229:30861,45230:29233,45231:38552,45232:38797,45233:27688,45234:23433,45235:20474,45236:25353,45237:26263,45238:23736,45239:33018,45240:26696,45241:32942,45242:26114,45243:30414,45244:20985,45245:25942,45246:29100,45247:32753,45248:34948,45249:20658,45250:22885,45251:25034,45252:28595,45253:33453,45254:25420,45255:25170,45256:21485,45257:21543,45258:31494,45259:20843,45260:30116,45261:24052,45262:25300,45263:36299,45264:38774,45265:25226,45266:32793,45267:22365,45268:38712,45269:32610,45270:29240,45271:30333,45272:26575,45273:30334,45274:25670,45275:20336,45276:36133,45277:25308,45278:31255,45279:26001,45280:29677,45281:25644,45282:25203,45283:33324,45284:39041,45285:26495,45286:29256,45287:25198,45288:25292,45289:20276,45290:29923,45291:21322,45292:21150,45293:32458,45294:37030,45295:24110,45296:26758,45297:27036,45298:33152,45299:32465,45300:26834,45301:30917,45302:34444,45303:38225,45304:20621,45305:35876,45306:33502,45307:32990,45308:21253,45309:35090,45310:21093,45376:30404,45377:30407,45378:30409,45379:30411,45380:30412,45381:30419,45382:30421,45383:30425,45384:30426,45385:30428,45386:30429,45387:30430,45388:30432,45389:30433,45390:30434,45391:30435,45392:30436,45393:30438,45394:30439,45395:30440,45396:30441,45397:30442,45398:30443,45399:30444,45400:30445,45401:30448,45402:30451,45403:30453,45404:30454,45405:30455,45406:30458,45407:30459,45408:30461,45409:30463,45410:30464,45411:30466,45412:30467,45413:30469,45414:30470,45415:30474,45416:30476,45417:30478,45418:30479,45419:30480,45420:30481,45421:30482,45422:30483,45423:30484,45424:30485,45425:30486,45426:30487,45427:30488,45428:30491,45429:30492,45430:30493,45431:30494,45432:30497,45433:30499,45434:30500,45435:30501,45436:30503,45437:30506,45438:30507,45440:30508,45441:30510,45442:30512,45443:30513,45444:30514,45445:30515,45446:30516,45447:30521,45448:30523,45449:30525,45450:30526,45451:30527,45452:30530,45453:30532,45454:30533,45455:30534,45456:30536,45457:30537,45458:30538,45459:30539,45460:30540,45461:30541,45462:30542,45463:30543,45464:30546,45465:30547,45466:30548,45467:30549,45468:30550,45469:30551,45470:30552,45471:30553,45472:30556,45473:34180,45474:38649,45475:20445,45476:22561,45477:39281,45478:23453,45479:25265,45480:25253,45481:26292,45482:35961,45483:40077,45484:29190,45485:26479,45486:30865,45487:24754,45488:21329,45489:21271,45490:36744,45491:32972,45492:36125,45493:38049,45494:20493,45495:29384,45496:22791,45497:24811,45498:28953,45499:34987,45500:22868,45501:33519,45502:26412,45503:31528,45504:23849,45505:32503,45506:29997,45507:27893,45508:36454,45509:36856,45510:36924,45511:40763,45512:27604,45513:37145,45514:31508,45515:24444,45516:30887,45517:34006,45518:34109,45519:27605,45520:27609,45521:27606,45522:24065,45523:24199,45524:30201,45525:38381,45526:25949,45527:24330,45528:24517,45529:36767,45530:22721,45531:33218,45532:36991,45533:38491,45534:38829,45535:36793,45536:32534,45537:36140,45538:25153,45539:20415,45540:21464,45541:21342,45542:36776,45543:36777,45544:36779,45545:36941,45546:26631,45547:24426,45548:33176,45549:34920,45550:40150,45551:24971,45552:21035,45553:30250,45554:24428,45555:25996,45556:28626,45557:28392,45558:23486,45559:25672,45560:20853,45561:20912,45562:26564,45563:19993,45564:31177,45565:39292,45566:28851,45632:30557,45633:30558,45634:30559,45635:30560,45636:30564,45637:30567,45638:30569,45639:30570,45640:30573,45641:30574,45642:30575,45643:30576,45644:30577,45645:30578,45646:30579,45647:30580,45648:30581,45649:30582,45650:30583,45651:30584,45652:30586,45653:30587,45654:30588,45655:30593,45656:30594,45657:30595,45658:30598,45659:30599,45660:30600,45661:30601,45662:30602,45663:30603,45664:30607,45665:30608,45666:30611,45667:30612,45668:30613,45669:30614,45670:30615,45671:30616,45672:30617,45673:30618,45674:30619,45675:30620,45676:30621,45677:30622,45678:30625,45679:30627,45680:30628,45681:30630,45682:30632,45683:30635,45684:30637,45685:30638,45686:30639,45687:30641,45688:30642,45689:30644,45690:30646,45691:30647,45692:30648,45693:30649,45694:30650,45696:30652,45697:30654,45698:30656,45699:30657,45700:30658,45701:30659,45702:30660,45703:30661,45704:30662,45705:30663,45706:30664,45707:30665,45708:30666,45709:30667,45710:30668,45711:30670,45712:30671,45713:30672,45714:30673,45715:30674,45716:30675,45717:30676,45718:30677,45719:30678,45720:30680,45721:30681,45722:30682,45723:30685,45724:30686,45725:30687,45726:30688,45727:30689,45728:30692,45729:30149,45730:24182,45731:29627,45732:33760,45733:25773,45734:25320,45735:38069,45736:27874,45737:21338,45738:21187,45739:25615,45740:38082,45741:31636,45742:20271,45743:24091,45744:33334,45745:33046,45746:33162,45747:28196,45748:27850,45749:39539,45750:25429,45751:21340,45752:21754,45753:34917,45754:22496,45755:19981,45756:24067,45757:27493,45758:31807,45759:37096,45760:24598,45761:25830,45762:29468,45763:35009,45764:26448,45765:25165,45766:36130,45767:30572,45768:36393,45769:37319,45770:24425,45771:33756,45772:34081,45773:39184,45774:21442,45775:34453,45776:27531,45777:24813,45778:24808,45779:28799,45780:33485,45781:33329,45782:20179,45783:27815,45784:34255,45785:25805,45786:31961,45787:27133,45788:26361,45789:33609,45790:21397,45791:31574,45792:20391,45793:20876,45794:27979,45795:23618,45796:36461,45797:25554,45798:21449,45799:33580,45800:33590,45801:26597,45802:30900,45803:25661,45804:23519,45805:23700,45806:24046,45807:35815,45808:25286,45809:26612,45810:35962,45811:25600,45812:25530,45813:34633,45814:39307,45815:35863,45816:32544,45817:38130,45818:20135,45819:38416,45820:39076,45821:26124,45822:29462,45888:30694,45889:30696,45890:30698,45891:30703,45892:30704,45893:30705,45894:30706,45895:30708,45896:30709,45897:30711,45898:30713,45899:30714,45900:30715,45901:30716,45902:30723,45903:30724,45904:30725,45905:30726,45906:30727,45907:30728,45908:30730,45909:30731,45910:30734,45911:30735,45912:30736,45913:30739,45914:30741,45915:30745,45916:30747,45917:30750,45918:30752,45919:30753,45920:30754,45921:30756,45922:30760,45923:30762,45924:30763,45925:30766,45926:30767,45927:30769,45928:30770,45929:30771,45930:30773,45931:30774,45932:30781,45933:30783,45934:30785,45935:30786,45936:30787,45937:30788,45938:30790,45939:30792,45940:30793,45941:30794,45942:30795,45943:30797,45944:30799,45945:30801,45946:30803,45947:30804,45948:30808,45949:30809,45950:30810,45952:30811,45953:30812,45954:30814,45955:30815,45956:30816,45957:30817,45958:30818,45959:30819,45960:30820,45961:30821,45962:30822,45963:30823,45964:30824,45965:30825,45966:30831,45967:30832,45968:30833,45969:30834,45970:30835,45971:30836,45972:30837,45973:30838,45974:30840,45975:30841,45976:30842,45977:30843,45978:30845,45979:30846,45980:30847,45981:30848,45982:30849,45983:30850,45984:30851,45985:22330,45986:23581,45987:24120,45988:38271,45989:20607,45990:32928,45991:21378,45992:25950,45993:30021,45994:21809,45995:20513,45996:36229,45997:25220,45998:38046,45999:26397,46000:22066,46001:28526,46002:24034,46003:21557,46004:28818,46005:36710,46006:25199,46007:25764,46008:25507,46009:24443,46010:28552,46011:37108,46012:33251,46013:36784,46014:23576,46015:26216,46016:24561,46017:27785,46018:38472,46019:36225,46020:34924,46021:25745,46022:31216,46023:22478,46024:27225,46025:25104,46026:21576,46027:20056,46028:31243,46029:24809,46030:28548,46031:35802,46032:25215,46033:36894,46034:39563,46035:31204,46036:21507,46037:30196,46038:25345,46039:21273,46040:27744,46041:36831,46042:24347,46043:39536,46044:32827,46045:40831,46046:20360,46047:23610,46048:36196,46049:32709,46050:26021,46051:28861,46052:20805,46053:20914,46054:34411,46055:23815,46056:23456,46057:25277,46058:37228,46059:30068,46060:36364,46061:31264,46062:24833,46063:31609,46064:20167,46065:32504,46066:30597,46067:19985,46068:33261,46069:21021,46070:20986,46071:27249,46072:21416,46073:36487,46074:38148,46075:38607,46076:28353,46077:38500,46078:26970,46144:30852,46145:30853,46146:30854,46147:30856,46148:30858,46149:30859,46150:30863,46151:30864,46152:30866,46153:30868,46154:30869,46155:30870,46156:30873,46157:30877,46158:30878,46159:30880,46160:30882,46161:30884,46162:30886,46163:30888,46164:30889,46165:30890,46166:30891,46167:30892,46168:30893,46169:30894,46170:30895,46171:30901,46172:30902,46173:30903,46174:30904,46175:30906,46176:30907,46177:30908,46178:30909,46179:30911,46180:30912,46181:30914,46182:30915,46183:30916,46184:30918,46185:30919,46186:30920,46187:30924,46188:30925,46189:30926,46190:30927,46191:30929,46192:30930,46193:30931,46194:30934,46195:30935,46196:30936,46197:30938,46198:30939,46199:30940,46200:30941,46201:30942,46202:30943,46203:30944,46204:30945,46205:30946,46206:30947,46208:30948,46209:30949,46210:30950,46211:30951,46212:30953,46213:30954,46214:30955,46215:30957,46216:30958,46217:30959,46218:30960,46219:30961,46220:30963,46221:30965,46222:30966,46223:30968,46224:30969,46225:30971,46226:30972,46227:30973,46228:30974,46229:30975,46230:30976,46231:30978,46232:30979,46233:30980,46234:30982,46235:30983,46236:30984,46237:30985,46238:30986,46239:30987,46240:30988,46241:30784,46242:20648,46243:30679,46244:25616,46245:35302,46246:22788,46247:25571,46248:24029,46249:31359,46250:26941,46251:20256,46252:33337,46253:21912,46254:20018,46255:30126,46256:31383,46257:24162,46258:24202,46259:38383,46260:21019,46261:21561,46262:28810,46263:25462,46264:38180,46265:22402,46266:26149,46267:26943,46268:37255,46269:21767,46270:28147,46271:32431,46272:34850,46273:25139,46274:32496,46275:30133,46276:33576,46277:30913,46278:38604,46279:36766,46280:24904,46281:29943,46282:35789,46283:27492,46284:21050,46285:36176,46286:27425,46287:32874,46288:33905,46289:22257,46290:21254,46291:20174,46292:19995,46293:20945,46294:31895,46295:37259,46296:31751,46297:20419,46298:36479,46299:31713,46300:31388,46301:25703,46302:23828,46303:20652,46304:33030,46305:30209,46306:31929,46307:28140,46308:32736,46309:26449,46310:23384,46311:23544,46312:30923,46313:25774,46314:25619,46315:25514,46316:25387,46317:38169,46318:25645,46319:36798,46320:31572,46321:30249,46322:25171,46323:22823,46324:21574,46325:27513,46326:20643,46327:25140,46328:24102,46329:27526,46330:20195,46331:36151,46332:34955,46333:24453,46334:36910,46400:30989,46401:30990,46402:30991,46403:30992,46404:30993,46405:30994,46406:30996,46407:30997,46408:30998,46409:30999,46410:31000,46411:31001,46412:31002,46413:31003,46414:31004,46415:31005,46416:31007,46417:31008,46418:31009,46419:31010,46420:31011,46421:31013,46422:31014,46423:31015,46424:31016,46425:31017,46426:31018,46427:31019,46428:31020,46429:31021,46430:31022,46431:31023,46432:31024,46433:31025,46434:31026,46435:31027,46436:31029,46437:31030,46438:31031,46439:31032,46440:31033,46441:31037,46442:31039,46443:31042,46444:31043,46445:31044,46446:31045,46447:31047,46448:31050,46449:31051,46450:31052,46451:31053,46452:31054,46453:31055,46454:31056,46455:31057,46456:31058,46457:31060,46458:31061,46459:31064,46460:31065,46461:31073,46462:31075,46464:31076,46465:31078,46466:31081,46467:31082,46468:31083,46469:31084,46470:31086,46471:31088,46472:31089,46473:31090,46474:31091,46475:31092,46476:31093,46477:31094,46478:31097,46479:31099,46480:31100,46481:31101,46482:31102,46483:31103,46484:31106,46485:31107,46486:31110,46487:31111,46488:31112,46489:31113,46490:31115,46491:31116,46492:31117,46493:31118,46494:31120,46495:31121,46496:31122,46497:24608,46498:32829,46499:25285,46500:20025,46501:21333,46502:37112,46503:25528,46504:32966,46505:26086,46506:27694,46507:20294,46508:24814,46509:28129,46510:35806,46511:24377,46512:34507,46513:24403,46514:25377,46515:20826,46516:33633,46517:26723,46518:20992,46519:25443,46520:36424,46521:20498,46522:23707,46523:31095,46524:23548,46525:21040,46526:31291,46527:24764,46528:36947,46529:30423,46530:24503,46531:24471,46532:30340,46533:36460,46534:28783,46535:30331,46536:31561,46537:30634,46538:20979,46539:37011,46540:22564,46541:20302,46542:28404,46543:36842,46544:25932,46545:31515,46546:29380,46547:28068,46548:32735,46549:23265,46550:25269,46551:24213,46552:22320,46553:33922,46554:31532,46555:24093,46556:24351,46557:36882,46558:32532,46559:39072,46560:25474,46561:28359,46562:30872,46563:28857,46564:20856,46565:38747,46566:22443,46567:30005,46568:20291,46569:30008,46570:24215,46571:24806,46572:22880,46573:28096,46574:27583,46575:30857,46576:21500,46577:38613,46578:20939,46579:20993,46580:25481,46581:21514,46582:38035,46583:35843,46584:36300,46585:29241,46586:30879,46587:34678,46588:36845,46589:35853,46590:21472,46656:31123,46657:31124,46658:31125,46659:31126,46660:31127,46661:31128,46662:31129,46663:31131,46664:31132,46665:31133,46666:31134,46667:31135,46668:31136,46669:31137,46670:31138,46671:31139,46672:31140,46673:31141,46674:31142,46675:31144,46676:31145,46677:31146,46678:31147,46679:31148,46680:31149,46681:31150,46682:31151,46683:31152,46684:31153,46685:31154,46686:31156,46687:31157,46688:31158,46689:31159,46690:31160,46691:31164,46692:31167,46693:31170,46694:31172,46695:31173,46696:31175,46697:31176,46698:31178,46699:31180,46700:31182,46701:31183,46702:31184,46703:31187,46704:31188,46705:31190,46706:31191,46707:31193,46708:31194,46709:31195,46710:31196,46711:31197,46712:31198,46713:31200,46714:31201,46715:31202,46716:31205,46717:31208,46718:31210,46720:31212,46721:31214,46722:31217,46723:31218,46724:31219,46725:31220,46726:31221,46727:31222,46728:31223,46729:31225,46730:31226,46731:31228,46732:31230,46733:31231,46734:31233,46735:31236,46736:31237,46737:31239,46738:31240,46739:31241,46740:31242,46741:31244,46742:31247,46743:31248,46744:31249,46745:31250,46746:31251,46747:31253,46748:31254,46749:31256,46750:31257,46751:31259,46752:31260,46753:19969,46754:30447,46755:21486,46756:38025,46757:39030,46758:40718,46759:38189,46760:23450,46761:35746,46762:20002,46763:19996,46764:20908,46765:33891,46766:25026,46767:21160,46768:26635,46769:20375,46770:24683,46771:20923,46772:27934,46773:20828,46774:25238,46775:26007,46776:38497,46777:35910,46778:36887,46779:30168,46780:37117,46781:30563,46782:27602,46783:29322,46784:29420,46785:35835,46786:22581,46787:30585,46788:36172,46789:26460,46790:38208,46791:32922,46792:24230,46793:28193,46794:22930,46795:31471,46796:30701,46797:38203,46798:27573,46799:26029,46800:32526,46801:22534,46802:20817,46803:38431,46804:23545,46805:22697,46806:21544,46807:36466,46808:25958,46809:39039,46810:22244,46811:38045,46812:30462,46813:36929,46814:25479,46815:21702,46816:22810,46817:22842,46818:22427,46819:36530,46820:26421,46821:36346,46822:33333,46823:21057,46824:24816,46825:22549,46826:34558,46827:23784,46828:40517,46829:20420,46830:39069,46831:35769,46832:23077,46833:24694,46834:21380,46835:25212,46836:36943,46837:37122,46838:39295,46839:24681,46840:32780,46841:20799,46842:32819,46843:23572,46844:39285,46845:27953,46846:20108,46912:31261,46913:31263,46914:31265,46915:31266,46916:31268,46917:31269,46918:31270,46919:31271,46920:31272,46921:31273,46922:31274,46923:31275,46924:31276,46925:31277,46926:31278,46927:31279,46928:31280,46929:31281,46930:31282,46931:31284,46932:31285,46933:31286,46934:31288,46935:31290,46936:31294,46937:31296,46938:31297,46939:31298,46940:31299,46941:31300,46942:31301,46943:31303,46944:31304,46945:31305,46946:31306,46947:31307,46948:31308,46949:31309,46950:31310,46951:31311,46952:31312,46953:31314,46954:31315,46955:31316,46956:31317,46957:31318,46958:31320,46959:31321,46960:31322,46961:31323,46962:31324,46963:31325,46964:31326,46965:31327,46966:31328,46967:31329,46968:31330,46969:31331,46970:31332,46971:31333,46972:31334,46973:31335,46974:31336,46976:31337,46977:31338,46978:31339,46979:31340,46980:31341,46981:31342,46982:31343,46983:31345,46984:31346,46985:31347,46986:31349,46987:31355,46988:31356,46989:31357,46990:31358,46991:31362,46992:31365,46993:31367,46994:31369,46995:31370,46996:31371,46997:31372,46998:31374,46999:31375,47000:31376,47001:31379,47002:31380,47003:31385,47004:31386,47005:31387,47006:31390,47007:31393,47008:31394,47009:36144,47010:21457,47011:32602,47012:31567,47013:20240,47014:20047,47015:38400,47016:27861,47017:29648,47018:34281,47019:24070,47020:30058,47021:32763,47022:27146,47023:30718,47024:38034,47025:32321,47026:20961,47027:28902,47028:21453,47029:36820,47030:33539,47031:36137,47032:29359,47033:39277,47034:27867,47035:22346,47036:33459,47037:26041,47038:32938,47039:25151,47040:38450,47041:22952,47042:20223,47043:35775,47044:32442,47045:25918,47046:33778,47047:38750,47048:21857,47049:39134,47050:32933,47051:21290,47052:35837,47053:21536,47054:32954,47055:24223,47056:27832,47057:36153,47058:33452,47059:37210,47060:21545,47061:27675,47062:20998,47063:32439,47064:22367,47065:28954,47066:27774,47067:31881,47068:22859,47069:20221,47070:24575,47071:24868,47072:31914,47073:20016,47074:23553,47075:26539,47076:34562,47077:23792,47078:38155,47079:39118,47080:30127,47081:28925,47082:36898,47083:20911,47084:32541,47085:35773,47086:22857,47087:20964,47088:20315,47089:21542,47090:22827,47091:25975,47092:32932,47093:23413,47094:25206,47095:25282,47096:36752,47097:24133,47098:27679,47099:31526,47100:20239,47101:20440,47102:26381,47168:31395,47169:31396,47170:31399,47171:31401,47172:31402,47173:31403,47174:31406,47175:31407,47176:31408,47177:31409,47178:31410,47179:31412,47180:31413,47181:31414,47182:31415,47183:31416,47184:31417,47185:31418,47186:31419,47187:31420,47188:31421,47189:31422,47190:31424,47191:31425,47192:31426,47193:31427,47194:31428,47195:31429,47196:31430,47197:31431,47198:31432,47199:31433,47200:31434,47201:31436,47202:31437,47203:31438,47204:31439,47205:31440,47206:31441,47207:31442,47208:31443,47209:31444,47210:31445,47211:31447,47212:31448,47213:31450,47214:31451,47215:31452,47216:31453,47217:31457,47218:31458,47219:31460,47220:31463,47221:31464,47222:31465,47223:31466,47224:31467,47225:31468,47226:31470,47227:31472,47228:31473,47229:31474,47230:31475,47232:31476,47233:31477,47234:31478,47235:31479,47236:31480,47237:31483,47238:31484,47239:31486,47240:31488,47241:31489,47242:31490,47243:31493,47244:31495,47245:31497,47246:31500,47247:31501,47248:31502,47249:31504,47250:31506,47251:31507,47252:31510,47253:31511,47254:31512,47255:31514,47256:31516,47257:31517,47258:31519,47259:31521,47260:31522,47261:31523,47262:31527,47263:31529,47264:31533,47265:28014,47266:28074,47267:31119,47268:34993,47269:24343,47270:29995,47271:25242,47272:36741,47273:20463,47274:37340,47275:26023,47276:33071,47277:33105,47278:24220,47279:33104,47280:36212,47281:21103,47282:35206,47283:36171,47284:22797,47285:20613,47286:20184,47287:38428,47288:29238,47289:33145,47290:36127,47291:23500,47292:35747,47293:38468,47294:22919,47295:32538,47296:21648,47297:22134,47298:22030,47299:35813,47300:25913,47301:27010,47302:38041,47303:30422,47304:28297,47305:24178,47306:29976,47307:26438,47308:26577,47309:31487,47310:32925,47311:36214,47312:24863,47313:31174,47314:25954,47315:36195,47316:20872,47317:21018,47318:38050,47319:32568,47320:32923,47321:32434,47322:23703,47323:28207,47324:26464,47325:31705,47326:30347,47327:39640,47328:33167,47329:32660,47330:31957,47331:25630,47332:38224,47333:31295,47334:21578,47335:21733,47336:27468,47337:25601,47338:25096,47339:40509,47340:33011,47341:30105,47342:21106,47343:38761,47344:33883,47345:26684,47346:34532,47347:38401,47348:38548,47349:38124,47350:20010,47351:21508,47352:32473,47353:26681,47354:36319,47355:32789,47356:26356,47357:24218,47358:32697,47424:31535,47425:31536,47426:31538,47427:31540,47428:31541,47429:31542,47430:31543,47431:31545,47432:31547,47433:31549,47434:31551,47435:31552,47436:31553,47437:31554,47438:31555,47439:31556,47440:31558,47441:31560,47442:31562,47443:31565,47444:31566,47445:31571,47446:31573,47447:31575,47448:31577,47449:31580,47450:31582,47451:31583,47452:31585,47453:31587,47454:31588,47455:31589,47456:31590,47457:31591,47458:31592,47459:31593,47460:31594,47461:31595,47462:31596,47463:31597,47464:31599,47465:31600,47466:31603,47467:31604,47468:31606,47469:31608,47470:31610,47471:31612,47472:31613,47473:31615,47474:31617,47475:31618,47476:31619,47477:31620,47478:31622,47479:31623,47480:31624,47481:31625,47482:31626,47483:31627,47484:31628,47485:31630,47486:31631,47488:31633,47489:31634,47490:31635,47491:31638,47492:31640,47493:31641,47494:31642,47495:31643,47496:31646,47497:31647,47498:31648,47499:31651,47500:31652,47501:31653,47502:31662,47503:31663,47504:31664,47505:31666,47506:31667,47507:31669,47508:31670,47509:31671,47510:31673,47511:31674,47512:31675,47513:31676,47514:31677,47515:31678,47516:31679,47517:31680,47518:31682,47519:31683,47520:31684,47521:22466,47522:32831,47523:26775,47524:24037,47525:25915,47526:21151,47527:24685,47528:40858,47529:20379,47530:36524,47531:20844,47532:23467,47533:24339,47534:24041,47535:27742,47536:25329,47537:36129,47538:20849,47539:38057,47540:21246,47541:27807,47542:33503,47543:29399,47544:22434,47545:26500,47546:36141,47547:22815,47548:36764,47549:33735,47550:21653,47551:31629,47552:20272,47553:27837,47554:23396,47555:22993,47556:40723,47557:21476,47558:34506,47559:39592,47560:35895,47561:32929,47562:25925,47563:39038,47564:22266,47565:38599,47566:21038,47567:29916,47568:21072,47569:23521,47570:25346,47571:35074,47572:20054,47573:25296,47574:24618,47575:26874,47576:20851,47577:23448,47578:20896,47579:35266,47580:31649,47581:39302,47582:32592,47583:24815,47584:28748,47585:36143,47586:20809,47587:24191,47588:36891,47589:29808,47590:35268,47591:22317,47592:30789,47593:24402,47594:40863,47595:38394,47596:36712,47597:39740,47598:35809,47599:30328,47600:26690,47601:26588,47602:36330,47603:36149,47604:21053,47605:36746,47606:28378,47607:26829,47608:38149,47609:37101,47610:22269,47611:26524,47612:35065,47613:36807,47614:21704,47680:31685,47681:31688,47682:31689,47683:31690,47684:31691,47685:31693,47686:31694,47687:31695,47688:31696,47689:31698,47690:31700,47691:31701,47692:31702,47693:31703,47694:31704,47695:31707,47696:31708,47697:31710,47698:31711,47699:31712,47700:31714,47701:31715,47702:31716,47703:31719,47704:31720,47705:31721,47706:31723,47707:31724,47708:31725,47709:31727,47710:31728,47711:31730,47712:31731,47713:31732,47714:31733,47715:31734,47716:31736,47717:31737,47718:31738,47719:31739,47720:31741,47721:31743,47722:31744,47723:31745,47724:31746,47725:31747,47726:31748,47727:31749,47728:31750,47729:31752,47730:31753,47731:31754,47732:31757,47733:31758,47734:31760,47735:31761,47736:31762,47737:31763,47738:31764,47739:31765,47740:31767,47741:31768,47742:31769,47744:31770,47745:31771,47746:31772,47747:31773,47748:31774,47749:31776,47750:31777,47751:31778,47752:31779,47753:31780,47754:31781,47755:31784,47756:31785,47757:31787,47758:31788,47759:31789,47760:31790,47761:31791,47762:31792,47763:31793,47764:31794,47765:31795,47766:31796,47767:31797,47768:31798,47769:31799,47770:31801,47771:31802,47772:31803,47773:31804,47774:31805,47775:31806,47776:31810,47777:39608,47778:23401,47779:28023,47780:27686,47781:20133,47782:23475,47783:39559,47784:37219,47785:25000,47786:37039,47787:38889,47788:21547,47789:28085,47790:23506,47791:20989,47792:21898,47793:32597,47794:32752,47795:25788,47796:25421,47797:26097,47798:25022,47799:24717,47800:28938,47801:27735,47802:27721,47803:22831,47804:26477,47805:33322,47806:22741,47807:22158,47808:35946,47809:27627,47810:37085,47811:22909,47812:32791,47813:21495,47814:28009,47815:21621,47816:21917,47817:33655,47818:33743,47819:26680,47820:31166,47821:21644,47822:20309,47823:21512,47824:30418,47825:35977,47826:38402,47827:27827,47828:28088,47829:36203,47830:35088,47831:40548,47832:36154,47833:22079,47834:40657,47835:30165,47836:24456,47837:29408,47838:24680,47839:21756,47840:20136,47841:27178,47842:34913,47843:24658,47844:36720,47845:21700,47846:28888,47847:34425,47848:40511,47849:27946,47850:23439,47851:24344,47852:32418,47853:21897,47854:20399,47855:29492,47856:21564,47857:21402,47858:20505,47859:21518,47860:21628,47861:20046,47862:24573,47863:29786,47864:22774,47865:33899,47866:32993,47867:34676,47868:29392,47869:31946,47870:28246,47936:31811,47937:31812,47938:31813,47939:31814,47940:31815,47941:31816,47942:31817,47943:31818,47944:31819,47945:31820,47946:31822,47947:31823,47948:31824,47949:31825,47950:31826,47951:31827,47952:31828,47953:31829,47954:31830,47955:31831,47956:31832,47957:31833,47958:31834,47959:31835,47960:31836,47961:31837,47962:31838,47963:31839,47964:31840,47965:31841,47966:31842,47967:31843,47968:31844,47969:31845,47970:31846,47971:31847,47972:31848,47973:31849,47974:31850,47975:31851,47976:31852,47977:31853,47978:31854,47979:31855,47980:31856,47981:31857,47982:31858,47983:31861,47984:31862,47985:31863,47986:31864,47987:31865,47988:31866,47989:31870,47990:31871,47991:31872,47992:31873,47993:31874,47994:31875,47995:31876,47996:31877,47997:31878,47998:31879,48000:31880,48001:31882,48002:31883,48003:31884,48004:31885,48005:31886,48006:31887,48007:31888,48008:31891,48009:31892,48010:31894,48011:31897,48012:31898,48013:31899,48014:31904,48015:31905,48016:31907,48017:31910,48018:31911,48019:31912,48020:31913,48021:31915,48022:31916,48023:31917,48024:31919,48025:31920,48026:31924,48027:31925,48028:31926,48029:31927,48030:31928,48031:31930,48032:31931,48033:24359,48034:34382,48035:21804,48036:25252,48037:20114,48038:27818,48039:25143,48040:33457,48041:21719,48042:21326,48043:29502,48044:28369,48045:30011,48046:21010,48047:21270,48048:35805,48049:27088,48050:24458,48051:24576,48052:28142,48053:22351,48054:27426,48055:29615,48056:26707,48057:36824,48058:32531,48059:25442,48060:24739,48061:21796,48062:30186,48063:35938,48064:28949,48065:28067,48066:23462,48067:24187,48068:33618,48069:24908,48070:40644,48071:30970,48072:34647,48073:31783,48074:30343,48075:20976,48076:24822,48077:29004,48078:26179,48079:24140,48080:24653,48081:35854,48082:28784,48083:25381,48084:36745,48085:24509,48086:24674,48087:34516,48088:22238,48089:27585,48090:24724,48091:24935,48092:21321,48093:24800,48094:26214,48095:36159,48096:31229,48097:20250,48098:28905,48099:27719,48100:35763,48101:35826,48102:32472,48103:33636,48104:26127,48105:23130,48106:39746,48107:27985,48108:28151,48109:35905,48110:27963,48111:20249,48112:28779,48113:33719,48114:25110,48115:24785,48116:38669,48117:36135,48118:31096,48119:20987,48120:22334,48121:22522,48122:26426,48123:30072,48124:31293,48125:31215,48126:31637,48192:31935,48193:31936,48194:31938,48195:31939,48196:31940,48197:31942,48198:31945,48199:31947,48200:31950,48201:31951,48202:31952,48203:31953,48204:31954,48205:31955,48206:31956,48207:31960,48208:31962,48209:31963,48210:31965,48211:31966,48212:31969,48213:31970,48214:31971,48215:31972,48216:31973,48217:31974,48218:31975,48219:31977,48220:31978,48221:31979,48222:31980,48223:31981,48224:31982,48225:31984,48226:31985,48227:31986,48228:31987,48229:31988,48230:31989,48231:31990,48232:31991,48233:31993,48234:31994,48235:31996,48236:31997,48237:31998,48238:31999,48239:32000,48240:32001,48241:32002,48242:32003,48243:32004,48244:32005,48245:32006,48246:32007,48247:32008,48248:32009,48249:32011,48250:32012,48251:32013,48252:32014,48253:32015,48254:32016,48256:32017,48257:32018,48258:32019,48259:32020,48260:32021,48261:32022,48262:32023,48263:32024,48264:32025,48265:32026,48266:32027,48267:32028,48268:32029,48269:32030,48270:32031,48271:32033,48272:32035,48273:32036,48274:32037,48275:32038,48276:32040,48277:32041,48278:32042,48279:32044,48280:32045,48281:32046,48282:32048,48283:32049,48284:32050,48285:32051,48286:32052,48287:32053,48288:32054,48289:32908,48290:39269,48291:36857,48292:28608,48293:35749,48294:40481,48295:23020,48296:32489,48297:32521,48298:21513,48299:26497,48300:26840,48301:36753,48302:31821,48303:38598,48304:21450,48305:24613,48306:30142,48307:27762,48308:21363,48309:23241,48310:32423,48311:25380,48312:20960,48313:33034,48314:24049,48315:34015,48316:25216,48317:20864,48318:23395,48319:20238,48320:31085,48321:21058,48322:24760,48323:27982,48324:23492,48325:23490,48326:35745,48327:35760,48328:26082,48329:24524,48330:38469,48331:22931,48332:32487,48333:32426,48334:22025,48335:26551,48336:22841,48337:20339,48338:23478,48339:21152,48340:33626,48341:39050,48342:36158,48343:30002,48344:38078,48345:20551,48346:31292,48347:20215,48348:26550,48349:39550,48350:23233,48351:27516,48352:30417,48353:22362,48354:23574,48355:31546,48356:38388,48357:29006,48358:20860,48359:32937,48360:33392,48361:22904,48362:32516,48363:33575,48364:26816,48365:26604,48366:30897,48367:30839,48368:25315,48369:25441,48370:31616,48371:20461,48372:21098,48373:20943,48374:33616,48375:27099,48376:37492,48377:36341,48378:36145,48379:35265,48380:38190,48381:31661,48382:20214,48448:32055,48449:32056,48450:32057,48451:32058,48452:32059,48453:32060,48454:32061,48455:32062,48456:32063,48457:32064,48458:32065,48459:32066,48460:32067,48461:32068,48462:32069,48463:32070,48464:32071,48465:32072,48466:32073,48467:32074,48468:32075,48469:32076,48470:32077,48471:32078,48472:32079,48473:32080,48474:32081,48475:32082,48476:32083,48477:32084,48478:32085,48479:32086,48480:32087,48481:32088,48482:32089,48483:32090,48484:32091,48485:32092,48486:32093,48487:32094,48488:32095,48489:32096,48490:32097,48491:32098,48492:32099,48493:32100,48494:32101,48495:32102,48496:32103,48497:32104,48498:32105,48499:32106,48500:32107,48501:32108,48502:32109,48503:32111,48504:32112,48505:32113,48506:32114,48507:32115,48508:32116,48509:32117,48510:32118,48512:32120,48513:32121,48514:32122,48515:32123,48516:32124,48517:32125,48518:32126,48519:32127,48520:32128,48521:32129,48522:32130,48523:32131,48524:32132,48525:32133,48526:32134,48527:32135,48528:32136,48529:32137,48530:32138,48531:32139,48532:32140,48533:32141,48534:32142,48535:32143,48536:32144,48537:32145,48538:32146,48539:32147,48540:32148,48541:32149,48542:32150,48543:32151,48544:32152,48545:20581,48546:33328,48547:21073,48548:39279,48549:28176,48550:28293,48551:28071,48552:24314,48553:20725,48554:23004,48555:23558,48556:27974,48557:27743,48558:30086,48559:33931,48560:26728,48561:22870,48562:35762,48563:21280,48564:37233,48565:38477,48566:34121,48567:26898,48568:30977,48569:28966,48570:33014,48571:20132,48572:37066,48573:27975,48574:39556,48575:23047,48576:22204,48577:25605,48578:38128,48579:30699,48580:20389,48581:33050,48582:29409,48583:35282,48584:39290,48585:32564,48586:32478,48587:21119,48588:25945,48589:37237,48590:36735,48591:36739,48592:21483,48593:31382,48594:25581,48595:25509,48596:30342,48597:31224,48598:34903,48599:38454,48600:25130,48601:21163,48602:33410,48603:26708,48604:26480,48605:25463,48606:30571,48607:31469,48608:27905,48609:32467,48610:35299,48611:22992,48612:25106,48613:34249,48614:33445,48615:30028,48616:20511,48617:20171,48618:30117,48619:35819,48620:23626,48621:24062,48622:31563,48623:26020,48624:37329,48625:20170,48626:27941,48627:35167,48628:32039,48629:38182,48630:20165,48631:35880,48632:36827,48633:38771,48634:26187,48635:31105,48636:36817,48637:28908,48638:28024,48704:32153,48705:32154,48706:32155,48707:32156,48708:32157,48709:32158,48710:32159,48711:32160,48712:32161,48713:32162,48714:32163,48715:32164,48716:32165,48717:32167,48718:32168,48719:32169,48720:32170,48721:32171,48722:32172,48723:32173,48724:32175,48725:32176,48726:32177,48727:32178,48728:32179,48729:32180,48730:32181,48731:32182,48732:32183,48733:32184,48734:32185,48735:32186,48736:32187,48737:32188,48738:32189,48739:32190,48740:32191,48741:32192,48742:32193,48743:32194,48744:32195,48745:32196,48746:32197,48747:32198,48748:32199,48749:32200,48750:32201,48751:32202,48752:32203,48753:32204,48754:32205,48755:32206,48756:32207,48757:32208,48758:32209,48759:32210,48760:32211,48761:32212,48762:32213,48763:32214,48764:32215,48765:32216,48766:32217,48768:32218,48769:32219,48770:32220,48771:32221,48772:32222,48773:32223,48774:32224,48775:32225,48776:32226,48777:32227,48778:32228,48779:32229,48780:32230,48781:32231,48782:32232,48783:32233,48784:32234,48785:32235,48786:32236,48787:32237,48788:32238,48789:32239,48790:32240,48791:32241,48792:32242,48793:32243,48794:32244,48795:32245,48796:32246,48797:32247,48798:32248,48799:32249,48800:32250,48801:23613,48802:21170,48803:33606,48804:20834,48805:33550,48806:30555,48807:26230,48808:40120,48809:20140,48810:24778,48811:31934,48812:31923,48813:32463,48814:20117,48815:35686,48816:26223,48817:39048,48818:38745,48819:22659,48820:25964,48821:38236,48822:24452,48823:30153,48824:38742,48825:31455,48826:31454,48827:20928,48828:28847,48829:31384,48830:25578,48831:31350,48832:32416,48833:29590,48834:38893,48835:20037,48836:28792,48837:20061,48838:37202,48839:21417,48840:25937,48841:26087,48842:33276,48843:33285,48844:21646,48845:23601,48846:30106,48847:38816,48848:25304,48849:29401,48850:30141,48851:23621,48852:39545,48853:33738,48854:23616,48855:21632,48856:30697,48857:20030,48858:27822,48859:32858,48860:25298,48861:25454,48862:24040,48863:20855,48864:36317,48865:36382,48866:38191,48867:20465,48868:21477,48869:24807,48870:28844,48871:21095,48872:25424,48873:40515,48874:23071,48875:20518,48876:30519,48877:21367,48878:32482,48879:25733,48880:25899,48881:25225,48882:25496,48883:20500,48884:29237,48885:35273,48886:20915,48887:35776,48888:32477,48889:22343,48890:33740,48891:38055,48892:20891,48893:21531,48894:23803,48960:32251,48961:32252,48962:32253,48963:32254,48964:32255,48965:32256,48966:32257,48967:32258,48968:32259,48969:32260,48970:32261,48971:32262,48972:32263,48973:32264,48974:32265,48975:32266,48976:32267,48977:32268,48978:32269,48979:32270,48980:32271,48981:32272,48982:32273,48983:32274,48984:32275,48985:32276,48986:32277,48987:32278,48988:32279,48989:32280,48990:32281,48991:32282,48992:32283,48993:32284,48994:32285,48995:32286,48996:32287,48997:32288,48998:32289,48999:32290,49000:32291,49001:32292,49002:32293,49003:32294,49004:32295,49005:32296,49006:32297,49007:32298,49008:32299,49009:32300,49010:32301,49011:32302,49012:32303,49013:32304,49014:32305,49015:32306,49016:32307,49017:32308,49018:32309,49019:32310,49020:32311,49021:32312,49022:32313,49024:32314,49025:32316,49026:32317,49027:32318,49028:32319,49029:32320,49030:32322,49031:32323,49032:32324,49033:32325,49034:32326,49035:32328,49036:32329,49037:32330,49038:32331,49039:32332,49040:32333,49041:32334,49042:32335,49043:32336,49044:32337,49045:32338,49046:32339,49047:32340,49048:32341,49049:32342,49050:32343,49051:32344,49052:32345,49053:32346,49054:32347,49055:32348,49056:32349,49057:20426,49058:31459,49059:27994,49060:37089,49061:39567,49062:21888,49063:21654,49064:21345,49065:21679,49066:24320,49067:25577,49068:26999,49069:20975,49070:24936,49071:21002,49072:22570,49073:21208,49074:22350,49075:30733,49076:30475,49077:24247,49078:24951,49079:31968,49080:25179,49081:25239,49082:20130,49083:28821,49084:32771,49085:25335,49086:28900,49087:38752,49088:22391,49089:33499,49090:26607,49091:26869,49092:30933,49093:39063,49094:31185,49095:22771,49096:21683,49097:21487,49098:28212,49099:20811,49100:21051,49101:23458,49102:35838,49103:32943,49104:21827,49105:22438,49106:24691,49107:22353,49108:21549,49109:31354,49110:24656,49111:23380,49112:25511,49113:25248,49114:21475,49115:25187,49116:23495,49117:26543,49118:21741,49119:31391,49120:33510,49121:37239,49122:24211,49123:35044,49124:22840,49125:22446,49126:25358,49127:36328,49128:33007,49129:22359,49130:31607,49131:20393,49132:24555,49133:23485,49134:27454,49135:21281,49136:31568,49137:29378,49138:26694,49139:30719,49140:30518,49141:26103,49142:20917,49143:20111,49144:30420,49145:23743,49146:31397,49147:33909,49148:22862,49149:39745,49150:20608,49216:32350,49217:32351,49218:32352,49219:32353,49220:32354,49221:32355,49222:32356,49223:32357,49224:32358,49225:32359,49226:32360,49227:32361,49228:32362,49229:32363,49230:32364,49231:32365,49232:32366,49233:32367,49234:32368,49235:32369,49236:32370,49237:32371,49238:32372,49239:32373,49240:32374,49241:32375,49242:32376,49243:32377,49244:32378,49245:32379,49246:32380,49247:32381,49248:32382,49249:32383,49250:32384,49251:32385,49252:32387,49253:32388,49254:32389,49255:32390,49256:32391,49257:32392,49258:32393,49259:32394,49260:32395,49261:32396,49262:32397,49263:32398,49264:32399,49265:32400,49266:32401,49267:32402,49268:32403,49269:32404,49270:32405,49271:32406,49272:32407,49273:32408,49274:32409,49275:32410,49276:32412,49277:32413,49278:32414,49280:32430,49281:32436,49282:32443,49283:32444,49284:32470,49285:32484,49286:32492,49287:32505,49288:32522,49289:32528,49290:32542,49291:32567,49292:32569,49293:32571,49294:32572,49295:32573,49296:32574,49297:32575,49298:32576,49299:32577,49300:32579,49301:32582,49302:32583,49303:32584,49304:32585,49305:32586,49306:32587,49307:32588,49308:32589,49309:32590,49310:32591,49311:32594,49312:32595,49313:39304,49314:24871,49315:28291,49316:22372,49317:26118,49318:25414,49319:22256,49320:25324,49321:25193,49322:24275,49323:38420,49324:22403,49325:25289,49326:21895,49327:34593,49328:33098,49329:36771,49330:21862,49331:33713,49332:26469,49333:36182,49334:34013,49335:23146,49336:26639,49337:25318,49338:31726,49339:38417,49340:20848,49341:28572,49342:35888,49343:25597,49344:35272,49345:25042,49346:32518,49347:28866,49348:28389,49349:29701,49350:27028,49351:29436,49352:24266,49353:37070,49354:26391,49355:28010,49356:25438,49357:21171,49358:29282,49359:32769,49360:20332,49361:23013,49362:37226,49363:28889,49364:28061,49365:21202,49366:20048,49367:38647,49368:38253,49369:34174,49370:30922,49371:32047,49372:20769,49373:22418,49374:25794,49375:32907,49376:31867,49377:27882,49378:26865,49379:26974,49380:20919,49381:21400,49382:26792,49383:29313,49384:40654,49385:31729,49386:29432,49387:31163,49388:28435,49389:29702,49390:26446,49391:37324,49392:40100,49393:31036,49394:33673,49395:33620,49396:21519,49397:26647,49398:20029,49399:21385,49400:21169,49401:30782,49402:21382,49403:21033,49404:20616,49405:20363,49406:20432,49472:32598,49473:32601,49474:32603,49475:32604,49476:32605,49477:32606,49478:32608,49479:32611,49480:32612,49481:32613,49482:32614,49483:32615,49484:32619,49485:32620,49486:32621,49487:32623,49488:32624,49489:32627,49490:32629,49491:32630,49492:32631,49493:32632,49494:32634,49495:32635,49496:32636,49497:32637,49498:32639,49499:32640,49500:32642,49501:32643,49502:32644,49503:32645,49504:32646,49505:32647,49506:32648,49507:32649,49508:32651,49509:32653,49510:32655,49511:32656,49512:32657,49513:32658,49514:32659,49515:32661,49516:32662,49517:32663,49518:32664,49519:32665,49520:32667,49521:32668,49522:32672,49523:32674,49524:32675,49525:32677,49526:32678,49527:32680,49528:32681,49529:32682,49530:32683,49531:32684,49532:32685,49533:32686,49534:32689,49536:32691,49537:32692,49538:32693,49539:32694,49540:32695,49541:32698,49542:32699,49543:32702,49544:32704,49545:32706,49546:32707,49547:32708,49548:32710,49549:32711,49550:32712,49551:32713,49552:32715,49553:32717,49554:32719,49555:32720,49556:32721,49557:32722,49558:32723,49559:32726,49560:32727,49561:32729,49562:32730,49563:32731,49564:32732,49565:32733,49566:32734,49567:32738,49568:32739,49569:30178,49570:31435,49571:31890,49572:27813,49573:38582,49574:21147,49575:29827,49576:21737,49577:20457,49578:32852,49579:33714,49580:36830,49581:38256,49582:24265,49583:24604,49584:28063,49585:24088,49586:25947,49587:33080,49588:38142,49589:24651,49590:28860,49591:32451,49592:31918,49593:20937,49594:26753,49595:31921,49596:33391,49597:20004,49598:36742,49599:37327,49600:26238,49601:20142,49602:35845,49603:25769,49604:32842,49605:20698,49606:30103,49607:29134,49608:23525,49609:36797,49610:28518,49611:20102,49612:25730,49613:38243,49614:24278,49615:26009,49616:21015,49617:35010,49618:28872,49619:21155,49620:29454,49621:29747,49622:26519,49623:30967,49624:38678,49625:20020,49626:37051,49627:40158,49628:28107,49629:20955,49630:36161,49631:21533,49632:25294,49633:29618,49634:33777,49635:38646,49636:40836,49637:38083,49638:20278,49639:32666,49640:20940,49641:28789,49642:38517,49643:23725,49644:39046,49645:21478,49646:20196,49647:28316,49648:29705,49649:27060,49650:30827,49651:39311,49652:30041,49653:21016,49654:30244,49655:27969,49656:26611,49657:20845,49658:40857,49659:32843,49660:21657,49661:31548,49662:31423,49728:32740,49729:32743,49730:32744,49731:32746,49732:32747,49733:32748,49734:32749,49735:32751,49736:32754,49737:32756,49738:32757,49739:32758,49740:32759,49741:32760,49742:32761,49743:32762,49744:32765,49745:32766,49746:32767,49747:32770,49748:32775,49749:32776,49750:32777,49751:32778,49752:32782,49753:32783,49754:32785,49755:32787,49756:32794,49757:32795,49758:32797,49759:32798,49760:32799,49761:32801,49762:32803,49763:32804,49764:32811,49765:32812,49766:32813,49767:32814,49768:32815,49769:32816,49770:32818,49771:32820,49772:32825,49773:32826,49774:32828,49775:32830,49776:32832,49777:32833,49778:32836,49779:32837,49780:32839,49781:32840,49782:32841,49783:32846,49784:32847,49785:32848,49786:32849,49787:32851,49788:32853,49789:32854,49790:32855,49792:32857,49793:32859,49794:32860,49795:32861,49796:32862,49797:32863,49798:32864,49799:32865,49800:32866,49801:32867,49802:32868,49803:32869,49804:32870,49805:32871,49806:32872,49807:32875,49808:32876,49809:32877,49810:32878,49811:32879,49812:32880,49813:32882,49814:32883,49815:32884,49816:32885,49817:32886,49818:32887,49819:32888,49820:32889,49821:32890,49822:32891,49823:32892,49824:32893,49825:38534,49826:22404,49827:25314,49828:38471,49829:27004,49830:23044,49831:25602,49832:31699,49833:28431,49834:38475,49835:33446,49836:21346,49837:39045,49838:24208,49839:28809,49840:25523,49841:21348,49842:34383,49843:40065,49844:40595,49845:30860,49846:38706,49847:36335,49848:36162,49849:40575,49850:28510,49851:31108,49852:24405,49853:38470,49854:25134,49855:39540,49856:21525,49857:38109,49858:20387,49859:26053,49860:23653,49861:23649,49862:32533,49863:34385,49864:27695,49865:24459,49866:29575,49867:28388,49868:32511,49869:23782,49870:25371,49871:23402,49872:28390,49873:21365,49874:20081,49875:25504,49876:30053,49877:25249,49878:36718,49879:20262,49880:20177,49881:27814,49882:32438,49883:35770,49884:33821,49885:34746,49886:32599,49887:36923,49888:38179,49889:31657,49890:39585,49891:35064,49892:33853,49893:27931,49894:39558,49895:32476,49896:22920,49897:40635,49898:29595,49899:30721,49900:34434,49901:39532,49902:39554,49903:22043,49904:21527,49905:22475,49906:20080,49907:40614,49908:21334,49909:36808,49910:33033,49911:30610,49912:39314,49913:34542,49914:28385,49915:34067,49916:26364,49917:24930,49918:28459,49984:32894,49985:32897,49986:32898,49987:32901,49988:32904,49989:32906,49990:32909,49991:32910,49992:32911,49993:32912,49994:32913,49995:32914,49996:32916,49997:32917,49998:32919,49999:32921,50000:32926,50001:32931,50002:32934,50003:32935,50004:32936,50005:32940,50006:32944,50007:32947,50008:32949,50009:32950,50010:32952,50011:32953,50012:32955,50013:32965,50014:32967,50015:32968,50016:32969,50017:32970,50018:32971,50019:32975,50020:32976,50021:32977,50022:32978,50023:32979,50024:32980,50025:32981,50026:32984,50027:32991,50028:32992,50029:32994,50030:32995,50031:32998,50032:33006,50033:33013,50034:33015,50035:33017,50036:33019,50037:33022,50038:33023,50039:33024,50040:33025,50041:33027,50042:33028,50043:33029,50044:33031,50045:33032,50046:33035,50048:33036,50049:33045,50050:33047,50051:33049,50052:33051,50053:33052,50054:33053,50055:33055,50056:33056,50057:33057,50058:33058,50059:33059,50060:33060,50061:33061,50062:33062,50063:33063,50064:33064,50065:33065,50066:33066,50067:33067,50068:33069,50069:33070,50070:33072,50071:33075,50072:33076,50073:33077,50074:33079,50075:33081,50076:33082,50077:33083,50078:33084,50079:33085,50080:33087,50081:35881,50082:33426,50083:33579,50084:30450,50085:27667,50086:24537,50087:33725,50088:29483,50089:33541,50090:38170,50091:27611,50092:30683,50093:38086,50094:21359,50095:33538,50096:20882,50097:24125,50098:35980,50099:36152,50100:20040,50101:29611,50102:26522,50103:26757,50104:37238,50105:38665,50106:29028,50107:27809,50108:30473,50109:23186,50110:38209,50111:27599,50112:32654,50113:26151,50114:23504,50115:22969,50116:23194,50117:38376,50118:38391,50119:20204,50120:33804,50121:33945,50122:27308,50123:30431,50124:38192,50125:29467,50126:26790,50127:23391,50128:30511,50129:37274,50130:38753,50131:31964,50132:36855,50133:35868,50134:24357,50135:31859,50136:31192,50137:35269,50138:27852,50139:34588,50140:23494,50141:24130,50142:26825,50143:30496,50144:32501,50145:20885,50146:20813,50147:21193,50148:23081,50149:32517,50150:38754,50151:33495,50152:25551,50153:30596,50154:34256,50155:31186,50156:28218,50157:24217,50158:22937,50159:34065,50160:28781,50161:27665,50162:25279,50163:30399,50164:25935,50165:24751,50166:38397,50167:26126,50168:34719,50169:40483,50170:38125,50171:21517,50172:21629,50173:35884,50174:25720,50240:33088,50241:33089,50242:33090,50243:33091,50244:33092,50245:33093,50246:33095,50247:33097,50248:33101,50249:33102,50250:33103,50251:33106,50252:33110,50253:33111,50254:33112,50255:33115,50256:33116,50257:33117,50258:33118,50259:33119,50260:33121,50261:33122,50262:33123,50263:33124,50264:33126,50265:33128,50266:33130,50267:33131,50268:33132,50269:33135,50270:33138,50271:33139,50272:33141,50273:33142,50274:33143,50275:33144,50276:33153,50277:33155,50278:33156,50279:33157,50280:33158,50281:33159,50282:33161,50283:33163,50284:33164,50285:33165,50286:33166,50287:33168,50288:33170,50289:33171,50290:33172,50291:33173,50292:33174,50293:33175,50294:33177,50295:33178,50296:33182,50297:33183,50298:33184,50299:33185,50300:33186,50301:33188,50302:33189,50304:33191,50305:33193,50306:33195,50307:33196,50308:33197,50309:33198,50310:33199,50311:33200,50312:33201,50313:33202,50314:33204,50315:33205,50316:33206,50317:33207,50318:33208,50319:33209,50320:33212,50321:33213,50322:33214,50323:33215,50324:33220,50325:33221,50326:33223,50327:33224,50328:33225,50329:33227,50330:33229,50331:33230,50332:33231,50333:33232,50334:33233,50335:33234,50336:33235,50337:25721,50338:34321,50339:27169,50340:33180,50341:30952,50342:25705,50343:39764,50344:25273,50345:26411,50346:33707,50347:22696,50348:40664,50349:27819,50350:28448,50351:23518,50352:38476,50353:35851,50354:29279,50355:26576,50356:25287,50357:29281,50358:20137,50359:22982,50360:27597,50361:22675,50362:26286,50363:24149,50364:21215,50365:24917,50366:26408,50367:30446,50368:30566,50369:29287,50370:31302,50371:25343,50372:21738,50373:21584,50374:38048,50375:37027,50376:23068,50377:32435,50378:27670,50379:20035,50380:22902,50381:32784,50382:22856,50383:21335,50384:30007,50385:38590,50386:22218,50387:25376,50388:33041,50389:24700,50390:38393,50391:28118,50392:21602,50393:39297,50394:20869,50395:23273,50396:33021,50397:22958,50398:38675,50399:20522,50400:27877,50401:23612,50402:25311,50403:20320,50404:21311,50405:33147,50406:36870,50407:28346,50408:34091,50409:25288,50410:24180,50411:30910,50412:25781,50413:25467,50414:24565,50415:23064,50416:37247,50417:40479,50418:23615,50419:25423,50420:32834,50421:23421,50422:21870,50423:38218,50424:38221,50425:28037,50426:24744,50427:26592,50428:29406,50429:20957,50430:23425,50496:33236,50497:33237,50498:33238,50499:33239,50500:33240,50501:33241,50502:33242,50503:33243,50504:33244,50505:33245,50506:33246,50507:33247,50508:33248,50509:33249,50510:33250,50511:33252,50512:33253,50513:33254,50514:33256,50515:33257,50516:33259,50517:33262,50518:33263,50519:33264,50520:33265,50521:33266,50522:33269,50523:33270,50524:33271,50525:33272,50526:33273,50527:33274,50528:33277,50529:33279,50530:33283,50531:33287,50532:33288,50533:33289,50534:33290,50535:33291,50536:33294,50537:33295,50538:33297,50539:33299,50540:33301,50541:33302,50542:33303,50543:33304,50544:33305,50545:33306,50546:33309,50547:33312,50548:33316,50549:33317,50550:33318,50551:33319,50552:33321,50553:33326,50554:33330,50555:33338,50556:33340,50557:33341,50558:33343,50560:33344,50561:33345,50562:33346,50563:33347,50564:33349,50565:33350,50566:33352,50567:33354,50568:33356,50569:33357,50570:33358,50571:33360,50572:33361,50573:33362,50574:33363,50575:33364,50576:33365,50577:33366,50578:33367,50579:33369,50580:33371,50581:33372,50582:33373,50583:33374,50584:33376,50585:33377,50586:33378,50587:33379,50588:33380,50589:33381,50590:33382,50591:33383,50592:33385,50593:25319,50594:27870,50595:29275,50596:25197,50597:38062,50598:32445,50599:33043,50600:27987,50601:20892,50602:24324,50603:22900,50604:21162,50605:24594,50606:22899,50607:26262,50608:34384,50609:30111,50610:25386,50611:25062,50612:31983,50613:35834,50614:21734,50615:27431,50616:40485,50617:27572,50618:34261,50619:21589,50620:20598,50621:27812,50622:21866,50623:36276,50624:29228,50625:24085,50626:24597,50627:29750,50628:25293,50629:25490,50630:29260,50631:24472,50632:28227,50633:27966,50634:25856,50635:28504,50636:30424,50637:30928,50638:30460,50639:30036,50640:21028,50641:21467,50642:20051,50643:24222,50644:26049,50645:32810,50646:32982,50647:25243,50648:21638,50649:21032,50650:28846,50651:34957,50652:36305,50653:27873,50654:21624,50655:32986,50656:22521,50657:35060,50658:36180,50659:38506,50660:37197,50661:20329,50662:27803,50663:21943,50664:30406,50665:30768,50666:25256,50667:28921,50668:28558,50669:24429,50670:34028,50671:26842,50672:30844,50673:31735,50674:33192,50675:26379,50676:40527,50677:25447,50678:30896,50679:22383,50680:30738,50681:38713,50682:25209,50683:25259,50684:21128,50685:29749,50686:27607,50752:33386,50753:33387,50754:33388,50755:33389,50756:33393,50757:33397,50758:33398,50759:33399,50760:33400,50761:33403,50762:33404,50763:33408,50764:33409,50765:33411,50766:33413,50767:33414,50768:33415,50769:33417,50770:33420,50771:33424,50772:33427,50773:33428,50774:33429,50775:33430,50776:33434,50777:33435,50778:33438,50779:33440,50780:33442,50781:33443,50782:33447,50783:33458,50784:33461,50785:33462,50786:33466,50787:33467,50788:33468,50789:33471,50790:33472,50791:33474,50792:33475,50793:33477,50794:33478,50795:33481,50796:33488,50797:33494,50798:33497,50799:33498,50800:33501,50801:33506,50802:33511,50803:33512,50804:33513,50805:33514,50806:33516,50807:33517,50808:33518,50809:33520,50810:33522,50811:33523,50812:33525,50813:33526,50814:33528,50816:33530,50817:33532,50818:33533,50819:33534,50820:33535,50821:33536,50822:33546,50823:33547,50824:33549,50825:33552,50826:33554,50827:33555,50828:33558,50829:33560,50830:33561,50831:33565,50832:33566,50833:33567,50834:33568,50835:33569,50836:33570,50837:33571,50838:33572,50839:33573,50840:33574,50841:33577,50842:33578,50843:33582,50844:33584,50845:33586,50846:33591,50847:33595,50848:33597,50849:21860,50850:33086,50851:30130,50852:30382,50853:21305,50854:30174,50855:20731,50856:23617,50857:35692,50858:31687,50859:20559,50860:29255,50861:39575,50862:39128,50863:28418,50864:29922,50865:31080,50866:25735,50867:30629,50868:25340,50869:39057,50870:36139,50871:21697,50872:32856,50873:20050,50874:22378,50875:33529,50876:33805,50877:24179,50878:20973,50879:29942,50880:35780,50881:23631,50882:22369,50883:27900,50884:39047,50885:23110,50886:30772,50887:39748,50888:36843,50889:31893,50890:21078,50891:25169,50892:38138,50893:20166,50894:33670,50895:33889,50896:33769,50897:33970,50898:22484,50899:26420,50900:22275,50901:26222,50902:28006,50903:35889,50904:26333,50905:28689,50906:26399,50907:27450,50908:26646,50909:25114,50910:22971,50911:19971,50912:20932,50913:28422,50914:26578,50915:27791,50916:20854,50917:26827,50918:22855,50919:27495,50920:30054,50921:23822,50922:33040,50923:40784,50924:26071,50925:31048,50926:31041,50927:39569,50928:36215,50929:23682,50930:20062,50931:20225,50932:21551,50933:22865,50934:30732,50935:22120,50936:27668,50937:36804,50938:24323,50939:27773,50940:27875,50941:35755,50942:25488,51008:33598,51009:33599,51010:33601,51011:33602,51012:33604,51013:33605,51014:33608,51015:33610,51016:33611,51017:33612,51018:33613,51019:33614,51020:33619,51021:33621,51022:33622,51023:33623,51024:33624,51025:33625,51026:33629,51027:33634,51028:33648,51029:33649,51030:33650,51031:33651,51032:33652,51033:33653,51034:33654,51035:33657,51036:33658,51037:33662,51038:33663,51039:33664,51040:33665,51041:33666,51042:33667,51043:33668,51044:33671,51045:33672,51046:33674,51047:33675,51048:33676,51049:33677,51050:33679,51051:33680,51052:33681,51053:33684,51054:33685,51055:33686,51056:33687,51057:33689,51058:33690,51059:33693,51060:33695,51061:33697,51062:33698,51063:33699,51064:33700,51065:33701,51066:33702,51067:33703,51068:33708,51069:33709,51070:33710,51072:33711,51073:33717,51074:33723,51075:33726,51076:33727,51077:33730,51078:33731,51079:33732,51080:33734,51081:33736,51082:33737,51083:33739,51084:33741,51085:33742,51086:33744,51087:33745,51088:33746,51089:33747,51090:33749,51091:33751,51092:33753,51093:33754,51094:33755,51095:33758,51096:33762,51097:33763,51098:33764,51099:33766,51100:33767,51101:33768,51102:33771,51103:33772,51104:33773,51105:24688,51106:27965,51107:29301,51108:25190,51109:38030,51110:38085,51111:21315,51112:36801,51113:31614,51114:20191,51115:35878,51116:20094,51117:40660,51118:38065,51119:38067,51120:21069,51121:28508,51122:36963,51123:27973,51124:35892,51125:22545,51126:23884,51127:27424,51128:27465,51129:26538,51130:21595,51131:33108,51132:32652,51133:22681,51134:34103,51135:24378,51136:25250,51137:27207,51138:38201,51139:25970,51140:24708,51141:26725,51142:30631,51143:20052,51144:20392,51145:24039,51146:38808,51147:25772,51148:32728,51149:23789,51150:20431,51151:31373,51152:20999,51153:33540,51154:19988,51155:24623,51156:31363,51157:38054,51158:20405,51159:20146,51160:31206,51161:29748,51162:21220,51163:33465,51164:25810,51165:31165,51166:23517,51167:27777,51168:38738,51169:36731,51170:27682,51171:20542,51172:21375,51173:28165,51174:25806,51175:26228,51176:27696,51177:24773,51178:39031,51179:35831,51180:24198,51181:29756,51182:31351,51183:31179,51184:19992,51185:37041,51186:29699,51187:27714,51188:22234,51189:37195,51190:27845,51191:36235,51192:21306,51193:34502,51194:26354,51195:36527,51196:23624,51197:39537,51198:28192,51264:33774,51265:33775,51266:33779,51267:33780,51268:33781,51269:33782,51270:33783,51271:33786,51272:33787,51273:33788,51274:33790,51275:33791,51276:33792,51277:33794,51278:33797,51279:33799,51280:33800,51281:33801,51282:33802,51283:33808,51284:33810,51285:33811,51286:33812,51287:33813,51288:33814,51289:33815,51290:33817,51291:33818,51292:33819,51293:33822,51294:33823,51295:33824,51296:33825,51297:33826,51298:33827,51299:33833,51300:33834,51301:33835,51302:33836,51303:33837,51304:33838,51305:33839,51306:33840,51307:33842,51308:33843,51309:33844,51310:33845,51311:33846,51312:33847,51313:33849,51314:33850,51315:33851,51316:33854,51317:33855,51318:33856,51319:33857,51320:33858,51321:33859,51322:33860,51323:33861,51324:33863,51325:33864,51326:33865,51328:33866,51329:33867,51330:33868,51331:33869,51332:33870,51333:33871,51334:33872,51335:33874,51336:33875,51337:33876,51338:33877,51339:33878,51340:33880,51341:33885,51342:33886,51343:33887,51344:33888,51345:33890,51346:33892,51347:33893,51348:33894,51349:33895,51350:33896,51351:33898,51352:33902,51353:33903,51354:33904,51355:33906,51356:33908,51357:33911,51358:33913,51359:33915,51360:33916,51361:21462,51362:23094,51363:40843,51364:36259,51365:21435,51366:22280,51367:39079,51368:26435,51369:37275,51370:27849,51371:20840,51372:30154,51373:25331,51374:29356,51375:21048,51376:21149,51377:32570,51378:28820,51379:30264,51380:21364,51381:40522,51382:27063,51383:30830,51384:38592,51385:35033,51386:32676,51387:28982,51388:29123,51389:20873,51390:26579,51391:29924,51392:22756,51393:25880,51394:22199,51395:35753,51396:39286,51397:25200,51398:32469,51399:24825,51400:28909,51401:22764,51402:20161,51403:20154,51404:24525,51405:38887,51406:20219,51407:35748,51408:20995,51409:22922,51410:32427,51411:25172,51412:20173,51413:26085,51414:25102,51415:33592,51416:33993,51417:33635,51418:34701,51419:29076,51420:28342,51421:23481,51422:32466,51423:20887,51424:25545,51425:26580,51426:32905,51427:33593,51428:34837,51429:20754,51430:23418,51431:22914,51432:36785,51433:20083,51434:27741,51435:20837,51436:35109,51437:36719,51438:38446,51439:34122,51440:29790,51441:38160,51442:38384,51443:28070,51444:33509,51445:24369,51446:25746,51447:27922,51448:33832,51449:33134,51450:40131,51451:22622,51452:36187,51453:19977,51454:21441,51520:33917,51521:33918,51522:33919,51523:33920,51524:33921,51525:33923,51526:33924,51527:33925,51528:33926,51529:33930,51530:33933,51531:33935,51532:33936,51533:33937,51534:33938,51535:33939,51536:33940,51537:33941,51538:33942,51539:33944,51540:33946,51541:33947,51542:33949,51543:33950,51544:33951,51545:33952,51546:33954,51547:33955,51548:33956,51549:33957,51550:33958,51551:33959,51552:33960,51553:33961,51554:33962,51555:33963,51556:33964,51557:33965,51558:33966,51559:33968,51560:33969,51561:33971,51562:33973,51563:33974,51564:33975,51565:33979,51566:33980,51567:33982,51568:33984,51569:33986,51570:33987,51571:33989,51572:33990,51573:33991,51574:33992,51575:33995,51576:33996,51577:33998,51578:33999,51579:34002,51580:34004,51581:34005,51582:34007,51584:34008,51585:34009,51586:34010,51587:34011,51588:34012,51589:34014,51590:34017,51591:34018,51592:34020,51593:34023,51594:34024,51595:34025,51596:34026,51597:34027,51598:34029,51599:34030,51600:34031,51601:34033,51602:34034,51603:34035,51604:34036,51605:34037,51606:34038,51607:34039,51608:34040,51609:34041,51610:34042,51611:34043,51612:34045,51613:34046,51614:34048,51615:34049,51616:34050,51617:20254,51618:25955,51619:26705,51620:21971,51621:20007,51622:25620,51623:39578,51624:25195,51625:23234,51626:29791,51627:33394,51628:28073,51629:26862,51630:20711,51631:33678,51632:30722,51633:26432,51634:21049,51635:27801,51636:32433,51637:20667,51638:21861,51639:29022,51640:31579,51641:26194,51642:29642,51643:33515,51644:26441,51645:23665,51646:21024,51647:29053,51648:34923,51649:38378,51650:38485,51651:25797,51652:36193,51653:33203,51654:21892,51655:27733,51656:25159,51657:32558,51658:22674,51659:20260,51660:21830,51661:36175,51662:26188,51663:19978,51664:23578,51665:35059,51666:26786,51667:25422,51668:31245,51669:28903,51670:33421,51671:21242,51672:38902,51673:23569,51674:21736,51675:37045,51676:32461,51677:22882,51678:36170,51679:34503,51680:33292,51681:33293,51682:36198,51683:25668,51684:23556,51685:24913,51686:28041,51687:31038,51688:35774,51689:30775,51690:30003,51691:21627,51692:20280,51693:36523,51694:28145,51695:23072,51696:32453,51697:31070,51698:27784,51699:23457,51700:23158,51701:29978,51702:32958,51703:24910,51704:28183,51705:22768,51706:29983,51707:29989,51708:29298,51709:21319,51710:32499,51776:34051,51777:34052,51778:34053,51779:34054,51780:34055,51781:34056,51782:34057,51783:34058,51784:34059,51785:34061,51786:34062,51787:34063,51788:34064,51789:34066,51790:34068,51791:34069,51792:34070,51793:34072,51794:34073,51795:34075,51796:34076,51797:34077,51798:34078,51799:34080,51800:34082,51801:34083,51802:34084,51803:34085,51804:34086,51805:34087,51806:34088,51807:34089,51808:34090,51809:34093,51810:34094,51811:34095,51812:34096,51813:34097,51814:34098,51815:34099,51816:34100,51817:34101,51818:34102,51819:34110,51820:34111,51821:34112,51822:34113,51823:34114,51824:34116,51825:34117,51826:34118,51827:34119,51828:34123,51829:34124,51830:34125,51831:34126,51832:34127,51833:34128,51834:34129,51835:34130,51836:34131,51837:34132,51838:34133,51840:34135,51841:34136,51842:34138,51843:34139,51844:34140,51845:34141,51846:34143,51847:34144,51848:34145,51849:34146,51850:34147,51851:34149,51852:34150,51853:34151,51854:34153,51855:34154,51856:34155,51857:34156,51858:34157,51859:34158,51860:34159,51861:34160,51862:34161,51863:34163,51864:34165,51865:34166,51866:34167,51867:34168,51868:34172,51869:34173,51870:34175,51871:34176,51872:34177,51873:30465,51874:30427,51875:21097,51876:32988,51877:22307,51878:24072,51879:22833,51880:29422,51881:26045,51882:28287,51883:35799,51884:23608,51885:34417,51886:21313,51887:30707,51888:25342,51889:26102,51890:20160,51891:39135,51892:34432,51893:23454,51894:35782,51895:21490,51896:30690,51897:20351,51898:23630,51899:39542,51900:22987,51901:24335,51902:31034,51903:22763,51904:19990,51905:26623,51906:20107,51907:25325,51908:35475,51909:36893,51910:21183,51911:26159,51912:21980,51913:22124,51914:36866,51915:20181,51916:20365,51917:37322,51918:39280,51919:27663,51920:24066,51921:24643,51922:23460,51923:35270,51924:35797,51925:25910,51926:25163,51927:39318,51928:23432,51929:23551,51930:25480,51931:21806,51932:21463,51933:30246,51934:20861,51935:34092,51936:26530,51937:26803,51938:27530,51939:25234,51940:36755,51941:21460,51942:33298,51943:28113,51944:30095,51945:20070,51946:36174,51947:23408,51948:29087,51949:34223,51950:26257,51951:26329,51952:32626,51953:34560,51954:40653,51955:40736,51956:23646,51957:26415,51958:36848,51959:26641,51960:26463,51961:25101,51962:31446,51963:22661,51964:24246,51965:25968,51966:28465,52032:34178,52033:34179,52034:34182,52035:34184,52036:34185,52037:34186,52038:34187,52039:34188,52040:34189,52041:34190,52042:34192,52043:34193,52044:34194,52045:34195,52046:34196,52047:34197,52048:34198,52049:34199,52050:34200,52051:34201,52052:34202,52053:34205,52054:34206,52055:34207,52056:34208,52057:34209,52058:34210,52059:34211,52060:34213,52061:34214,52062:34215,52063:34217,52064:34219,52065:34220,52066:34221,52067:34225,52068:34226,52069:34227,52070:34228,52071:34229,52072:34230,52073:34232,52074:34234,52075:34235,52076:34236,52077:34237,52078:34238,52079:34239,52080:34240,52081:34242,52082:34243,52083:34244,52084:34245,52085:34246,52086:34247,52087:34248,52088:34250,52089:34251,52090:34252,52091:34253,52092:34254,52093:34257,52094:34258,52096:34260,52097:34262,52098:34263,52099:34264,52100:34265,52101:34266,52102:34267,52103:34269,52104:34270,52105:34271,52106:34272,52107:34273,52108:34274,52109:34275,52110:34277,52111:34278,52112:34279,52113:34280,52114:34282,52115:34283,52116:34284,52117:34285,52118:34286,52119:34287,52120:34288,52121:34289,52122:34290,52123:34291,52124:34292,52125:34293,52126:34294,52127:34295,52128:34296,52129:24661,52130:21047,52131:32781,52132:25684,52133:34928,52134:29993,52135:24069,52136:26643,52137:25332,52138:38684,52139:21452,52140:29245,52141:35841,52142:27700,52143:30561,52144:31246,52145:21550,52146:30636,52147:39034,52148:33308,52149:35828,52150:30805,52151:26388,52152:28865,52153:26031,52154:25749,52155:22070,52156:24605,52157:31169,52158:21496,52159:19997,52160:27515,52161:32902,52162:23546,52163:21987,52164:22235,52165:20282,52166:20284,52167:39282,52168:24051,52169:26494,52170:32824,52171:24578,52172:39042,52173:36865,52174:23435,52175:35772,52176:35829,52177:25628,52178:33368,52179:25822,52180:22013,52181:33487,52182:37221,52183:20439,52184:32032,52185:36895,52186:31903,52187:20723,52188:22609,52189:28335,52190:23487,52191:35785,52192:32899,52193:37240,52194:33948,52195:31639,52196:34429,52197:38539,52198:38543,52199:32485,52200:39635,52201:30862,52202:23681,52203:31319,52204:36930,52205:38567,52206:31071,52207:23385,52208:25439,52209:31499,52210:34001,52211:26797,52212:21766,52213:32553,52214:29712,52215:32034,52216:38145,52217:25152,52218:22604,52219:20182,52220:23427,52221:22905,52222:22612,52288:34297,52289:34298,52290:34300,52291:34301,52292:34302,52293:34304,52294:34305,52295:34306,52296:34307,52297:34308,52298:34310,52299:34311,52300:34312,52301:34313,52302:34314,52303:34315,52304:34316,52305:34317,52306:34318,52307:34319,52308:34320,52309:34322,52310:34323,52311:34324,52312:34325,52313:34327,52314:34328,52315:34329,52316:34330,52317:34331,52318:34332,52319:34333,52320:34334,52321:34335,52322:34336,52323:34337,52324:34338,52325:34339,52326:34340,52327:34341,52328:34342,52329:34344,52330:34346,52331:34347,52332:34348,52333:34349,52334:34350,52335:34351,52336:34352,52337:34353,52338:34354,52339:34355,52340:34356,52341:34357,52342:34358,52343:34359,52344:34361,52345:34362,52346:34363,52347:34365,52348:34366,52349:34367,52350:34368,52352:34369,52353:34370,52354:34371,52355:34372,52356:34373,52357:34374,52358:34375,52359:34376,52360:34377,52361:34378,52362:34379,52363:34380,52364:34386,52365:34387,52366:34389,52367:34390,52368:34391,52369:34392,52370:34393,52371:34395,52372:34396,52373:34397,52374:34399,52375:34400,52376:34401,52377:34403,52378:34404,52379:34405,52380:34406,52381:34407,52382:34408,52383:34409,52384:34410,52385:29549,52386:25374,52387:36427,52388:36367,52389:32974,52390:33492,52391:25260,52392:21488,52393:27888,52394:37214,52395:22826,52396:24577,52397:27760,52398:22349,52399:25674,52400:36138,52401:30251,52402:28393,52403:22363,52404:27264,52405:30192,52406:28525,52407:35885,52408:35848,52409:22374,52410:27631,52411:34962,52412:30899,52413:25506,52414:21497,52415:28845,52416:27748,52417:22616,52418:25642,52419:22530,52420:26848,52421:33179,52422:21776,52423:31958,52424:20504,52425:36538,52426:28108,52427:36255,52428:28907,52429:25487,52430:28059,52431:28372,52432:32486,52433:33796,52434:26691,52435:36867,52436:28120,52437:38518,52438:35752,52439:22871,52440:29305,52441:34276,52442:33150,52443:30140,52444:35466,52445:26799,52446:21076,52447:36386,52448:38161,52449:25552,52450:39064,52451:36420,52452:21884,52453:20307,52454:26367,52455:22159,52456:24789,52457:28053,52458:21059,52459:23625,52460:22825,52461:28155,52462:22635,52463:30000,52464:29980,52465:24684,52466:33300,52467:33094,52468:25361,52469:26465,52470:36834,52471:30522,52472:36339,52473:36148,52474:38081,52475:24086,52476:21381,52477:21548,52478:28867,52544:34413,52545:34415,52546:34416,52547:34418,52548:34419,52549:34420,52550:34421,52551:34422,52552:34423,52553:34424,52554:34435,52555:34436,52556:34437,52557:34438,52558:34439,52559:34440,52560:34441,52561:34446,52562:34447,52563:34448,52564:34449,52565:34450,52566:34452,52567:34454,52568:34455,52569:34456,52570:34457,52571:34458,52572:34459,52573:34462,52574:34463,52575:34464,52576:34465,52577:34466,52578:34469,52579:34470,52580:34475,52581:34477,52582:34478,52583:34482,52584:34483,52585:34487,52586:34488,52587:34489,52588:34491,52589:34492,52590:34493,52591:34494,52592:34495,52593:34497,52594:34498,52595:34499,52596:34501,52597:34504,52598:34508,52599:34509,52600:34514,52601:34515,52602:34517,52603:34518,52604:34519,52605:34522,52606:34524,52608:34525,52609:34528,52610:34529,52611:34530,52612:34531,52613:34533,52614:34534,52615:34535,52616:34536,52617:34538,52618:34539,52619:34540,52620:34543,52621:34549,52622:34550,52623:34551,52624:34554,52625:34555,52626:34556,52627:34557,52628:34559,52629:34561,52630:34564,52631:34565,52632:34566,52633:34571,52634:34572,52635:34574,52636:34575,52637:34576,52638:34577,52639:34580,52640:34582,52641:27712,52642:24311,52643:20572,52644:20141,52645:24237,52646:25402,52647:33351,52648:36890,52649:26704,52650:37230,52651:30643,52652:21516,52653:38108,52654:24420,52655:31461,52656:26742,52657:25413,52658:31570,52659:32479,52660:30171,52661:20599,52662:25237,52663:22836,52664:36879,52665:20984,52666:31171,52667:31361,52668:22270,52669:24466,52670:36884,52671:28034,52672:23648,52673:22303,52674:21520,52675:20820,52676:28237,52677:22242,52678:25512,52679:39059,52680:33151,52681:34581,52682:35114,52683:36864,52684:21534,52685:23663,52686:33216,52687:25302,52688:25176,52689:33073,52690:40501,52691:38464,52692:39534,52693:39548,52694:26925,52695:22949,52696:25299,52697:21822,52698:25366,52699:21703,52700:34521,52701:27964,52702:23043,52703:29926,52704:34972,52705:27498,52706:22806,52707:35916,52708:24367,52709:28286,52710:29609,52711:39037,52712:20024,52713:28919,52714:23436,52715:30871,52716:25405,52717:26202,52718:30358,52719:24779,52720:23451,52721:23113,52722:19975,52723:33109,52724:27754,52725:29579,52726:20129,52727:26505,52728:32593,52729:24448,52730:26106,52731:26395,52732:24536,52733:22916,52734:23041,52800:34585,52801:34587,52802:34589,52803:34591,52804:34592,52805:34596,52806:34598,52807:34599,52808:34600,52809:34602,52810:34603,52811:34604,52812:34605,52813:34607,52814:34608,52815:34610,52816:34611,52817:34613,52818:34614,52819:34616,52820:34617,52821:34618,52822:34620,52823:34621,52824:34624,52825:34625,52826:34626,52827:34627,52828:34628,52829:34629,52830:34630,52831:34634,52832:34635,52833:34637,52834:34639,52835:34640,52836:34641,52837:34642,52838:34644,52839:34645,52840:34646,52841:34648,52842:34650,52843:34651,52844:34652,52845:34653,52846:34654,52847:34655,52848:34657,52849:34658,52850:34662,52851:34663,52852:34664,52853:34665,52854:34666,52855:34667,52856:34668,52857:34669,52858:34671,52859:34673,52860:34674,52861:34675,52862:34677,52864:34679,52865:34680,52866:34681,52867:34682,52868:34687,52869:34688,52870:34689,52871:34692,52872:34694,52873:34695,52874:34697,52875:34698,52876:34700,52877:34702,52878:34703,52879:34704,52880:34705,52881:34706,52882:34708,52883:34709,52884:34710,52885:34712,52886:34713,52887:34714,52888:34715,52889:34716,52890:34717,52891:34718,52892:34720,52893:34721,52894:34722,52895:34723,52896:34724,52897:24013,52898:24494,52899:21361,52900:38886,52901:36829,52902:26693,52903:22260,52904:21807,52905:24799,52906:20026,52907:28493,52908:32500,52909:33479,52910:33806,52911:22996,52912:20255,52913:20266,52914:23614,52915:32428,52916:26410,52917:34074,52918:21619,52919:30031,52920:32963,52921:21890,52922:39759,52923:20301,52924:28205,52925:35859,52926:23561,52927:24944,52928:21355,52929:30239,52930:28201,52931:34442,52932:25991,52933:38395,52934:32441,52935:21563,52936:31283,52937:32010,52938:38382,52939:21985,52940:32705,52941:29934,52942:25373,52943:34583,52944:28065,52945:31389,52946:25105,52947:26017,52948:21351,52949:25569,52950:27779,52951:24043,52952:21596,52953:38056,52954:20044,52955:27745,52956:35820,52957:23627,52958:26080,52959:33436,52960:26791,52961:21566,52962:21556,52963:27595,52964:27494,52965:20116,52966:25410,52967:21320,52968:33310,52969:20237,52970:20398,52971:22366,52972:25098,52973:38654,52974:26212,52975:29289,52976:21247,52977:21153,52978:24735,52979:35823,52980:26132,52981:29081,52982:26512,52983:35199,52984:30802,52985:30717,52986:26224,52987:22075,52988:21560,52989:38177,52990:29306,53056:34725,53057:34726,53058:34727,53059:34729,53060:34730,53061:34734,53062:34736,53063:34737,53064:34738,53065:34740,53066:34742,53067:34743,53068:34744,53069:34745,53070:34747,53071:34748,53072:34750,53073:34751,53074:34753,53075:34754,53076:34755,53077:34756,53078:34757,53079:34759,53080:34760,53081:34761,53082:34764,53083:34765,53084:34766,53085:34767,53086:34768,53087:34772,53088:34773,53089:34774,53090:34775,53091:34776,53092:34777,53093:34778,53094:34780,53095:34781,53096:34782,53097:34783,53098:34785,53099:34786,53100:34787,53101:34788,53102:34790,53103:34791,53104:34792,53105:34793,53106:34795,53107:34796,53108:34797,53109:34799,53110:34800,53111:34801,53112:34802,53113:34803,53114:34804,53115:34805,53116:34806,53117:34807,53118:34808,53120:34810,53121:34811,53122:34812,53123:34813,53124:34815,53125:34816,53126:34817,53127:34818,53128:34820,53129:34821,53130:34822,53131:34823,53132:34824,53133:34825,53134:34827,53135:34828,53136:34829,53137:34830,53138:34831,53139:34832,53140:34833,53141:34834,53142:34836,53143:34839,53144:34840,53145:34841,53146:34842,53147:34844,53148:34845,53149:34846,53150:34847,53151:34848,53152:34851,53153:31232,53154:24687,53155:24076,53156:24713,53157:33181,53158:22805,53159:24796,53160:29060,53161:28911,53162:28330,53163:27728,53164:29312,53165:27268,53166:34989,53167:24109,53168:20064,53169:23219,53170:21916,53171:38115,53172:27927,53173:31995,53174:38553,53175:25103,53176:32454,53177:30606,53178:34430,53179:21283,53180:38686,53181:36758,53182:26247,53183:23777,53184:20384,53185:29421,53186:19979,53187:21414,53188:22799,53189:21523,53190:25472,53191:38184,53192:20808,53193:20185,53194:40092,53195:32420,53196:21688,53197:36132,53198:34900,53199:33335,53200:38386,53201:28046,53202:24358,53203:23244,53204:26174,53205:38505,53206:29616,53207:29486,53208:21439,53209:33146,53210:39301,53211:32673,53212:23466,53213:38519,53214:38480,53215:32447,53216:30456,53217:21410,53218:38262,53219:39321,53220:31665,53221:35140,53222:28248,53223:20065,53224:32724,53225:31077,53226:35814,53227:24819,53228:21709,53229:20139,53230:39033,53231:24055,53232:27233,53233:20687,53234:21521,53235:35937,53236:33831,53237:30813,53238:38660,53239:21066,53240:21742,53241:22179,53242:38144,53243:28040,53244:23477,53245:28102,53246:26195,53312:34852,53313:34853,53314:34854,53315:34855,53316:34856,53317:34857,53318:34858,53319:34859,53320:34860,53321:34861,53322:34862,53323:34863,53324:34864,53325:34865,53326:34867,53327:34868,53328:34869,53329:34870,53330:34871,53331:34872,53332:34874,53333:34875,53334:34877,53335:34878,53336:34879,53337:34881,53338:34882,53339:34883,53340:34886,53341:34887,53342:34888,53343:34889,53344:34890,53345:34891,53346:34894,53347:34895,53348:34896,53349:34897,53350:34898,53351:34899,53352:34901,53353:34902,53354:34904,53355:34906,53356:34907,53357:34908,53358:34909,53359:34910,53360:34911,53361:34912,53362:34918,53363:34919,53364:34922,53365:34925,53366:34927,53367:34929,53368:34931,53369:34932,53370:34933,53371:34934,53372:34936,53373:34937,53374:34938,53376:34939,53377:34940,53378:34944,53379:34947,53380:34950,53381:34951,53382:34953,53383:34954,53384:34956,53385:34958,53386:34959,53387:34960,53388:34961,53389:34963,53390:34964,53391:34965,53392:34967,53393:34968,53394:34969,53395:34970,53396:34971,53397:34973,53398:34974,53399:34975,53400:34976,53401:34977,53402:34979,53403:34981,53404:34982,53405:34983,53406:34984,53407:34985,53408:34986,53409:23567,53410:23389,53411:26657,53412:32918,53413:21880,53414:31505,53415:25928,53416:26964,53417:20123,53418:27463,53419:34638,53420:38795,53421:21327,53422:25375,53423:25658,53424:37034,53425:26012,53426:32961,53427:35856,53428:20889,53429:26800,53430:21368,53431:34809,53432:25032,53433:27844,53434:27899,53435:35874,53436:23633,53437:34218,53438:33455,53439:38156,53440:27427,53441:36763,53442:26032,53443:24571,53444:24515,53445:20449,53446:34885,53447:26143,53448:33125,53449:29481,53450:24826,53451:20852,53452:21009,53453:22411,53454:24418,53455:37026,53456:34892,53457:37266,53458:24184,53459:26447,53460:24615,53461:22995,53462:20804,53463:20982,53464:33016,53465:21256,53466:27769,53467:38596,53468:29066,53469:20241,53470:20462,53471:32670,53472:26429,53473:21957,53474:38152,53475:31168,53476:34966,53477:32483,53478:22687,53479:25100,53480:38656,53481:34394,53482:22040,53483:39035,53484:24464,53485:35768,53486:33988,53487:37207,53488:21465,53489:26093,53490:24207,53491:30044,53492:24676,53493:32110,53494:23167,53495:32490,53496:32493,53497:36713,53498:21927,53499:23459,53500:24748,53501:26059,53502:29572,53568:34988,53569:34990,53570:34991,53571:34992,53572:34994,53573:34995,53574:34996,53575:34997,53576:34998,53577:35000,53578:35001,53579:35002,53580:35003,53581:35005,53582:35006,53583:35007,53584:35008,53585:35011,53586:35012,53587:35015,53588:35016,53589:35018,53590:35019,53591:35020,53592:35021,53593:35023,53594:35024,53595:35025,53596:35027,53597:35030,53598:35031,53599:35034,53600:35035,53601:35036,53602:35037,53603:35038,53604:35040,53605:35041,53606:35046,53607:35047,53608:35049,53609:35050,53610:35051,53611:35052,53612:35053,53613:35054,53614:35055,53615:35058,53616:35061,53617:35062,53618:35063,53619:35066,53620:35067,53621:35069,53622:35071,53623:35072,53624:35073,53625:35075,53626:35076,53627:35077,53628:35078,53629:35079,53630:35080,53632:35081,53633:35083,53634:35084,53635:35085,53636:35086,53637:35087,53638:35089,53639:35092,53640:35093,53641:35094,53642:35095,53643:35096,53644:35100,53645:35101,53646:35102,53647:35103,53648:35104,53649:35106,53650:35107,53651:35108,53652:35110,53653:35111,53654:35112,53655:35113,53656:35116,53657:35117,53658:35118,53659:35119,53660:35121,53661:35122,53662:35123,53663:35125,53664:35127,53665:36873,53666:30307,53667:30505,53668:32474,53669:38772,53670:34203,53671:23398,53672:31348,53673:38634,53674:34880,53675:21195,53676:29071,53677:24490,53678:26092,53679:35810,53680:23547,53681:39535,53682:24033,53683:27529,53684:27739,53685:35757,53686:35759,53687:36874,53688:36805,53689:21387,53690:25276,53691:40486,53692:40493,53693:21568,53694:20011,53695:33469,53696:29273,53697:34460,53698:23830,53699:34905,53700:28079,53701:38597,53702:21713,53703:20122,53704:35766,53705:28937,53706:21693,53707:38409,53708:28895,53709:28153,53710:30416,53711:20005,53712:30740,53713:34578,53714:23721,53715:24310,53716:35328,53717:39068,53718:38414,53719:28814,53720:27839,53721:22852,53722:25513,53723:30524,53724:34893,53725:28436,53726:33395,53727:22576,53728:29141,53729:21388,53730:30746,53731:38593,53732:21761,53733:24422,53734:28976,53735:23476,53736:35866,53737:39564,53738:27523,53739:22830,53740:40495,53741:31207,53742:26472,53743:25196,53744:20335,53745:30113,53746:32650,53747:27915,53748:38451,53749:27687,53750:20208,53751:30162,53752:20859,53753:26679,53754:28478,53755:36992,53756:33136,53757:22934,53758:29814,53824:35128,53825:35129,53826:35130,53827:35131,53828:35132,53829:35133,53830:35134,53831:35135,53832:35136,53833:35138,53834:35139,53835:35141,53836:35142,53837:35143,53838:35144,53839:35145,53840:35146,53841:35147,53842:35148,53843:35149,53844:35150,53845:35151,53846:35152,53847:35153,53848:35154,53849:35155,53850:35156,53851:35157,53852:35158,53853:35159,53854:35160,53855:35161,53856:35162,53857:35163,53858:35164,53859:35165,53860:35168,53861:35169,53862:35170,53863:35171,53864:35172,53865:35173,53866:35175,53867:35176,53868:35177,53869:35178,53870:35179,53871:35180,53872:35181,53873:35182,53874:35183,53875:35184,53876:35185,53877:35186,53878:35187,53879:35188,53880:35189,53881:35190,53882:35191,53883:35192,53884:35193,53885:35194,53886:35196,53888:35197,53889:35198,53890:35200,53891:35202,53892:35204,53893:35205,53894:35207,53895:35208,53896:35209,53897:35210,53898:35211,53899:35212,53900:35213,53901:35214,53902:35215,53903:35216,53904:35217,53905:35218,53906:35219,53907:35220,53908:35221,53909:35222,53910:35223,53911:35224,53912:35225,53913:35226,53914:35227,53915:35228,53916:35229,53917:35230,53918:35231,53919:35232,53920:35233,53921:25671,53922:23591,53923:36965,53924:31377,53925:35875,53926:23002,53927:21676,53928:33280,53929:33647,53930:35201,53931:32768,53932:26928,53933:22094,53934:32822,53935:29239,53936:37326,53937:20918,53938:20063,53939:39029,53940:25494,53941:19994,53942:21494,53943:26355,53944:33099,53945:22812,53946:28082,53947:19968,53948:22777,53949:21307,53950:25558,53951:38129,53952:20381,53953:20234,53954:34915,53955:39056,53956:22839,53957:36951,53958:31227,53959:20202,53960:33008,53961:30097,53962:27778,53963:23452,53964:23016,53965:24413,53966:26885,53967:34433,53968:20506,53969:24050,53970:20057,53971:30691,53972:20197,53973:33402,53974:25233,53975:26131,53976:37009,53977:23673,53978:20159,53979:24441,53980:33222,53981:36920,53982:32900,53983:30123,53984:20134,53985:35028,53986:24847,53987:27589,53988:24518,53989:20041,53990:30410,53991:28322,53992:35811,53993:35758,53994:35850,53995:35793,53996:24322,53997:32764,53998:32716,53999:32462,54000:33589,54001:33643,54002:22240,54003:27575,54004:38899,54005:38452,54006:23035,54007:21535,54008:38134,54009:28139,54010:23493,54011:39278,54012:23609,54013:24341,54014:38544,54080:35234,54081:35235,54082:35236,54083:35237,54084:35238,54085:35239,54086:35240,54087:35241,54088:35242,54089:35243,54090:35244,54091:35245,54092:35246,54093:35247,54094:35248,54095:35249,54096:35250,54097:35251,54098:35252,54099:35253,54100:35254,54101:35255,54102:35256,54103:35257,54104:35258,54105:35259,54106:35260,54107:35261,54108:35262,54109:35263,54110:35264,54111:35267,54112:35277,54113:35283,54114:35284,54115:35285,54116:35287,54117:35288,54118:35289,54119:35291,54120:35293,54121:35295,54122:35296,54123:35297,54124:35298,54125:35300,54126:35303,54127:35304,54128:35305,54129:35306,54130:35308,54131:35309,54132:35310,54133:35312,54134:35313,54135:35314,54136:35316,54137:35317,54138:35318,54139:35319,54140:35320,54141:35321,54142:35322,54144:35323,54145:35324,54146:35325,54147:35326,54148:35327,54149:35329,54150:35330,54151:35331,54152:35332,54153:35333,54154:35334,54155:35336,54156:35337,54157:35338,54158:35339,54159:35340,54160:35341,54161:35342,54162:35343,54163:35344,54164:35345,54165:35346,54166:35347,54167:35348,54168:35349,54169:35350,54170:35351,54171:35352,54172:35353,54173:35354,54174:35355,54175:35356,54176:35357,54177:21360,54178:33521,54179:27185,54180:23156,54181:40560,54182:24212,54183:32552,54184:33721,54185:33828,54186:33829,54187:33639,54188:34631,54189:36814,54190:36194,54191:30408,54192:24433,54193:39062,54194:30828,54195:26144,54196:21727,54197:25317,54198:20323,54199:33219,54200:30152,54201:24248,54202:38605,54203:36362,54204:34553,54205:21647,54206:27891,54207:28044,54208:27704,54209:24703,54210:21191,54211:29992,54212:24189,54213:20248,54214:24736,54215:24551,54216:23588,54217:30001,54218:37038,54219:38080,54220:29369,54221:27833,54222:28216,54223:37193,54224:26377,54225:21451,54226:21491,54227:20305,54228:37321,54229:35825,54230:21448,54231:24188,54232:36802,54233:28132,54234:20110,54235:30402,54236:27014,54237:34398,54238:24858,54239:33286,54240:20313,54241:20446,54242:36926,54243:40060,54244:24841,54245:28189,54246:28180,54247:38533,54248:20104,54249:23089,54250:38632,54251:19982,54252:23679,54253:31161,54254:23431,54255:35821,54256:32701,54257:29577,54258:22495,54259:33419,54260:37057,54261:21505,54262:36935,54263:21947,54264:23786,54265:24481,54266:24840,54267:27442,54268:29425,54269:32946,54270:35465,54336:35358,54337:35359,54338:35360,54339:35361,54340:35362,54341:35363,54342:35364,54343:35365,54344:35366,54345:35367,54346:35368,54347:35369,54348:35370,54349:35371,54350:35372,54351:35373,54352:35374,54353:35375,54354:35376,54355:35377,54356:35378,54357:35379,54358:35380,54359:35381,54360:35382,54361:35383,54362:35384,54363:35385,54364:35386,54365:35387,54366:35388,54367:35389,54368:35391,54369:35392,54370:35393,54371:35394,54372:35395,54373:35396,54374:35397,54375:35398,54376:35399,54377:35401,54378:35402,54379:35403,54380:35404,54381:35405,54382:35406,54383:35407,54384:35408,54385:35409,54386:35410,54387:35411,54388:35412,54389:35413,54390:35414,54391:35415,54392:35416,54393:35417,54394:35418,54395:35419,54396:35420,54397:35421,54398:35422,54400:35423,54401:35424,54402:35425,54403:35426,54404:35427,54405:35428,54406:35429,54407:35430,54408:35431,54409:35432,54410:35433,54411:35434,54412:35435,54413:35436,54414:35437,54415:35438,54416:35439,54417:35440,54418:35441,54419:35442,54420:35443,54421:35444,54422:35445,54423:35446,54424:35447,54425:35448,54426:35450,54427:35451,54428:35452,54429:35453,54430:35454,54431:35455,54432:35456,54433:28020,54434:23507,54435:35029,54436:39044,54437:35947,54438:39533,54439:40499,54440:28170,54441:20900,54442:20803,54443:22435,54444:34945,54445:21407,54446:25588,54447:36757,54448:22253,54449:21592,54450:22278,54451:29503,54452:28304,54453:32536,54454:36828,54455:33489,54456:24895,54457:24616,54458:38498,54459:26352,54460:32422,54461:36234,54462:36291,54463:38053,54464:23731,54465:31908,54466:26376,54467:24742,54468:38405,54469:32792,54470:20113,54471:37095,54472:21248,54473:38504,54474:20801,54475:36816,54476:34164,54477:37213,54478:26197,54479:38901,54480:23381,54481:21277,54482:30776,54483:26434,54484:26685,54485:21705,54486:28798,54487:23472,54488:36733,54489:20877,54490:22312,54491:21681,54492:25874,54493:26242,54494:36190,54495:36163,54496:33039,54497:33900,54498:36973,54499:31967,54500:20991,54501:34299,54502:26531,54503:26089,54504:28577,54505:34468,54506:36481,54507:22122,54508:36896,54509:30338,54510:28790,54511:29157,54512:36131,54513:25321,54514:21017,54515:27901,54516:36156,54517:24590,54518:22686,54519:24974,54520:26366,54521:36192,54522:25166,54523:21939,54524:28195,54525:26413,54526:36711,54592:35457,54593:35458,54594:35459,54595:35460,54596:35461,54597:35462,54598:35463,54599:35464,54600:35467,54601:35468,54602:35469,54603:35470,54604:35471,54605:35472,54606:35473,54607:35474,54608:35476,54609:35477,54610:35478,54611:35479,54612:35480,54613:35481,54614:35482,54615:35483,54616:35484,54617:35485,54618:35486,54619:35487,54620:35488,54621:35489,54622:35490,54623:35491,54624:35492,54625:35493,54626:35494,54627:35495,54628:35496,54629:35497,54630:35498,54631:35499,54632:35500,54633:35501,54634:35502,54635:35503,54636:35504,54637:35505,54638:35506,54639:35507,54640:35508,54641:35509,54642:35510,54643:35511,54644:35512,54645:35513,54646:35514,54647:35515,54648:35516,54649:35517,54650:35518,54651:35519,54652:35520,54653:35521,54654:35522,54656:35523,54657:35524,54658:35525,54659:35526,54660:35527,54661:35528,54662:35529,54663:35530,54664:35531,54665:35532,54666:35533,54667:35534,54668:35535,54669:35536,54670:35537,54671:35538,54672:35539,54673:35540,54674:35541,54675:35542,54676:35543,54677:35544,54678:35545,54679:35546,54680:35547,54681:35548,54682:35549,54683:35550,54684:35551,54685:35552,54686:35553,54687:35554,54688:35555,54689:38113,54690:38392,54691:30504,54692:26629,54693:27048,54694:21643,54695:20045,54696:28856,54697:35784,54698:25688,54699:25995,54700:23429,54701:31364,54702:20538,54703:23528,54704:30651,54705:27617,54706:35449,54707:31896,54708:27838,54709:30415,54710:26025,54711:36759,54712:23853,54713:23637,54714:34360,54715:26632,54716:21344,54717:25112,54718:31449,54719:28251,54720:32509,54721:27167,54722:31456,54723:24432,54724:28467,54725:24352,54726:25484,54727:28072,54728:26454,54729:19976,54730:24080,54731:36134,54732:20183,54733:32960,54734:30260,54735:38556,54736:25307,54737:26157,54738:25214,54739:27836,54740:36213,54741:29031,54742:32617,54743:20806,54744:32903,54745:21484,54746:36974,54747:25240,54748:21746,54749:34544,54750:36761,54751:32773,54752:38167,54753:34071,54754:36825,54755:27993,54756:29645,54757:26015,54758:30495,54759:29956,54760:30759,54761:33275,54762:36126,54763:38024,54764:20390,54765:26517,54766:30137,54767:35786,54768:38663,54769:25391,54770:38215,54771:38453,54772:33976,54773:25379,54774:30529,54775:24449,54776:29424,54777:20105,54778:24596,54779:25972,54780:25327,54781:27491,54782:25919,54848:35556,54849:35557,54850:35558,54851:35559,54852:35560,54853:35561,54854:35562,54855:35563,54856:35564,54857:35565,54858:35566,54859:35567,54860:35568,54861:35569,54862:35570,54863:35571,54864:35572,54865:35573,54866:35574,54867:35575,54868:35576,54869:35577,54870:35578,54871:35579,54872:35580,54873:35581,54874:35582,54875:35583,54876:35584,54877:35585,54878:35586,54879:35587,54880:35588,54881:35589,54882:35590,54883:35592,54884:35593,54885:35594,54886:35595,54887:35596,54888:35597,54889:35598,54890:35599,54891:35600,54892:35601,54893:35602,54894:35603,54895:35604,54896:35605,54897:35606,54898:35607,54899:35608,54900:35609,54901:35610,54902:35611,54903:35612,54904:35613,54905:35614,54906:35615,54907:35616,54908:35617,54909:35618,54910:35619,54912:35620,54913:35621,54914:35623,54915:35624,54916:35625,54917:35626,54918:35627,54919:35628,54920:35629,54921:35630,54922:35631,54923:35632,54924:35633,54925:35634,54926:35635,54927:35636,54928:35637,54929:35638,54930:35639,54931:35640,54932:35641,54933:35642,54934:35643,54935:35644,54936:35645,54937:35646,54938:35647,54939:35648,54940:35649,54941:35650,54942:35651,54943:35652,54944:35653,54945:24103,54946:30151,54947:37073,54948:35777,54949:33437,54950:26525,54951:25903,54952:21553,54953:34584,54954:30693,54955:32930,54956:33026,54957:27713,54958:20043,54959:32455,54960:32844,54961:30452,54962:26893,54963:27542,54964:25191,54965:20540,54966:20356,54967:22336,54968:25351,54969:27490,54970:36286,54971:21482,54972:26088,54973:32440,54974:24535,54975:25370,54976:25527,54977:33267,54978:33268,54979:32622,54980:24092,54981:23769,54982:21046,54983:26234,54984:31209,54985:31258,54986:36136,54987:28825,54988:30164,54989:28382,54990:27835,54991:31378,54992:20013,54993:30405,54994:24544,54995:38047,54996:34935,54997:32456,54998:31181,54999:32959,55000:37325,55001:20210,55002:20247,55003:33311,55004:21608,55005:24030,55006:27954,55007:35788,55008:31909,55009:36724,55010:32920,55011:24090,55012:21650,55013:30385,55014:23449,55015:26172,55016:39588,55017:29664,55018:26666,55019:34523,55020:26417,55021:29482,55022:35832,55023:35803,55024:36880,55025:31481,55026:28891,55027:29038,55028:25284,55029:30633,55030:22065,55031:20027,55032:33879,55033:26609,55034:21161,55035:34496,55036:36142,55037:38136,55038:31569,55104:35654,55105:35655,55106:35656,55107:35657,55108:35658,55109:35659,55110:35660,55111:35661,55112:35662,55113:35663,55114:35664,55115:35665,55116:35666,55117:35667,55118:35668,55119:35669,55120:35670,55121:35671,55122:35672,55123:35673,55124:35674,55125:35675,55126:35676,55127:35677,55128:35678,55129:35679,55130:35680,55131:35681,55132:35682,55133:35683,55134:35684,55135:35685,55136:35687,55137:35688,55138:35689,55139:35690,55140:35691,55141:35693,55142:35694,55143:35695,55144:35696,55145:35697,55146:35698,55147:35699,55148:35700,55149:35701,55150:35702,55151:35703,55152:35704,55153:35705,55154:35706,55155:35707,55156:35708,55157:35709,55158:35710,55159:35711,55160:35712,55161:35713,55162:35714,55163:35715,55164:35716,55165:35717,55166:35718,55168:35719,55169:35720,55170:35721,55171:35722,55172:35723,55173:35724,55174:35725,55175:35726,55176:35727,55177:35728,55178:35729,55179:35730,55180:35731,55181:35732,55182:35733,55183:35734,55184:35735,55185:35736,55186:35737,55187:35738,55188:35739,55189:35740,55190:35741,55191:35742,55192:35743,55193:35756,55194:35761,55195:35771,55196:35783,55197:35792,55198:35818,55199:35849,55200:35870,55201:20303,55202:27880,55203:31069,55204:39547,55205:25235,55206:29226,55207:25341,55208:19987,55209:30742,55210:36716,55211:25776,55212:36186,55213:31686,55214:26729,55215:24196,55216:35013,55217:22918,55218:25758,55219:22766,55220:29366,55221:26894,55222:38181,55223:36861,55224:36184,55225:22368,55226:32512,55227:35846,55228:20934,55229:25417,55230:25305,55231:21331,55232:26700,55233:29730,55234:33537,55235:37196,55236:21828,55237:30528,55238:28796,55239:27978,55240:20857,55241:21672,55242:36164,55243:23039,55244:28363,55245:28100,55246:23388,55247:32043,55248:20180,55249:31869,55250:28371,55251:23376,55252:33258,55253:28173,55254:23383,55255:39683,55256:26837,55257:36394,55258:23447,55259:32508,55260:24635,55261:32437,55262:37049,55263:36208,55264:22863,55265:25549,55266:31199,55267:36275,55268:21330,55269:26063,55270:31062,55271:35781,55272:38459,55273:32452,55274:38075,55275:32386,55276:22068,55277:37257,55278:26368,55279:32618,55280:23562,55281:36981,55282:26152,55283:24038,55284:20304,55285:26590,55286:20570,55287:20316,55288:22352,55289:24231,55290:59408,55291:59409,55292:59410,55293:59411,55294:59412,55360:35896,55361:35897,55362:35898,55363:35899,55364:35900,55365:35901,55366:35902,55367:35903,55368:35904,55369:35906,55370:35907,55371:35908,55372:35909,55373:35912,55374:35914,55375:35915,55376:35917,55377:35918,55378:35919,55379:35920,55380:35921,55381:35922,55382:35923,55383:35924,55384:35926,55385:35927,55386:35928,55387:35929,55388:35931,55389:35932,55390:35933,55391:35934,55392:35935,55393:35936,55394:35939,55395:35940,55396:35941,55397:35942,55398:35943,55399:35944,55400:35945,55401:35948,55402:35949,55403:35950,55404:35951,55405:35952,55406:35953,55407:35954,55408:35956,55409:35957,55410:35958,55411:35959,55412:35963,55413:35964,55414:35965,55415:35966,55416:35967,55417:35968,55418:35969,55419:35971,55420:35972,55421:35974,55422:35975,55424:35976,55425:35979,55426:35981,55427:35982,55428:35983,55429:35984,55430:35985,55431:35986,55432:35987,55433:35989,55434:35990,55435:35991,55436:35993,55437:35994,55438:35995,55439:35996,55440:35997,55441:35998,55442:35999,55443:36000,55444:36001,55445:36002,55446:36003,55447:36004,55448:36005,55449:36006,55450:36007,55451:36008,55452:36009,55453:36010,55454:36011,55455:36012,55456:36013,55457:20109,55458:19980,55459:20800,55460:19984,55461:24319,55462:21317,55463:19989,55464:20120,55465:19998,55466:39730,55467:23404,55468:22121,55469:20008,55470:31162,55471:20031,55472:21269,55473:20039,55474:22829,55475:29243,55476:21358,55477:27664,55478:22239,55479:32996,55480:39319,55481:27603,55482:30590,55483:40727,55484:20022,55485:20127,55486:40720,55487:20060,55488:20073,55489:20115,55490:33416,55491:23387,55492:21868,55493:22031,55494:20164,55495:21389,55496:21405,55497:21411,55498:21413,55499:21422,55500:38757,55501:36189,55502:21274,55503:21493,55504:21286,55505:21294,55506:21310,55507:36188,55508:21350,55509:21347,55510:20994,55511:21000,55512:21006,55513:21037,55514:21043,55515:21055,55516:21056,55517:21068,55518:21086,55519:21089,55520:21084,55521:33967,55522:21117,55523:21122,55524:21121,55525:21136,55526:21139,55527:20866,55528:32596,55529:20155,55530:20163,55531:20169,55532:20162,55533:20200,55534:20193,55535:20203,55536:20190,55537:20251,55538:20211,55539:20258,55540:20324,55541:20213,55542:20261,55543:20263,55544:20233,55545:20267,55546:20318,55547:20327,55548:25912,55549:20314,55550:20317,55616:36014,55617:36015,55618:36016,55619:36017,55620:36018,55621:36019,55622:36020,55623:36021,55624:36022,55625:36023,55626:36024,55627:36025,55628:36026,55629:36027,55630:36028,55631:36029,55632:36030,55633:36031,55634:36032,55635:36033,55636:36034,55637:36035,55638:36036,55639:36037,55640:36038,55641:36039,55642:36040,55643:36041,55644:36042,55645:36043,55646:36044,55647:36045,55648:36046,55649:36047,55650:36048,55651:36049,55652:36050,55653:36051,55654:36052,55655:36053,55656:36054,55657:36055,55658:36056,55659:36057,55660:36058,55661:36059,55662:36060,55663:36061,55664:36062,55665:36063,55666:36064,55667:36065,55668:36066,55669:36067,55670:36068,55671:36069,55672:36070,55673:36071,55674:36072,55675:36073,55676:36074,55677:36075,55678:36076,55680:36077,55681:36078,55682:36079,55683:36080,55684:36081,55685:36082,55686:36083,55687:36084,55688:36085,55689:36086,55690:36087,55691:36088,55692:36089,55693:36090,55694:36091,55695:36092,55696:36093,55697:36094,55698:36095,55699:36096,55700:36097,55701:36098,55702:36099,55703:36100,55704:36101,55705:36102,55706:36103,55707:36104,55708:36105,55709:36106,55710:36107,55711:36108,55712:36109,55713:20319,55714:20311,55715:20274,55716:20285,55717:20342,55718:20340,55719:20369,55720:20361,55721:20355,55722:20367,55723:20350,55724:20347,55725:20394,55726:20348,55727:20396,55728:20372,55729:20454,55730:20456,55731:20458,55732:20421,55733:20442,55734:20451,55735:20444,55736:20433,55737:20447,55738:20472,55739:20521,55740:20556,55741:20467,55742:20524,55743:20495,55744:20526,55745:20525,55746:20478,55747:20508,55748:20492,55749:20517,55750:20520,55751:20606,55752:20547,55753:20565,55754:20552,55755:20558,55756:20588,55757:20603,55758:20645,55759:20647,55760:20649,55761:20666,55762:20694,55763:20742,55764:20717,55765:20716,55766:20710,55767:20718,55768:20743,55769:20747,55770:20189,55771:27709,55772:20312,55773:20325,55774:20430,55775:40864,55776:27718,55777:31860,55778:20846,55779:24061,55780:40649,55781:39320,55782:20865,55783:22804,55784:21241,55785:21261,55786:35335,55787:21264,55788:20971,55789:22809,55790:20821,55791:20128,55792:20822,55793:20147,55794:34926,55795:34980,55796:20149,55797:33044,55798:35026,55799:31104,55800:23348,55801:34819,55802:32696,55803:20907,55804:20913,55805:20925,55806:20924,55872:36110,55873:36111,55874:36112,55875:36113,55876:36114,55877:36115,55878:36116,55879:36117,55880:36118,55881:36119,55882:36120,55883:36121,55884:36122,55885:36123,55886:36124,55887:36128,55888:36177,55889:36178,55890:36183,55891:36191,55892:36197,55893:36200,55894:36201,55895:36202,55896:36204,55897:36206,55898:36207,55899:36209,55900:36210,55901:36216,55902:36217,55903:36218,55904:36219,55905:36220,55906:36221,55907:36222,55908:36223,55909:36224,55910:36226,55911:36227,55912:36230,55913:36231,55914:36232,55915:36233,55916:36236,55917:36237,55918:36238,55919:36239,55920:36240,55921:36242,55922:36243,55923:36245,55924:36246,55925:36247,55926:36248,55927:36249,55928:36250,55929:36251,55930:36252,55931:36253,55932:36254,55933:36256,55934:36257,55936:36258,55937:36260,55938:36261,55939:36262,55940:36263,55941:36264,55942:36265,55943:36266,55944:36267,55945:36268,55946:36269,55947:36270,55948:36271,55949:36272,55950:36274,55951:36278,55952:36279,55953:36281,55954:36283,55955:36285,55956:36288,55957:36289,55958:36290,55959:36293,55960:36295,55961:36296,55962:36297,55963:36298,55964:36301,55965:36304,55966:36306,55967:36307,55968:36308,55969:20935,55970:20886,55971:20898,55972:20901,55973:35744,55974:35750,55975:35751,55976:35754,55977:35764,55978:35765,55979:35767,55980:35778,55981:35779,55982:35787,55983:35791,55984:35790,55985:35794,55986:35795,55987:35796,55988:35798,55989:35800,55990:35801,55991:35804,55992:35807,55993:35808,55994:35812,55995:35816,55996:35817,55997:35822,55998:35824,55999:35827,56000:35830,56001:35833,56002:35836,56003:35839,56004:35840,56005:35842,56006:35844,56007:35847,56008:35852,56009:35855,56010:35857,56011:35858,56012:35860,56013:35861,56014:35862,56015:35865,56016:35867,56017:35864,56018:35869,56019:35871,56020:35872,56021:35873,56022:35877,56023:35879,56024:35882,56025:35883,56026:35886,56027:35887,56028:35890,56029:35891,56030:35893,56031:35894,56032:21353,56033:21370,56034:38429,56035:38434,56036:38433,56037:38449,56038:38442,56039:38461,56040:38460,56041:38466,56042:38473,56043:38484,56044:38495,56045:38503,56046:38508,56047:38514,56048:38516,56049:38536,56050:38541,56051:38551,56052:38576,56053:37015,56054:37019,56055:37021,56056:37017,56057:37036,56058:37025,56059:37044,56060:37043,56061:37046,56062:37050,56128:36309,56129:36312,56130:36313,56131:36316,56132:36320,56133:36321,56134:36322,56135:36325,56136:36326,56137:36327,56138:36329,56139:36333,56140:36334,56141:36336,56142:36337,56143:36338,56144:36340,56145:36342,56146:36348,56147:36350,56148:36351,56149:36352,56150:36353,56151:36354,56152:36355,56153:36356,56154:36358,56155:36359,56156:36360,56157:36363,56158:36365,56159:36366,56160:36368,56161:36369,56162:36370,56163:36371,56164:36373,56165:36374,56166:36375,56167:36376,56168:36377,56169:36378,56170:36379,56171:36380,56172:36384,56173:36385,56174:36388,56175:36389,56176:36390,56177:36391,56178:36392,56179:36395,56180:36397,56181:36400,56182:36402,56183:36403,56184:36404,56185:36406,56186:36407,56187:36408,56188:36411,56189:36412,56190:36414,56192:36415,56193:36419,56194:36421,56195:36422,56196:36428,56197:36429,56198:36430,56199:36431,56200:36432,56201:36435,56202:36436,56203:36437,56204:36438,56205:36439,56206:36440,56207:36442,56208:36443,56209:36444,56210:36445,56211:36446,56212:36447,56213:36448,56214:36449,56215:36450,56216:36451,56217:36452,56218:36453,56219:36455,56220:36456,56221:36458,56222:36459,56223:36462,56224:36465,56225:37048,56226:37040,56227:37071,56228:37061,56229:37054,56230:37072,56231:37060,56232:37063,56233:37075,56234:37094,56235:37090,56236:37084,56237:37079,56238:37083,56239:37099,56240:37103,56241:37118,56242:37124,56243:37154,56244:37150,56245:37155,56246:37169,56247:37167,56248:37177,56249:37187,56250:37190,56251:21005,56252:22850,56253:21154,56254:21164,56255:21165,56256:21182,56257:21759,56258:21200,56259:21206,56260:21232,56261:21471,56262:29166,56263:30669,56264:24308,56265:20981,56266:20988,56267:39727,56268:21430,56269:24321,56270:30042,56271:24047,56272:22348,56273:22441,56274:22433,56275:22654,56276:22716,56277:22725,56278:22737,56279:22313,56280:22316,56281:22314,56282:22323,56283:22329,56284:22318,56285:22319,56286:22364,56287:22331,56288:22338,56289:22377,56290:22405,56291:22379,56292:22406,56293:22396,56294:22395,56295:22376,56296:22381,56297:22390,56298:22387,56299:22445,56300:22436,56301:22412,56302:22450,56303:22479,56304:22439,56305:22452,56306:22419,56307:22432,56308:22485,56309:22488,56310:22490,56311:22489,56312:22482,56313:22456,56314:22516,56315:22511,56316:22520,56317:22500,56318:22493,56384:36467,56385:36469,56386:36471,56387:36472,56388:36473,56389:36474,56390:36475,56391:36477,56392:36478,56393:36480,56394:36482,56395:36483,56396:36484,56397:36486,56398:36488,56399:36489,56400:36490,56401:36491,56402:36492,56403:36493,56404:36494,56405:36497,56406:36498,56407:36499,56408:36501,56409:36502,56410:36503,56411:36504,56412:36505,56413:36506,56414:36507,56415:36509,56416:36511,56417:36512,56418:36513,56419:36514,56420:36515,56421:36516,56422:36517,56423:36518,56424:36519,56425:36520,56426:36521,56427:36522,56428:36525,56429:36526,56430:36528,56431:36529,56432:36531,56433:36532,56434:36533,56435:36534,56436:36535,56437:36536,56438:36537,56439:36539,56440:36540,56441:36541,56442:36542,56443:36543,56444:36544,56445:36545,56446:36546,56448:36547,56449:36548,56450:36549,56451:36550,56452:36551,56453:36552,56454:36553,56455:36554,56456:36555,56457:36556,56458:36557,56459:36559,56460:36560,56461:36561,56462:36562,56463:36563,56464:36564,56465:36565,56466:36566,56467:36567,56468:36568,56469:36569,56470:36570,56471:36571,56472:36572,56473:36573,56474:36574,56475:36575,56476:36576,56477:36577,56478:36578,56479:36579,56480:36580,56481:22539,56482:22541,56483:22525,56484:22509,56485:22528,56486:22558,56487:22553,56488:22596,56489:22560,56490:22629,56491:22636,56492:22657,56493:22665,56494:22682,56495:22656,56496:39336,56497:40729,56498:25087,56499:33401,56500:33405,56501:33407,56502:33423,56503:33418,56504:33448,56505:33412,56506:33422,56507:33425,56508:33431,56509:33433,56510:33451,56511:33464,56512:33470,56513:33456,56514:33480,56515:33482,56516:33507,56517:33432,56518:33463,56519:33454,56520:33483,56521:33484,56522:33473,56523:33449,56524:33460,56525:33441,56526:33450,56527:33439,56528:33476,56529:33486,56530:33444,56531:33505,56532:33545,56533:33527,56534:33508,56535:33551,56536:33543,56537:33500,56538:33524,56539:33490,56540:33496,56541:33548,56542:33531,56543:33491,56544:33553,56545:33562,56546:33542,56547:33556,56548:33557,56549:33504,56550:33493,56551:33564,56552:33617,56553:33627,56554:33628,56555:33544,56556:33682,56557:33596,56558:33588,56559:33585,56560:33691,56561:33630,56562:33583,56563:33615,56564:33607,56565:33603,56566:33631,56567:33600,56568:33559,56569:33632,56570:33581,56571:33594,56572:33587,56573:33638,56574:33637,56640:36581,56641:36582,56642:36583,56643:36584,56644:36585,56645:36586,56646:36587,56647:36588,56648:36589,56649:36590,56650:36591,56651:36592,56652:36593,56653:36594,56654:36595,56655:36596,56656:36597,56657:36598,56658:36599,56659:36600,56660:36601,56661:36602,56662:36603,56663:36604,56664:36605,56665:36606,56666:36607,56667:36608,56668:36609,56669:36610,56670:36611,56671:36612,56672:36613,56673:36614,56674:36615,56675:36616,56676:36617,56677:36618,56678:36619,56679:36620,56680:36621,56681:36622,56682:36623,56683:36624,56684:36625,56685:36626,56686:36627,56687:36628,56688:36629,56689:36630,56690:36631,56691:36632,56692:36633,56693:36634,56694:36635,56695:36636,56696:36637,56697:36638,56698:36639,56699:36640,56700:36641,56701:36642,56702:36643,56704:36644,56705:36645,56706:36646,56707:36647,56708:36648,56709:36649,56710:36650,56711:36651,56712:36652,56713:36653,56714:36654,56715:36655,56716:36656,56717:36657,56718:36658,56719:36659,56720:36660,56721:36661,56722:36662,56723:36663,56724:36664,56725:36665,56726:36666,56727:36667,56728:36668,56729:36669,56730:36670,56731:36671,56732:36672,56733:36673,56734:36674,56735:36675,56736:36676,56737:33640,56738:33563,56739:33641,56740:33644,56741:33642,56742:33645,56743:33646,56744:33712,56745:33656,56746:33715,56747:33716,56748:33696,56749:33706,56750:33683,56751:33692,56752:33669,56753:33660,56754:33718,56755:33705,56756:33661,56757:33720,56758:33659,56759:33688,56760:33694,56761:33704,56762:33722,56763:33724,56764:33729,56765:33793,56766:33765,56767:33752,56768:22535,56769:33816,56770:33803,56771:33757,56772:33789,56773:33750,56774:33820,56775:33848,56776:33809,56777:33798,56778:33748,56779:33759,56780:33807,56781:33795,56782:33784,56783:33785,56784:33770,56785:33733,56786:33728,56787:33830,56788:33776,56789:33761,56790:33884,56791:33873,56792:33882,56793:33881,56794:33907,56795:33927,56796:33928,56797:33914,56798:33929,56799:33912,56800:33852,56801:33862,56802:33897,56803:33910,56804:33932,56805:33934,56806:33841,56807:33901,56808:33985,56809:33997,56810:34000,56811:34022,56812:33981,56813:34003,56814:33994,56815:33983,56816:33978,56817:34016,56818:33953,56819:33977,56820:33972,56821:33943,56822:34021,56823:34019,56824:34060,56825:29965,56826:34104,56827:34032,56828:34105,56829:34079,56830:34106,56896:36677,56897:36678,56898:36679,56899:36680,56900:36681,56901:36682,56902:36683,56903:36684,56904:36685,56905:36686,56906:36687,56907:36688,56908:36689,56909:36690,56910:36691,56911:36692,56912:36693,56913:36694,56914:36695,56915:36696,56916:36697,56917:36698,56918:36699,56919:36700,56920:36701,56921:36702,56922:36703,56923:36704,56924:36705,56925:36706,56926:36707,56927:36708,56928:36709,56929:36714,56930:36736,56931:36748,56932:36754,56933:36765,56934:36768,56935:36769,56936:36770,56937:36772,56938:36773,56939:36774,56940:36775,56941:36778,56942:36780,56943:36781,56944:36782,56945:36783,56946:36786,56947:36787,56948:36788,56949:36789,56950:36791,56951:36792,56952:36794,56953:36795,56954:36796,56955:36799,56956:36800,56957:36803,56958:36806,56960:36809,56961:36810,56962:36811,56963:36812,56964:36813,56965:36815,56966:36818,56967:36822,56968:36823,56969:36826,56970:36832,56971:36833,56972:36835,56973:36839,56974:36844,56975:36847,56976:36849,56977:36850,56978:36852,56979:36853,56980:36854,56981:36858,56982:36859,56983:36860,56984:36862,56985:36863,56986:36871,56987:36872,56988:36876,56989:36878,56990:36883,56991:36885,56992:36888,56993:34134,56994:34107,56995:34047,56996:34044,56997:34137,56998:34120,56999:34152,57000:34148,57001:34142,57002:34170,57003:30626,57004:34115,57005:34162,57006:34171,57007:34212,57008:34216,57009:34183,57010:34191,57011:34169,57012:34222,57013:34204,57014:34181,57015:34233,57016:34231,57017:34224,57018:34259,57019:34241,57020:34268,57021:34303,57022:34343,57023:34309,57024:34345,57025:34326,57026:34364,57027:24318,57028:24328,57029:22844,57030:22849,57031:32823,57032:22869,57033:22874,57034:22872,57035:21263,57036:23586,57037:23589,57038:23596,57039:23604,57040:25164,57041:25194,57042:25247,57043:25275,57044:25290,57045:25306,57046:25303,57047:25326,57048:25378,57049:25334,57050:25401,57051:25419,57052:25411,57053:25517,57054:25590,57055:25457,57056:25466,57057:25486,57058:25524,57059:25453,57060:25516,57061:25482,57062:25449,57063:25518,57064:25532,57065:25586,57066:25592,57067:25568,57068:25599,57069:25540,57070:25566,57071:25550,57072:25682,57073:25542,57074:25534,57075:25669,57076:25665,57077:25611,57078:25627,57079:25632,57080:25612,57081:25638,57082:25633,57083:25694,57084:25732,57085:25709,57086:25750,57152:36889,57153:36892,57154:36899,57155:36900,57156:36901,57157:36903,57158:36904,57159:36905,57160:36906,57161:36907,57162:36908,57163:36912,57164:36913,57165:36914,57166:36915,57167:36916,57168:36919,57169:36921,57170:36922,57171:36925,57172:36927,57173:36928,57174:36931,57175:36933,57176:36934,57177:36936,57178:36937,57179:36938,57180:36939,57181:36940,57182:36942,57183:36948,57184:36949,57185:36950,57186:36953,57187:36954,57188:36956,57189:36957,57190:36958,57191:36959,57192:36960,57193:36961,57194:36964,57195:36966,57196:36967,57197:36969,57198:36970,57199:36971,57200:36972,57201:36975,57202:36976,57203:36977,57204:36978,57205:36979,57206:36982,57207:36983,57208:36984,57209:36985,57210:36986,57211:36987,57212:36988,57213:36990,57214:36993,57216:36996,57217:36997,57218:36998,57219:36999,57220:37001,57221:37002,57222:37004,57223:37005,57224:37006,57225:37007,57226:37008,57227:37010,57228:37012,57229:37014,57230:37016,57231:37018,57232:37020,57233:37022,57234:37023,57235:37024,57236:37028,57237:37029,57238:37031,57239:37032,57240:37033,57241:37035,57242:37037,57243:37042,57244:37047,57245:37052,57246:37053,57247:37055,57248:37056,57249:25722,57250:25783,57251:25784,57252:25753,57253:25786,57254:25792,57255:25808,57256:25815,57257:25828,57258:25826,57259:25865,57260:25893,57261:25902,57262:24331,57263:24530,57264:29977,57265:24337,57266:21343,57267:21489,57268:21501,57269:21481,57270:21480,57271:21499,57272:21522,57273:21526,57274:21510,57275:21579,57276:21586,57277:21587,57278:21588,57279:21590,57280:21571,57281:21537,57282:21591,57283:21593,57284:21539,57285:21554,57286:21634,57287:21652,57288:21623,57289:21617,57290:21604,57291:21658,57292:21659,57293:21636,57294:21622,57295:21606,57296:21661,57297:21712,57298:21677,57299:21698,57300:21684,57301:21714,57302:21671,57303:21670,57304:21715,57305:21716,57306:21618,57307:21667,57308:21717,57309:21691,57310:21695,57311:21708,57312:21721,57313:21722,57314:21724,57315:21673,57316:21674,57317:21668,57318:21725,57319:21711,57320:21726,57321:21787,57322:21735,57323:21792,57324:21757,57325:21780,57326:21747,57327:21794,57328:21795,57329:21775,57330:21777,57331:21799,57332:21802,57333:21863,57334:21903,57335:21941,57336:21833,57337:21869,57338:21825,57339:21845,57340:21823,57341:21840,57342:21820,57408:37058,57409:37059,57410:37062,57411:37064,57412:37065,57413:37067,57414:37068,57415:37069,57416:37074,57417:37076,57418:37077,57419:37078,57420:37080,57421:37081,57422:37082,57423:37086,57424:37087,57425:37088,57426:37091,57427:37092,57428:37093,57429:37097,57430:37098,57431:37100,57432:37102,57433:37104,57434:37105,57435:37106,57436:37107,57437:37109,57438:37110,57439:37111,57440:37113,57441:37114,57442:37115,57443:37116,57444:37119,57445:37120,57446:37121,57447:37123,57448:37125,57449:37126,57450:37127,57451:37128,57452:37129,57453:37130,57454:37131,57455:37132,57456:37133,57457:37134,57458:37135,57459:37136,57460:37137,57461:37138,57462:37139,57463:37140,57464:37141,57465:37142,57466:37143,57467:37144,57468:37146,57469:37147,57470:37148,57472:37149,57473:37151,57474:37152,57475:37153,57476:37156,57477:37157,57478:37158,57479:37159,57480:37160,57481:37161,57482:37162,57483:37163,57484:37164,57485:37165,57486:37166,57487:37168,57488:37170,57489:37171,57490:37172,57491:37173,57492:37174,57493:37175,57494:37176,57495:37178,57496:37179,57497:37180,57498:37181,57499:37182,57500:37183,57501:37184,57502:37185,57503:37186,57504:37188,57505:21815,57506:21846,57507:21877,57508:21878,57509:21879,57510:21811,57511:21808,57512:21852,57513:21899,57514:21970,57515:21891,57516:21937,57517:21945,57518:21896,57519:21889,57520:21919,57521:21886,57522:21974,57523:21905,57524:21883,57525:21983,57526:21949,57527:21950,57528:21908,57529:21913,57530:21994,57531:22007,57532:21961,57533:22047,57534:21969,57535:21995,57536:21996,57537:21972,57538:21990,57539:21981,57540:21956,57541:21999,57542:21989,57543:22002,57544:22003,57545:21964,57546:21965,57547:21992,57548:22005,57549:21988,57550:36756,57551:22046,57552:22024,57553:22028,57554:22017,57555:22052,57556:22051,57557:22014,57558:22016,57559:22055,57560:22061,57561:22104,57562:22073,57563:22103,57564:22060,57565:22093,57566:22114,57567:22105,57568:22108,57569:22092,57570:22100,57571:22150,57572:22116,57573:22129,57574:22123,57575:22139,57576:22140,57577:22149,57578:22163,57579:22191,57580:22228,57581:22231,57582:22237,57583:22241,57584:22261,57585:22251,57586:22265,57587:22271,57588:22276,57589:22282,57590:22281,57591:22300,57592:24079,57593:24089,57594:24084,57595:24081,57596:24113,57597:24123,57598:24124,57664:37189,57665:37191,57666:37192,57667:37201,57668:37203,57669:37204,57670:37205,57671:37206,57672:37208,57673:37209,57674:37211,57675:37212,57676:37215,57677:37216,57678:37222,57679:37223,57680:37224,57681:37227,57682:37229,57683:37235,57684:37242,57685:37243,57686:37244,57687:37248,57688:37249,57689:37250,57690:37251,57691:37252,57692:37254,57693:37256,57694:37258,57695:37262,57696:37263,57697:37267,57698:37268,57699:37269,57700:37270,57701:37271,57702:37272,57703:37273,57704:37276,57705:37277,57706:37278,57707:37279,57708:37280,57709:37281,57710:37284,57711:37285,57712:37286,57713:37287,57714:37288,57715:37289,57716:37291,57717:37292,57718:37296,57719:37297,57720:37298,57721:37299,57722:37302,57723:37303,57724:37304,57725:37305,57726:37307,57728:37308,57729:37309,57730:37310,57731:37311,57732:37312,57733:37313,57734:37314,57735:37315,57736:37316,57737:37317,57738:37318,57739:37320,57740:37323,57741:37328,57742:37330,57743:37331,57744:37332,57745:37333,57746:37334,57747:37335,57748:37336,57749:37337,57750:37338,57751:37339,57752:37341,57753:37342,57754:37343,57755:37344,57756:37345,57757:37346,57758:37347,57759:37348,57760:37349,57761:24119,57762:24132,57763:24148,57764:24155,57765:24158,57766:24161,57767:23692,57768:23674,57769:23693,57770:23696,57771:23702,57772:23688,57773:23704,57774:23705,57775:23697,57776:23706,57777:23708,57778:23733,57779:23714,57780:23741,57781:23724,57782:23723,57783:23729,57784:23715,57785:23745,57786:23735,57787:23748,57788:23762,57789:23780,57790:23755,57791:23781,57792:23810,57793:23811,57794:23847,57795:23846,57796:23854,57797:23844,57798:23838,57799:23814,57800:23835,57801:23896,57802:23870,57803:23860,57804:23869,57805:23916,57806:23899,57807:23919,57808:23901,57809:23915,57810:23883,57811:23882,57812:23913,57813:23924,57814:23938,57815:23961,57816:23965,57817:35955,57818:23991,57819:24005,57820:24435,57821:24439,57822:24450,57823:24455,57824:24457,57825:24460,57826:24469,57827:24473,57828:24476,57829:24488,57830:24493,57831:24501,57832:24508,57833:34914,57834:24417,57835:29357,57836:29360,57837:29364,57838:29367,57839:29368,57840:29379,57841:29377,57842:29390,57843:29389,57844:29394,57845:29416,57846:29423,57847:29417,57848:29426,57849:29428,57850:29431,57851:29441,57852:29427,57853:29443,57854:29434,57920:37350,57921:37351,57922:37352,57923:37353,57924:37354,57925:37355,57926:37356,57927:37357,57928:37358,57929:37359,57930:37360,57931:37361,57932:37362,57933:37363,57934:37364,57935:37365,57936:37366,57937:37367,57938:37368,57939:37369,57940:37370,57941:37371,57942:37372,57943:37373,57944:37374,57945:37375,57946:37376,57947:37377,57948:37378,57949:37379,57950:37380,57951:37381,57952:37382,57953:37383,57954:37384,57955:37385,57956:37386,57957:37387,57958:37388,57959:37389,57960:37390,57961:37391,57962:37392,57963:37393,57964:37394,57965:37395,57966:37396,57967:37397,57968:37398,57969:37399,57970:37400,57971:37401,57972:37402,57973:37403,57974:37404,57975:37405,57976:37406,57977:37407,57978:37408,57979:37409,57980:37410,57981:37411,57982:37412,57984:37413,57985:37414,57986:37415,57987:37416,57988:37417,57989:37418,57990:37419,57991:37420,57992:37421,57993:37422,57994:37423,57995:37424,57996:37425,57997:37426,57998:37427,57999:37428,58000:37429,58001:37430,58002:37431,58003:37432,58004:37433,58005:37434,58006:37435,58007:37436,58008:37437,58009:37438,58010:37439,58011:37440,58012:37441,58013:37442,58014:37443,58015:37444,58016:37445,58017:29435,58018:29463,58019:29459,58020:29473,58021:29450,58022:29470,58023:29469,58024:29461,58025:29474,58026:29497,58027:29477,58028:29484,58029:29496,58030:29489,58031:29520,58032:29517,58033:29527,58034:29536,58035:29548,58036:29551,58037:29566,58038:33307,58039:22821,58040:39143,58041:22820,58042:22786,58043:39267,58044:39271,58045:39272,58046:39273,58047:39274,58048:39275,58049:39276,58050:39284,58051:39287,58052:39293,58053:39296,58054:39300,58055:39303,58056:39306,58057:39309,58058:39312,58059:39313,58060:39315,58061:39316,58062:39317,58063:24192,58064:24209,58065:24203,58066:24214,58067:24229,58068:24224,58069:24249,58070:24245,58071:24254,58072:24243,58073:36179,58074:24274,58075:24273,58076:24283,58077:24296,58078:24298,58079:33210,58080:24516,58081:24521,58082:24534,58083:24527,58084:24579,58085:24558,58086:24580,58087:24545,58088:24548,58089:24574,58090:24581,58091:24582,58092:24554,58093:24557,58094:24568,58095:24601,58096:24629,58097:24614,58098:24603,58099:24591,58100:24589,58101:24617,58102:24619,58103:24586,58104:24639,58105:24609,58106:24696,58107:24697,58108:24699,58109:24698,58110:24642,58176:37446,58177:37447,58178:37448,58179:37449,58180:37450,58181:37451,58182:37452,58183:37453,58184:37454,58185:37455,58186:37456,58187:37457,58188:37458,58189:37459,58190:37460,58191:37461,58192:37462,58193:37463,58194:37464,58195:37465,58196:37466,58197:37467,58198:37468,58199:37469,58200:37470,58201:37471,58202:37472,58203:37473,58204:37474,58205:37475,58206:37476,58207:37477,58208:37478,58209:37479,58210:37480,58211:37481,58212:37482,58213:37483,58214:37484,58215:37485,58216:37486,58217:37487,58218:37488,58219:37489,58220:37490,58221:37491,58222:37493,58223:37494,58224:37495,58225:37496,58226:37497,58227:37498,58228:37499,58229:37500,58230:37501,58231:37502,58232:37503,58233:37504,58234:37505,58235:37506,58236:37507,58237:37508,58238:37509,58240:37510,58241:37511,58242:37512,58243:37513,58244:37514,58245:37515,58246:37516,58247:37517,58248:37519,58249:37520,58250:37521,58251:37522,58252:37523,58253:37524,58254:37525,58255:37526,58256:37527,58257:37528,58258:37529,58259:37530,58260:37531,58261:37532,58262:37533,58263:37534,58264:37535,58265:37536,58266:37537,58267:37538,58268:37539,58269:37540,58270:37541,58271:37542,58272:37543,58273:24682,58274:24701,58275:24726,58276:24730,58277:24749,58278:24733,58279:24707,58280:24722,58281:24716,58282:24731,58283:24812,58284:24763,58285:24753,58286:24797,58287:24792,58288:24774,58289:24794,58290:24756,58291:24864,58292:24870,58293:24853,58294:24867,58295:24820,58296:24832,58297:24846,58298:24875,58299:24906,58300:24949,58301:25004,58302:24980,58303:24999,58304:25015,58305:25044,58306:25077,58307:24541,58308:38579,58309:38377,58310:38379,58311:38385,58312:38387,58313:38389,58314:38390,58315:38396,58316:38398,58317:38403,58318:38404,58319:38406,58320:38408,58321:38410,58322:38411,58323:38412,58324:38413,58325:38415,58326:38418,58327:38421,58328:38422,58329:38423,58330:38425,58331:38426,58332:20012,58333:29247,58334:25109,58335:27701,58336:27732,58337:27740,58338:27722,58339:27811,58340:27781,58341:27792,58342:27796,58343:27788,58344:27752,58345:27753,58346:27764,58347:27766,58348:27782,58349:27817,58350:27856,58351:27860,58352:27821,58353:27895,58354:27896,58355:27889,58356:27863,58357:27826,58358:27872,58359:27862,58360:27898,58361:27883,58362:27886,58363:27825,58364:27859,58365:27887,58366:27902,58432:37544,58433:37545,58434:37546,58435:37547,58436:37548,58437:37549,58438:37551,58439:37552,58440:37553,58441:37554,58442:37555,58443:37556,58444:37557,58445:37558,58446:37559,58447:37560,58448:37561,58449:37562,58450:37563,58451:37564,58452:37565,58453:37566,58454:37567,58455:37568,58456:37569,58457:37570,58458:37571,58459:37572,58460:37573,58461:37574,58462:37575,58463:37577,58464:37578,58465:37579,58466:37580,58467:37581,58468:37582,58469:37583,58470:37584,58471:37585,58472:37586,58473:37587,58474:37588,58475:37589,58476:37590,58477:37591,58478:37592,58479:37593,58480:37594,58481:37595,58482:37596,58483:37597,58484:37598,58485:37599,58486:37600,58487:37601,58488:37602,58489:37603,58490:37604,58491:37605,58492:37606,58493:37607,58494:37608,58496:37609,58497:37610,58498:37611,58499:37612,58500:37613,58501:37614,58502:37615,58503:37616,58504:37617,58505:37618,58506:37619,58507:37620,58508:37621,58509:37622,58510:37623,58511:37624,58512:37625,58513:37626,58514:37627,58515:37628,58516:37629,58517:37630,58518:37631,58519:37632,58520:37633,58521:37634,58522:37635,58523:37636,58524:37637,58525:37638,58526:37639,58527:37640,58528:37641,58529:27961,58530:27943,58531:27916,58532:27971,58533:27976,58534:27911,58535:27908,58536:27929,58537:27918,58538:27947,58539:27981,58540:27950,58541:27957,58542:27930,58543:27983,58544:27986,58545:27988,58546:27955,58547:28049,58548:28015,58549:28062,58550:28064,58551:27998,58552:28051,58553:28052,58554:27996,58555:28000,58556:28028,58557:28003,58558:28186,58559:28103,58560:28101,58561:28126,58562:28174,58563:28095,58564:28128,58565:28177,58566:28134,58567:28125,58568:28121,58569:28182,58570:28075,58571:28172,58572:28078,58573:28203,58574:28270,58575:28238,58576:28267,58577:28338,58578:28255,58579:28294,58580:28243,58581:28244,58582:28210,58583:28197,58584:28228,58585:28383,58586:28337,58587:28312,58588:28384,58589:28461,58590:28386,58591:28325,58592:28327,58593:28349,58594:28347,58595:28343,58596:28375,58597:28340,58598:28367,58599:28303,58600:28354,58601:28319,58602:28514,58603:28486,58604:28487,58605:28452,58606:28437,58607:28409,58608:28463,58609:28470,58610:28491,58611:28532,58612:28458,58613:28425,58614:28457,58615:28553,58616:28557,58617:28556,58618:28536,58619:28530,58620:28540,58621:28538,58622:28625,58688:37642,58689:37643,58690:37644,58691:37645,58692:37646,58693:37647,58694:37648,58695:37649,58696:37650,58697:37651,58698:37652,58699:37653,58700:37654,58701:37655,58702:37656,58703:37657,58704:37658,58705:37659,58706:37660,58707:37661,58708:37662,58709:37663,58710:37664,58711:37665,58712:37666,58713:37667,58714:37668,58715:37669,58716:37670,58717:37671,58718:37672,58719:37673,58720:37674,58721:37675,58722:37676,58723:37677,58724:37678,58725:37679,58726:37680,58727:37681,58728:37682,58729:37683,58730:37684,58731:37685,58732:37686,58733:37687,58734:37688,58735:37689,58736:37690,58737:37691,58738:37692,58739:37693,58740:37695,58741:37696,58742:37697,58743:37698,58744:37699,58745:37700,58746:37701,58747:37702,58748:37703,58749:37704,58750:37705,58752:37706,58753:37707,58754:37708,58755:37709,58756:37710,58757:37711,58758:37712,58759:37713,58760:37714,58761:37715,58762:37716,58763:37717,58764:37718,58765:37719,58766:37720,58767:37721,58768:37722,58769:37723,58770:37724,58771:37725,58772:37726,58773:37727,58774:37728,58775:37729,58776:37730,58777:37731,58778:37732,58779:37733,58780:37734,58781:37735,58782:37736,58783:37737,58784:37739,58785:28617,58786:28583,58787:28601,58788:28598,58789:28610,58790:28641,58791:28654,58792:28638,58793:28640,58794:28655,58795:28698,58796:28707,58797:28699,58798:28729,58799:28725,58800:28751,58801:28766,58802:23424,58803:23428,58804:23445,58805:23443,58806:23461,58807:23480,58808:29999,58809:39582,58810:25652,58811:23524,58812:23534,58813:35120,58814:23536,58815:36423,58816:35591,58817:36790,58818:36819,58819:36821,58820:36837,58821:36846,58822:36836,58823:36841,58824:36838,58825:36851,58826:36840,58827:36869,58828:36868,58829:36875,58830:36902,58831:36881,58832:36877,58833:36886,58834:36897,58835:36917,58836:36918,58837:36909,58838:36911,58839:36932,58840:36945,58841:36946,58842:36944,58843:36968,58844:36952,58845:36962,58846:36955,58847:26297,58848:36980,58849:36989,58850:36994,58851:37000,58852:36995,58853:37003,58854:24400,58855:24407,58856:24406,58857:24408,58858:23611,58859:21675,58860:23632,58861:23641,58862:23409,58863:23651,58864:23654,58865:32700,58866:24362,58867:24361,58868:24365,58869:33396,58870:24380,58871:39739,58872:23662,58873:22913,58874:22915,58875:22925,58876:22953,58877:22954,58878:22947,58944:37740,58945:37741,58946:37742,58947:37743,58948:37744,58949:37745,58950:37746,58951:37747,58952:37748,58953:37749,58954:37750,58955:37751,58956:37752,58957:37753,58958:37754,58959:37755,58960:37756,58961:37757,58962:37758,58963:37759,58964:37760,58965:37761,58966:37762,58967:37763,58968:37764,58969:37765,58970:37766,58971:37767,58972:37768,58973:37769,58974:37770,58975:37771,58976:37772,58977:37773,58978:37774,58979:37776,58980:37777,58981:37778,58982:37779,58983:37780,58984:37781,58985:37782,58986:37783,58987:37784,58988:37785,58989:37786,58990:37787,58991:37788,58992:37789,58993:37790,58994:37791,58995:37792,58996:37793,58997:37794,58998:37795,58999:37796,59000:37797,59001:37798,59002:37799,59003:37800,59004:37801,59005:37802,59006:37803,59008:37804,59009:37805,59010:37806,59011:37807,59012:37808,59013:37809,59014:37810,59015:37811,59016:37812,59017:37813,59018:37814,59019:37815,59020:37816,59021:37817,59022:37818,59023:37819,59024:37820,59025:37821,59026:37822,59027:37823,59028:37824,59029:37825,59030:37826,59031:37827,59032:37828,59033:37829,59034:37830,59035:37831,59036:37832,59037:37833,59038:37835,59039:37836,59040:37837,59041:22935,59042:22986,59043:22955,59044:22942,59045:22948,59046:22994,59047:22962,59048:22959,59049:22999,59050:22974,59051:23045,59052:23046,59053:23005,59054:23048,59055:23011,59056:23000,59057:23033,59058:23052,59059:23049,59060:23090,59061:23092,59062:23057,59063:23075,59064:23059,59065:23104,59066:23143,59067:23114,59068:23125,59069:23100,59070:23138,59071:23157,59072:33004,59073:23210,59074:23195,59075:23159,59076:23162,59077:23230,59078:23275,59079:23218,59080:23250,59081:23252,59082:23224,59083:23264,59084:23267,59085:23281,59086:23254,59087:23270,59088:23256,59089:23260,59090:23305,59091:23319,59092:23318,59093:23346,59094:23351,59095:23360,59096:23573,59097:23580,59098:23386,59099:23397,59100:23411,59101:23377,59102:23379,59103:23394,59104:39541,59105:39543,59106:39544,59107:39546,59108:39551,59109:39549,59110:39552,59111:39553,59112:39557,59113:39560,59114:39562,59115:39568,59116:39570,59117:39571,59118:39574,59119:39576,59120:39579,59121:39580,59122:39581,59123:39583,59124:39584,59125:39586,59126:39587,59127:39589,59128:39591,59129:32415,59130:32417,59131:32419,59132:32421,59133:32424,59134:32425,59200:37838,59201:37839,59202:37840,59203:37841,59204:37842,59205:37843,59206:37844,59207:37845,59208:37847,59209:37848,59210:37849,59211:37850,59212:37851,59213:37852,59214:37853,59215:37854,59216:37855,59217:37856,59218:37857,59219:37858,59220:37859,59221:37860,59222:37861,59223:37862,59224:37863,59225:37864,59226:37865,59227:37866,59228:37867,59229:37868,59230:37869,59231:37870,59232:37871,59233:37872,59234:37873,59235:37874,59236:37875,59237:37876,59238:37877,59239:37878,59240:37879,59241:37880,59242:37881,59243:37882,59244:37883,59245:37884,59246:37885,59247:37886,59248:37887,59249:37888,59250:37889,59251:37890,59252:37891,59253:37892,59254:37893,59255:37894,59256:37895,59257:37896,59258:37897,59259:37898,59260:37899,59261:37900,59262:37901,59264:37902,59265:37903,59266:37904,59267:37905,59268:37906,59269:37907,59270:37908,59271:37909,59272:37910,59273:37911,59274:37912,59275:37913,59276:37914,59277:37915,59278:37916,59279:37917,59280:37918,59281:37919,59282:37920,59283:37921,59284:37922,59285:37923,59286:37924,59287:37925,59288:37926,59289:37927,59290:37928,59291:37929,59292:37930,59293:37931,59294:37932,59295:37933,59296:37934,59297:32429,59298:32432,59299:32446,59300:32448,59301:32449,59302:32450,59303:32457,59304:32459,59305:32460,59306:32464,59307:32468,59308:32471,59309:32475,59310:32480,59311:32481,59312:32488,59313:32491,59314:32494,59315:32495,59316:32497,59317:32498,59318:32525,59319:32502,59320:32506,59321:32507,59322:32510,59323:32513,59324:32514,59325:32515,59326:32519,59327:32520,59328:32523,59329:32524,59330:32527,59331:32529,59332:32530,59333:32535,59334:32537,59335:32540,59336:32539,59337:32543,59338:32545,59339:32546,59340:32547,59341:32548,59342:32549,59343:32550,59344:32551,59345:32554,59346:32555,59347:32556,59348:32557,59349:32559,59350:32560,59351:32561,59352:32562,59353:32563,59354:32565,59355:24186,59356:30079,59357:24027,59358:30014,59359:37013,59360:29582,59361:29585,59362:29614,59363:29602,59364:29599,59365:29647,59366:29634,59367:29649,59368:29623,59369:29619,59370:29632,59371:29641,59372:29640,59373:29669,59374:29657,59375:39036,59376:29706,59377:29673,59378:29671,59379:29662,59380:29626,59381:29682,59382:29711,59383:29738,59384:29787,59385:29734,59386:29733,59387:29736,59388:29744,59389:29742,59390:29740,59456:37935,59457:37936,59458:37937,59459:37938,59460:37939,59461:37940,59462:37941,59463:37942,59464:37943,59465:37944,59466:37945,59467:37946,59468:37947,59469:37948,59470:37949,59471:37951,59472:37952,59473:37953,59474:37954,59475:37955,59476:37956,59477:37957,59478:37958,59479:37959,59480:37960,59481:37961,59482:37962,59483:37963,59484:37964,59485:37965,59486:37966,59487:37967,59488:37968,59489:37969,59490:37970,59491:37971,59492:37972,59493:37973,59494:37974,59495:37975,59496:37976,59497:37977,59498:37978,59499:37979,59500:37980,59501:37981,59502:37982,59503:37983,59504:37984,59505:37985,59506:37986,59507:37987,59508:37988,59509:37989,59510:37990,59511:37991,59512:37992,59513:37993,59514:37994,59515:37996,59516:37997,59517:37998,59518:37999,59520:38000,59521:38001,59522:38002,59523:38003,59524:38004,59525:38005,59526:38006,59527:38007,59528:38008,59529:38009,59530:38010,59531:38011,59532:38012,59533:38013,59534:38014,59535:38015,59536:38016,59537:38017,59538:38018,59539:38019,59540:38020,59541:38033,59542:38038,59543:38040,59544:38087,59545:38095,59546:38099,59547:38100,59548:38106,59549:38118,59550:38139,59551:38172,59552:38176,59553:29723,59554:29722,59555:29761,59556:29788,59557:29783,59558:29781,59559:29785,59560:29815,59561:29805,59562:29822,59563:29852,59564:29838,59565:29824,59566:29825,59567:29831,59568:29835,59569:29854,59570:29864,59571:29865,59572:29840,59573:29863,59574:29906,59575:29882,59576:38890,59577:38891,59578:38892,59579:26444,59580:26451,59581:26462,59582:26440,59583:26473,59584:26533,59585:26503,59586:26474,59587:26483,59588:26520,59589:26535,59590:26485,59591:26536,59592:26526,59593:26541,59594:26507,59595:26487,59596:26492,59597:26608,59598:26633,59599:26584,59600:26634,59601:26601,59602:26544,59603:26636,59604:26585,59605:26549,59606:26586,59607:26547,59608:26589,59609:26624,59610:26563,59611:26552,59612:26594,59613:26638,59614:26561,59615:26621,59616:26674,59617:26675,59618:26720,59619:26721,59620:26702,59621:26722,59622:26692,59623:26724,59624:26755,59625:26653,59626:26709,59627:26726,59628:26689,59629:26727,59630:26688,59631:26686,59632:26698,59633:26697,59634:26665,59635:26805,59636:26767,59637:26740,59638:26743,59639:26771,59640:26731,59641:26818,59642:26990,59643:26876,59644:26911,59645:26912,59646:26873,59712:38183,59713:38195,59714:38205,59715:38211,59716:38216,59717:38219,59718:38229,59719:38234,59720:38240,59721:38254,59722:38260,59723:38261,59724:38263,59725:38264,59726:38265,59727:38266,59728:38267,59729:38268,59730:38269,59731:38270,59732:38272,59733:38273,59734:38274,59735:38275,59736:38276,59737:38277,59738:38278,59739:38279,59740:38280,59741:38281,59742:38282,59743:38283,59744:38284,59745:38285,59746:38286,59747:38287,59748:38288,59749:38289,59750:38290,59751:38291,59752:38292,59753:38293,59754:38294,59755:38295,59756:38296,59757:38297,59758:38298,59759:38299,59760:38300,59761:38301,59762:38302,59763:38303,59764:38304,59765:38305,59766:38306,59767:38307,59768:38308,59769:38309,59770:38310,59771:38311,59772:38312,59773:38313,59774:38314,59776:38315,59777:38316,59778:38317,59779:38318,59780:38319,59781:38320,59782:38321,59783:38322,59784:38323,59785:38324,59786:38325,59787:38326,59788:38327,59789:38328,59790:38329,59791:38330,59792:38331,59793:38332,59794:38333,59795:38334,59796:38335,59797:38336,59798:38337,59799:38338,59800:38339,59801:38340,59802:38341,59803:38342,59804:38343,59805:38344,59806:38345,59807:38346,59808:38347,59809:26916,59810:26864,59811:26891,59812:26881,59813:26967,59814:26851,59815:26896,59816:26993,59817:26937,59818:26976,59819:26946,59820:26973,59821:27012,59822:26987,59823:27008,59824:27032,59825:27000,59826:26932,59827:27084,59828:27015,59829:27016,59830:27086,59831:27017,59832:26982,59833:26979,59834:27001,59835:27035,59836:27047,59837:27067,59838:27051,59839:27053,59840:27092,59841:27057,59842:27073,59843:27082,59844:27103,59845:27029,59846:27104,59847:27021,59848:27135,59849:27183,59850:27117,59851:27159,59852:27160,59853:27237,59854:27122,59855:27204,59856:27198,59857:27296,59858:27216,59859:27227,59860:27189,59861:27278,59862:27257,59863:27197,59864:27176,59865:27224,59866:27260,59867:27281,59868:27280,59869:27305,59870:27287,59871:27307,59872:29495,59873:29522,59874:27521,59875:27522,59876:27527,59877:27524,59878:27538,59879:27539,59880:27533,59881:27546,59882:27547,59883:27553,59884:27562,59885:36715,59886:36717,59887:36721,59888:36722,59889:36723,59890:36725,59891:36726,59892:36728,59893:36727,59894:36729,59895:36730,59896:36732,59897:36734,59898:36737,59899:36738,59900:36740,59901:36743,59902:36747,59968:38348,59969:38349,59970:38350,59971:38351,59972:38352,59973:38353,59974:38354,59975:38355,59976:38356,59977:38357,59978:38358,59979:38359,59980:38360,59981:38361,59982:38362,59983:38363,59984:38364,59985:38365,59986:38366,59987:38367,59988:38368,59989:38369,59990:38370,59991:38371,59992:38372,59993:38373,59994:38374,59995:38375,59996:38380,59997:38399,59998:38407,59999:38419,60000:38424,60001:38427,60002:38430,60003:38432,60004:38435,60005:38436,60006:38437,60007:38438,60008:38439,60009:38440,60010:38441,60011:38443,60012:38444,60013:38445,60014:38447,60015:38448,60016:38455,60017:38456,60018:38457,60019:38458,60020:38462,60021:38465,60022:38467,60023:38474,60024:38478,60025:38479,60026:38481,60027:38482,60028:38483,60029:38486,60030:38487,60032:38488,60033:38489,60034:38490,60035:38492,60036:38493,60037:38494,60038:38496,60039:38499,60040:38501,60041:38502,60042:38507,60043:38509,60044:38510,60045:38511,60046:38512,60047:38513,60048:38515,60049:38520,60050:38521,60051:38522,60052:38523,60053:38524,60054:38525,60055:38526,60056:38527,60057:38528,60058:38529,60059:38530,60060:38531,60061:38532,60062:38535,60063:38537,60064:38538,60065:36749,60066:36750,60067:36751,60068:36760,60069:36762,60070:36558,60071:25099,60072:25111,60073:25115,60074:25119,60075:25122,60076:25121,60077:25125,60078:25124,60079:25132,60080:33255,60081:29935,60082:29940,60083:29951,60084:29967,60085:29969,60086:29971,60087:25908,60088:26094,60089:26095,60090:26096,60091:26122,60092:26137,60093:26482,60094:26115,60095:26133,60096:26112,60097:28805,60098:26359,60099:26141,60100:26164,60101:26161,60102:26166,60103:26165,60104:32774,60105:26207,60106:26196,60107:26177,60108:26191,60109:26198,60110:26209,60111:26199,60112:26231,60113:26244,60114:26252,60115:26279,60116:26269,60117:26302,60118:26331,60119:26332,60120:26342,60121:26345,60122:36146,60123:36147,60124:36150,60125:36155,60126:36157,60127:36160,60128:36165,60129:36166,60130:36168,60131:36169,60132:36167,60133:36173,60134:36181,60135:36185,60136:35271,60137:35274,60138:35275,60139:35276,60140:35278,60141:35279,60142:35280,60143:35281,60144:29294,60145:29343,60146:29277,60147:29286,60148:29295,60149:29310,60150:29311,60151:29316,60152:29323,60153:29325,60154:29327,60155:29330,60156:25352,60157:25394,60158:25520,60224:38540,60225:38542,60226:38545,60227:38546,60228:38547,60229:38549,60230:38550,60231:38554,60232:38555,60233:38557,60234:38558,60235:38559,60236:38560,60237:38561,60238:38562,60239:38563,60240:38564,60241:38565,60242:38566,60243:38568,60244:38569,60245:38570,60246:38571,60247:38572,60248:38573,60249:38574,60250:38575,60251:38577,60252:38578,60253:38580,60254:38581,60255:38583,60256:38584,60257:38586,60258:38587,60259:38591,60260:38594,60261:38595,60262:38600,60263:38602,60264:38603,60265:38608,60266:38609,60267:38611,60268:38612,60269:38614,60270:38615,60271:38616,60272:38617,60273:38618,60274:38619,60275:38620,60276:38621,60277:38622,60278:38623,60279:38625,60280:38626,60281:38627,60282:38628,60283:38629,60284:38630,60285:38631,60286:38635,60288:38636,60289:38637,60290:38638,60291:38640,60292:38641,60293:38642,60294:38644,60295:38645,60296:38648,60297:38650,60298:38651,60299:38652,60300:38653,60301:38655,60302:38658,60303:38659,60304:38661,60305:38666,60306:38667,60307:38668,60308:38672,60309:38673,60310:38674,60311:38676,60312:38677,60313:38679,60314:38680,60315:38681,60316:38682,60317:38683,60318:38685,60319:38687,60320:38688,60321:25663,60322:25816,60323:32772,60324:27626,60325:27635,60326:27645,60327:27637,60328:27641,60329:27653,60330:27655,60331:27654,60332:27661,60333:27669,60334:27672,60335:27673,60336:27674,60337:27681,60338:27689,60339:27684,60340:27690,60341:27698,60342:25909,60343:25941,60344:25963,60345:29261,60346:29266,60347:29270,60348:29232,60349:34402,60350:21014,60351:32927,60352:32924,60353:32915,60354:32956,60355:26378,60356:32957,60357:32945,60358:32939,60359:32941,60360:32948,60361:32951,60362:32999,60363:33000,60364:33001,60365:33002,60366:32987,60367:32962,60368:32964,60369:32985,60370:32973,60371:32983,60372:26384,60373:32989,60374:33003,60375:33009,60376:33012,60377:33005,60378:33037,60379:33038,60380:33010,60381:33020,60382:26389,60383:33042,60384:35930,60385:33078,60386:33054,60387:33068,60388:33048,60389:33074,60390:33096,60391:33100,60392:33107,60393:33140,60394:33113,60395:33114,60396:33137,60397:33120,60398:33129,60399:33148,60400:33149,60401:33133,60402:33127,60403:22605,60404:23221,60405:33160,60406:33154,60407:33169,60408:28373,60409:33187,60410:33194,60411:33228,60412:26406,60413:33226,60414:33211,60480:38689,60481:38690,60482:38691,60483:38692,60484:38693,60485:38694,60486:38695,60487:38696,60488:38697,60489:38699,60490:38700,60491:38702,60492:38703,60493:38705,60494:38707,60495:38708,60496:38709,60497:38710,60498:38711,60499:38714,60500:38715,60501:38716,60502:38717,60503:38719,60504:38720,60505:38721,60506:38722,60507:38723,60508:38724,60509:38725,60510:38726,60511:38727,60512:38728,60513:38729,60514:38730,60515:38731,60516:38732,60517:38733,60518:38734,60519:38735,60520:38736,60521:38737,60522:38740,60523:38741,60524:38743,60525:38744,60526:38746,60527:38748,60528:38749,60529:38751,60530:38755,60531:38756,60532:38758,60533:38759,60534:38760,60535:38762,60536:38763,60537:38764,60538:38765,60539:38766,60540:38767,60541:38768,60542:38769,60544:38770,60545:38773,60546:38775,60547:38776,60548:38777,60549:38778,60550:38779,60551:38781,60552:38782,60553:38783,60554:38784,60555:38785,60556:38786,60557:38787,60558:38788,60559:38790,60560:38791,60561:38792,60562:38793,60563:38794,60564:38796,60565:38798,60566:38799,60567:38800,60568:38803,60569:38805,60570:38806,60571:38807,60572:38809,60573:38810,60574:38811,60575:38812,60576:38813,60577:33217,60578:33190,60579:27428,60580:27447,60581:27449,60582:27459,60583:27462,60584:27481,60585:39121,60586:39122,60587:39123,60588:39125,60589:39129,60590:39130,60591:27571,60592:24384,60593:27586,60594:35315,60595:26000,60596:40785,60597:26003,60598:26044,60599:26054,60600:26052,60601:26051,60602:26060,60603:26062,60604:26066,60605:26070,60606:28800,60607:28828,60608:28822,60609:28829,60610:28859,60611:28864,60612:28855,60613:28843,60614:28849,60615:28904,60616:28874,60617:28944,60618:28947,60619:28950,60620:28975,60621:28977,60622:29043,60623:29020,60624:29032,60625:28997,60626:29042,60627:29002,60628:29048,60629:29050,60630:29080,60631:29107,60632:29109,60633:29096,60634:29088,60635:29152,60636:29140,60637:29159,60638:29177,60639:29213,60640:29224,60641:28780,60642:28952,60643:29030,60644:29113,60645:25150,60646:25149,60647:25155,60648:25160,60649:25161,60650:31035,60651:31040,60652:31046,60653:31049,60654:31067,60655:31068,60656:31059,60657:31066,60658:31074,60659:31063,60660:31072,60661:31087,60662:31079,60663:31098,60664:31109,60665:31114,60666:31130,60667:31143,60668:31155,60669:24529,60670:24528,60736:38814,60737:38815,60738:38817,60739:38818,60740:38820,60741:38821,60742:38822,60743:38823,60744:38824,60745:38825,60746:38826,60747:38828,60748:38830,60749:38832,60750:38833,60751:38835,60752:38837,60753:38838,60754:38839,60755:38840,60756:38841,60757:38842,60758:38843,60759:38844,60760:38845,60761:38846,60762:38847,60763:38848,60764:38849,60765:38850,60766:38851,60767:38852,60768:38853,60769:38854,60770:38855,60771:38856,60772:38857,60773:38858,60774:38859,60775:38860,60776:38861,60777:38862,60778:38863,60779:38864,60780:38865,60781:38866,60782:38867,60783:38868,60784:38869,60785:38870,60786:38871,60787:38872,60788:38873,60789:38874,60790:38875,60791:38876,60792:38877,60793:38878,60794:38879,60795:38880,60796:38881,60797:38882,60798:38883,60800:38884,60801:38885,60802:38888,60803:38894,60804:38895,60805:38896,60806:38897,60807:38898,60808:38900,60809:38903,60810:38904,60811:38905,60812:38906,60813:38907,60814:38908,60815:38909,60816:38910,60817:38911,60818:38912,60819:38913,60820:38914,60821:38915,60822:38916,60823:38917,60824:38918,60825:38919,60826:38920,60827:38921,60828:38922,60829:38923,60830:38924,60831:38925,60832:38926,60833:24636,60834:24669,60835:24666,60836:24679,60837:24641,60838:24665,60839:24675,60840:24747,60841:24838,60842:24845,60843:24925,60844:25001,60845:24989,60846:25035,60847:25041,60848:25094,60849:32896,60850:32895,60851:27795,60852:27894,60853:28156,60854:30710,60855:30712,60856:30720,60857:30729,60858:30743,60859:30744,60860:30737,60861:26027,60862:30765,60863:30748,60864:30749,60865:30777,60866:30778,60867:30779,60868:30751,60869:30780,60870:30757,60871:30764,60872:30755,60873:30761,60874:30798,60875:30829,60876:30806,60877:30807,60878:30758,60879:30800,60880:30791,60881:30796,60882:30826,60883:30875,60884:30867,60885:30874,60886:30855,60887:30876,60888:30881,60889:30883,60890:30898,60891:30905,60892:30885,60893:30932,60894:30937,60895:30921,60896:30956,60897:30962,60898:30981,60899:30964,60900:30995,60901:31012,60902:31006,60903:31028,60904:40859,60905:40697,60906:40699,60907:40700,60908:30449,60909:30468,60910:30477,60911:30457,60912:30471,60913:30472,60914:30490,60915:30498,60916:30489,60917:30509,60918:30502,60919:30517,60920:30520,60921:30544,60922:30545,60923:30535,60924:30531,60925:30554,60926:30568,60992:38927,60993:38928,60994:38929,60995:38930,60996:38931,60997:38932,60998:38933,60999:38934,61000:38935,61001:38936,61002:38937,61003:38938,61004:38939,61005:38940,61006:38941,61007:38942,61008:38943,61009:38944,61010:38945,61011:38946,61012:38947,61013:38948,61014:38949,61015:38950,61016:38951,61017:38952,61018:38953,61019:38954,61020:38955,61021:38956,61022:38957,61023:38958,61024:38959,61025:38960,61026:38961,61027:38962,61028:38963,61029:38964,61030:38965,61031:38966,61032:38967,61033:38968,61034:38969,61035:38970,61036:38971,61037:38972,61038:38973,61039:38974,61040:38975,61041:38976,61042:38977,61043:38978,61044:38979,61045:38980,61046:38981,61047:38982,61048:38983,61049:38984,61050:38985,61051:38986,61052:38987,61053:38988,61054:38989,61056:38990,61057:38991,61058:38992,61059:38993,61060:38994,61061:38995,61062:38996,61063:38997,61064:38998,61065:38999,61066:39000,61067:39001,61068:39002,61069:39003,61070:39004,61071:39005,61072:39006,61073:39007,61074:39008,61075:39009,61076:39010,61077:39011,61078:39012,61079:39013,61080:39014,61081:39015,61082:39016,61083:39017,61084:39018,61085:39019,61086:39020,61087:39021,61088:39022,61089:30562,61090:30565,61091:30591,61092:30605,61093:30589,61094:30592,61095:30604,61096:30609,61097:30623,61098:30624,61099:30640,61100:30645,61101:30653,61102:30010,61103:30016,61104:30030,61105:30027,61106:30024,61107:30043,61108:30066,61109:30073,61110:30083,61111:32600,61112:32609,61113:32607,61114:35400,61115:32616,61116:32628,61117:32625,61118:32633,61119:32641,61120:32638,61121:30413,61122:30437,61123:34866,61124:38021,61125:38022,61126:38023,61127:38027,61128:38026,61129:38028,61130:38029,61131:38031,61132:38032,61133:38036,61134:38039,61135:38037,61136:38042,61137:38043,61138:38044,61139:38051,61140:38052,61141:38059,61142:38058,61143:38061,61144:38060,61145:38063,61146:38064,61147:38066,61148:38068,61149:38070,61150:38071,61151:38072,61152:38073,61153:38074,61154:38076,61155:38077,61156:38079,61157:38084,61158:38088,61159:38089,61160:38090,61161:38091,61162:38092,61163:38093,61164:38094,61165:38096,61166:38097,61167:38098,61168:38101,61169:38102,61170:38103,61171:38105,61172:38104,61173:38107,61174:38110,61175:38111,61176:38112,61177:38114,61178:38116,61179:38117,61180:38119,61181:38120,61182:38122,61248:39023,61249:39024,61250:39025,61251:39026,61252:39027,61253:39028,61254:39051,61255:39054,61256:39058,61257:39061,61258:39065,61259:39075,61260:39080,61261:39081,61262:39082,61263:39083,61264:39084,61265:39085,61266:39086,61267:39087,61268:39088,61269:39089,61270:39090,61271:39091,61272:39092,61273:39093,61274:39094,61275:39095,61276:39096,61277:39097,61278:39098,61279:39099,61280:39100,61281:39101,61282:39102,61283:39103,61284:39104,61285:39105,61286:39106,61287:39107,61288:39108,61289:39109,61290:39110,61291:39111,61292:39112,61293:39113,61294:39114,61295:39115,61296:39116,61297:39117,61298:39119,61299:39120,61300:39124,61301:39126,61302:39127,61303:39131,61304:39132,61305:39133,61306:39136,61307:39137,61308:39138,61309:39139,61310:39140,61312:39141,61313:39142,61314:39145,61315:39146,61316:39147,61317:39148,61318:39149,61319:39150,61320:39151,61321:39152,61322:39153,61323:39154,61324:39155,61325:39156,61326:39157,61327:39158,61328:39159,61329:39160,61330:39161,61331:39162,61332:39163,61333:39164,61334:39165,61335:39166,61336:39167,61337:39168,61338:39169,61339:39170,61340:39171,61341:39172,61342:39173,61343:39174,61344:39175,61345:38121,61346:38123,61347:38126,61348:38127,61349:38131,61350:38132,61351:38133,61352:38135,61353:38137,61354:38140,61355:38141,61356:38143,61357:38147,61358:38146,61359:38150,61360:38151,61361:38153,61362:38154,61363:38157,61364:38158,61365:38159,61366:38162,61367:38163,61368:38164,61369:38165,61370:38166,61371:38168,61372:38171,61373:38173,61374:38174,61375:38175,61376:38178,61377:38186,61378:38187,61379:38185,61380:38188,61381:38193,61382:38194,61383:38196,61384:38198,61385:38199,61386:38200,61387:38204,61388:38206,61389:38207,61390:38210,61391:38197,61392:38212,61393:38213,61394:38214,61395:38217,61396:38220,61397:38222,61398:38223,61399:38226,61400:38227,61401:38228,61402:38230,61403:38231,61404:38232,61405:38233,61406:38235,61407:38238,61408:38239,61409:38237,61410:38241,61411:38242,61412:38244,61413:38245,61414:38246,61415:38247,61416:38248,61417:38249,61418:38250,61419:38251,61420:38252,61421:38255,61422:38257,61423:38258,61424:38259,61425:38202,61426:30695,61427:30700,61428:38601,61429:31189,61430:31213,61431:31203,61432:31211,61433:31238,61434:23879,61435:31235,61436:31234,61437:31262,61438:31252,61504:39176,61505:39177,61506:39178,61507:39179,61508:39180,61509:39182,61510:39183,61511:39185,61512:39186,61513:39187,61514:39188,61515:39189,61516:39190,61517:39191,61518:39192,61519:39193,61520:39194,61521:39195,61522:39196,61523:39197,61524:39198,61525:39199,61526:39200,61527:39201,61528:39202,61529:39203,61530:39204,61531:39205,61532:39206,61533:39207,61534:39208,61535:39209,61536:39210,61537:39211,61538:39212,61539:39213,61540:39215,61541:39216,61542:39217,61543:39218,61544:39219,61545:39220,61546:39221,61547:39222,61548:39223,61549:39224,61550:39225,61551:39226,61552:39227,61553:39228,61554:39229,61555:39230,61556:39231,61557:39232,61558:39233,61559:39234,61560:39235,61561:39236,61562:39237,61563:39238,61564:39239,61565:39240,61566:39241,61568:39242,61569:39243,61570:39244,61571:39245,61572:39246,61573:39247,61574:39248,61575:39249,61576:39250,61577:39251,61578:39254,61579:39255,61580:39256,61581:39257,61582:39258,61583:39259,61584:39260,61585:39261,61586:39262,61587:39263,61588:39264,61589:39265,61590:39266,61591:39268,61592:39270,61593:39283,61594:39288,61595:39289,61596:39291,61597:39294,61598:39298,61599:39299,61600:39305,61601:31289,61602:31287,61603:31313,61604:40655,61605:39333,61606:31344,61607:30344,61608:30350,61609:30355,61610:30361,61611:30372,61612:29918,61613:29920,61614:29996,61615:40480,61616:40482,61617:40488,61618:40489,61619:40490,61620:40491,61621:40492,61622:40498,61623:40497,61624:40502,61625:40504,61626:40503,61627:40505,61628:40506,61629:40510,61630:40513,61631:40514,61632:40516,61633:40518,61634:40519,61635:40520,61636:40521,61637:40523,61638:40524,61639:40526,61640:40529,61641:40533,61642:40535,61643:40538,61644:40539,61645:40540,61646:40542,61647:40547,61648:40550,61649:40551,61650:40552,61651:40553,61652:40554,61653:40555,61654:40556,61655:40561,61656:40557,61657:40563,61658:30098,61659:30100,61660:30102,61661:30112,61662:30109,61663:30124,61664:30115,61665:30131,61666:30132,61667:30136,61668:30148,61669:30129,61670:30128,61671:30147,61672:30146,61673:30166,61674:30157,61675:30179,61676:30184,61677:30182,61678:30180,61679:30187,61680:30183,61681:30211,61682:30193,61683:30204,61684:30207,61685:30224,61686:30208,61687:30213,61688:30220,61689:30231,61690:30218,61691:30245,61692:30232,61693:30229,61694:30233,61760:39308,61761:39310,61762:39322,61763:39323,61764:39324,61765:39325,61766:39326,61767:39327,61768:39328,61769:39329,61770:39330,61771:39331,61772:39332,61773:39334,61774:39335,61775:39337,61776:39338,61777:39339,61778:39340,61779:39341,61780:39342,61781:39343,61782:39344,61783:39345,61784:39346,61785:39347,61786:39348,61787:39349,61788:39350,61789:39351,61790:39352,61791:39353,61792:39354,61793:39355,61794:39356,61795:39357,61796:39358,61797:39359,61798:39360,61799:39361,61800:39362,61801:39363,61802:39364,61803:39365,61804:39366,61805:39367,61806:39368,61807:39369,61808:39370,61809:39371,61810:39372,61811:39373,61812:39374,61813:39375,61814:39376,61815:39377,61816:39378,61817:39379,61818:39380,61819:39381,61820:39382,61821:39383,61822:39384,61824:39385,61825:39386,61826:39387,61827:39388,61828:39389,61829:39390,61830:39391,61831:39392,61832:39393,61833:39394,61834:39395,61835:39396,61836:39397,61837:39398,61838:39399,61839:39400,61840:39401,61841:39402,61842:39403,61843:39404,61844:39405,61845:39406,61846:39407,61847:39408,61848:39409,61849:39410,61850:39411,61851:39412,61852:39413,61853:39414,61854:39415,61855:39416,61856:39417,61857:30235,61858:30268,61859:30242,61860:30240,61861:30272,61862:30253,61863:30256,61864:30271,61865:30261,61866:30275,61867:30270,61868:30259,61869:30285,61870:30302,61871:30292,61872:30300,61873:30294,61874:30315,61875:30319,61876:32714,61877:31462,61878:31352,61879:31353,61880:31360,61881:31366,61882:31368,61883:31381,61884:31398,61885:31392,61886:31404,61887:31400,61888:31405,61889:31411,61890:34916,61891:34921,61892:34930,61893:34941,61894:34943,61895:34946,61896:34978,61897:35014,61898:34999,61899:35004,61900:35017,61901:35042,61902:35022,61903:35043,61904:35045,61905:35057,61906:35098,61907:35068,61908:35048,61909:35070,61910:35056,61911:35105,61912:35097,61913:35091,61914:35099,61915:35082,61916:35124,61917:35115,61918:35126,61919:35137,61920:35174,61921:35195,61922:30091,61923:32997,61924:30386,61925:30388,61926:30684,61927:32786,61928:32788,61929:32790,61930:32796,61931:32800,61932:32802,61933:32805,61934:32806,61935:32807,61936:32809,61937:32808,61938:32817,61939:32779,61940:32821,61941:32835,61942:32838,61943:32845,61944:32850,61945:32873,61946:32881,61947:35203,61948:39032,61949:39040,61950:39043,62016:39418,62017:39419,62018:39420,62019:39421,62020:39422,62021:39423,62022:39424,62023:39425,62024:39426,62025:39427,62026:39428,62027:39429,62028:39430,62029:39431,62030:39432,62031:39433,62032:39434,62033:39435,62034:39436,62035:39437,62036:39438,62037:39439,62038:39440,62039:39441,62040:39442,62041:39443,62042:39444,62043:39445,62044:39446,62045:39447,62046:39448,62047:39449,62048:39450,62049:39451,62050:39452,62051:39453,62052:39454,62053:39455,62054:39456,62055:39457,62056:39458,62057:39459,62058:39460,62059:39461,62060:39462,62061:39463,62062:39464,62063:39465,62064:39466,62065:39467,62066:39468,62067:39469,62068:39470,62069:39471,62070:39472,62071:39473,62072:39474,62073:39475,62074:39476,62075:39477,62076:39478,62077:39479,62078:39480,62080:39481,62081:39482,62082:39483,62083:39484,62084:39485,62085:39486,62086:39487,62087:39488,62088:39489,62089:39490,62090:39491,62091:39492,62092:39493,62093:39494,62094:39495,62095:39496,62096:39497,62097:39498,62098:39499,62099:39500,62100:39501,62101:39502,62102:39503,62103:39504,62104:39505,62105:39506,62106:39507,62107:39508,62108:39509,62109:39510,62110:39511,62111:39512,62112:39513,62113:39049,62114:39052,62115:39053,62116:39055,62117:39060,62118:39066,62119:39067,62120:39070,62121:39071,62122:39073,62123:39074,62124:39077,62125:39078,62126:34381,62127:34388,62128:34412,62129:34414,62130:34431,62131:34426,62132:34428,62133:34427,62134:34472,62135:34445,62136:34443,62137:34476,62138:34461,62139:34471,62140:34467,62141:34474,62142:34451,62143:34473,62144:34486,62145:34500,62146:34485,62147:34510,62148:34480,62149:34490,62150:34481,62151:34479,62152:34505,62153:34511,62154:34484,62155:34537,62156:34545,62157:34546,62158:34541,62159:34547,62160:34512,62161:34579,62162:34526,62163:34548,62164:34527,62165:34520,62166:34513,62167:34563,62168:34567,62169:34552,62170:34568,62171:34570,62172:34573,62173:34569,62174:34595,62175:34619,62176:34590,62177:34597,62178:34606,62179:34586,62180:34622,62181:34632,62182:34612,62183:34609,62184:34601,62185:34615,62186:34623,62187:34690,62188:34594,62189:34685,62190:34686,62191:34683,62192:34656,62193:34672,62194:34636,62195:34670,62196:34699,62197:34643,62198:34659,62199:34684,62200:34660,62201:34649,62202:34661,62203:34707,62204:34735,62205:34728,62206:34770,62272:39514,62273:39515,62274:39516,62275:39517,62276:39518,62277:39519,62278:39520,62279:39521,62280:39522,62281:39523,62282:39524,62283:39525,62284:39526,62285:39527,62286:39528,62287:39529,62288:39530,62289:39531,62290:39538,62291:39555,62292:39561,62293:39565,62294:39566,62295:39572,62296:39573,62297:39577,62298:39590,62299:39593,62300:39594,62301:39595,62302:39596,62303:39597,62304:39598,62305:39599,62306:39602,62307:39603,62308:39604,62309:39605,62310:39609,62311:39611,62312:39613,62313:39614,62314:39615,62315:39619,62316:39620,62317:39622,62318:39623,62319:39624,62320:39625,62321:39626,62322:39629,62323:39630,62324:39631,62325:39632,62326:39634,62327:39636,62328:39637,62329:39638,62330:39639,62331:39641,62332:39642,62333:39643,62334:39644,62336:39645,62337:39646,62338:39648,62339:39650,62340:39651,62341:39652,62342:39653,62343:39655,62344:39656,62345:39657,62346:39658,62347:39660,62348:39662,62349:39664,62350:39665,62351:39666,62352:39667,62353:39668,62354:39669,62355:39670,62356:39671,62357:39672,62358:39674,62359:39676,62360:39677,62361:39678,62362:39679,62363:39680,62364:39681,62365:39682,62366:39684,62367:39685,62368:39686,62369:34758,62370:34696,62371:34693,62372:34733,62373:34711,62374:34691,62375:34731,62376:34789,62377:34732,62378:34741,62379:34739,62380:34763,62381:34771,62382:34749,62383:34769,62384:34752,62385:34762,62386:34779,62387:34794,62388:34784,62389:34798,62390:34838,62391:34835,62392:34814,62393:34826,62394:34843,62395:34849,62396:34873,62397:34876,62398:32566,62399:32578,62400:32580,62401:32581,62402:33296,62403:31482,62404:31485,62405:31496,62406:31491,62407:31492,62408:31509,62409:31498,62410:31531,62411:31503,62412:31559,62413:31544,62414:31530,62415:31513,62416:31534,62417:31537,62418:31520,62419:31525,62420:31524,62421:31539,62422:31550,62423:31518,62424:31576,62425:31578,62426:31557,62427:31605,62428:31564,62429:31581,62430:31584,62431:31598,62432:31611,62433:31586,62434:31602,62435:31601,62436:31632,62437:31654,62438:31655,62439:31672,62440:31660,62441:31645,62442:31656,62443:31621,62444:31658,62445:31644,62446:31650,62447:31659,62448:31668,62449:31697,62450:31681,62451:31692,62452:31709,62453:31706,62454:31717,62455:31718,62456:31722,62457:31756,62458:31742,62459:31740,62460:31759,62461:31766,62462:31755,62528:39687,62529:39689,62530:39690,62531:39691,62532:39692,62533:39693,62534:39694,62535:39696,62536:39697,62537:39698,62538:39700,62539:39701,62540:39702,62541:39703,62542:39704,62543:39705,62544:39706,62545:39707,62546:39708,62547:39709,62548:39710,62549:39712,62550:39713,62551:39714,62552:39716,62553:39717,62554:39718,62555:39719,62556:39720,62557:39721,62558:39722,62559:39723,62560:39724,62561:39725,62562:39726,62563:39728,62564:39729,62565:39731,62566:39732,62567:39733,62568:39734,62569:39735,62570:39736,62571:39737,62572:39738,62573:39741,62574:39742,62575:39743,62576:39744,62577:39750,62578:39754,62579:39755,62580:39756,62581:39758,62582:39760,62583:39762,62584:39763,62585:39765,62586:39766,62587:39767,62588:39768,62589:39769,62590:39770,62592:39771,62593:39772,62594:39773,62595:39774,62596:39775,62597:39776,62598:39777,62599:39778,62600:39779,62601:39780,62602:39781,62603:39782,62604:39783,62605:39784,62606:39785,62607:39786,62608:39787,62609:39788,62610:39789,62611:39790,62612:39791,62613:39792,62614:39793,62615:39794,62616:39795,62617:39796,62618:39797,62619:39798,62620:39799,62621:39800,62622:39801,62623:39802,62624:39803,62625:31775,62626:31786,62627:31782,62628:31800,62629:31809,62630:31808,62631:33278,62632:33281,62633:33282,62634:33284,62635:33260,62636:34884,62637:33313,62638:33314,62639:33315,62640:33325,62641:33327,62642:33320,62643:33323,62644:33336,62645:33339,62646:33331,62647:33332,62648:33342,62649:33348,62650:33353,62651:33355,62652:33359,62653:33370,62654:33375,62655:33384,62656:34942,62657:34949,62658:34952,62659:35032,62660:35039,62661:35166,62662:32669,62663:32671,62664:32679,62665:32687,62666:32688,62667:32690,62668:31868,62669:25929,62670:31889,62671:31901,62672:31900,62673:31902,62674:31906,62675:31922,62676:31932,62677:31933,62678:31937,62679:31943,62680:31948,62681:31949,62682:31944,62683:31941,62684:31959,62685:31976,62686:33390,62687:26280,62688:32703,62689:32718,62690:32725,62691:32741,62692:32737,62693:32742,62694:32745,62695:32750,62696:32755,62697:31992,62698:32119,62699:32166,62700:32174,62701:32327,62702:32411,62703:40632,62704:40628,62705:36211,62706:36228,62707:36244,62708:36241,62709:36273,62710:36199,62711:36205,62712:35911,62713:35913,62714:37194,62715:37200,62716:37198,62717:37199,62718:37220,62784:39804,62785:39805,62786:39806,62787:39807,62788:39808,62789:39809,62790:39810,62791:39811,62792:39812,62793:39813,62794:39814,62795:39815,62796:39816,62797:39817,62798:39818,62799:39819,62800:39820,62801:39821,62802:39822,62803:39823,62804:39824,62805:39825,62806:39826,62807:39827,62808:39828,62809:39829,62810:39830,62811:39831,62812:39832,62813:39833,62814:39834,62815:39835,62816:39836,62817:39837,62818:39838,62819:39839,62820:39840,62821:39841,62822:39842,62823:39843,62824:39844,62825:39845,62826:39846,62827:39847,62828:39848,62829:39849,62830:39850,62831:39851,62832:39852,62833:39853,62834:39854,62835:39855,62836:39856,62837:39857,62838:39858,62839:39859,62840:39860,62841:39861,62842:39862,62843:39863,62844:39864,62845:39865,62846:39866,62848:39867,62849:39868,62850:39869,62851:39870,62852:39871,62853:39872,62854:39873,62855:39874,62856:39875,62857:39876,62858:39877,62859:39878,62860:39879,62861:39880,62862:39881,62863:39882,62864:39883,62865:39884,62866:39885,62867:39886,62868:39887,62869:39888,62870:39889,62871:39890,62872:39891,62873:39892,62874:39893,62875:39894,62876:39895,62877:39896,62878:39897,62879:39898,62880:39899,62881:37218,62882:37217,62883:37232,62884:37225,62885:37231,62886:37245,62887:37246,62888:37234,62889:37236,62890:37241,62891:37260,62892:37253,62893:37264,62894:37261,62895:37265,62896:37282,62897:37283,62898:37290,62899:37293,62900:37294,62901:37295,62902:37301,62903:37300,62904:37306,62905:35925,62906:40574,62907:36280,62908:36331,62909:36357,62910:36441,62911:36457,62912:36277,62913:36287,62914:36284,62915:36282,62916:36292,62917:36310,62918:36311,62919:36314,62920:36318,62921:36302,62922:36303,62923:36315,62924:36294,62925:36332,62926:36343,62927:36344,62928:36323,62929:36345,62930:36347,62931:36324,62932:36361,62933:36349,62934:36372,62935:36381,62936:36383,62937:36396,62938:36398,62939:36387,62940:36399,62941:36410,62942:36416,62943:36409,62944:36405,62945:36413,62946:36401,62947:36425,62948:36417,62949:36418,62950:36433,62951:36434,62952:36426,62953:36464,62954:36470,62955:36476,62956:36463,62957:36468,62958:36485,62959:36495,62960:36500,62961:36496,62962:36508,62963:36510,62964:35960,62965:35970,62966:35978,62967:35973,62968:35992,62969:35988,62970:26011,62971:35286,62972:35294,62973:35290,62974:35292,63040:39900,63041:39901,63042:39902,63043:39903,63044:39904,63045:39905,63046:39906,63047:39907,63048:39908,63049:39909,63050:39910,63051:39911,63052:39912,63053:39913,63054:39914,63055:39915,63056:39916,63057:39917,63058:39918,63059:39919,63060:39920,63061:39921,63062:39922,63063:39923,63064:39924,63065:39925,63066:39926,63067:39927,63068:39928,63069:39929,63070:39930,63071:39931,63072:39932,63073:39933,63074:39934,63075:39935,63076:39936,63077:39937,63078:39938,63079:39939,63080:39940,63081:39941,63082:39942,63083:39943,63084:39944,63085:39945,63086:39946,63087:39947,63088:39948,63089:39949,63090:39950,63091:39951,63092:39952,63093:39953,63094:39954,63095:39955,63096:39956,63097:39957,63098:39958,63099:39959,63100:39960,63101:39961,63102:39962,63104:39963,63105:39964,63106:39965,63107:39966,63108:39967,63109:39968,63110:39969,63111:39970,63112:39971,63113:39972,63114:39973,63115:39974,63116:39975,63117:39976,63118:39977,63119:39978,63120:39979,63121:39980,63122:39981,63123:39982,63124:39983,63125:39984,63126:39985,63127:39986,63128:39987,63129:39988,63130:39989,63131:39990,63132:39991,63133:39992,63134:39993,63135:39994,63136:39995,63137:35301,63138:35307,63139:35311,63140:35390,63141:35622,63142:38739,63143:38633,63144:38643,63145:38639,63146:38662,63147:38657,63148:38664,63149:38671,63150:38670,63151:38698,63152:38701,63153:38704,63154:38718,63155:40832,63156:40835,63157:40837,63158:40838,63159:40839,63160:40840,63161:40841,63162:40842,63163:40844,63164:40702,63165:40715,63166:40717,63167:38585,63168:38588,63169:38589,63170:38606,63171:38610,63172:30655,63173:38624,63174:37518,63175:37550,63176:37576,63177:37694,63178:37738,63179:37834,63180:37775,63181:37950,63182:37995,63183:40063,63184:40066,63185:40069,63186:40070,63187:40071,63188:40072,63189:31267,63190:40075,63191:40078,63192:40080,63193:40081,63194:40082,63195:40084,63196:40085,63197:40090,63198:40091,63199:40094,63200:40095,63201:40096,63202:40097,63203:40098,63204:40099,63205:40101,63206:40102,63207:40103,63208:40104,63209:40105,63210:40107,63211:40109,63212:40110,63213:40112,63214:40113,63215:40114,63216:40115,63217:40116,63218:40117,63219:40118,63220:40119,63221:40122,63222:40123,63223:40124,63224:40125,63225:40132,63226:40133,63227:40134,63228:40135,63229:40138,63230:40139,63296:39996,63297:39997,63298:39998,63299:39999,63300:40000,63301:40001,63302:40002,63303:40003,63304:40004,63305:40005,63306:40006,63307:40007,63308:40008,63309:40009,63310:40010,63311:40011,63312:40012,63313:40013,63314:40014,63315:40015,63316:40016,63317:40017,63318:40018,63319:40019,63320:40020,63321:40021,63322:40022,63323:40023,63324:40024,63325:40025,63326:40026,63327:40027,63328:40028,63329:40029,63330:40030,63331:40031,63332:40032,63333:40033,63334:40034,63335:40035,63336:40036,63337:40037,63338:40038,63339:40039,63340:40040,63341:40041,63342:40042,63343:40043,63344:40044,63345:40045,63346:40046,63347:40047,63348:40048,63349:40049,63350:40050,63351:40051,63352:40052,63353:40053,63354:40054,63355:40055,63356:40056,63357:40057,63358:40058,63360:40059,63361:40061,63362:40062,63363:40064,63364:40067,63365:40068,63366:40073,63367:40074,63368:40076,63369:40079,63370:40083,63371:40086,63372:40087,63373:40088,63374:40089,63375:40093,63376:40106,63377:40108,63378:40111,63379:40121,63380:40126,63381:40127,63382:40128,63383:40129,63384:40130,63385:40136,63386:40137,63387:40145,63388:40146,63389:40154,63390:40155,63391:40160,63392:40161,63393:40140,63394:40141,63395:40142,63396:40143,63397:40144,63398:40147,63399:40148,63400:40149,63401:40151,63402:40152,63403:40153,63404:40156,63405:40157,63406:40159,63407:40162,63408:38780,63409:38789,63410:38801,63411:38802,63412:38804,63413:38831,63414:38827,63415:38819,63416:38834,63417:38836,63418:39601,63419:39600,63420:39607,63421:40536,63422:39606,63423:39610,63424:39612,63425:39617,63426:39616,63427:39621,63428:39618,63429:39627,63430:39628,63431:39633,63432:39749,63433:39747,63434:39751,63435:39753,63436:39752,63437:39757,63438:39761,63439:39144,63440:39181,63441:39214,63442:39253,63443:39252,63444:39647,63445:39649,63446:39654,63447:39663,63448:39659,63449:39675,63450:39661,63451:39673,63452:39688,63453:39695,63454:39699,63455:39711,63456:39715,63457:40637,63458:40638,63459:32315,63460:40578,63461:40583,63462:40584,63463:40587,63464:40594,63465:37846,63466:40605,63467:40607,63468:40667,63469:40668,63470:40669,63471:40672,63472:40671,63473:40674,63474:40681,63475:40679,63476:40677,63477:40682,63478:40687,63479:40738,63480:40748,63481:40751,63482:40761,63483:40759,63484:40765,63485:40766,63486:40772,63552:40163,63553:40164,63554:40165,63555:40166,63556:40167,63557:40168,63558:40169,63559:40170,63560:40171,63561:40172,63562:40173,63563:40174,63564:40175,63565:40176,63566:40177,63567:40178,63568:40179,63569:40180,63570:40181,63571:40182,63572:40183,63573:40184,63574:40185,63575:40186,63576:40187,63577:40188,63578:40189,63579:40190,63580:40191,63581:40192,63582:40193,63583:40194,63584:40195,63585:40196,63586:40197,63587:40198,63588:40199,63589:40200,63590:40201,63591:40202,63592:40203,63593:40204,63594:40205,63595:40206,63596:40207,63597:40208,63598:40209,63599:40210,63600:40211,63601:40212,63602:40213,63603:40214,63604:40215,63605:40216,63606:40217,63607:40218,63608:40219,63609:40220,63610:40221,63611:40222,63612:40223,63613:40224,63614:40225,63616:40226,63617:40227,63618:40228,63619:40229,63620:40230,63621:40231,63622:40232,63623:40233,63624:40234,63625:40235,63626:40236,63627:40237,63628:40238,63629:40239,63630:40240,63631:40241,63632:40242,63633:40243,63634:40244,63635:40245,63636:40246,63637:40247,63638:40248,63639:40249,63640:40250,63641:40251,63642:40252,63643:40253,63644:40254,63645:40255,63646:40256,63647:40257,63648:40258,63649:57908,63650:57909,63651:57910,63652:57911,63653:57912,63654:57913,63655:57914,63656:57915,63657:57916,63658:57917,63659:57918,63660:57919,63661:57920,63662:57921,63663:57922,63664:57923,63665:57924,63666:57925,63667:57926,63668:57927,63669:57928,63670:57929,63671:57930,63672:57931,63673:57932,63674:57933,63675:57934,63676:57935,63677:57936,63678:57937,63679:57938,63680:57939,63681:57940,63682:57941,63683:57942,63684:57943,63685:57944,63686:57945,63687:57946,63688:57947,63689:57948,63690:57949,63691:57950,63692:57951,63693:57952,63694:57953,63695:57954,63696:57955,63697:57956,63698:57957,63699:57958,63700:57959,63701:57960,63702:57961,63703:57962,63704:57963,63705:57964,63706:57965,63707:57966,63708:57967,63709:57968,63710:57969,63711:57970,63712:57971,63713:57972,63714:57973,63715:57974,63716:57975,63717:57976,63718:57977,63719:57978,63720:57979,63721:57980,63722:57981,63723:57982,63724:57983,63725:57984,63726:57985,63727:57986,63728:57987,63729:57988,63730:57989,63731:57990,63732:57991,63733:57992,63734:57993,63735:57994,63736:57995,63737:57996,63738:57997,63739:57998,63740:57999,63741:58000,63742:58001,63808:40259,63809:40260,63810:40261,63811:40262,63812:40263,63813:40264,63814:40265,63815:40266,63816:40267,63817:40268,63818:40269,63819:40270,63820:40271,63821:40272,63822:40273,63823:40274,63824:40275,63825:40276,63826:40277,63827:40278,63828:40279,63829:40280,63830:40281,63831:40282,63832:40283,63833:40284,63834:40285,63835:40286,63836:40287,63837:40288,63838:40289,63839:40290,63840:40291,63841:40292,63842:40293,63843:40294,63844:40295,63845:40296,63846:40297,63847:40298,63848:40299,63849:40300,63850:40301,63851:40302,63852:40303,63853:40304,63854:40305,63855:40306,63856:40307,63857:40308,63858:40309,63859:40310,63860:40311,63861:40312,63862:40313,63863:40314,63864:40315,63865:40316,63866:40317,63867:40318,63868:40319,63869:40320,63870:40321,63872:40322,63873:40323,63874:40324,63875:40325,63876:40326,63877:40327,63878:40328,63879:40329,63880:40330,63881:40331,63882:40332,63883:40333,63884:40334,63885:40335,63886:40336,63887:40337,63888:40338,63889:40339,63890:40340,63891:40341,63892:40342,63893:40343,63894:40344,63895:40345,63896:40346,63897:40347,63898:40348,63899:40349,63900:40350,63901:40351,63902:40352,63903:40353,63904:40354,63905:58002,63906:58003,63907:58004,63908:58005,63909:58006,63910:58007,63911:58008,63912:58009,63913:58010,63914:58011,63915:58012,63916:58013,63917:58014,63918:58015,63919:58016,63920:58017,63921:58018,63922:58019,63923:58020,63924:58021,63925:58022,63926:58023,63927:58024,63928:58025,63929:58026,63930:58027,63931:58028,63932:58029,63933:58030,63934:58031,63935:58032,63936:58033,63937:58034,63938:58035,63939:58036,63940:58037,63941:58038,63942:58039,63943:58040,63944:58041,63945:58042,63946:58043,63947:58044,63948:58045,63949:58046,63950:58047,63951:58048,63952:58049,63953:58050,63954:58051,63955:58052,63956:58053,63957:58054,63958:58055,63959:58056,63960:58057,63961:58058,63962:58059,63963:58060,63964:58061,63965:58062,63966:58063,63967:58064,63968:58065,63969:58066,63970:58067,63971:58068,63972:58069,63973:58070,63974:58071,63975:58072,63976:58073,63977:58074,63978:58075,63979:58076,63980:58077,63981:58078,63982:58079,63983:58080,63984:58081,63985:58082,63986:58083,63987:58084,63988:58085,63989:58086,63990:58087,63991:58088,63992:58089,63993:58090,63994:58091,63995:58092,63996:58093,63997:58094,63998:58095,64064:40355,64065:40356,64066:40357,64067:40358,64068:40359,64069:40360,64070:40361,64071:40362,64072:40363,64073:40364,64074:40365,64075:40366,64076:40367,64077:40368,64078:40369,64079:40370,64080:40371,64081:40372,64082:40373,64083:40374,64084:40375,64085:40376,64086:40377,64087:40378,64088:40379,64089:40380,64090:40381,64091:40382,64092:40383,64093:40384,64094:40385,64095:40386,64096:40387,64097:40388,64098:40389,64099:40390,64100:40391,64101:40392,64102:40393,64103:40394,64104:40395,64105:40396,64106:40397,64107:40398,64108:40399,64109:40400,64110:40401,64111:40402,64112:40403,64113:40404,64114:40405,64115:40406,64116:40407,64117:40408,64118:40409,64119:40410,64120:40411,64121:40412,64122:40413,64123:40414,64124:40415,64125:40416,64126:40417,64128:40418,64129:40419,64130:40420,64131:40421,64132:40422,64133:40423,64134:40424,64135:40425,64136:40426,64137:40427,64138:40428,64139:40429,64140:40430,64141:40431,64142:40432,64143:40433,64144:40434,64145:40435,64146:40436,64147:40437,64148:40438,64149:40439,64150:40440,64151:40441,64152:40442,64153:40443,64154:40444,64155:40445,64156:40446,64157:40447,64158:40448,64159:40449,64160:40450,64161:58096,64162:58097,64163:58098,64164:58099,64165:58100,64166:58101,64167:58102,64168:58103,64169:58104,64170:58105,64171:58106,64172:58107,64173:58108,64174:58109,64175:58110,64176:58111,64177:58112,64178:58113,64179:58114,64180:58115,64181:58116,64182:58117,64183:58118,64184:58119,64185:58120,64186:58121,64187:58122,64188:58123,64189:58124,64190:58125,64191:58126,64192:58127,64193:58128,64194:58129,64195:58130,64196:58131,64197:58132,64198:58133,64199:58134,64200:58135,64201:58136,64202:58137,64203:58138,64204:58139,64205:58140,64206:58141,64207:58142,64208:58143,64209:58144,64210:58145,64211:58146,64212:58147,64213:58148,64214:58149,64215:58150,64216:58151,64217:58152,64218:58153,64219:58154,64220:58155,64221:58156,64222:58157,64223:58158,64224:58159,64225:58160,64226:58161,64227:58162,64228:58163,64229:58164,64230:58165,64231:58166,64232:58167,64233:58168,64234:58169,64235:58170,64236:58171,64237:58172,64238:58173,64239:58174,64240:58175,64241:58176,64242:58177,64243:58178,64244:58179,64245:58180,64246:58181,64247:58182,64248:58183,64249:58184,64250:58185,64251:58186,64252:58187,64253:58188,64254:58189,64320:40451,64321:40452,64322:40453,64323:40454,64324:40455,64325:40456,64326:40457,64327:40458,64328:40459,64329:40460,64330:40461,64331:40462,64332:40463,64333:40464,64334:40465,64335:40466,64336:40467,64337:40468,64338:40469,64339:40470,64340:40471,64341:40472,64342:40473,64343:40474,64344:40475,64345:40476,64346:40477,64347:40478,64348:40484,64349:40487,64350:40494,64351:40496,64352:40500,64353:40507,64354:40508,64355:40512,64356:40525,64357:40528,64358:40530,64359:40531,64360:40532,64361:40534,64362:40537,64363:40541,64364:40543,64365:40544,64366:40545,64367:40546,64368:40549,64369:40558,64370:40559,64371:40562,64372:40564,64373:40565,64374:40566,64375:40567,64376:40568,64377:40569,64378:40570,64379:40571,64380:40572,64381:40573,64382:40576,64384:40577,64385:40579,64386:40580,64387:40581,64388:40582,64389:40585,64390:40586,64391:40588,64392:40589,64393:40590,64394:40591,64395:40592,64396:40593,64397:40596,64398:40597,64399:40598,64400:40599,64401:40600,64402:40601,64403:40602,64404:40603,64405:40604,64406:40606,64407:40608,64408:40609,64409:40610,64410:40611,64411:40612,64412:40613,64413:40615,64414:40616,64415:40617,64416:40618,64417:58190,64418:58191,64419:58192,64420:58193,64421:58194,64422:58195,64423:58196,64424:58197,64425:58198,64426:58199,64427:58200,64428:58201,64429:58202,64430:58203,64431:58204,64432:58205,64433:58206,64434:58207,64435:58208,64436:58209,64437:58210,64438:58211,64439:58212,64440:58213,64441:58214,64442:58215,64443:58216,64444:58217,64445:58218,64446:58219,64447:58220,64448:58221,64449:58222,64450:58223,64451:58224,64452:58225,64453:58226,64454:58227,64455:58228,64456:58229,64457:58230,64458:58231,64459:58232,64460:58233,64461:58234,64462:58235,64463:58236,64464:58237,64465:58238,64466:58239,64467:58240,64468:58241,64469:58242,64470:58243,64471:58244,64472:58245,64473:58246,64474:58247,64475:58248,64476:58249,64477:58250,64478:58251,64479:58252,64480:58253,64481:58254,64482:58255,64483:58256,64484:58257,64485:58258,64486:58259,64487:58260,64488:58261,64489:58262,64490:58263,64491:58264,64492:58265,64493:58266,64494:58267,64495:58268,64496:58269,64497:58270,64498:58271,64499:58272,64500:58273,64501:58274,64502:58275,64503:58276,64504:58277,64505:58278,64506:58279,64507:58280,64508:58281,64509:58282,64510:58283,64576:40619,64577:40620,64578:40621,64579:40622,64580:40623,64581:40624,64582:40625,64583:40626,64584:40627,64585:40629,64586:40630,64587:40631,64588:40633,64589:40634,64590:40636,64591:40639,64592:40640,64593:40641,64594:40642,64595:40643,64596:40645,64597:40646,64598:40647,64599:40648,64600:40650,64601:40651,64602:40652,64603:40656,64604:40658,64605:40659,64606:40661,64607:40662,64608:40663,64609:40665,64610:40666,64611:40670,64612:40673,64613:40675,64614:40676,64615:40678,64616:40680,64617:40683,64618:40684,64619:40685,64620:40686,64621:40688,64622:40689,64623:40690,64624:40691,64625:40692,64626:40693,64627:40694,64628:40695,64629:40696,64630:40698,64631:40701,64632:40703,64633:40704,64634:40705,64635:40706,64636:40707,64637:40708,64638:40709,64640:40710,64641:40711,64642:40712,64643:40713,64644:40714,64645:40716,64646:40719,64647:40721,64648:40722,64649:40724,64650:40725,64651:40726,64652:40728,64653:40730,64654:40731,64655:40732,64656:40733,64657:40734,64658:40735,64659:40737,64660:40739,64661:40740,64662:40741,64663:40742,64664:40743,64665:40744,64666:40745,64667:40746,64668:40747,64669:40749,64670:40750,64671:40752,64672:40753,64673:58284,64674:58285,64675:58286,64676:58287,64677:58288,64678:58289,64679:58290,64680:58291,64681:58292,64682:58293,64683:58294,64684:58295,64685:58296,64686:58297,64687:58298,64688:58299,64689:58300,64690:58301,64691:58302,64692:58303,64693:58304,64694:58305,64695:58306,64696:58307,64697:58308,64698:58309,64699:58310,64700:58311,64701:58312,64702:58313,64703:58314,64704:58315,64705:58316,64706:58317,64707:58318,64708:58319,64709:58320,64710:58321,64711:58322,64712:58323,64713:58324,64714:58325,64715:58326,64716:58327,64717:58328,64718:58329,64719:58330,64720:58331,64721:58332,64722:58333,64723:58334,64724:58335,64725:58336,64726:58337,64727:58338,64728:58339,64729:58340,64730:58341,64731:58342,64732:58343,64733:58344,64734:58345,64735:58346,64736:58347,64737:58348,64738:58349,64739:58350,64740:58351,64741:58352,64742:58353,64743:58354,64744:58355,64745:58356,64746:58357,64747:58358,64748:58359,64749:58360,64750:58361,64751:58362,64752:58363,64753:58364,64754:58365,64755:58366,64756:58367,64757:58368,64758:58369,64759:58370,64760:58371,64761:58372,64762:58373,64763:58374,64764:58375,64765:58376,64766:58377,64832:40754,64833:40755,64834:40756,64835:40757,64836:40758,64837:40760,64838:40762,64839:40764,64840:40767,64841:40768,64842:40769,64843:40770,64844:40771,64845:40773,64846:40774,64847:40775,64848:40776,64849:40777,64850:40778,64851:40779,64852:40780,64853:40781,64854:40782,64855:40783,64856:40786,64857:40787,64858:40788,64859:40789,64860:40790,64861:40791,64862:40792,64863:40793,64864:40794,64865:40795,64866:40796,64867:40797,64868:40798,64869:40799,64870:40800,64871:40801,64872:40802,64873:40803,64874:40804,64875:40805,64876:40806,64877:40807,64878:40808,64879:40809,64880:40810,64881:40811,64882:40812,64883:40813,64884:40814,64885:40815,64886:40816,64887:40817,64888:40818,64889:40819,64890:40820,64891:40821,64892:40822,64893:40823,64894:40824,64896:40825,64897:40826,64898:40827,64899:40828,64900:40829,64901:40830,64902:40833,64903:40834,64904:40845,64905:40846,64906:40847,64907:40848,64908:40849,64909:40850,64910:40851,64911:40852,64912:40853,64913:40854,64914:40855,64915:40856,64916:40860,64917:40861,64918:40862,64919:40865,64920:40866,64921:40867,64922:40868,64923:40869,64924:63788,64925:63865,64926:63893,64927:63975,64928:63985,64929:58378,64930:58379,64931:58380,64932:58381,64933:58382,64934:58383,64935:58384,64936:58385,64937:58386,64938:58387,64939:58388,64940:58389,64941:58390,64942:58391,64943:58392,64944:58393,64945:58394,64946:58395,64947:58396,64948:58397,64949:58398,64950:58399,64951:58400,64952:58401,64953:58402,64954:58403,64955:58404,64956:58405,64957:58406,64958:58407,64959:58408,64960:58409,64961:58410,64962:58411,64963:58412,64964:58413,64965:58414,64966:58415,64967:58416,64968:58417,64969:58418,64970:58419,64971:58420,64972:58421,64973:58422,64974:58423,64975:58424,64976:58425,64977:58426,64978:58427,64979:58428,64980:58429,64981:58430,64982:58431,64983:58432,64984:58433,64985:58434,64986:58435,64987:58436,64988:58437,64989:58438,64990:58439,64991:58440,64992:58441,64993:58442,64994:58443,64995:58444,64996:58445,64997:58446,64998:58447,64999:58448,65000:58449,65001:58450,65002:58451,65003:58452,65004:58453,65005:58454,65006:58455,65007:58456,65008:58457,65009:58458,65010:58459,65011:58460,65012:58461,65013:58462,65014:58463,65015:58464,65016:58465,65017:58466,65018:58467,65019:58468,65020:58469,65021:58470,65022:58471,65088:64012,65089:64013,65090:64014,65091:64015,65092:64017,65093:64019,65094:64020,65095:64024,65096:64031,65097:64032,65098:64033,65099:64035,65100:64036,65101:64039,65102:64040,65103:64041,65104:11905,65105:59414,65106:59415,65107:59416,65108:11908,65109:13427,65110:13383,65111:11912,65112:11915,65113:59422,65114:13726,65115:13850,65116:13838,65117:11916,65118:11927,65119:14702,65120:14616,65121:59430,65122:14799,65123:14815,65124:14963,65125:14800,65126:59435,65127:59436,65128:15182,65129:15470,65130:15584,65131:11943,65132:59441,65133:59442,65134:11946,65135:16470,65136:16735,65137:11950,65138:17207,65139:11955,65140:11958,65141:11959,65142:59451,65143:17329,65144:17324,65145:11963,65146:17373,65147:17622,65148:18017,65149:17996,65150:59459,65152:18211,65153:18217,65154:18300,65155:18317,65156:11978,65157:18759,65158:18810,65159:18813,65160:18818,65161:18819,65162:18821,65163:18822,65164:18847,65165:18843,65166:18871,65167:18870,65168:59476,65169:59477,65170:19619,65171:19615,65172:19616,65173:19617,65174:19575,65175:19618,65176:19731,65177:19732,65178:19733,65179:19734,65180:19735,65181:19736,65182:19737,65183:19886,65184:59492,65185:58472,65186:58473,65187:58474,65188:58475,65189:58476,65190:58477,65191:58478,65192:58479,65193:58480,65194:58481,65195:58482,65196:58483,65197:58484,65198:58485,65199:58486,65200:58487,65201:58488,65202:58489,65203:58490,65204:58491,65205:58492,65206:58493,65207:58494,65208:58495,65209:58496,65210:58497,65211:58498,65212:58499,65213:58500,65214:58501,65215:58502,65216:58503,65217:58504,65218:58505,65219:58506,65220:58507,65221:58508,65222:58509,65223:58510,65224:58511,65225:58512,65226:58513,65227:58514,65228:58515,65229:58516,65230:58517,65231:58518,65232:58519,65233:58520,65234:58521,65235:58522,65236:58523,65237:58524,65238:58525,65239:58526,65240:58527,65241:58528,65242:58529,65243:58530,65244:58531,65245:58532,65246:58533,65247:58534,65248:58535,65249:58536,65250:58537,65251:58538,65252:58539,65253:58540,65254:58541,65255:58542,65256:58543,65257:58544,65258:58545,65259:58546,65260:58547,65261:58548,65262:58549,65263:58550,65264:58551,65265:58552,65266:58553,65267:58554,65268:58555,65269:58556,65270:58557,65271:58558,65272:58559,65273:58560,65274:58561,65275:58562,65276:58563,65277:58564,65278:58565} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/generation/generate-singlebyte.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/generation/generate-singlebyte.js deleted file mode 100644 index 2cbebece8a7..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/generation/generate-singlebyte.js +++ /dev/null @@ -1,142 +0,0 @@ -var fs = require("fs"); -var Iconv = require("iconv").Iconv; - - -var encodingFamilies = [ - { - // Windows code pages - encodings: [1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258], - convert: function(cp) { - return { - name: "windows-"+cp, - aliases: ["win"+cp, "cp"+cp, ""+cp], - } - } - }, - { - // ISO-8859 code pages - encodings: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16], - convert: function(i) { - return { - name: "iso-8859-"+i, - aliases: ["cp"+(28590+i), (28590+i)], - } - } - }, - { - // IBM/DOS code pages - encodings: [437, 737, 775, 850, 852, 855, 857, 858, 860, 861, 862, 863, 864, 865, 866, 869], - convert: function(cp) { - return { - name: "CP"+cp, - aliases: ["ibm"+cp, ""+cp], - } - } - }, - { - // Macintosh code pages - encodings: ["macCroatian", "macCyrillic", "macGreek", - "macIceland", "macRoman", "macRomania", - "macThai", "macTurkish", "macUkraine"], - }, - { - // KOI8 code pages - encodings: ["KOI8-R", "KOI8-U"], - }, -]; - - -var encodings = { - // Aliases. - "ascii8bit": "ascii", - "usascii": "ascii", - - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", - - "cp819": "iso88951", - "arabic": "iso88596", - "arabic8": "iso88596", - "greek" : "iso88597", - "greek8" : "iso88597", - "hebrew": "iso88598", - "hebrew8": "iso88598", - "turkish": "iso88599", - "turkish8": "iso88599", - "thai": "iso885911", - "thai8": "iso885911", - "tis620": "iso885911", - "windows874": "iso885911", - "win874": "iso885911", - "cp874": "iso885911", - "874": "iso885911", - "celtic": "iso885914", - "celtic8": "iso885914", - - "cp20866": "koi8r", - "20866": "koi8r", - "ibm878": "koi8r", - "cp21866": "koi8u", - "21866": "koi8u", - "ibm1168": "koi8u", - -}; - -// Add all encodings from encodingFamilies. -encodingFamilies.forEach(function(family){ - family.encodings.forEach(function(encoding){ - if (family.convert) - encoding = family.convert(encoding); - - var encodingIconvName = encoding.name ? encoding.name : encoding; - var encodingName = encodingIconvName.replace(/[-_]/g, "").toLowerCase(); - - encodings[encodingName] = { - type: "singlebyte", - chars: generateCharsString(encodingIconvName) - }; - - if (encoding.aliases) - encoding.aliases.forEach(function(alias){ - encodings[alias] = encodingName; - }); - }); -}); - -// Write encodings. -fs.writeFileSync("encodings/singlebyte.js", - "module.exports = " + JSON.stringify(encodings, undefined, " ") + ";"); - - -function generateCharsString(encoding) { - console.log("Generate encoding for " + encoding); - var iconvToUtf8 = new Iconv(encoding, "UTF-8"); - var chars = ""; - - for (var b = 0x80; b < 0x100; b++) { - - try { - var convertedChar = iconvToUtf8.convert(new Buffer([b])).toString(); - - if (convertedChar.length != 1) - throw new Error("Single-byte encoding error: Must return single char."); - } catch (exception) { - if (exception.code === "EILSEQ") { - convertedChar = "\ufffd"; - } else { - throw exception; - } - } - - chars += convertedChar; - } - - return chars; -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/index.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/index.js deleted file mode 100644 index 8f60b74486b..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/index.js +++ /dev/null @@ -1,216 +0,0 @@ -// Module exports -var iconv = module.exports = { - toEncoding: function(str, encoding) { - return iconv.getCodec(encoding).toEncoding(str); - }, - fromEncoding: function(buf, encoding) { - return iconv.getCodec(encoding).fromEncoding(buf); - }, - - defaultCharUnicode: '�', - defaultCharSingleByte: '?', - - // Get correct codec for given encoding. - getCodec: function(encoding) { - var enc = encoding || "utf8"; - var codecOptions = undefined; - while (1) { - if (getType(enc) === "String") - enc = enc.replace(/[- ]/g, "").toLowerCase(); - var codec = iconv.encodings[enc]; - var type = getType(codec); - if (type === "String") { - // Link to other encoding. - codecOptions = {originalEncoding: enc}; - enc = codec; - } - else if (type === "Object" && codec.type != undefined) { - // Options for other encoding. - codecOptions = codec; - enc = codec.type; - } - else if (type === "Function") - // Codec itself. - return codec(codecOptions); - else - throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); - } - }, - - // Define basic encodings - encodings: { - internal: function(options) { - return { - toEncoding: toInternalEncoding, - fromEncoding: fromInternalEncoding, - options: options - }; - }, - utf8: "internal", - ucs2: "internal", - binary: "internal", - ascii: "internal", - base64: "internal", - - // Codepage single-byte encodings. - singlebyte: function(options) { - // Prepare chars if needed - if (!options.charsBuf) { - if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256)) - throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)"); - - if (options.chars.length === 128) - options.chars = asciiString + options.chars; - - options.charsBuf = new Buffer(options.chars, 'ucs2'); - } - - if (!options.revCharsBuf) { - options.revCharsBuf = new Buffer(65536); - var defChar = iconv.defaultCharSingleByte.charCodeAt(0); - for (var i = 0; i < options.revCharsBuf.length; i++) - options.revCharsBuf[i] = defChar; - for (var i = 0; i < options.chars.length; i++) - options.revCharsBuf[options.chars.charCodeAt(i)] = i; - } - - return { - toEncoding: toSingleByteEncoding, - fromEncoding: fromSingleByteEncoding, - options: options, - }; - }, - - // Codepage double-byte encodings. - table: function(options) { - if (!options.table) { - throw new Error("Encoding '" + options.type + "' has incorect 'table' option"); - } - if (!options.revCharsTable) { - var revCharsTable = options.revCharsTable = {}; - for (var i = 0; i <= 0xFFFF; i++) { - revCharsTable[i] = 0; - } - - var table = options.table; - for (var key in table) { - revCharsTable[table[key]] = +key; - } - } - - return { - toEncoding: toTableEncoding, - fromEncoding: fromTableEncoding, - options: options, - }; - } - } -}; - -function toInternalEncoding(str) { - return new Buffer(ensureString(str), this.options.originalEncoding); -} - -function fromInternalEncoding(buf) { - return ensureBuffer(buf).toString(this.options.originalEncoding); -} - -function toTableEncoding(str) { - str = ensureString(str); - var strLen = str.length; - var revCharsTable = this.options.revCharsTable; - var newBuf = new Buffer(strLen*2), gbkcode, unicode, - defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)]; - - for (var i = 0, j = 0; i < strLen; i++) { - unicode = str.charCodeAt(i); - if (unicode >> 7) { - gbkcode = revCharsTable[unicode] || defaultChar; - newBuf[j++] = gbkcode >> 8; //high byte; - newBuf[j++] = gbkcode & 0xFF; //low byte - } else {//ascii - newBuf[j++] = unicode; - } - } - return newBuf.slice(0, j); -} - -function fromTableEncoding(buf) { - buf = ensureBuffer(buf); - var bufLen = buf.length; - var table = this.options.table; - var newBuf = new Buffer(bufLen*2), unicode, gbkcode, - defaultChar = iconv.defaultCharUnicode.charCodeAt(0); - - for (var i = 0, j = 0; i < bufLen; i++, j+=2) { - gbkcode = buf[i]; - if (gbkcode & 0x80) { - gbkcode = (gbkcode << 8) + buf[++i]; - unicode = table[gbkcode] || defaultChar; - } else { - unicode = gbkcode; - } - newBuf[j] = unicode & 0xFF; //low byte - newBuf[j+1] = unicode >> 8; //high byte - } - return newBuf.slice(0, j).toString('ucs2'); -} - -function toSingleByteEncoding(str) { - str = ensureString(str); - - var buf = new Buffer(str.length); - var revCharsBuf = this.options.revCharsBuf; - for (var i = 0; i < str.length; i++) - buf[i] = revCharsBuf[str.charCodeAt(i)]; - - return buf; -} - -function fromSingleByteEncoding(buf) { - buf = ensureBuffer(buf); - - // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. - var charsBuf = this.options.charsBuf; - var newBuf = new Buffer(buf.length*2); - var idx1 = 0, idx2 = 0; - for (var i = 0, _len = buf.length; i < _len; i++) { - idx1 = buf[i]*2; idx2 = i*2; - newBuf[idx2] = charsBuf[idx1]; - newBuf[idx2+1] = charsBuf[idx1+1]; - } - return newBuf.toString('ucs2'); -} - -// Add aliases to convert functions -iconv.encode = iconv.toEncoding; -iconv.decode = iconv.fromEncoding; - -// Load other encodings manually from files in /encodings dir. -function applyEncodings(encodings) { - for (var key in encodings) - iconv.encodings[key] = encodings[key] -} - -applyEncodings(require('./encodings/singlebyte')); -applyEncodings(require('./encodings/gbk')); - - -// Utilities -var asciiString = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; - -var ensureBuffer = function(buf) { - buf = buf || new Buffer(0); - return (buf instanceof Buffer) ? buf : new Buffer(buf.toString(), "utf8"); -} - -var ensureString = function(str) { - str = str || ""; - return (str instanceof String) ? str : str.toString((str instanceof Buffer) ? 'utf8' : undefined); -} - -var getType = function(obj) { - return Object.prototype.toString.call(obj).slice(8, -1); -} - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/package.json b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/package.json deleted file mode 100644 index 8001ca81592..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "iconv-lite", - "description": "Convert character encodings in pure javascript.", - "version": "0.2.7", - "keywords": [ - "iconv", - "convert", - "charset" - ], - "author": { - "name": "Alexander Shtuchkin", - "email": "ashtuchkin@gmail.com" - }, - "contributors": [ - { - "name": "Jinwu Zhan", - "url": "https://github.com/jenkinv" - }, - { - "name": "Adamansky Anton", - "url": "https://github.com/adamansky" - }, - { - "name": "George Stagas", - "url": "https://github.com/stagas" - }, - { - "name": "Mike D Pilsbury", - "url": "https://github.com/pekim" - } - ], - "main": "index.js", - "homepage": "https://github.com/ashtuchkin/iconv-lite", - "repository": { - "type": "git", - "url": "git://github.com/ashtuchkin/iconv-lite.git" - }, - "engines": { - "node": ">=0.4.0" - }, - "scripts": { - "test": "vows --spec" - }, - "devDependencies": { - "vows": "", - "iconv": ">=1.1" - }, - "readme": "iconv-lite - pure javascript character encoding conversion\n======================================================================\n\n[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite)\n\n## Features\n\n* Pure javascript. Doesn't need native code compilation.\n* Easy API.\n* Works on Windows and in sandboxed environments like [Cloud9](http://c9.io).\n* Encoding is much faster than node-iconv (see below for performance comparison).\n\n## Usage\n\n var iconv = require('iconv-lite');\n \n // Convert from an encoded buffer to string.\n str = iconv.decode(buf, 'win1251');\n \n // Convert from string to an encoded buffer.\n buf = iconv.encode(\"Sample input string\", 'win1251');\n\n## Supported encodings\n\n* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64'\n* All widespread single byte encodings: Windows 125x family, ISO-8859 family, \n IBM/DOS codepages, Macintosh family, KOI8 family. \n Aliases like 'latin1', 'us-ascii' also supported.\n* Multibyte encodings: 'gbk', 'gb2313'.\n\nOthers are easy to add, see the source. Please, participate.\nMost encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors!\n\nNot supported yet: Big5, EUC family, Shift_JIS.\n\n\n## Encoding/decoding speed\n\nComparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). \nNote: your results may vary, so please always check on your hardware.\n\n operation iconv@1.2.4 iconv-lite@0.2.4 \n ----------------------------------------------------------\n encode('win1251') ~115 Mb/s ~230 Mb/s\n decode('win1251') ~95 Mb/s ~130 Mb/s\n\n\n## Notes\n\nUntranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome.\n\n## Testing\n\n npm install --dev iconv-lite\n vows\n \n # To view performance:\n node test/performance.js\n\n## TODO\n\n* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')).\n* Add more encodings.\n* Add transliteration (best fit char).\n* Add tests and correct support of variable-byte encodings (currently work is delegated to node).\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/ashtuchkin/iconv-lite/issues" - }, - "_id": "iconv-lite@0.2.7", - "_from": "iconv-lite@0.2.7" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/cyrillic-test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/cyrillic-test.js deleted file mode 100644 index 259d283244b..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/cyrillic-test.js +++ /dev/null @@ -1,86 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var baseStrings = { - empty: "", - hi: "Привет!", - ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', - rus: "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ", - additional1: "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋÐђ‘’“â€â€¢â€“—™љ›њќћџ ЎўЈ¤Ò¦§Ð©Є«¬\xAD®Ї°±Ііґµ¶·ё№є»јЅѕї", - additional2: "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•â•‘╒ё╓╔╕╖╗╘╙╚╛╜â•â•žâ•Ÿâ• â•¡Ð╢╣╤╥╦╧╨╩╪╫╬©", - additional3: " ÐЂЃЄЅІЇЈЉЊЋЌ­ЎÐ№ёђѓєѕіїјљњћќ§ўџ", - untranslatable: "£Åçþÿ¿", -}; - -var encodings = [{ - name: "Win-1251", - variations: ['win1251', 'Windows-1251', 'windows1251', 'CP1251', 1251], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xcf\xf0\xe8\xe2\xe5\xf2!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), - additional1: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf','binary'), - } -}, { - name: "Koi8-R", - variations: ['koi8r', 'KOI8-R', 'cp20866', 20866], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xf0\xd2\xc9\xd7\xc5\xd4!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xe1\xe2\xf7\xe7\xe4\xe5\xf6\xfa\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf2\xf3\xf4\xf5\xe6\xe8\xe3\xfe\xfb\xfd\xff\xf9\xf8\xfc\xe0\xf1\xc1\xc2\xd7\xc7\xc4\xc5\xd6\xda\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd2\xd3\xd4\xd5\xc6\xc8\xc3\xde\xdb\xdd\xdf\xd9\xd8\xdc\xc0\xd1', 'binary'), - additional2: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf', 'binary'), - } -}, { - name: "ISO 8859-5", - variations: ['iso88595', 'ISO-8859-5', 'ISO 8859-5', 'cp28595', 28595], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xbf\xe0\xd8\xd2\xd5\xe2!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef', 'binary'), - additional3: new Buffer('\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "hi"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - baseStrings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Cyrillic encodings").addBatch(testsBatch).export(module); - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbk-test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbk-test.js deleted file mode 100644 index 7b2e47bd480..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbk-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require('vows'), - fs = require('fs'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var testString = "中国abc",//unicode contains GBK-code and ascii - testStringGBKBuffer = new Buffer([0xd6,0xd0,0xb9,0xfa,0x61,0x62,0x63]); - -vows.describe("GBK tests").addBatch({ - "Vows is working": function() {}, - "Return values are of correct types": function() { - assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); - var s = iconv.fromEncoding(new Buffer(testString), "utf8"); - assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); - }, - "GBK correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "GBK").toString('binary'), testStringGBKBuffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GBK"), testString); - }, - "GB2312 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "GB2312").toString('binary'), testStringGBKBuffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GB2312"), testString); - }, - "GBK file read decoded,compare with iconv result": function() { - var contentBuffer = fs.readFileSync(__dirname+"/gbkFile.txt"); - var str = iconv.fromEncoding(contentBuffer, "GBK"); - var iconvc = new (require('iconv').Iconv)('GBK','utf8'); - assert.strictEqual(iconvc.convert(contentBuffer).toString(), str); - }, - "GBK correctly decodes and encodes characters · and ×": function() { - // https://github.com/ashtuchkin/iconv-lite/issues/13 - // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT - var chars = "·×"; - var gbkChars = new Buffer([0xA1, 0xA4, 0xA1, 0xC1]); - assert.strictEqual(iconv.toEncoding(chars, "GBK").toString('binary'), gbkChars.toString('binary')); - assert.strictEqual(iconv.fromEncoding(gbkChars, "GBK"), chars) - }, -}).export(module) diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbkFile.txt b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbkFile.txt deleted file mode 100644 index 1154d0a2f35..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/gbkFile.txt +++ /dev/null @@ -1,14 +0,0 @@ -°Ù¶Èһϣ¬Äã¾ÍÖªµÀ - - -
- - - - - - - - \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/greek-test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/greek-test.js deleted file mode 100644 index 0394ee6f558..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/greek-test.js +++ /dev/null @@ -1,79 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var baseStrings = { - empty: "", - hi: "Γειά!", - ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', - greek: "αβγδεζηθικλμνξοπÏστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩάέήίόÏώΆΈΉΊΌΎÎϊϋΪΫ", - untranslatable: "Åçþÿ¿" -}; - -var encodings = [{ - name: "windows1253", - variations: ['windows-1253', 'win-1253', 'win1253', 'cp1253', 'cp-1253', 1253], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xa2\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), - } -}, { - name: "iso88597", - variations: ['iso-8859-7', 'greek', 'greek8', 'cp28597', 'cp-28597', 28597], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xb6\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), - } -}, { - name: "cp737", - variations: ['cp-737', 737], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\x82\x9c\xa0\xe1!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xab\xac\xad\xae\xaf\xe0\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\xe1\xe2\xe3\xe5\xe6\xe7\xe9\xea\xeb\xec\xed\xee\xef\xf0\xe4\xe8\xf4\xf5', 'binary'), - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "hi"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - baseStrings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Greek encodings").addBatch(testsBatch).export(module); diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/main-test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/main-test.js deleted file mode 100644 index 072c5998e72..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/main-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var testString = "Hello123!"; -var testStringLatin1 = "Hello123!£Å÷×çþÿ¿®"; -var testStringBase64 = "SGVsbG8xMjMh"; - -vows.describe("Generic UTF8-UCS2 tests").addBatch({ - "Vows is working": function() {}, - "Return values are of correct types": function() { - assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); - - var s = iconv.fromEncoding(new Buffer(testString), "utf8"); - assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); - }, - "Internal encodings all correctly encoded/decoded": function() { - ['utf8', "UTF-8", "UCS2", "binary", ""].forEach(function(enc) { - assert.strictEqual(iconv.toEncoding(testStringLatin1, enc).toString(enc), testStringLatin1); - assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, enc), enc), testStringLatin1); - }); - }, - "Base64 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testStringBase64, "base64").toString("binary"), testString); - assert.strictEqual(iconv.fromEncoding(new Buffer(testString, "binary"), "base64"), testStringBase64); - }, - "Latin1 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testStringLatin1, "latin1").toString("binary"), testStringLatin1); - assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, "binary"), "latin1"), testStringLatin1); - }, - "Convert from string, not buffer (utf8 used)": function() { - assert.strictEqual(iconv.fromEncoding(testStringLatin1, "utf8"), testStringLatin1); - }, - "Convert to string, not buffer (utf8 used)": function() { - var res = iconv.toEncoding(new Buffer(testStringLatin1, "utf8")); - assert.ok(res instanceof Buffer); - assert.strictEqual(res.toString("utf8"), testStringLatin1); - }, - "Throws on unknown encodings": function() { - assert.throws(function() { iconv.toEncoding("a", "xxx"); }); - assert.throws(function() { iconv.fromEncoding("a", "xxx"); }); - }, - "Convert non-strings and non-buffers": function() { - assert.strictEqual(iconv.toEncoding({}, "utf8").toString(), "[object Object]"); - assert.strictEqual(iconv.toEncoding(10, "utf8").toString(), "10"); - assert.strictEqual(iconv.toEncoding(undefined, "utf8").toString(), ""); - assert.strictEqual(iconv.fromEncoding({}, "utf8"), "[object Object]"); - assert.strictEqual(iconv.fromEncoding(10, "utf8"), "10"); - assert.strictEqual(iconv.fromEncoding(undefined, "utf8"), ""); - }, - "Aliases encode and decode work the same as toEncoding and fromEncoding": function() { - assert.strictEqual(iconv.toEncoding(testString, "latin1").toString("binary"), iconv.encode(testString, "latin1").toString("binary")); - assert.strictEqual(iconv.fromEncoding(testStringLatin1, "latin1"), iconv.decode(testStringLatin1, "latin1")); - }, -}).export(module) diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/performance.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/performance.js deleted file mode 100644 index 835deac5792..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/performance.js +++ /dev/null @@ -1,67 +0,0 @@ - -var iconv = require('iconv'); -var iconv_lite = require("../index"); - -var encoding = process.argv[2] || "windows-1251"; -var convertTimes = 10000; - -var encodingStrings = { - 'windows-1251': 'This is a test string 32 chars..', - 'gbk': '这是中文字符测试。。ï¼@ï¿¥%12', - 'utf8': '这是中文字符测试。。ï¼@ï¿¥%12This is a test string 48 chars..', -}; -// Test encoding. -var str = encodingStrings[encoding]; -if (!str) { - throw new Error('Don\'t support ' + encoding + ' performance test.'); -} -for (var i = 0; i < 13; i++) { - str = str + str; -} - -console.log('\n' + encoding + ' charset performance test:'); -console.log("\nEncoding "+str.length+" chars "+convertTimes+" times:"); - -var start = Date.now(); -var converter = new iconv.Iconv("utf8", encoding); -for (var i = 0; i < convertTimes; i++) { - var b = converter.convert(str); -} -var duration = Date.now() - start; -var mbs = convertTimes*b.length/duration/1024; - -console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - -var start = Date.now(); -for (var i = 0; i < convertTimes; i++) { - var b = iconv_lite.encode(str, encoding); -} -var duration = Date.now() - start; -var mbs = convertTimes*b.length/duration/1024; - -console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - - -// Test decoding. -var buf = iconv_lite.encode(str, encoding); -console.log("\nDecoding "+buf.length+" bytes "+convertTimes+" times:"); - -var start = Date.now(); -var converter = new iconv.Iconv(encoding, "utf8"); -for (var i = 0; i < convertTimes; i++) { - var s = converter.convert(buf).toString(); -} -var duration = Date.now() - start; -var mbs = convertTimes*buf.length/duration/1024; - -console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - -var start = Date.now(); -for (var i = 0; i < convertTimes; i++) { - var s = iconv_lite.decode(buf, encoding); -} -var duration = Date.now() - start; -var mbs = convertTimes*buf.length/duration/1024; - -console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/turkish-test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/turkish-test.js deleted file mode 100644 index b2eb68e67c6..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/test/turkish-test.js +++ /dev/null @@ -1,90 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var ascii = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; - -var encodings = [{ - name: "windows1254", - variations: ['windows-1254', 'win-1254', 'win1254', 'cp1254', 'cp-1254', 1254], - strings: { - empty: "", - ascii: ascii, - turkish: "€‚ƒ„…†‡ˆ‰Š‹Œ‘’“â€â€¢â€“—˜™š›œŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", - untranslatable: "\x81\x8d\x8e\x8f\x90\x9d\x9e" - }, - encodedStrings: { - empty: new Buffer(''), - ascii: new Buffer(ascii, 'binary'), - turkish: new Buffer( - '\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c' + - '\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9f' + - '\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf' + - '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + - '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + - '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + - '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + - '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', - 'binary'), - } -}, { - name: "iso88599", - variations: ['iso-8859-9', 'turkish', 'turkish8', 'cp28599', 'cp-28599', 28599], - strings: { - empty: "", - ascii: ascii, - turkish: "\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", - untranslatable: '' - }, - encodedStrings: { - empty: new Buffer(''), - ascii: new Buffer(ascii, 'binary'), - turkish: new Buffer( - '\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf' + - '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + - '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + - '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + - '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + - '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', - 'binary') - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "turkish"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - encoding.strings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), encoding.strings[key]); - assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = encoding.strings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(encoding.strings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Turkish encodings").addBatch(testsBatch).export(module); diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/package.json b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/package.json deleted file mode 100644 index 393fe911bd8..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "encoding", - "version": "0.1.6", - "description": "Convert encodings, uses iconv by default and fallbacks to iconv-lite if needed", - "main": "index.js", - "scripts": { - "test": "nodeunit test.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/andris9/encoding.git" - }, - "author": { - "name": "Andris Reinman" - }, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.2.7" - }, - "devDependencies": { - "nodeunit": "*" - }, - "readme": "# Encoding\n\n**encoding** is a simple wrapper around [node-iconv](https://github.com/bnoordhuis/node-iconv) and [iconv-lite](https://github.com/ashtuchkin/iconv-lite/) to convert strings from one encoding to another. If node-iconv is not available for some reason,\niconv-lite will be used instead of it as a fallback.\n\n## Install\n\nInstall through npm\n\n npm install encoding\n\n## Usage\n\nRequire the module\n\n var encoding = require(\"encoding\");\n\nConvert with encoding.convert()\n\n var resultBuffer = encoding.convert(text, toCharset, fromCharset);\n\nWhere\n\n * **text** is either a Buffer or a String to be converted\n * **toCharset** is the characterset to convert the string\n * **fromCharset** (*optional*, defaults to UTF-8) is the source charset\n\nOutput of the conversion is always a Buffer object.\n\nExample\n\n var result = encoding.convert(\"ÕÄÖÜ\", \"Latin_1\");\n console.log(result); //\n\n## iconv support\n\nBy default only iconv-lite is bundled. If you need node-iconv support, you need to add it\nas an additional dependency for your project:\n\n ...,\n \"dependencies\":{\n \"encoding\": \"*\",\n \"iconv\": \"*\"\n },\n ...\n\n## License\n\n**MIT**", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/encoding/issues" - }, - "_id": "encoding@0.1.6", - "_from": "encoding@~0.1" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/test.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/test.js deleted file mode 100644 index 489aa3874d6..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/test.js +++ /dev/null @@ -1,35 +0,0 @@ -var testCase = require('nodeunit').testCase, - encoding = require("./index"); - -exports["General tests"] = { - "From UTF-8 to Latin_1": function(test){ - var input = "ÕÄÖÜ", - expected = new Buffer([0xd5, 0xc4, 0xd6, 0xdc]); - test.deepEqual(encoding.convert(input, "latin1"), expected); - test.done(); - }, - "From Latin_1 to UTF-8": function(test){ - var input = new Buffer([0xd5, 0xc4, 0xd6, 0xdc]), - expected = "ÕÄÖÜ"; - test.deepEqual(encoding.convert(input, "utf-8", "latin1").toString(), expected); - test.done(); - }, - "From Latin_13 to Latin_15": function(test){ - var input = new Buffer([0xd5, 0xc4, 0xd6, 0xdc, 0xd0]), - expected = new Buffer([0xd5, 0xc4, 0xd6, 0xdc, 0xA6]); - test.deepEqual(encoding.convert(input, "latin_15", "latin13"), expected); - test.done(); - }, - "From Latin_13 to Latin_15 lite": function(test){ - var input = new Buffer([0xd5, 0xc4, 0xd6, 0xdc, 0xd0]), - expected = new Buffer([0xd5, 0xc4, 0xd6, 0xdc, 0xA6]); - test.deepEqual(encoding.convert(input, "latin_15", "latin13", true), expected); - test.done(); - }, - "From ISO-2022-JP to UTF-8": function(test){ - var input = new Buffer("GyRCM1g5OzU7PVEwdzgmPSQ4IUYkMnFKczlwGyhC", "base64"), - expected = new Buffer("5a2m5qCh5oqA6KGT5ZOh56CU5L+u5qSc6KiO5Lya5aCx5ZGK", "base64"); - test.deepEqual(encoding.convert(input, "utf-8", "ISO-2022-JP"), expected); - test.done(); - } -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/package.json b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/package.json deleted file mode 100644 index b6c5d62b51d..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "mimelib", - "description": "MIME functions to encode/decode e-mails etc.", - "version": "0.2.12", - "author": { - "name": "Andris Reinman" - }, - "homepage": "http://github.com/andris9/mimelib", - "maintainers": [ - { - "name": "andris", - "email": "andris@node.ee" - } - ], - "contributors": [ - { - "name": "Swift", - "email": "theycallmeswift@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/andris9/mimelib.git" - }, - "scripts": { - "test": "nodeunit test/" - }, - "main": "index.js", - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/andris9/mimelib/blob/master/LICENSE" - } - ], - "dependencies": { - "encoding": "~0.1", - "addressparser": "~0.1" - }, - "devDependencies": { - "nodeunit": "*" - }, - "keywords": [ - "e-mail", - "mime", - "email" - ], - "readme": "# mimelib\n\n*mimelib* is a collection of useful functions to deal with mime-encoded data.\n\n## Installation\n\nInstall with *npm*\n\n npm install mimelib\n \n## Usage\n\n var mimelib = require(\"mimelib\");\n\n## Reference\n\n### foldLine\n\nFolds a long line according to the RFC 5322 \n\n mimelib.foldLine(str [, maxLength][, foldAnywhere][, afterSpace]) -> String\n \n - `str` (String): mime string that might need folding\n - `maxLength` (Number): max length for a line, defaults to 78\n - `foldAnywhere` (Boolean): can fold at any location (ie. in base64)\n - `afterSpace` (Boolean): If `true` fold after the space\n \n\nFor example:\n\n Content-Type: multipart/alternative; boundary=\"----zzzz----\"\n\nwill become\n\n Content-Type: multipart/alternative;\n boundary=\"----zzzz----\"\n\n### encodeMimeWord\n\nEncodes a string into mime encoded word format (see also `decodeMimeWord`)\n\n mimelib.encodeMimeWord = function(str [, encoding][, charset])\n\n - `str` (String): String to be encoded\n - `encoding` (String): Encoding Q for quoted printable or B (def.) for base64\n - `charset` (String): Charset to be used\n \nFor example:\n\n See on õhin test\n\nBecomes with UTF-8 and Quoted-printable encoding\n\n =?UTF-8?Q?See_on_=C3=B5hin_test?=\n \n### decodeMimeWord\n\nDecodes a string from mime encoded word format (see also `encodeMimeWord`)\n\n mimelib.decodeMimeWord(str) -> String\n \n - `str` (String): String to be decoded\n\nFor example\n\n mimelib.decodeMimeWord(\"=?UTF-8?Q?See_on_=C3=B5hin_test?=\");\n\nwill become\n\n See on õhin test\n\n### encodeQuotedPrintable\n\nEncodes a string into Quoted-printable format (see also `decodeQuotedPrintable`)\n\n mimelib.encodeQuotedPrintable(str [, mimeWord][, charset]) -> String\n \n - `str` (String): String to be encoded into Quoted-printable\n - `mimeWord` (Boolean): Deprecated, has no effect, ignore it\n - `charset` (String): Destination charset, defaults to UTF-8\n\n### decodeQuotedPrintable\n\nDecodes a string from Quoted-printable format (see also `encodeQuotedPrintable`)\n\n mimelib.decodeQuotedPrintable(str [, mimeWord][, charset]) -> String\n \n - `str` (String): String to be decoded\n - `mimeWord` (Boolean): Deprecated, has no effect, ignore it\n - `charset` (String): Charset to be used, defaults to UTF-8\n \n### encodeBase64\n\nEncodes a string into Base64 format. Base64 is mime-word safe (see also `decodeBase64`)\n\n mimelib.encodeBase64(str [, charset]) -> String\n \n - `str` (String): String to be encoded into Base64\n - `charset` (String): Destination charset, defaults to UTF-8\n\n### decodeBase64\n\nDecodes a string from Base64 format. Base64 is mime-word safe (see also `encodeBase64`)\n\nNB! Always returns UTF-8\n\n mimelib.decodeBase64(str) -> String\n\n - `str` (String): String to be decoded from Base64\n - `charset` (String): Source charset, defaults to UTF-8\n \n### parseHeaders\n\nParses header lines into an array of objects (see `parseHeaderLine`)\n\n mimelib.parseHeaders(headers) -> Array\n \n - `headers` (String): header section of the e-mail\n\nExample:\n\n var headers = [\n \"From: andris@node.ee\",\n \"To: juulius@node.ee\",\n \"To: juulius2@node.ee\",\n \"Content-type: text/html;\",\n \" charset=utf-8\"\n ].join(\"\\r\\n\");\n mimelib.parseHeaders(headers);\n\nResults in \n\n {\"from\": [ 'andris@node.ee' ],\n \"to\": [ 'juulius@node.ee', 'juulius2@node.ee' ],\n \"content-type\": [ 'text/html; charset=utf-8' ] }\n\n### parseAddresses\n\nParses names and addresses from a from, to, cc or bcc line\n\n mimelib.parseAddresses(addresses) -> Array\n \n - `addresses` (String): string with comma separated e-mail addresses \n \nExample:\n\n var to = '\"Andris Reinman\" , juulius@node.ee'\n mimelib.parseAddresses(to);\n \nResults in\n\n [{ address: 'andris@node.ee', name: 'Andris Reinman' },\n { address: 'juulius@node.ee', name: false }]\n\n### parseMimeWords\n\nParses mime-words into UTF-8 strings\n\n mimelib.parseMimeWords(str) -> String\n\n - `str` (String): string to be parsed, if includes any mime words, then these are converted to UTF-8 strings\n \n \nFor example:\n\n mimelib.parseMimeWords(\"Hello: =?UTF-8?Q?See_on_=C3=B5hin_test?=\");\n\nResults in\n\n \"Hello: See on õhin test\"\n \n### parseHeaderLine\n\nParses a header line to search for additional parameters.\n\n mimelib.parseHeaderLine(line) -> Object\n \n - `line` (String): a line from a message headers\n \nFor example:\n\n mimelib.parseHeaderLine(\"text/plain; charset=utf-8\")imelib\n\nResults in\n\n {\"defaultValue\": 'text/plain',\n \"charset\": 'utf-8' }\n\n### contentTypes\n\n**NB! this feature is deprecated**, use [mime](https://github.com/broofa/node-mime) module instead to detect content types and extensions\n\n`mimelib.contentTypes` is an object to provide content type strings for common\nfile extensions\n\n mimelib.contentTypes[\"xls\"]; // \"application/vnd.ms-excel\"\n\n## iconv support\n\nBy default only iconv-lite support is bundled. If you need node-iconv support, you need to add it\nas an additional dependency for your project:\n\n ...,\n \"dependencies\":{\n \"mimelib\": \"*\",\n \"iconv\": \"*\"\n },\n ...\n\n## License\n\nmimelib license is", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/mimelib/issues" - }, - "_id": "mimelib@0.2.12", - "_from": "mimelib@~0.2" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/test/mimelib.js b/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/test/mimelib.js deleted file mode 100644 index 6d1c2b2096b..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/test/mimelib.js +++ /dev/null @@ -1,164 +0,0 @@ -var testCase = require('nodeunit').testCase, - mimelib = require("../index"); - -exports["Quoted printable"] = { - "Encode short string": function(test){ - test.equal("Tere =D5=C4=D6=DC!", mimelib.encodeQuotedPrintable("Tere ÕÄÖÜ!", null, "Latin_1")); - test.equal("Tere =C3=95=C3=84=C3=96=C3=9C=C5=A0=C5=BD!", mimelib.encodeQuotedPrintable("Tere ÕÄÖÜŠŽ!", null, "UTF-8")); - test.equal("Tere =D0=DE!", mimelib.encodeQuotedPrintable("Tere ŠŽ!", null, "Win-1257")); - test.done(); - }, - - "parseMimeWords example": function(test){ - test.equal("Hello: See on õhin test", mimelib.parseMimeWords("Hello: =?UTF-8?q?See_on_=C3=B5hin_test?=")); - test.equal("=?UTF-8?Q?See_on_=C3=B5hin_test?=", mimelib.encodeMimeWord("See on õhin test")); - test.equal("See on õhin test", mimelib.decodeMimeWord("=?UTF-8?q?See_on_=C3=B5hin_test?=")); - test.done(); - }, - - "Don't wrap between encoded chars": function(test){ - var wrapped = "a__________________________", - wrappedEncoded = "a=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=5F=\r\n=5F=5F"; - test.equal(wrappedEncoded, mimelib.encodeQuotedPrintable(wrapped)); - test.done(); - }, - - "Encode long string": function(test){ - var longLine = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - longLineEncoded = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLM=\r\n"+ - "NOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ=\r\n"+ - "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm=\r\n"+ - "nopqrstuvwxyz0123456789"; - - test.equal(longLineEncoded, mimelib.encodeQuotedPrintable(longLine)); - test.done(); - }, - - "Quote at line edge": function(test){ - var str = 'Title: The future of e-commerce is storytelling
', - strEncoded = "Title: The future of e-commerce is storytelling =\r\n
"; - test.equal(strEncoded, mimelib.encodeQuotedPrintable(str)); - test.done(); - }, - - "Wordwrap long string with UTF-8 sequence on edge": function(test){ - var longLine = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIÄÄÄPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - longLineEncoded = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHI=\r\n"+ - "=C3=84=C3=84=C3=84PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJ=\r\n"+ - "KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVW=\r\n"+ - "XYZabcdefghijklmnopqrstuvwxyz0123456789"; - test.equal(longLineEncoded, mimelib.encodeQuotedPrintable(longLine)); - test.done(); - }, - - "Decode string": function(test){ - var longLine = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIÄÄÄPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - longLineEncoded = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHI=\r\n"+ - "=C3=84=C3=84=C3=84PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJ=\r\n"+ - "KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVW=\r\n"+ - "XYZabcdefghijklmnopqrstuvwxyz0123456789"; - - test.equal(longLine, mimelib.decodeQuotedPrintable(longLineEncoded)); - test.done(); - }, - - "Decode string with soft linebreaks": function(test){ - var input = "Tere =\r\nvana kere=", - output = "Tere vana kere"; - - test.equal(output, mimelib.decodeQuotedPrintable(input)); - test.done(); - }, - - "Surrogate pair": function(test){ - // 💩 pile of poo - test.equal("=F0=9F=92=A9", mimelib.encodeQuotedPrintable('\ud83d\udca9')) - test.equal("\ud83d\udca9", mimelib.decodeQuotedPrintable('=F0=9F=92=A9')) - test.done(); - } -} - -exports["Base64"] = { - "Convert string": function(test){ - test.equal("VGVyZSDVxNbcIQ==", mimelib.encodeBase64("Tere ÕÄÖÜ!", "Latin_1")); - test.done(); - }, - - "Decode string": function(test){ - test.equal("Tere ÕÄÖÜ!", mimelib.decodeBase64("VGVyZSDVxNbcIQ==", "Latin_1")); - test.done(); - } -} - -exports["Mime Words"] = { - "Encode Mime Word QP": function(test){ - test.equal("=?ISO-8859-13?Q?J=F5ge-va=DE?=", mimelib.encodeMimeWord("Jõge-vaŽ", "Q", "iso-8859-13")); - test.done(); - }, - - "Decode Mime Word QP": function(test){ - test.equal("Jõge-vaŽ", mimelib.decodeMimeWord("=?ISO-8859-13?Q?J=F5ge-va=DE?=")); - test.done(); - }, - - "Parse Mime Words": function(test){ - test.equal("Jõge-vaŽ zz Jõge-vaŽJõge-vaŽJõge-vaŽ", mimelib.parseMimeWords("=?ISO-8859-13?Q?J=F5ge-va=DE?= zz =?ISO-8859-13?Q?J=F5ge-va=DE?= =?ISO-8859-13?Q?J=F5ge-va=DE?= =?ISO-8859-13?Q?J=F5ge-va=DE?=")) - test.equal("SssÅ› LaÅ‚alalala", mimelib.parseMimeWords("=?UTF-8?B?U3NzxZsgTGHFgmFsYQ==?= =?UTF-8?B?bGFsYQ==?=")); - test.done(); - }, - - "Split on maxLength QP": function(test){ - var inputStr = "Jõgeva Jõgeva Jõgeva mugeva Jõgeva Jõgeva Jõgeva Jõgeva Jõgeva", - outputStr = "=?ISO-8859-1?Q?J=F5geva_J=F5gev?= =?ISO-8859-1?Q?a_J=F5geva?= mugeva =?ISO-8859-1?Q?J=F5geva_J=F5gev?= =?ISO-8859-1?Q?a_J=F5geva_J=F5g?= =?ISO-8859-1?Q?eva_J=F5geva?=", - encoded = mimelib.encodeMimeWords(inputStr, "Q", 16, "ISO-8859-1"); - - test.equal(outputStr, encoded) - test.equal(inputStr, mimelib.parseMimeWords(encoded)); - test.done(); - }, - - "Split on maxLength Base64": function(test){ - var inputStr = "Jõgeva Jõgeva Jõgeva mugeva Jõgeva Jõgeva Jõgeva Jõgeva Jõgeva", - outputStr = "=?ISO-8859-1?B?SvVnZXZhIEr1Z2V2?= =?ISO-8859-1?B?YSBK9WdldmE=?= mugeva =?ISO-8859-1?B?SvVnZXZhIEr1Z2V2?= =?ISO-8859-1?B?YSBK9WdldmEgSvVn?= =?ISO-8859-1?B?ZXZhIEr1Z2V2YQ==?=", - encoded = mimelib.encodeMimeWords(inputStr,"B", 16, "ISO-8859-1"); - - test.equal(outputStr, encoded) - test.equal(inputStr, mimelib.parseMimeWords(encoded)); - test.done(); - }, - - "Ascii range": function(test){ - var input1 = "метель\" вьюга", - input2 = "метель'вьюга", - output1 = "=?UTF-8?Q?=D0=BC=D0=B5=D1=82=D0=B5=D0=BB=D1=8C=22_?= =?UTF-8?Q?=D0=B2=D1=8C=D1=8E=D0=B3=D0=B0?=", - output2 = "=?UTF-8?Q?=D0=BC=D0=B5=D1=82=D0=B5=D0=BB=D1=8C'?= =?UTF-8?Q?=D0=B2=D1=8C=D1=8E=D0=B3=D0=B0?="; - - test.equal(mimelib.encodeMimeWords(input1, "Q", 52), output1); - test.equal(mimelib.parseMimeWords(output1), input1); - - test.equal(mimelib.encodeMimeWords(input2, "Q", 52), output2); - test.equal(mimelib.parseMimeWords(output2), input2); - - test.done(); - } -} - -exports["Fold long line"] = function(test){ - var inputStr = "Subject: Testin command line kirja õkva kakva mõni tõnis kõllas põllas tõllas rõllas juÅ¡la kuÅ¡la tuÅ¡la musla", - outputStr = "Subject: Testin command line kirja =?UTF-8?Q?=C3=B5kva?= kakva\r\n"+ - " =?UTF-8?Q?m=C3=B5ni_t=C3=B5nis_k=C3=B5llas_p=C3=B5?=\r\n"+ - " =?UTF-8?Q?llas_t=C3=B5llas_r=C3=B5llas_ju=C5=A1la_?=\r\n"+ - " =?UTF-8?Q?ku=C5=A1la_tu=C5=A1la?= musla"; - - test.equal(outputStr, mimelib.foldLine(mimelib.encodeMimeWords(inputStr, "Q", 52), 76, false, false, 52)); - test.done(); -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/package.json b/api/node_modules/nodemailer/node_modules/mailcomposer/package.json deleted file mode 100644 index 05807f1784e..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "mailcomposer", - "description": "Compose E-Mail messages", - "version": "0.1.33", - "author": { - "name": "Andris Reinman" - }, - "maintainers": [ - { - "name": "andris", - "email": "andris@node.ee" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/andris9/mailcomposer.git" - }, - "scripts": { - "test": "nodeunit test/" - }, - "main": "./lib/mailcomposer", - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/andris9/mailcomposer/blob/master/LICENSE" - } - ], - "dependencies": { - "mimelib": "~0.2", - "mime": "1.2.9" - }, - "devDependencies": { - "nodeunit": "*", - "mailparser": "*" - }, - "engine": { - "node": ">=0.4" - }, - "keywords": [ - "e-mail", - "mime", - "parser" - ], - "readme": "# mailcomposer\n\n**mailcomposer** is a Node.JS module for generating e-mail messages that can be\nstreamed to SMTP or file. \n\nThis is a standalone module that only generates raw e-mail source, you need to \nwrite your own or use an existing transport mechanism (SMTP client, Amazon SES, \nSendGrid etc). **mailcomposer** frees you from the tedious task of generating \n[rfc2822](http://tools.ietf.org/html/rfc2822) compatible messages.\n\n[![Build Status](https://secure.travis-ci.org/andris9/mailcomposer.png)](http://travis-ci.org/andris9/mailcomposer)\n\n**mailcomposer** supports:\n\n * **Unicode** to use any characters ✔\n * **HTML** content as well as **plain text** alternative\n * **Attachments** and streaming for larger files (use strings, buffers, files or binary streams as attachments)\n * **Embedded images** in HTML\n * **DKIM** signing\n * usage of **your own** transport mechanism\n\n## Support mailcomposer development\n\n[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)\n\n## Installation\n\nInstall through NPM\n\n npm install mailcomposer\n\n## Usage\n\n### Include mailcomposer module\n\n var MailComposer = require(\"mailcomposer\").MailComposer;\n\n### Create a new `MailComposer` instance\n\n var mailcomposer = new MailComposer([options]);\n\nWhere `options` is an optional options object with the following possible properties:\n\n * **escapeSMTP** - if set replaces dots in the beginning of a line with double dots\n * **encoding** - sets transfer encoding for the textual parts (defaults to `\"quoted-printable\"`)\n * **charset** - sets output character set for strings (defaults to `\"utf-8\"`)\n * **keepBcc** - if set to true, includes `Bcc:` field in the message headers. Useful for *sendmail* command.\n * **forceEmbeddedImages** - convert image urls and absolute paths in HTML to embedded attachments.\n\n### Simple example\n\nThe following example generates a simple e-mail message with plaintext and html\nbody.\n\n var MailComposer = require(\"mailcomposer\").MailComposer;\n mailcomposer = new MailComposer(),\n fs = require(\"fs\");\n \n // add additional header field\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n \n // setup message data\n mailcomposer.setMessageOption({\n from: \"andris@tr.ee\",\n to: \"andris@node.ee\",\n body: \"Hello world!\",\n html: \"Hello world!\"\n }); \n \n mailcomposer.streamMessage();\n \n // pipe the output to a file\n mailcomposer.pipe(fs.createWriteStream(\"test.eml\"));\n\nThe output for such a script (the contents for \"test.eml\") would look like:\n\n MIME-Version: 1.0\n X-Mailer: Nodemailer 1.0\n From: andris@tr.ee\n To: andris@node.ee\n Content-Type: multipart/alternative;\n boundary=\"----mailcomposer-?=_1-1328088797399\"\n \n ------mailcomposer-?=_1-1328088797399\n Content-Type: text/plain; charset=utf-8\n Content-Transfer-Encoding: quoted-printable\n \n Hello world!\n ------mailcomposer-?=_1-1328088797399\n Content-Type: text/html; charset=utf-8\n Content-Transfer-Encoding: quoted-printable\n \n Hello world!\n ------mailcomposer-?=_1-1328088797399--\n\n## API\n\n### Add custom headers\n\nHeaders can be added with `mailcomposer.addHeader(key, value)`\n\n var mailcomposer = new MailComposer();\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n\nIf you add an header value with the same key several times, all of the values will be used\nin the generated header. For example:\n\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 1.0\");\n mailcomposer.addHeader(\"x-mailer\", \"Nodemailer 2.0\");\n \nWill be generated into\n\n ...\n X-Mailer: Nodemailer 1.0\n X-Mailer: Nodemailer 2.0\n ...\n\nThe contents of the field value is not edited in any way (except for the folding),\nso if you want to use unicode symbols you need to escape these to mime words\nby yourself. Exception being object values - in this case the object\nis automatically JSONized and mime encoded.\n\n // using objects as header values is allowed (will be converted to JSON)\n var apiOptions = {};\n apiOptions.category = \"newuser\";\n apiOptions.tags = [\"user\", \"web\"];\n mailcomposer.addHeader(\"X-SMTPAPI\", apiOptions)\n\n### Add message parts\n\nYou can set message sender, receiver, subject line, message body etc. with\n`mailcomposer.setMessageOption(options)` where options is an object with the\ndata to be set. This function overwrites any previously set values with the\nsame key\n\nThe following example creates a simple e-mail with sender being `andris@tr.ee`, \nreceiver `andris@node.ee` and plaintext part of the message as `Hello world!`:\n\n mailcomposer.setMessageOption({\n from: \"andris@tr.ee\",\n to: \"andris@node.ee\",\n body: \"Hello world!\"\n }); \n\nPossible options that can be used are (all fields accept unicode):\n\n * **from** (alias `sender`) - the sender of the message. If several addresses are given, only the first one will be used\n * **to** - receivers for the `To:` field\n * **cc** - receivers for the `Cc:` field\n * **bcc** - receivers for the `Bcc:` field\n * **replyTo** (alias `reply_to`) - e-mail address for the `Reply-To:` field\n * **inReplyTo** - The message-id this message is replying\n * **references** - Message-id list\n * **subject** - the subject line of the message\n * **body** (alias `text`) - the plaintext part of the message\n * **html** - the HTML part of the message\n * **envelope** - optional SMTP envelope, if auto generated envelope is not suitable\n\nThis method can be called several times\n\n mailcomposer.setMessageOption({from: \"andris@tr.ee\"});\n mailcomposer.setMessageOption({to: \"andris@node.ee\"});\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n\nTrying to set the same key several times will yield in overwrite\n\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n mailcomposer.setMessageOption({body: \"Hello world?\"});\n // body contents will be \"Hello world?\"\n\n### Address format\n\nAll e-mail address fields take structured e-mail lists (comma separated)\nas the input. Unicode is allowed for all the parts (receiver name, e-mail username\nand domain) of the address. If the domain part contains unicode symbols, it is\nautomatically converted into punycode, user part will be converted into UTF-8\nmime word.\n\nE-mail addresses can be a plain e-mail addresses\n\n username@example.com\n\nor with a formatted name\n\n 'Ðоде Майлер' \n\nOr in case of comma separated lists, the formatting can be mixed\n\n username@example.com, 'Ðоде Майлер' , \"Name, User\" \n\n### SMTP envelope\n\nSMTP envelope is usually auto generated from `from`, `to`, `cc` and `bcc` fields but\nif for some reason you want to specify it yourself, you can do it with `envelope` property.\n\n`envelope` is an object with the following params: `from`, `to`, `cc` and `bcc` just like\nwith regular mail options. You can also use the regular address format.\n\n mailOptions = {\n ...,\n from: \"mailer@node.ee\",\n to: \"daemon@node.ee\",\n envelope: {\n from: \"Daemon \",\n to: \"mailer@node.ee, Mailer \"\n }\n }\n\n### Add attachments\n\nAttachments can be added with `mailcomposer.addAttachment(attachment)` where\n`attachment` is an object with attachment (meta)data with the following possible\nproperties:\n\n * **fileName** (alias `filename`) - filename to be reported as the name of the attached file, use of unicode is allowed\n * **cid** - content id for using inline images in HTML message source\n * **contents** - String or a Buffer contents for the attachment\n * **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments)\n * **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*)\n * **contentType** - content type for the attachment, if not set will be derived from the `fileName` property\n * **contentDisposition** - content disposition type for the attachment, defaults to \"attachment\" \n * **userAgent** - User-Agent string to be used if the fileName points to an URL\n\nOne of `contents`, `filePath` or `streamSource` must be specified, if none is \npresent, the attachment will be discarded. Other fields are optional.\n\nAttachments can be added as many as you want.\n\n**Using embedded images in HTML**\n\nAttachments can be used as embedded images in the HTML body. To use this \nfeature, you need to set additional property of the attachment - `cid` \n(unique identifier of the file) which is a reference to the attachment file. \nThe same `cid` value must be used as the image URL in HTML (using `cid:` as \nthe URL protocol, see example below).\n\nNB! the cid value should be as unique as possible!\n\n var cid_value = Date.now() + '.image.jpg';\n \n var html = 'Embedded image: ';\n \n var attachment = {\n fileName: \"image.png\",\n filePath: \"/static/images/image.png\",\n cid: cid_value\n };\n\n**Automatic embedding images**\n\nIf you want to convert images in the HTML to embedded images automatically, you can\nset mailcomposer option `forceEmbeddedImages` to true. In this case all images in\nthe HTML that are either using an absolute URL (http://...) or absolute file path\n(/path/to/file) are replaced with embedded attachments.\n\nFor example when using this code\n\n var mailcomposer = new MailComposer({forceEmbeddedImages: true});\n mailcomposer.setMessageOption({\n html: 'Embedded image: '\n });\n\nThe image linked is fetched and added automatically as an attachment and the url \nin the HTML is replaced automatically with a proper `cid:` string.\n\n### Add alternatives to HTML and text\n\nIn addition to text and HTML, any kind of data can be inserted as an alternative content of the main body - for example a word processing document with the same text as in the HTML field. It is the job of the e-mail client to select and show the best fitting alternative to the reader. \n\nAlternatives to text and HTML can be added with `mailcomposer.addAlternative(alternative)` where\n`alternative` is an object with alternative (meta)data with the following possible\nproperties:\n\n * **contents** - String or a Buffer contents for the attachment\n * **contentType** - optional content type for the attachment, if not set will be set to \"application/octet-stream\"\n * **contentEncoding** - optional value of how the data is encoded, defaults to \"base64\" \n\nIf `contents` is empty, the alternative will be discarded. Other fields are optional.\n\n**Usage example:**\n\n // add HTML \"alternative\"\n mailcomposer.setMessageOption({\n html: \"Hello world!\"\n });\n\n // add Markdown alternative\n mailcomposer.addAlternative({\n contentType: \"text/x-web-markdown\",\n contents: \"**Hello world!**\"\n });\n\nIf the receiving e-mail client can render messages in Markdown syntax as well, it could prefer\nto display this alternative as the main content of the message.\n\nAlternatives can be added as many as you want.\n\n### DKIM Signing\n\n**mailcomposer** supports DKIM signing with very simple setup. Use this with caution \nthough since the generated message needs to be buffered entirely before it can be\nsigned - in this case the streaming capability offered by mailcomposer is illusionary,\nthere will only be one `'data'` event with the entire message. Not a big deal with\nsmall messages but might consume a lot of RAM when using larger attachments.\n\nSet up the DKIM signing with `useDKIM` method:\n\n mailcomposer.useDKIM(dkimOptions)\n\nWhere `dkimOptions` includes necessary options for signing\n\n * **domainName** - the domainname that is being used for signing\n * **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.example.com* then `zzz` is the selector\n * **privateKey** - DKIM private key that is used for signing as a string\n * **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used\n\n**NB!** Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.\n\nExample:\n\n mailcomposer.setMessageOption({from: \"andris@tr.ee\"});\n mailcomposer.setMessageOption({to: \"andris@node.ee\"});\n mailcomposer.setMessageOption({body: \"Hello world!\"});\n mailcomposer.useDKIM({\n domainName: \"node.ee\",\n keySelector: \"dkim\",\n privateKey: fs.readFileSync(\"private_key.pem\")\n });\n\n### Start streaming\n\nWhen the message data is setup, streaming can be started. After this it is not\npossible to add headers, attachments or change body contents.\n\n mailcomposer.streamMessage();\n\nThis generates `'data'` events for the message headers and body and final `'end'` event.\nAs `MailComposer` objects are Stream instances, these can be piped\n\n // save the output to a file\n mailcomposer.streamMessage();\n mailcomposer.pipe(fs.createWriteStream(\"out.txt\"));\n\n### Compile the message in one go\n\nIf you do not want to use the streaming possibilities, you can compile the entire\nmessage into a string in one go with `buildMessage`.\n\n mailcomposer.buildMessage(function(err, messageSource){\n console.log(err || messageSource);\n });\n\nThe function is actually just a wrapper around `streamMessage` and emitted events.\n\n## Envelope\n\nEnvelope can be generated with an `getEnvelope()` which returns an object\nthat includes a `from` address (string) and a list of `to` addresses (array of\nstrings) suitable for forwarding to a SMTP server as `MAIL FROM:` and `RCPT TO:`.\n\n console.log(mailcomposer.getEnvelope());\n // {from:\"sender@example.com\", to:[\"receiver@example.com\"]}\n\n**NB!** both `from` and `to` properties might be missing from the envelope object\nif corresponding addresses were not detected from the e-mail.\n\n## Running tests\n\nTests are run with [nodeunit](https://github.com/caolan/nodeunit)\n\nRun\n\n npm test\n\n## License\n\n**MIT**\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/mailcomposer/issues" - }, - "_id": "mailcomposer@0.1.33", - "_from": "mailcomposer@~0.1" -} diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js b/api/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js deleted file mode 100644 index 3703ec91f33..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/test/dkim.js +++ /dev/null @@ -1,47 +0,0 @@ -var testCase = require('nodeunit').testCase, - dkim = require("../lib/dkim"), - fs = require("fs"); - - -exports["Canonicalizer tests"] = { - "Relaxed body": function(test){ - // dkim.org samples - var body = " C \r\nD \t E\r\n\r\n\r\n"; - test.equal(" C\r\nD E\r\n", dkim.DKIMCanonicalizer.relaxedBody(body)); - test.done(); - }, - "Relaxed body short": function(test){ - // dkim.org samples - var body = " C \r\nD \t E"; - test.equal(" C\r\nD E\r\n", dkim.DKIMCanonicalizer.relaxedBody(body)); - test.done(); - }, - "Relaxed headers": function(test){ - var headers = "A: X\r\nB: Y\t\r\n\tZ \r\n"; - test.equal("a:X\r\nb:Y Z\r\n", dkim.DKIMCanonicalizer.relaxedHeaders(headers, "a:b").headers); - test.done(); - } -} - -exports["General tests"] = { - "Unicode domain": function(test){ - var mail = "From: andris@node.ee\r\nTo:andris@kreata.ee\r\n\r\nHello world!"; - var dkimField = dkim.DKIMSign(mail,{ - domainName: "müriaad-polüteism.info", - keySelector: "dkim", - privateKey: fs.readFileSync(__dirname+"/test_private.pem") - }); - test.equal(dkimField.replace(/\r?\n\s*/g, "").replace(/\s+/g, ""), "DKIM-Signature:v=1;a=rsa-sha256;c=relaxed/relaxed;d=xn--mriaad-polteism-zvbj.info;q=dns/txt;s=dkim;bh=z6TUz85EdYrACGMHYgZhJGvVy5oQI0dooVMKa2ZT7c4=;h=from:to;b=oBJ1MkwEkftfXa2AK4Expjp2xgIcAR43SVrftSEHVQ6F1SlGjP3EKP+cn/hLkhUel3rY0icthk/myDu6uhTBmM6DMtzIBW/7uQd6q9hfgaiYnw5Iew2tZc4TzBEYSdKi") - test.done(); - }, - "Normal domain": function(test){ - var mail = "From: andris@node.ee\r\nTo:andris@kreata.ee\r\n\r\nHello world!"; - var dkimField = dkim.DKIMSign(mail,{ - domainName: "node.ee", - keySelector: "dkim", - privateKey: fs.readFileSync(__dirname+"/test_private.pem") - }); - test.equal(dkimField.replace(/\r?\n\s*/g, "").replace(/\s+/g, ""), "DKIM-Signature:v=1;a=rsa-sha256;c=relaxed/relaxed;d=node.ee;q=dns/txt;s=dkim;bh=z6TUz85EdYrACGMHYgZhJGvVy5oQI0dooVMKa2ZT7c4=;h=from:to;b=pVd+Dp+EjmYBcc1AWlBAP4ESpuAJ2WMS4gbxWLoeUZ1vZRodVN7K9UXvcCsLuqjJktCZMN2+8dyEUaYW2VIcxg4sVBCS1wqB/tqYZ/gxXLnG2/nZf4fyD2vxltJP4pDL"); - test.done(); - } -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/image3.png b/api/node_modules/nodemailer/node_modules/mailcomposer/test/image3.png deleted file mode 100644 index ee8d8c3b5fb..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/mailcomposer/test/image3.png and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js b/api/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js deleted file mode 100644 index afdb5aef17e..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/test/mailcomposer.js +++ /dev/null @@ -1,1289 +0,0 @@ -var testCase = require('nodeunit').testCase, - MailComposer = require("../lib/mailcomposer").MailComposer, - toPunycode = require("../lib/punycode"), - MailParser = require("mailparser").MailParser, - fs = require("fs"), - mime = require("mime"), - http = require("http"); - - -var HTTP_PORT = 9437; - -exports["General tests"] = { - - "Create a new MailComposer object": function(test){ - var mailcomposer = new MailComposer(); - test.equal(typeof mailcomposer.on, "function"); - test.equal(typeof mailcomposer.emit, "function"); - test.done(); - }, - - "Normalize key names": function(test){ - var normalizer = MailComposer.prototype._normalizeKey; - - test.equal(normalizer("abc"), "Abc"); - test.equal(normalizer("aBC"), "Abc"); - test.equal(normalizer("ABC"), "Abc"); - test.equal(normalizer("a-b-c"), "A-B-C"); - test.equal(normalizer("ab-bc"), "Ab-Bc"); - test.equal(normalizer("ab-bc-cd"), "Ab-Bc-Cd"); - test.equal(normalizer("AB-BC-CD"), "Ab-Bc-Cd"); - test.equal(normalizer("mime-version"), "MIME-Version"); // special case - - test.done(); - }, - - "Add header": function(test){ - var mc = new MailComposer(); - test.equal(typeof mc._headers["Test-Key"], "undefined"); - mc.addHeader("test-key", "first"); - test.equal(mc._headers["Test-Key"], "first"); - mc.addHeader("test-key", "second"); - test.deepEqual(mc._headers["Test-Key"], ["first","second"]); - mc.addHeader("test-key", "third"); - test.deepEqual(mc._headers["Test-Key"], ["first","second","third"]); - test.done(); - }, - - "Get header": function(test){ - var mc = new MailComposer(); - test.equal(mc._getHeader("MIME-Version"), "1.0"); - test.equal(mc._getHeader("test-key"), ""); - mc.addHeader("test-key", "first"); - test.equal(mc._getHeader("test-key"), "first"); - mc.addHeader("test-key", "second"); - test.deepEqual(mc._getHeader("test-key"), ["first", "second"]); - test.done(); - }, - - "Uppercase header keys": function(test){ - var mc = new MailComposer(); - - mc.addHeader("X-TEST", "first"); - test.equal(mc._headers["X-TEST"], "first"); - - mc.addHeader("TEST", "second"); - test.equal(mc._headers["Test"], "second"); - - test.done(); - }, - - "Set object header": function(test){ - var mc = new MailComposer(); - - var testObj = { - stringValue: "String with unicode symbols: ÕÄÖÜŽŠ", - arrayValue: ["hello ÕÄÖÜ", 12345], - objectValue: { - customerId: "12345" - } - }; - - mc.addHeader("x-mytest-string", "first"); - mc.addHeader("x-mytest-json", testObj); - - mc.streamMessage(); - - //mc.on("data", function(c){console.log(c.toString("utf-8"))}) - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.headers['x-mytest-string'], "first"); - test.deepEqual(JSON.parse(mail.headers['x-mytest-json']), testObj); - //console.log(mail) - test.done(); - }); - }, - - "Add message option": function(test){ - var mc = new MailComposer(); - test.equal(typeof mc._message.subject, "undefined"); - - mc.setMessageOption({ - subject: "Test1", - body: "Test2", - nonexistent: "Test3" - }); - - test.equal(mc._message.subject, "Test1"); - test.equal(mc._message.body, "Test2"); - test.equal(typeof mc._message.nonexistent, "undefined"); - - mc.setMessageOption({ - subject: "Test4" - }); - - test.equal(mc._message.subject, "Test4"); - test.equal(mc._message.body, "Test2"); - - test.done(); - }, - - "Detect mime type": function(test){ - var mc = new MailComposer(); - - test.equal(mime.lookup("test.txt"), "text/plain"); - test.equal(mime.lookup("test.unknown"), "application/octet-stream"); - - test.done(); - }, - - "keepBcc off": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({bcc: "andris@node.ee"}); - mc._buildMessageHeaders(); - test.ok(!mc._getHeader("Bcc")); - test.done(); - }, - - "keepBcc on": function(test){ - var mc = new MailComposer({keepBcc: true}); - mc.setMessageOption({bcc: "andris@node.ee"}); - mc._buildMessageHeaders(); - test.equal(mc._getHeader("Bcc"), "andris@node.ee"); - test.done(); - }, - - "zero length cc": function(test){ - var mc = new MailComposer({keepBcc: true}); - mc.setMessageOption({cc: ""}); - mc._buildMessageHeaders(); - test.equal(mc._getHeader("cc"), ""); - test.done(); - } -}; - - -exports["Text encodings"] = { - "Punycode": function(test){ - test.equal(toPunycode("andris@age.ee"), "andris@age.ee"); - test.equal(toPunycode("andris@äge.ee"), "andris@xn--ge-uia.ee"); - test.done(); - }, - - "Mime words": function(test){ - var mc = new MailComposer(); - test.equal(mc._encodeMimeWord("Tere"), "Tere"); - test.equal(mc._encodeMimeWord("Tere","Q"), "Tere"); - test.equal(mc._encodeMimeWord("Tere","B"), "Tere"); - - // simple - test.equal(mc._encodeMimeWord("äss"), "=?UTF-8?Q?=C3=A4ss?="); - test.equal(mc._encodeMimeWord("äss","B"), "=?UTF-8?B?"+(new Buffer("äss","utf-8").toString("base64"))+"?="); - - //multiliple - test.equal(mc._encodeMimeWord("äss tekst on see siin või kuidas?","Q", 20), "=?UTF-8?Q?=C3=A4ss?= tekst on see siin =?UTF-8?Q?v=C3=B5i?= kuidas?"); - - test.done(); - }, - - "Addresses": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" ' - }); - - test.equal(mc._message.from, "\"Jaanuar Veebruar, =?UTF-8?Q?M=C3=A4rts?=\" <=?UTF-8?Q?m=C3=A4rts?=@xn--mrts-loa.eu>"); - - mc.setMessageOption({ - sender: 'aavik ' - }); - - test.equal(mc._message.from, '"aavik" '); - - mc.setMessageOption({ - sender: '' - }); - - test.equal(mc._message.from, 'aavik@node.ee'); - - mc.setMessageOption({ - sender: '' - }); - - test.equal(mc._message.from, 'aavik@xn--mrts-loa.eu'); - - // multiple - - mc.setMessageOption({ - sender: ', juulius@node.ee, "Node, Master" ' - }); - - test.equal(mc._message.from, 'aavik@xn--mrts-loa.eu, juulius@node.ee, "Node, Master" '); - - mc.setMessageOption({ - sender: ['', 'juulius@node.ee, "Node, Master" ', 'andris@node.ee'] - }); - - mc.setMessageOption({ - to: ['', 'juulius@node.ee, "Node, Master" ', 'andris@node.ee'] - }); - - test.equal(mc._message.from, 'aavik@xn--mrts-loa.eu, juulius@node.ee, "Node, Master" , andris@node.ee'); - test.equal(mc._message.to, 'aavik@xn--mrts-loa.eu, juulius@node.ee, "Node, Master" , andris@node.ee'); - - test.done(); - }, - - "Invalid subject": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - subject: "tere\ntere!" - }); - - test.equal(mc._message.subject, "tere tere!"); - test.done(); - }, - - "Long header line": function(test){ - var mc = new MailComposer(); - - mc._headers = { - From: "a very log line, \"=?UTF-8?Q?Jaanuar_Veebruar,_M=C3=A4rts?=\" <=?UTF-8?Q?m=C3=A4rts?=@xn--mrts-loa.eu>" - }; - - mc.on("data", function(chunk){ - test.ok(chunk.toString().trim().match(/From\:\s[^\r\n]+\r\n\s+[^\r\n]+/)); - test.done(); - }); - mc._composeHeader(); - - } - -}; - -exports["Mail related"] = { - "Envelope": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" ', - to: ', juulius@node.ee', - cc: '"Node, Master" ' - }); - - test.deepEqual(mc._envelope, {from:[ 'märts@xn--mrts-loa.eu' ],to:[ 'aavik@xn--mrts-loa.eu', 'juulius@node.ee'], cc:['node@node.ee' ]}); - test.done(); - }, - - "User defined envelope": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" ', - envelope: { - from: "Andris ", - to: ["Andris , Node ", "aavik@märts.eu", "juulius@gmail.com"], - cc: "trips@node.ee" - }, - to: ', juulius@node.ee', - cc: '"Node, Master" ' - }); - - test.deepEqual(mc._envelope, {userDefined: true, from:[ 'andris@tr.ee' ],to:[ 'andris@tr.ee', 'andris@node.ee', 'aavik@xn--mrts-loa.eu', 'juulius@gmail.com'], "cc":['trips@node.ee']}); - test.done(); - }, - - "Add alternative": function(test){ - var mc = new MailComposer(); - mc.addAlternative(); - test.equal(mc._alternatives.length, 0); - - mc.addAlternative({contents:"tere tere"}); - test.equal(mc._alternatives.length, 1); - - test.equal(mc._alternatives[0].contentType, "application/octet-stream"); - test.equal(mc._alternatives[0].contentEncoding, "base64"); - test.equal(mc._alternatives[0].contents, "tere tere"); - - mc.addAlternative({contents:"tere tere", contentType:"text/plain", contentEncoding:"7bit"}); - test.equal(mc._alternatives[1].contentType, "text/plain"); - test.equal(mc._alternatives[1].contentEncoding, "7bit"); - - test.done(); - }, - - "Add attachment": function(test){ - var mc = new MailComposer(); - mc.addAttachment(); - test.equal(mc._attachments.length, 0); - - mc.addAttachment({filePath:"/tmp/var.txt"}); - test.equal(mc._attachments[0].contentType, "text/plain"); - test.equal(mc._attachments[0].fileName, "var.txt"); - - mc.addAttachment({contents:"/tmp/var.txt"}); - test.equal(mc._attachments[1].contentType, "application/octet-stream"); - test.equal(mc._attachments[1].fileName, undefined); - - mc.addAttachment({filePath:"/tmp/var.txt", fileName:"test.txt"}); - test.equal(mc._attachments[2].fileName, "test.txt"); - - test.done(); - }, - - "Default attachment disposition": function(test){ - var mc = new MailComposer(); - mc.addAttachment(); - test.equal(mc._attachments.length, 0); - - mc.addAttachment({filePath:"/tmp/var.txt"}); - test.equal(mc._attachments[0].contentDisposition, undefined); - - test.done(); - }, - - "Set attachment disposition": function(test){ - var mc = new MailComposer(); - mc.addAttachment(); - test.equal(mc._attachments.length, 0); - - mc.addAttachment({filePath:"/tmp/var.txt", contentDisposition: "inline"}); - test.equal(mc._attachments[0].contentDisposition, "inline"); - - test.done(); - }, - - "Generate envelope": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" , karu@ahven.ee', - to: ', juulius@node.ee', - cc: '"Node, Master" ' - }); - - test.deepEqual(mc.getEnvelope(), {from: 'märts@xn--mrts-loa.eu',to:[ 'aavik@xn--mrts-loa.eu', 'juulius@node.ee', 'node@node.ee' ], stamp: 'Postage paid, Par Avion'}); - test.done(); - }, - - "Generate user defined envelope": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" , karu@ahven.ee', - to: ', juulius@node.ee', - envelope: { - from: "Andris ", - to: ["Andris , Node ", "aavik@märts.eu", "juulius@gmail.com"], - cc: "trips@node.ee" - }, - cc: '"Node, Master" ' - }); - - test.deepEqual(mc.getEnvelope(), {from: 'andris@tr.ee', to:[ 'andris@tr.ee', 'andris@node.ee', 'aavik@xn--mrts-loa.eu', 'juulius@gmail.com', 'trips@node.ee'], stamp: 'Postage paid, Par Avion'}); - test.done(); - }, - - "Generate Headers": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - sender: '"Jaanuar Veebruar, Märts" , karu@ahven.ee', - to: ', juulius@node.ee', - cc: '"Node, Master" ', - replyTo: 'julla@pulla.ee', - subject: "Tere õkva!" - }); - - mc.on("data", function(chunk){ - chunk = (chunk || "").toString("utf-8"); - test.ok(chunk.match(/^(?:(?:[\s]+|[a-zA-Z0-0\-]+\:)[^\r\n]+\r\n)+\r\n$/)); - test.done(); - }); - - mc._composeHeader(); - } -}; - -exports["Mime tree"] = { - "No contents": function(test){ - test.expect(4); - - var mc = new MailComposer(); - mc._composeMessage(); - - test.ok(!mc._message.tree.boundary); - test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "text/plain"); - test.equal(mc._message.tree.childNodes.length, 0); - - for(var i=0, len = mc._message.flatTree.length; itest" - }); - mc._composeMessage(); - - test.ok(!mc._message.tree.boundary); - test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "text/html"); - test.equal(mc._message.tree.childNodes.length, 0); - - for(var i=0, len = mc._message.flatTree.length; itest"); - } - } - - test.done(); - }, - "HTML and text contents": function(test){ - test.expect(5); - - var mc = new MailComposer(); - mc.setMessageOption({ - body: "test", - html: "test" - }); - mc._composeMessage(); - - test.equal(mc._message.tree.childNodes.length, 2); - test.equal(mc._getHeader("Content-Type").split(";").shift().trim(), "multipart/alternative"); - test.ok(mc._message.tree.boundary); - - for(var i=0, len = mc._message.flatTree.length; itest" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.html.trim(), "test"); - test.done(); - }); - }, - "HTML and text": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "test", - body: "test" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.text.trim(), "test"); - test.equal(mail.html.trim(), "test"); - test.done(); - }); - }, - "Flowed text": function(test){ - var mc = new MailComposer({encoding:"8bit"}), - file = fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8"); - - mc.setMessageOption({ - body: file - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.text.trim(), file.trim()); - test.done(); - }); - }, - "Attachment as string": function(test){ - var mc = new MailComposer(); - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "Attachment as buffer": function(test){ - var mc = new MailComposer(); - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - contents: fs.readFileSync(__dirname+"/textfile.txt") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "Attachment file stream": function(test){ - var mc = new MailComposer(); - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - filePath: __dirname+"/textfile.txt" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "Attachment source stream": function(test){ - var mc = new MailComposer(); - - var fileStream = fs.createReadStream(__dirname+"/textfile.txt"); - - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - streamSource: fileStream - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "Attachment source url": function(test){ - - var server = http.createServer(function (req, res) { - if(req.url=="/textfile.txt"){ - fs.createReadStream(__dirname+"/textfile.txt").pipe(res); - }else{ - res.writeHead(404, {'Content-Type': 'text/plain'}); - res.end('Not found!\n'); - } - }); - server.listen(HTTP_PORT, '127.0.0.1'); - - var mc = new MailComposer(); - - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - server.close(); - test.done(); - }); - }, - "Attachment source invalid url": function(test){ - - var server = http.createServer(function (req, res) { - res.writeHead(404, {'Content-Type': 'text/plain'}); - res.end('Not found!\n'); - }); - server.listen(HTTP_PORT, '127.0.0.1'); - - var mc = new MailComposer(); - - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].checksum, "3995d423c7453e472ce0d54e475bae3e"); - server.close(); - test.done(); - }); - }, - "Custom User-Agent": function(test){ - - var server = http.createServer(function (req, res) { - test.equal(req.headers['user-agent'], "test"); - - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('OK!\n'); - }) - server.listen(HTTP_PORT, '127.0.0.1'); - - var mc = new MailComposer(); - - mc.setMessageOption(); - mc.addAttachment({ - fileName: "file.txt", - filePath: "http://localhost:"+HTTP_PORT+"/textfile.txt", - userAgent: "test" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - server.close(); - test.done(); - }); - }, - "escape SMTP": function(test){ - var mc = new MailComposer({escapeSMTP: true}); - mc.setMessageOption({ - body: ".\r\n." - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.text.trim(), "..\n.."); - test.done(); - }); - }, - "don't escape SMTP": function(test){ - var mc = new MailComposer({escapeSMTP: false}); - mc.setMessageOption({ - body: ".\r\n." - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.text.trim(), ".\n."); - test.done(); - }); - }, - "HTML and text and attachment": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "test", - body: "test" - }); - mc.addAttachment({ - fileName: "file.txt", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.text.trim(), "test"); - test.equal(mail.html.trim(), "test"); - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "HTML and related attachment": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "" - }); - mc.addAttachment({ - fileName: "file.txt", - cid: "test@node", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - /* - var d = ""; - mc.on("data", function(data){ - d += data.toString(); - }) - - mc.on("end", function(){ - console.log(d); - }); - */ - - mp.on("end", function(mail){ - test.equal(mc._attachments.length, 0); - test.equal(mc._relatedAttachments.length, 1); - test.equal(mail.html.trim(), ""); - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "HTML and related plus regular attachment": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "" - }); - mc.addAttachment({ - fileName: "file.txt", - cid: "test@node", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.addAttachment({ - fileName: "file.txt", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mc._attachments.length, 1); - test.equal(mc._relatedAttachments.length, 1); - test.equal(mail.html.trim(), ""); - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.equal(mail.attachments[1].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "HTML and text related attachment": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "", - text:"test" - }); - mc.addAttachment({ - fileName: "file.txt", - cid: "test@node", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mc._attachments.length, 0); - test.equal(mc._relatedAttachments.length, 1); - test.equal(mail.text.trim(), "test"); - test.equal(mail.html.trim(), ""); - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "HTML, text, related+regular attachment": function(test){ - var mc = new MailComposer(); - mc.setMessageOption({ - html: "", - text:"test" - }); - mc.addAttachment({ - fileName: "file.txt", - cid: "test@node", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.addAttachment({ - fileName: "file.txt", - contents: fs.readFileSync(__dirname+"/textfile.txt").toString("utf-8") - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mc._attachments.length, 1); - test.equal(mc._relatedAttachments.length, 1); - test.equal(mail.text.trim(), "test"); - test.equal(mail.html.trim(), ""); - test.equal(mail.attachments[0].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.equal(mail.attachments[1].checksum, "59fbcbcaf18cb9232f7da6663f374eb9"); - test.done(); - }); - }, - "Only alternative": function(test){ - var mc = new MailComposer(); - mc.addAlternative({ - contents: "tere tere" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.attachments.length, 1) - test.equal(mail.attachments[0].content.toString(), "tere tere") - test.equal(mail.attachments[0].contentType, "application/octet-stream") - test.done(); - }); - }, - "References Header": function(test){ - - var mc = new MailComposer(); - mc.setMessageOption({ - references: ["myrdo", "vyrdo"] - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.deepEqual(mail.references, ["myrdo", "vyrdo"]); - test.done(); - }); - }, - "InReplyTo Header": function(test){ - - var mc = new MailComposer(); - mc.setMessageOption({ - inReplyTo: "test" - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.inReplyTo, "test"); - test.done(); - }); - }, - "Non UTF-8 charset": function(test){ - var mc = new MailComposer({charset: "iso-8859-1"}), - message = "", - mp = new MailParser(), - subject = "Jõgeva maakond, Ärni küla", - text = "Lõäöpõld Jääger Sußi", - fromName = "Mäger Mõksi", - from = fromName+" " - - mc.setMessageOption({ - subject: subject, - text: text, - from: from - }); - - mp.on("end", function(mail){ - //console.log(mail); - test.equal(mail.subject, subject); - test.equal((mail.text || "").trim(), text); - test.equal(fromName, mail.from && mail.from[0] && mail.from[0].name); - test.done(); - }); - - mc.on("data", function(chunk){ - message += chunk.toString("utf-8"); - }); - - mc.on("end", function(){ - //console.log(message) - test.ok(message.match(/J=F5geva/)); - test.ok(message.match(/=C4rni_k=FCla/)); - test.ok(message.match(/L=F5=E4=F6p=F5ld J=E4=E4ger Su=DFi/)); - test.ok(message.match(/M=E4ger_M=F5ksi/)); - - mp.end(message); - }); - mc.streamMessage(); - }, - "Convert image URL to embedded attachment": function(test){ - - var image1 = new Buffer("iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", "base64"), - image2 = new Buffer("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC", "base64"); - - var server = http.createServer(function (req, res) { - if(req.url=="/image1.png"){ - res.writeHead(200, {'Content-Type': 'image/png'}); - res.end(image1); - }else if(req.url=="/image2.png"){ - res.writeHead(200, {'Content-Type': 'image/png'}); - res.end(image2); - }else{ - res.writeHead(404, {'Content-Type': 'text/plain'}); - res.end('Not found!\n'); - } - }); - server.listen(HTTP_PORT, '127.0.0.1'); - - var mc = new MailComposer({ - forceEmbeddedImages: true - }); - - mc.setMessageOption({ - from: "andris@kreata.ee", - to: "andris@node.ee", - subject: "embedded images", - html: '

Embedded images:

\n'+ - '
    \n'+ - '
  • Embedded image1
  • \n'+ - '
  • Embedded image2
  • \n'+ - '
  • Embedded image1
  • \n'+ - '
' - }); - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - var str = ""; - mc.on("data", function(chunk){str += chunk.toString()}) - - mp.on("end", function(mail){ - test.equal(mail.attachments[0].content.toString("base64"), image1.toString("base64")); - test.equal(mail.attachments[1].content.toString("base64"), image2.toString("base64")); - test.equal(mail.attachments[2].checksum, "29445222b4f912167463b8c65e9a6420"); - server.close(); - test.done(); - }); - } -}; - -exports["Output buffering"] = { - "Use DKIM": function(test){ - var mc = new MailComposer(); - - mc.setMessageOption({ - from: "Andris Reinman ", - to: "Andris ", - html: "Hello world!", - subject: "Hello world!" - }); - - mc.useDKIM({ - domainName: "do-not-trust.node.ee", - keySelector: "dkim", - privateKey: fs.readFileSync(__dirname+"/test_private.pem") - }); - - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.headers['dkim-signature'].replace(/\s/g, ""), 'v=1;a=rsa-sha256;c=relaxed/relaxed;d=do-not-trust.node.ee;q=dns/txt;s=dkim;bh=88i0PUP3tj3X/n0QT6Baw8ZPSeHZPqT7J0EmE26pjng=;h=from:subject:to:mime-version:content-type:content-transfer-encoding;b=dtxxQLotrcarEA5nbgBJLBJQxSAHcfrNxxpItcXSj68ntRvxmjXt9aPZTbVrzfRYe+xRzP2FTGpS7js8iYpAZZ2N3DBRLVp4gyyKHB1oWMkg/EV92uPtnjQ3MlHMbxC0'); - test.done(); - }); - }, - - "Use DKIM with escapeSMTP": function(test){ - var mc = new MailComposer({escapeSMTP: true}); - - mc.setMessageOption({ - from: "Andris Reinman ", - to: "Andris ", - text: ".Hello World", - subject: "Hello world!" - }); - - mc.useDKIM({ - domainName: "do-not-trust.node.ee", - keySelector: "dkim", - privateKey: fs.readFileSync(__dirname+"/test_private.pem") - }); - - mc.streamMessage(); - - var mp = new MailParser(); - - mc.pipe(mp); - - mp.on("end", function(mail){ - test.equal(mail.headers['dkim-signature'].replace(/\s/g, ""), 'v=1;a=rsa-sha256;c=relaxed/relaxed;d=do-not-trust.node.ee;q=dns/txt;s=dkim;bh=G6F+AsXwSI9QevjP2K03mJc6ftXnKHR5egjeWd29Muo=;h=from:subject:to:mime-version:content-type:content-transfer-encoding;b=GY96OWF1PPjzRDpw/QSEz7OfbW/MWb4PO0nA6PJNtdpAPSUJMomz4klv99rrqW8z8xW1ha9LM+39EPUN7c29OTNPoRJ9ybb9F1lttfD0l7AETFboBEknrdMaouc+HYWA'); - test.done(); - }); - }, - - "Build message": function(test){ - var mc = new MailComposer(); - - mc.setMessageOption({ - from: "Andris Reinman ", - to: "Andris ", - html: "Hello world!", - subject: "Hello world!" - }); - - mc.useDKIM({ - domainName: "do-not-trust.node.ee", - keySelector: "dkim", - privateKey: fs.readFileSync(__dirname+"/test_private.pem") - }); - - mc.buildMessage(function(err, body){ - test.ifError(err); - var mp = new MailParser(); - - mp.on("end", function(mail){ - test.equal(mail.headers['dkim-signature'].replace(/\s/g, ""), 'v=1;a=rsa-sha256;c=relaxed/relaxed;d=do-not-trust.node.ee;q=dns/txt;s=dkim;bh=88i0PUP3tj3X/n0QT6Baw8ZPSeHZPqT7J0EmE26pjng=;h=from:subject:to:mime-version:content-type:content-transfer-encoding;b=dtxxQLotrcarEA5nbgBJLBJQxSAHcfrNxxpItcXSj68ntRvxmjXt9aPZTbVrzfRYe+xRzP2FTGpS7js8iYpAZZ2N3DBRLVp4gyyKHB1oWMkg/EV92uPtnjQ3MlHMbxC0'); - test.done(); - }); - - mp.end(body); - }); - - - } -} - diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem b/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem deleted file mode 100644 index 9d0326665b8..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_private.pem +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBywIBAAJhANCx7ncKUfQ8wBUYmMqq6ky8rBB0NL8knBf3+uA7q/CSxpX6sQ8N -dFNtEeEd7gu7BWEM7+PkO1P0M78eZOvVmput8BP9R44ARpgHY4V0qSCdUt4rD32n -wfjlGbh8p5ua5wIDAQABAmAm+uUQpQPTu7kg95wqVqw2sxLsa9giT6M8MtxQH7Uo -1TF0eAO0TQ4KOxgY1S9OT5sGPVKnag258m3qX7o5imawcuyStb68DQgAUg6xv7Af -AqAEDfYN5HW6xK+X81jfOUECMQDr7XAS4PERATvgb1B3vRu5UEbuXcenHDYgdoyT -3qJFViTbep4qeaflF0uF9eFveMcCMQDic10rJ8fopGD7/a45O4VJb0+lRXVdqZxJ -QzAp+zVKWqDqPfX7L93SQLzOGhdd7OECMQDeQyD7WBkjSQNMy/GF7I1qxrscIxNN -VqGTcbu8Lti285Hjhx/sqhHHHGwU9vB7oM8CMQDKTS3Kw/s/xrot5O+kiZwFgr+w -cmDrj/7jJHb+ykFNb7GaEkiSYqzUjKkfpweBDYECMFJUyzuuFJAjq3BXmGJlyykQ -TweUw+zMVdSXjO+FCPcYNi6CP1t1KoESzGKBVoqA/g== ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem b/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem deleted file mode 100644 index 2214c8004b9..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/test/test_public.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhANCx7ncKUfQ8wBUYmMqq6ky8rBB0NL8k -nBf3+uA7q/CSxpX6sQ8NdFNtEeEd7gu7BWEM7+PkO1P0M78eZOvVmput8BP9R44A -RpgHY4V0qSCdUt4rD32nwfjlGbh8p5ua5wIDAQAB ------END PUBLIC KEY----- diff --git a/api/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt b/api/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt deleted file mode 100644 index 3628c58b8be..00000000000 --- a/api/node_modules/nodemailer/node_modules/mailcomposer/test/textfile.txt +++ /dev/null @@ -1,601 +0,0 @@ -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -Some unicode symbols ÕÄÖÜ ↑, →, ↓, ↔, ↕, ↖, ↗, ↘, ↙, ↚, ↛, ↜, â†, ↞, ↟, ↠, ↡, ↢, ↣, ↤, ↥, ↦ - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." - -"Because I am scorched all over, Captain Ahab," answered Perth, resting for a moment on his hammer; "I am past scorching; not easily can'st thou scorch a scar." - -"Well, well; no more. Thy shrunk voice sounds too calmly, sanely woeful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad?—What wert thou making there?" - -"Welding an old pike-head, sir; there were seams and dents in it." - -"And can'st thou make it all smooth again, blacksmith, after such hard usage as it had?" - -"I think so, sir." - -"And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith?" - -"Aye, sir, I think I can; all seams and dents but one." - -"Look ye here, then," cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; "look ye here—HERE—can ye smoothe out a seam like this, blacksmith," sweeping one hand across his ribbed brow; "if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam?" - -"Oh! that is the one, sir! Said I not all seams and dents but one?" - -"Aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull—THAT is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here!" jingling the leathern bag, as if it were full of gold coins. "I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff," flinging the pouch upon the anvil. "Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses." diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/.npmignore b/api/node_modules/nodemailer/node_modules/simplesmtp/.npmignore deleted file mode 100644 index fd4f2b066b3..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.DS_Store diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml b/api/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml deleted file mode 100644 index 48c1cc912da..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js -node_js: - - 0.8 - - "0.10" - -notifications: - email: - recipients: - - andris@node.ee - on_success: change - on_failure: change diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/LICENSE b/api/node_modules/nodemailer/node_modules/simplesmtp/LICENSE deleted file mode 100644 index a47b0eaf959..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2012 Andris Reinman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/README.md b/api/node_modules/nodemailer/node_modules/simplesmtp/README.md deleted file mode 100644 index e07e93d3d33..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/README.md +++ /dev/null @@ -1,337 +0,0 @@ -# simplesmtp - -This is a module to easily create custom SMTP servers and clients - use SMTP as a first class protocol in Node.JS! - -[![Build Status](https://secure.travis-ci.org/andris9/simplesmtp.png)](http://travis-ci.org/andris9/simplesmtp) -[![NPM version](https://badge.fury.io/js/simplesmtp.png)](http://badge.fury.io/js/simplesmtp) - -## Version warning! - -If you are using node v0.6, then the last usable version of **simplesmtp** is v0.2.7 - -Current version of simplesmtp is fully supported for Node v0.8+ - -## Support simplesmtp development - -[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W) - -## SMTP Server - -## Simple SMTP server - -For a simple inbound only, no authentication SMT server you can use - - simplesmtp.createSimpleServer([options], requestListener).listen(port); - -Example - - simplesmtp.createSimpleServer({SMTPBanner:"My Server"}, function(req){ - req.pipe(process.stdout); - req.accept(); - }).listen(port); - -Properties - - * **req.from** - From address - * **req.to** - an array of To addresses - * **req.host** - hostname reported by the client - * **req.remodeAddress** - client IP address - -Methods - - * **req.accept** *([id])* - Accept the message with the selected ID - * **req.reject** *([message])* - Reject the message with the selected message - * **req.pipe** *(stream)* - Pipe the incoming data to a writable stream - -Events - - * **'data'** *(chunk)* - A chunk (Buffer) of the message. - * **'end'** - The message has been transferred - - -## Advanced SMTP server - -### Usage - -Create a new SMTP server instance with - - var smtp = simplesmtp.createServer([options]); - -And start listening on selected port - - smtp.listen(25, [function(err){}]); - -SMTP options can include the following: - - * **name** - the hostname of the server, will be used for informational messages - * **debug** - if set to true, print out messages about the connection - * **timeout** - client timeout in milliseconds, defaults to 60 000 (60 sec.) - * **secureConnection** - start a server on secure connection - * **SMTPBanner** - greeting banner that is sent to the client on connection - * **requireAuthentication** - if set to true, require that the client must authenticate itself - * **enableAuthentication** - if set to true, client may authenticate itself but don't have to (as opposed to `requireAuthentication` that explicitly requires clients to authenticate themselves) - * **maxSize** - maximum size of an e-mail in bytes (currently informational only) - * **credentials** - TLS credentials (`{key:'', cert:'', ca:['']}`) for the server - * **authMethods** - allowed authentication methods, defaults to `["PLAIN", "LOGIN"]` - * **disableEHLO** - if set to true, support HELO command only - * **ignoreTLS** - if set to true, allow client do not use STARTTLS - * **disableDNSValidation** - if set, do not validate sender domains - -### Example - - var simplesmtp = require("simplesmtp"), - fs = require("fs"); - - var smtp = simplesmtp.createServer(); - smtp.listen(25); - - smtp.on("startData", function(connection){ - console.log("Message from:", connection.from); - console.log("Message to:", connection.to); - connection.saveStream = fs.createWriteStream("/tmp/message.txt"); - }); - - smtp.on("data", function(connection, chunk){ - connection.saveStream.write(chunk); - }); - - smtp.on("dataReady", function(connection, callback){ - connection.saveStream.end(); - console.log("Incoming message saved to /tmp/message.txt"); - callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client - // callback(new Error("Rejected as spam!")); // reported back to the client - }); - -### Events - - * **startData** *(connection)* - DATA stream is opened by the client (`connection` is an object with `from`, `to`, `host` and `remoteAddress` properties) - * **data** *(connection, chunk)* - e-mail data chunk is passed from the client - * **dataReady** *(connection, callback)* - client is finished passing e-mail data, `callback` returns the queue id to the client - * **authorizeUser** *(connection, username, password, callback)* - will be emitted if `requireAuthentication` option is set to true. `callback` has two parameters *(err, success)* where `success` is Boolean and should be true, if user is authenticated successfully - * **validateSender** *(connection, email, callback)* - will be emitted if `validateSender` listener is set up - * **validateRecipient** *(connection, email, callback)* - will be emitted it `validataRecipients` listener is set up - * **close** *(connection)* - emitted when the connection to client is closed - -## SMTP Client - -### Usage - -SMTP client can be created with `simplesmptp.connect(port[,host][, options])` -where - - * **port** is the port to connect to - * **host** is the hostname to connect to (defaults to "localhost") - * **options** is an optional options object (see below) - -### Connection options - -The following connection options can be used with `simplesmtp.connect`: - - * **secureConnection** - use SSL - * **name** - the name of the client server - * **auth** - authentication object `{user:"...", pass:"..."}` or `{XOAuthToken:"base64data"}` - * **ignoreTLS** - ignore server support for STARTTLS - * **tls** - optional options object for `tls.connect`, also applies to STARTTLS. For example `rejectUnauthorized` is set to `false` by default. You can override this option by setting `tls: {rejectUnauthorized: true}` - * **debug** - output client and server messages to console - * **instanceId** - unique instance id for debugging (will be output console with the messages) - -### Connection events - -Once a connection is set up the following events can be listened to: - - * **'idle'** - the connection to the SMTP server has been successfully set up and the client is waiting for an envelope - * **'message'** - the envelope is passed successfully to the server and a message stream can be started - * **'ready'** `(success)` - the message was sent - * **'rcptFailed'** `(addresses)` - not all recipients were accepted (invalid addresses are included as an array) - * **'error'** `(err)` - An error occurred. The connection is closed and an 'end' event is emitted shortly - * **'end'** - connection to the client is closed - -### Sending an envelope - -When an `'idle'` event is emitted, an envelope object can be sent to the server. -This includes a string `from` and an array of strings `to` property. - -Envelope can be sent with `client.useEnvelope(envelope)` - - // run only once as 'idle' is emitted again after message delivery - client.once("idle", function(){ - client.useEnvelope({ - from: "me@example.com", - to: ["receiver1@example.com", "receiver2@example.com"] - }); - }); - -The `to` part of the envelope includes **all** recipients from `To:`, `Cc:` and `Bcc:` fields. - -If setting the envelope up fails, an error is emitted. If only some (not all) -recipients are not accepted, the mail can still be sent but an `rcptFailed` -event is emitted. - - client.on("rcptFailed", function(addresses){ - console.log("The following addresses were rejected: ", addresses); - }); - -If the envelope is set up correctly a `'message'` event is emitted. - -### Sending a message - -When `'message'` event is emitted, it is possible to send mail. To do this -you can pipe directly a message source (for example an .eml file) to the client -or alternatively you can send the message with `client.write` calls (you also -need to call `client.end()` once the message is completed. - -If you are piping a stream to the client, do not leave the `'end'` event out, -this is needed to complete the message sequence by the client. - - client.on("message", function(){ - fs.createReadStream("test.eml").pipe(client); - }); - -Once the message is delivered a `'ready'` event is emitted. The event has an -parameter which indicates if the message was transmitted( (true) or not (false) -and another which includes the last received data from the server. - - client.on("ready", function(success, response){ - if(success){ - console.log("The message was transmitted successfully with "+response); - } - }); - -### XOAUTH - -**simplesmtp** supports [XOAUTH2 and XOAUTH](https://developers.google.com/google-apps/gmail/oauth_protocol) authentication. - -#### XOAUTH2 - -To use this feature you can set `XOAuth2` param as an `auth` option - - var mailOptions = { - ..., - auth:{ - XOAuth2: { - user: "example.user@gmail.com", - clientId: "8819981768.apps.googleusercontent.com", - clientSecret: "{client_secret}", - refreshToken: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI", - accessToken: "vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==", - timeout: 3600 - } - } - } - -`accessToken` and `timeout` values are optional. If login fails a new access token is generated automatically. - -#### XOAUTH - -To use this feature you can set `XOAuthToken` param as an `auth` option - - var mailOptions = { - ..., - auth:{ - XOAuthToken: "R0VUIGh0dHBzOi8vbWFpbC5nb29...." - } - } - -Alternatively it is also possible to use XOAuthToken generators (supported by Nodemailer) - this -needs to be an object with a mandatory method `generate` that takes a callback function for -generating a XOAUTH token string. This is better for generating tokens only when needed - -there is no need to calculate unique token for every e-mail request, since a lot of these -might share the same connection and thus the cleint needs not to re-authenticate itself -with another token. - - var XOGen = { - token: "abc", - generate: function(callback){ - if(1 != 1){ - return callback(new Error("Tokens can't be generated in strange environments")); - } - callback(null, new Buffer(this.token, "utf-8").toString("base64")); - } - } - - var mailOptions = { - ..., - auth:{ - XOAuthToken: XOGen - } - } - -### Error types - -Emitted errors include the reason for failing in the `name` property - - * **UnknowAuthError** - the client tried to authenticate but the method was not supported - * **AuthError** - the username/password used were rejected - * **TLSError** - STARTTLS failed - * **SenderError** - the sender e-mail address was rejected - * **RecipientError** - all recipients were rejected (if only some of the recipients are rejected, a `'rcptFailed'` event is raised instead - -There's also an additional property in the error object called `data` that includes -the last response received from the server (if available for the current error type). - -### About reusing the connection - -You can reuse the same connection several times but you can't send a mail -through the same connection concurrently. So if you catch and `'idle'` event -lock the connection to a message process and unlock after `'ready'`. - -On `'error'` events you should reschedule the message and on `'end'` events -you should recreate the connection. - -### Closing the client - -By default the client tries to keep the connection up. If you want to close it, -run `client.quit()` - this sends a `QUIT` command to the server and closes the -connection - - client.quit(); - -## SMTP Client Connection pool - -**simplesmtp** has the option for connection pooling if you want to reuse a bulk -of connections. - -### Usage - -Create a connection pool of SMTP clients with - - simplesmtp.createClientPool(port[,host][, options]) - -where - - * **port** is the port to connect to - * **host** is the hostname to connect to (defaults to "localhost") - * **options** is an optional options object (see below) - -### Connection options - -The following connection options can be used with `simplesmtp.connect`: - - * **secureConnection** - use SSL - * **name** - the name of the client server - * **auth** - authentication object `{user:"...", pass:"..."}` or `{XOAuthToken:"base64data"}` - * **ignoreTLS** - ignore server support for STARTTLS - * **debug** - output client and server messages to console - * **maxConnections** - how many connections to keep in the pool (defaults to 5) - -### Send an e-mail - -E-mails can be sent through the pool with - - pool.sendMail(mail[, callback]) - -where - - * **mail** is a [MailComposer](/andris9/mailcomposer) compatible object - * **callback** `(error, responseObj)` - is the callback function to run after the message is delivered or an error occured. `responseObj` may include `failedRecipients` which is an array with e-mail addresses that were rejected and `message` which is the last response from the server. - -### Errors - -In addition to SMTP client errors another error name is used - - * **DeliveryError** - used if the message was not accepted by the SMTP server - -## License - -**MIT** - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/examples/simpleserver.js b/api/node_modules/nodemailer/node_modules/simplesmtp/examples/simpleserver.js deleted file mode 100644 index f42b59f57e7..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/examples/simpleserver.js +++ /dev/null @@ -1,17 +0,0 @@ -//console.log(process.stdout.writable); -var simplesmtp = require("../index"); - -simplesmtp.createSimpleServer({SMTPBanner:"My Server", debug: true}, function(req){ - process.stdout.write("\r\nNew Mail:\r\n"); - req.on("data", function(chunk){ - process.stdout.write(chunk); - }); - req.accept(); -}).listen(25, function(err){ - if(!err){ - console.log("SMTP server listening on port 25"); - }else{ - console.log("Could not start server on port 25. Ports under 1000 require root privileges."); - console.log(err.message); - } -}); diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/examples/validate-recipient.js b/api/node_modules/nodemailer/node_modules/simplesmtp/examples/validate-recipient.js deleted file mode 100644 index 3005a32f699..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/examples/validate-recipient.js +++ /dev/null @@ -1,35 +0,0 @@ -var simplesmtp = require("simplesmtp"), - fs = require("fs"); - -var allowedRecipientDomains = ["node.ee", "neti.ee"]; - -var smtp = simplesmtp.createServer(); -smtp.listen(25); - -// Set up recipient validation function -smtp.on("validateRecipient", function(connection, email, done){ - var domain = ((email || "").split("@").pop() || "").toLowerCase().trim(); - - if(allowedRecipientDomains.indexOf(domain) < 0){ - done(new Error("Invalid domain")); - }else{ - done(); - } -}); - -smtp.on("startData", function(connection){ - connection.saveStream = fs.createWriteStream("/tmp/message.txt"); -}); - -smtp.on("data", function(connection, chunk){ - connection.saveStream.write(chunk); -}); - -smtp.on("dataReady", function(connection, done){ - connection.saveStream.end(); - done(); - - console.log("Delivered message by " + connection.from + - " to " + connection.to.join(", ") + ", sent from " + connection.host + - " (" + connection.remoteAddress + ")"); -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/index.js b/api/node_modules/nodemailer/node_modules/simplesmtp/index.js deleted file mode 100644 index 2ff35991ecf..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/index.js +++ /dev/null @@ -1,6 +0,0 @@ - -// expose the API to the world -module.exports.createServer = require("./lib/server.js"); -module.exports.createSimpleServer = require("./lib/simpleserver.js"); -module.exports.connect = require("./lib/client.js"); -module.exports.createClientPool = require("./lib/pool.js"); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js b/api/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js deleted file mode 100644 index 87ea83d0492..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js +++ /dev/null @@ -1,858 +0,0 @@ -// TODO: -// * Lisada timeout serveri ühenduse jaoks - -var Stream = require("stream").Stream, - utillib = require("util"), - net = require("net"), - tls = require("tls"), - oslib = require("os"), - xoauth2 = require("xoauth2"), - crypto = require("crypto"); - -// expose to the world -module.exports = function(port, host, options){ - var connection = new SMTPClient(port, host, options); - process.nextTick(connection.connect.bind(connection)); - return connection; -}; - -/** - *

Generates a SMTP connection object

- * - *

Optional options object takes the following possible properties:

- *
    - *
  • secureConnection - use SSL
  • - *
  • name - the name of the client server
  • - *
  • auth - authentication object {user:"...", pass:"..."} - *
  • ignoreTLS - ignore server support for STARTTLS
  • - *
  • tls - options for createCredentials
  • - *
  • debug - output client and server messages to console
  • - *
  • instanceId - unique instance id for debugging
  • - *
- * - * @constructor - * @namespace SMTP Client module - * @param {Number} [port=25] Port number to connect to - * @param {String} [host="localhost"] Hostname to connect to - * @param {Object} [options] Option properties - */ -function SMTPClient(port, host, options){ - Stream.call(this); - this.writable = true; - this.readable = true; - - this.options = options || {}; - - this.port = port || (this.options.secureConnection ? 465 : 25); - this.host = host || "localhost"; - - this.options.secureConnection = !!this.options.secureConnection; - this.options.auth = this.options.auth || false; - this.options.maxConnections = this.options.maxConnections || 5; - - if(!this.options.name){ - // defaul hostname is machine hostname or [IP] - var defaultHostname = (oslib.hostname && oslib.hostname()) || ""; - - if(defaultHostname.indexOf('.')<0){ - defaultHostname = "[127.0.0.1]"; - } - if(defaultHostname.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)){ - defaultHostname = "["+defaultHostname+"]"; - } - - this.options.name = defaultHostname; - } - - this._init(); -} -utillib.inherits(SMTPClient, Stream); - -/** - *

Initializes instance variables

- */ -SMTPClient.prototype._init = function(){ - /** - * Defines if the current connection is secure or not. If not, - * STARTTLS can be used if available - * @private - */ - this._secureMode = false; - - /** - * Ignore incoming data on TLS negotiation - * @private - */ - this._ignoreData = false; - - /** - * Store incomplete messages coming from the server - * @private - */ - this._remainder = ""; - - /** - * If set to true, then this object is no longer active - * @private - */ - this.destroyed = false; - - /** - * The socket connecting to the server - * @publick - */ - this.socket = false; - - /** - * Lists supported auth mechanisms - * @private - */ - this._supportedAuth = []; - - /** - * Currently in data transfer state - * @private - */ - this._dataMode = false; - - /** - * Keep track if the client sends a leading \r\n in data mode - * @private - */ - this._lastDataBytes = new Buffer(2); - - /** - * Function to run if a data chunk comes from the server - * @private - */ - this._currentAction = false; - - if(this.options.ignoreTLS || this.options.secureConnection){ - this._secureMode = true; - } - - /** - * XOAuth2 token generator if XOAUTH2 auth is used - * @private - */ - this._xoauth2 = false; - - if(typeof this.options.auth.XOAuth2 == "object" && typeof this.options.auth.XOAuth2.getToken == "function"){ - this._xoauth2 = this.options.auth.XOAuth2; - }else if(typeof this.options.auth.XOAuth2 == "object"){ - if(!this.options.auth.XOAuth2.user && this.options.auth.user){ - this.options.auth.XOAuth2.user = this.options.auth.user; - } - this._xoauth2 = xoauth2.createXOAuth2Generator(this.options.auth.XOAuth2); - } -}; - -/** - *

Creates a connection to a SMTP server and sets up connection - * listener

- */ -SMTPClient.prototype.connect = function(){ - if(this.options.secureConnection){ - this.socket = tls.connect(this.port, this.host, this.options.tls || {rejectUnauthorized: false}, this._onConnect.bind(this)); - }else{ - this.socket = net.connect(this.port, this.host); - this.socket.on("connect", this._onConnect.bind(this)); - } - - this.socket.on("error", this._onError.bind(this)); -}; - -/** - *

Upgrades the connection to TLS

- * - * @param {Function} callback Callbac function to run when the connection - * has been secured - */ -SMTPClient.prototype._upgradeConnection = function(callback){ - this._ignoreData = true; - this.socket.removeAllListeners("data"); - this.socket.removeAllListeners("error"); - - var opts = { - socket: this.socket, - host: this.host, - rejectUnauthorized: false - }; - - Object.keys(this.options.tls || {}).forEach((function(key){ - opts[key] = this.options.tls[key]; - }).bind(this)); - - this.socket = tls.connect(opts, (function(){ - this._ignoreData = false; - this._secureMode = true; - this.socket.on("data", this._onData.bind(this)); - - return callback(null, true); - }).bind(this)); - this.socket.on("error", this._onError.bind(this)); -}; - -/** - *

Connection listener that is run when the connection to - * the server is opened

- * - * @event - */ -SMTPClient.prototype._onConnect = function(){ - if("setKeepAlive" in this.socket){ - this.socket.setKeepAlive(true); - }else if(this.socket.encrypted && "setKeepAlive" in this.socket.encrypted){ - this.socket.encrypted.setKeepAlive(true); // secure connection - } - - this.socket.on("data", this._onData.bind(this)); - this.socket.on("close", this._onClose.bind(this)); - this.socket.on("end", this._onEnd.bind(this)); - - this.socket.setTimeout(3 * 3600 * 1000); // 1 hours - this.socket.on("timeout", this._onTimeout.bind(this)); - - this._currentAction = this._actionGreeting; -}; - -/** - *

Destroys the client - removes listeners etc.

- */ -SMTPClient.prototype._destroy = function(){ - if(this._destroyed)return; - this._destroyed = true; - this._ignoreData = true; - this.emit("end"); - this.removeAllListeners(); -}; - -/** - *

'data' listener for data coming from the server

- * - * @event - * @param {Buffer} chunk Data chunk coming from the server - */ -SMTPClient.prototype._onData = function(chunk){ - var str; - - if(this._ignoreData || !chunk || !chunk.length){ - return; - } - - // Wait until end of line - if(chunk[chunk.length-1] != 0x0A){ - this._remainder += chunk.toString(); - return; - }else{ - str = (this._remainder + chunk.toString()).trim(); - this._remainder = ""; - } - - // if this is a multi line reply, wait until the ending - if(str.match(/(?:^|\n)\d{3}-.+$/)){ - this._remainder = str; - return; - } - - if(this.options.debug){ - console.log("SERVER"+(this.options.instanceId?" "+ - this.options.instanceId:"")+":\n└──"+str.replace(/\r?\n/g,"\n ")); - } - - if(typeof this._currentAction == "function"){ - this._currentAction.call(this, str); - } -}; - -/** - *

'error' listener for the socket

- * - * @event - * @param {Error} err Error object - * @param {String} type Error name - */ -SMTPClient.prototype._onError = function(err, type, data){ - if(type && type != "Error"){ - err.name = type; - } - if(data){ - err.data = data; - } - this.emit("error", err); - this.close(); -}; - -/** - *

'close' listener for the socket

- * - * @event - */ -SMTPClient.prototype._onClose = function(){ - this._destroy(); -}; - -/** - *

'end' listener for the socket

- * - * @event - */ -SMTPClient.prototype._onEnd = function(){ - this._destroy(); -}; - -/** - *

'timeout' listener for the socket

- * - * @event - */ -SMTPClient.prototype._onTimeout = function(){ - this.close(); -}; - -/** - *

Passes data stream to socket if in data mode

- * - * @param {Buffer} chunk Chunk of data to be sent to the server - */ -SMTPClient.prototype.write = function(chunk){ - // works only in data mode - if(!this._dataMode){ - // this line should never be reached but if it does, then - // say act like everything's normal. - return true; - } - - if(typeof chunk == "string"){ - chunk = new Buffer(chunk, "utf-8"); - } - - if(chunk.length > 2){ - this._lastDataBytes[0] = chunk[chunk.length-2]; - this._lastDataBytes[1] = chunk[chunk.length-1]; - }else if(chunk.length == 1){ - this._lastDataBytes[0] = this._lastDataBytes[1]; - this._lastDataBytes[1] = chunk[0]; - } - - if(this.options.debug){ - console.log("CLIENT (DATA)"+(this.options.instanceId?" "+ - this.options.instanceId:"")+":\n└──"+chunk.toString().trim().replace(/\n/g,"\n ")); - } - - // pass the chunk to the socket - return this.socket.write(chunk); -}; - -/** - *

Indicates that a data stream for the socket is ended. Works only - * in data mode.

- * - * @param {Buffer} [chunk] Chunk of data to be sent to the server - */ -SMTPClient.prototype.end = function(chunk){ - // works only in data mode - if(!this._dataMode){ - // this line should never be reached but if it does, then - // say act like everything's normal. - return true; - } - - if(chunk && chunk.length){ - this.write(chunk); - } - - // redirect output from the server to _actionStream - this._currentAction = this._actionStream; - - // indicate that the stream has ended by sending a single dot on its own line - // if the client already closed the data with \r\n no need to do it again - if(this._lastDataBytes[0] == 0x0D && this._lastDataBytes[1] == 0x0A){ - this.socket.write(new Buffer(".\r\n", "utf-8")); - }else if(this._lastDataBytes[1] == 0x0D){ - this.socket.write(new Buffer("\n.\r\n")); - }else{ - this.socket.write(new Buffer("\r\n.\r\n")); - } - - // end data mode - this._dataMode = false; -}; - -/** - *

Send a command to the server, append \r\n

- * - * @param {String} str String to be sent to the server - */ -SMTPClient.prototype.sendCommand = function(str){ - if(this.options.debug){ - console.log("CLIENT"+(this.options.instanceId?" "+ - this.options.instanceId:"")+":\n└──"+(str || "").toString().trim().replace(/\n/g,"\n ")); - } - this.socket.write(new Buffer(str+"\r\n", "utf-8")); -}; - -/** - *

Sends QUIT

- */ -SMTPClient.prototype.quit = function(){ - this.sendCommand("QUIT"); - this._currentAction = this.close; -}; - -/** - *

Closes the connection to the server

- */ -SMTPClient.prototype.close = function(){ - if(this.options.debug){ - console.log("Closing connection to the server"); - } - if(this.socket && this.socket.socket && this.socket.socket.end && !this.socket.socket.destroyed){ - this.socket.socket.end(); - } - if(this.socket && this.socket.end && !this.socket.destroyed){ - this.socket.end(); - } - this._destroy(); -}; - -/** - *

Initiates a new message by submitting envelope data, starting with - * MAIL FROM: command

- * - * @param {Object} envelope Envelope object in the form of - * {from:"...", to:["..."]} - */ -SMTPClient.prototype.useEnvelope = function(envelope){ - this._envelope = envelope || {}; - this._envelope.from = this._envelope.from || ("anonymous@"+this.options.name); - - // clone the recipients array for latter manipulation - this._envelope.rcptQueue = JSON.parse(JSON.stringify(this._envelope.to || [])); - this._envelope.rcptFailed = []; - - this._currentAction = this._actionMAIL; - this.sendCommand("MAIL FROM:<"+(this._envelope.from)+">"); -}; - -/** - *

If needed starts the authentication, if not emits 'idle' to - * indicate that this client is ready to take in an outgoing mail

- */ -SMTPClient.prototype._authenticateUser = function(){ - - if(!this.options.auth){ - // no need to authenticate, at least no data given - this._currentAction = this._actionIdle; - this.emit("idle"); // ready to take orders - return; - } - - var auth; - if(this.options.auth.XOAuthToken && this._supportedAuth.indexOf("XOAUTH")>=0){ - auth = "XOAUTH"; - }else if(this._xoauth2 && this._supportedAuth.indexOf("XOAUTH2")>=0){ - auth = "XOAUTH2"; - }else if(this.options.authMethod) { - auth = this.options.authMethod.toUpperCase().trim(); - }else{ - // use first supported - auth = (this._supportedAuth[0] || "PLAIN").toUpperCase().trim(); - } - - switch(auth){ - case "XOAUTH": - this._currentAction = this._actionAUTHComplete; - - if(typeof this.options.auth.XOAuthToken == "object" && - typeof this.options.auth.XOAuthToken.generate == "function"){ - this.options.auth.XOAuthToken.generate((function(err, XOAuthToken){ - if(err){ - return this._onError(err, "XOAuthTokenError"); - } - this.sendCommand("AUTH XOAUTH " + XOAuthToken); - }).bind(this)); - }else{ - this.sendCommand("AUTH XOAUTH " + this.options.auth.XOAuthToken.toString()); - } - return; - case "XOAUTH2": - this._currentAction = this._actionAUTHComplete; - this._xoauth2.getToken((function(err, token){ - if(err){ - this._onError(err, "XOAUTH2Error"); - return; - } - this.sendCommand("AUTH XOAUTH2 " + token); - }).bind(this)); - return; - case "LOGIN": - this._currentAction = this._actionAUTH_LOGIN_USER; - this.sendCommand("AUTH LOGIN"); - return; - case "PLAIN": - this._currentAction = this._actionAUTHComplete; - this.sendCommand("AUTH PLAIN "+new Buffer( - //this.options.auth.user+"\u0000"+ - "\u0000"+ // skip authorization identity as it causes problems with some servers - this.options.auth.user+"\u0000"+ - this.options.auth.pass,"utf-8").toString("base64")); - return; - case "CRAM-MD5": - this._currentAction = this._actionAUTH_CRAM_MD5; - this.sendCommand("AUTH CRAM-MD5"); - return; - } - - this._onError(new Error("Unknown authentication method - "+auth), "UnknowAuthError"); -}; - -/** ACTIONS **/ - -/** - *

Will be run after the connection is created and the server sends - * a greeting. If the incoming message starts with 220 initiate - * SMTP session by sending EHLO command

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionGreeting = function(str){ - if(str.substr(0,3) != "220"){ - this._onError(new Error("Invalid greeting from server - "+str), false, str); - return; - } - - this._currentAction = this._actionEHLO; - this.sendCommand("EHLO "+this.options.name); -}; - -/** - *

Handles server response for EHLO command. If it yielded in - * error, try HELO instead, otherwise initiate TLS negotiation - * if STARTTLS is supported by the server or move into the - * authentication phase.

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionEHLO = function(str){ - if(str.charAt(0) != "2"){ - // Try HELO instead - this._currentAction = this._actionHELO; - this.sendCommand("HELO "+this.options.name); - return; - } - - // Detect if the server supports STARTTLS - if(!this._secureMode && str.match(/[ \-]STARTTLS\r?$/mi)){ - this.sendCommand("STARTTLS"); - this._currentAction = this._actionSTARTTLS; - return; - } - - // Detect if the server supports PLAIN auth - if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)PLAIN/i)){ - this._supportedAuth.push("PLAIN"); - } - - // Detect if the server supports LOGIN auth - if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)LOGIN/i)){ - this._supportedAuth.push("LOGIN"); - } - - // Detect if the server supports CRAM-MD5 auth - if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)CRAM-MD5/i)){ - this._supportedAuth.push("CRAM-MD5"); - } - - // Detect if the server supports XOAUTH auth - if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)XOAUTH/i)){ - this._supportedAuth.push("XOAUTH"); - } - - // Detect if the server supports XOAUTH2 auth - if(str.match(/AUTH(?:\s+[^\n]*\s+|\s+)XOAUTH2/i)){ - this._supportedAuth.push("XOAUTH2"); - } - - this._authenticateUser.call(this); -}; - -/** - *

Handles server response for HELO command. If it yielded in - * error, emit 'error', otherwise move into the authentication phase.

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionHELO = function(str){ - if(str.charAt(0) != "2"){ - this._onError(new Error("Invalid response for EHLO/HELO - "+str), false, str); - return; - } - this._authenticateUser.call(this); -}; - -/** - *

Handles server response for STARTTLS command. If there's an error - * try HELO instead, otherwise initiate TLS upgrade. If the upgrade - * succeedes restart the EHLO

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionSTARTTLS = function(str){ - if(str.charAt(0) != "2"){ - // Try HELO instead - this._currentAction = this._actionHELO; - this.sendCommand("HELO "+this.options.name); - return; - } - - this._upgradeConnection((function(err, secured){ - if(err){ - this._onError(new Error("Error initiating TLS - "+(err.message || err)), "TLSError"); - return; - } - if(this.options.debug){ - console.log("Connection secured"); - } - - if(secured){ - // restart session - this._currentAction = this._actionEHLO; - this.sendCommand("EHLO "+this.options.name); - }else{ - this._authenticateUser.call(this); - } - }).bind(this)); -}; - -/** - *

Handle the response for AUTH LOGIN command. We are expecting - * '334 VXNlcm5hbWU6' (base64 for 'Username:'). Data to be sent as - * response needs to be base64 encoded username.

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionAUTH_LOGIN_USER = function(str){ - if(str != "334 VXNlcm5hbWU6"){ - this._onError(new Error("Invalid login sequence while waiting for '334 VXNlcm5hbWU6' - "+str), false, str); - return; - } - this._currentAction = this._actionAUTH_LOGIN_PASS; - this.sendCommand(new Buffer( - this.options.auth.user, "utf-8").toString("base64")); -}; - -/** - *

Handle the response for AUTH CRAM-MD5 command. We are expecting - * '334 '. Data to be sent as response needs to be - * base64 decoded challenge string, MD5 hashed using the password as - * a HMAC key, prefixed by the username and a space, and finally all - * base64 encoded again.

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionAUTH_CRAM_MD5 = function(str) { - var challengeMatch = str.match(/^334\s+(.+)$/), - challengeString = ""; - - if (!challengeMatch) { - this._onError(new Error("Invalid login sequence while waiting for server challenge string - "+str), false, str); - return; - } else { - challengeString = challengeMatch[1]; - } - - // Decode from base64 - var base64decoded = new Buffer(challengeString, 'base64').toString('ascii'), - hmac_md5 = crypto.createHmac('md5', this.options.auth.pass); - hmac_md5.update(base64decoded); - var hex_hmac = hmac_md5.digest('hex'), - prepended = this.options.auth.user + " " + hex_hmac; - - this._currentAction = this._actionAUTH_CRAM_MD5_PASS; - - this.sendCommand(new Buffer(prepended).toString("base64")); -}; - -/** - *

Handles the response to CRAM-MD5 authentication, if there's no error, - * the user can be considered logged in. Emit 'idle' and start - * waiting for a message to send

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionAUTH_CRAM_MD5_PASS = function(str) { - if (!str.match(/^235\s+/)) { - this._onError(new Error("Invalid login sequence while waiting for '235 go ahead' - "+str), false, str); - return; - } - this._currentAction = this._actionIdle; - this.emit("idle"); // ready to take orders -}; - -/** - *

Handle the response for AUTH LOGIN command. We are expecting - * '334 UGFzc3dvcmQ6' (base64 for 'Password:'). Data to be sent as - * response needs to be base64 encoded password.

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionAUTH_LOGIN_PASS = function(str){ - if(str != "334 UGFzc3dvcmQ6"){ - this._onError(new Error("Invalid login sequence while waiting for '334 UGFzc3dvcmQ6' - "+str), false, str); - return; - } - this._currentAction = this._actionAUTHComplete; - this.sendCommand(new Buffer(this.options.auth.pass, "utf-8").toString("base64")); -}; - -/** - *

Handles the response for authentication, if there's no error, - * the user can be considered logged in. Emit 'idle' and start - * waiting for a message to send

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionAUTHComplete = function(str){ - var response; - - if(this._xoauth2 && str.substr(0, 3) == "334"){ - try{ - response = str.split(" "); - response.shift(); - response = JSON.parse(new Buffer(response.join(" "), "base64").toString("utf-8")); - - if((!this._xoauth2.reconnectCount || this._xoauth2.reconnectCount < 2) && ['400','401'].indexOf(response.status)>=0){ - this._xoauth2.reconnectCount = (this._xoauth2.reconnectCount || 0) + 1; - this._currentAction = this._actionXOAUTHRetry; - }else{ - this._xoauth2.reconnectCount = 0; - this._currentAction = this._actionAUTHComplete; - } - this.sendCommand(new Buffer(0)); - return; - - }catch(E){} - } - - this._xoauth2.reconnectCount = 0; - - if(str.charAt(0) != "2"){ - this._onError(new Error("Invalid login - "+str), "AuthError", str); - return; - } - - this._currentAction = this._actionIdle; - this.emit("idle"); // ready to take orders -}; - -SMTPClient.prototype._actionXOAUTHRetry = function(str){ - this._xoauth2.generateToken((function(err, token){ - if(err){ - this._onError(err, "XOAUTH2Error"); - return; - } - this._currentAction = this._actionAUTHComplete; - this.sendCommand("AUTH XOAUTH2 " + token); - }).bind(this)); -}; - -/** - *

This function is not expected to run. If it does then there's probably - * an error (timeout etc.)

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionIdle = function(str){ - if(Number(str.charAt(0)) > 3){ - this._onError(new Error(str), false, str); - return; - } - - // this line should never get called -}; - -/** - *

Handle response for a MAIL FROM: command

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionMAIL = function(str){ - if(Number(str.charAt(0)) != "2"){ - this._onError(new Error("Mail from command failed - " + str), "SenderError", str); - return; - } - - if(!this._envelope.rcptQueue.length){ - this._onError(new Error("Can't send mail - no recipients defined"), "RecipientError"); - }else{ - this._envelope.curRecipient = this._envelope.rcptQueue.shift(); - this._currentAction = this._actionRCPT; - this.sendCommand("RCPT TO:<"+this._envelope.curRecipient+">"); - } -}; - -/** - *

Handle response for a RCPT TO: command

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionRCPT = function(str){ - if(Number(str.charAt(0)) != "2"){ - // this is a soft error - this._envelope.rcptFailed.push(this._envelope.curRecipient); - } - - if(!this._envelope.rcptQueue.length){ - if(this._envelope.rcptFailed.length < this._envelope.to.length){ - this.emit("rcptFailed", this._envelope.rcptFailed); - this._currentAction = this._actionDATA; - this.sendCommand("DATA"); - }else{ - this._onError(new Error("Can't send mail - all recipients were rejected"), "RecipientError"); - return; - } - }else{ - this._envelope.curRecipient = this._envelope.rcptQueue.shift(); - this._currentAction = this._actionRCPT; - this.sendCommand("RCPT TO:<"+this._envelope.curRecipient+">"); - } -}; - -/** - *

Handle response for a DATA command

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionDATA = function(str){ - // response should be 354 but according to this issue https://github.com/eleith/emailjs/issues/24 - // some servers might use 250 instead, so lets check for 2 or 3 as the first digit - if([2,3].indexOf(Number(str.charAt(0)))<0){ - this._onError(new Error("Data command failed - " + str), false, str); - return; - } - - // Emit that connection is set up for streaming - this._dataMode = true; - this._currentAction = this._actionIdle; - this.emit("message"); -}; - -/** - *

Handle response for a DATA stream

- * - * @param {String} str Message from the server - */ -SMTPClient.prototype._actionStream = function(str){ - if(Number(str.charAt(0)) != "2"){ - // Message failed - this.emit("ready", false, str); - }else{ - // Message sent succesfully - this.emit("ready", true, str); - } - - // Waiting for new connections - this._currentAction = this._actionIdle; - process.nextTick(this.emit.bind(this, "idle")); -}; diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js b/api/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js deleted file mode 100644 index 21bb0fac147..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js +++ /dev/null @@ -1,332 +0,0 @@ -var simplesmtp = require("../index"), - EventEmitter = require('events').EventEmitter, - utillib = require("util"), - xoauth2 = require("xoauth2"); - -// expose to the world -module.exports = function(port, host, options){ - var pool = new SMTPConnectionPool(port, host, options); - return pool; -}; - -/** - *

Creates a SMTP connection pool

- * - *

Optional options object takes the following possible properties:

- *
    - *
  • secureConnection - use SSL
  • - *
  • name - the name of the client server
  • - *
  • auth - authentication object {user:"...", pass:"..."} - *
  • ignoreTLS - ignore server support for STARTTLS
  • - *
  • tls - options for createCredentials
  • - *
  • debug - output client and server messages to console
  • - *
  • maxConnections - how many connections to keep in the pool
  • - *
- * - * @constructor - * @namespace SMTP Client Pool module - * @param {Number} [port=25] The port number to connecto to - * @param {String} [host="localhost"] THe hostname to connect to - * @param {Object} [options] optional options object - */ -function SMTPConnectionPool(port, host, options){ - EventEmitter.call(this); - - /** - * Port number to connect to - * @public - */ - this.port = port || 25; - - /** - * Hostname to connect to - * @public - */ - this.host = host || "localhost"; - - /** - * Options object - * @public - */ - this.options = options || {}; - this.options.maxConnections = this.options.maxConnections || 5; - - /** - * An array of connections that are currently idle - * @private - */ - this._connectionsAvailable = []; - - /** - * An array of connections that are currently in use - * @private - */ - this._connectionsInUse = []; - - /** - * Message queue (FIFO) - * @private - */ - this._messageQueue = []; - - /** - * Counter for generating ID values for debugging - * @private - */ - this._idgen = 0; - - // Initialize XOAUTH2 if needed - if(this.options.auth && typeof this.options.auth.XOAuth2 == "object"){ - if(!this.options.auth.XOAuth2.user && this.options.auth.user){ - this.options.auth.XOAuth2.user = this.options.auth.user; - } - this.options.auth.XOAuth2 = xoauth2.createXOAuth2Generator(this.options.auth.XOAuth2); - } -} -utillib.inherits(SMTPConnectionPool, EventEmitter); - -/** - *

Sends a message. If there's any idling connections available - * use one to send the message immediatelly, otherwise add to queue.

- * - * @param {Object} message MailComposer object - * @param {Function} callback Callback function to run on finish, gets an - * error object as a parameter if the sending failed - * and on success an object with failedRecipients array as - * a list of addresses that were rejected (if any) and - * message which indicates the last message received from - * the server - */ -SMTPConnectionPool.prototype.sendMail = function(message, callback){ - var connection; - - message.returnCallback = callback; - - if(this._connectionsAvailable.length){ - // if available connections pick one - connection = this._connectionsAvailable.pop(); - this._connectionsInUse.push(connection); - this._processMessage(message, connection); - }else{ - this._messageQueue.push(message); - - if(this._connectionsAvailable.length + this._connectionsInUse.length < this.options.maxConnections){ - this._createConnection(); - } - } - -}; - -/** - *

Closes all connections

- */ -SMTPConnectionPool.prototype.close = function(callback){ - var connection; - - // for some reason destroying the connections seem to be the only way :S - while(this._connectionsAvailable.length){ - connection = this._connectionsAvailable.pop(); - if(connection.socket){ - connection.socket.destroy(); - } - } - - while(this._connectionsInUse.length){ - connection = this._connectionsInUse.pop(); - if(connection.socket){ - connection.socket.destroy(); - } - } - - if(callback){ - process.nextTick(callback); - } -}; - -/** - *

Initiates a connection to the SMTP server and adds it to the pool

- */ -SMTPConnectionPool.prototype._createConnection = function(){ - var connectionOptions = { - instanceId: ++this._idgen, - debug: !!this.options.debug, - ignoreTLS: !!this.options.ignoreTLS, - tls: this.options.tls || false, - auth: this.options.auth || false, - authMethod: this.options.authMethod, - name: this.options.name || false, - secureConnection: !!this.options.secureConnection - }, - connection = simplesmtp.connect(this.port, this.host, connectionOptions); - - connection.on("idle", this._onConnectionIdle.bind(this, connection)); - connection.on("message", this._onConnectionMessage.bind(this, connection)); - connection.on("ready", this._onConnectionReady.bind(this, connection)); - connection.on("error", this._onConnectionError.bind(this, connection)); - connection.on("end", this._onConnectionEnd.bind(this, connection)); - connection.on("rcptFailed", this._onConnectionRCPTFailed.bind(this, connection)); - - this.emit('connectionCreated', connection); - - // as the connection is not ready yet, add to "in use" queue - this._connectionsInUse.push(connection); -}; - -/** - *

Processes a message by assigning it to a connection object and initiating - * the sending process by setting the envelope

- * - * @param {Object} message MailComposer message object - * @param {Object} connection simplesmtp.connect connection - */ -SMTPConnectionPool.prototype._processMessage = function(message, connection){ - connection.currentMessage = message; - message.currentConnection = connection; - - // send envelope - connection.useEnvelope(message.getEnvelope()); -}; - -/** - *

Will be fired on 'idle' events by the connection, if - * there's a message currently in queue

- * - * @event - * @param {Object} connection Connection object that fired the event - */ -SMTPConnectionPool.prototype._onConnectionIdle = function(connection){ - - var message = this._messageQueue.shift(); - - if(message){ - this._processMessage(message, connection); - }else{ - for(var i=0, len = this._connectionsInUse.length; iWill be called when not all recipients were accepted

- * - * @event - * @param {Object} connection Connection object that fired the event - * @param {Array} addresses Failed addresses as an array of strings - */ -SMTPConnectionPool.prototype._onConnectionRCPTFailed = function(connection, addresses){ - if(connection.currentMessage){ - connection.currentMessage.failedRecipients = addresses; - } -}; - -/** - *

Will be called when the client is waiting for a message to deliver

- * - * @event - * @param {Object} connection Connection object that fired the event - */ -SMTPConnectionPool.prototype._onConnectionMessage = function(connection){ - if(connection.currentMessage){ - connection.currentMessage.streamMessage(); - connection.currentMessage.pipe(connection); - } -}; - -/** - *

Will be called when a message has been delivered

- * - * @event - * @param {Object} connection Connection object that fired the event - * @param {Boolean} success True if the message was queued by the SMTP server - * @param {String} message Last message received from the server - */ -SMTPConnectionPool.prototype._onConnectionReady = function(connection, success, message){ - var error, responseObj = {}; - if(connection.currentMessage && connection.currentMessage.returnCallback){ - if(success){ - - if(connection.currentMessage.failedRecipients){ - responseObj.failedRecipients = connection.currentMessage.failedRecipients; - } - - if(message){ - responseObj.message = message; - } - - if(connection.currentMessage._messageId){ - responseObj.messageId = connection.currentMessage._messageId; - } - - connection.currentMessage.returnCallback(null, responseObj); - - }else{ - error = new Error("Message delivery failed" + (message?": "+message:"")); - error.name = "DeliveryError"; - connection.currentMessage.returnCallback(error); - } - } - connection.currentMessage = false; -}; - -/** - *

Will be called when an error occurs

- * - * @event - * @param {Object} connection Connection object that fired the event - * @param {Object} error Error object - */ -SMTPConnectionPool.prototype._onConnectionError = function(connection, error){ - var message = connection.currentMessage; - connection.currentMessage = false; - - // clear a first message from the list, otherwise an infinite loop will emerge - if(!message){ - message = this._messageQueue.shift(); - } - - if(message && message.returnCallback){ - message.returnCallback(error); - } -}; - -/** - *

Will be called when a connection to the client is closed

- * - * @event - * @param {Object} connection Connection object that fired the event - */ -SMTPConnectionPool.prototype._onConnectionEnd = function(connection){ - var removed = false, i, len; - - // if in "available" list, remove - for(i=0, len = this._connectionsAvailable.length; iAndris Reinman - */ - -var RAIServer = require("rai").RAIServer, - EventEmitter = require('events').EventEmitter, - oslib = require('os'), - utillib = require("util"), - dnslib = require("dns"), - crypto = require("crypto"); - -// expose to the world -module.exports = function(options){ - return new SMTPServer(options); -}; - -/** - *

Constructs a SMTP server

- * - *

Possible options are:

- * - *
    - *
  • name - the hostname of the server, will be used for - * informational messages
  • - *
  • debug - if set to true, print out messages about the connection
  • - *
  • timeout - client timeout in milliseconds, defaults to 60 000
  • - *
  • secureConnection - start a server on secure connection
  • - *
  • SMTPBanner - greeting banner that is sent to the client on connection
  • - *
  • requireAuthentication - if set to true, require that the client - * must authenticate itself
  • - *
  • enableAuthentication - if set to true, client may authenticate itself but don't have to
  • - *
  • maxSize - maximum size of an e-mail in bytes
  • - *
  • credentials - TLS credentials
  • - *
  • authMethods - allowed authentication methods, defaults to ["PLAIN", "LOGIN"]
  • - *
  • disableEHLO - if set, support HELO only
  • - *
  • ignoreTLS - if set, allow client do not use STARTTLS
  • - *
  • disableDNSValidation - if set, do not validate sender domains
  • - *
- * - * @constructor - * @namespace SMTP Server module - * @param {Object} [options] Options object - */ -function SMTPServer(options){ - EventEmitter.call(this); - - this.options = options || {}; - this.options.name = this.options.name || (oslib.hostname && oslib.hostname()) || - (oslib.getHostname && oslib.getHostname()) || - "127.0.0.1"; - - this.options.authMethods = (this.options.authMethods || ["PLAIN", "LOGIN"]).map( - function(auth){ - return auth.toUpperCase().trim(); - }); - - this.options.disableEHLO = !!this.options.disableEHLO; - this.options.ignoreTLS = !!this.options.ignoreTLS; - - this.SMTPServer = new RAIServer({ - secureConnection: !!this.options.secureConnection, - credentials: this.options.credentials, - timeout: this.options.timeout || 60*1000, - disconnectOnTimeout: false, - debug: !!this.options.debug - }); - - this.SMTPServer.on("connect", this._createSMTPServerConnection.bind(this)); -} -utillib.inherits(SMTPServer, EventEmitter); - -/** - * Server starts listening on defined port and hostname - * - * @param {Number} port The port number to listen - * @param {String} [host] The hostname to listen - * @param {Function} callback The callback function to run when the server is listening - */ -SMTPServer.prototype.listen = function(port, host, callback){ - this.SMTPServer.listen(port, host, callback); -}; - -/** - *

Closes the server

- * - * @param {Function} callback The callback function to run when the server is closed - */ -SMTPServer.prototype.end = function(callback){ - this.SMTPServer.end(callback); -}; - -/** - *

Creates a new {@link SMTPServerConnection} object and links the main server with - * the client socket

- * - * @param {Object} client RAISocket object to a client - */ -SMTPServer.prototype._createSMTPServerConnection = function(client){ - new SMTPServerConnection(this, client); -}; - -/** - *

Sets up a handler for the connected client

- * - *

Restarts the state and sets up event listeners for client actions

- * - * @constructor - * @param {Object} server {@link SMTPServer} instance - * @param {Object} client RAISocket instance for the client - */ -function SMTPServerConnection(server, client){ - this.server = server; - this.client = client; - - this.init(); - - if(this.server.options.debug){ - console.log("Connection from", this.client.remoteAddress); - } - - this.client.on("timeout", this._onTimeout.bind(this)); - this.client.on("error", this._onError.bind(this)); - this.client.on("command", this._onCommand.bind(this)); - this.client.on("end", this._onEnd.bind(this)); - - this.client.on("data", this._onData.bind(this)); - this.client.on("ready", this._onDataReady.bind(this)); - - // Send the greeting banner. Force ESMTP notice - this.client.send("220 "+this.server.options.name + " ESMTP " + (this.server.options.SMTPBanner || "node.js simplesmtp")); -} - -/** - *

Reset the envelope state

- * - *

If keepAuthData is set to true, then doesn't remove - * authentication data

- * - * @param {Boolean} [keepAuthData=false] If set to true keep authentication data - */ -SMTPServerConnection.prototype.init = function(keepAuthData){ - this.envelope = {from: "", to:[], date: new Date()}; - - if(this.hostNameAppearsAs){ - this.envelope.host = this.hostNameAppearsAs; - } - - if(this.client.remoteAddress){ - this.envelope.remoteAddress = this.client.remoteAddress; - } - - if(!keepAuthData){ - this.authentication = { - username: false, - authenticated: false, - state: "NORMAL" - }; - } - - this.envelope.authentication = this.authentication; -}; - -/** - *

Sends a message to the client and closes the connection

- * - * @param {String} [message] if set, send it to the client before disconnecting - */ -SMTPServerConnection.prototype.end = function(message){ - if(message){ - this.client.send(message); - } - this.client.end(); -}; - -/** - *

Will be called when the connection to the client is closed

- * - * @event - */ -SMTPServerConnection.prototype._onEnd = function(){ - if(this.server.options.debug){ - console.log("Connection closed to", this.client.remoteAddress); - } - this.server.emit("close", this.envelope); -}; - -/** - *

Will be called when timeout occurs

- * - * @event - */ -SMTPServerConnection.prototype._onTimeout = function(){ - this.end("421 4.4.2 "+this.server.options.name+" Error: timeout exceeded"); -}; - -/** - *

Will be called when an error occurs

- * - * @event - */ -SMTPServerConnection.prototype._onError = function(){ - this.end("421 4.4.2 "+this.server.options.name+" Error: client error"); -}; - -/** - *

Will be called when a command is received from the client

- * - *

If there's curently an authentication process going on, route - * the data to _handleAuthLogin, otherwise act as - * defined

- * - * @event - * @param {String} command Command - * @param {Buffer} command Payload related to the command - */ -SMTPServerConnection.prototype._onCommand = function(command, payload){ - - if(this.authentication.state == "AUTHPLAINUSERDATA"){ - this._handleAuthPlain(command.toString("utf-8").trim().split(" ")); - return; - } - - if(this.authentication.state == "AUTHENTICATING"){ - this._handleAuthLogin(command); - return; - } - - switch((command || "").toString().trim().toUpperCase()){ - - // Should not occur too often - case "HELO": - this._onCommandHELO(payload.toString("utf-8").trim()); - break; - - // Lists server capabilities - case "EHLO": - if(!this.server.options.disableEHLO){ - this._onCommandEHLO(payload.toString("utf-8").trim()); - }else{ - this.client.send("502 5.5.2 Error: command not recognized"); - } - break; - - // Closes the connection - case "QUIT": - this.end("221 2.0.0 Goodbye!"); - break; - - // Resets the current state - case "RSET": - this._onCommandRSET(); - break; - - // Doesn't work for spam related purposes - case "VRFY": - this.client.send("252 2.1.5 Send some mail, I'll try my best"); - break; - - // Initiate an e-mail by defining a sender - case "MAIL": - this._onCommandMAIL(payload.toString("utf-8").trim()); - break; - - // Add recipients to the e-mail envelope - case "RCPT": - this._onCommandRCPT(payload.toString("utf-8").trim()); - break; - - // Authenticate if needed - case "AUTH": - this._onCommandAUTH(payload); - break; - - // Start accepting binary data stream - case "DATA": - this._onCommandDATA(); - break; - - // Upgrade connection to secure TLS - case "STARTTLS": - this._onCommandSTARTTLS(); - break; - - // Display an error on anything else - default: - this.client.send("502 5.5.2 Error: command not recognized"); - } -}; - -/** - *

Initiate an e-mail by defining a sender.

- * - *

This doesn't work if authorization is required but the client is - * not logged in yet.

- * - *

If validateSender option is set to true, then emits - * 'validateSender' and wait for the callback before moving - * on

- * - * @param {String} mail Address payload in the form of "FROM:<address>" - */ -SMTPServerConnection.prototype._onCommandMAIL = function(mail){ - var self = this, - match, - email, - domain; - - if(!this.hostNameAppearsAs){ - return this.client.send("503 5.5.1 Error: send HELO/EHLO first"); - } - - if(this.server.options.requireAuthentication && !this.authentication.authenticated){ - return this.client.send("530 5.5.1 Authentication Required"); - } - - if(this.envelope.from){ - return this.client.send("503 5.5.1 Error: nested MAIL command"); - } - - if(!(match = mail.match(/^from\:\s*<([^@>]+\@([^@>]+))>(\s|$)/i))){ - return this.client.send("501 5.1.7 Bad sender address syntax"); - } - - email = match[1] || ""; - domain = (match[2] || "").toLowerCase(); - - this._validateAddress("sender", email, domain, function (err) { - if (err) { - return self.client.send(err.message); - } - email = email.substr(0, email.length - domain.length) + domain; - self.envelope.from = email; - self.client.send("250 2.1.0 Ok"); - }); -}; - -/** - *

Add recipients to the e-mail envelope

- * - *

This doesn't work if MAIL command is not yet executed

- * - *

If validateRecipients option is set to true, then emits - * 'validateRecipient' and wait for the callback before moving - * on

- * - * @param {String} mail Address payload in the form of "TO:<address>" - */ -SMTPServerConnection.prototype._onCommandRCPT = function(mail){ - var self = this, - match, - email, - domain; - - if(!this.envelope.from){ - return this.client.send("503 5.5.1 Error: need MAIL command"); - } - - if(!(match = mail.match(/^to\:\s*<([^@>]+\@([^@>]+))>$/i))){ - return this.client.send("501 5.1.7 Bad recipient address syntax"); - } - - email = match[1] || ""; - domain = (match[2] || "").toLowerCase(); - - this._validateAddress("recipient", email, domain, function (err) { - if (err) { - return self.client.send(err.message); - } - - // force domain part to be lowercase - email = email.substr(0, email.length - domain.length) + domain; - - // add to recipients list - if(self.envelope.to.indexOf(email)<0){ - self.envelope.to.push(email); - } - self.client.send("250 2.1.0 Ok"); - }); - -}; - -/** - *

If disableDNSValidation option is set to false, then performs - * validation via DNS lookup. - * - *

If validate{type} option is set to true, then emits - * 'validate{type}' and waits for the callback before moving - * on

- * - * @param {String} addressType 'sender' or 'recipient' - * @param {String} email - * @param {String} domain - * @param {Function} callback - */ -SMTPServerConnection.prototype._validateAddress = function (addressType, email, domain, callback) { - - var validateEvent, - validationFailedEvent, - dnsErrorMessage, - localErrorMessage; - - if (addressType === "sender") { - validateEvent = "validateSender"; - validationFailedEvent = "senderValidationFailed"; - dnsErrorMessage = "450 4.1.8 <"+email+">: Sender address rejected: Domain not found"; - localErrorMessage = "550 5.1.1 <"+email+">: Sender address rejected: User unknown in local sender table"; - } else if (addressType === "recipient") { - validateEvent = "validateRecipient"; - validationFailedEvent = "recipientValidationFailed"; - dnsErrorMessage = "450 4.1.8 <"+email+">: Recipient address rejected: Domain not found"; - localErrorMessage = "550 5.1.1 <"+email+">: Recipient address rejected: User unknown in local recipient table"; - } else { - // How are internal errors handled? - throw new Error('Address type not supported'); - } - - var validateViaLocal = function () { - if(this.server.listeners(validateEvent).length){ - this.server.emit(validateEvent, this.envelope, email, (function(err){ - if(err){ - return callback(new Error(localErrorMessage)); - } - return callback(); - }).bind(this)); - } else { - return callback(); - } - }; - - var validateViaDNS = function () { - dnslib.resolveMx(domain, (function(err, addresses){ - if(err || !addresses || !addresses.length){ - this.server.emit(validationFailedEvent, email); - return callback(new Error(dnsErrorMessage)); - } - validateViaLocal.call(this); - }).bind(this)); - }; - - if(!this.server.options.disableDNSValidation) { - validateViaDNS.call(this); - } else { - return validateViaLocal.call(this); - } -}; - -/** - *

Switch to data mode and starts waiting for a binary data stream. Emits - * 'startData'.

- * - *

If RCPT is not yet run, stop

- */ -SMTPServerConnection.prototype._onCommandDATA = function(){ - - if(!this.envelope.to.length){ - return this.client.send("503 5.5.1 Error: need RCPT command"); - } - - this.client.startDataMode(); - this.client.send("354 End data with ."); - this.server.emit("startData", this.envelope); -}; - -/** - *

Resets the current state - e-mail data and authentication info

- */ -SMTPServerConnection.prototype._onCommandRSET = function(){ - this.init(); - this.client.send("250 2.0.0 Ok"); -}; - -/** - *

If the server is in secure connection mode, start the authentication - * process. Param payload defines the authentication mechanism.

- * - *

Currently supported - PLAIN and LOGIN. There is no need for more - * complicated mechanisms (different CRAM versions etc.) since authentication - * is only done in secure connection mode

- * - * @param {Buffer} payload Defines the authentication mechanism - */ -SMTPServerConnection.prototype._onCommandAUTH = function(payload){ - var method; - - if(!this.server.options.requireAuthentication && !this.server.options.enableAuthentication){ - return this.client.send("503 5.5.1 Error: authentication not enabled"); - } - - if(!this.server.options.ignoreTLS && !this.client.secureConnection){ - return this.client.send("530 5.7.0 Must issue a STARTTLS command first"); - } - - if(this.authentication.authenticated){ - return this.client.send("503 5.7.0 No identity changes permitted"); - } - - payload = payload.toString("utf-8").trim().split(" "); - method = payload.shift().trim().toUpperCase(); - - if(this.server.options.authMethods.indexOf(method)<0){ - return this.client.send("535 5.7.8 Error: authentication failed: no mechanism available"); - } - - switch(method){ - case "PLAIN": - this._handleAuthPlain(payload); - break; - case "LOGIN": - this._handleAuthLogin(); - break; - } -}; - -/** - *

Upgrade the connection to a secure TLS connection

- */ -SMTPServerConnection.prototype._onCommandSTARTTLS = function(){ - if(this.client.secureConnection){ - return this.client.send("554 5.5.1 Error: TLS already active"); - } - - this.client.send("220 2.0.0 Ready to start TLS"); - - this.client.startTLS(this.server.options.credentials, (function(){ - // Connection secured - // nothing to do here, since it is the client that should - // make the next move - }).bind(this)); -}; - -/** - *

Retrieve hostname from the client. Not very important, since client - * IP is already known and the client can send fake data

- * - * @param {String} host Hostname of the client - */ -SMTPServerConnection.prototype._onCommandHELO = function(host){ - if(!host){ - return this.client.send("501 Syntax: EHLO hostname"); - }else{ - this.hostNameAppearsAs = host; - this.envelope.host = host; - } - this.client.send("250 "+this.server.options.name+" at your service, ["+ - this.client.remoteAddress+"]"); -}; - -/** - *

Retrieve hostname from the client. Not very important, since client - * IP is already known and the client can send fake data

- * - *

Additionally displays server capability list to the client

- * - * @param {String} host Hostname of the client - */ -SMTPServerConnection.prototype._onCommandEHLO = function(host){ - var response = [this.server.options.name+" at your service, ["+ - this.client.remoteAddress+"]", "8BITMIME", "ENHANCEDSTATUSCODES"]; - - if(this.server.options.maxSize){ - response.push("SIZE "+this.server.options.maxSize); - } - - if((this.client.secureConnection || this.server.options.ignoreTLS) && (this.server.options.requireAuthentication || this.server.options.enableAuthentication)){ - response.push("AUTH "+this.server.options.authMethods.join(" ")); - response.push("AUTH="+this.server.options.authMethods.join(" ")); - } - - if(!this.client.secureConnection){ - response.push("STARTTLS"); - } - - if(!host){ - return this.client.send("501 Syntax: EHLO hostname"); - }else{ - this.hostNameAppearsAs = host; - this.envelope.host = host; - } - - this.client.send(response.map(function(feature, i, arr){ - return "250"+(iDetect login information from the payload and initiate authentication - * by emitting 'authorizeUser' and waiting for its callback

- * - * @param {Buffer} payload AUTH PLAIN login information - */ -SMTPServerConnection.prototype._handleAuthPlain = function(payload){ - if (payload.length) { - var userdata = new Buffer(payload.join(" "), "base64"), password; - userdata = userdata.toString("utf-8").split("\u0000"); - - if (userdata.length != 3) { - return this.client.send("500 5.5.2 Error: invalid userdata to decode"); - } - - this.authentication.username = userdata[1] || userdata[0] || ""; - password = userdata[2] || ""; - - this.server.emit("authorizeUser", - this.envelope, - this.authentication.username, - password, - (function(err, success){ - if(err || !success){ - this.authentication.authenticated = false; - this.authentication.username = false; - this.authentication.state = "NORMAL"; - return this.client.send("535 5.7.8 Error: authentication failed: generic failure"); - } - this.client.send("235 2.7.0 Authentication successful"); - this.authentication.authenticated = true; - this.authentication.state = "AUTHENTICATED"; - }).bind(this)); - } else { - if(this.authentication.state == "NORMAL"){ - this.authentication.state = "AUTHPLAINUSERDATA"; - this.client.send("334"); - } - } - -}; - -/** - *

Sets authorization state to "AUTHENTICATING" and reuqests for the - * username and password from the client

- * - *

If username and password are set initiate authentication - * by emitting 'authorizeUser' and waiting for its callback

- * - * @param {Buffer} payload AUTH LOGIN login information - */ -SMTPServerConnection.prototype._handleAuthLogin = function(payload){ - if(this.authentication.state == "NORMAL"){ - this.authentication.state = "AUTHENTICATING"; - this.client.send("334 VXNlcm5hbWU6"); - }else if(this.authentication.state == "AUTHENTICATING"){ - if(this.authentication.username === false){ - this.authentication.username = new Buffer(payload, "base64").toString("utf-8"); - this.client.send("334 UGFzc3dvcmQ6"); - }else{ - this.authentication.state = "VERIFYING"; - this.server.emit("authorizeUser", - this.envelope, - this.authentication.username, - new Buffer(payload, "base64").toString("utf-8"), - (function(err, success){ - if(err || !success){ - this.authentication.authenticated = false; - this.authentication.username = false; - this.authentication.state = "NORMAL"; - return this.client.send("535 5.7.8 Error: authentication failed: generic failure"); - } - this.client.send("235 2.7.0 Authentication successful"); - this.authentication.authenticated = true; - this.authentication.state = "AUTHENTICATED"; - }).bind(this)); - } - - } -}; - -/** - *

Emits the data received from the client with 'data' - * - * @event - * @param {Buffer} chunk Binary data sent by the client on data mode - */ -SMTPServerConnection.prototype._onData = function(chunk){ - this.server.emit("data", this.envelope, chunk); -}; - -/** - *

If the data stream ends, emit 'dataReady'and wait for - * the callback, only if server listened for it.

- * - * @event - */ -SMTPServerConnection.prototype._onDataReady = function(){ - if (this.server.listeners('dataReady').length) { - this.server.emit("dataReady", this.envelope, (function(err, code){ - this.init(true); //reset state, keep auth data - - if(err){ - this.client.send("550 "+(err && err.message || "FAILED")); - }else{ - this.client.send("250 2.0.0 Ok: queued as "+(code || crypto.randomBytes(10).toString("hex"))); - } - - }).bind(this)); - } else { - this.init(true); //reset state, keep auth data - this.client.send("250 2.0.0 Ok: queued as " + crypto.randomBytes(10).toString("hex")); - } -}; - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/simpleserver.js b/api/node_modules/nodemailer/node_modules/simplesmtp/lib/simpleserver.js deleted file mode 100644 index 7458d3a8909..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/simpleserver.js +++ /dev/null @@ -1,124 +0,0 @@ -var createSMTPServer = require("./server"), - Stream = require("stream").Stream, - utillib = require("util"), - oslib = require("os"); - -module.exports = function(options, connectionCallback){ - return new SimpleServer(options, connectionCallback); -} - -function SimpleServer(options, connectionCallback){ - if(!connectionCallback && typeof options == "function"){ - connectionCallback = options; - options = undefined; - } - - this.connectionCallback = connectionCallback; - - this.options = options || {}; - this.initialChunk = true; - - if(!("ignoreTLS" in this.options)){ - this.options.ignoreTLS = true; - } - - if(!("disableDNSValidation" in this.options)){ - this.options.disableDNSValidation = true; - } - - this.server = createSMTPServer(options); - this.listen = this.server.listen.bind(this.server); - - this.server.on("startData", this._onStartData.bind(this)); - this.server.on("data", this._onData.bind(this)); - this.server.on("dataReady", this._onDataReady.bind(this)); -} - -SimpleServer.prototype._onStartData = function(connection){ - connection._session = new SimpleServerConnection(connection); - this.connectionCallback(connection._session); -} - -SimpleServer.prototype._onData = function(connection, chunk){ - if(this.initialChunk){ - chunk = Buffer.concat([new Buffer(this._generateReceivedHeader(connection) + "\r\n", "utf-8"), chunk]) - this.initialChunk = false; - } - connection._session.emit("data", chunk); -} - -SimpleServer.prototype._onDataReady = function(connection, callback){ - connection._session._setCallback(callback); - connection._session.emit("end"); -} - -SimpleServer.prototype._generateReceivedHeader = function(connection){ - var parts = []; - - if(connection.host && !connection.host.match(/^\[?\d+\.\d+\.\d+\.\d+\]?$/)){ - parts.push("from " + connection.host); - parts.push("("+connection.remoteAddress+")"); - }else{ - parts.push("from " + connection.remoteAddress); - } - - parts.push("by " + getHostName()); - - parts.push("with SMTP;"); - - parts.push(Date()); - - return "Received: " + parts.join(" "); -} - -function SimpleServerConnection(connection){ - Stream.call(this); - - this.accepted = false; - this.rejected = false; - - this._callback = (function(err, code){ - if(err){ - this.rejected = err; - }else{ - this.accepted = code || true; - } - }); - - ["from", "to", "host", "remodeAddress"].forEach((function(key){ - if(connection[key]){ - this[key] = connection[key]; - } - }).bind(this)); -} -utillib.inherits(SimpleServerConnection, Stream); - -SimpleServerConnection.prototype._setCallback = function(callback){ - - if(this.rejected){ - return callback(this.rejected); - }else if(this.accepted){ - return callback(null, this.accepted !== true ? this.accepted : undefined); - }else{ - this._callback = callback; - } - -} - -SimpleServerConnection.prototype.pause = function(){} - -SimpleServerConnection.prototype.resume = function(){} - -SimpleServerConnection.prototype.accept = function(code){ - this._callback(null, code); -} - -SimpleServerConnection.prototype.reject = function(reason){ - this._callback(new Error(reason || "Rejected")); -} - -function getHostName(){ - return (oslib.hostname && oslib.hostname()) || - (oslib.getHostname && oslib.getHostname()) || - "127.0.0.1"; -} diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js b/api/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js deleted file mode 100644 index 836f0f6d210..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js +++ /dev/null @@ -1,112 +0,0 @@ -// SOURCE: https://gist.github.com/848444 - -// Target API: -// -// var s = require('net').createStream(25, 'smtp.example.com'); -// s.on('connect', function() { -// require('starttls')(s, options, function() { -// if (!s.authorized) { -// s.destroy(); -// return; -// } -// -// s.end("hello world\n"); -// }); -// }); -// -// - -/** - * @namespace Client STARTTLS module - * @name starttls - */ -module.exports.starttls = starttls; - -/** - *

Upgrades a socket to a secure TLS connection

- * - * @memberOf starttls - * @param {Object} socket Plaintext socket to be upgraded - * @param {Function} callback Callback function to be run after upgrade - */ -function starttls(socket, callback) { - var sslcontext, pair, cleartext; - - socket.removeAllListeners("data"); - sslcontext = require('crypto').createCredentials(); - pair = require('tls').createSecurePair(sslcontext, false); - cleartext = pipe(pair, socket); - - pair.on('secure', function() { - var verifyError = (pair._ssl || pair.ssl).verifyError(); - - if (verifyError) { - cleartext.authorized = false; - cleartext.authorizationError = verifyError; - } else { - cleartext.authorized = true; - } - - callback(cleartext); - }); - - cleartext._controlReleased = true; - return pair; -} - -function forwardEvents(events, emitterSource, emitterDestination) { - var map = [], name, handler; - - for(var i = 0, len = events.length; i < len; i++) { - name = events[i]; - - handler = forwardEvent.bind(emitterDestination, name); - - map.push(name); - emitterSource.on(name, handler); - } - - return map; -} - -function forwardEvent() { - this.emit.apply(this, arguments); -} - -function removeEvents(map, emitterSource) { - for(var i = 0, len = map.length; i < len; i++){ - emitterSource.removeAllListeners(map[i]); - } -} - -function pipe(pair, socket) { - pair.encrypted.pipe(socket); - socket.pipe(pair.encrypted); - - pair.fd = socket.fd; - - var cleartext = pair.cleartext; - - cleartext.socket = socket; - cleartext.encrypted = pair.encrypted; - cleartext.authorized = false; - - function onerror(e) { - if (cleartext._controlReleased) { - cleartext.emit('error', e); - } - } - - var map = forwardEvents(["timeout", "end", "close", "drain", "error"], socket, cleartext); - - function onclose() { - socket.removeListener('error', onerror); - socket.removeListener('close', onclose); - removeEvents(map,socket); - } - - socket.on('error', onerror); - socket.on('close', onclose); - - return cleartext; -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore deleted file mode 100644 index 8d4c2d1d2bc..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.DS_Store -npm-debug.log \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml deleted file mode 100644 index c8f68efafba..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 - -notifications: - email: - recipients: - - andris@node.ee - on_success: change - on_failure: change diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE deleted file mode 100644 index a47b0eaf959..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) 2012 Andris Reinman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md deleted file mode 100644 index 15a81f4e02c..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/README.md +++ /dev/null @@ -1,159 +0,0 @@ -# RAI - Request-Answer-Interface - -**rai** is a node.js module to easily generate text based command line servers. -When a client sends something to the server, the first word of the line is -treated as a command and the rest of the line as binary payload. - -[![Build Status](https://secure.travis-ci.org/andris9/rai.png)](http://travis-ci.org/andris9/rai) - -In addition to line based commands, there's also a data mode, to transmit -everygting received. And there's also an option to switch to TLS mode for -secure connections. - -This way it is trivial to create SMTP, POP3 or similar servers. - -## Installation - - npm install rai - -## Usage - -### Simple server - - var RAIServer = require("rai").RAIServer; - - // create a RAIServer on port 1234 - var server = new RAIServer(); - server.listen(1234); - - // Start listening for client connections - server.on("connect", function(client){ - - // Greet the client - client.send("Hello!"); - - // Wait for a command - client.on("command", function(command, payload){ - - if(command == "STATUS"){ - client.send("Status is OK!"); - }else if(command == "QUIT"){ - client.send("Goodbye"); - client.end(); - }else{ - client.send("Unknown command"); - } - - }); - - }); - -Server only emits `'connect'` and `'error'` events, while the client -objects emit `'timeout'`, `'error'` and `'end'` in addition to data -related events. - -### Starting a server - -Server can be started with `new RAIServer([options])` where options is an optional -parameters object with the following properties: - - * **debug** - if set to true print traffic to console - * **disconnectOnTimeout** - if set to true close the connection on disconnect - * **secureConnection** - if set to true close the connection on disconnect - * **credentials** - credentials for secureConnection and STARTTLS - * **timeout** - timeout in milliseconds for disconnecting the client, defaults to 0 (no timeout) - -Once the server has been set up, it can start listening for client connections -with `server.listen(port[, hostname][, callback])`. Callback function gets an error -object as a parameter if the listening failed. - - var server = new RAIServer(); - server.listen(25); // start listening for port 25 on "localhost" - -### Closing server - -Server can be closed with `server.end([callback])` where callback is run when -the server is finally closed. - -### Sending data - -Data can be sent with `client.send(data)` where `data` is either a String or -a Buffer. `"\r\n"` is automatically appended to the data. - - client.send("Greetings!"); - -### Forcing connection close - -Connections can be ended with `client.end()` - - if(command == "QUIT"){ - client.send("Good bye!"); - client.end(); - } - -### TLS mode - -TLS can be switched on with `client.startTLS([credentials][, callback])` and the status can -be listened with `'tls'` (emitted when secure connection is established) - -`credentials` is an object with strings of pem encoded `key`, `cert` and optionally an -array `ca`. If `credentials` is not supplied, an autogenerated value is used. - - if(command == "STARTTLS"){ - client.startTLS(); - } - - client.on("tls", function(){ - console.log("Switched to secure connection"); - }); - -If `callback` is not set `'tls'` will be emitted on connection upgrade. - -### Data mode - -Data mode can be turned on with `client.startDataMode([endSequence])` and incoming -chunks can be received with `'data'`. The end of data mode can be detected by -`'ready'`. - -`endSequence` is a String for matching the end (entire line) of the data stream. -By default it's `"."` which is suitable for SMTP and POP3. - - if(command == "DATA"){ - client.send("End data with ."); - client.startDataMode(); - } - - client.on("data", function(chunk){ - console.log("Data from client:", chunk); - }); - - client.on("ready", function(){ - client.send("Data received"); - }); - -## Testing - -There is a possibility to set up a mockup client which sends a batch of commands -one by one to the server and returns the last response. - - var runClientMockup = require("rai").runClientMockup; - - var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"]; - runClientMockup(25, "mail.hot.ee", cmds, function(resp){ - console.log("Final:", resp.toString("utf-8").trim()); - }); - -`runClientMockup` has he following parameters in the following order: - - * **port** - Port number - * **host** - Hostname to connect to - * **commands** - Command list (an array) to be sent to server - * **callback** - Callback function to run on completion - * **debug** - if set to true log all input/output - -Response from the callback function is a Buffer and contains the -last data received from the server - -## License - -**MIT** \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem deleted file mode 100644 index cd8c07d1d77..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDcjCCAloCCQCrMskwMC/aPzANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJF -RTEOMAwGA1UECBMFSGFyanUxEDAOBgNVBAcTB1RhbGxpbm4xEjAQBgNVBAoTCUty -ZWF0YSBPVTEXMBUGA1UEAxMOQW5kcmlzIFJlaW5tYW4xHTAbBgkqhkiG9w0BCQEW -DmFuZHJpc0Bub2RlLmVlMB4XDTEzMDExNjA3MjUyMVoXDTIzMDExNDA3MjUyMVow -ezELMAkGA1UEBhMCRUUxDjAMBgNVBAgTBUhhcmp1MRAwDgYDVQQHEwdUYWxsaW5u -MRIwEAYDVQQKEwlLcmVhdGEgT1UxFzAVBgNVBAMTDkFuZHJpcyBSZWlubWFuMR0w -GwYJKoZIhvcNAQkBFg5hbmRyaXNAbm9kZS5lZTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMJHgbiDVizxJ7LGc9yNe/evIdF0gchhKe4o67hn6Qkozdcj -ndtTYP9RpPUk6T7CEcF80WBFCm05m4424ifwuuhUNMEvbLzbcZMs2VmXJi198NzX -koaNJuC51dy+oTnbOc1DlqysokHUr1VaDSz1Nbdxd6Dmm7YVoNa5YpbiqAgPE3I/ -woOwNicSJQSyn7j0+uOOdsMAFZqPrNcNKFuRMV0TiEzByvTdz9iE7M5neTQwP0Zv -iXRHLMv9/Cy2VAL2o0nIbpJj+0pEQLTxvv7UWGKrXlJO5ZgBNanxqxSOcG63Q8ZF -lQsbLfobZy4ufxk2dI7+7uOiCHF8ERqqRobtygsCAwEAATANBgkqhkiG9w0BAQUF -AAOCAQEAUQOFXwJADGwetYtf1eX8tIzIwpOdAE5CBOt+pajJPij64gKLXvaLwk5F -Mxg9jQ3AX3VCU09UQUm7FBYu93dof8FnWyO/jdFeZon1w/Lxycl2FVwkudK1j0xp -bQ7DQwT7h0QsKaZVTfGMD9KBiNFn63k+owyBp9JvdyCIcWv3Q+/QkJ4ED5A0bqlr -bmpGmXT758CJueGbT0ABlta+PTN0kjH4mTJrQ7x4ZdthbFkvqMwjxcsSzyPjS1oq -ANv2jRNGEirj2tT9lZMc2YRl+s4+FFgQeW5ZxMZ7IoLHbzoSHVnK8KrjeA9tX+v2 -QOENJJksNsyiRXkojDarWmufSnA8dw== ------END CERTIFICATE----- diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem deleted file mode 100644 index 8575bda9a32..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAwkeBuINWLPEnssZz3I17968h0XSByGEp7ijruGfpCSjN1yOd -21Ng/1Gk9STpPsIRwXzRYEUKbTmbjjbiJ/C66FQ0wS9svNtxkyzZWZcmLX3w3NeS -ho0m4LnV3L6hOds5zUOWrKyiQdSvVVoNLPU1t3F3oOabthWg1rliluKoCA8Tcj/C -g7A2JxIlBLKfuPT64452wwAVmo+s1w0oW5ExXROITMHK9N3P2ITszmd5NDA/Rm+J -dEcsy/38LLZUAvajSchukmP7SkRAtPG+/tRYYqteUk7lmAE1qfGrFI5wbrdDxkWV -Cxst+htnLi5/GTZ0jv7u46IIcXwRGqpGhu3KCwIDAQABAoIBAEndUAer/5aktXg2 -FZT0Qf7AmjX9et6Jepyu+DgrYaF23xP92aWqxMUt8G638upGdOPApgZZGYa/kVH3 -sfKHhziP02Ljug7vy/Wt5pE2c3B2Yp5EY9Q+VFq6rQH5hGjv3cEaAm5yUFqBF4x2 -6W1/aUXuoRIOu4L2JCmfYEmHsWUmU/IGpP7Wbg3lqGXgZICwDWb3EqbqowGUBu5A -a1oUX47tqC1yz5TilleNZhT0PxGXqMY2D1GuNmy6VQrlB3u90jC0l1K7PnwAoJCy -2A0tM5AudQhE67UIicc4Co9eVP9E0Flht2Tph/+Xx6Mq950bDvPdn3mgYw60WuB7 -U6EkzjkCgYEA9CyBAfGU008+zs1hTaj9XLaQJKv5dDpIU53iPVFoSd/eLb7w+6qW -MZomv8As1lK+dSILvWrOpgEB5DaYzE7dCdqHvSHpDde0+lybQryN6RHNaev1YEAH -rJ/47xNoKeIiW8fLlHTIMNLFM9vwM5Y/xCGd6ie1kTgYsue1nY8Ssh8CgYEAy7Bd -IJ5RisPQhMXaP//p1D+LKX8+Vl902OrYMe+qacL/jBBWjCmI0LgJW1D3XxVcw9hv -XtivEhmlVMLgrDMTGLcSK/HOCvkGrLaEMo1dsrXKFRWlpFn0g2Fits/Vu6r20oop -ppmfeGPs6LYSFnSQDNqbfscVMg7UHC3mFHYcIpUCgYEAySn1Kw3F6AVsoGISXTHx -crWxsZTBkqEFv2Xe41ezTNGUMSoTTbOvw7PVYrrH9db7tHLVKzvYfmlsDoFwhzod -3yVcGVTbtZzWLEGpZGUFoVQaYL6WTLLT38N4Cjd55K+6UNUdAvTnjVnIQD5d+ZI6 -fLKZcDVA4CBQMOy28tTRuU8CgYBq6kf3tyJWFDJ/ftrwfQPfxPrm7UNrUu+ibKLO -k15/5Tr96hWDvMlzxSYkKHuwDSaEJjdPMa2zcoK12xTTTnvXnUCMkH/2goBeZ+88 -Gbf09jb8mkA35H/T9mo6Sx2FRFgKazsxl7F9H/ZasDcOUmDKXnUANr+JZv8vS2hZ -lSVvgQKBgA9UNWZ160LnemRYKTz47meSs767Y+z1MtmGDlZiyLlHelh98x+IrpP0 -/Fu0vIto7CLX/PhBVqUMcqXr6knNgNg7iqesiohjvK+z1D3/F9xSGt8jIPFQiYMk -8P8L8dMqT6BOKkU8/MEVUSOnDHi4Oqtpkj4DKmLQx1QYf3bI2kjK ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js deleted file mode 100644 index 4ee27637ab9..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/examples/smtp.js +++ /dev/null @@ -1,73 +0,0 @@ -var RAIServer = require("../lib/rai").RAIServer; - -var server = new RAIServer({debug: true, timeout:25*1000}); - -server.listen(1234, function(err){ - console.log(err || "listening on port 1234...") -}); - -server.on("connection", function(socket){ - - socket.send("220 foo.bar"); // send banner greeting - - socket.on("command", function(command, payload){ - - command = (command || "").toString().toUpperCase().trim(); - - switch(command){ - case "EHLO": - socket.send("250-foo.bar at your service\r\n"+ - "250-PIPELINING\r\n" + - "250-8BITMIME\r\n"+ - "250 STARTTLS"); - break; - case "STARTTLS": - socket.send("220 Ready to start TLS"); - socket.startTLS(); - break; - case "MAIL": - socket.send("250 Ok"); - break; - case "RCPT": - socket.send("250 Ok"); - break; - case "DATA": - socket.send("354 End with ."); - socket.startDataMode(); - break; - case "QUIT": - socket.send("221 Good bye"); - socket.end(); - break; - default: - socket.send("500 Unknown command"); - } - - }); - - socket.on("tls", function(data){ - console.log("TLS STARTED"); - }); - - socket.on("data", function(data){ - console.log("MAIL DATA", data); - }); - - socket.on("ready", function(data){ - console.log("DATA READY"); - socket.send("250 Ok: queued as FOOBAR"); - }); - - socket.on("timeout", function(data){ - console.log("TIMEOUT"); - }); - - socket.on("error", function(err){ - console.log("ERROR:", err.message || err); - }); - - socket.on("end", function(){ - console.log("Connection closed"); - }); - -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css deleted file mode 100644 index c253cb0d4d4..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/all.css +++ /dev/null @@ -1,358 +0,0 @@ -/* TABLE OF CONTENTS: - * - Browser reset - * - HTML elements - * - JsDoc styling - */ - - - - - - -/* - * BEGIN BROWSER RESET - */ - -body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,p,pre,form,fieldset,input,textarea,p,blockquote,th,td { - margin:0; - padding:0 -} -html { - height:100%; - overflow:-moz-scrollbars-vertical; - overflow-x:auto -} -table { - border:0; - border-collapse:collapse; - border-spacing:0 -} -fieldset,img { - border:0 -} -address,caption,cite,code,dfn,em,strong,th,var { - font-style:normal; - font-weight:normal -} -em,cite { - font-style:italic -} -strong { - font-weight:bold -} -ol,ul { - list-style:none -} -caption,th { - text-align:left -} -h1,h2,h3,h4,h5,h6 { - font-size:100%; - font-weight:normal; - margin:0; - padding:0 -} -q:before,q:after { - content:'' -} -abbr,acronym { - border:0 -} -section,article,header,footer,nav,aside,hgroup { - display:block -} - -/* - * END BROWSER RESET - */ - - - - - - -/* - * HTML ELEMENTS - */ - -@font-face { - font-family: 'M1m'; - src: url('fonts/mplus-1m-regular-webfont.eot'); - src: local('☺'), url('fonts/mplus-1m-regular-webfont.woff') format('woff'), url('fonts/mplus-1m-regular-webfont.ttf') format('truetype'), url('fonts/mplus-1m-regular-webfont.svg#webfontVd14f4NN') format('svg'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'M1m'; - src: url('fonts/mplus-1m-bold-webfont.eot'); - src: local('☺'), url('fonts/mplus-1m-bold-webfont.woff') format('woff'), url('fonts/mplus-1m-bold-webfont.ttf') format('truetype'), url('fonts/mplus-1m-bold-webfont.svg#webfontIjI5mZqE') format('svg'); - font-weight: bold; - font-style: normal; -} - - - -* { - line-height: 1.4em; -} - -html { - font-size: 100%; -} - -body { - font-size: 0.75em; - padding: 15px 0; - background: #eee; - background-image: -moz-linear-gradient(left, #dddddd, #f9f9f9) fixed; - background-image: -webkit-gradient(linear,left bottom,right bottom,color-stop(0, #dddddd),color-stop(1, #f9f9f9)) fixed; - } - -body, -input, -select, -textarea { - color: #000; - font-family: Arial, Geneva, sans-serif; -} - -a:link, -a:hover, -a:active, -a:visited { - color: #19199e; -} -a:hover, -a:focus { - color: #00f; - text-decoration: none; -} - -p { - margin: 0 0 1.5em 0; -} - -/* - * END HTML ELEMENTS - */ - - - -/* - * BEGIN HACK - */ - -div.containerMain:after, -div.safeBox:after { - content:""; - display:block; - height:0; - clear:both; -} - -/* - * END HACK - */ - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index *.heading1 { - margin-bottom: 0.5em; - border-bottom: 1px solid #999999; - font-family: M1m, Arial, sans-serif; - font-size: 1.6em; - letter-spacing: 1px; - line-height: 1.3em; -} - -div.index div.menu { - background-color: #FFFFFF; -} -*+html div.index div.menu { - background-color: #FFFFFF; -} -* html div.index div.menu { - background-color: #FFFFFF; -} - -div.index div.menu div { - text-align: left; -} - -div.index div.menu a { - text-decoration: none; -} -div.index div.menu a:hover { - text-decoration: underline; -} - -div.index ul.classList { - padding-left: 0; -} - -div.index ul.classList a { - display: block; - margin: 1px 0; - padding: 4px 0 2px 10px; - text-indent: -10px; -} - -div.index div.fineprint { - color: #777; - font-size: 0.9em; -} -div.index div.fineprint a { - color: #777; -} -/* End menu */ - - - -/* Start content */ -div.content ul { - padding-left: 0; -} - -div.content *.classTitle { - font-size: 1.2em; - font-weight: bold; - line-height: 1em; -} - -div.content *.classTitle span { - display: block; - font-size: 2em; - letter-spacing: 2px; - line-height: 1em; - padding-top: 5px; - text-shadow: 1px 1px 1px #999999; - word-wrap: break-word; -} - -div.content p.summary { - font-size: 1.25em; -} - -div.content ul *.classname a, -div.content ul *.filename a { - font-family: Consolas, "Courier New", Courier, monospace; - text-decoration: none; - font-weight: bold; -} -div.content ul *.classname a:hover, -div.content ul *.filename a:hover { - text-decoration: underline; -} - -div.content div.props { - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - background: #fff; - background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.2)); /* FF3.6 */ - background: -webkit-gradient(linear,left top,left bottom,color-stop(0, rgba(255, 255, 255, 0.7)),color-stop(1, rgba(255, 255, 255, 0.2))); - -moz-box-shadow: 0px 0px 10px #ccc; - -webkit-box-shadow: 0px 0px 5px #bbb; - box-shadow: 0px 0px 5px #bbb; -} - - - -*.sectionTitle { - font-family: M1m, sans-serif; - font-size: 1.6em; - letter-spacing: 1px; -} - -table.summaryTable td, -table.summaryTable th { - vertical-align: top; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable th { - font-weight: bold; -} - -table.summaryTable td.attributes { - font-family: Consolas, "Courier New", Courier, monospace; - color: #666; -} - -table.summaryTable td.nameDescription div.fixedFont { - font-weight: bold; -} - -table.summaryTable div.description { - color: #333; -} - - - -dl.detailList dt { - font-weight: bold; -} - -dl.inheritsList dd + dt { - margin-top: 10px; -} - -dl.inheritsList dd { - display: inline; -} - - - -.fixedFont { - font-family: Consolas, "Courier New", Courier, monospace; -} - -.fixedFont.heading { - font-size: 1.25em; - line-height: 1.1em -} - -.fixedFont.heading + .description { - font-size: 1.2em; -} - -.fixedFont.heading .light, -.fixedFont.heading .lighter { - font-weight: bold; -} - -pre.code { - overflow: auto; - font-family: Consolas, "Courier New", Courier, monospace; - background: #eee; -} -/* Start content */ - - - -/* Start general styles */ -.light { - color: #666; -} - -.lighter { - color: #999; -} - -span.break { - font-size: 1px; - line-height: 1px; -} -/* End general styles */ - -/* - * END JSDOC - */ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot deleted file mode 100644 index 6c64f8d71d2..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.eot and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg deleted file mode 100644 index 51295128aa1..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.svg +++ /dev/null @@ -1,134 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Foundry URL : http://mplus-fonts.sourceforge.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf deleted file mode 100644 index 0cf54cbbef8..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff deleted file mode 100644 index f90475d890f..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-bold-webfont.woff and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot deleted file mode 100644 index a53f8b54571..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.eot and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg deleted file mode 100644 index 3c835a313b9..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.svg +++ /dev/null @@ -1,134 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Foundry URL : http://mplus-fonts.sourceforge.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf deleted file mode 100644 index 684abfd19f9..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff deleted file mode 100644 index 49585d82dfb..00000000000 Binary files a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/fonts/mplus-1m-regular-webfont.woff and /dev/null differ diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css deleted file mode 100644 index 073c0d1d293..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/handheld.css +++ /dev/null @@ -1,217 +0,0 @@ -/* - * TABLE OF CONTENTS: - * - Browser reset - * - HTML elements - * - JsDoc styling - * - Media query check - */ - - - - - - -/* - * HTML ELEMENTS - */ - -body { - padding: 1% 4% 1% 4%; -} - -/* - * HTML ELEMENTS - */ - - - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index div.menu { - position: fixed; - top: 0; - right: 0; - -moz-border-radius-bottomleft: 15px; - -webkit-border-bottom-left-radius: 15px; - -border-bottom-left-radius: 15px; - padding: 4px 5px 8px 10px; - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; - background-color: rgba(255, 255, 255, 0.9); -} - -div.index input.classFilter { - display: none; -} - -div.index div.indexLinks a { - float: right; - clear: both; - font-size: 1.1em; -} - -div.index *.heading1 { - display:none; -} - -div.index ul.classList { - display:none; -} - -div.index div.fineprint { - display:none; -} - -div.indexStatic { - display: none; -} -/* End menu */ - - - -/* Start content */ -div.content *.classTitle { - margin-right: 60px; - margin-bottom: 15px; -} - -div.content div.intro { - margin: 15px 0 35px; -} - -div.content p.description.summary { - margin-bottom: 0.2em; -} - -div.content div.props { - margin: 1.5em -2% 0 -2%; - padding: 2%; -} - -table.summaryTable { - position: relative; - left: -10px; - width: 100%; - border-collapse: collapse; - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - -ms-box-sizing: content-box; - -o-box-sizing: content-box; - -icab-box-sizing: content-box; - -khtml-box-sizing: content-box; -} - -*.sectionTitle { - padding: 0 10px 10px 0; -} -caption.sectionTitle { - padding-left: 10px; -} - -table.summaryTable td, -table.summaryTable th { - padding: 0px 10px 10px 10px; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable td.attributes { - width: 35%; -} - -table.summaryTable td.nameDescription { - width: 65% -} - - - -dl.detailList { - margin-top: 0.5em; -} - -dl.detailList.nomargin + dl.detailList.nomargin { - margin-top: 0; -} - -dl.detailList dt { - display: inline; - margin-right: 5px; -} - -dl.detailList dt:before { - display: block; - content: ""; -} - -dl.detailList dd { - display: inline; -} - -dl.detailList.params dt { - display: block; -} -dl.detailList.params dd { - display: block; - padding-left: 2em; - padding-bottom: 0.4em; -} - - - - -ul.fileList li { - margin-bottom: 1.5em; -} - - - -.fixedFont.heading { - margin-bottom: 0.5em; -} - -pre.code { - margin: 10px 0 10px 0; - padding: 10px; - border: 1px solid #ccc; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; -} -/* End content */ - -/* - * END JSDOC - */ - - - - - - - -/* - * START MEDIA QUERY CHECK - */ - -.cssLoadCheck { - position: absolute; - top: -99999px; - left: -99999px; - border: 0; - width: 100px; - padding: 0; - overflow: hidden; -} - -/* - * END MEDIA QUERY CHECK - */ - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css deleted file mode 100644 index 8cb4bba34c3..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/css/screen.css +++ /dev/null @@ -1,297 +0,0 @@ -/* - * TABLE OF CONTENTS: - * - JsDoc styling - * - Media query check - */ - - - - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index { - position: fixed; - top: 0; - bottom: 0; - float: left; - width: 30%; - min-width: 100px; - max-width: 300px; - padding: 0 0 10px 0; - overflow: auto; -} - -div.index *.heading1 { - padding: 8px 0 0 0; -} - -div.index div.menu { - margin: 0 15px 0 -15px; - -moz-border-radius-bottomright: 15px; - -webkit-border-bottom-right-radius: 15px; - -border-bottom-right-radius: 15px; - padding: 15px 15px 15px 30px; - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; - background-color: rgba(255, 255, 255, 0.5); -} - -div.index div.indexLinks { - margin-top: 13px; - position: absolute; - right: 30px; -} - -div.index div.indexLinks a { - color: #999999; - text-transform: lowercase; -} - -div.index div.indexLinks a:first-child { - margin-right: 3px; - border-right: 1px solid #999999; - padding-right: 5px; -} - -div.index input.classFilter { - margin-bottom: 4px; - width: 100%; - border-width: 1px; - border-style: solid; - border-color: #CCCCCC #999999 #999999 #CCCCCC; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - -border-radius: 3px; -} - -div.index ul.classList a { - line-height: 1.3em; -} - -div.index ul.classList a + a { - margin-left: 0.5em; -} - -div.index div.fineprint { - margin: 1em 0 0 15px; - color: #777; - font-size: 0.9em; -} - -div.index div.fineprint a { - color: #777; -} - -div.indexStatic { - position: static; - min-height: 1em; -} -/* End menu */ - - -/* Start content */ -div.content { - float: left; - width: 70%; - min-width: 300px; - max-width: 600px; -} -div.innerContent { - padding: 0 0 0 2.5em; -} - -div.content ul, -div.content ol { - margin-bottom: 3em; -} - -div.content ul.methodDetail { - margin-bottom: 0; -} - -div.content *.classTitle { - position: relative; - left: -10px; - margin: -30px 0 15px 0; - -moz-border-radius: 15px; - -webkit-border-radius: 15px; - border-radius: 15px; - padding: 25px 15px 15px 15px; - background-color: #FFFFFF; - background-color: rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; -} - -div.content div.intro { - margin: 15px 0 45px -} - -div.content p.summary { - margin-bottom: 0.5em; -} - -div.content ul.summary { - margin-bottom: 1.5em; -} - -div.content ul *.classname a, -div.content ul *.filename a { - font-family: Consolas, "Courier New", Courier, monospace; - text-decoration: none; - font-weight: bold; -} -div.content ul *.classname a:hover, -div.content ul *.filename a:hover { - text-decoration: underline; -} - -div.content div.props { - position: relative; - left: -10px; - margin-bottom: 2.5em; - padding: 10px 15px 15px 15px; - overflow: hidden; -} - -div.content div.hr { - margin: 0 10px 0 0; - height: 4em; -} - - - -table.summaryTable { - position: relative; - left: -10px; - width: 100%; - border-collapse: collapse; - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - -ms-box-sizing: content-box; - -o-box-sizing: content-box; - -icab-box-sizing: content-box; - -khtml-box-sizing: content-box; -} - -*.sectionTitle { - padding: 0 10px 10px 0; -} -caption.sectionTitle { - padding-left: 10px; -} - -table.summaryTable td, -table.summaryTable th { - padding: 0px 10px 10px 10px; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable td.attributes { - width: 35%; -} - -table.summaryTable td.nameDescription { - width: 65% -} - - - -dl.detailList { - margin-top: 0.5em; -} - -dl.detailList.nomargin + dl.detailList.nomargin { - margin-top: 0; -} - -dl.detailList dt { - display: inline; - margin-right: 5px; -} - -dl.detailList dt:before { - display: block; - content: ""; -} - -dl.detailList dd { - display: inline; -} - -dl.detailList.params dt { - display: block; -} -dl.detailList.params dd { - display: block; - padding-left: 2em; - padding-bottom: 0.4em; -} - - - - -ul.fileList li { - margin-bottom: 1.5em; -} - - - -.fixedFont.heading { - margin-bottom: 0.5em; -} - -pre.code { - margin: 10px 0 10px 0; - padding: 10px; - border: 1px solid #ccc; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; -} -/* End content */ - -.clear { - clear: both; - width: 100%; - min-height: 0; -} - -/* - * END JSDOC - */ - - - - - - - -/* - * START MEDIA QUERY CHECK - */ - -.cssLoadCheck { - position: absolute; - top: -99999px; - left: -99999px; - border: 0; - width: 100px; - padding: 0; - overflow: hidden; -} - -/* - * END MEDIA QUERY CHECK - */ - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html deleted file mode 100644 index a4f372ae5f1..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/files.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - File Index | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-

File Index

- - -
-
-
- - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html deleted file mode 100644 index 544613f169e..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/index.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - Class Index | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
- -
-
- - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js deleted file mode 100644 index 5b6876af3b6..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/all.js +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @fileOverview Contains standard code in the namespace 'wbos' and code specifically written for Codeview in the namespace 'codeview' - * @author Wouter Bos (www.thebrightlines.com) - * @since 1.0 - 2010-09-10 - * @version 1.0 - 2010-09-10 - */ - - - - - - -if (typeof(wbos) == "undefined") { - /** - * @namespace Standard code of Wouter Bos (wbos) - */ - wbos = {} -} -if (typeof(wbos.CssTools) == "undefined") { - /** - * @namespace Namespace for CSS-related functionality - */ - wbos.CssTools = {} -} - - - - -/** - * @namespace Fallback for CSS advanced media query - * @class - * @since 1.0 - 2010-09-10 - * @version 1.0 - 2010-09-10 - */ -wbos.CssTools.MediaQueryFallBack = ( function() { - var config = { - cssScreen: "/css/screen.css", - cssHandheld: "/css/handheld.css", - mobileMaxWidth: 660, - testDivClass: "cssLoadCheck", - dynamicCssLinkId: "DynCssLink", - resizeDelay: 30 - } - var noMediaQuery = false; - var delay; - var currentCssMediaType; - - // Adding events to elements in the DOM without overwriting it - function addEvent(element, newFunction, eventType) { - var oldEvent = eval("element." + eventType); - var eventContentType = eval("typeof element." + eventType) - - if ( eventContentType != 'function' ) { - eval("element." + eventType + " = newFunction") - } else { - eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }") - } - } - - // Get the the inner width of the browser window - function getWindowWidth() { - if (window.innerWidth) { - return window.innerWidth; - } else if (document.documentElement.clientWidth) { - return document.documentElement.clientWidth; - } else if (document.body.clientWidth) { - return document.body.clientWidth; - } else{ - return 0; - } - } - - function addCssLink(cssHref) { - var cssNode = document.createElement('link'); - var windowWidth; - cssNode.type = 'text/css'; - cssNode.rel = 'stylesheet'; - cssNode.media = 'screen, handheld, fallback'; - cssNode.href = cssHref; - document.getElementsByTagName("head")[0].appendChild(cssNode); - } - - - - /* Start public */ - return { - /** - * Adds link to CSS in the head if no CSS is loaded - * - * @since 1.0 - 2010-08-21 - * @version 1.0 - 2010-08-21 - * @param {String|Object} cssScreen URL to CSS file for larger screens - * @param {String|Object} cssHandheld URL to CSS file for smaller screens - * @param {Number} mobileMaxWidth Maximum width for handheld devices - * @example - * wbos.CssTools.MediaQueryFallBack.LoadCss(['screen.css', 'screen2.css'], 'mobile.css', 480) - */ - LoadCss: function(cssScreen, cssHandheld, mobileMaxWidth) { - // Set config values - if (typeof(cssScreen) != "undefined") { - config.cssScreen = cssScreen; - } - if (typeof(cssHandheld) != "undefined") { - config.cssHandheld = cssHandheld; - } - if (typeof(mobileMaxWidth) != "undefined") { - config.mobileMaxWidth = mobileMaxWidth; - } - - // Check if CSS is loaded - var cssloadCheckNode = document.createElement('div'); - cssloadCheckNode.className = config.testDivClass; - document.getElementsByTagName("body")[0].appendChild(cssloadCheckNode); - if (cssloadCheckNode.offsetWidth != 100 && noMediaQuery == false) { - noMediaQuery = true; - } - cssloadCheckNode.parentNode.removeChild(cssloadCheckNode) - - if (noMediaQuery == true) { - // Browser does not support Media Queries, so JavaScript will supply a fallback - var cssHref = ""; - - // Determines what CSS file to load - if (getWindowWidth() <= config.mobileMaxWidth) { - cssHref = config.cssHandheld; - newCssMediaType = "handheld"; - } else { - cssHref = config.cssScreen; - newCssMediaType = "screen"; - } - - // Add CSS link to of page - if (cssHref != "" && currentCssMediaType != newCssMediaType) { - var currentCssLinks = document.styleSheets - for (var i = 0; i < currentCssLinks.length; i++) { - for (var ii = 0; ii < currentCssLinks[i].media.length; ii++) { - if (typeof(currentCssLinks[i].media) == "object") { - if (currentCssLinks[i].media.item(ii) == "fallback") { - currentCssLinks[i].ownerNode.parentNode.removeChild(currentCssLinks[i].ownerNode) - i-- - break; - } - } else { - if (currentCssLinks[i].media.indexOf("fallback") >= 0) { - currentCssLinks[i].owningElement.parentNode.removeChild(currentCssLinks[i].owningElement) - i-- - break; - } - } - } - } - if (typeof(cssHref) == "object") { - for (var i = 0; i < cssHref.length; i++) { - addCssLink(cssHref[i]) - } - } else { - addCssLink(cssHref) - } - - currentCssMediaType = newCssMediaType; - } - - - // Check screen size again if user resizes window - addEvent(window, wbos.CssTools.MediaQueryFallBack.LoadCssDelayed, 'onresize') - } - }, - - /** - * Runs LoadCSS after a short delay - * - * @since 1.0 - 2010-08-21 - * @version 1.0 - 2010-08-21 - * @example - * wbos.CssTools.MediaQueryFallBack.LoadCssDelayed() - */ - LoadCssDelayed: function() { - clearTimeout(delay); - delay = setTimeout( "wbos.CssTools.MediaQueryFallBack.LoadCss()", config.resizeDelay) - } - - } - /* End public */ -})(); - - - - - - -/** - * @namespace Adds a function to an event of a single element. Use this if - * you don't want to use jQuery - * @class - * @since 1.0 - 2010-02-23 - * @version 1.0 - 2010-02-23 - */ -wbos.Events = ( function() { - /* Start public */ - return { - /** - * Adds a function to an event of a single element - * - * @since 1.0 - 2010-02-23 - * @version 1.0 - 2010-02-23 - * @param {Object} element The element on which the event is placed - * @param {Function} newFunction The function that has to be linked to the event - * @param {String} eventType Name of the event - * @example - * wbos.Events.AddEvent( document.getElementById('elementId'), functionName, "onclick" ) - */ - AddEvent: function( element, newFunction, eventType ) { - var oldEvent = eval("element." + eventType); - var eventContentType = eval("typeof element." + eventType) - - if ( eventContentType != 'function' ) { - eval("element." + eventType + " = newFunction") - } else { - eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }") - } - } - } - /* End public */ -})(); - - - - - - -if (typeof(codeview) == "undefined") { - /** - * @namespace Code written for the Codeview template - */ - codeview = {} -} - - - - - - - -/** - * @namespace Enables filtering in class lists - * @class - * @since 1.0 - 2010-11-08 - * @version 1.0 - 2010-11-08 - */ -codeview.classFilter = ( function() { - function onkeyup_ClassFilter() { - var listItems - var search = document.getElementById('ClassFilter').value - search = search.toLowerCase() - if (document.getElementById('ClassList')) { - listItems = document.getElementById('ClassList').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('ClassList2')) { - listItems = document.getElementById('ClassList2').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('FileList')) { - listItems = document.getElementById('FileList').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('MethodsListInherited')) { - var links = document.getElementById('MethodsListInherited').getElementsByTagName('a') - var linksSelected = new Array() - for (var i=0; i < links.length; i++) { - if (links[i].parentNode.parentNode.tagName == "DD") { - linksSelected.push(links[i]) - } - } - filterList(linksSelected, search) - } - if (document.getElementById('MethodsList')) { - listItems = document.getElementById('MethodsList').getElementsByTagName('tbody')[0].getElementsByTagName('tr') - filterList(listItems, search, document.getElementById('MethodDetail').getElementsByTagName('li')) - } - } - - function filterList(listItems, search, relatedElements) { - var itemContent = "" - for (var i=0; i < listItems.length; i++) { - itemContent = listItems[i].textContent||listItems[i].innerText - if (itemContent != undefined) { - itemContent = itemContent.toLowerCase() - itemContent = itemContent.replace(/\s/g, "") - if (itemContent.indexOf(search) >= 0 || itemContent == "") { - listItems[i].style.display = "" - } else { - listItems[i].style.display = "none" - } - if (relatedElements != null) { - filterRelatedList(listItems[i], search, relatedElements) - } - } - } - } - - function filterRelatedList(listItem, search, relatedElements) { - var itemIndex = parseInt(listItem.className.replace('item', '')) - if (itemIndex <= relatedElements.length) { - if (relatedElements[itemIndex].className == "item"+ itemIndex) { - relatedElements[itemIndex].style.display = listItem.style.display - } - } - } - - - - - - /* Start public */ - return { - Init: function() { - wbos.Events.AddEvent( - document.getElementById('ClassFilter'), - onkeyup_ClassFilter, - "onkeyup" - ) - } - } - /* End public */ -})(); diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js deleted file mode 100644 index 3587bf73497..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/javascript/html5.js +++ /dev/null @@ -1,6 +0,0 @@ -// html5shiv MIT @rem remysharp.com/html5-enabling-script -// iepp v1.6.2 MIT @jon_neal iecss.com/print-protector -/*@cc_on(function(m,c){var z="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video";function n(d){for(var a=-1;++ai";if(g.childNodes.length!==1){var i=z.split("|"),o=i.length,s=RegExp("(^|\\s)("+z+")", -"gi"),t=RegExp("<(/*)("+z+")","gi"),u=RegExp("(^|[^\\n]*?\\s)("+z+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),r=c.createDocumentFragment(),k=c.documentElement;g=k.firstChild;var h=c.createElement("body"),l=c.createElement("style"),f;n(c);n(r);g.insertBefore(l, -g.firstChild);l.media="print";m.attachEvent("onbeforeprint",function(){var d=-1,a=p(c.styleSheets,"all"),e=[],b;for(f=f||c.body;(b=u.exec(a))!=null;)e.push((b[1]+b[2]+b[3]).replace(s,"$1.iepp_$2")+b[4]);for(l.styleSheet.cssText=e.join("\n");++d - - - - - RAIServer | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-
-

- - Class RAIServer -

- -
-

- -

- - -
    - - - -
  • Defined in: rai.js
  • - - -
- -
-
- - -
-
- - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- RAIServer(options) -
-

Creates instance of RAIServer

- -

Options object has the following properties:

- -
    -
  • debug - if set to true print traffic to console
  • -
  • disconnectOnTimeout - if set to true close the connection on disconnect
  • -
  • timeout - timeout in milliseconds for disconnecting the client, - defaults to 0 (no timeout)
  • -
- -

Events

- -
    -
  • 'connect' - emitted if a client connects to the server, param - is a client (RAISocket) object
  • -
  • 'error' - emitted on error, has an error object as a param
  • -
-
-
-
- - - - - -
- - -
-

Method Summary

- - - - - - -
-
- - - - - -
- - - - - -
- - - -
-
-
-

- Class Detail -

- -
- RAIServer(options) -
- -
-

Creates instance of RAIServer

- -

Options object has the following properties:

- -
    -
  • debug - if set to true print traffic to console
  • -
  • disconnectOnTimeout - if set to true close the connection on disconnect
  • -
  • timeout - timeout in milliseconds for disconnecting the client, - defaults to 0 (no timeout)
  • -
- -

Events

- -
    -
  • 'connect' - emitted if a client connects to the server, param - is a client (RAISocket) object
  • -
  • 'error' - emitted on error, has an error object as a param
  • -
- -
- - - - -
-
Parameters:
- -
- {Object} options - Optional -
-
Optional options object
- -
- - - -
-
-
- - - - - -
-
-
-

- Method Detail -

- -
    - - -
  • -
    - - <private> - - - - - _createServer() -
    - -
    -

    Creates a server with listener callback

    - - - - -
    - - - - - - -
    -
  • - -
  • -
    - - <private> - - - - - _serverListener(socket) -
    - -
    -

    Server listener that is run on client connection

    - -

    RAISocket object instance is created based on the client socket - and a 'connection' event is emitted

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Object} socket - -
    -
    The socket to the client
    - -
    - - - -
    -
  • - -
  • -
    - - - - - - - end(callback) -
    - -
    -

    Stops the server

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Function} callback - -
    -
    Is run when the server is closed
    - -
    - - - -
    -
  • - -
  • -
    - - - - - - - listen(port, host, callback) -
    - -
    -

    Starts listening on selected port

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Number} port - -
    -
    The port to listen
    - -
    - {String} host - Optional -
    -
    The IP address to listen
    - -
    - {Function} callback - -
    -
    The callback function to be run after the server -is listening, the only param is an error message if the operation failed
    - -
    - - - - -
  • - -
-
-
-
- - - - -
-
-
-

- Event Detail -

- - -
- - <private> - - - - - _onError(err) -
- -
-

Listens for errors

- - - - -
- - - - -
-
Parameters:
- -
- {Object} err - -
-
Error object
- -
- - - - - - -
-
-
- -
-
-
- - - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html deleted file mode 100644 index 15cad387018..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/RAISocket.html +++ /dev/null @@ -1,826 +0,0 @@ - - - - - - - RAISocket | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-
-

- - Class RAISocket -

- -
-

- -

- - -
    - - - -
  • Defined in: rai.js
  • - - -
- -
-
- - -
-
- - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- RAISocket(socket, options) -
-

Creates a instance for interacting with a client (socket)

- -

Optional options object is the same that is passed to the parent -RAIServer object

- -

Events

- -
    -
  • 'command' - emitted if a client sends a command.
-
-
-
- - - - - -
- - -
-

Method Summary

- - - - - - -
-
- - - - - -
- - - - - -
- - - -
-
-
-

- Class Detail -

- -
- RAISocket(socket, options) -
- -
-

Creates a instance for interacting with a client (socket)

- -

Optional options object is the same that is passed to the parent -RAIServer object

- -

Events

- -
    -
  • 'command' - emitted if a client sends a command. Gets two - params - command (String) and payload (Buffer)
  • -
  • 'data' - emitted when a chunk is received in data mode, the - param being the payload (Buffer)
  • -
  • 'ready' - emitted when data stream ends and normal command - flow is recovered
  • -
  • 'tls' - emitted when the connection is secured by TLS
  • -
  • 'error' - emitted when an error occurs. Connection to the - client is disconnected automatically. Param is an error object. -
  • 'timeout' - emitted when a timeout occurs. Connection to the - client is disconnected automatically if disconnectOnTimeout option - is set to true. -
  • 'end' - emitted when the client disconnects -
- -
- - - - -
-
Parameters:
- -
- {Object} socket - -
-
Socket for the client
- -
- {Object} options - Optional -
-
Optional options object
- -
- - - -
-
-
- - - - - -
-
-
-

- Method Detail -

- -
    - - -
  • -
    - - <private> - - - - - _destroy() -
    - -
    -

    Called when the connection is or is going to be ended

    - - - - -
    - - - - - - -
    -
  • - -
  • -
    - - <private> - - - - - _processData(str) -
    - -
    -

    Processed incoming command lines and emits found data as -'command' with the command name as the first param and the rest -of the data as second (Buffer)

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {String} str - -
    -
    Binary string to be processed
    - -
    - - - -
    -
  • - -
  • -
    - - - - - - - end() -
    - -
    -

    Closes the connection to the client

    - - - - -
    - - - - - - -
    -
  • - -
  • -
    - - - - - - - send(data) -
    - -
    -

    Sends some data to the client. <CR><LF> is automatically appended to - the data

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {String|Buffer} data - -
    -
    Data to be sent to the client
    - -
    - - - -
    -
  • - -
  • -
    - - - - - - - startDataMode(sequence) -
    - -
    -

    Instructs the server to be listening for mixed data instead of line based - commands

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {String} sequence - Optional, Default: "." -
    -
    - optional sequence on separate line for - matching the data end
    - -
    - - - -
    -
  • - -
  • -
    - - - - - - - startTLS(credentials, callback) -
    - -
    -

    Instructs the server to upgrade the connection to secure TLS connection

    - -

    Fires callback on successful connection upgrade if set, -otherwise emits 'tls'

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Object} credentials - Optional -
    -
    An object with PEM encoded key and - certificate {key:"---BEGIN...", cert:"---BEGIN..."}, - if not set autogenerated values will be used.
    - -
    - {Function} callback - Optional -
    -
    If calback is set fire it after successful connection - upgrade, otherwise 'tls' is emitted
    - -
    - - - - -
  • - -
-
-
-
- - - - -
-
-
-

- Event Detail -

- - -
- - <private> - - - - - _onClose(hadError) -
- -
-

Called when the connection is closed

- - - - -
- - - - -
-
Parameters:
- -
- {Boolean} hadError - -
-
did the connection end because of an error?
- -
- - - - -
- -
- - <private> - - - - - _onEnd() -
- -
-

Called when the connection is ended. Emits 'end'

- - - - -
- - - - - - - -
- -
- - <private> - - - - - _onError(err) -
- -
-

Called when an error has appeared. Emits 'error' with -the error object as a parameter.

- - - - -
- - - - -
-
Parameters:
- -
- {Object} err - -
-
Error object
- -
- - - - -
- -
- - <private> - - - - - _onReceiveData(chunk) -
- -
-

Called when a chunk of data arrives from the client. If currently in data -mode, transmit the data otherwise send it to _processData

- - - - -
- - - - -
-
Parameters:
- -
- {Buffer|String} chunk - -
-
Data sent by the client
- -
- - - - -
- -
- - <private> - - - - - _onTimeout() -
- -
-

Called when a timeout has occured. Connection will be closed and -'timeout' is emitted.

- - - - -
- - - - - - - - - -
-
-
- -
-
-
- - - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html deleted file mode 100644 index b215cf7a0d0..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/_global_.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - _global_ | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-
-

- - Built-In Namespace _global_ -

- -
-

- -

- - -
-
- - - - - - - - - - - - - - - - - - -
-
-
- - - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html deleted file mode 100644 index 987f5be8801..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/mockup.html +++ /dev/null @@ -1,264 +0,0 @@ - - - - - - - mockup | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-
-

- - Namespace mockup -

- -
-

- Mockup module -

- - - - -
-
- - - - - - -
- - -
-

Method Summary

- - - - - - -
-
- - - - - - - - - - -
-
-
-

- Method Detail -

- -
    - - -
  • -
    - - <static> - - - - - mockup.runClientMockup(port, host, commands, callback, debug) -
    - -
    -

    Runs a batch of commands against a server

    - -
    -var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
    -runClientMockup(25, "mail.hot.ee", cmds, function(resp){
    -    console.log("Final:", resp.toString("utf-8").trim());
    -});
    -
    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Number} port - -
    -
    Port number
    - -
    - {String} host - -
    -
    Hostname to connect to
    - -
    - {Array} commands - -
    -
    Command list to be sent to server
    - -
    - {Function} callback - -
    -
    Callback function to run on completion, - has the last response from the server as a param
    - -
    - {Boolean} debug - Optional -
    -
    if set to true log all input/output
    - -
    - - - - -
  • - -
-
-
-
- - - - -
-
-
- - - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html deleted file mode 100644 index 3cee0e3f9c1..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_index.js.html +++ /dev/null @@ -1,394 +0,0 @@ -
  1 /**
-  2  * @fileOverview This is the main file for the RAI library to create text based servers
-  3  * @author <a href="mailto:andris@node.ee">Andris Reinman</a>
-  4  * @version 0.1.0
-  5  */
-  6 
-  7 var netlib = require("net"),
-  8     utillib = require("util"),
-  9     EventEmitter = require('events').EventEmitter,
- 10     starttls = require("./starttls"),
- 11     tlslib = require("tls"),
- 12     crypto = require("crypto"),
- 13     fs = require("fs");
- 14 
- 15 // Default credentials for starting TLS server
- 16 var defaultCredentials = {
- 17     key: fs.readFileSync(__dirname+"/cert/key.pem"),
- 18     cert: fs.readFileSync(__dirname+"/cert/cert.pem")
- 19 }
- 20 
- 21 // Expose to the world
- 22 module.exports.RAIServer = RAIServer;
- 23 
- 24 /**
- 25  * <p>Creates instance of RAIServer</p>
- 26  * 
- 27  * <p>Options object has the following properties:</p>
- 28  * 
- 29  * <ul>
- 30  *   <li><b>debug</b> - if set to true print traffic to console</li>
- 31  *   <li><b>timeout</b> - timeout in milliseconds for disconnecting the client,
- 32  *       defaults to 0 (no timeout)</li>
- 33  * </ul>
- 34  * 
- 35  * <p><b>Events</b></p>
- 36  * 
- 37  * <ul>
- 38  *     <li><b>'connect'</b> - emitted if a client connects to the server, param
- 39  *         is a client ({@link RAISocket}) object</li>
- 40  * </ul> 
- 41  * 
- 42  * @constructor
- 43  * @param {Object} [options] Optional options object
- 44  */
- 45 function RAIServer(options){
- 46     EventEmitter.call(this);
- 47     
- 48     this.options = options || {};
- 49     
- 50     this._createServer();
- 51 }
- 52 utillib.inherits(RAIServer, EventEmitter);
- 53 
- 54 /**
- 55  * <p>Starts listening on selected port</p>
- 56  * 
- 57  * @param {Number} port The port to listen
- 58  * @param {String} [host] The IP address to listen
- 59  * @param {Function} callback The callback function to be run after the server
- 60  * is listening, the only param is an error message if the operation failed 
- 61  */
- 62 RAIServer.prototype.listen = function(port, host, callback){
- 63     if(!callback && typeof host=="function"){
- 64         callback = host;
- 65         host = undefined;
- 66     }
- 67     this._port = port;
- 68     this._host = host;
- 69     
- 70     this._server.listen(port, host, function(err){
- 71         if(err && !callback){
- 72             this.emit("error", err);
- 73         }else if(callback){
- 74             callback(err || null);
- 75         }
- 76     });
- 77 }
- 78 
- 79 /**
- 80  * <p>Creates a server with listener callback</p> 
- 81  */
- 82 RAIServer.prototype._createServer = function(){
- 83     this._server = netlib.createServer(this._serverListener.bind(this));
- 84 }
- 85 
- 86 /**
- 87  * <p>Server listener that is run on client connection</p>
- 88  * 
- 89  * <p>{@link RAISocket} object instance is created based on the client socket
- 90  *    and a <code>'connection'</code> event is emitted</p>
- 91  * 
- 92  * @param {Object} socket The socket to the client 
- 93  */
- 94 RAIServer.prototype._serverListener = function(socket){
- 95     if(this.options.debug){
- 96         console.log("CONNECTION FROM "+socket.remoteAddress);
- 97     }
- 98     
- 99     var handler = new RAISocket(socket, this.options);
-100     
-101     socket.on("data", handler._onReceiveData.bind(handler));
-102     socket.on("end", handler._onEnd.bind(handler));
-103     socket.on("error", handler._onError.bind(handler));
-104     socket.on("timeout", handler._onTimeout.bind(handler));
-105     socket.on("close", handler._onClose.bind(handler));
-106 
-107     this.emit("connection", handler);
-108 }
-109 
-110 /**
-111  * <p>Creates a instance for interacting with a client (socket)</p>
-112  * 
-113  * <p>Optional options object is the same that is passed to the parent
-114  * {@link RAIServer} object</p>
-115  * 
-116  * <p><b>Events</b></p>
-117  * 
-118  * <ul>
-119  *     <li><b>'command'</b> - emitted if a client sends a command. Gets two
-120  *         params - command (String) and payload (Buffer)</li>
-121  *     <li><b>'data'</b> - emitted when a chunk is received in data mode, the
-122  *         param being the payload (Buffer)</li>
-123  *     <li><b>'ready'</b> - emitted when data stream ends and normal command
-124  *         flow is recovered</li>
-125  *     <li><b>'tls'</b> - emitted when the connection is secured by TLS</li>
-126  *     <li><b>'error'</b> - emitted when an error occurs. Connection to the
-127  *         client is disconnected automatically. Param is an error object.</l>
-128  *     <li><b>'timeout'</b> - emitted when a timeout occurs. Connection to the
-129  *         client is disconnected automatically.</l>
-130  *     <li><b>'end'</b> - emitted when the client disconnects</l>
-131  * </ul>
-132  * 
-133  * @constructor
-134  * @param {Object} socket Socket for the client
-135  * @param {Object} [options] Optional options object
-136  */
-137 function RAISocket(socket, options){
-138     EventEmitter.call(this);
-139     
-140     this.socket = socket;
-141     this.options = options || {};
-142     
-143     this.remoteAddress = socket.remoteAddress;
-144     
-145     this._dataMode = false;
-146     this._endDataModeSequence = /\r\n\.\r\n|^\.\r\n/;
-147     
-148     this._secureConnection = false;
-149     this._destroyed = false;
-150     this._remainder = "";
-151     
-152     this._ignore_data = false;
-153     
-154     if(this.options.timeout){
-155         socket.setTimeout(this.options.timeout);
-156     }
-157 }
-158 utillib.inherits(RAISocket, EventEmitter);
-159 
-160 /**
-161  * <p>Sends some data to the client. <CR><LF> is automatically appended to
-162  *    the data</p>
-163  * 
-164  * @param {String|Buffer} data Data to be sent to the client
-165  */
-166 RAISocket.prototype.send = function(data){
-167     var buffer;
-168     if(data instanceof Buffer || (typeof SlowBuffer != "undefined" && data instanceof SlowBuffer)){
-169         buffer = new Buffer(data.length+2);
-170         buffer[buffer.length-2] = 0xD;
-171         buffer[buffer.length-1] = 0xA;
-172         data.copy(buffer);
-173     }else{
-174         buffer = new Buffer((data || "").toString()+"\r\n", "binary");
-175     }
-176     
-177     if(this.options.debug){
-178         console.log("OUT: \"" +buffer.toString("utf-8").trim()+"\"");
-179     }
-180     
-181     this.socket.write(buffer);
-182 }
-183 
-184 /**
-185  * <p>Instructs the server to be listening for mixed data instead of line based
-186  *    commands</p>
-187  * 
-188  * @param {String|RegExp} [sequence="\r\n.\r\n"] - optional sequence for
-189  *        matching the data end 
-190  */
-191 RAISocket.prototype.startDataMode = function(sequence){
-192     this._dataMode = true;
-193     if(sequence){
-194         this._endDataModeSequence = typeof sequence == "string" ? new RegExp(sequence) : sequence;
-195     }
-196 }
-197 
-198 /**
-199  * <p>Instructs the server to upgrade the connection to secure TLS connection</p>
-200  * 
-201  * <p>Emits <code>'tls'</code> on successful upgrade</p>
-202  * 
-203  * @param {Object} [credentials] - An object with PEM encoded key and 
-204  *        certificate <code>{key:"---BEGIN...", cert:"---BEGIN..."}</code>,
-205  *        if not set autogenerated values will be used.
-206  */
-207 RAISocket.prototype.startTLS = function(credentials){
-208     if(this._secureConnection){
-209         this._onError(new Error("Secure connection already established"));
-210     }
-211     
-212     credentials = credentials || defaultCredentials;
-213     
-214     this._ignore_data = true;
-215     
-216     var secure_connector = starttls(this.socket, credentials, (function(ssl_socket){
-217 
-218         if(this.options.debug && !ssl_socket.authorized){
-219             console.log("WARNING: TLS ERROR ("+ssl_socket.authorizationError+")");
-220         }
-221         
-222         this._remainder = "";
-223         this._ignore_data = false;
-224         
-225         this._secureConnection = true;
-226     
-227         this.socket = ssl_socket;
-228         this.socket.on("data", this._onReceiveData.bind(this));
-229         
-230         if(this.options.debug){
-231             console.log("TLS CONNECTION STARTED");
-232         }
-233         
-234         this.emit("tls");
-235         
-236     }).bind(this));
-237     
-238     secure_connector.on("error", (function(err){
-239         this._onError(err);
-240     }).bind(this));
-241 }
-242 
-243 /**
-244  * <p>Closes the connection to the client</p>
-245  */
-246 RAISocket.prototype.end = function(){
-247     this.socket.end();
-248 }
-249 
-250 /**
-251  * <p>Called when a chunk of data arrives from the client. If currently in data
-252  * mode, transmit the data otherwise send it to <code>_processData</code></p>
-253  * 
-254  * @param {Buffer|String} chunk Data sent by the client
-255  */
-256 RAISocket.prototype._onReceiveData = function(chunk){
-257     if(this._ignore_data){ // if currently setting up TLS connection
-258         return;
-259     }
-260     
-261     var str = typeof chunk=="string"?chunk:chunk.toString("binary"),
-262         dataEndMatch, dataRemainderMatch, data;
-263     
-264     if(this._dataMode){
-265         
-266         str = this._remainder + str;
-267         
-268         if(dataEndMatch = str.match(/\r\n.*?$/)){
-269             // if theres a line that is not ended, keep it for later
-270             this._remainder = str.substr(dataEndMatch.index);
-271             str = str.substr(0, dataEndMatch.index);
-272         }else{
-273             this._remainder = "";
-274         }
-275         
-276         if((dataRemainderMatch = (str+this._remainder).match(this._endDataModeSequence))){
-277             if(dataRemainderMatch.index){
-278                 data = new Buffer((str+this._remainder).substr(0, dataRemainderMatch.index), "binary");
-279                 if(this.options.debug){
-280                     console.log("DATA:", data.toString("utf-8"));
-281                 }
-282                 this.emit("data", data);
-283             }
-284             this._remainder = "";
-285             this.emit("ready");
-286             this._dataMode = false;
-287             
-288             // send the remaining data for processing
-289             this._processData(str.substr(dataRemainderMatch.index + dataRemainderMatch[0].length));
-290         }else{
-291             data = new Buffer(str, "binary");
-292             if(this.options.debug){
-293                 console.log("DATA:", data.toString("utf-8"));
-294             }
-295             this.emit("data", data);
-296         }
-297     }else{
-298         this._processData(str);
-299     }
-300     
-301 }
-302 
-303 /**
-304  * <p>Processed incoming command lines and emits found data as 
-305  * <code>'command'</code> with the command name as the first param and the rest
-306  * of the data as second (Buffer)</p>
-307  * 
-308  * @param {String} str Binary string to be processed
-309  */
-310 RAISocket.prototype._processData = function(str){
-311     if(!str.length){
-312         return;
-313     }
-314     var lines = (this._remainder+str).split("\r\n"),
-315         match, command;
-316         
-317     this._remainder = lines.pop();
-318     
-319     for(var i=0, len = lines.length; i<len; i++){
-320         if(!this._dataMode){
-321             if(match = lines[i].match(/\s*[\S]+\s?/)){
-322                 command = (match[0] || "").trim();
-323                 if(this.options.debug){
-324                     console.log("COMMAND:", lines[i]);
-325                 }
-326                 this.emit("command", command, new Buffer(lines[i].substr(match.index + match[0].length), "binary"));
-327             }
-328         }else{
-329             if(this._remainder){
-330                 this._remainder += "\r\n";
-331             }
-332             this._onReceiveData(lines.slice(i).join("\r\n"));
-333             break;
-334         }
-335     }
-336     
-337 }
-338 
-339 /**
-340  * <p>Called when the connection is or is going to be ended</p> 
-341  */
-342 RAISocket.prototype._destroy = function(){
-343     if(this._destroyed)return;
-344     this._destroyed = true;
-345     
-346     this.removeAllListeners();
-347 }
-348 
-349 /**
-350  * <p>Called when the connection is ended. Emits <code>'end'</code></p>
-351  */
-352 RAISocket.prototype._onEnd = function(){
-353     this.emit("end");
-354     this._destroy();
-355 }
-356 
-357 /**
-358  * <p>Called when an error has appeared. Emits <code>'error'</code> with
-359  * the error object as a parameter.</p>
-360  * 
-361  * @param {Object} err Error object
-362  */
-363 RAISocket.prototype._onError = function(err){
-364     this.emit("error", err);
-365     this._destroy();
-366 }
-367 
-368 /**
-369  * <p>Called when a timeout has occured. Connection will be closed and
-370  * <code>'timeout'</code> is emitted.</p>
-371  */
-372 RAISocket.prototype._onTimeout = function(){
-373     if(this.socket && !this.socket.destroyed){
-374         this.socket.end();
-375     }
-376     this.emit("timeout");
-377     this._destroy();
-378 }
-379 
-380 /**
-381  * <p>Called when the connection is closed</p>
-382  * 
-383  * @param {Boolean} hadError did the connection end because of an error?
-384  */
-385 RAISocket.prototype._onClose = function(hadError){
-386     this._destroy();
-387 }
\ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html deleted file mode 100644 index 2690ce4187d..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_mockup.js.html +++ /dev/null @@ -1,110 +0,0 @@ -
  1 var net = require("net"),
-  2     crypto = require("crypto"),
-  3     tlslib = require("tls");
-  4 
-  5 /**
-  6  * @namespace Mockup module
-  7  * @name mockup
-  8  */
-  9 module.exports = runClientMockup;
- 10 
- 11 /**
- 12  * <p>Runs a batch of commands against a server</p>
- 13  * 
- 14  * <pre>
- 15  * var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
- 16  * runClientMockup(25, "mail.hot.ee", cmds, function(resp){
- 17  *     console.log("Final:", resp.toString("utf-8").trim());
- 18  * });
- 19  * </pre>
- 20  * 
- 21  * @memberOf mockup
- 22  * @param {Number} port Port number
- 23  * @param {String} host Hostname to connect to
- 24  * @param {Array} commands Command list to be sent to server
- 25  * @param {Function} callback Callback function to run on completion,
- 26  *        has the last response from the server as a param
- 27  * @param {Boolean} [debug] if set to true log all input/output
- 28  */
- 29 function runClientMockup(port, host, commands, callback, debug){
- 30     host = host || "localhost";
- 31     port = port || 25;
- 32     commands = Array.isArray(commands) ? commands : [];
- 33 
- 34     var command, ignore_data = false, sslcontext, pair;
- 35 
- 36     var socket = net.connect(port, host, function(){
- 37         socket.on("data", function(chunk){
- 38             if(ignore_data)return;
- 39             
- 40             if(debug){
- 41                 console.log("S: "+chunk.toString("utf-8").trim());
- 42             }
- 43             
- 44             if(!commands.length){
- 45                 socket.end();
- 46                 if(typeof callback == "function"){
- 47                     callback(chunk);
- 48                 }
- 49                 return;
- 50             }
- 51             
- 52             if(["STARTTLS", "STLS"].indexOf((command || "").trim().toUpperCase())>=0){
- 53                 ignore_data = true;
- 54                 if(debug){
- 55                     console.log("Initiated TLS connection");
- 56                 }
- 57                 sslcontext = crypto.createCredentials();
- 58                 pair = tlslib.createSecurePair(sslcontext, false);
- 59                 
- 60                 pair.encrypted.pipe(socket);
- 61                 socket.pipe(pair.encrypted);
- 62                 pair.fd = socket.fd;
- 63                 
- 64                 pair.on("secure", function(){
- 65                     if(debug){
- 66                         console.log("TLS connection secured");
- 67                     }
- 68                     command = commands.shift();
- 69                     if(debug){
- 70                         console.log("C: "+command);
- 71                     }
- 72                     pair.cleartext.write(command+"\r\n");
- 73 
- 74                     pair.cleartext.on("data", function(chunk){
- 75                         if(debug){
- 76                             console.log("S: "+chunk.toString("utf-8").trim());
- 77                         }
- 78                         
- 79                         if(!commands.length){
- 80                             pair.cleartext.end();
- 81                             if(typeof callback == "function"){
- 82                                 callback(chunk);
- 83                             }
- 84                             return;
- 85                         }
- 86                         command = commands.shift();
- 87                         pair.cleartext.write(command+"\r\n");
- 88                         if(debug){
- 89                             console.log("C: "+command);
- 90                         }
- 91                     });
- 92                 });
- 93             }else{
- 94                 command = commands.shift();
- 95                 socket.write(command+"\r\n");
- 96                 if(debug){
- 97                     console.log("C: "+command);
- 98                 }
- 99             }
-100         });
-101     });
-102     
-103 }
\ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html deleted file mode 100644 index 4e12b247330..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_rai.js.html +++ /dev/null @@ -1,484 +0,0 @@ -
  1 /**
-  2  * @fileOverview This is the main file for the RAI library to create text based servers
-  3  * @author <a href="mailto:andris@node.ee">Andris Reinman</a>
-  4  * @version 0.1.3
-  5  */
-  6 
-  7 var netlib = require("net"),
-  8     utillib = require("util"),
-  9     EventEmitter = require('events').EventEmitter,
- 10     starttls = require("./starttls").starttls,
- 11     tlslib = require("tls"),
- 12     crypto = require("crypto"),
- 13     fs = require("fs");
- 14 
- 15 // Default credentials for starting TLS server
- 16 var defaultCredentials = {
- 17     key: fs.readFileSync(__dirname+"/../cert/key.pem"),
- 18     cert: fs.readFileSync(__dirname+"/../cert/cert.pem")
- 19 };
- 20 
- 21 // Expose to the world
- 22 module.exports.RAIServer = RAIServer;
- 23 module.exports.runClientMockup = require("./mockup");
- 24 
- 25 /**
- 26  * <p>Creates instance of RAIServer</p>
- 27  * 
- 28  * <p>Options object has the following properties:</p>
- 29  * 
- 30  * <ul>
- 31  *   <li><b>debug</b> - if set to true print traffic to console</li>
- 32  *   <li><b>disconnectOnTimeout</b> - if set to true close the connection on disconnect</li>
- 33  *   <li><b>timeout</b> - timeout in milliseconds for disconnecting the client,
- 34  *       defaults to 0 (no timeout)</li>
- 35  * </ul>
- 36  * 
- 37  * <p><b>Events</b></p>
- 38  * 
- 39  * <ul>
- 40  *     <li><b>'connect'</b> - emitted if a client connects to the server, param
- 41  *         is a client ({@link RAISocket}) object</li>
- 42  *     <li><b>'error'</b> - emitted on error, has an error object as a param</li>
- 43  * </ul> 
- 44  * 
- 45  * @constructor
- 46  * @param {Object} [options] Optional options object
- 47  */
- 48 function RAIServer(options){
- 49     EventEmitter.call(this);
- 50     
- 51     this.options = options || {};
- 52     
- 53     this._createServer();
- 54 }
- 55 utillib.inherits(RAIServer, EventEmitter);
- 56 
- 57 /**
- 58  * <p>Starts listening on selected port</p>
- 59  * 
- 60  * @param {Number} port The port to listen
- 61  * @param {String} [host] The IP address to listen
- 62  * @param {Function} callback The callback function to be run after the server
- 63  * is listening, the only param is an error message if the operation failed 
- 64  */
- 65 RAIServer.prototype.listen = function(port, host, callback){
- 66     if(!callback && typeof host=="function"){
- 67         callback = host;
- 68         host = undefined;
- 69     }
- 70     this._port = port;
- 71     this._host = host;
- 72     
- 73     this._connected = false;
- 74     
- 75     if(callback){
- 76         
- 77         this._server.on("listening", (function(){
- 78             this._connected = true;
- 79             callback(null);
- 80         }).bind(this));
- 81         
- 82         this._server.on("error", (function(err){
- 83             if(!this._connected){
- 84                 callback(err);
- 85             }
- 86         }).bind(this));
- 87         
- 88     }
- 89     
- 90     this._server.listen(this._port, this._host);
- 91 };
- 92 
- 93 /**
- 94  * <p>Stops the server</p>
- 95  * 
- 96  * @param {Function} callback Is run when the server is closed 
- 97  */
- 98 RAIServer.prototype.end = function(callback){
- 99     this._server.on("close", callback);
-100     this._server.close();
-101 };
-102 
-103 /**
-104  * <p>Creates a server with listener callback</p> 
-105  */
-106 RAIServer.prototype._createServer = function(){
-107     this._server = netlib.createServer(this._serverListener.bind(this));
-108     this._server.on("error", this._onError.bind(this));
-109 };
-110 
-111 /**
-112  * <p>Listens for errors</p>
-113  * 
-114  * @event
-115  * @param {Object} err Error object
-116  */
-117 RAIServer.prototype._onError = function(err){
-118     if(this._connected){
-119         this.emit("error", err);
-120     }
-121 };
-122 
-123 /**
-124  * <p>Server listener that is run on client connection</p>
-125  * 
-126  * <p>{@link RAISocket} object instance is created based on the client socket
-127  *    and a <code>'connection'</code> event is emitted</p>
-128  * 
-129  * @param {Object} socket The socket to the client 
-130  */
-131 RAIServer.prototype._serverListener = function(socket){
-132     if(this.options.debug){
-133         console.log("CONNECTION FROM "+socket.remoteAddress);
-134     }
-135     
-136     var handler = new RAISocket(socket, this.options);
-137     
-138     socket.on("data", handler._onReceiveData.bind(handler));
-139     socket.on("end", handler._onEnd.bind(handler));
-140     socket.on("error", handler._onError.bind(handler));
-141     socket.on("timeout", handler._onTimeout.bind(handler));
-142     socket.on("close", handler._onClose.bind(handler));
-143 
-144     this.emit("connection", handler);
-145 };
-146 
-147 /**
-148  * <p>Creates a instance for interacting with a client (socket)</p>
-149  * 
-150  * <p>Optional options object is the same that is passed to the parent
-151  * {@link RAIServer} object</p>
-152  * 
-153  * <p><b>Events</b></p>
-154  * 
-155  * <ul>
-156  *     <li><b>'command'</b> - emitted if a client sends a command. Gets two
-157  *         params - command (String) and payload (Buffer)</li>
-158  *     <li><b>'data'</b> - emitted when a chunk is received in data mode, the
-159  *         param being the payload (Buffer)</li>
-160  *     <li><b>'ready'</b> - emitted when data stream ends and normal command
-161  *         flow is recovered</li>
-162  *     <li><b>'tls'</b> - emitted when the connection is secured by TLS</li>
-163  *     <li><b>'error'</b> - emitted when an error occurs. Connection to the
-164  *         client is disconnected automatically. Param is an error object.</l>
-165  *     <li><b>'timeout'</b> - emitted when a timeout occurs. Connection to the
-166  *         client is disconnected automatically if disconnectOnTimeout option 
-167  *         is set to true.</l>
-168  *     <li><b>'end'</b> - emitted when the client disconnects</l>
-169  * </ul>
-170  * 
-171  * @constructor
-172  * @param {Object} socket Socket for the client
-173  * @param {Object} [options] Optional options object
-174  */
-175 function RAISocket(socket, options){
-176     EventEmitter.call(this);
-177     
-178     this.socket = socket;
-179     this.options = options || {};
-180     
-181     this.remoteAddress = socket.remoteAddress;
-182     
-183     this._dataMode = false;
-184     this._endDataModeSequence = "\r\n.\r\n";
-185     this._endDataModeSequenceRegEx = /\r\n\.\r\n|^\.\r\n/;
-186     
-187     this.secureConnection = false;
-188     this._destroyed = false;
-189     this._remainder = "";
-190     
-191     this._ignore_data = false;
-192     
-193     if(this.options.timeout){
-194         socket.setTimeout(this.options.timeout);
-195     }
-196 }
-197 utillib.inherits(RAISocket, EventEmitter);
-198 
-199 /**
-200  * <p>Sends some data to the client. <code><CR><LF></code> is automatically appended to
-201  *    the data</p>
-202  * 
-203  * @param {String|Buffer} data Data to be sent to the client
-204  */
-205 RAISocket.prototype.send = function(data){
-206     var buffer;
-207     if(data instanceof Buffer || (typeof SlowBuffer != "undefined" && data instanceof SlowBuffer)){
-208         buffer = new Buffer(data.length+2);
-209         buffer[buffer.length-2] = 0xD;
-210         buffer[buffer.length-1] = 0xA;
-211         data.copy(buffer);
-212     }else{
-213         buffer = new Buffer((data || "").toString()+"\r\n", "binary");
-214     }
-215     
-216     if(this.options.debug){
-217         console.log("OUT: \"" +buffer.toString("utf-8").trim()+"\"");
-218     }
-219     
-220     if(this.socket && this.socket.writable){
-221         this.socket.write(buffer);
-222     }else{
-223         this.socket.end();
-224     }
-225 };
-226 
-227 /**
-228  * <p>Instructs the server to be listening for mixed data instead of line based
-229  *    commands</p>
-230  * 
-231  * @param {String} [sequence="."] - optional sequence on separate line for
-232  *        matching the data end
-233  */
-234 RAISocket.prototype.startDataMode = function(sequence){
-235     this._dataMode = true;
-236     if(sequence){
-237         sequence = sequence.replace(/\.\=\(\)\-\?\*\\\[\]\^\+\:\|\,/g, "\\$1");
-238         this._endDataModeSequence = "\r\n"+sequence+"\r\n";
-239         this._endDataModeSequenceRegEx = new RegExp("/\r\n"+sequence+"\r\n|^"+sequence+"\r\n/");
-240     }
-241 };
-242 
-243 /**
-244  * <p>Instructs the server to upgrade the connection to secure TLS connection</p>
-245  * 
-246  * <p>Fires <code>callback</code> on successful connection upgrade if set, 
-247  * otherwise emits <code>'tls'</code></p>
-248  * 
-249  * @param {Object} [credentials] An object with PEM encoded key and 
-250  *        certificate <code>{key:"---BEGIN...", cert:"---BEGIN..."}</code>,
-251  *        if not set autogenerated values will be used.
-252  * @param {Function} [callback] If calback is set fire it after successful connection
-253  *        upgrade, otherwise <code>'tls'</code> is emitted
-254  */
-255 RAISocket.prototype.startTLS = function(credentials, callback){
-256     if(this.secureConnection){
-257         this._onError(new Error("Secure connection already established"));
-258     }
-259     
-260     if(!callback && typeof credentials == "function"){
-261         callback = credentials;
-262         credentials = undefined;
-263     }
-264     
-265     credentials = credentials || defaultCredentials;
-266     
-267     this._ignore_data = true;
-268     
-269     var secure_connector = starttls(this.socket, credentials, (function(ssl_socket){
-270 
-271         if(this.options.debug && !ssl_socket.authorized){
-272             console.log("WARNING: TLS ERROR ("+ssl_socket.authorizationError+")");
-273         }
-274         
-275         this._remainder = "";
-276         this._ignore_data = false;
-277         
-278         this.secureConnection = true;
-279     
-280         this.socket = ssl_socket;
-281         this.socket.on("data", this._onReceiveData.bind(this));
-282         
-283         if(this.options.debug){
-284             console.log("TLS CONNECTION STARTED");
-285         }
-286         
-287         if(callback){
-288             callback();
-289         }else{
-290             this.emit("tls");
-291         }
-292         
-293     }).bind(this));
-294     
-295     secure_connector.on("error", (function(err){
-296         this._onError(err);
-297     }).bind(this));
-298 };
-299 
-300 /**
-301  * <p>Closes the connection to the client</p>
-302  */
-303 RAISocket.prototype.end = function(){
-304     this.socket.end();
-305 };
-306 
-307 /**
-308  * <p>Called when a chunk of data arrives from the client. If currently in data
-309  * mode, transmit the data otherwise send it to <code>_processData</code></p>
-310  * 
-311  * @event
-312  * @param {Buffer|String} chunk Data sent by the client
-313  */
-314 RAISocket.prototype._onReceiveData = function(chunk){
-315 
-316     if(this._ignore_data){ // if currently setting up TLS connection
-317         return;
-318     }
-319     
-320     var str = typeof chunk=="string"?chunk:chunk.toString("binary"),
-321         dataEndMatch, dataRemainderMatch, data, match;
-322     
-323     if(this._dataMode){
-324         
-325         str = this._remainder + str;
-326         if((dataEndMatch = str.match(/\r\n.*?$/))){
-327             // if theres a line that is not ended, keep it for later
-328             this._remainder = str.substr(dataEndMatch.index);
-329             str = str.substr(0, dataEndMatch.index);
-330         }else{
-331             this._remainder = "";
-332         }
-333 
-334         // check if a data end sequence is found from the data
-335         if((dataRemainderMatch = (str+this._remainder).match(this._endDataModeSequenceRegEx))){
-336             str = str + this._remainder;
-337             // if the sequence is not on byte 0 emit remaining data
-338             if(dataRemainderMatch.index){
-339                 data = new Buffer(str.substr(0, dataRemainderMatch.index), "binary");
-340                 if(this.options.debug){
-341                     console.log("DATA:", data.toString("utf-8"));
-342                 }
-343                 this.emit("data", data);
-344             }
-345             // emit data ready
-346             this._remainder = "";
-347             this.emit("ready");
-348             this._dataMode = false;
-349             // send the remaining data for processing
-350             this._processData(str.substr(dataRemainderMatch.index + dataRemainderMatch[0].length)+"\r\n");
-351         }else{
-352             // check if there's not something in the end of the data that resembles
-353             // end sequence - if so, cut it off and save it to the remainder
-354             str = str + this._remainder;
-355             this._remainder=  "";
-356             for(var i = Math.min(this._endDataModeSequence.length-1, str.length); i>0; i--){
-357                 match = this._endDataModeSequence.substr(0, i);
-358                 if(str.substr(-match.length) == match){
-359                     this._remainder = str.substr(-match.length);
-360                     str = str.substr(0, str.length - match.length);
-361                 }
-362             }
-363 
-364             // if there's some data leht, emit it
-365             if(str.length){
-366                 data = new Buffer(str, "binary");
-367                 if(this.options.debug){
-368                     console.log("DATA:", data.toString("utf-8"));
-369                 }
-370                 this.emit("data", data);
-371             }
-372         }
-373     }else{
-374         // Not in data mode, process as command
-375         this._processData(str);
-376     }
-377 };
-378 
-379 /**
-380  * <p>Processed incoming command lines and emits found data as 
-381  * <code>'command'</code> with the command name as the first param and the rest
-382  * of the data as second (Buffer)</p>
-383  * 
-384  * @param {String} str Binary string to be processed
-385  */
-386 RAISocket.prototype._processData = function(str){
-387     if(!str.length){
-388         return;
-389     }
-390     var lines = (this._remainder+str).split("\r\n"),
-391         match, command;
-392         
-393     this._remainder = lines.pop();
-394     
-395     for(var i=0, len = lines.length; i<len; i++){
-396         if(this._ignore_data){
-397             // If TLS upgrade is initiated do not process current buffer
-398             this._remainder = "";
-399             break;
-400         }
-401         if(!this._dataMode){
-402             if((match = lines[i].match(/\s*[\S]+\s?/))){
-403                 command = (match[0] || "").trim();
-404                 if(this.options.debug){
-405                     console.log("COMMAND:", lines[i]);
-406                 }
-407                 this.emit("command", command, new Buffer(lines[i].substr(match.index + match[0].length), "binary"));
-408             }
-409         }else{
-410             if(this._remainder){
-411                 this._remainder += "\r\n";
-412             }
-413             this._onReceiveData(lines.slice(i).join("\r\n"));
-414             break;
-415         }
-416     }  
-417 };
-418 
-419 /**
-420  * <p>Called when the connection is or is going to be ended</p> 
-421  */
-422 RAISocket.prototype._destroy = function(){
-423     if(this._destroyed)return;
-424     this._destroyed = true;
-425     
-426     this.removeAllListeners();
-427 };
-428 
-429 /**
-430  * <p>Called when the connection is ended. Emits <code>'end'</code></p>
-431  * 
-432  * @event
-433  */
-434 RAISocket.prototype._onEnd = function(){
-435     this.emit("end");
-436     this._destroy();
-437 };
-438 
-439 /**
-440  * <p>Called when an error has appeared. Emits <code>'error'</code> with
-441  * the error object as a parameter.</p>
-442  * 
-443  * @event
-444  * @param {Object} err Error object
-445  */
-446 RAISocket.prototype._onError = function(err){
-447     this.emit("error", err);
-448     this._destroy();
-449 };
-450 
-451 /**
-452  * <p>Called when a timeout has occured. Connection will be closed and
-453  * <code>'timeout'</code> is emitted.</p>
-454  * 
-455  * @event
-456  */
-457 RAISocket.prototype._onTimeout = function(){
-458     if(this.options.disconnectOnTimeout){
-459         if(this.socket && !this.socket.destroyed){
-460             this.socket.end();
-461         }
-462         this.emit("timeout");
-463         this._destroy();
-464     }else{
-465         this.emit("timeout");
-466     }
-467 };
-468 
-469 /**
-470  * <p>Called when the connection is closed</p>
-471  * 
-472  * @event
-473  * @param {Boolean} hadError did the connection end because of an error?
-474  */
-475 RAISocket.prototype._onClose = function(hadError){
-476     this._destroy();
-477 };
\ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html deleted file mode 100644 index dd1b2ea1afa..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/src/RAI_lib_starttls.js.html +++ /dev/null @@ -1,120 +0,0 @@ -
  1 // SOURCE: https://gist.github.com/848444
-  2 
-  3 // Target API:
-  4 //
-  5 //  var s = require('net').createStream(25, 'smtp.example.com');
-  6 //  s.on('connect', function() {
-  7 //   require('starttls')(s, options, function() {
-  8 //      if (!s.authorized) {
-  9 //        s.destroy();
- 10 //        return;
- 11 //      }
- 12 //
- 13 //      s.end("hello world\n");
- 14 //    });
- 15 //  });
- 16 //
- 17 //
- 18 
- 19 /**
- 20  * @namespace STARTTLS module
- 21  * @name starttls
- 22  */
- 23 module.exports.starttls = starttls;
- 24 
- 25 /**
- 26  * <p>Upgrades a socket to a secure TLS connection</p>
- 27  * 
- 28  * @memberOf starttls
- 29  * @param {Object} socket Plaintext socket to be upgraded
- 30  * @param {Object} options Certificate data for the server
- 31  * @param {Function} callback Callback function to be run after upgrade
- 32  */
- 33 function starttls(socket, options, callback) {
- 34     var sslcontext, pair, cleartext;
- 35     
- 36     socket.removeAllListeners("data");
- 37     sslcontext = require('crypto').createCredentials(options);
- 38     pair = require('tls').createSecurePair(sslcontext, true);
- 39     cleartext = pipe(pair, socket);
- 40 
- 41     pair.on('secure', function() {
- 42         var verifyError = (pair._ssl || pair.ssl).verifyError();
- 43 
- 44         if (verifyError) {
- 45             cleartext.authorized = false;
- 46             cleartext.authorizationError = verifyError;
- 47         } else {
- 48             cleartext.authorized = true;
- 49         }
- 50 
- 51         callback(cleartext);
- 52     });
- 53 
- 54     cleartext._controlReleased = true;
- 55     return pair;
- 56 }
- 57 
- 58 function forwardEvents(events, emitterSource, emitterDestination) {
- 59     var map = [], name, handler;
- 60     
- 61     for(var i = 0, len = events.length; i < len; i++) {
- 62         name = events[i];
- 63 
- 64         handler = forwardEvent.bind(emitterDestination, name);
- 65         
- 66         map.push(name);
- 67         emitterSource.on(name, handler);
- 68     }
- 69     
- 70     return map;
- 71 }
- 72 
- 73 function forwardEvent() {
- 74     this.emit.apply(this, arguments);
- 75 }
- 76 
- 77 function removeEvents(map, emitterSource) {
- 78     for(var i = 0, len = map.length; i < len; i++){
- 79         emitterSource.removeAllListeners(map[i]);
- 80     }
- 81 }
- 82 
- 83 function pipe(pair, socket) {
- 84     pair.encrypted.pipe(socket);
- 85     socket.pipe(pair.encrypted);
- 86 
- 87     pair.fd = socket.fd;
- 88     
- 89     var cleartext = pair.cleartext;
- 90   
- 91     cleartext.socket = socket;
- 92     cleartext.encrypted = pair.encrypted;
- 93     cleartext.authorized = false;
- 94 
- 95     function onerror(e) {
- 96         if (cleartext._controlReleased) {
- 97             cleartext.emit('error', e);
- 98         }
- 99     }
-100 
-101     var map = forwardEvents(["timeout", "end", "close", "drain", "error"], socket, cleartext);
-102   
-103     function onclose() {
-104         socket.removeListener('error', onerror);
-105         socket.removeListener('close', onclose);
-106         removeEvents(map,socket);
-107     }
-108 
-109     socket.on('error', onerror);
-110     socket.on('close', onclose);
-111 
-112     return cleartext;
-113 }
\ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html deleted file mode 100644 index e16b9151033..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/jsdoc/symbols/starttls.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - starttls | JsDoc Reference - - - - - - - - - - - - - - - -
- -
-
- - Documentation generator: JsDoc Toolkit 2.4.0
- Template: Codeview 1.2
- Generated on: - -
-
-
- -
- -
-
-
-
-

- - Namespace starttls -

- -
-

- STARTTLS module -

- - - - -
-
- - - - - - -
- - -
-

Method Summary

- - - - - - -
-
- - - - - - - - - - -
-
-
-

- Method Detail -

- -
    - - -
  • -
    - - <static> - - - - - starttls.starttls(socket, options, callback) -
    - -
    -

    Upgrades a socket to a secure TLS connection

    - - - - -
    - - - - -
    -
    Parameters:
    - -
    - {Object} socket - -
    -
    Plaintext socket to be upgraded
    - -
    - {Object} options - -
    -
    Certificate data for the server
    - -
    - {Function} callback - -
    -
    Callback function to be run after upgrade
    - -
    - - - - -
  • - -
-
-
-
- - - - -
-
-
- - - - - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js deleted file mode 100644 index 47bbc4ae13e..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js +++ /dev/null @@ -1,113 +0,0 @@ -var net = require("net"), - crypto = require("crypto"), - tlslib = require("tls"); - -// monkey patch net and tls to support nodejs 0.4 -if(!net.connect && net.createConnection){ - net.connect = net.createConnection; -} - -if(!tlslib.connect && tlslib.createConnection){ - tlslib.connect = tlslib.createConnection; -} - -/** - * @namespace Mockup module - * @name mockup - */ -module.exports = runClientMockup; - -/** - *

Runs a batch of commands against a server

- * - *
- * var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
- * runClientMockup(25, "mail.hot.ee", cmds, function(resp){
- *     console.log("Final:", resp.toString("utf-8").trim());
- * });
- * 
- * - * @memberOf mockup - * @param {Number} port Port number - * @param {String} host Hostname to connect to - * @param {Array} commands Command list to be sent to server - * @param {Function} callback Callback function to run on completion, - * has the last response from the server as a param - * @param {Boolean} [debug] if set to true log all input/output - */ -function runClientMockup(port, host, commands, callback, debug){ - host = host || "localhost"; - port = port || 25; - commands = Array.isArray(commands) ? commands : []; - - var command, ignore_data = false, sslcontext, pair; - - var socket = net.connect(port, host); - socket.on("connect", function(){ - socket.on("data", function(chunk){ - if(ignore_data)return; - - if(debug){ - console.log("S: "+chunk.toString("utf-8").trim()); - } - - if(!commands.length){ - socket.end(); - if(typeof callback == "function"){ - callback(chunk); - } - return; - } - - if(["STARTTLS", "STLS"].indexOf((command || "").trim().toUpperCase())>=0){ - ignore_data = true; - if(debug){ - console.log("Initiated TLS connection"); - } - sslcontext = crypto.createCredentials(); - pair = tlslib.createSecurePair(sslcontext, false); - - pair.encrypted.pipe(socket); - socket.pipe(pair.encrypted); - pair.fd = socket.fd; - - pair.on("secure", function(){ - if(debug){ - console.log("TLS connection secured"); - } - command = commands.shift(); - if(debug){ - console.log("C: "+command); - } - pair.cleartext.write(command+"\r\n"); - - pair.cleartext.on("data", function(chunk){ - if(debug){ - console.log("S: "+chunk.toString("utf-8").trim()); - } - - if(!commands.length){ - pair.cleartext.end(); - if(typeof callback == "function"){ - callback(chunk); - } - return; - } - command = commands.shift(); - pair.cleartext.write(command+"\r\n"); - if(debug){ - console.log("C: "+command); - } - }); - }); - }else{ - command = commands.shift(); - socket.write(command+"\r\n"); - if(debug){ - console.log("C: "+command); - } - } - }); - }); - -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js deleted file mode 100644 index d4720639d35..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js +++ /dev/null @@ -1,489 +0,0 @@ -/** - * @fileOverview This is the main file for the RAI library to create text based servers - * @author Andris Reinman - * @version 0.1.3 - */ - -var netlib = require("net"), - utillib = require("util"), - EventEmitter = require('events').EventEmitter, - starttls = require("./starttls").starttls, - tlslib = require("tls"), - crypto = require("crypto"), - fs = require("fs"); - -// Default credentials for starting TLS server -var defaultCredentials = { - key: fs.readFileSync(__dirname+"/../cert/key.pem"), - cert: fs.readFileSync(__dirname+"/../cert/cert.pem") -}; - -// Expose to the world -module.exports.RAIServer = RAIServer; -module.exports.runClientMockup = require("./mockup"); - -/** - *

Creates instance of RAIServer

- * - *

Options object has the following properties:

- * - *
    - *
  • debug - if set to true print traffic to console
  • - *
  • disconnectOnTimeout - if set to true close the connection on disconnect
  • - *
  • secureConnection - if set to true close the connection on disconnect
  • - *
  • credentials - credentials for secureConnection and STARTTLS
  • - *
  • timeout - timeout in milliseconds for disconnecting the client, - * defaults to 0 (no timeout)
  • - *
- * - *

Events

- * - *
    - *
  • 'connect' - emitted if a client connects to the server, param - * is a client ({@link RAISocket}) object
  • - *
  • 'error' - emitted on error, has an error object as a param
  • - *
- * - * @constructor - * @param {Object} [options] Optional options object - */ -function RAIServer(options){ - EventEmitter.call(this); - - this.options = options || {}; - - this._createServer(); -} -utillib.inherits(RAIServer, EventEmitter); - -/** - *

Starts listening on selected port

- * - * @param {Number} port The port to listen - * @param {String} [host] The IP address to listen - * @param {Function} callback The callback function to be run after the server - * is listening, the only param is an error message if the operation failed - */ -RAIServer.prototype.listen = function(port, host, callback){ - if(!callback && typeof host=="function"){ - callback = host; - host = undefined; - } - this._port = port; - this._host = host; - - this._connected = false; - if(callback){ - this._server.on("listening", (function(){ - this._connected = true; - callback(null); - }).bind(this)); - - this._server.on("error", (function(err){ - if(!this._connected){ - callback(err); - } - }).bind(this)); - } - - this._server.listen(this._port, this._host); -}; - -/** - *

Stops the server

- * - * @param {Function} callback Is run when the server is closed - */ -RAIServer.prototype.end = function(callback){ - this._server.on("close", callback); - this._server.close(); -}; - -/** - *

Creates a server with listener callback

- */ -RAIServer.prototype._createServer = function(){ - if(this.options.secureConnection){ - this._server = tlslib.createServer( - this.options.credentials || defaultCredentials, - this._serverListener.bind(this)); - }else{ - this._server = netlib.createServer(this._serverListener.bind(this)); - } - this._server.on("error", this._onError.bind(this)); -}; - -/** - *

Listens for errors

- * - * @event - * @param {Object} err Error object - */ -RAIServer.prototype._onError = function(err){ - if(this._connected){ - this.emit("error", err); - } -}; - -/** - *

Server listener that is run on client connection

- * - *

{@link RAISocket} object instance is created based on the client socket - * and a 'connection' event is emitted

- * - * @param {Object} socket The socket to the client - */ -RAIServer.prototype._serverListener = function(socket){ - if(this.options.debug){ - console.log("CONNECTION FROM "+socket.remoteAddress); - } - - var handler = new RAISocket(socket, this.options); - - socket.on("data", handler._onReceiveData.bind(handler)); - socket.on("end", handler._onEnd.bind(handler)); - socket.on("error", handler._onError.bind(handler)); - socket.on("timeout", handler._onTimeout.bind(handler)); - socket.on("close", handler._onClose.bind(handler)); - - if("setKeepAlive" in socket){ - socket.setKeepAlive(true); // plaintext server - }else if(socket.encrypted && "setKeepAlive" in socket.encrypted){ - socket.encrypted.setKeepAlive(true); // secure server - } - - this.emit("connect", handler); -}; - -/** - *

Creates a instance for interacting with a client (socket)

- * - *

Optional options object is the same that is passed to the parent - * {@link RAIServer} object

- * - *

Events

- * - *
    - *
  • 'command' - emitted if a client sends a command. Gets two - * params - command (String) and payload (Buffer)
  • - *
  • 'data' - emitted when a chunk is received in data mode, the - * param being the payload (Buffer)
  • - *
  • 'ready' - emitted when data stream ends and normal command - * flow is recovered
  • - *
  • 'tls' - emitted when the connection is secured by TLS
  • - *
  • 'error' - emitted when an error occurs. Connection to the - * client is disconnected automatically. Param is an error object. - *
  • 'timeout' - emitted when a timeout occurs. Connection to the - * client is disconnected automatically if disconnectOnTimeout option - * is set to true. - *
  • 'end' - emitted when the client disconnects - *
- * - * @constructor - * @param {Object} socket Socket for the client - * @param {Object} [options] Optional options object - */ -function RAISocket(socket, options){ - EventEmitter.call(this); - - this.socket = socket; - this.options = options || {}; - - this.remoteAddress = socket.remoteAddress; - - this._dataMode = false; - this._endDataModeSequence = "\r\n.\r\n"; - this._endDataModeSequenceRegEx = /\r\n\.\r\n|^\.\r\n/; - - this.secureConnection = !!this.options.secureConnection; - this._destroyed = false; - this._remainder = ""; - - this._ignore_data = false; - - if(this.options.timeout){ - socket.setTimeout(this.options.timeout); - } -} -utillib.inherits(RAISocket, EventEmitter); - -/** - *

Sends some data to the client. <CR><LF> is automatically appended to - * the data

- * - * @param {String|Buffer} data Data to be sent to the client - */ -RAISocket.prototype.send = function(data){ - var buffer; - if(data instanceof Buffer || (typeof SlowBuffer != "undefined" && data instanceof SlowBuffer)){ - buffer = new Buffer(data.length+2); - buffer[buffer.length-2] = 0xD; - buffer[buffer.length-1] = 0xA; - data.copy(buffer); - }else{ - buffer = new Buffer((data || "").toString()+"\r\n", "binary"); - } - - if(this.options.debug){ - console.log("OUT: \"" +buffer.toString("utf-8").trim()+"\""); - } - - if(this.socket && this.socket.writable){ - this.socket.write(buffer); - }else{ - this.socket.end(); - } -}; - -/** - *

Instructs the server to be listening for mixed data instead of line based - * commands

- * - * @param {String} [sequence="."] - optional sequence on separate line for - * matching the data end - */ -RAISocket.prototype.startDataMode = function(sequence){ - this._dataMode = true; - if(sequence){ - sequence = sequence.replace(/\.\=\(\)\-\?\*\\\[\]\^\+\:\|\,/g, "\\$1"); - this._endDataModeSequence = "\r\n"+sequence+"\r\n"; - this._endDataModeSequenceRegEx = new RegExp("/\r\n"+sequence+"\r\n|^"+sequence+"\r\n/"); - } -}; - -/** - *

Instructs the server to upgrade the connection to secure TLS connection

- * - *

Fires callback on successful connection upgrade if set, - * otherwise emits 'tls'

- * - * @param {Object} [credentials] An object with PEM encoded key and - * certificate {key:"---BEGIN...", cert:"---BEGIN..."}, - * if not set autogenerated values will be used. - * @param {Function} [callback] If calback is set fire it after successful connection - * upgrade, otherwise 'tls' is emitted - */ -RAISocket.prototype.startTLS = function(credentials, callback){ - - if(this.secureConnection){ - return this._onError(new Error("Secure connection already established")); - } - - if(!callback && typeof credentials == "function"){ - callback = credentials; - credentials = undefined; - } - - credentials = credentials || this.options.credentials || defaultCredentials; - - this._ignore_data = true; - - var secure_connector = starttls(this.socket, credentials, (function(ssl_socket){ - - if(this.options.debug && !ssl_socket.authorized){ - console.log("WARNING: TLS ERROR ("+ssl_socket.authorizationError+")"); - } - - this._remainder = ""; - this._ignore_data = false; - - this.secureConnection = true; - - this.socket = ssl_socket; - this.socket.on("data", this._onReceiveData.bind(this)); - - if(this.options.debug){ - console.log("TLS CONNECTION STARTED"); - } - - if(callback){ - callback(); - }else{ - this.emit("tls"); - } - - }).bind(this)); - - secure_connector.on("error", (function(err){ - this._onError(err); - }).bind(this)); -}; - -/** - *

Closes the connection to the client

- */ -RAISocket.prototype.end = function(){ - this.socket.end(); -}; - -/** - *

Called when a chunk of data arrives from the client. If currently in data - * mode, transmit the data otherwise send it to _processData

- * - * @event - * @param {Buffer|String} chunk Data sent by the client - */ -RAISocket.prototype._onReceiveData = function(chunk){ - - if(this._ignore_data){ // if currently setting up TLS connection - return; - } - - var str = typeof chunk=="string"?chunk:chunk.toString("binary"), - dataEndMatch, dataRemainderMatch, data, match; - - if(this._dataMode){ - - str = this._remainder + str; - if((dataEndMatch = str.match(/\r\n.*?$/))){ - // if ther's a line that is not ended, keep it for later - this._remainder = str.substr(dataEndMatch.index); - str = str.substr(0, dataEndMatch.index); - }else{ - this._remainder = ""; - } - - // check if a data end sequence is found from the data - if((dataRemainderMatch = (str+this._remainder).match(this._endDataModeSequenceRegEx))){ - str = str + this._remainder; - // if the sequence is not on byte 0 emit remaining data - if(dataRemainderMatch.index){ - data = new Buffer(str.substr(0, dataRemainderMatch.index), "binary"); - if(this.options.debug){ - console.log("DATA:", data.toString("utf-8")); - } - this.emit("data", data); - } - // emit data ready - this._remainder = ""; - this.emit("ready"); - this._dataMode = false; - // send the remaining data for processing - this._processData(str.substr(dataRemainderMatch.index + dataRemainderMatch[0].length)+"\r\n"); - }else{ - // check if there's not something in the end of the data that resembles - // end sequence - if so, cut it off and save it to the remainder - str = str + this._remainder; - this._remainder= ""; - for(var i = Math.min(this._endDataModeSequence.length-1, str.length); i>0; i--){ - match = this._endDataModeSequence.substr(0, i); - if(str.substr(-match.length) == match){ - this._remainder = str.substr(-match.length); - str = str.substr(0, str.length - match.length); - } - } - - // if there's some data leht, emit it - if(str.length){ - data = new Buffer(str, "binary"); - if(this.options.debug){ - console.log("DATA:", data.toString("utf-8")); - } - this.emit("data", data); - } - } - }else{ - // Not in data mode, process as command - this._processData(str); - } -}; - -/** - *

Processed incoming command lines and emits found data as - * 'command' with the command name as the first param and the rest - * of the data as second (Buffer)

- * - * @param {String} str Binary string to be processed - */ -RAISocket.prototype._processData = function(str){ - if(!str.length){ - return; - } - var lines = (this._remainder+str).split("\r\n"), - match, command; - - this._remainder = lines.pop(); - - for(var i=0, len = lines.length; iCalled when the connection is or is going to be ended

- */ -RAISocket.prototype._destroy = function(){ - if(this._destroyed)return; - this._destroyed = true; - - this.removeAllListeners(); -}; - -/** - *

Called when the connection is ended. Emits 'end'

- * - * @event - */ -RAISocket.prototype._onEnd = function(){ - this.emit("end"); - this._destroy(); -}; - -/** - *

Called when an error has appeared. Emits 'error' with - * the error object as a parameter.

- * - * @event - * @param {Object} err Error object - */ -RAISocket.prototype._onError = function(err){ - this.emit("error", err); - this._destroy(); -}; - -/** - *

Called when a timeout has occured. Connection will be closed and - * 'timeout' is emitted.

- * - * @event - */ -RAISocket.prototype._onTimeout = function(){ - if(this.options.disconnectOnTimeout){ - if(this.socket && !this.socket.destroyed){ - this.socket.end(); - } - this.emit("timeout"); - this._destroy(); - }else{ - this.emit("timeout"); - } -}; - -/** - *

Called when the connection is closed

- * - * @event - * @param {Boolean} hadError did the connection end because of an error? - */ -RAISocket.prototype._onClose = function(hadError){ - this._destroy(); -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js deleted file mode 100644 index b17dc65e841..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js +++ /dev/null @@ -1,113 +0,0 @@ -// SOURCE: https://gist.github.com/848444 - -// Target API: -// -// var s = require('net').createStream(25, 'smtp.example.com'); -// s.on('connect', function() { -// require('starttls')(s, options, function() { -// if (!s.authorized) { -// s.destroy(); -// return; -// } -// -// s.end("hello world\n"); -// }); -// }); -// -// - -/** - * @namespace STARTTLS module - * @name starttls - */ -module.exports.starttls = starttls; - -/** - *

Upgrades a socket to a secure TLS connection

- * - * @memberOf starttls - * @param {Object} socket Plaintext socket to be upgraded - * @param {Object} options Certificate data for the server - * @param {Function} callback Callback function to be run after upgrade - */ -function starttls(socket, options, callback) { - var sslcontext, pair, cleartext; - - socket.removeAllListeners("data"); - sslcontext = require('crypto').createCredentials(options); - pair = require('tls').createSecurePair(sslcontext, true); - cleartext = pipe(pair, socket); - - pair.on('secure', function() { - var verifyError = (pair._ssl || pair.ssl).verifyError(); - - if (verifyError) { - cleartext.authorized = false; - cleartext.authorizationError = verifyError; - } else { - cleartext.authorized = true; - } - - callback(cleartext); - }); - - cleartext._controlReleased = true; - return pair; -} - -function forwardEvents(events, emitterSource, emitterDestination) { - var map = [], name, handler; - - for(var i = 0, len = events.length; i < len; i++) { - name = events[i]; - - handler = forwardEvent.bind(emitterDestination, name); - - map.push(name); - emitterSource.on(name, handler); - } - - return map; -} - -function forwardEvent() { - this.emit.apply(this, arguments); -} - -function removeEvents(map, emitterSource) { - for(var i = 0, len = map.length; i < len; i++){ - emitterSource.removeAllListeners(map[i]); - } -} - -function pipe(pair, socket) { - pair.encrypted.pipe(socket); - socket.pipe(pair.encrypted); - - pair.fd = socket.fd; - - var cleartext = pair.cleartext; - - cleartext.socket = socket; - cleartext.encrypted = pair.encrypted; - cleartext.authorized = false; - - function onerror(e) { - if (cleartext._controlReleased) { - cleartext.emit('error', e); - } - } - - var map = forwardEvents(["timeout", "end", "close", "drain", "error"], socket, cleartext); - - function onclose() { - socket.removeListener('error', onerror); - socket.removeListener('close', onclose); - removeEvents(map,socket); - } - - socket.on('error', onerror); - socket.on('close', onclose); - - return cleartext; -} \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json deleted file mode 100644 index 9993ca6e0a8..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "rai", - "description": "Request-Answer-Interface for generating text based command servers (SMTP, POP etc)", - "version": "0.1.7", - "author": { - "name": "Andris Reinman" - }, - "maintainers": [ - { - "name": "andris", - "email": "andris@node.ee" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/andris9/rai.git" - }, - "scripts": { - "test": "nodeunit test" - }, - "main": "./lib/rai", - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/andris9/rai/blob/master/LICENSE" - } - ], - "devDependencies": { - "nodeunit": "*" - }, - "engines": [ - "node >=0.4.0" - ], - "keywords": [ - "servers", - "text-based" - ], - "readme": "# RAI - Request-Answer-Interface\n\n**rai** is a node.js module to easily generate text based command line servers.\nWhen a client sends something to the server, the first word of the line is\ntreated as a command and the rest of the line as binary payload.\n\n[![Build Status](https://secure.travis-ci.org/andris9/rai.png)](http://travis-ci.org/andris9/rai)\n\nIn addition to line based commands, there's also a data mode, to transmit\neverygting received. And there's also an option to switch to TLS mode for\nsecure connections.\n\nThis way it is trivial to create SMTP, POP3 or similar servers.\n\n## Installation\n\n npm install rai\n \n## Usage\n\n### Simple server\n\n var RAIServer = require(\"rai\").RAIServer;\n \n // create a RAIServer on port 1234\n var server = new RAIServer();\n server.listen(1234);\n \n // Start listening for client connections\n server.on(\"connect\", function(client){\n \n // Greet the client\n client.send(\"Hello!\");\n \n // Wait for a command\n client.on(\"command\", function(command, payload){\n \n if(command == \"STATUS\"){\n client.send(\"Status is OK!\");\n }else if(command == \"QUIT\"){\n client.send(\"Goodbye\");\n client.end();\n }else{\n client.send(\"Unknown command\");\n }\n \n });\n \n });\n\nServer only emits `'connect'` and `'error'` events, while the client \nobjects emit `'timeout'`, `'error'` and `'end'` in addition to data \nrelated events.\n\n### Starting a server\n\nServer can be started with `new RAIServer([options])` where options is an optional\nparameters object with the following properties:\n\n * **debug** - if set to true print traffic to console\n * **disconnectOnTimeout** - if set to true close the connection on disconnect\n * **secureConnection** - if set to true close the connection on disconnect\n * **credentials** - credentials for secureConnection and STARTTLS\n * **timeout** - timeout in milliseconds for disconnecting the client, defaults to 0 (no timeout)\n \nOnce the server has been set up, it can start listening for client connections\nwith `server.listen(port[, hostname][, callback])`. Callback function gets an error\nobject as a parameter if the listening failed.\n\n var server = new RAIServer();\n server.listen(25); // start listening for port 25 on \"localhost\"\n\n### Closing server\n\nServer can be closed with `server.end([callback])` where callback is run when\nthe server is finally closed.\n\n### Sending data\n\nData can be sent with `client.send(data)` where `data` is either a String or\na Buffer. `\"\\r\\n\"` is automatically appended to the data.\n\n client.send(\"Greetings!\");\n\n### Forcing connection close\n\nConnections can be ended with `client.end()`\n\n if(command == \"QUIT\"){\n client.send(\"Good bye!\");\n client.end();\n }\n\n### TLS mode\n\nTLS can be switched on with `client.startTLS([credentials][, callback])` and the status can\nbe listened with `'tls'` (emitted when secure connection is established)\n\n`credentials` is an object with strings of pem encoded `key`, `cert` and optionally an\narray `ca`. If `credentials` is not supplied, an autogenerated value is used.\n\n if(command == \"STARTTLS\"){\n client.startTLS();\n }\n \n client.on(\"tls\", function(){\n console.log(\"Switched to secure connection\");\n });\n\nIf `callback` is not set `'tls'` will be emitted on connection upgrade.\n\n### Data mode\n\nData mode can be turned on with `client.startDataMode([endSequence])` and incoming\nchunks can be received with `'data'`. The end of data mode can be detected by\n`'ready'`.\n\n`endSequence` is a String for matching the end (entire line) of the data stream.\nBy default it's `\".\"` which is suitable for SMTP and POP3.\n\n if(command == \"DATA\"){\n client.send(\"End data with .\");\n client.startDataMode();\n }\n\n client.on(\"data\", function(chunk){\n console.log(\"Data from client:\", chunk);\n });\n \n client.on(\"ready\", function(){\n client.send(\"Data received\");\n });\n\n## Testing\n\nThere is a possibility to set up a mockup client which sends a batch of commands\none by one to the server and returns the last response.\n\n var runClientMockup = require(\"rai\").runClientMockup;\n \n var cmds = [\"EHLO FOOBAR\", \"STARTTLS\", \"QUIT\"];\n runClientMockup(25, \"mail.hot.ee\", cmds, function(resp){\n console.log(\"Final:\", resp.toString(\"utf-8\").trim());\n });\n\n`runClientMockup` has he following parameters in the following order:\n\n * **port** - Port number\n * **host** - Hostname to connect to\n * **commands** - Command list (an array) to be sent to server\n * **callback** - Callback function to run on completion\n * **debug** - if set to true log all input/output\n\nResponse from the callback function is a Buffer and contains the\nlast data received from the server\n\n## License\n\n**MIT**", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/rai/issues" - }, - "_id": "rai@0.1.7", - "_from": "rai@~0.1" -} diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js deleted file mode 100644 index 944668346b2..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/run_tests.js +++ /dev/null @@ -1,2 +0,0 @@ -var reporter = require('nodeunit').reporters["default"]; -reporter.run(['test']); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js deleted file mode 100644 index a1af00b62be..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/test/rai.js +++ /dev/null @@ -1,589 +0,0 @@ -var RAIServer = require("../lib/rai").RAIServer, - testCase = require('nodeunit').testCase, - utillib = require("util"), - netlib = require("net"), - crypto = require("crypto"), - tlslib = require("tls"); - -var PORT_NUMBER = 8397; - -// monkey patch net and tls to support nodejs 0.4 -if(!netlib.connect && netlib.createConnection){ - netlib.connect = netlib.createConnection; -} - -if(!tlslib.connect && tlslib.createConnection){ - tlslib.connect = tlslib.createConnection; -} - -exports["General tests"] = { - "Create and close a server": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - test.ifError(err); - server.end(function(){ - test.ok(1, "Server closed"); - test.done(); - }); - }); - }, - "Create a secure server": function(test){ - var server = new RAIServer({secureConnection: true}); - server.listen(PORT_NUMBER, function(err){ - test.ifError(err); - server.end(function(){ - test.ok(1, "Server closed"); - test.done(); - }); - }); - }, - "Duplicate server fails": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - test.ifError(err); - - var duplicate = new RAIServer(); - duplicate.listen(PORT_NUMBER, function(err){ - test.ok(err, "Responds with error"); - server.end(function(){ - test.ok(1, "Server closed"); - test.done(); - }); - }); - - }); - }, - "Connection event": function(test){ - var server = new RAIServer(); - test.expect(3); - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - test.ok(socket, "Client connected"); - - socket.on("end", function(){ - test.ok(1, "Connection closed"); - - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - test.ok(1, "Connected to server"); - client.end(); - }); - - }); - }, - "Close client socket": function(test){ - var server = new RAIServer(); - test.expect(4); - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - test.ok(socket, "Client connected"); - - socket.on("end", function(){ - test.ok(1, "Connection closed"); - - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - - socket.end(); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - test.ok(1, "Connected to server"); - }); - client.on("end", function(){ - test.ok(1, "Connection closed by host"); - }); - - }); - }, - "Send data to client": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - - socket.send("HELLO"); - - socket.on("end", function(){ - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - client.on("data", function(chunk){ - test.equal(chunk.toString(), "HELLO\r\n"); - client.end(); - }); - }); - - }); - } -}; - -exports["Secure connection"] = { - "STARTTLS with event": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - test.expect(2); - - server.on("connect", function(socket){ - - socket.startTLS(); - socket.on("tls", function(){ - test.ok(1, "Secure connection opened"); - socket.send("TEST"); - }); - - socket.on("end", function(){ - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - var sslcontext = crypto.createCredentials(); - var pair = tlslib.createSecurePair(sslcontext, false); - - pair.encrypted.pipe(client); - client.pipe(pair.encrypted); - pair.fd = client.fd; - - pair.on("secure", function(){ - pair.cleartext.on("data", function(chunk){ - test.equal(chunk.toString(), "TEST\r\n"); - pair.cleartext.end(); - }); - }); - }); - - }); - }, - "STARTTLS Callback": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - test.expect(2); - - server.on("connect", function(socket){ - - socket.startTLS(function(){ - test.ok(1, "Secure connection opened"); - socket.send("TEST"); - }); - - socket.on("tls", function(){ - test.ok(0, "Should not occur"); - }); - - socket.on("end", function(){ - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - var sslcontext = crypto.createCredentials(); - var pair = tlslib.createSecurePair(sslcontext, false); - - pair.encrypted.pipe(client); - client.pipe(pair.encrypted); - pair.fd = client.fd; - - pair.on("secure", function(){ - pair.cleartext.on("data", function(chunk){ - test.equal(chunk.toString(), "TEST\r\n"); - pair.cleartext.end(); - }); - }); - }); - - }); - }, - "STARTTLS clears command buffer": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - test.expect(2); - - server.on("connect", function(socket){ - - socket.on("command", function(command){ - if(command == "STARTTLS"){ - socket.startTLS(); - socket.send("OK"); - }else if(command == "KILL"){ - test.ok(0, "Should not occur"); - }else if(command == "OK"){ - test.ok(1, "OK"); - } - - }); - - socket.on("tls", function(){ - test.ok(1, "Secure connection opened"); - socket.send("TEST"); - }); - - socket.on("end", function(){ - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - - client.write("STARTTLS\r\nKILL\r\n"); - - client.on("data", function(chunk){ - if(chunk.toString("utf-8").trim() == "OK"){ - var sslcontext = crypto.createCredentials(); - var pair = tlslib.createSecurePair(sslcontext, false); - - pair.encrypted.pipe(client); - client.pipe(pair.encrypted); - pair.fd = client.fd; - - pair.on("secure", function(){ - pair.cleartext.write("OK\r\n"); - pair.cleartext.end(); - }); - } - }); - - }); - - }); - }, - "STARTTLS on secure server fails": function(test){ - var server = new RAIServer({secureConnection: true}); - server.listen(PORT_NUMBER, function(err){ - - test.expect(2); - server.on("connect", function(socket){ - - socket.on("error", function(err){ - test.ok(err); - socket.end(); - server.end(function(){ - test.done(); - }); - }); - - socket.on("command", (function(command){ - process.nextTick(socket.startTLS.bind(socket, function(){ - test.ok(false, "Secure connection opened"); // should not occur - server.end(function(){ - test.done(); - }); - })); - - }).bind(this)); - - socket.on("tls", function(){ - test.ok(0, "Should not occur"); - }); - - }); - - var client = tlslib.connect(PORT_NUMBER, function(){ - test.ok(true); - client.write("HELLO!\r\n"); - }); - - }); - } -}; - -exports["Client commands"] = { - "Receive Simple Command": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - - socket.on("command", function(command, payload){ - test.equal(command, "STATUS"); - test.equal(payload.toString(), ""); - socket.end(); - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - client.write("STATUS\r\n"); - }); - - }); - }, - "Receive Command with payload": function(test){ - var server = new RAIServer(); - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - - socket.on("command", function(command, payload){ - test.equal(command, "MAIL"); - test.equal(payload.toString(), "TO:"); - socket.end(); - - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - client.write("MAIL TO:\r\n"); - }); - - }); - } -}; - -exports["Data mode"] = { - "DATA mode": function(test){ - var server = new RAIServer(), - datapayload = "tere\r\nvana kere"; - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - - socket.startDataMode(); - - test.expect(2); - - socket.on("data", function(chunk){ - test.equal(datapayload, chunk.toString()); - }); - - socket.on("ready", function(){ - test.ok(1,"Data ready"); - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - }); - - var client = netlib.connect(PORT_NUMBER, function(){ - client.write(datapayload+"\r\n.\r\n"); - client.end(); - }); - - }); - }, - "Small chunks DATA mode": function(test){ - var server = new RAIServer(), - datapayload = "tere\r\nvana kere õäöü\r\n.\r", - databytes = [], - fullpayload = datapayload+"\r\n.\r\n"; - server.listen(PORT_NUMBER, function(err){ - - server.on("connect", function(socket){ - - socket.startDataMode(); - - test.expect(1); - - socket.on("data", function(chunk){ - databytes = databytes.concat(Array.prototype.slice.call(chunk)); - }); - - socket.on("ready", function(){ - test.equal(new Buffer(databytes).toString("utf-8"), datapayload); - server.end(function(){ - test.done(); - }); - }); - - socket.on("error", function(err){ - test.isError(err); - }); - - for(var i=0, len = fullpayload.length; i Date.now())){ - return callback(null, this.token, this.accessToken); - } - this.generateToken(callback); -}; - -/** - * Updates token values - * - * @param {String} accessToken New access token - * @param {Number} timeout Access token lifetime in seconds - * - * Emits 'token': { user: User email-address, accessToken: the new accessToken, timeout: Timestamp in seconds after 1.1.1970 } - */ -XOAuth2Generator.prototype.updateToken = function(accessToken, timeout){ - this.token = this.buildXOAuth2Token(accessToken); - this.accessToken = accessToken; - this.timeout = timeout && Date.now() + ((Number(timeout) || 0) - 1) * 1000 || 0; - - this.emit("token", { - user: this.options.user, - accessToken: accessToken || "", - timeout: Math.floor(this.timeout/1000) - }); -}; - -/** - * Generates a new XOAuth2 token with the credentials provided at initialization - * - * @param {Function} callback Callback function with error object and token string - */ -XOAuth2Generator.prototype.generateToken = function(callback){ - var urlOptions = { - client_id: this.options.clientId || "", - client_secret: this.options.clientSecret || "", - refresh_token: this.options.refreshToken, - grant_type: "refresh_token" - }, - payload = querystring.stringify(urlOptions); - - postRequest(this.options.accessUrl, payload, (function(error, response, body){ - var data; - - if(error){ - return callback(error); - } - try{ - data = JSON.parse(body.toString()); - }catch(E){ - return callback(E); - } - - if(!data || typeof data != "object"){ - return callback(new Error("Invalid authentication response")); - } - - if(data.error){ - return callback(new Error(data.error)); - } - - if(data.access_token){ - this.updateToken(data.access_token, data.expires_in); - return callback(null, this.token, this.accessToken); - } - - return callback(new Error("No access token")); - }).bind(this)); -}; - -/** - * Converts an access_token and user id into a base64 encoded XOAuth2 token - * - * @param {String} accessToken Access token string - * @return {String} Base64 encoded token for IMAP or SMTP login - */ -XOAuth2Generator.prototype.buildXOAuth2Token = function(accessToken){ - var authData = [ - "user=" + (this.options.user || ""), - "auth=Bearer " + accessToken, - "", - ""]; - return new Buffer(authData.join("\x01"), "utf-8").toString("base64"); -}; - - -function postRequest(url, payload, callback){ - var options = urllib.parse(url), - finished = false; - - options.method = "POST"; - - var req = (options.protocol=="https:"?https:http).request(options, function(res) { - var data = []; - - res.on('data', function (chunk) { - data.push(chunk); - }); - - res.on("end", function(){ - if(finished){return;} - finished = true - return callback(null, res, Buffer.concat(data)); - }); - - res.on("error", function(err) { - if(finished){return;} - finished = true - callback(err); - }); - }); - - req.on("error", function(err) { - if(finished){return;} - finished = true - callback(err); - }); - - if(payload){ - req.setHeader("Content-Type", "application/x-www-form-urlencoded"); - req.setHeader("Content-Length", typeof payload == "string" ? Buffer.byteLength(payload) : payload.length); - } - - req.write(payload); - req.end(); - -} diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/package.json b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/package.json deleted file mode 100644 index e97c5fdca65..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "xoauth2", - "version": "0.1.8", - "description": "XOAuth2 token generation for accessing GMail SMTP and IMAP", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git://github.com/andris9/xoauth2.git" - }, - "keywords": [ - "XOAUTH", - "XOAUTH2", - "GMail", - "SMTP", - "IMAP" - ], - "author": { - "name": "Andris Reinman" - }, - "license": "MIT", - "readme": "xoauth2\n=======\n\nXOAuth2 token generation with node.js\n\n## Installation\n\n npm install xoauth2\n\n## Usage\n\n**xoauth2** generates XOAUTH2 login tokens from provided Client and User credentials.\n\nUse `xoauth2.createXOAuth2Generator(options)` to initialize Token Generator\n\nPossible options values:\n\n * **user** _(Required)_ User e-mail address\n * **accessUrl** _(Optional)_ Endpoint for token generation (defaults to *https://accounts.google.com/o/oauth2/token*)\n * **clientId** _(Required)_ Client ID value\n * **clientSecret** _(Required)_ Client secret value\n * **refreshToken** _(Required)_ Refresh token for an user\n * **accessToken** _(Optional)_ initial access token. If not set, a new one will be generated\n * **timeout** _(Optional)_ timestamp for when the initial access token times out. In **milliseconds** after 1.1.1970.\n\nSee [https://developers.google.com/accounts/docs/OAuth2WebServer#offline]() for generating the required credentials\n\n### Methods\n\n#### Request an access token\n\nUse `xoauth2obj.getToken(callback)` to get an access token. If a cached token is found and it should not be expired yet, the cached value will be used.\n\n#### Request for generating a new access token\n\nUse `xoauth2obj.generateToken(callback)` to get an access token. Cache will not be used and a new token is generated.\n\n#### Update access token values\n\nUse `xoauth2obj.updateToken(accessToken, timeout)` to set the new value for the xoauth2 access token. This function emits 'token'\n\n### Events\n\nIf a new token value has been set, `'token'` event is emitted.\n\n xoauth2obj.on(\"token\", function(token){\n console.log(\"User: \", token.user); // e-mail address\n console.log(\"New access token: \", token.accessToken);\n console.log(\"New access token timeout: \", token.timeout); // timestamp after 1.1.1970 in seconds\n });\n\n### Example\n\n var xoauth2 = require(\"xoauth2\"),\n xoauth2gen;\n\n xoauth2gen = xoauth2.createXOAuth2Generator({\n user: \"user@gmail.com\",\n clientId: \"{Client ID}\",\n clientSecret: \"{Client Secret}\",\n refreshToken: \"{User Refresh Token}\"\n });\n\n // SMTP/IMAP\n xoauth2gen.getToken(function(err, token){\n if(err){\n return console.log(err);\n }\n console.log(\"AUTH XOAUTH2 \" + token);\n });\n\n // HTTP\n xoauth2gen.getToken(function(err, token, accessToken){\n if(err){\n return console.log(err);\n }\n console.log(\"Authorization: Bearer \" + accessToken);\n });\n\n## License\n\n**MIT**", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/xoauth2/issues" - }, - "_id": "xoauth2@0.1.8", - "_from": "xoauth2@~0.1" -} diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/test.js b/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/test.js deleted file mode 100644 index 813e2cf55c3..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/node_modules/xoauth2/test.js +++ /dev/null @@ -1,20 +0,0 @@ -var xoauth2 = require("./index"), - xoauth2gen; - -xoauth2gen = xoauth2.createXOAuth2Generator({ - user: "user@gmail.com", - clientId: "{Client ID}", - clientSecret: "{Client Secret}", - refreshToken: "{User Refresh Token}", - accessToken: "{User Refresh Token}", - timeout: 3600 -}); - -// SMTP/IMAP -xoauth2gen.getToken(function(err, token){ - if(err){ - console.log(123) - return console.log(err); - } - console.log("AUTH XOAUTH2 " + token); -}); \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/package.json b/api/node_modules/nodemailer/node_modules/simplesmtp/package.json deleted file mode 100644 index 57cace94e19..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "simplesmtp", - "description": "Simple SMTP server module to create custom SMTP servers", - "version": "0.3.2", - "author": { - "name": "Andris Reinman" - }, - "maintainers": [ - { - "name": "andris", - "email": "andris@node.ee" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/andris9/simplesmtp.git" - }, - "scripts": { - "test": "nodeunit test/" - }, - "main": "./lib/smtp", - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/andris9/simplesmtp/blob/master/LICENSE" - } - ], - "dependencies": { - "rai": "~0.1", - "xoauth2": "~0.1" - }, - "devDependencies": { - "nodeunit": "*", - "mailcomposer": "*" - }, - "engines": { - "node": ">=0.8.0" - }, - "keywords": [ - "servers", - "text-based", - "smtp", - "email", - "mail", - "e-mail" - ], - "readme": "# simplesmtp\n\nThis is a module to easily create custom SMTP servers and clients - use SMTP as a first class protocol in Node.JS!\n\n[![Build Status](https://secure.travis-ci.org/andris9/simplesmtp.png)](http://travis-ci.org/andris9/simplesmtp)\n[![NPM version](https://badge.fury.io/js/simplesmtp.png)](http://badge.fury.io/js/simplesmtp)\n\n## Version warning!\n\nIf you are using node v0.6, then the last usable version of **simplesmtp** is v0.2.7\n\nCurrent version of simplesmtp is fully supported for Node v0.8+\n\n## Support simplesmtp development\n\n[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)\n\n## SMTP Server\n\n## Simple SMTP server\n\nFor a simple inbound only, no authentication SMT server you can use\n\n simplesmtp.createSimpleServer([options], requestListener).listen(port);\n\nExample\n\n simplesmtp.createSimpleServer({SMTPBanner:\"My Server\"}, function(req){\n req.pipe(process.stdout);\n req.accept();\n }).listen(port);\n\nProperties\n\n * **req.from** - From address\n * **req.to** - an array of To addresses\n * **req.host** - hostname reported by the client\n * **req.remodeAddress** - client IP address\n\nMethods\n\n * **req.accept** *([id])* - Accept the message with the selected ID\n * **req.reject** *([message])* - Reject the message with the selected message\n * **req.pipe** *(stream)* - Pipe the incoming data to a writable stream\n\nEvents\n\n * **'data'** *(chunk)* - A chunk (Buffer) of the message.\n * **'end'** - The message has been transferred\n\n\n## Advanced SMTP server\n\n### Usage\n\nCreate a new SMTP server instance with\n\n var smtp = simplesmtp.createServer([options]);\n\nAnd start listening on selected port\n\n smtp.listen(25, [function(err){}]);\n\nSMTP options can include the following:\n\n * **name** - the hostname of the server, will be used for informational messages\n * **debug** - if set to true, print out messages about the connection\n * **timeout** - client timeout in milliseconds, defaults to 60 000 (60 sec.)\n * **secureConnection** - start a server on secure connection\n * **SMTPBanner** - greeting banner that is sent to the client on connection\n * **requireAuthentication** - if set to true, require that the client must authenticate itself\n * **enableAuthentication** - if set to true, client may authenticate itself but don't have to (as opposed to `requireAuthentication` that explicitly requires clients to authenticate themselves)\n * **maxSize** - maximum size of an e-mail in bytes (currently informational only)\n * **credentials** - TLS credentials (`{key:'', cert:'', ca:['']}`) for the server\n * **authMethods** - allowed authentication methods, defaults to `[\"PLAIN\", \"LOGIN\"]`\n * **disableEHLO** - if set to true, support HELO command only\n * **ignoreTLS** - if set to true, allow client do not use STARTTLS\n * **disableDNSValidation** - if set, do not validate sender domains\n\n### Example\n\n var simplesmtp = require(\"simplesmtp\"),\n fs = require(\"fs\");\n\n var smtp = simplesmtp.createServer();\n smtp.listen(25);\n\n smtp.on(\"startData\", function(connection){\n console.log(\"Message from:\", connection.from);\n console.log(\"Message to:\", connection.to);\n connection.saveStream = fs.createWriteStream(\"/tmp/message.txt\");\n });\n\n smtp.on(\"data\", function(connection, chunk){\n connection.saveStream.write(chunk);\n });\n\n smtp.on(\"dataReady\", function(connection, callback){\n connection.saveStream.end();\n console.log(\"Incoming message saved to /tmp/message.txt\");\n callback(null, \"ABC1\"); // ABC1 is the queue id to be advertised to the client\n // callback(new Error(\"Rejected as spam!\")); // reported back to the client\n });\n\n### Events\n\n * **startData** *(connection)* - DATA stream is opened by the client (`connection` is an object with `from`, `to`, `host` and `remoteAddress` properties)\n * **data** *(connection, chunk)* - e-mail data chunk is passed from the client\n * **dataReady** *(connection, callback)* - client is finished passing e-mail data, `callback` returns the queue id to the client\n * **authorizeUser** *(connection, username, password, callback)* - will be emitted if `requireAuthentication` option is set to true. `callback` has two parameters *(err, success)* where `success` is Boolean and should be true, if user is authenticated successfully\n * **validateSender** *(connection, email, callback)* - will be emitted if `validateSender` listener is set up\n * **validateRecipient** *(connection, email, callback)* - will be emitted it `validataRecipients` listener is set up\n * **close** *(connection)* - emitted when the connection to client is closed\n\n## SMTP Client\n\n### Usage\n\nSMTP client can be created with `simplesmptp.connect(port[,host][, options])`\nwhere\n\n * **port** is the port to connect to\n * **host** is the hostname to connect to (defaults to \"localhost\")\n * **options** is an optional options object (see below)\n\n### Connection options\n\nThe following connection options can be used with `simplesmtp.connect`:\n\n * **secureConnection** - use SSL\n * **name** - the name of the client server\n * **auth** - authentication object `{user:\"...\", pass:\"...\"}` or `{XOAuthToken:\"base64data\"}`\n * **ignoreTLS** - ignore server support for STARTTLS\n * **tls** - optional options object for `tls.connect`, also applies to STARTTLS. For example `rejectUnauthorized` is set to `false` by default. You can override this option by setting `tls: {rejectUnauthorized: true}`\n * **debug** - output client and server messages to console\n * **instanceId** - unique instance id for debugging (will be output console with the messages)\n\n### Connection events\n\nOnce a connection is set up the following events can be listened to:\n\n * **'idle'** - the connection to the SMTP server has been successfully set up and the client is waiting for an envelope\n * **'message'** - the envelope is passed successfully to the server and a message stream can be started\n * **'ready'** `(success)` - the message was sent\n * **'rcptFailed'** `(addresses)` - not all recipients were accepted (invalid addresses are included as an array)\n * **'error'** `(err)` - An error occurred. The connection is closed and an 'end' event is emitted shortly\n * **'end'** - connection to the client is closed\n\n### Sending an envelope\n\nWhen an `'idle'` event is emitted, an envelope object can be sent to the server.\nThis includes a string `from` and an array of strings `to` property.\n\nEnvelope can be sent with `client.useEnvelope(envelope)`\n\n // run only once as 'idle' is emitted again after message delivery\n client.once(\"idle\", function(){\n client.useEnvelope({\n from: \"me@example.com\",\n to: [\"receiver1@example.com\", \"receiver2@example.com\"]\n });\n });\n\nThe `to` part of the envelope includes **all** recipients from `To:`, `Cc:` and `Bcc:` fields.\n\nIf setting the envelope up fails, an error is emitted. If only some (not all)\nrecipients are not accepted, the mail can still be sent but an `rcptFailed`\nevent is emitted.\n\n client.on(\"rcptFailed\", function(addresses){\n console.log(\"The following addresses were rejected: \", addresses);\n });\n\nIf the envelope is set up correctly a `'message'` event is emitted.\n\n### Sending a message\n\nWhen `'message'` event is emitted, it is possible to send mail. To do this\nyou can pipe directly a message source (for example an .eml file) to the client\nor alternatively you can send the message with `client.write` calls (you also\nneed to call `client.end()` once the message is completed.\n\nIf you are piping a stream to the client, do not leave the `'end'` event out,\nthis is needed to complete the message sequence by the client.\n\n client.on(\"message\", function(){\n fs.createReadStream(\"test.eml\").pipe(client);\n });\n\nOnce the message is delivered a `'ready'` event is emitted. The event has an\nparameter which indicates if the message was transmitted( (true) or not (false)\nand another which includes the last received data from the server.\n\n client.on(\"ready\", function(success, response){\n if(success){\n console.log(\"The message was transmitted successfully with \"+response);\n }\n });\n\n### XOAUTH\n\n**simplesmtp** supports [XOAUTH2 and XOAUTH](https://developers.google.com/google-apps/gmail/oauth_protocol) authentication.\n\n#### XOAUTH2\n\nTo use this feature you can set `XOAuth2` param as an `auth` option\n\n var mailOptions = {\n ...,\n auth:{\n XOAuth2: {\n user: \"example.user@gmail.com\",\n clientId: \"8819981768.apps.googleusercontent.com\",\n clientSecret: \"{client_secret}\",\n refreshToken: \"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI\",\n accessToken: \"vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==\",\n timeout: 3600\n }\n }\n }\n\n`accessToken` and `timeout` values are optional. If login fails a new access token is generated automatically.\n\n#### XOAUTH\n\nTo use this feature you can set `XOAuthToken` param as an `auth` option\n\n var mailOptions = {\n ...,\n auth:{\n XOAuthToken: \"R0VUIGh0dHBzOi8vbWFpbC5nb29....\"\n }\n }\n\nAlternatively it is also possible to use XOAuthToken generators (supported by Nodemailer) - this\nneeds to be an object with a mandatory method `generate` that takes a callback function for\ngenerating a XOAUTH token string. This is better for generating tokens only when needed -\nthere is no need to calculate unique token for every e-mail request, since a lot of these\nmight share the same connection and thus the cleint needs not to re-authenticate itself\nwith another token.\n\n var XOGen = {\n token: \"abc\",\n generate: function(callback){\n if(1 != 1){\n return callback(new Error(\"Tokens can't be generated in strange environments\"));\n }\n callback(null, new Buffer(this.token, \"utf-8\").toString(\"base64\"));\n }\n }\n\n var mailOptions = {\n ...,\n auth:{\n XOAuthToken: XOGen\n }\n }\n\n### Error types\n\nEmitted errors include the reason for failing in the `name` property\n\n * **UnknowAuthError** - the client tried to authenticate but the method was not supported\n * **AuthError** - the username/password used were rejected\n * **TLSError** - STARTTLS failed\n * **SenderError** - the sender e-mail address was rejected\n * **RecipientError** - all recipients were rejected (if only some of the recipients are rejected, a `'rcptFailed'` event is raised instead\n\nThere's also an additional property in the error object called `data` that includes\nthe last response received from the server (if available for the current error type).\n\n### About reusing the connection\n\nYou can reuse the same connection several times but you can't send a mail\nthrough the same connection concurrently. So if you catch and `'idle'` event\nlock the connection to a message process and unlock after `'ready'`.\n\nOn `'error'` events you should reschedule the message and on `'end'` events\nyou should recreate the connection.\n\n### Closing the client\n\nBy default the client tries to keep the connection up. If you want to close it,\nrun `client.quit()` - this sends a `QUIT` command to the server and closes the\nconnection\n\n client.quit();\n\n## SMTP Client Connection pool\n\n**simplesmtp** has the option for connection pooling if you want to reuse a bulk\nof connections.\n\n### Usage\n\nCreate a connection pool of SMTP clients with\n\n simplesmtp.createClientPool(port[,host][, options])\n\nwhere\n\n * **port** is the port to connect to\n * **host** is the hostname to connect to (defaults to \"localhost\")\n * **options** is an optional options object (see below)\n\n### Connection options\n\nThe following connection options can be used with `simplesmtp.connect`:\n\n * **secureConnection** - use SSL\n * **name** - the name of the client server\n * **auth** - authentication object `{user:\"...\", pass:\"...\"}` or `{XOAuthToken:\"base64data\"}`\n * **ignoreTLS** - ignore server support for STARTTLS\n * **debug** - output client and server messages to console\n * **maxConnections** - how many connections to keep in the pool (defaults to 5)\n\n### Send an e-mail\n\nE-mails can be sent through the pool with\n\n pool.sendMail(mail[, callback])\n\nwhere\n\n * **mail** is a [MailComposer](/andris9/mailcomposer) compatible object\n * **callback** `(error, responseObj)` - is the callback function to run after the message is delivered or an error occured. `responseObj` may include `failedRecipients` which is an array with e-mail addresses that were rejected and `message` which is the last response from the server.\n\n### Errors\n\nIn addition to SMTP client errors another error name is used\n\n * **DeliveryError** - used if the message was not accepted by the SMTP server\n\n## License\n\n**MIT**\n\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/simplesmtp/issues" - }, - "_id": "simplesmtp@0.3.2", - "_from": "simplesmtp@~0.2 || ~0.3" -} diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/test/client.js b/api/node_modules/nodemailer/node_modules/simplesmtp/test/client.js deleted file mode 100644 index 0929913ea64..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/test/client.js +++ /dev/null @@ -1,444 +0,0 @@ -var testCase = require('nodeunit').testCase, - runClientMockup = require("rai").runClientMockup, - simplesmtp = require("../index"), - fs = require("fs"); - -process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" - -var PORT_NUMBER = 8397; - -exports["General tests"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer(); - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Connect and setup": function(test){ - var client = simplesmtp.connect(PORT_NUMBER); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - } -}; - -exports["Secure server"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({ - secureConnection: true - }); - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Connect and setup": function(test){ - var client = simplesmtp.connect(PORT_NUMBER, false, { - secureConnection: true - }); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - } -}; - -exports["Disabled EHLO"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({disableEHLO: true}); - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Connect and setup": function(test){ - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - } -}; - -exports["Authentication needed"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({ - requireAuthentication: true - }); - - this.server.on("authorizeUser", function(envelope, user, pass, callback){ - callback(null, user=="test1" && pass == "test2"); - }); - - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Auth success": function(test){ - var client = simplesmtp.connect(PORT_NUMBER, false, { - auth: { - user: "test1", - pass: "test2" - } - }); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Auth fails": function(test){ - var client = simplesmtp.connect(PORT_NUMBER, false, { - auth: { - user: "test3", - pass: "test4" - } - }); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(false); // should not occur - client.close(); - }); - - client.on("error", function(err){ - test.ok(true); // login failed - }); - - client.on("end", function(){ - test.done(); - }); - } -}; - -exports["Message tests"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({ - validateSender: true, - validateRecipients: true - }); - - this.server.on("validateSender", function(envelope, email, callback){ - callback(email != "test@pangalink.net"?new Error("Failed sender") : null); - }); - - this.server.on("validateRecipient", function(envelope, email, callback){ - callback(email.split("@").pop() != "pangalink.net"?new Error("Failed recipient") : null); - }); - - this.server.on("dataReady", function(envelope, callback){ - callback(null, "ABC1"); // ABC1 is the queue id to be advertised to the client - // callback(new Error("That was clearly a spam!")); - }); - - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Set envelope success": function(test){ - test.expect(2); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test@pangalink.net", - to: [ - "test1@pangalink.net", - "test2@pangalink.net" - ] - }); - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(true); // waiting for message - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Set envelope fails for sender": function(test){ - test.expect(2); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test3@pangalink.net", - to: [ - "test1@pangalink.net", - "test2@pangalink.net" - ] - }); - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(false); // waiting for message - client.close(); - }); - - client.on("error", function(err){ - test.ok(true); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Set envelope fails for receiver": function(test){ - test.expect(2); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test@pangalink.net", - to: [ - "test1@kreata.ee", - "test2@kreata.ee" - ] - }); - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(false); // waiting for message - client.close(); - }); - - client.on("error", function(err){ - test.ok(true); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Set envelope partly fails": function(test){ - test.expect(3); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test@pangalink.net", - to: [ - "test1@pangalink.net", - "test2@kreata.ee" - ] - }); - }); - - client.on("rcptFailed", function(){ - // Client is ready to take messages - test.ok(true); // waiting for message - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(true); // waiting for message - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Send message success": function(test){ - test.expect(3); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test@pangalink.net", - to: [ - "test1@pangalink.net", - "test2@pangalink.net" - ] - }); - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(true); // waiting for message - - client.write("From: abc@pangalink.net\r\nTo:cde@pangalink.net\r\nSubject: test\r\n\r\nHello World!"); - client.end(); - }); - - client.on("ready", function(success){ - test.ok(success); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - }, - - "Stream message": function(test){ - test.expect(3); - - var client = simplesmtp.connect(PORT_NUMBER, false, {}); - - client.once("idle", function(){ - // Client is ready to take messages - test.ok(true); // waiting for envelope - - client.useEnvelope({ - from: "test@pangalink.net", - to: [ - "test1@pangalink.net", - "test2@pangalink.net" - ] - }); - }); - - client.on("message", function(){ - // Client is ready to take messages - test.ok(true); // waiting for message - - // pipe file to client - fs.createReadStream(__dirname+"/testmessage.eml").pipe(client); - }); - - client.on("ready", function(success){ - test.ok(success); - client.close(); - }); - - client.on("error", function(err){ - test.ok(false); - }); - - client.on("end", function(){ - test.done(); - }); - } - -}; diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js b/api/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js deleted file mode 100644 index 5c2d521b29d..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/test/pool.js +++ /dev/null @@ -1,275 +0,0 @@ -var testCase = require('nodeunit').testCase, - runClientMockup = require("rai").runClientMockup, - simplesmtp = require("../index"), - MailComposer = require("mailcomposer").MailComposer, - fs = require("fs"); - -var PORT_NUMBER = 8397; - -exports["General tests"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({}); - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Send single message": function(test){ - - var pool = simplesmtp.createClientPool(PORT_NUMBER), - mc = new MailComposer({escapeSMTP: true}); - - mc.setMessageOption({ - from: "andmekala@hot.ee", - to: "andris@pangalink.net", - subject:"Hello!", - body: "Hello world!", - html: "Hello world!" - }); - - this.server.on("dataReady", function(envelope, callback){ - test.ok(true); - callback(); - }); - - pool.sendMail(mc, function(error){ - test.ifError(error); - pool.close(function(){ - test.ok(true); - test.done(); - }); - }); - }, - - "Send several messages": function(test){ - var total = 10; - - test.expect(total*2); - - var pool = simplesmtp.createClientPool(PORT_NUMBER), - mc; - - this.server.on("dataReady", function(envelope, callback){ - process.nextTick(callback); - }); - - var completed = 0; - for(var i=0; iHello world!" - }); - pool.sendMail(mc, function(error){ - test.ifError(error); - test.ok(true); - completed++; - if(completed >= total){ - pool.close(function(){ - test.done(); - }); - } - }); - } - }, - - "Delivery error once": function(test){ - - var pool = simplesmtp.createClientPool(PORT_NUMBER), - mc = new MailComposer({escapeSMTP: true}); - - mc.setMessageOption({ - from: "andmekala@hot.ee", - to: "andris@pangalink.net", - subject:"Hello!", - body: "Hello world!", - html: "Hello world!" - }); - - this.server.on("dataReady", function(envelope, callback){ - test.ok(true); - callback(new Error("Spam!")); - }); - - pool.sendMail(mc, function(error){ - test.equal(error && error.name, "DeliveryError"); - pool.close(function(){ - test.ok(true); - test.done(); - }); - }); - }, - - "Delivery error several times": function(test){ - var total = 10; - - test.expect(total); - - var pool = simplesmtp.createClientPool(PORT_NUMBER), - mc; - - this.server.on("dataReady", function(envelope, callback){ - process.nextTick(function(){callback(new Error("Spam!"));}); - }); - - var completed = 0; - for(var i=0; iHello world!" - }); - - pool.sendMail(mc, function(error){ - test.equal(error && error.name, "DeliveryError"); - completed++; - if(completed >= total){ - pool.close(function(){ - test.done(); - }); - } - }); - } - } -}; - -exports["Auth fail tests"] = { - setUp: function (callback) { - this.server = new simplesmtp.createServer({ - requireAuthentication: true - }); - - this.server.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - this.server.on("authorizeUser", function(envelope, username, password, callback){ - callback(null, username == password); - }); - }, - - tearDown: function (callback) { - this.server.end(callback); - }, - - "Authentication passes once": function(test){ - var pool = simplesmtp.createClientPool(PORT_NUMBER, false, { - auth: { - "user": "test", - "pass": "test" - } - }), - mc = new MailComposer({escapeSMTP: true}); - - mc.setMessageOption({ - from: "andmekala2@hot.ee", - to: "andris2@pangalink.net", - subject:"Hello2!", - body: "Hello2 world!", - html: "Hello2 world!" - }); - - this.server.on("dataReady", function(envelope, callback){ - test.ok(true); - callback(); - }); - - pool.sendMail(mc, function(error){ - test.ifError(error); - pool.close(function(){ - test.ok(true); - test.done(); - }); - }); - - }, - - "Authentication error once": function(test){ - var pool = simplesmtp.createClientPool(PORT_NUMBER, false, { - auth: { - "user": "test1", - "pass": "test2" - } - }), - mc = new MailComposer({escapeSMTP: true}); - - mc.setMessageOption({ - from: "andmekala2@hot.ee", - to: "andris2@pangalink.net", - subject:"Hello2!", - body: "Hello2 world!", - html: "Hello2 world!" - }); - - this.server.on("dataReady", function(envelope, callback){ - test.ok(true); - callback(); - }); - - pool.sendMail(mc, function(error){ - test.equal(error && error.name, "AuthError"); - pool.close(function(){ - test.ok(true); - test.done(); - }); - }); - - }, - - "Authentication error several times": function(test){ - var total = 10; - test.expect(total); - - var pool = simplesmtp.createClientPool(PORT_NUMBER, false, { - auth: { - "user": "test1", - "pass": "test2" - } - }), - mc; - this.server.on("dataReady", function(envelope, callback){ - process.nextTick(function(){callback(new Error("Spam!"));}); - }); - - var completed = 0; - for(var i=0; iHello world!" - }); - - pool.sendMail(mc, function(error){ - test.equal(error && error.name, "AuthError"); - completed++; - if(completed >= total){ - pool.close(function(){ - test.done(); - }); - } - }); - } - } -}; \ No newline at end of file diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/test/server.js b/api/node_modules/nodemailer/node_modules/simplesmtp/test/server.js deleted file mode 100644 index 43d54e85507..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/test/server.js +++ /dev/null @@ -1,599 +0,0 @@ -var testCase = require('nodeunit').testCase, - runClientMockup = require("rai").runClientMockup, - simplesmtp = require("../index"), - netlib = require("net"); - -var PORT_NUMBER = 8397; - -// monkey patch net and tls to support nodejs 0.4 -if(!netlib.connect && netlib.createConnection){ - netlib.connect = netlib.createConnection; -} - -exports["General tests"] = { - setUp: function (callback) { - - this.smtp = new simplesmtp.createServer({ - SMTPBanner: "SCORPIO", - name: "MYRDO", - maxSize: 1234 - }); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "QUIT": function(test){ - var cmds = ["QUIT"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("221",resp.toString("utf-8").trim().substr(0,3)); - test.done(); - }); - - }, - "HELO": function(test){ - var cmds = ["HELO FOO"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("250",resp.toString("utf-8").trim().substr(0,3)); - test.done(); - }); - - }, - "HELO fails": function(test){ - var cmds = ["HELO"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "EHLO": function(test){ - var cmds = ["EHLO FOO"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - resp = resp.toString("utf-8").trim(); - var lines = resp.split("\r\n"); - for(var i=0; i BODY=8BITMIME"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.ok(resp.toString("utf-8").match(/^250/)); - test.done(); - }); - }, - "MAXSIZE": function(test){ - var cmds = ["EHLO FOO"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.ok(resp.toString("utf-8").trim().match(/^250[\- ]SIZE 1234$/mi)); - test.done(); - }); - } -}; - -exports["EHLO setting"] = { - setUp: function (callback) { - - this.smtp = new simplesmtp.createServer({ - disableEHLO: true - }); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "Disable EHLO": function(test){ - runClientMockup(PORT_NUMBER, "localhost", ["EHLO foo"], function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - runClientMockup(PORT_NUMBER, "localhost", ["HELO foo"], function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }); - - } -}; - -exports["Client disconnect"] = { - - "Client disconnect": function(test){ - - var smtp = new simplesmtp.createServer(), - clientEnvelope; - smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - } - - runClientMockup(PORT_NUMBER, "localhost", ["EHLO foo", "MAIL FROM:", "RCPT TO:", "DATA"], function(resp){ - test.equal("3",resp.toString("utf-8").trim().substr(0,1)); - }); - - }); - smtp.on("startData", function(envelope){ - clientEnvelope = envelope; - }); - smtp.on("close", function(envelope){ - test.equal(envelope, clientEnvelope); - smtp.end(function(){}); - test.done(); - }); - - } -}; - -exports["Require AUTH"] = { - setUp: function (callback) { - - this.smtp = new simplesmtp.createServer({requireAuthentication: true}); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - this.smtp.on("authorizeUser", function(envelope, username, password, callback){ - callback(null, username=="andris" && password=="test"); - }); - - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "Fail without AUTH": function(test){ - var cmds = ["EHLO FOO", "MAIL FROM:"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "Unknown AUTH": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH CRAM"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH fails before STARTTLS": function(test){ - var cmds = ["EHLO FOO", "AUTH LOGIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("3",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid login": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("inv").toString("base64"), - new Buffer("alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid username": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("inv").toString("base64"), - new Buffer("test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid password": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("andris").toString("base64"), - new Buffer("alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("andris").toString("base64"), - new Buffer("test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("3",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid login": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("inv\u0000inv\u0000alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid user": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("inv\u0000inv\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid password": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("andris\u0000andris\u0000alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("andris\u0000andris\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Yet another login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN", - new Buffer("andris\u0000andris\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - } -}; - -exports["Enable AUTH"] = { - setUp: function (callback) { - - this.smtp = new simplesmtp.createServer({enableAuthentication: true}); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - this.smtp.on("authorizeUser", function(envelope, username, password, callback){ - callback(null, username=="andris" && password=="test"); - }); - - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "Pass without AUTH": function(test){ - var cmds = ["EHLO FOO", "MAIL FROM:"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "Unknown AUTH": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH CRAM"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH fails before STARTTLS": function(test){ - var cmds = ["EHLO FOO", "AUTH LOGIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("3",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid login": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("inv").toString("base64"), - new Buffer("alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid username": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("inv").toString("base64"), - new Buffer("test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Invalid password": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("andris").toString("base64"), - new Buffer("alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH LOGIN Login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH LOGIN", - new Buffer("andris").toString("base64"), - new Buffer("test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("3",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid login": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("inv\u0000inv\u0000alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid user": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("inv\u0000inv\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Invalid password": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("andris\u0000andris\u0000alid").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN "+ - new Buffer("andris\u0000andris\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "AUTH PLAIN Yet another login success": function(test){ - var cmds = ["EHLO FOO", "STARTTLS", "EHLO FOO", "AUTH PLAIN", - new Buffer("andris\u0000andris\u0000test").toString("base64")]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("2",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - } -}; - -exports["ignoreTLS"] = { - setUp: function (callback) { - - this.smtp = new simplesmtp.createServer({requireAuthentication: true, ignoreTLS: true}); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - this.smtp.on("authorizeUser", function(envelope, username, password, callback){ - callback(null, username=="d3ph" && password=="test"); - }); - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "Fail without AUTH": function(test){ - var cmds = ["EHLO FOO", "MAIL FROM:"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "Fail MAIL FROM without HELO": function(test){ - var cmds = ["MAIL FROM:"]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("5",resp.toString("utf-8").trim().substr(0,1)); - test.done(); - }); - }, - "Success AUTH & SEND MAIL with .": function(test){ - var cmds = ["EHLO FOO", - "AUTH PLAIN", - new Buffer("\u0000d3ph\u0000test").toString("base64"), - "MAIL FROM:", - "RCPT TO:", - "DATA", - "Test mail\015\012.\015\012", - ]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - var resp = resp.toString("utf-8").trim(); - test.equal("2",resp.substr(0,1)); - test.ok(resp.match('queued as')); - test.done(); - }); - } -}; - -exports["Sending mail listen for dataReady"] = { - setUp: function (callback) { - var data = ""; - - this.smtp = new simplesmtp.createServer({ignoreTLS: true}); - this.smtp.listen(PORT_NUMBER, function(err){ - if(err){ - throw err; - }else{ - callback(); - } - }); - - this.smtp.on("authorizeUser", function(envelope, username, password, callback){ - callback(null, username=="d3ph" && password=="test"); - }); - - this.smtp.on("data", function(envelope, chunk){ - data += chunk; - }); - - this.smtp.on("dataReady", function(envelope, callback){ - setTimeout(function(){ - if (data.match('spam')) { - callback(new Error("FAILED")); - } else { - callback(null, '#ID'); - } - }, 2000); - }); - }, - tearDown: function (callback) { - this.smtp.end(callback); - }, - "Fail send mail if body contains 'spam'": function(test){ - var cmds = ["EHLO FOO", - "MAIL FROM:", - "RCPT TO:", - "DATA", - "Test mail with spam!\015\012.\015\012", - ]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - test.equal("550 FAILED",resp.toString("utf-8").trim()); - test.done(); - }); - }, - "Create #ID for mail": function(test){ - var cmds = ["EHLO FOO", - "MAIL FROM:", - "RCPT TO:", - "DATA", - "Clear mail body\015\012.\015\012", - ]; - runClientMockup(PORT_NUMBER, "localhost", cmds, function(resp){ - var resp = resp.toString("utf-8").trim(); - test.equal("2",resp.substr(0,1)); - test.ok(resp.match('#ID')); - test.done(); - }); - } -} - diff --git a/api/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml b/api/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml deleted file mode 100644 index dff23e5082e..00000000000 --- a/api/node_modules/nodemailer/node_modules/simplesmtp/test/testmessage.eml +++ /dev/null @@ -1,5 +0,0 @@ -From: test@pangalink.net -To: test@pangalink.net -Subject: Test - -Hello world! \ No newline at end of file diff --git a/api/node_modules/nodemailer/package.json b/api/node_modules/nodemailer/package.json deleted file mode 100644 index e1ff25dc3db..00000000000 --- a/api/node_modules/nodemailer/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "nodemailer", - "description": "Easy to use module to send e-mails, supports unicode and SSL/TLS", - "version": "0.4.4", - "author": { - "name": "Andris Reinman" - }, - "maintainers": [ - { - "name": "andris", - "email": "andris@kreata.ee" - } - ], - "homepage": "http://github.com/andris9/nodemailer", - "repository": { - "type": "git", - "url": "http://github.com/andris9/nodemailer.git" - }, - "scripts": { - "test": "nodeunit test/" - }, - "main": "./lib/nodemailer", - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/andris9/nodemailer/blob/master/LICENSE" - } - ], - "dependencies": { - "mailcomposer": "~0.1", - "simplesmtp": "~0.2 || ~0.3" - }, - "devDependencies": { - "nodeunit": "*" - }, - "engines": { - "node": ">=0.6.0" - }, - "keywords": [ - "e-mail", - "mime", - "email", - "mail", - "sendmail", - "ses" - ], - "readme": "Nodemailer\n==========\n\n**Nodemailer** is an easy to use module to send e-mails with Node.JS (using\nSMTP or sendmail or Amazon SES) and is unicode friendly - You can use any characters you like ✔\n\nNodemailer is Windows friendly, you can install it with *npm* on Windows just like any other module, there are no compiled dependencies. Use it from Azure or from your Windows box hassle free.\n\n**[Read about using Nodemailer from the Node Knockout blog](http://blog.nodeknockout.com/post/34641712180/sending-email-from-node-js)**\n\n[![Build Status](https://secure.travis-ci.org/andris9/Nodemailer.png)](http://travis-ci.org/andris9/Nodemailer)\n[![NPM version](https://badge.fury.io/js/nodemailer.png)](http://badge.fury.io/js/nodemailer)\n\n## Notes and information\n\n### Nodemailer supports\n\n * **Unicode** to use any characters\n * **HTML content** as well as **plain text** alternative\n * **Attachments** (including attachment **streaming** for sending larger files)\n * **Embedded images** in HTML\n * **SSL/STARTTLS** for secure e-mail delivery\n * Different transport methods - **SMTP**, **sendmail** and **Amazon SES**\n * SMTP **Connection pool** and connection reuse for rapid delivery\n * **Preconfigured** services for using SMTP with Gmail, Hotmail etc.\n * Use objects as header values for **SendGrid** SMTP API\n * **XOAUTH2** authentication and token generation support - useful with Gmail\n * **DKIM** signing\n\n### Support Nodemailer development\n\n[![Donate to author](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DB26KWR2BQX5W)\n\nIf you want to support with Bitcoins, then my wallet address is `15Z8ADxhssKUiwP3jbbqJwA21744KMCfTM`\n\n### Nodemailer PaaS support\n\nNodemailer has been tested successfully on the following PaaS platforms (using free/trial accounts):\n\n * [heroku](http://www.heroku.com/)\n * [AppFog](http://www.appfog.com/)\n * [OpenShift](https://openshift.redhat.com/app/)\n * [Nodejitsu](http://nodejitsu.com/)\n * [Windows Azure](http://www.windowsazure.com/)\n\n### Check out my other mail related modules\n\nIf you want to parse generated or received e-mail instead of sending it, check\nout [MailParser](https://github.com/andris9/mailparser).\n\nIf you only want to generate the raw e-mail stream, check out\n[MailComposer](https://github.com/andris9/mailcomposer).\n\nIf you only want to communicate with the SMTP (both as client and the server),\ncheck out [simplesmtp](https://github.com/andris9/simplesmtp).\n\n### Templates\n\nTo use Nodemailer with templates, please see documentation for these projects.\n\n * [swig-email-templates](https://github.com/superjoe30/swig-email-templates) - swig, template inheritance, dummy context\n * [node-email-templates](https://github.com/niftylettuce/node-email-templates) - ejs\n\n## TL;DR Usage Example\n\nThis is a complete example to send an e-mail with plaintext and HTML body\n\n```javascript\nvar nodemailer = require(\"nodemailer\");\n\n// create reusable transport method (opens pool of SMTP connections)\nvar smtpTransport = nodemailer.createTransport(\"SMTP\",{\n service: \"Gmail\",\n auth: {\n user: \"gmail.user@gmail.com\",\n pass: \"userpass\"\n }\n});\n\n// setup e-mail data with unicode symbols\nvar mailOptions = {\n from: \"Fred Foo ✔ \", // sender address\n to: \"bar@blurdybloop.com, baz@blurdybloop.com\", // list of receivers\n subject: \"Hello ✔\", // Subject line\n text: \"Hello world ✔\", // plaintext body\n html: \"Hello world ✔\" // html body\n}\n\n// send mail with defined transport object\nsmtpTransport.sendMail(mailOptions, function(error, response){\n if(error){\n console.log(error);\n }else{\n console.log(\"Message sent: \" + response.message);\n }\n\n // if you don't want to use this transport object anymore, uncomment following line\n //smtpTransport.close(); // shut down the connection pool, no more messages\n});\n```\n\nSee also the [examples folder](https://github.com/andris9/Nodemailer/tree/master/examples)\nfor full featured examples\n\n## Installation\n\nInstall through NPM\n\n```\nnpm install nodemailer\n```\n\n## Usage\n\nInclude the module\n\n```javascript\nvar nodemailer = require(\"nodemailer\");\n```\n\nAn e-mail can be sent with `sendMail(mailOptions[, callback])` command\n\n```javascript\ntransport.sendMail(mailOptions, callback);\n```\n\nWhere\n\n * `transport` is a transport object created from the `nodemailer.createTransport` method\n * **mailOptions** defines the e-mail (set its subject, body text, receivers etc.), see [E-mail Message Fields](#e-mail-message-fields) for details\n * **callback** is the callback function that will be run after the e-mail is sent or the sending failed (see [Return callback](#return-callback) for details)\n\n## Setting up a transport method\n\nBefore you can send any e-mails you need to set up a transport method. This can\nbe done with `nodemailer.createTransport(type, options)` where `type` indicates\nthe transport protocol and `options` defines how it is used.\n\n```javascript\nvar transport = nodemailer.createTransport(\"SMTP\", {smtp_options});\n```\n\nThe same transport object can and should be reused several times.\n\nWhen the transport method is defined, it can be used to send e-mail with `sendMail`\n\n```javascript\nvar transport = nodemailer.createTransport(\"SMTP\", {smtp_options});\n\ntransport.sendMail({\n from: \"sender@tr.ee\",\n to: \"receiver@tr.ee\"\n ...\n});\n```\n\n### Possible transport methods\n\nRequired `type` parameter can be one of the following:\n\n * **SMTP** for using SMTP\n * **SES** for using Amazon SES\n * **Sendmail** for utilizing systems *sendmail* command\n\n### Setting up SMTP\n\nSMTP is different from the other transport mechanisms, as in its case a connection\npool is created. All the connections try to stay alive as long as possible and\nare reusable to minimize the protocol overhead delay - for example setting up\nTLS for authenticating is relatively lengthy process (in CPU terms, not by human\nterms), you do not want to do it several times.\n\nPossible SMTP options are the following:\n\n * **service** - an optional well known service identifier (\"Gmail\", \"Hotmail\" etc., see [Well known Services](#well-known-services-for-smtp) for a list of supported services) to auto-configure host, port and secure connection settings\n * **host** - hostname of the SMTP server (defaults to \"localhost\", not needed with `service`)\n * **port** - port of the SMTP server (defaults to 25, not needed with `service`)\n * **secureConnection** - use SSL (default is `false`, not needed with `service`). If you're using port 587 then keep `secureConnection` false, since the connection is started in insecure plain text mode and only later upgraded with STARTTLS\n * **name** - the name of the client server (defaults to machine name)\n * **auth** - authentication object as `{user:\"...\", pass:\"...\"}` or `{XOAuth2: {xoauth2_options}}` or `{XOAuthToken: \"base64data\"}`\n * **ignoreTLS** - ignore server support for STARTTLS (defaults to `false`)\n * **debug** - output client and server messages to console\n * **maxConnections** - how many connections to keep in the pool (defaults to 5)\n\nExample:\n\n```javascript\nvar transport = nodemailer.createTransport(\"SMTP\", {\n service: \"Gmail\",\n auth: {\n user: \"gmail.user@gmail.com\",\n pass: \"userpass\"\n }\n});\n```\n\nor the same without `service` parameter\n\n```javascript\nvar transport = nodemailer.createTransport(\"SMTP\", {\n host: \"smtp.gmail.com\", // hostname\n secureConnection: true, // use SSL\n port: 465, // port for secure SMTP\n auth: {\n user: \"gmail.user@gmail.com\",\n pass: \"userpass\"\n }\n});\n```\n\n**NB!** if you want to close the pool (cancel all open connections) you can use `transport.close()`\n\n```javascript\n\nvar transport = nodemailer.createTransport(\"SMTP\",{});\n...\ntransport.close(); // close the pool\n```\n\n\n#### SMTP XOAUTH and token generation\n\n##### XOAUTH2\n\n**nodemailer** supports XOAUTH2 authentication protocol. To use this you need to obtain a Client ID and a Client Secret from [Google API Console](https://code.google.com/apis/console) (Open \"API Access\" and create \"Client ID for web applications\") and then request a refresh token for an user. See [Google OAuth 2.0 Offline Access](https://developers.google.com/accounts/docs/OAuth2WebServer#offline) for more information.\n\nOnce you have obtained the Client ID, Client Secret and a Refresh Token for an user, you can use these values to send mail on behalf of the user.\n\n```javascript\nvar transportOptions = {\n ...,\n auth: {\n XOAuth2: {\n user: \"example.user@gmail.com\",\n clientId: \"8819981768.apps.googleusercontent.com\",\n clientSecret: \"{client_secret}\",\n refreshToken: \"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI\",\n accessToken: \"vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg==\",\n timeout: 3600\n }\n }\n}\n```\n\n`accessToken` and `timeout` values are both optional. If XOAUTH2 login fails a new access token is generated automatically and the login is retried.\n\n##### XOAUTH\n\nOlder XOAUTH is also supporteb by **nodemailer** for SMTP. XOAUTH is based on OAuth protocol 1.0 and is considered deprecated.\n\nTo use this, include `XOAuthToken` option in `auth` instead of the regular `user` and `pass`.\n\n```javascript\nvar transportOptions = {\n ...,\n auth: {\n XOAuthToken: \"R0VUIGh0dHBzOi8vbWFpbC5nb29....\"\n }\n}\n```\n\n**nodemailer** includes also built in XOAUTH token generator which can be used\nwith `nodemailer.createXOAuthGenerator()`. The function is preconfigured for\nGmail, so in this case only mandatory options are `user`, `token` and `tokenSecret`.\n\n```javascript\nvar XOAuthTokenGenerator = nodemailer.createXOAuthGenerator({\n user: \"test.nodemailer@gmail.com\",\n // requestUrl: \"https://oauth.access.point\",\n // consumerKey: \"anonymous\",\n // consumerSecret: \"anonymous\",\n token: \"1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM\",\n tokenSecret: \"_mUBkIwNPnfQBUIWrJrpXJ0c\"\n });\n```\n\nOne of `user` or `requestUrl` is mandatory. `consumerKey` and `consumerSecret` both\ndefault to `\"anonymous\"`.\n\n```javascript\nvar transportOptions = {\n service: \"Gmail\",\n auth: {\n XOAuthToken: nodemailer.createXOAuthGenerator({\n user: \"test.nodemailer@gmail.com\",\n token: \"1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM\",\n tokenSecret: \"_mUBkIwNPnfQBUIWrJrpXJ0c\"\n })\n }\n}\n```\n\n### Setting up SES\n\nSES is actually a HTTP based protocol, the compiled e-mail and related info\n(signatures and such) are sent as a HTTP request to SES servers.\n\nPossible SES options are the following:\n\n * **AWSAccessKeyID** - AWS access key (required)\n * **AWSSecretKey** - AWS secret (required)\n * **ServiceUrl** - optional API end point URL (defaults to *\"https://email.us-east-1.amazonaws.com\"*)\n\nExample:\n\n```javascript\nvar transport = nodemailer.createTransport(\"SES\", {\n AWSAccessKeyID: \"AWSACCESSKEY\",\n AWSSecretKey: \"AWS/Secret/key\"\n});\n```\n\n### Setting up Sendmail\n\nSendmail transport method streams the compiled message to the *stdin* of *sendmail*\ncommand.\n\nOptions object is optional, possible sendmail options are the following:\n\n * **path** - path to the `sendmail` command (defaults to *\"sendmail\"*)\n * **args** - an array of extra command line options to pass to the `sendmail` command (ie. `[\"-f foo@blurdybloop.com\"]`)\n\nExample:\n\n```javascript\nvar transport = nodemailer.createTransport(\"sendmail\");\n```\n\nor\n\n```javascript\nvar transport = nodemailer.createTransport(\"sendmail\", {\n path: \"/usr/local/bin/sendmail\",\n args: [\"-f foo@blurdybloop.com\"]\n});\n```\n\n### DKIM Signing\n\n**Nodemailer** supports DKIM signing with very simple setup. Use this with caution\nthough since the generated message needs to be buffered entirely before it can be\nsigned. Not a big deal with small messages but might consume a lot of RAM when\nusing larger attachments.\n\nSet up the DKIM signing with `useDKIM` method for a transport object:\n\n```javascript\ntransport.useDKIM(dkimOptions)\n```\n\nWhere `dkimOptions` includes necessary options for signing\n\n * **domainName** - the domainname that is being used for signing\n * **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.blurdybloop.com* then `zzz` is the selector\n * **privateKey** - DKIM private key that is used for signing as a string\n * **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used\n\nAll messages transmitted through this transport objects are from now on DKIM signed.\n\nCurrently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.\n\nExample:\n\n```javascript\nvar transport = nodemailer.createTransport(\"Sendmail\");\n\ntransport.useDKIM({\n domainName: \"kreata.ee\",\n keySelector: \"dkim\",\n privateKey: fs.readFileSync(\"private_key.pem\")\n});\n\ntransport.sendMail(mailOptions);\n```\n\nSee [examples/example_dkim.js](https://github.com/andris9/Nodemailer/blob/master/examples/example_dkim.js) for a complete example.\n\n### Well known services for SMTP\n\nIf you want to use a well known service as the SMTP host, you do not need\nto enter the hostname or port number, just use the `service` parameter\n\nCurrently supported services are:\n\n * **DynectEmail**\n * **Gmail**\n * **hot.ee**\n * **Hotmail**\n * **iCloud**\n * **mail.ee**\n * **Mail.Ru**\n * **Mailgun**\n * **Mandrill**\n * **Postmark**\n * **QQ**\n * **SendGrid**\n * **SES**\n * **Yahoo**\n * **yandex**\n * **Zoho**\n\nPredefined service data covers `host`, `port` and secure connection settings,\nany other parameters (ie. `auth`) need to be set separately. Service names are\ncase insensitive, so using \"gmail\" instead of \"Gmail\" is totally fine.\n\nExample:\n\n```javascript\nvar smtpTransport = nodemailer.createTransport(\"Gmail\",{\n auth: {\n user: \"gmail.user@gmail.com\",\n pass: \"userpass\"\n }\n});\n```\n\nor alternatively\n\n```javascript\nvar smtpTransport = nodemailer.createTransport(\"SMTP\",{\n service: \"Gmail\", // sets automatically host, port and connection security settings\n auth: {\n user: \"gmail.user@gmail.com\",\n pass: \"userpass\"\n }\n});\n```\n\nActually, if you are authenticatinw with an e-mail address that has a domain name\nlike @gmail.com or @yahoo.com etc., then you don't even need to provide the service name,\nit is detected automatically.\n\n```javascript\nvar smtpTransport = nodemailer.createTransport(\"SMTP\",{\n auth: {\n user: \"gmail.user@gmail.com\", // service is detected from the username\n pass: \"userpass\"\n }\n});\n```\n\n## E-mail message fields\n\nThe following are the possible fields of an e-mail message:\n\n - **from** - The e-mail address of the sender. All e-mail addresses can be plain `sender@server.com` or formatted `Sender Name `\n - **to** - Comma separated list or an array of recipients e-mail addresses that will appear on the `To:` field\n - **cc** - Comma separated list or an array of recipients e-mail addresses that will appear on the `Cc:` field\n - **bcc** - Comma separated list or an array of recipients e-mail addresses that will appear on the `Bcc:` field\n - **replyTo** - An e-mail address that will appear on the `Reply-To:` field\n - **inReplyTo** - The message-id this message is replying\n - **references** - Message-id list\n - **subject** - The subject of the e-mail\n - **text** - The plaintext version of the message\n - **html** - The HTML version of the message\n - **generateTextFromHTML** - if set to true uses HTML to generate plain text body part from the HTML if the text is not defined\n - **headers** - An object of additional header fields `{\"X-Key-Name\": \"key value\"}` (NB! values are passed as is, you should do your own encoding to 7bit if needed)\n - **attachments** - An array of attachment objects.\n - **alternatives** - An array of alternative text contents (in addition to text and html parts)\n - **envelope** - optional SMTP envelope, if auto generated envelope is not suitable\n - **messageId** - optional Message-Id value, random value will be generated if not set. Set to false to omit the Message-Id header\n - **date** - optional Date value, current UTC string will be used if not set\n - **encoding** - optional transfer encoding for the textual parts (defaults to \"quoted-printable\")\n - **charset** - optional output character set for the textual parts (defaults to \"utf-8\")\n\nAll text fields (e-mail addresses, plaintext body, html body) use UTF-8 as the encoding.\nAttachments are streamed as binary.\n\nExample:\n\n```javascript\nvar transport = nodemailer.createTransport(\"Sendmail\");\n\nvar mailOptions = {\n from: \"me@tr.ee\",\n to: \"me@tr.ee\",\n subject: \"Hello world!\",\n text: \"Plaintext body\"\n}\n\ntransport.sendMail(mailOptions);\n```\n\n### SendGrid support\n\nNodemailer supports SendGrid [SMTP API](http://docs.sendgrid.com/documentation/api/smtp-api/) out of the box - you can\nuse objects as header values and these are automatically JSONized (and mime encoded if needed).\n\n```javascript\nvar mailOptions = {\n ...,\n headers: {\n 'X-SMTPAPI': {\n category : \"newuser\",\n sub:{\n \"%name%\": [\"Žiguli Õllepruul\"]\n }\n }\n },\n subject: \"Hello, %name%\"\n}\n```\n\nThis also applies to any other service that expects a JSON string as a header value for specified key.\n\n### Generate Text from HTML\n\nIf `generateTextFromHTML` option is set to true, then HTML contents of the mail is automatically converted\nto plaintext format when plaintext content is empty or missing.\n\nFor example\n\n```javascript\nmailOptions = {\n ...,\n generateTextFromHTML: true,\n html: '

Hello world

How are you?',\n // text: '' // no text part\n}\n```\n\nis automatically converted in the backround by Nodemailer to:\n\n```javascript\nmailOptions = {\n ...,\n // source html:\n html: '

Hello world

How are you?',\n // automatically generated plaintext message:\n text: \"Hello world\\n\"+\n \"===========\\n\"+\n \"\\n\"+\n \"**How** are you?\"\n}\n```\n\nAs you can see the output syntax for `generateTextFromHTML` looks similar to markdown, and that\nis exactly the case here - Nodemailer includes a simple HTML to markdown converter. But don't\nexpect too much from it, it's not full featured or perfect, just some regexes here and there.\n\n### Attachment fields\n\nAttachment object consists of the following properties:\n\n * **fileName** - filename to be reported as the name of the attached file, use of unicode is allowed (except when using Amazon SES which doesn't like it)\n * **cid** - optional content id for using inline images in HTML message source\n * **contents** - String or a Buffer contents for the attachment\n * **filePath** - path to a file or an URL if you want to stream the file instead of including it (better for larger attachments)\n * **streamSource** - Stream object for arbitrary binary streams if you want to stream the contents (needs to support *pause*/*resume*)\n * **contentType** - optional content type for the attachment, if not set will be derived from the `fileName` property\n * **contentDisposition** - optional content disposition type for the attachment, defaults to \"attachment\"\n\nOne of `contents`, `filePath` or `streamSource` must be specified, if none is\npresent, the attachment will be discarded. Other fields are optional.\n\nAttachments can be added as many as you want.\n\n```javascript\nvar mailOptions = {\n ...\n attachments: [\n { // utf-8 string as an attachment\n fileName: \"text1.txt\",\n contents: \"hello world!\"\n },\n { // binary buffer as an attachment\n fileName: \"text2.txt\",\n contents: new Buffer(\"hello world!\",\"utf-8\")\n },\n { // file on disk as an attachment\n fileName: \"text3.txt\",\n filePath: \"/path/to/file.txt\" // stream this file\n },\n { // fileName and content type is derived from filePath\n filePath: \"/path/to/file.txt\"\n },\n { // stream as an attachment\n fileName: \"text4.txt\",\n streamSource: fs.createReadStream(\"file.txt\")\n },\n { // define custom content type for the attachment\n fileName: \"text.bin\",\n contents: \"hello world!\",\n contentType: \"text/plain\"\n },\n { // use URL as an attachment\n fileName: \"license.txt\",\n filePath: \"https://raw.github.com/andris9/Nodemailer/master/LICENSE\"\n }\n ]\n}\n```\n\n### Alternative fields\n\nIn addition to text and HTML, any kind of data can be inserted as an alternative content of the main body - for example a word processing document with the same text as in the HTML field. It is the job of the e-mail client to select and show the best fitting alternative to the reader.\n\nAttahcment object consists of the following properties:\n\n * **contents** - String or a Buffer contents for the attachment\n * **contentType** - optional content type for the attachment, if not set will be set to \"application/octet-stream\"\n * **contentEncoding** - optional value of how the data is encoded, defaults to \"base64\"\n\nIf `contents` is empty, the alternative will be discarded. Other fields are optional.\n\n**Usage example:**\n\n```javascript\nvar mailOptions = {\n ...\n html: \"Hello world!\",\n alternatives: [\n {\n contentType: \"text/x-web-markdown\",\n contents: \"**Hello world!**\"\n }\n ]\n}\n```\nIf the receiving e-mail client can render messages in Markdown syntax as well, it could prefer\nto display this alternative as the main content of the message instead of the html part.\n\nAlternatives can be added as many as you want.\n\n### Address Formatting\n\nAll the e-mail addresses can be plain e-mail address\n\n```\nfoobar@blurdybloop.com\n```\n\nor with formatted name (includes unicode support)\n\n```\n\"Ðоде Майлер\" \n```\n\nTo, Cc and Bcc fields accept comma separated list of e-mails or an array of\nemails or an array of comma separated list of e-mails - use it as you like.\nFormatting can be mixed.\n\n```\n...,\nto: 'foobar@blurdybloop.com, \"Ðоде Майлер\" , \"Name, User\" ',\ncc: ['foobar@blurdybloop.com', '\"Ðоде Майлер\" , \"Name, User\" ']\n...\n```\n\nYou can even use unicode domain and user names, these are automatically converted\nto the supported form\n\n```\n\"Unicode Domain\" \n```\n\n### SMTP envelope\n\nSMTP envelope is usually auto generated from `from`, `to`, `cc` and `bcc` fields but\nif for some reason you want to specify it yourself, you can do it with `envelope` property.\n\n`envelope` is an object with the following params: `from`, `to`, `cc` and `bcc` just like\nwith regular mail options. You can also use the regular address format, unicode domains etc.\n\n```javascript\nmailOptions = {\n ...,\n from: \"mailer@kreata.ee\",\n to: \"daemon@kreata.ee\",\n envelope: {\n from: \"Daemon \",\n to: \"mailer@kreata.ee, Mailer \"\n }\n}\n```\n\nThe envelope only applies when using SMTP or sendmail, setting envelope has no effect with SES.\n\n### Using Embedded Images\n\nAttachments can be used as embedded images in the HTML body. To use this\nfeature, you need to set additional property of the attachment - `cid` (unique\nidentifier of the file) which is a reference to the attachment file. The same\n`cid` value must be used as the image URL in HTML (using `cid:` as the URL\nprotocol, see example below).\n\n**NB!** the cid value should be as unique as possible!\n\n```javascript\nvar mailOptions = {\n ...\n html: \"Embedded image: \",\n attachments: [{\n filename: \"image.png\",\n filePath: \"/path/to/file\",\n cid: \"unique@kreata.ee\" //same cid value as in the html img src\n }]\n}\n```\n\n**Automatic embedding images**\n\nIf you want to convert images in the HTML to embedded images automatically, you can\nset mail option `forceEmbeddedImages` to true. In this case all images in\nthe HTML that are either using an absolute URL (http://...) or absolute file path\n(/path/to/file) are replaced with embedded attachments.\n\nFor example when using this code\n\n```javascript\nvar mailOptions = {\n forceEmbeddedImages: true\n html: 'Embedded image: '\n};\n```\n\nThe image linked is fetched and added automatically as an attachment and the url\nin the HTML is replaced automatically with a proper `cid:` string.\n\n## Return callback\n\nReturn callback gets two parameters\n\n * **error** - an error object if the message failed\n * **responseStatus** - an object with some information about the status on success\n * **responseStatus.messageId** - message ID used with the message\n\nExample:\n\n```javascript\nnodemailer.sendMail(mailOptions, function(error, responseStatus){\n if(!error){\n console.log(responseStatus.message); // response from the server\n console.log(responseStatus.messageId); // Message-ID value used\n }\n});\n```\n\n**NB!** Message-ID used might not be the same that reaches recipients inbox since some providers (like **SES**) may change the value.\n\n## Command line usage\n\n**NB!** Command line usage was removed from v0.4\n\n## Tests\n\nRun the tests with npm in Nodemailer's directory\n\n```\nnpm test\n```\n\nThere aren't currently many tests for Nodemailer but there are a lot of tests\nin the modules that are used to generate the raw e-mail body and to use the\nSMTP client connection.\n\n## Tweaking\n\nNodemailer in itself is actually more like a wrapper for my other modules\n[mailcomposer](https://github.com/andris9/mailcomposer) for composing the raw message stream\nand [simplesmtp](https://github.com/andris9/simplesmtp) for delivering it, by providing an\nunified API. If there's some problems with particular parts of the\nmessage composing/sending process you should look at the appropriate module.\n\n## License\n\n**Nodemailer** is licensed under [MIT license](https://github.com/andris9/Nodemailer/blob/master/LICENSE). Basically you can do whatever you want to with it.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/andris9/nodemailer/issues" - }, - "_id": "nodemailer@0.4.4", - "dist": { - "shasum": "46dfe849c8d22490de6331f19e0854ce6002bb69" - }, - "_from": "nodemailer@0.4.4", - "_resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-0.4.4.tgz" -} diff --git a/api/node_modules/nodemailer/test/nodemailer.js b/api/node_modules/nodemailer/test/nodemailer.js deleted file mode 100644 index 2a7a8c3f640..00000000000 --- a/api/node_modules/nodemailer/test/nodemailer.js +++ /dev/null @@ -1,216 +0,0 @@ -var testCase = require('nodeunit').testCase, - nodemailer = require("../lib/nodemailer"), - stripHTML = require("../lib/helpers").stripHTML; - -exports["General tests"] = { - - "Create a new Nodemailer object": function(test){ - // this is more like a stub here - var mail = new nodemailer.Nodemailer(); - test.done(); - }, - - "stripHTML": function(test){ - - var html = "Title

Tere »

  • Test
", - output = "Tere »\n======\n\n * Test"; - - test.equal(stripHTML(html).trim(), output); - test.done(); - }, - - "generate XOAuthToken": function(test){ - nodemailer.createXOAuthGenerator({ - user: "test.nodemailer@gmail.com", - consumerKey: "anonymous", // optional - consumerSecret: "anonymous", // optional - token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM", - tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c", - timestamp: "1332499914", - nonce: "3595015741981970681" - }).generate(function(err, token){ - test.equal(token, "R0VUIGh0dHBzOi8vbWFpbC5nb29nbGUuY29tL21haWwvYi90ZXN0Lm5vZGVtYWlsZXJAZ21haWwuY29tL3NtdHAvIG9hdXRoX2NvbnN1bWVyX2tleT0iYW5vbnltb3VzIixvYXV0aF9ub25jZT0iMzU5NTAxNTc0MTk4MTk3MDY4MSIsb2F1dGhfc2lnbmF0dXJlPSJZZkt4QlJHZnRkMUx0bk5LMXM5d25QUjM5UnclM0QiLG9hdXRoX3NpZ25hdHVyZV9tZXRob2Q9IkhNQUMtU0hBMSIsb2F1dGhfdGltZXN0YW1wPSIxMzMyNDk5OTE0IixvYXV0aF90b2tlbj0iMSUyRk9fSGdvTzRoMnVPVWZwdXMwVi0tN215Z0lDWHJRUTBaYWpCM1pINTJLcU0iLG9hdXRoX3ZlcnNpb249IjEuMCI="); - test.done(); - }); - - }, - - "generate XOAuthToken with defaults": function(test){ - nodemailer.createXOAuthGenerator({ - user: "test.nodemailer@gmail.com", - token: "1/O_HgoO4h2uOUfpus0V--7mygICXrQQ0ZajB3ZH52KqM", - tokenSecret: "_mUBkIwNPnfQBUIWrJrpXJ0c", - timestamp: "1332499914", - nonce: "3595015741981970681" - }).generate(function(err, token){ - test.equal(token, "R0VUIGh0dHBzOi8vbWFpbC5nb29nbGUuY29tL21haWwvYi90ZXN0Lm5vZGVtYWlsZXJAZ21haWwuY29tL3NtdHAvIG9hdXRoX2NvbnN1bWVyX2tleT0iYW5vbnltb3VzIixvYXV0aF9ub25jZT0iMzU5NTAxNTc0MTk4MTk3MDY4MSIsb2F1dGhfc2lnbmF0dXJlPSJZZkt4QlJHZnRkMUx0bk5LMXM5d25QUjM5UnclM0QiLG9hdXRoX3NpZ25hdHVyZV9tZXRob2Q9IkhNQUMtU0hBMSIsb2F1dGhfdGltZXN0YW1wPSIxMzMyNDk5OTE0IixvYXV0aF90b2tlbj0iMSUyRk9fSGdvTzRoMnVPVWZwdXMwVi0tN215Z0lDWHJRUTBaYWpCM1pINTJLcU0iLG9hdXRoX3ZlcnNpb249IjEuMCI="); - test.done(); - }); - - }, - - "Use default Message-Id value": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = {}; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - var regex = "^Message\\-Id:\\s*<[0-9\.a-fA-F]+@"+nodemailer.X_MAILER_NAME.replace(/([\(\)\\\.\[\]\-\?\:\!\{\}])/g, "\\$1")+">$"; - test.ok(response.message.match(new RegExp(regex, "m"))); - test.done(); - }) - }, - - "Use custom Message-Id value": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - messageId: "ABCDEF" - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.ok(response.message.match(/Message\-Id:\s*/)); - // default not present - var regex = "^Message\\-Id:\\s*<[0-9\.a-fA-F]+@"+nodemailer.X_MAILER_NAME.replace(/([\(\)\\\.\[\]\-\?\:\!\{\}])/g, "\\$1")+">$"; - test.ok(!response.message.match(new RegExp(regex, "m"))); - test.done(); - }) - }, - - "Use custom Date value": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - date: "Fri, 5 Nov 2012 09:41:00 -0800" - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.ok(response.message.match(/Date:\s*Fri, 5 Nov 2012 09:41:00 -0800/)); - // default not present - test.ok(!response.message.match(/^Date:\s*[0-9\s:a-yA-Y]+\s+GMT$/m)); - test.done(); - }) - }, - - "Use In-Reply-To": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - inReplyTo: "abc" - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.ok(response.message.match(/^In\-Reply\-To:\s*$/m)); - test.done(); - }) - }, - - "Use References": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - references: ["abc def ", "jkl"] - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.ok(response.message.match(/^References:\s* $/m)); - test.done(); - }) - }, - - "Skip Message-Id value": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - messageId: false - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.ok(!response.message.match(/Message\-Id:/i)); - test.done(); - }); - }, - - "Use custom envelope": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - from: "sender1@tr.ee", - to: "receiver1@tr.ee", - envelope: { - from: "sender2@tr.ee", - to: "receiver2@tr.ee", - } - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.deepEqual(response.envelope, {from:'sender2@tr.ee',to: [ 'receiver2@tr.ee' ],stamp: 'Postage paid, Par Avion'}) - test.done(); - }) - }, - - "Use default envelope": function(test){ - var transport = nodemailer.createTransport("Stub"), - mailOptions = { - from: "sender1@tr.ee", - to: "receiver1@tr.ee" - }; - - transport.sendMail(mailOptions, function(error, response){ - test.ifError(error); - test.deepEqual(response.envelope, {from:'sender1@tr.ee',to: [ 'receiver1@tr.ee' ],stamp: 'Postage paid, Par Avion'}) - test.done(); - }) - } -}; - -exports["Transport close"] = { - "SMTP - Callback in transport.close": function(test){ - var transport = nodemailer.createTransport("SMTP", {}); - transport.close(function(){ - test.ok(true); - test.done(); - }); - }, - - "SMTP - No callback in transport.close": function(test){ - var transport = nodemailer.createTransport("SMTP", {}); - transport.close(); - process.nextTick(function(){ - test.ok(true); - test.done(); - }); - }, - "Sendmail - Callback in transport.close": function(test){ - var transport = nodemailer.createTransport("Sendmail", {}); - transport.close(function(){ - test.ok(true); - test.done(); - }); - }, - - "Sendmail - No callback in transport.close": function(test){ - var transport = nodemailer.createTransport("Sendmail", {}); - transport.close(); - process.nextTick(function(){ - test.ok(true); - test.done(); - }); - }, - "SES - Callback in transport.close": function(test){ - var transport = nodemailer.createTransport("SES", {}); - transport.close(function(){ - test.ok(true); - test.done(); - }); - }, - - "SES - No callback in transport.close": function(test){ - var transport = nodemailer.createTransport("SES", {}); - transport.close(); - process.nextTick(function(){ - test.ok(true); - test.done(); - }); - } -}; diff --git a/api/node_modules/request/LICENSE b/api/node_modules/request/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/api/node_modules/request/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/api/node_modules/request/README.md b/api/node_modules/request/README.md deleted file mode 100644 index eca6a5ab302..00000000000 --- a/api/node_modules/request/README.md +++ /dev/null @@ -1,344 +0,0 @@ -# Request -- Simplified HTTP request method - -## Install - -
-  npm install request
-
- -Or from source: - -
-  git clone git://github.com/mikeal/request.git 
-  cd request
-  npm link
-
- -## Super simple to use - -Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default. - -```javascript -var request = require('request'); -request('http://www.google.com', function (error, response, body) { - if (!error && response.statusCode == 200) { - console.log(body) // Print the google web page. - } -}) -``` - -## Streaming - -You can stream any response to a file stream. - -```javascript -request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) -``` - -You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. - -```javascript -fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) -``` - -Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. - -```javascript -request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')) -``` - -Now let's get fancy. - -```javascript -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - if (req.method === 'PUT') { - req.pipe(request.put('http://mysite.com/doodle.png')) - } else if (req.method === 'GET' || req.method === 'HEAD') { - request.get('http://mysite.com/doodle.png').pipe(resp) - } - } -}) -``` - -You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do: - -```javascript -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - var x = request('http://mysite.com/doodle.png') - req.pipe(x) - x.pipe(resp) - } -}) -``` - -And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :) - -```javascript -req.pipe(request('http://mysite.com/doodle.png')).pipe(resp) -``` - -Also, none of this new functionality conflicts with requests previous features, it just expands them. - -```javascript -var r = request.defaults({'proxy':'http://localproxy.com'}) - -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - r.get('http://google.com/doodle.png').pipe(resp) - } -}) -``` -You can still use intermediate proxies, the requests will still follow HTTP forwards, etc. - -## Forms - -`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API. - -Url encoded forms are simple - -```javascript -request.post('http://service.com/upload', {form:{key:'value'}}) -// or -request.post('http://service.com/upload').form({key:'value'}) -``` - -For `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you. - -```javascript -var r = request.post('http://service.com/upload') -var form = r.form() -form.append('my_field', 'my_value') -form.append('my_buffer', new Buffer([1, 2, 3])) -form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')) -form.append('remote_file', request('http://google.com/doodle.png')) -``` - -## HTTP Authentication - -```javascript -request.auth('username', 'password', false).get('http://some.server.com/'); -// or -request.get('http://some.server.com/', { - 'auth': { - 'user': 'username', - 'pass': 'password', - 'sendImmediately': false - } -}); -``` - -If passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`. - -`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method). - -Digest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail). - -## OAuth Signing - -```javascript -// Twitter OAuth -var qs = require('querystring') - , oauth = - { callback: 'http://mysite.com/callback/' - , consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - } - , url = 'https://api.twitter.com/oauth/request_token' - ; -request.post({url:url, oauth:oauth}, function (e, r, body) { - // Ideally, you would take the body in the response - // and construct a URL that a user clicks on (like a sign in button). - // The verifier is only available in the response after a user has - // verified with twitter that they are authorizing your app. - var access_token = qs.parse(body) - , oauth = - { consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - , token: access_token.oauth_token - , verifier: access_token.oauth_verifier - } - , url = 'https://api.twitter.com/oauth/access_token' - ; - request.post({url:url, oauth:oauth}, function (e, r, body) { - var perm_token = qs.parse(body) - , oauth = - { consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - , token: perm_token.oauth_token - , token_secret: perm_token.oauth_token_secret - } - , url = 'https://api.twitter.com/1/users/show.json?' - , params = - { screen_name: perm_token.screen_name - , user_id: perm_token.user_id - } - ; - url += qs.stringify(params) - request.get({url:url, oauth:oauth, json:true}, function (e, r, user) { - console.log(user) - }) - }) -}) -``` - - - -### request(options, callback) - -The first argument can be either a url or an options object. The only required option is uri, all others are optional. - -* `uri` || `url` - fully qualified uri or a parsed url object from url.parse() -* `qs` - object containing querystring values to be appended to the uri -* `method` - http method, defaults to GET -* `headers` - http headers, defaults to {} -* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string. -* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request. -* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above. -* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json. -* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. -* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. -* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. -* `maxRedirects` - the maximum number of redirects to follow, defaults to 10. -* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. -* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets. -* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool. -* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request -* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri. -* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above. -* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example). -* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. -* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section) -* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services) -* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options. -* `localAddress` - Local interface to bind for network connections. - - -The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer. - -## Convenience methods - -There are also shorthand methods for different HTTP METHODs and some other conveniences. - -### request.defaults(options) - -This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it. - -### request.put - -Same as request() but defaults to `method: "PUT"`. - -```javascript -request.put(url) -``` - -### request.patch - -Same as request() but defaults to `method: "PATCH"`. - -```javascript -request.patch(url) -``` - -### request.post - -Same as request() but defaults to `method: "POST"`. - -```javascript -request.post(url) -``` - -### request.head - -Same as request() but defaults to `method: "HEAD"`. - -```javascript -request.head(url) -``` - -### request.del - -Same as request() but defaults to `method: "DELETE"`. - -```javascript -request.del(url) -``` - -### request.get - -Alias to normal request method for uniformity. - -```javascript -request.get(url) -``` -### request.cookie - -Function that creates a new cookie. - -```javascript -request.cookie('cookie_string_here') -``` -### request.jar - -Function that creates a new cookie jar. - -```javascript -request.jar() -``` - - -## Examples: - -```javascript - var request = require('request') - , rand = Math.floor(Math.random()*100000000).toString() - ; - request( - { method: 'PUT' - , uri: 'http://mikeal.iriscouch.com/testjs/' + rand - , multipart: - [ { 'content-type': 'application/json' - , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) - } - , { body: 'I am an attachment' } - ] - } - , function (error, response, body) { - if(response.statusCode == 201){ - console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) - } else { - console.log('error: '+ response.statusCode) - console.log(body) - } - } - ) -``` -Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent). - -```javascript -var request = request.defaults({jar: false}) -request('http://www.google.com', function () { - request('http://images.google.com') -}) -``` - -If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option: - -```javascript -var j = request.jar() -var request = request.defaults({jar:j}) -request('http://www.google.com', function () { - request('http://images.google.com') -}) -``` -OR - -```javascript -var j = request.jar() -var cookie = request.cookie('your_cookie_here') -j.add(cookie) -request({url: 'http://www.google.com', jar: j}, function () { - request('http://images.google.com') -}) -``` diff --git a/api/node_modules/request/aws.js b/api/node_modules/request/aws.js deleted file mode 100644 index 4d8d95075bb..00000000000 --- a/api/node_modules/request/aws.js +++ /dev/null @@ -1,191 +0,0 @@ - -/*! - * knox - auth - * Copyright(c) 2010 LearnBoost - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var crypto = require('crypto') - , parse = require('url').parse - ; - -/** - * Valid keys. - */ - -var keys = - [ 'acl' - , 'location' - , 'logging' - , 'notification' - , 'partNumber' - , 'policy' - , 'requestPayment' - , 'torrent' - , 'uploadId' - , 'uploads' - , 'versionId' - , 'versioning' - , 'versions' - , 'website' - ] - -/** - * Return an "Authorization" header value with the given `options` - * in the form of "AWS :" - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.authorization = function(options){ - return 'AWS ' + options.key + ':' + exports.sign(options) -} - -/** - * Simple HMAC-SHA1 Wrapper - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.hmacSha1 = function(options){ - return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') -} - -/** - * Create a base64 sha1 HMAC for `options`. - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.sign = function(options){ - options.message = exports.stringToSign(options) - return exports.hmacSha1(options) -} - -/** - * Create a base64 sha1 HMAC for `options`. - * - * Specifically to be used with S3 presigned URLs - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.signQuery = function(options){ - options.message = exports.queryStringToSign(options) - return exports.hmacSha1(options) -} - -/** - * Return a string for sign() with the given `options`. - * - * Spec: - * - * \n - * \n - * \n - * \n - * [headers\n] - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.stringToSign = function(options){ - var headers = options.amazonHeaders || '' - if (headers) headers += '\n' - var r = - [ options.verb - , options.md5 - , options.contentType - , options.date.toUTCString() - , headers + options.resource - ] - return r.join('\n') -} - -/** - * Return a string for sign() with the given `options`, but is meant exclusively - * for S3 presigned URLs - * - * Spec: - * - * \n - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -exports.queryStringToSign = function(options){ - return 'GET\n\n\n' + options.date + '\n' + options.resource -}; - -/** - * Perform the following: - * - * - ignore non-amazon headers - * - lowercase fields - * - sort lexicographically - * - trim whitespace between ":" - * - join with newline - * - * @param {Object} headers - * @return {String} - * @api private - */ - -exports.canonicalizeHeaders = function(headers){ - var buf = [] - , fields = Object.keys(headers) - ; - for (var i = 0, len = fields.length; i < len; ++i) { - var field = fields[i] - , val = headers[field] - , field = field.toLowerCase() - ; - if (0 !== field.indexOf('x-amz')) continue - buf.push(field + ':' + val) - } - return buf.sort().join('\n') -}; - -/** - * Perform the following: - * - * - ignore non sub-resources - * - sort lexicographically - * - * @param {String} resource - * @return {String} - * @api private - */ - -exports.canonicalizeResource = function(resource){ - var url = parse(resource, true) - , path = url.pathname - , buf = [] - ; - - Object.keys(url.query).forEach(function(key){ - if (!~keys.indexOf(key)) return - var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) - buf.push(key + val) - }) - - return path + (buf.length ? '?' + buf.sort().join('&') : '') -}; diff --git a/api/node_modules/request/forever.js b/api/node_modules/request/forever.js deleted file mode 100644 index 1e1d4b9cfc6..00000000000 --- a/api/node_modules/request/forever.js +++ /dev/null @@ -1,103 +0,0 @@ -module.exports = ForeverAgent -ForeverAgent.SSL = ForeverAgentSSL - -var util = require('util') - , Agent = require('http').Agent - , net = require('net') - , tls = require('tls') - , AgentSSL = require('https').Agent - -function ForeverAgent(options) { - var self = this - self.options = options || {} - self.requests = {} - self.sockets = {} - self.freeSockets = {} - self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets - self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets - self.on('free', function(socket, host, port) { - var name = host + ':' + port - if (self.requests[name] && self.requests[name].length) { - self.requests[name].shift().onSocket(socket) - } else if (self.sockets[name].length < self.minSockets) { - if (!self.freeSockets[name]) self.freeSockets[name] = [] - self.freeSockets[name].push(socket) - - // if an error happens while we don't use the socket anyway, meh, throw the socket away - function onIdleError() { - socket.destroy() - } - socket._onIdleError = onIdleError - socket.on('error', onIdleError) - } else { - // If there are no pending requests just destroy the - // socket and it will get removed from the pool. This - // gets us out of timeout issues and allows us to - // default to Connection:keep-alive. - socket.destroy() - } - }) - -} -util.inherits(ForeverAgent, Agent) - -ForeverAgent.defaultMinSockets = 5 - - -ForeverAgent.prototype.createConnection = net.createConnection -ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest -ForeverAgent.prototype.addRequest = function(req, host, port) { - var name = host + ':' + port - if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { - var idleSocket = this.freeSockets[name].pop() - idleSocket.removeListener('error', idleSocket._onIdleError) - delete idleSocket._onIdleError - req._reusedSocket = true - req.onSocket(idleSocket) - } else { - this.addRequestNoreuse(req, host, port) - } -} - -ForeverAgent.prototype.removeSocket = function(s, name, host, port) { - if (this.sockets[name]) { - var index = this.sockets[name].indexOf(s) - if (index !== -1) { - this.sockets[name].splice(index, 1) - } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name] - delete this.requests[name] - } - - if (this.freeSockets[name]) { - var index = this.freeSockets[name].indexOf(s) - if (index !== -1) { - this.freeSockets[name].splice(index, 1) - if (this.freeSockets[name].length === 0) { - delete this.freeSockets[name] - } - } - } - - if (this.requests[name] && this.requests[name].length) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(name, host, port).emit('free') - } -} - -function ForeverAgentSSL (options) { - ForeverAgent.call(this, options) -} -util.inherits(ForeverAgentSSL, ForeverAgent) - -ForeverAgentSSL.prototype.createConnection = createConnectionSSL -ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest - -function createConnectionSSL (port, host, options) { - options.port = port - options.host = host - return tls.connect(options) -} diff --git a/api/node_modules/request/index.js b/api/node_modules/request/index.js deleted file mode 100644 index 22707be7087..00000000000 --- a/api/node_modules/request/index.js +++ /dev/null @@ -1,1365 +0,0 @@ -// Copyright 2010-2012 Mikeal Rogers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -var http = require('http') - , https = false - , tls = false - , url = require('url') - , util = require('util') - , stream = require('stream') - , qs = require('qs') - , querystring = require('querystring') - , crypto = require('crypto') - - , oauth = require('oauth-sign') - , hawk = require('hawk') - , aws = require('aws-sign') - , httpSignature = require('http-signature') - , uuid = require('node-uuid') - , mime = require('mime') - , tunnel = require('tunnel-agent') - , safeStringify = require('json-stringify-safe') - - , ForeverAgent = require('forever-agent') - , FormData = require('form-data') - - , Cookie = require('cookie-jar') - , CookieJar = Cookie.Jar - , cookieJar = new CookieJar - ; - -try { - https = require('https') -} catch (e) {} - -try { - tls = require('tls') -} catch (e) {} - -var debug -if (/\brequest\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - console.error('REQUEST %s', util.format.apply(util, arguments)) - } -} else { - debug = function() {} -} - -function toBase64 (str) { - return (new Buffer(str || "", "ascii")).toString("base64") -} - -function md5 (str) { - return crypto.createHash('md5').update(str).digest('hex') -} - -// Hacky fix for pre-0.4.4 https -if (https && !https.Agent) { - https.Agent = function (options) { - http.Agent.call(this, options) - } - util.inherits(https.Agent, http.Agent) - https.Agent.prototype._getConnection = function (host, port, cb) { - var s = tls.connect(port, host, this.options, function () { - // do other checks here? - if (cb) cb() - }) - return s - } -} - -function isReadStream (rs) { - if (rs.readable && rs.path && rs.mode) { - return true - } -} - -function copy (obj) { - var o = {} - Object.keys(obj).forEach(function (i) { - o[i] = obj[i] - }) - return o -} - -var isUrl = /^https?:/ - -var globalPool = {} - -function Request (options) { - stream.Stream.call(this) - this.readable = true - this.writable = true - - if (typeof options === 'string') { - options = {uri:options} - } - - var reserved = Object.keys(Request.prototype) - for (var i in options) { - if (reserved.indexOf(i) === -1) { - this[i] = options[i] - } else { - if (typeof options[i] === 'function') { - delete options[i] - } - } - } - - if (options.method) { - this.explicitMethod = true - } - - this.init(options) -} -util.inherits(Request, stream.Stream) -Request.prototype.init = function (options) { - // init() contains all the code to setup the request object. - // the actual outgoing request is not started until start() is called - // this function is called from both the constructor and on redirect. - var self = this - if (!options) options = {} - - if (!self.method) self.method = options.method || 'GET' - self.localAddress = options.localAddress - - debug(options) - if (!self.pool && self.pool !== false) self.pool = globalPool - self.dests = self.dests || [] - self.__isRequestRequest = true - - // Protect against double callback - if (!self._callback && self.callback) { - self._callback = self.callback - self.callback = function () { - if (self._callbackCalled) return // Print a warning maybe? - self._callbackCalled = true - self._callback.apply(self, arguments) - } - self.on('error', self.callback.bind()) - self.on('complete', self.callback.bind(self, null)) - } - - if (self.url) { - // People use this property instead all the time so why not just support it. - self.uri = self.url - delete self.url - } - - if (!self.uri) { - // this will throw if unhandled but is handleable when in a redirect - return self.emit('error', new Error("options.uri is a required argument")) - } else { - if (typeof self.uri == "string") self.uri = url.parse(self.uri) - } - - if (self.strictSSL === false) { - self.rejectUnauthorized = false - } - - if (self.proxy) { - if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) - - // do the HTTP CONNECT dance using koichik/node-tunnel - if (http.globalAgent && self.uri.protocol === "https:") { - var tunnelFn = self.proxy.protocol === "http:" - ? tunnel.httpsOverHttp : tunnel.httpsOverHttps - - var tunnelOptions = { proxy: { host: self.proxy.hostname - , port: +self.proxy.port - , proxyAuth: self.proxy.auth - , headers: { Host: self.uri.hostname + ':' + - (self.uri.port || self.uri.protocol === 'https:' ? 443 : 80) }} - , rejectUnauthorized: self.rejectUnauthorized - , ca: this.ca } - - self.agent = tunnelFn(tunnelOptions) - self.tunnel = true - } - } - - if (!self.uri.host || !self.uri.pathname) { - // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar - // Detect and reject it as soon as possible - var faultyUri = url.format(self.uri) - var message = 'Invalid URI "' + faultyUri + '"' - if (Object.keys(options).length === 0) { - // No option ? This can be the sign of a redirect - // As this is a case where the user cannot do anything (he didn't call request directly with this URL) - // he should be warned that it can be caused by a redirection (can save some hair) - message += '. This can be caused by a crappy redirection.' - } - self.emit('error', new Error(message)) - return // This error was fatal - } - - self._redirectsFollowed = self._redirectsFollowed || 0 - self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 - self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true - self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false - if (self.followRedirect || self.followAllRedirects) - self.redirects = self.redirects || [] - - self.headers = self.headers ? copy(self.headers) : {} - - self.setHost = false - if (!(self.headers.host || self.headers.Host)) { - self.headers.host = self.uri.hostname - if (self.uri.port) { - if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && - !(self.uri.port === 443 && self.uri.protocol === 'https:') ) - self.headers.host += (':'+self.uri.port) - } - self.setHost = true - } - - self.jar(self._jar || options.jar) - - if (!self.uri.pathname) {self.uri.pathname = '/'} - if (!self.uri.port) { - if (self.uri.protocol == 'http:') {self.uri.port = 80} - else if (self.uri.protocol == 'https:') {self.uri.port = 443} - } - - if (self.proxy && !self.tunnel) { - self.port = self.proxy.port - self.host = self.proxy.hostname - } else { - self.port = self.uri.port - self.host = self.uri.hostname - } - - self.clientErrorHandler = function (error) { - if (self._aborted) return - - if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' - && self.agent.addRequestNoreuse) { - self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } - self.start() - self.req.end() - return - } - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - self.emit('error', error) - } - - self._parserErrorHandler = function (error) { - if (this.res) { - if (this.res.request) { - this.res.request.emit('error', error) - } else { - this.res.emit('error', error) - } - } else { - this._httpMessage.emit('error', error) - } - } - - if (options.form) { - self.form(options.form) - } - - if (options.qs) self.qs(options.qs) - - if (self.uri.path) { - self.path = self.uri.path - } else { - self.path = self.uri.pathname + (self.uri.search || "") - } - - if (self.path.length === 0) self.path = '/' - - - // Auth must happen last in case signing is dependent on other headers - if (options.oauth) { - self.oauth(options.oauth) - } - - if (options.aws) { - self.aws(options.aws) - } - - if (options.hawk) { - self.hawk(options.hawk) - } - - if (options.httpSignature) { - self.httpSignature(options.httpSignature) - } - - if (options.auth) { - self.auth( - (options.auth.user==="") ? options.auth.user : (options.auth.user || options.auth.username ), - options.auth.pass || options.auth.password, - options.auth.sendImmediately) - } - - if (self.uri.auth && !self.headers.authorization) { - var authPieces = self.uri.auth.split(':').map(function(item){ return querystring.unescape(item) }) - self.auth(authPieces[0], authPieces.slice(1).join(':'), true) - } - if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) { - self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return querystring.unescape(item)}).join(':')) - } - - - if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - - if (options.json) { - self.json(options.json) - } else if (options.multipart) { - self.boundary = uuid() - self.multipart(options.multipart) - } - - if (self.body) { - var length = 0 - if (!Buffer.isBuffer(self.body)) { - if (Array.isArray(self.body)) { - for (var i = 0; i < self.body.length; i++) { - length += self.body[i].length - } - } else { - self.body = new Buffer(self.body) - length = self.body.length - } - } else { - length = self.body.length - } - if (length) { - if(!self.headers['content-length'] && !self.headers['Content-Length']) - self.headers['content-length'] = length - } else { - throw new Error('Argument error, options.body.') - } - } - - var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol - , defaultModules = {'http:':http, 'https:':https} - , httpModules = self.httpModules || {} - ; - self.httpModule = httpModules[protocol] || defaultModules[protocol] - - if (!self.httpModule) return this.emit('error', new Error("Invalid protocol")) - - if (options.ca) self.ca = options.ca - - if (!self.agent) { - if (options.agentOptions) self.agentOptions = options.agentOptions - - if (options.agentClass) { - self.agentClass = options.agentClass - } else if (options.forever) { - self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL - } else { - self.agentClass = self.httpModule.Agent - } - } - - if (self.pool === false) { - self.agent = false - } else { - self.agent = self.agent || self.getAgent() - if (self.maxSockets) { - // Don't use our pooling if node has the refactored client - self.agent.maxSockets = self.maxSockets - } - if (self.pool.maxSockets) { - // Don't use our pooling if node has the refactored client - self.agent.maxSockets = self.pool.maxSockets - } - } - - self.once('pipe', function (src) { - if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.") - self.src = src - if (isReadStream(src)) { - if (!self.headers['content-type'] && !self.headers['Content-Type']) - self.headers['content-type'] = mime.lookup(src.path) - } else { - if (src.headers) { - for (var i in src.headers) { - if (!self.headers[i]) { - self.headers[i] = src.headers[i] - } - } - } - if (self._json && !self.headers['content-type'] && !self.headers['Content-Type']) - self.headers['content-type'] = 'application/json' - if (src.method && !self.explicitMethod) { - self.method = src.method - } - } - - self.on('pipe', function () { - console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") - }) - }) - - process.nextTick(function () { - if (self._aborted) return - - if (self._form) { - self.setHeaders(self._form.getHeaders()) - self._form.pipe(self) - } - if (self.body) { - if (Array.isArray(self.body)) { - self.body.forEach(function (part) { - self.write(part) - }) - } else { - self.write(self.body) - } - self.end() - } else if (self.requestBodyStream) { - console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") - self.requestBodyStream.pipe(self) - } else if (!self.src) { - if (self.method !== 'GET' && typeof self.method !== 'undefined') { - self.headers['content-length'] = 0 - } - self.end() - } - self.ntick = true - }) -} - -// Must call this when following a redirect from https to http or vice versa -// Attempts to keep everything as identical as possible, but update the -// httpModule, Tunneling agent, and/or Forever Agent in use. -Request.prototype._updateProtocol = function () { - var self = this - var protocol = self.uri.protocol - - if (protocol === 'https:') { - // previously was doing http, now doing https - // if it's https, then we might need to tunnel now. - if (self.proxy) { - self.tunnel = true - var tunnelFn = self.proxy.protocol === 'http:' - ? tunnel.httpsOverHttp : tunnel.httpsOverHttps - var tunnelOptions = { proxy: { host: self.proxy.hostname - , port: +self.proxy.port - , proxyAuth: self.proxy.auth } - , rejectUnauthorized: self.rejectUnauthorized - , ca: self.ca } - self.agent = tunnelFn(tunnelOptions) - return - } - - self.httpModule = https - switch (self.agentClass) { - case ForeverAgent: - self.agentClass = ForeverAgent.SSL - break - case http.Agent: - self.agentClass = https.Agent - break - default: - // nothing we can do. Just hope for the best. - return - } - - // if there's an agent, we need to get a new one. - if (self.agent) self.agent = self.getAgent() - - } else { - // previously was doing https, now doing http - // stop any tunneling. - if (self.tunnel) self.tunnel = false - self.httpModule = http - switch (self.agentClass) { - case ForeverAgent.SSL: - self.agentClass = ForeverAgent - break - case https.Agent: - self.agentClass = http.Agent - break - default: - // nothing we can do. just hope for the best - return - } - - // if there's an agent, then get a new one. - if (self.agent) { - self.agent = null - self.agent = self.getAgent() - } - } -} - -Request.prototype.getAgent = function () { - var Agent = this.agentClass - var options = {} - if (this.agentOptions) { - for (var i in this.agentOptions) { - options[i] = this.agentOptions[i] - } - } - if (this.ca) options.ca = this.ca - if (typeof this.rejectUnauthorized !== 'undefined') options.rejectUnauthorized = this.rejectUnauthorized - - if (this.cert && this.key) { - options.key = this.key - options.cert = this.cert - } - - var poolKey = '' - - // different types of agents are in different pools - if (Agent !== this.httpModule.Agent) { - poolKey += Agent.name - } - - if (!this.httpModule.globalAgent) { - // node 0.4.x - options.host = this.host - options.port = this.port - if (poolKey) poolKey += ':' - poolKey += this.host + ':' + this.port - } - - // ca option is only relevant if proxy or destination are https - var proxy = this.proxy - if (typeof proxy === 'string') proxy = url.parse(proxy) - var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' - if (isHttps) { - if (options.ca) { - if (poolKey) poolKey += ':' - poolKey += options.ca - } - - if (typeof options.rejectUnauthorized !== 'undefined') { - if (poolKey) poolKey += ':' - poolKey += options.rejectUnauthorized - } - - if (options.cert) - poolKey += options.cert.toString('ascii') + options.key.toString('ascii') - } - - if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) { - // not doing anything special. Use the globalAgent - return this.httpModule.globalAgent - } - - // we're using a stored agent. Make sure it's protocol-specific - poolKey = this.uri.protocol + poolKey - - // already generated an agent for this setting - if (this.pool[poolKey]) return this.pool[poolKey] - - return this.pool[poolKey] = new Agent(options) -} - -Request.prototype.start = function () { - // start() is called once we are ready to send the outgoing HTTP request. - // this is usually called on the first write(), end() or on nextTick() - var self = this - - if (self._aborted) return - - self._started = true - self.method = self.method || 'GET' - self.href = self.uri.href - - if (self.src && self.src.stat && self.src.stat.size && !self.headers['content-length'] && !self.headers['Content-Length']) { - self.headers['content-length'] = self.src.stat.size - } - if (self._aws) { - self.aws(self._aws, true) - } - - // We have a method named auth, which is completely different from the http.request - // auth option. If we don't remove it, we're gonna have a bad time. - var reqOptions = copy(self) - delete reqOptions.auth - - debug('make request', self.uri.href) - self.req = self.httpModule.request(reqOptions, self.onResponse.bind(self)) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function () { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - - // Set additional timeout on socket - in case if remote - // server freeze after sending headers - if (self.req.setTimeout) { // only works on node 0.6+ - self.req.setTimeout(self.timeout, function () { - if (self.req) { - self.req.abort() - var e = new Error("ESOCKETTIMEDOUT") - e.code = "ESOCKETTIMEDOUT" - self.emit("error", e) - } - }) - } - } - - self.req.on('error', self.clientErrorHandler) - self.req.on('drain', function() { - self.emit('drain') - }) - self.on('end', function() { - if ( self.req.connection ) self.req.connection.removeListener('error', self._parserErrorHandler) - }) - self.emit('request', self.req) -} -Request.prototype.onResponse = function (response) { - var self = this - debug('onResponse', self.uri.href, response.statusCode, response.headers) - response.on('end', function() { - debug('response end', self.uri.href, response.statusCode, response.headers) - }); - - if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) { - response.connection.once('error', self._parserErrorHandler) - } - if (self._aborted) { - debug('aborted', self.uri.href) - response.resume() - return - } - if (self._paused) response.pause() - else response.resume() - - self.response = response - response.request = self - response.toJSON = toJSON - - // XXX This is different on 0.10, because SSL is strict by default - if (self.httpModule === https && - self.strictSSL && - !response.client.authorized) { - debug('strict ssl error', self.uri.href) - var sslErr = response.client.authorizationError - self.emit('error', new Error('SSL Error: '+ sslErr)) - return - } - - if (self.setHost) delete self.headers.host - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - - var addCookie = function (cookie) { - if (self._jar) self._jar.add(new Cookie(cookie)) - else cookieJar.add(new Cookie(cookie)) - } - - if (response.headers['set-cookie'] && (!self._disableCookies)) { - if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie) - else addCookie(response.headers['set-cookie']) - } - - var redirectTo = null - if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { - debug('redirect', response.headers.location) - - if (self.followAllRedirects) { - redirectTo = response.headers.location - } else if (self.followRedirect) { - switch (self.method) { - case 'PATCH': - case 'PUT': - case 'POST': - case 'DELETE': - // Do not follow redirects - break - default: - redirectTo = response.headers.location - break - } - } - } else if (response.statusCode == 401 && self._hasAuth && !self._sentAuth) { - var authHeader = response.headers['www-authenticate'] - var authVerb = authHeader && authHeader.split(' ')[0] - debug('reauth', authVerb) - - switch (authVerb) { - case 'Basic': - self.auth(self._user, self._pass, true) - redirectTo = self.uri - break - - case 'Digest': - // TODO: More complete implementation of RFC 2617. For reference: - // http://tools.ietf.org/html/rfc2617#section-3 - // https://github.com/bagder/curl/blob/master/lib/http_digest.c - - var matches = authHeader.match(/([a-z0-9_-]+)="([^"]+)"/gi) - var challenge = {} - - for (var i = 0; i < matches.length; i++) { - var eqPos = matches[i].indexOf('=') - var key = matches[i].substring(0, eqPos) - var quotedValue = matches[i].substring(eqPos + 1) - challenge[key] = quotedValue.substring(1, quotedValue.length - 1) - } - - var ha1 = md5(self._user + ':' + challenge.realm + ':' + self._pass) - var ha2 = md5(self.method + ':' + self.uri.path) - var digestResponse = md5(ha1 + ':' + challenge.nonce + ':1::auth:' + ha2) - var authValues = { - username: self._user, - realm: challenge.realm, - nonce: challenge.nonce, - uri: self.uri.path, - qop: challenge.qop, - response: digestResponse, - nc: 1, - cnonce: '' - } - - authHeader = [] - for (var k in authValues) { - authHeader.push(k + '="' + authValues[k] + '"') - } - authHeader = 'Digest ' + authHeader.join(', ') - self.setHeader('authorization', authHeader) - self._sentAuth = true - - redirectTo = self.uri - break - } - } - - if (redirectTo) { - debug('redirect to', redirectTo) - - // ignore any potential response body. it cannot possibly be useful - // to us at this point. - if (self._paused) response.resume() - - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop "+self.uri.href)) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(redirectTo)) { - redirectTo = url.resolve(self.uri.href, redirectTo) - } - - var uriPrev = self.uri - self.uri = url.parse(redirectTo) - - // handle the case where we change protocol from https to http or vice versa - if (self.uri.protocol !== uriPrev.protocol) { - self._updateProtocol() - } - - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: redirectTo - } - ) - if (self.followAllRedirects && response.statusCode != 401) self.method = 'GET' - // self.method = 'GET' // Force all redirects to use GET || commented out fixes #215 - delete self.src - delete self.req - delete self.agent - delete self._started - if (response.statusCode != 401) { - // Remove parameters from the previous response, unless this is the second request - // for a server that requires digest authentication. - delete self.body - delete self._form - if (self.headers) { - delete self.headers.host - delete self.headers['content-type'] - delete self.headers['content-length'] - } - } - - self.emit('redirect'); - - self.init() - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.emit('response', response) - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - debug('end event', self.uri.href) - if (self._aborted) { - debug('aborted', self.uri.href) - return - } - - if (buffer.length && Buffer.isBuffer(buffer[0])) { - debug('has body', self.uri.href, bodyLen) - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString(self.encoding) - } - } else if (buffer.length) { - // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. - // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). - if (self.encoding === 'utf8' && buffer[0].length > 0 && buffer[0][0] === "\uFEFF") { - buffer[0] = buffer[0].substring(1) - } - response.body = buffer.join('') - } - - if (self._json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - debug('emitting complete', self.uri.href) - if(response.body == undefined && !self._json) { - response.body = ""; - } - self.emit('complete', response, response.body) - }) - } - } - debug('finish init function', self.uri.href) -} - -Request.prototype.abort = function () { - this._aborted = true - - if (this.req) { - this.req.abort() - } - else if (this.response) { - this.response.abort() - } - - this.emit("abort") -} - -Request.prototype.pipeDest = function (dest) { - var response = this.response - // Called after the response is received - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (this.pipefilter) this.pipefilter(response, dest) -} - -// Composable API -Request.prototype.setHeader = function (name, value, clobber) { - if (clobber === undefined) clobber = true - if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value - else this.headers[name] += ',' + value - return this -} -Request.prototype.setHeaders = function (headers) { - for (var i in headers) {this.setHeader(i, headers[i])} - return this -} -Request.prototype.qs = function (q, clobber) { - var base - if (!clobber && this.uri.query) base = qs.parse(this.uri.query) - else base = {} - - for (var i in q) { - base[i] = q[i] - } - - if (qs.stringify(base) === ''){ - return this - } - - this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) - this.url = this.uri - this.path = this.uri.path - - return this -} -Request.prototype.form = function (form) { - if (form) { - this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - this.body = qs.stringify(form).toString('utf8') - return this - } - // create form-data object - this._form = new FormData() - return this._form -} -Request.prototype.multipart = function (multipart) { - var self = this - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary - } - - if (!multipart.forEach) throw new Error('Argument error, options.multipart.') - - if (self.preambleCRLF) { - self.body.push(new Buffer('\r\n')) - } - - multipart.forEach(function (part) { - var body = part.body - if(body == null) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--' + self.boundary + '\r\n' - Object.keys(part).forEach(function (key) { - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--' + self.boundary + '--')) - return self -} -Request.prototype.json = function (val) { - var self = this; - var setAcceptHeader = function() { - if (!self.headers['accept'] && !self.headers['Accept']) { - self.setHeader('accept', 'application/json') - } - } - setAcceptHeader(); - this._json = true - if (typeof val === 'boolean') { - if (typeof this.body === 'object') { - setAcceptHeader(); - this.body = safeStringify(this.body) - self.setHeader('content-type', 'application/json') - } - } else { - setAcceptHeader(); - this.body = safeStringify(val) - self.setHeader('content-type', 'application/json') - } - return this -} -function getHeader(name, headers) { - var result, re, match - Object.keys(headers).forEach(function (key) { - re = new RegExp(name, 'i') - match = key.match(re) - if (match) result = headers[key] - }) - return result -} -Request.prototype.auth = function (user, pass, sendImmediately) { - if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { - throw new Error('auth() received invalid user or password') - } - this._user = user - this._pass = pass - this._hasAuth = true - if (sendImmediately || typeof sendImmediately == 'undefined') { - this.setHeader('authorization', 'Basic ' + toBase64(user + ':' + pass)) - this._sentAuth = true - } - return this -} -Request.prototype.aws = function (opts, now) { - if (!now) { - this._aws = opts - return this - } - var date = new Date() - this.setHeader('date', date.toUTCString()) - var auth = - { key: opts.key - , secret: opts.secret - , verb: this.method.toUpperCase() - , date: date - , contentType: getHeader('content-type', this.headers) || '' - , md5: getHeader('content-md5', this.headers) || '' - , amazonHeaders: aws.canonicalizeHeaders(this.headers) - } - if (opts.bucket && this.path) { - auth.resource = '/' + opts.bucket + this.path - } else if (opts.bucket && !this.path) { - auth.resource = '/' + opts.bucket - } else if (!opts.bucket && this.path) { - auth.resource = this.path - } else if (!opts.bucket && !this.path) { - auth.resource = '/' - } - auth.resource = aws.canonicalizeResource(auth.resource) - this.setHeader('authorization', aws.authorization(auth)) - - return this -} -Request.prototype.httpSignature = function (opts) { - var req = this - httpSignature.signRequest({ - getHeader: function(header) { - return getHeader(header, req.headers) - }, - setHeader: function(header, value) { - req.setHeader(header, value) - }, - method: this.method, - path: this.path - }, opts) - debug('httpSignature authorization', getHeader('authorization', this.headers)) - - return this -} - -Request.prototype.hawk = function (opts) { - this.headers.Authorization = hawk.client.header(this.uri, this.method, opts).field -} - -Request.prototype.oauth = function (_oauth) { - var form - if (this.headers['content-type'] && - this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(this.body) - } - if (this.uri.query) { - form = qs.parse(this.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in _oauth) oa['oauth_'+i] = _oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - var timestamp = oa.oauth_timestamp - - var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname - var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in _oauth) { - // skip - } else { - delete oa['oauth_'+i] - if (i !== 'x_auth_mode') delete oa[i] - } - } - oa.oauth_timestamp = timestamp - this.headers.Authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - this.headers.Authorization += ',oauth_signature="' + oauth.rfc3986(signature) + '"' - return this -} -Request.prototype.jar = function (jar) { - var cookies - - if (this._redirectsFollowed === 0) { - this.originalCookieHeader = this.headers.cookie - } - - if (jar === false) { - // disable cookies - cookies = false - this._disableCookies = true - } else if (jar) { - // fetch cookie from the user defined cookie jar - cookies = jar.get({ url: this.uri.href }) - } else { - // fetch cookie from the global cookie jar - cookies = cookieJar.get({ url: this.uri.href }) - } - - if (cookies && cookies.length) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value - }).join("; ") - - if (this.originalCookieHeader) { - // Don't overwrite existing Cookie header - this.headers.cookie = this.originalCookieHeader + '; ' + cookieString - } else { - this.headers.cookie = cookieString - } - } - this._jar = jar - return this -} - - -// Stream API -Request.prototype.pipe = function (dest, opts) { - if (this.response) { - if (this._destdata) { - throw new Error("You cannot pipe after data has been emitted from the response.") - } else if (this._ended) { - throw new Error("You cannot pipe after the response has been ended.") - } else { - stream.Stream.prototype.pipe.call(this, dest, opts) - this.pipeDest(dest) - return dest - } - } else { - this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest, opts) - return dest - } -} -Request.prototype.write = function () { - if (!this._started) this.start() - return this.req.write.apply(this.req, arguments) -} -Request.prototype.end = function (chunk) { - if (chunk) this.write(chunk) - if (!this._started) this.start() - this.req.end() -} -Request.prototype.pause = function () { - if (!this.response) this._paused = true - else this.response.pause.apply(this.response, arguments) -} -Request.prototype.resume = function () { - if (!this.response) this._paused = false - else this.response.resume.apply(this.response, arguments) -} -Request.prototype.destroy = function () { - if (!this._ended) this.end() - else if (this.response) this.response.destroy() -} - -// organize params for patch, post, put, head, del -function initParams(uri, options, callback) { - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - uri = options.uri - } - return { uri: uri, options: options, callback: callback } -} - -function request (uri, options, callback) { - if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - } - - options = copy(options) - - if (callback) options.callback = callback - var r = new Request(options) - return r -} - -module.exports = request - -request.debug = process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG) - -request.initParams = initParams - -request.defaults = function (options, requester) { - var def = function (method) { - var d = function (uri, opts, callback) { - var params = initParams(uri, opts, callback) - for (var i in options) { - if (params.options[i] === undefined) params.options[i] = options[i] - } - if(typeof requester === 'function') { - if(method === request) { - method = requester - } else { - params.options._requester = requester - } - } - return method(params.options, params.callback) - } - return d - } - var de = def(request) - de.get = def(request.get) - de.patch = def(request.patch) - de.post = def(request.post) - de.put = def(request.put) - de.head = def(request.head) - de.del = def(request.del) - de.cookie = def(request.cookie) - de.jar = request.jar - return de -} - -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - for (option in optionsArg) { - options[option] = optionsArg[option] - } - } - if (agentOptions) options.agentOptions = agentOptions - options.forever = true - return request.defaults(options) -} - -request.get = request -request.post = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'POST' - return request(params.uri || null, params.options, params.callback) -} -request.put = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'PUT' - return request(params.uri || null, params.options, params.callback) -} -request.patch = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'PATCH' - return request(params.uri || null, params.options, params.callback) -} -request.head = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'HEAD' - if (params.options.body || - params.options.requestBodyStream || - (params.options.json && typeof params.options.json !== 'boolean') || - params.options.multipart) { - throw new Error("HTTP HEAD requests MUST NOT include a request body.") - } - return request(params.uri || null, params.options, params.callback) -} -request.del = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'DELETE' - if(typeof params.options._requester === 'function') { - request = params.options._requester - } - return request(params.uri || null, params.options, params.callback) -} -request.jar = function () { - return new CookieJar -} -request.cookie = function (str) { - if (str && str.uri) str = str.uri - if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") - return new Cookie(str) -} - -// Safe toJSON - -function getSafe (self, uuid) { - if (typeof self === 'object' || typeof self === 'function') var safe = {} - if (Array.isArray(self)) var safe = [] - - var recurse = [] - - Object.defineProperty(self, uuid, {}) - - var attrs = Object.keys(self).filter(function (i) { - if (i === uuid) return false - if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true - return !(Object.getOwnPropertyDescriptor(self[i], uuid)) - }) - - - for (var i=0;i= 300 && response.statusCode < 400 && - (self.followAllRedirects || - (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) && - response.headers.location) { - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop "+self.uri.href)) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(response.headers.location)) { - response.headers.location = url.resolve(self.uri.href, response.headers.location) - } - - var uriPrev = self.uri - self.uri = url.parse(response.headers.location) - - // handle the case where we change protocol from https to http or vice versa - if (self.uri.protocol !== uriPrev.protocol) { - self._updateProtocol() - } - - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: response.headers.location - } - ) - if (self.followAllRedirects) self.method = 'GET' - // self.method = 'GET' // Force all redirects to use GET || commented out fixes #215 - delete self.src - delete self.req - delete self.agent - delete self._started - delete self.body - delete self._form - if (self.headers) { - delete self.headers.host - delete self.headers['content-type'] - delete self.headers['content-length'] - } - if (log) log('Redirect to %uri', self) - self.init() - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - self.emit('response', response) - - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - if (self._aborted) return - - if (buffer.length && Buffer.isBuffer(buffer[0])) { - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString(self.encoding) - } - } else if (buffer.length) { - response.body = buffer.join('') - } - - if (self._json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - - self.emit('complete', response, response.body) - }) - } - } - }) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function () { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - - // Set additional timeout on socket - in case if remote - // server freeze after sending headers - if (self.req.setTimeout) { // only works on node 0.6+ - self.req.setTimeout(self.timeout, function () { - if (self.req) { - self.req.abort() - var e = new Error("ESOCKETTIMEDOUT") - e.code = "ESOCKETTIMEDOUT" - self.emit("error", e) - } - }) - } - } - - self.req.on('error', self.clientErrorHandler) - self.req.on('drain', function() { - self.emit('drain') - }) - self.on('end', function() { - if ( self.req.connection ) self.req.connection.removeListener('error', self._parserErrorHandler) - }) - self.emit('request', self.req) -} - -Request.prototype.abort = function () { - this._aborted = true - - if (this.req) { - this.req.abort() - } - else if (this.response) { - this.response.abort() - } - - this.emit("abort") -} - -Request.prototype.pipeDest = function (dest) { - var response = this.response - // Called after the response is received - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (this.pipefilter) this.pipefilter(response, dest) -} - -// Composable API -Request.prototype.setHeader = function (name, value, clobber) { - if (clobber === undefined) clobber = true - if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value - else this.headers[name] += ',' + value - return this -} -Request.prototype.setHeaders = function (headers) { - for (var i in headers) {this.setHeader(i, headers[i])} - return this -} -Request.prototype.qs = function (q, clobber) { - var base - if (!clobber && this.uri.query) base = qs.parse(this.uri.query) - else base = {} - - for (var i in q) { - base[i] = q[i] - } - - this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) - this.url = this.uri - - return this -} -Request.prototype.form = function (form) { - if (form) { - this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - this.body = qs.stringify(form).toString('utf8') - return this - } - // create form-data object - this._form = new FormData() - return this._form -} -Request.prototype.multipart = function (multipart) { - var self = this - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary - } - - if (!multipart.forEach) throw new Error('Argument error, options.multipart.') - - if (self.preambleCRLF) { - self.body.push(new Buffer('\r\n')) - } - - multipart.forEach(function (part) { - var body = part.body - if(body == null) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--' + self.boundary + '\r\n' - Object.keys(part).forEach(function (key) { - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--' + self.boundary + '--')) - return self -} -Request.prototype.json = function (val) { - this.setHeader('accept', 'application/json') - this._json = true - if (typeof val === 'boolean') { - if (typeof this.body === 'object') { - this.setHeader('content-type', 'application/json') - this.body = JSON.stringify(this.body) - } - } else { - this.setHeader('content-type', 'application/json') - this.body = JSON.stringify(val) - } - return this -} -function getHeader(name, headers) { - var result, re, match - Object.keys(headers).forEach(function (key) { - re = new RegExp(name, 'i') - match = key.match(re) - if (match) result = headers[key] - }) - return result -} -Request.prototype.aws = function (opts, now) { - if (!now) { - this._aws = opts - return this - } - var date = new Date() - this.setHeader('date', date.toUTCString()) - var auth = - { key: opts.key - , secret: opts.secret - , verb: this.method.toUpperCase() - , date: date - , contentType: getHeader('content-type', this.headers) || '' - , md5: getHeader('content-md5', this.headers) || '' - , amazonHeaders: aws.canonicalizeHeaders(this.headers) - } - if (opts.bucket && this.path) { - auth.resource = '/' + opts.bucket + this.path - } else if (opts.bucket && !this.path) { - auth.resource = '/' + opts.bucket - } else if (!opts.bucket && this.path) { - auth.resource = this.path - } else if (!opts.bucket && !this.path) { - auth.resource = '/' - } - auth.resource = aws.canonicalizeResource(auth.resource) - this.setHeader('authorization', aws.authorization(auth)) - - return this -} - -Request.prototype.oauth = function (_oauth) { - var form - if (this.headers['content-type'] && - this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(this.body) - } - if (this.uri.query) { - form = qs.parse(this.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in _oauth) oa['oauth_'+i] = _oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - - var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname - var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in _oauth) { - // skip - } else { - delete oa['oauth_'+i] - if (i !== 'x_auth_mode') delete oa[i] - } - } - this.headers.Authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - this.headers.Authorization += ',oauth_signature="' + oauth.rfc3986(signature) + '"' - return this -} -Request.prototype.jar = function (jar) { - var cookies - - if (this._redirectsFollowed === 0) { - this.originalCookieHeader = this.headers.cookie - } - - if (jar === false) { - // disable cookies - cookies = false - this._disableCookies = true - } else if (jar) { - // fetch cookie from the user defined cookie jar - cookies = jar.get({ url: this.uri.href }) - } else { - // fetch cookie from the global cookie jar - cookies = cookieJar.get({ url: this.uri.href }) - } - - if (cookies && cookies.length) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value - }).join("; ") - - if (this.originalCookieHeader) { - // Don't overwrite existing Cookie header - this.headers.cookie = this.originalCookieHeader + '; ' + cookieString - } else { - this.headers.cookie = cookieString - } - } - this._jar = jar - return this -} - - -// Stream API -Request.prototype.pipe = function (dest, opts) { - if (this.response) { - if (this._destdata) { - throw new Error("You cannot pipe after data has been emitted from the response.") - } else if (this._ended) { - throw new Error("You cannot pipe after the response has been ended.") - } else { - stream.Stream.prototype.pipe.call(this, dest, opts) - this.pipeDest(dest) - return dest - } - } else { - this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest, opts) - return dest - } -} -Request.prototype.write = function () { - if (!this._started) this.start() - return this.req.write.apply(this.req, arguments) -} -Request.prototype.end = function (chunk) { - if (chunk) this.write(chunk) - if (!this._started) this.start() - this.req.end() -} -Request.prototype.pause = function () { - if (!this.response) this._paused = true - else this.response.pause.apply(this.response, arguments) -} -Request.prototype.resume = function () { - if (!this.response) this._paused = false - else this.response.resume.apply(this.response, arguments) -} -Request.prototype.destroy = function () { - if (!this._ended) this.end() -} - -// organize params for post, put, head, del -function initParams(uri, options, callback) { - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - uri = options.uri - } - return { uri: uri, options: options, callback: callback } -} - -function request (uri, options, callback) { - if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - } - - if (callback) options.callback = callback - var r = new Request(options) - return r -} - -module.exports = request - -request.initParams = initParams - -request.defaults = function (options, requester) { - var def = function (method) { - var d = function (uri, opts, callback) { - var params = initParams(uri, opts, callback) - for (var i in options) { - if (params.options[i] === undefined) params.options[i] = options[i] - } - if(typeof requester === 'function') { - if(method === request) { - method = requester - } else { - params.options._requester = requester - } - } - return method(params.options, params.callback) - } - return d - } - var de = def(request) - de.get = def(request.get) - de.post = def(request.post) - de.put = def(request.put) - de.head = def(request.head) - de.del = def(request.del) - de.cookie = def(request.cookie) - de.jar = request.jar - return de -} - -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - for (option in optionsArg) { - options[option] = optionsArg[option] - } - } - if (agentOptions) options.agentOptions = agentOptions - options.forever = true - return request.defaults(options) -} - -request.get = request -request.post = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'POST' - return request(params.uri || null, params.options, params.callback) -} -request.put = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'PUT' - return request(params.uri || null, params.options, params.callback) -} -request.head = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'HEAD' - if (params.options.body || - params.options.requestBodyStream || - (params.options.json && typeof params.options.json !== 'boolean') || - params.options.multipart) { - throw new Error("HTTP HEAD requests MUST NOT include a request body.") - } - return request(params.uri || null, params.options, params.callback) -} -request.del = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'DELETE' - if(typeof params.options._requester === 'function') { - request = params.options._requester - } - return request(params.uri || null, params.options, params.callback) -} -request.jar = function () { - return new CookieJar -} -request.cookie = function (str) { - if (str && str.uri) str = str.uri - if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") - return new Cookie(str) -} - -// Safe toJSON - -function getSafe (self, uuid) { - if (typeof self === 'object' || typeof self === 'function') var safe = {} - if (Array.isArray(self)) var safe = [] - - var recurse = [] - - Object.defineProperty(self, uuid, {}) - - var attrs = Object.keys(self).filter(function (i) { - if (i === uuid) return false - if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true - return !(Object.getOwnPropertyDescriptor(self[i], uuid)) - }) - - - for (var i=0;i - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var crypto = require('crypto') - , parse = require('url').parse - ; - -/** - * Valid keys. - */ - -var keys = - [ 'acl' - , 'location' - , 'logging' - , 'notification' - , 'partNumber' - , 'policy' - , 'requestPayment' - , 'torrent' - , 'uploadId' - , 'uploads' - , 'versionId' - , 'versioning' - , 'versions' - , 'website' - ] - -/** - * Return an "Authorization" header value with the given `options` - * in the form of "AWS :" - * - * @param {Object} options - * @return {String} - * @api private - */ - -function authorization (options) { - return 'AWS ' + options.key + ':' + sign(options) -} - -module.exports = authorization -module.exports.authorization = authorization - -/** - * Simple HMAC-SHA1 Wrapper - * - * @param {Object} options - * @return {String} - * @api private - */ - -function hmacSha1 (options) { - return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') -} - -module.exports.hmacSha1 = hmacSha1 - -/** - * Create a base64 sha1 HMAC for `options`. - * - * @param {Object} options - * @return {String} - * @api private - */ - -function sign (options) { - options.message = stringToSign(options) - return hmacSha1(options) -} -module.exports.sign = sign - -/** - * Create a base64 sha1 HMAC for `options`. - * - * Specifically to be used with S3 presigned URLs - * - * @param {Object} options - * @return {String} - * @api private - */ - -function signQuery (options) { - options.message = queryStringToSign(options) - return hmacSha1(options) -} -module.exports.signQuery= signQuery - -/** - * Return a string for sign() with the given `options`. - * - * Spec: - * - * \n - * \n - * \n - * \n - * [headers\n] - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function stringToSign (options) { - var headers = options.amazonHeaders || '' - if (headers) headers += '\n' - var r = - [ options.verb - , options.md5 - , options.contentType - , options.date.toUTCString() - , headers + options.resource - ] - return r.join('\n') -} -module.exports.queryStringToSign = stringToSign - -/** - * Return a string for sign() with the given `options`, but is meant exclusively - * for S3 presigned URLs - * - * Spec: - * - * \n - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function queryStringToSign (options){ - return 'GET\n\n\n' + options.date + '\n' + options.resource -} -module.exports.queryStringToSign = queryStringToSign - -/** - * Perform the following: - * - * - ignore non-amazon headers - * - lowercase fields - * - sort lexicographically - * - trim whitespace between ":" - * - join with newline - * - * @param {Object} headers - * @return {String} - * @api private - */ - -function canonicalizeHeaders (headers) { - var buf = [] - , fields = Object.keys(headers) - ; - for (var i = 0, len = fields.length; i < len; ++i) { - var field = fields[i] - , val = headers[field] - , field = field.toLowerCase() - ; - if (0 !== field.indexOf('x-amz')) continue - buf.push(field + ':' + val) - } - return buf.sort().join('\n') -} -module.exports.canonicalizeHeaders = canonicalizeHeaders - -/** - * Perform the following: - * - * - ignore non sub-resources - * - sort lexicographically - * - * @param {String} resource - * @return {String} - * @api private - */ - -function canonicalizeResource (resource) { - var url = parse(resource, true) - , path = url.pathname - , buf = [] - ; - - Object.keys(url.query).forEach(function(key){ - if (!~keys.indexOf(key)) return - var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) - buf.push(key + val) - }) - - return path + (buf.length ? '?' + buf.sort().join('&') : '') -} -module.exports.canonicalizeResource = canonicalizeResource diff --git a/api/node_modules/request/node_modules/aws-sign/package.json b/api/node_modules/request/node_modules/aws-sign/package.json deleted file mode 100644 index 54ebc98142b..00000000000 --- a/api/node_modules/request/node_modules/aws-sign/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "aws-sign", - "description": "AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/aws-sign" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "aws-sign\n========\n\nAWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/aws-sign/issues" - }, - "_id": "aws-sign@0.3.0", - "_from": "aws-sign@~0.3.0" -} diff --git a/api/node_modules/request/node_modules/cookie-jar/LICENSE b/api/node_modules/request/node_modules/cookie-jar/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/api/node_modules/request/node_modules/cookie-jar/README.md b/api/node_modules/request/node_modules/cookie-jar/README.md deleted file mode 100644 index bcd8f8d4451..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/README.md +++ /dev/null @@ -1,4 +0,0 @@ -cookie-jar -========== - -Cookie Jar. Originally pulled from LearnBoost/tobi, maintained as vendor in request, now a standalone module. diff --git a/api/node_modules/request/node_modules/cookie-jar/index.js b/api/node_modules/request/node_modules/cookie-jar/index.js deleted file mode 100644 index 7d54d940cc7..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/index.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * Tobi - Cookie - * Copyright(c) 2010 LearnBoost - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var url = require('url'); - -/** - * Initialize a new `Cookie` with the given cookie `str` and `req`. - * - * @param {String} str - * @param {IncomingRequest} req - * @api private - */ - -var Cookie = exports = module.exports = function Cookie(str, req) { - this.str = str; - - // Map the key/val pairs - str.split(/ *; */).reduce(function(obj, pair){ - var p = pair.indexOf('='); - var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); - var lowerCasedKey = key.toLowerCase(); - var value = p > 0 ? pair.substring(p + 1).trim() : true; - - if (!obj.name) { - // First key is the name - obj.name = key; - obj.value = value; - } - else if (lowerCasedKey === 'httponly') { - obj.httpOnly = value; - } - else { - obj[lowerCasedKey] = value; - } - return obj; - }, this); - - // Expires - this.expires = this.expires - ? new Date(this.expires) - : Infinity; - - // Default or trim path - this.path = this.path - ? this.path.trim(): req - ? url.parse(req.url).pathname: '/'; -}; - -/** - * Return the original cookie string. - * - * @return {String} - * @api public - */ - -Cookie.prototype.toString = function(){ - return this.str; -}; - -module.exports.Jar = require('./jar') \ No newline at end of file diff --git a/api/node_modules/request/node_modules/cookie-jar/jar.js b/api/node_modules/request/node_modules/cookie-jar/jar.js deleted file mode 100644 index 34920e06201..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/jar.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! -* Tobi - CookieJar -* Copyright(c) 2010 LearnBoost -* MIT Licensed -*/ - -/** -* Module dependencies. -*/ - -var url = require('url'); - -/** -* Initialize a new `CookieJar`. -* -* @api private -*/ - -var CookieJar = exports = module.exports = function CookieJar() { - this.cookies = []; -}; - -/** -* Add the given `cookie` to the jar. -* -* @param {Cookie} cookie -* @api private -*/ - -CookieJar.prototype.add = function(cookie){ - this.cookies = this.cookies.filter(function(c){ - // Avoid duplication (same path, same name) - return !(c.name == cookie.name && c.path == cookie.path); - }); - this.cookies.push(cookie); -}; - -/** -* Get cookies for the given `req`. -* -* @param {IncomingRequest} req -* @return {Array} -* @api private -*/ - -CookieJar.prototype.get = function(req){ - var path = url.parse(req.url).pathname - , now = new Date - , specificity = {}; - return this.cookies.filter(function(cookie){ - if (0 == path.indexOf(cookie.path) && now < cookie.expires - && cookie.path.length > (specificity[cookie.name] || 0)) - return specificity[cookie.name] = cookie.path.length; - }); -}; - -/** -* Return Cookie string for the given `req`. -* -* @param {IncomingRequest} req -* @return {String} -* @api private -*/ - -CookieJar.prototype.cookieString = function(req){ - var cookies = this.get(req); - if (cookies.length) { - return cookies.map(function(cookie){ - return cookie.name + '=' + cookie.value; - }).join('; '); - } -}; diff --git a/api/node_modules/request/node_modules/cookie-jar/package.json b/api/node_modules/request/node_modules/cookie-jar/package.json deleted file mode 100644 index b42df9b80dc..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "cookie-jar", - "description": "Cookie Jar. Originally pulled form tobi, maintained as vendor in request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/cookie-jar" - }, - "main": "index.js", - "scripts": { - "test": "node tests/run.js" - }, - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "cookie-jar\n==========\n\nCookie Jar. Originally pulled from LearnBoost/tobi, maintained as vendor in request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/cookie-jar/issues" - }, - "_id": "cookie-jar@0.3.0", - "_from": "cookie-jar@~0.3.0" -} diff --git a/api/node_modules/request/node_modules/cookie-jar/tests/run.js b/api/node_modules/request/node_modules/cookie-jar/tests/run.js deleted file mode 100644 index e717f02a31b..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/tests/run.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn - , exitCode = 0 - , timeout = 10000 - , fs = require('fs') - ; - -fs.readdir(__dirname, function (e, files) { - if (e) throw e - - var tests = files.filter(function (f) {return f.slice(0, 'test-'.length) === 'test-'}) - - var next = function () { - if (tests.length === 0) process.exit(exitCode); - - var file = tests.shift() - console.log(file) - var proc = spawn('node', [ 'tests/' + file ]) - - var killed = false - var t = setTimeout(function () { - proc.kill() - exitCode += 1 - console.error(file + ' timeout') - killed = true - }, timeout) - - proc.stdout.pipe(process.stdout) - proc.stderr.pipe(process.stderr) - proc.on('exit', function (code) { - if (code && !killed) console.error(file + ' failed') - exitCode += code || 0 - clearTimeout(t) - next() - }) - } - next() - -}) - - diff --git a/api/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js b/api/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js deleted file mode 100644 index 2cdc835bb4a..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js +++ /dev/null @@ -1,29 +0,0 @@ -var Cookie = require('../index') - , assert = require('assert'); - -var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; -var cookie = new Cookie(str); - -// test .toString() -assert.equal(cookie.toString(), str); - -// test .path -assert.equal(cookie.path, '/'); - -// test .httpOnly -assert.equal(cookie.httpOnly, true); - -// test .name -assert.equal(cookie.name, 'Sid'); - -// test .value -assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); - -// test .expires -assert.equal(cookie.expires instanceof Date, true); - -// test .path default -var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); -assert.equal(cookie.path, '/bar'); - -console.log('All tests passed'); diff --git a/api/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js b/api/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js deleted file mode 100644 index a33cfb23217..00000000000 --- a/api/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js +++ /dev/null @@ -1,90 +0,0 @@ -var Cookie = require('../index') - , Jar = Cookie.Jar - , assert = require('assert'); - -function expires(ms) { - return new Date(Date.now() + ms).toUTCString(); -} - -// test .get() expiration -(function() { - var jar = new Jar; - var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); - jar.add(cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 0); - }, 1000); - }, 5); -})(); - -// test .get() path support -(function() { - var jar = new Jar; - var a = new Cookie('sid=1234; path=/'); - var b = new Cookie('sid=1111; path=/foo/bar'); - var c = new Cookie('sid=2222; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - - // should remove the duplicates - assert.equal(jar.cookies.length, 2); - - // same name, same path, latter prevails - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], c); - - // same name, diff path, path specifity prevails, latter prevails - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], a); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=3333; path=/foo/bar'); - var c = new Cookie('pid=3333; path=/foo/bar'); - var d = new Cookie('sid=2222; path=/foo/'); - var e = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - jar.add(d); - jar.add(e); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 2); - assert.equal(cookies[0], b); - assert.equal(cookies[1], c); - - var cookies = jar.get({ url: 'http://foo.com/foo/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], d); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], e); -})(); - -setTimeout(function() { - console.log('All tests passed'); -}, 1200); diff --git a/api/node_modules/request/node_modules/forever-agent/LICENSE b/api/node_modules/request/node_modules/forever-agent/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/api/node_modules/request/node_modules/forever-agent/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/api/node_modules/request/node_modules/forever-agent/README.md b/api/node_modules/request/node_modules/forever-agent/README.md deleted file mode 100644 index 9d5b66343c4..00000000000 --- a/api/node_modules/request/node_modules/forever-agent/README.md +++ /dev/null @@ -1,4 +0,0 @@ -forever-agent -============= - -HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module. diff --git a/api/node_modules/request/node_modules/forever-agent/index.js b/api/node_modules/request/node_modules/forever-agent/index.js deleted file mode 100644 index 5c07928aebf..00000000000 --- a/api/node_modules/request/node_modules/forever-agent/index.js +++ /dev/null @@ -1,119 +0,0 @@ -module.exports = ForeverAgent -ForeverAgent.SSL = ForeverAgentSSL - -var util = require('util') - , Agent = require('http').Agent - , net = require('net') - , tls = require('tls') - , AgentSSL = require('https').Agent - -function ForeverAgent(options) { - var self = this - self.options = options || {} - self.requests = {} - self.sockets = {} - self.freeSockets = {} - self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets - self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets - self.on('free', function(socket, host, port) { - var name = host + ':' + port - if (self.requests[name] && self.requests[name].length) { - self.requests[name].shift().onSocket(socket) - } else if (self.sockets[name].length < self.minSockets) { - if (!self.freeSockets[name]) self.freeSockets[name] = [] - self.freeSockets[name].push(socket) - - // if an error happens while we don't use the socket anyway, meh, throw the socket away - function onIdleError() { - socket.destroy() - } - socket._onIdleError = onIdleError - socket.on('error', onIdleError) - } else { - // If there are no pending requests just destroy the - // socket and it will get removed from the pool. This - // gets us out of timeout issues and allows us to - // default to Connection:keep-alive. - socket.destroy() - } - }) - -} -util.inherits(ForeverAgent, Agent) - -ForeverAgent.defaultMinSockets = 5 - - -ForeverAgent.prototype.createConnection = net.createConnection -ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest -ForeverAgent.prototype.addRequest = function(req, host, port) { - var name = host + ':' + port - if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { - var idleSocket = this.freeSockets[name].pop() - idleSocket.removeListener('error', idleSocket._onIdleError) - delete idleSocket._onIdleError - req._reusedSocket = true - req.onSocket(idleSocket) - } else { - this.addRequestNoreuse(req, host, port) - } -} - -ForeverAgent.prototype.removeSocket = function(s, name, host, port) { - if (this.sockets[name]) { - var index = this.sockets[name].indexOf(s) - if (index !== -1) { - this.sockets[name].splice(index, 1) - } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name] - delete this.requests[name] - } - - if (this.freeSockets[name]) { - var index = this.freeSockets[name].indexOf(s) - if (index !== -1) { - this.freeSockets[name].splice(index, 1) - if (this.freeSockets[name].length === 0) { - delete this.freeSockets[name] - } - } - } - - if (this.requests[name] && this.requests[name].length) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(name, host, port).emit('free') - } -} - -function ForeverAgentSSL (options) { - ForeverAgent.call(this, options) -} -util.inherits(ForeverAgentSSL, ForeverAgent) - -ForeverAgentSSL.prototype.createConnection = createConnectionSSL -ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest - -function createConnectionSSL (port, host, options) { - if (typeof port === 'object') { - options = port; - } else if (typeof host === 'object') { - options = host; - } else if (typeof options === 'object') { - options = options; - } else { - options = {}; - } - - if (typeof port === 'number') { - options.port = port; - } - - if (typeof host === 'string') { - options.host = host; - } - - return tls.connect(options); -} diff --git a/api/node_modules/request/node_modules/forever-agent/package.json b/api/node_modules/request/node_modules/forever-agent/package.json deleted file mode 100644 index cf20ed19a26..00000000000 --- a/api/node_modules/request/node_modules/forever-agent/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "forever-agent", - "description": "HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module.", - "version": "0.5.0", - "repository": { - "url": "https://github.com/mikeal/forever-agent" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "forever-agent\n=============\n\nHTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/forever-agent/issues" - }, - "_id": "forever-agent@0.5.0", - "_from": "forever-agent@~0.5.0" -} diff --git a/api/node_modules/request/node_modules/form-data/.npmignore b/api/node_modules/request/node_modules/form-data/.npmignore deleted file mode 100644 index 85957343efd..00000000000 --- a/api/node_modules/request/node_modules/form-data/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -*.un~ -/node_modules/* -/test/tmp -/.idea -*.iml diff --git a/api/node_modules/request/node_modules/form-data/.travis.yml b/api/node_modules/request/node_modules/form-data/.travis.yml deleted file mode 100644 index f7e975f5ee0..00000000000 --- a/api/node_modules/request/node_modules/form-data/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.6" - - "0.8" diff --git a/api/node_modules/request/node_modules/form-data/License b/api/node_modules/request/node_modules/form-data/License deleted file mode 100644 index c7ff12a2f8a..00000000000 --- a/api/node_modules/request/node_modules/form-data/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. diff --git a/api/node_modules/request/node_modules/form-data/Makefile b/api/node_modules/request/node_modules/form-data/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/api/node_modules/request/node_modules/form-data/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/api/node_modules/request/node_modules/form-data/Readme.md b/api/node_modules/request/node_modules/form-data/Readme.md deleted file mode 100644 index db671128534..00000000000 --- a/api/node_modules/request/node_modules/form-data/Readme.md +++ /dev/null @@ -1,146 +0,0 @@ -# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data) - -A module to create readable `"multipart/form-data"` streams. Can be used to -submit forms and file uploads to other web applications. - -The API of this module is inspired by the -[XMLHttpRequest-2 FormData Interface][xhr2-fd]. - -[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface - -## Install - -``` -npm install form-data -``` - -## Usage - -In this example we are constructing a form with 3 fields that contain a string, -a buffer and a file stream. - -``` javascript -var FormData = require('form-data'); -var fs = require('fs'); - -var form = new FormData(); -form.append('my_field', 'my value'); -form.append('my_buffer', new Buffer(10)); -form.append('my_file', fs.createReadStream('/foo/bar.jpg')); -``` - -Also you can use http-response stream: - -``` javascript -var FormData = require('form-data'); -var http = require('http'); - -var form = new FormData(); - -http.request('http://nodejs.org/images/logo.png', function(response) { - form.append('my_field', 'my value'); - form.append('my_buffer', new Buffer(10)); - form.append('my_logo', response); -}); -``` - -Or @mikeal's request stream: - -``` javascript -var FormData = require('form-data'); -var request = require('request'); - -var form = new FormData(); - -form.append('my_field', 'my value'); -form.append('my_buffer', new Buffer(10)); -form.append('my_logo', request('http://nodejs.org/images/logo.png')); -``` - -In order to submit this form to a web application, you can use node's http -client interface: - -``` javascript -var http = require('http'); - -var request = http.request({ - method: 'post', - host: 'example.org', - path: '/upload', - headers: form.getHeaders() -}); - -form.pipe(request); - -request.on('response', function(res) { - console.log(res.statusCode); -}); -``` - -Or if you would prefer the `'Content-Length'` header to be set for you: - -``` javascript -form.submit('example.org/upload', function(err, res) { - console.log(res.statusCode); -}); -``` - -To use custom headers and pre-known length in parts: - -``` javascript -var CRLF = '\r\n'; -var form = new FormData(); - -var options = { - header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, - knownLength: 1 -}; - -form.append('my_buffer', buffer, options); - -form.submit('http://example.com/', function(err, res) { - if (err) throw err; - console.log('Done'); -}); -``` - -Form-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide "file"-related information manually: - -``` javascript -someModule.stream(function(err, stdout, stderr) { - if (err) throw err; - - var form = new FormData(); - - form.append('file', stdout, { - filename: 'unicycle.jpg', - contentType: 'image/jpg', - knownLength: 19806 - }); - - form.submit('http://example.com/', function(err, res) { - if (err) throw err; - console.log('Done'); - }); -}); -``` - -For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: - -``` javascript -form.submit({ - host: 'example.com', - path: '/probably.php?extra=params', - auth: 'username:password' -}, function(err, res) { - console.log(res.statusCode); -}); -``` - -## TODO - -- Add new streams (0.10) support and try really hard not to break it for 0.8.x. - -## License - -Form-Data is licensed under the MIT license. diff --git a/api/node_modules/request/node_modules/form-data/lib/form_data.js b/api/node_modules/request/node_modules/form-data/lib/form_data.js deleted file mode 100644 index 127b70a9942..00000000000 --- a/api/node_modules/request/node_modules/form-data/lib/form_data.js +++ /dev/null @@ -1,292 +0,0 @@ -var CombinedStream = require('combined-stream'); -var util = require('util'); -var path = require('path'); -var http = require('http'); -var https = require('https'); -var parseUrl = require('url').parse; -var fs = require('fs'); -var mime = require('mime'); -var async = require('async'); - -module.exports = FormData; -function FormData() { - this._overheadLength = 0; - this._valueLength = 0; - this._lengthRetrievers = []; - - CombinedStream.call(this); -} -util.inherits(FormData, CombinedStream); - -FormData.LINE_BREAK = '\r\n'; - -FormData.prototype.append = function(field, value, options) { - options = options || {}; - - var append = CombinedStream.prototype.append.bind(this); - - // all that streamy business can't handle numbers - if (typeof value == 'number') value = ''+value; - - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(field, value, options); - - append(header); - append(value); - append(footer); - - // pass along options.knownLength - this._trackLength(header, value, options); -}; - -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; - - // used w/ trackLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } - - this._valueLength += valueLength; - - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - + FormData.LINE_BREAK.length; - - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { - return; - } - - this._lengthRetrievers.push(function(next) { - - // do we already know the size? - // 0 additional leaves value from getSyncLength() - if (options.knownLength != null) { - next(null, 0); - - // check if it's local file - } else if (value.hasOwnProperty('fd')) { - fs.stat(value.path, function(err, stat) { - if (err) { - next(err); - return; - } - - next(null, stat.size); - }); - - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - next(null, +value.headers['content-length']); - - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - next(null, +response.headers['content-length']); - }); - value.resume(); - - // something else - } else { - next('Unknown stream'); - } - }); -}; - -FormData.prototype._multiPartHeader = function(field, value, options) { - var boundary = this.getBoundary(); - var header = ''; - - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (options.header != null) { - header = options.header; - } else { - header += '--' + boundary + FormData.LINE_BREAK + - 'Content-Disposition: form-data; name="' + field + '"'; - - // fs- and request- streams have path property - // or use custom filename and/or contentType - // TODO: Use request's response mime-type - if (options.filename || value.path) { - header += - '; filename="' + path.basename(options.filename || value.path) + '"' + FormData.LINE_BREAK + - 'Content-Type: ' + (options.contentType || mime.lookup(options.filename || value.path)); - - // http response has not - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - header += - '; filename="' + path.basename(value.client._httpMessage.path) + '"' + FormData.LINE_BREAK + - 'Content-Type: ' + value.headers['content-type']; - } - - header += FormData.LINE_BREAK + FormData.LINE_BREAK; - } - - return header; -}; - -FormData.prototype._multiPartFooter = function(field, value, options) { - return function(next) { - var footer = FormData.LINE_BREAK; - - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); - } - - next(footer); - }.bind(this); -}; - -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--'; -}; - -FormData.prototype.getHeaders = function(userHeaders) { - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; - - for (var header in userHeaders) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - - return formHeaders; -} - -FormData.prototype.getCustomHeaders = function(contentType) { - contentType = contentType ? contentType : 'multipart/form-data'; - - var formHeaders = { - 'content-type': contentType + '; boundary=' + this.getBoundary(), - 'content-length': this.getLengthSync() - }; - - return formHeaders; -} - -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } - - return this._boundary; -}; - -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } - - this._boundary = boundary; -}; - -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; - - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - return knownLength; -}; - -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; - - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - if (!this._lengthRetrievers.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } - - async.parallel(this._lengthRetrievers, function(err, values) { - if (err) { - cb(err); - return; - } - - values.forEach(function(length) { - knownLength += length; - }); - - cb(null, knownLength); - }); -}; - -FormData.prototype.submit = function(params, cb) { - this.getLength(function(err, length) { - - var request - , options - , defaults = { - method : 'post', - port : 80, - headers: this.getHeaders({'Content-Length': length}) - }; - - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { - params = parseUrl(params); - - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname - }, defaults); - } - else // use custom params - { - options = populate(params, defaults); - } - - // https if specified, fallback to http in any other case - if (params.protocol == 'https:') { - // override default port - if (!params.port) options.port = 443; - request = https.request(options); - } else { - request = http.request(options); - } - - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - - return request; - }.bind(this)); -}; - -/* - * Santa's little helpers - */ - -// populates missing values -function populate(dst, src) { - for (var prop in src) { - if (!dst[prop]) dst[prop] = src[prop]; - } - return dst; -} diff --git a/api/node_modules/request/node_modules/form-data/node-form-data.sublime-project b/api/node_modules/request/node_modules/form-data/node-form-data.sublime-project deleted file mode 100644 index 38100b87f7f..00000000000 --- a/api/node_modules/request/node_modules/form-data/node-form-data.sublime-project +++ /dev/null @@ -1,8 +0,0 @@ -{ - "folders": - [ - { - "path": "/Users/alexi/Dropbox/Projects/node-form-data" - } - ] -} diff --git a/api/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace b/api/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace deleted file mode 100644 index e5eb02dc54a..00000000000 --- a/api/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace +++ /dev/null @@ -1,673 +0,0 @@ -{ - "auto_complete": - { - "selected_items": - [ - [ - "back", - "background-clip" - ], - [ - "di", - "display" - ], - [ - "background-", - "background-position" - ], - [ - "de", - "defaults" - ], - [ - "no", - "normal" - ], - [ - "line", - "line-height" - ] - ] - }, - "buffers": - [ - { - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "line_ending": "Unix" - } - }, - { - "file": "package.json", - "settings": - { - "buffer_size": 673, - "line_ending": "Unix" - } - }, - { - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "line_ending": "Unix" - } - }, - { - "contents": "/*!\n * jQuery JavaScript Library v1.8.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)\n */\n(function( window, undefined ) {\nvar\n // A central reference to the root jQuery(document)\n rootjQuery,\n\n // The deferred used on DOM ready\n readyList,\n\n // Use the correct document accordingly with window argument (sandbox)\n document = window.document,\n location = window.location,\n navigator = window.navigator,\n\n // Map over jQuery in case of overwrite\n _jQuery = window.jQuery,\n\n // Map over the $ in case of overwrite\n _$ = window.$,\n\n // Save a reference to some core methods\n core_push = Array.prototype.push,\n core_slice = Array.prototype.slice,\n core_indexOf = Array.prototype.indexOf,\n core_toString = Object.prototype.toString,\n core_hasOwn = Object.prototype.hasOwnProperty,\n core_trim = String.prototype.trim,\n\n // Define a local copy of jQuery\n jQuery = function( selector, context ) {\n // The jQuery object is actually just the init constructor 'enhanced'\n return new jQuery.fn.init( selector, context, rootjQuery );\n },\n\n // Used for matching numbers\n core_pnum = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source,\n\n // Used for detecting and trimming whitespace\n core_rnotwhite = /\\S/,\n core_rspace = /\\s+/,\n\n // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n // A simple way to check for HTML strings\n // Prioritize #id over to avoid XSS via location.hash (#9521)\n rquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n // Match a standalone tag\n rsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n // JSON RegExp\n rvalidchars = /^[\\],:{}\\s]*$/,\n rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n rvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/g,\n\n // Matches dashed string for camelizing\n rmsPrefix = /^-ms-/,\n rdashAlpha = /-([\\da-z])/gi,\n\n // Used by jQuery.camelCase as callback to replace()\n fcamelCase = function( all, letter ) {\n return ( letter + \"\" ).toUpperCase();\n },\n\n // The ready event handler and self cleanup method\n DOMContentLoaded = function() {\n if ( document.addEventListener ) {\n document.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n jQuery.ready();\n } else if ( document.readyState === \"complete\" ) {\n // we're here because readyState === \"complete\" in oldIE\n // which is good enough for us to call the dom ready!\n document.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n jQuery.ready();\n }\n },\n\n // [[Class]] -> type pairs\n class2type = {};\n\njQuery.fn = jQuery.prototype = {\n constructor: jQuery,\n init: function( selector, context, rootjQuery ) {\n var match, elem, ret, doc;\n\n // Handle $(\"\"), $(null), $(undefined), $(false)\n if ( !selector ) {\n return this;\n }\n\n // Handle $(DOMElement)\n if ( selector.nodeType ) {\n this.context = this[0] = selector;\n this.length = 1;\n return this;\n }\n\n // Handle HTML strings\n if ( typeof selector === \"string\" ) {\n if ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n // Assume that strings that start and end with <> are HTML and skip the regex check\n match = [ null, selector, null ];\n\n } else {\n match = rquickExpr.exec( selector );\n }\n\n // Match html or make sure no context is specified for #id\n if ( match && (match[1] || !context) ) {\n\n // HANDLE: $(html) -> $(array)\n if ( match[1] ) {\n context = context instanceof jQuery ? context[0] : context;\n doc = ( context && context.nodeType ? context.ownerDocument || context : document );\n\n // scripts is true for back-compat\n selector = jQuery.parseHTML( match[1], doc, true );\n if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n this.attr.call( selector, context, true );\n }\n\n return jQuery.merge( this, selector );\n\n // HANDLE: $(#id)\n } else {\n elem = document.getElementById( match[2] );\n\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE and Opera return items\n // by name instead of ID\n if ( elem.id !== match[2] ) {\n return rootjQuery.find( selector );\n }\n\n // Otherwise, we inject the element directly into the jQuery object\n this.length = 1;\n this[0] = elem;\n }\n\n this.context = document;\n this.selector = selector;\n return this;\n }\n\n // HANDLE: $(expr, $(...))\n } else if ( !context || context.jquery ) {\n return ( context || rootjQuery ).find( selector );\n\n // HANDLE: $(expr, context)\n // (which is just equivalent to: $(context).find(expr)\n } else {\n return this.constructor( context ).find( selector );\n }\n\n // HANDLE: $(function)\n // Shortcut for document ready\n } else if ( jQuery.isFunction( selector ) ) {\n return rootjQuery.ready( selector );\n }\n\n if ( selector.selector !== undefined ) {\n this.selector = selector.selector;\n this.context = selector.context;\n }\n\n return jQuery.makeArray( selector, this );\n },\n\n // Start with an empty selector\n selector: \"\",\n\n // The current version of jQuery being used\n jquery: \"1.8.3\",\n\n // The default length of a jQuery object is 0\n length: 0,\n\n // The number of elements contained in the matched element set\n size: function() {\n return this.length;\n },\n\n toArray: function() {\n return core_slice.call( this );\n },\n\n // Get the Nth element in the matched element set OR\n // Get the whole matched element set as a clean array\n get: function( num ) {\n return num == null ?\n\n // Return a 'clean' array\n this.toArray() :\n\n // Return just the object\n ( num < 0 ? this[ this.length + num ] : this[ num ] );\n },\n\n // Take an array of elements and push it onto the stack\n // (returning the new matched element set)\n pushStack: function( elems, name, selector ) {\n\n // Build a new jQuery matched element set\n var ret = jQuery.merge( this.constructor(), elems );\n\n // Add the old object onto the stack (as a reference)\n ret.prevObject = this;\n\n ret.context = this.context;\n\n if ( name === \"find\" ) {\n ret.selector = this.selector + ( this.selector ? \" \" : \"\" ) + selector;\n } else if ( name ) {\n ret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n }\n\n // Return the newly-formed element set\n return ret;\n },\n\n // Execute a callback for every element in the matched set.\n // (You can seed the arguments with an array of args, but this is\n // only used internally.)\n each: function( callback, args ) {\n return jQuery.each( this, callback, args );\n },\n\n ready: function( fn ) {\n // Add the callback\n jQuery.ready.promise().done( fn );\n\n return this;\n },\n\n eq: function( i ) {\n i = +i;\n return i === -1 ?\n this.slice( i ) :\n this.slice( i, i + 1 );\n },\n\n first: function() {\n return this.eq( 0 );\n },\n\n last: function() {\n return this.eq( -1 );\n },\n\n slice: function() {\n return this.pushStack( core_slice.apply( this, arguments ),\n \"slice\", core_slice.call(arguments).join(\",\") );\n },\n\n map: function( callback ) {\n return this.pushStack( jQuery.map(this, function( elem, i ) {\n return callback.call( elem, i, elem );\n }));\n },\n\n end: function() {\n return this.prevObject || this.constructor(null);\n },\n\n // For internal use only.\n // Behaves like an Array's method, not like a jQuery method.\n push: core_push,\n sort: [].sort,\n splice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n var options, name, src, copy, copyIsArray, clone,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length,\n deep = false;\n\n // Handle a deep copy situation\n if ( typeof target === \"boolean\" ) {\n deep = target;\n target = arguments[1] || {};\n // skip the boolean and the target\n i = 2;\n }\n\n // Handle case when target is a string or something (possible in deep copy)\n if ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n target = {};\n }\n\n // extend jQuery itself if only one argument is passed\n if ( length === i ) {\n target = this;\n --i;\n }\n\n for ( ; i < length; i++ ) {\n // Only deal with non-null/undefined values\n if ( (options = arguments[ i ]) != null ) {\n // Extend the base object\n for ( name in options ) {\n src = target[ name ];\n copy = options[ name ];\n\n // Prevent never-ending loop\n if ( target === copy ) {\n continue;\n }\n\n // Recurse if we're merging plain objects or arrays\n if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n if ( copyIsArray ) {\n copyIsArray = false;\n clone = src && jQuery.isArray(src) ? src : [];\n\n } else {\n clone = src && jQuery.isPlainObject(src) ? src : {};\n }\n\n // Never move original objects, clone them\n target[ name ] = jQuery.extend( deep, clone, copy );\n\n // Don't bring in undefined values\n } else if ( copy !== undefined ) {\n target[ name ] = copy;\n }\n }\n }\n }\n\n // Return the modified object\n return target;\n};\n\njQuery.extend({\n noConflict: function( deep ) {\n if ( window.$ === jQuery ) {\n window.$ = _$;\n }\n\n if ( deep && window.jQuery === jQuery ) {\n window.jQuery = _jQuery;\n }\n\n return jQuery;\n },\n\n // Is the DOM ready to be used? Set to true once it occurs.\n isReady: false,\n\n // A counter to track how many items to wait for before\n // the ready event fires. See #6781\n readyWait: 1,\n\n // Hold (or release) the ready event\n holdReady: function( hold ) {\n if ( hold ) {\n jQuery.readyWait++;\n } else {\n jQuery.ready( true );\n }\n },\n\n // Handle when the DOM is ready\n ready: function( wait ) {\n\n // Abort if there are pending holds or we're already ready\n if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n return;\n }\n\n // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n if ( !document.body ) {\n return setTimeout( jQuery.ready, 1 );\n }\n\n // Remember that the DOM is ready\n jQuery.isReady = true;\n\n // If a normal DOM Ready event fired, decrement, and wait if need be\n if ( wait !== true && --jQuery.readyWait > 0 ) {\n return;\n }\n\n // If there are functions bound, to execute\n readyList.resolveWith( document, [ jQuery ] );\n\n // Trigger any bound ready events\n if ( jQuery.fn.trigger ) {\n jQuery( document ).trigger(\"ready\").off(\"ready\");\n }\n },\n\n // See test/unit/core.js for details concerning isFunction.\n // Since version 1.3, DOM methods and functions like alert\n // aren't supported. They return false on IE (#2968).\n isFunction: function( obj ) {\n return jQuery.type(obj) === \"function\";\n },\n\n isArray: Array.isArray || function( obj ) {\n return jQuery.type(obj) === \"array\";\n },\n\n isWindow: function( obj ) {\n return obj != null && obj == obj.window;\n },\n\n isNumeric: function( obj ) {\n return !isNaN( parseFloat(obj) ) && isFinite( obj );\n },\n\n type: function( obj ) {\n return obj == null ?\n String( obj ) :\n class2type[ core_toString.call(obj) ] || \"object\";\n },\n\n isPlainObject: function( obj ) {\n // Must be an Object.\n // Because of IE, we also have to check the presence of the constructor property.\n // Make sure that DOM nodes and window objects don't pass through, as well\n if ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n return false;\n }\n\n try {\n // Not own constructor property must be Object\n if ( obj.constructor &&\n !core_hasOwn.call(obj, \"constructor\") &&\n !core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n return false;\n }\n } catch ( e ) {\n // IE8,9 Will throw exceptions on certain host objects #9897\n return false;\n }\n\n // Own properties are enumerated firstly, so to speed up,\n // if last one is own, then all properties are own.\n\n var key;\n for ( key in obj ) {}\n\n return key === undefined || core_hasOwn.call( obj, key );\n },\n\n isEmptyObject: function( obj ) {\n var name;\n for ( name in obj ) {\n return false;\n }\n return true;\n },\n\n error: function( msg ) {\n throw new Error( msg );\n },\n\n // data: string of html\n // context (optional): If specified, the fragment will be created in this context, defaults to document\n // scripts (optional): If true, will include scripts passed in the html string\n parseHTML: function( data, context, scripts ) {\n var parsed;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n if ( typeof context === \"boolean\" ) {\n scripts = context;\n context = 0;\n }\n context = context || document;\n\n // Single tag\n if ( (parsed = rsingleTag.exec( data )) ) {\n return [ context.createElement( parsed[1] ) ];\n }\n\n parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );\n return jQuery.merge( [],\n (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );\n },\n\n parseJSON: function( data ) {\n if ( !data || typeof data !== \"string\") {\n return null;\n }\n\n // Make sure leading/trailing whitespace is removed (IE can't handle it)\n data = jQuery.trim( data );\n\n // Attempt to parse using the native JSON parser first\n if ( window.JSON && window.JSON.parse ) {\n return window.JSON.parse( data );\n }\n\n // Make sure the incoming data is actual JSON\n // Logic borrowed from http://json.org/json2.js\n if ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n .replace( rvalidtokens, \"]\" )\n .replace( rvalidbraces, \"\")) ) {\n\n return ( new Function( \"return \" + data ) )();\n\n }\n jQuery.error( \"Invalid JSON: \" + data );\n },\n\n // Cross-browser xml parsing\n parseXML: function( data ) {\n var xml, tmp;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n try {\n if ( window.DOMParser ) { // Standard\n tmp = new DOMParser();\n xml = tmp.parseFromString( data , \"text/xml\" );\n } else { // IE\n xml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n xml.async = \"false\";\n xml.loadXML( data );\n }\n } catch( e ) {\n xml = undefined;\n }\n if ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n jQuery.error( \"Invalid XML: \" + data );\n }\n return xml;\n },\n\n noop: function() {},\n\n // Evaluates a script in a global context\n // Workarounds based on findings by Jim Driscoll\n // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n globalEval: function( data ) {\n if ( data && core_rnotwhite.test( data ) ) {\n // We use execScript on Internet Explorer\n // We use an anonymous function so that context is window\n // rather than jQuery in Firefox\n ( window.execScript || function( data ) {\n window[ \"eval\" ].call( window, data );\n } )( data );\n }\n },\n\n // Convert dashed to camelCase; used by the css and data modules\n // Microsoft forgot to hump their vendor prefix (#9572)\n camelCase: function( string ) {\n return string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n },\n\n nodeName: function( elem, name ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n },\n\n // args is for internal usage only\n each: function( obj, callback, args ) {\n var name,\n i = 0,\n length = obj.length,\n isObj = length === undefined || jQuery.isFunction( obj );\n\n if ( args ) {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.apply( obj[ name ], args ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.apply( obj[ i++ ], args ) === false ) {\n break;\n }\n }\n }\n\n // A special, fast, case for the most common use of each\n } else {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {\n break;\n }\n }\n }\n }\n\n return obj;\n },\n\n // Use native String.trim function wherever possible\n trim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n function( text ) {\n return text == null ?\n \"\" :\n core_trim.call( text );\n } :\n\n // Otherwise use our own trimming functionality\n function( text ) {\n return text == null ?\n \"\" :\n ( text + \"\" ).replace( rtrim, \"\" );\n },\n\n // results is for internal usage only\n makeArray: function( arr, results ) {\n var type,\n ret = results || [];\n\n if ( arr != null ) {\n // The window, strings (and functions) also have 'length'\n // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n type = jQuery.type( arr );\n\n if ( arr.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( arr ) ) {\n core_push.call( ret, arr );\n } else {\n jQuery.merge( ret, arr );\n }\n }\n\n return ret;\n },\n\n inArray: function( elem, arr, i ) {\n var len;\n\n if ( arr ) {\n if ( core_indexOf ) {\n return core_indexOf.call( arr, elem, i );\n }\n\n len = arr.length;\n i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n for ( ; i < len; i++ ) {\n // Skip accessing in sparse arrays\n if ( i in arr && arr[ i ] === elem ) {\n return i;\n }\n }\n }\n\n return -1;\n },\n\n merge: function( first, second ) {\n var l = second.length,\n i = first.length,\n j = 0;\n\n if ( typeof l === \"number\" ) {\n for ( ; j < l; j++ ) {\n first[ i++ ] = second[ j ];\n }\n\n } else {\n while ( second[j] !== undefined ) {\n first[ i++ ] = second[ j++ ];\n }\n }\n\n first.length = i;\n\n return first;\n },\n\n grep: function( elems, callback, inv ) {\n var retVal,\n ret = [],\n i = 0,\n length = elems.length;\n inv = !!inv;\n\n // Go through the array, only saving the items\n // that pass the validator function\n for ( ; i < length; i++ ) {\n retVal = !!callback( elems[ i ], i );\n if ( inv !== retVal ) {\n ret.push( elems[ i ] );\n }\n }\n\n return ret;\n },\n\n // arg is for internal usage only\n map: function( elems, callback, arg ) {\n var value, key,\n ret = [],\n i = 0,\n length = elems.length,\n // jquery objects are treated as arrays\n isArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n // Go through the array, translating each of the items to their\n if ( isArray ) {\n for ( ; i < length; i++ ) {\n value = callback( elems[ i ], i, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n\n // Go through every key on the object,\n } else {\n for ( key in elems ) {\n value = callback( elems[ key ], key, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n }\n\n // Flatten any nested arrays\n return ret.concat.apply( [], ret );\n },\n\n // A global GUID counter for objects\n guid: 1,\n\n // Bind a function to a context, optionally partially applying any\n // arguments.\n proxy: function( fn, context ) {\n var tmp, args, proxy;\n\n if ( typeof context === \"string\" ) {\n tmp = fn[ context ];\n context = fn;\n fn = tmp;\n }\n\n // Quick check to determine if target is callable, in the spec\n // this throws a TypeError, but we will just return undefined.\n if ( !jQuery.isFunction( fn ) ) {\n return undefined;\n }\n\n // Simulated bind\n args = core_slice.call( arguments, 2 );\n proxy = function() {\n return fn.apply( context, args.concat( core_slice.call( arguments ) ) );\n };\n\n // Set the guid of unique handler to the same of original handler, so it can be removed\n proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n return proxy;\n },\n\n // Multifunctional method to get and set values of a collection\n // The value/s can optionally be executed if it's a function\n access: function( elems, fn, key, value, chainable, emptyGet, pass ) {\n var exec,\n bulk = key == null,\n i = 0,\n length = elems.length;\n\n // Sets many values\n if ( key && typeof key === \"object\" ) {\n for ( i in key ) {\n jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );\n }\n chainable = 1;\n\n // Sets one value\n } else if ( value !== undefined ) {\n // Optionally, function values get executed if exec is true\n exec = pass === undefined && jQuery.isFunction( value );\n\n if ( bulk ) {\n // Bulk operations only iterate when executing function values\n if ( exec ) {\n exec = fn;\n fn = function( elem, key, value ) {\n return exec.call( jQuery( elem ), value );\n };\n\n // Otherwise they run against the entire set\n } else {\n fn.call( elems, value );\n fn = null;\n }\n }\n\n if ( fn ) {\n for (; i < length; i++ ) {\n fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n }\n }\n\n chainable = 1;\n }\n\n return chainable ?\n elems :\n\n // Gets\n bulk ?\n fn.call( elems ) :\n length ? fn( elems[0], key ) : emptyGet;\n },\n\n now: function() {\n return ( new Date() ).getTime();\n }\n});\n\njQuery.ready.promise = function( obj ) {\n if ( !readyList ) {\n\n readyList = jQuery.Deferred();\n\n // Catch cases where $(document).ready() is called after the browser event has already occurred.\n // we once tried to use readyState \"interactive\" here, but it caused issues like the one\n // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n if ( document.readyState === \"complete\" ) {\n // Handle it asynchronously to allow scripts the opportunity to delay ready\n setTimeout( jQuery.ready, 1 );\n\n // Standards-based browsers support DOMContentLoaded\n } else if ( document.addEventListener ) {\n // Use the handy event callback\n document.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n // A fallback to window.onload, that will always work\n window.addEventListener( \"load\", jQuery.ready, false );\n\n // If IE event model is used\n } else {\n // Ensure firing before onload, maybe late but safe also for iframes\n document.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n // A fallback to window.onload, that will always work\n window.attachEvent( \"onload\", jQuery.ready );\n\n // If IE and not a frame\n // continually check to see if the document is ready\n var top = false;\n\n try {\n top = window.frameElement == null && document.documentElement;\n } catch(e) {}\n\n if ( top && top.doScroll ) {\n (function doScrollCheck() {\n if ( !jQuery.isReady ) {\n\n try {\n // Use the trick by Diego Perini\n // http://javascript.nwbox.com/IEContentLoaded/\n top.doScroll(\"left\");\n } catch(e) {\n return setTimeout( doScrollCheck, 50 );\n }\n\n // and execute any waiting functions\n jQuery.ready();\n }\n })();\n }\n }\n }\n return readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n var object = optionsCache[ options ] = {};\n jQuery.each( options.split( core_rspace ), function( _, flag ) {\n object[ flag ] = true;\n });\n return object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n * options: an optional list of space-separated options that will change how\n * the callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n * once: will ensure the callback list can only be fired once (like a Deferred)\n *\n * memory: will keep track of previous values and will call any callback added\n * after the list has been fired right away with the latest \"memorized\"\n * values (like a Deferred)\n *\n * unique: will ensure a callback can only be added once (no duplicate in the list)\n *\n * stopOnFalse: interrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n // Convert options from String-formatted to Object-formatted if needed\n // (we check in cache first)\n options = typeof options === \"string\" ?\n ( optionsCache[ options ] || createOptions( options ) ) :\n jQuery.extend( {}, options );\n\n var // Last fire value (for non-forgettable lists)\n memory,\n // Flag to know if list was already fired\n fired,\n // Flag to know if list is currently firing\n firing,\n // First callback to fire (used internally by add and fireWith)\n firingStart,\n // End of the loop when firing\n firingLength,\n // Index of currently firing callback (modified by remove if needed)\n firingIndex,\n // Actual callback list\n list = [],\n // Stack of fire calls for repeatable lists\n stack = !options.once && [],\n // Fire callbacks\n fire = function( data ) {\n memory = options.memory && data;\n fired = true;\n firingIndex = firingStart || 0;\n firingStart = 0;\n firingLength = list.length;\n firing = true;\n for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n memory = false; // To prevent further calls using add\n break;\n }\n }\n firing = false;\n if ( list ) {\n if ( stack ) {\n if ( stack.length ) {\n fire( stack.shift() );\n }\n } else if ( memory ) {\n list = [];\n } else {\n self.disable();\n }\n }\n },\n // Actual Callbacks object\n self = {\n // Add a callback or a collection of callbacks to the list\n add: function() {\n if ( list ) {\n // First, we save the current length\n var start = list.length;\n (function add( args ) {\n jQuery.each( args, function( _, arg ) {\n var type = jQuery.type( arg );\n if ( type === \"function\" ) {\n if ( !options.unique || !self.has( arg ) ) {\n list.push( arg );\n }\n } else if ( arg && arg.length && type !== \"string\" ) {\n // Inspect recursively\n add( arg );\n }\n });\n })( arguments );\n // Do we need to add the callbacks to the\n // current firing batch?\n if ( firing ) {\n firingLength = list.length;\n // With memory, if we're not firing then\n // we should call right away\n } else if ( memory ) {\n firingStart = start;\n fire( memory );\n }\n }\n return this;\n },\n // Remove a callback from the list\n remove: function() {\n if ( list ) {\n jQuery.each( arguments, function( _, arg ) {\n var index;\n while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n list.splice( index, 1 );\n // Handle firing indexes\n if ( firing ) {\n if ( index <= firingLength ) {\n firingLength--;\n }\n if ( index <= firingIndex ) {\n firingIndex--;\n }\n }\n }\n });\n }\n return this;\n },\n // Control if a given callback is in the list\n has: function( fn ) {\n return jQuery.inArray( fn, list ) > -1;\n },\n // Remove all callbacks from the list\n empty: function() {\n list = [];\n return this;\n },\n // Have the list do nothing anymore\n disable: function() {\n list = stack = memory = undefined;\n return this;\n },\n // Is it disabled?\n disabled: function() {\n return !list;\n },\n // Lock the list in its current state\n lock: function() {\n stack = undefined;\n if ( !memory ) {\n self.disable();\n }\n return this;\n },\n // Is it locked?\n locked: function() {\n return !stack;\n },\n // Call all callbacks with the given context and arguments\n fireWith: function( context, args ) {\n args = args || [];\n args = [ context, args.slice ? args.slice() : args ];\n if ( list && ( !fired || stack ) ) {\n if ( firing ) {\n stack.push( args );\n } else {\n fire( args );\n }\n }\n return this;\n },\n // Call all the callbacks with the given arguments\n fire: function() {\n self.fireWith( this, arguments );\n return this;\n },\n // To know if the callbacks have already been called at least once\n fired: function() {\n return !!fired;\n }\n };\n\n return self;\n};\njQuery.extend({\n\n Deferred: function( func ) {\n var tuples = [\n // action, add listener, listener list, final state\n [ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n [ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n [ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n ],\n state = \"pending\",\n promise = {\n state: function() {\n return state;\n },\n always: function() {\n deferred.done( arguments ).fail( arguments );\n return this;\n },\n then: function( /* fnDone, fnFail, fnProgress */ ) {\n var fns = arguments;\n return jQuery.Deferred(function( newDefer ) {\n jQuery.each( tuples, function( i, tuple ) {\n var action = tuple[ 0 ],\n fn = fns[ i ];\n // deferred[ done | fail | progress ] for forwarding actions to newDefer\n deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?\n function() {\n var returned = fn.apply( this, arguments );\n if ( returned && jQuery.isFunction( returned.promise ) ) {\n returned.promise()\n .done( newDefer.resolve )\n .fail( newDefer.reject )\n .progress( newDefer.notify );\n } else {\n newDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n }\n } :\n newDefer[ action ]\n );\n });\n fns = null;\n }).promise();\n },\n // Get a promise for this deferred\n // If obj is provided, the promise aspect is added to the object\n promise: function( obj ) {\n return obj != null ? jQuery.extend( obj, promise ) : promise;\n }\n },\n deferred = {};\n\n // Keep pipe for back-compat\n promise.pipe = promise.then;\n\n // Add list-specific methods\n jQuery.each( tuples, function( i, tuple ) {\n var list = tuple[ 2 ],\n stateString = tuple[ 3 ];\n\n // promise[ done | fail | progress ] = list.add\n promise[ tuple[1] ] = list.add;\n\n // Handle state\n if ( stateString ) {\n list.add(function() {\n // state = [ resolved | rejected ]\n state = stateString;\n\n // [ reject_list | resolve_list ].disable; progress_list.lock\n }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n }\n\n // deferred[ resolve | reject | notify ] = list.fire\n deferred[ tuple[0] ] = list.fire;\n deferred[ tuple[0] + \"With\" ] = list.fireWith;\n });\n\n // Make the deferred a promise\n promise.promise( deferred );\n\n // Call given func if any\n if ( func ) {\n func.call( deferred, deferred );\n }\n\n // All done!\n return deferred;\n },\n\n // Deferred helper\n when: function( subordinate /* , ..., subordinateN */ ) {\n var i = 0,\n resolveValues = core_slice.call( arguments ),\n length = resolveValues.length,\n\n // the count of uncompleted subordinates\n remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n // the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n deferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n // Update function for both resolve and progress values\n updateFunc = function( i, contexts, values ) {\n return function( value ) {\n contexts[ i ] = this;\n values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n if( values === progressValues ) {\n deferred.notifyWith( contexts, values );\n } else if ( !( --remaining ) ) {\n deferred.resolveWith( contexts, values );\n }\n };\n },\n\n progressValues, progressContexts, resolveContexts;\n\n // add listeners to Deferred subordinates; treat others as resolved\n if ( length > 1 ) {\n progressValues = new Array( length );\n progressContexts = new Array( length );\n resolveContexts = new Array( length );\n for ( ; i < length; i++ ) {\n if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n resolveValues[ i ].promise()\n .done( updateFunc( i, resolveContexts, resolveValues ) )\n .fail( deferred.reject )\n .progress( updateFunc( i, progressContexts, progressValues ) );\n } else {\n --remaining;\n }\n }\n }\n\n // if we're not waiting on anything, resolve the master\n if ( !remaining ) {\n deferred.resolveWith( resolveContexts, resolveValues );\n }\n\n return deferred.promise();\n }\n});\njQuery.support = (function() {\n\n var support,\n all,\n a,\n select,\n opt,\n input,\n fragment,\n eventName,\n i,\n isSupported,\n clickFn,\n div = document.createElement(\"div\");\n\n // Setup\n div.setAttribute( \"className\", \"t\" );\n div.innerHTML = \"
a\";\n\n // Support tests won't run in some limited or non-browser environments\n all = div.getElementsByTagName(\"*\");\n a = div.getElementsByTagName(\"a\")[ 0 ];\n if ( !all || !a || !all.length ) {\n return {};\n }\n\n // First batch of tests\n select = document.createElement(\"select\");\n opt = select.appendChild( document.createElement(\"option\") );\n input = div.getElementsByTagName(\"input\")[ 0 ];\n\n a.style.cssText = \"top:1px;float:left;opacity:.5\";\n support = {\n // IE strips leading whitespace when .innerHTML is used\n leadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n // Make sure that tbody elements aren't automatically inserted\n // IE will insert them into empty tables\n tbody: !div.getElementsByTagName(\"tbody\").length,\n\n // Make sure that link elements get serialized correctly by innerHTML\n // This requires a wrapper element in IE\n htmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n // Get the style information from getAttribute\n // (IE uses .cssText instead)\n style: /top/.test( a.getAttribute(\"style\") ),\n\n // Make sure that URLs aren't manipulated\n // (IE normalizes it by default)\n hrefNormalized: ( a.getAttribute(\"href\") === \"/a\" ),\n\n // Make sure that element opacity exists\n // (IE uses filter instead)\n // Use a regex to work around a WebKit issue. See #5145\n opacity: /^0.5/.test( a.style.opacity ),\n\n // Verify style float existence\n // (IE uses styleFloat instead of cssFloat)\n cssFloat: !!a.style.cssFloat,\n\n // Make sure that if no value is specified for a checkbox\n // that it defaults to \"on\".\n // (WebKit defaults to \"\" instead)\n checkOn: ( input.value === \"on\" ),\n\n // Make sure that a selected-by-default option has a working selected property.\n // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n optSelected: opt.selected,\n\n // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n getSetAttribute: div.className !== \"t\",\n\n // Tests for enctype support on a form (#6743)\n enctype: !!document.createElement(\"form\").enctype,\n\n // Makes sure cloning an html5 element does not cause problems\n // Where outerHTML is undefined, this still works\n html5Clone: document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav>\",\n\n // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode\n boxModel: ( document.compatMode === \"CSS1Compat\" ),\n\n // Will be defined later\n submitBubbles: true,\n changeBubbles: true,\n focusinBubbles: false,\n deleteExpando: true,\n noCloneEvent: true,\n inlineBlockNeedsLayout: false,\n shrinkWrapBlocks: false,\n reliableMarginRight: true,\n boxSizingReliable: true,\n pixelPosition: false\n };\n\n // Make sure checked status is properly cloned\n input.checked = true;\n support.noCloneChecked = input.cloneNode( true ).checked;\n\n // Make sure that the options inside disabled selects aren't marked as disabled\n // (WebKit marks them as disabled)\n select.disabled = true;\n support.optDisabled = !opt.disabled;\n\n // Test to see if it's possible to delete an expando from an element\n // Fails in Internet Explorer\n try {\n delete div.test;\n } catch( e ) {\n support.deleteExpando = false;\n }\n\n if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n div.attachEvent( \"onclick\", clickFn = function() {\n // Cloning a node shouldn't copy over any\n // bound event handlers (IE does this)\n support.noCloneEvent = false;\n });\n div.cloneNode( true ).fireEvent(\"onclick\");\n div.detachEvent( \"onclick\", clickFn );\n }\n\n // Check if a radio maintains its value\n // after being appended to the DOM\n input = document.createElement(\"input\");\n input.value = \"t\";\n input.setAttribute( \"type\", \"radio\" );\n support.radioValue = input.value === \"t\";\n\n input.setAttribute( \"checked\", \"checked\" );\n\n // #11217 - WebKit loses check when the name is after the checked attribute\n input.setAttribute( \"name\", \"t\" );\n\n div.appendChild( input );\n fragment = document.createDocumentFragment();\n fragment.appendChild( div.lastChild );\n\n // WebKit doesn't clone checked state correctly in fragments\n support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n // Check if a disconnected checkbox will retain its checked\n // value of true after appended to the DOM (IE6/7)\n support.appendChecked = input.checked;\n\n fragment.removeChild( input );\n fragment.appendChild( div );\n\n // Technique from Juriy Zaytsev\n // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/\n // We only care about the case where non-standard event systems\n // are used, namely in IE. Short-circuiting here helps us to\n // avoid an eval call (in setAttribute) which can cause CSP\n // to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n if ( div.attachEvent ) {\n for ( i in {\n submit: true,\n change: true,\n focusin: true\n }) {\n eventName = \"on\" + i;\n isSupported = ( eventName in div );\n if ( !isSupported ) {\n div.setAttribute( eventName, \"return;\" );\n isSupported = ( typeof div[ eventName ] === \"function\" );\n }\n support[ i + \"Bubbles\" ] = isSupported;\n }\n }\n\n // Run tests that need a body at doc ready\n jQuery(function() {\n var container, div, tds, marginDiv,\n divReset = \"padding:0;margin:0;border:0;display:block;overflow:hidden;\",\n body = document.getElementsByTagName(\"body\")[0];\n\n if ( !body ) {\n // Return for frameset docs that don't have a body\n return;\n }\n\n container = document.createElement(\"div\");\n container.style.cssText = \"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px\";\n body.insertBefore( container, body.firstChild );\n\n // Construct the test element\n div = document.createElement(\"div\");\n container.appendChild( div );\n\n // Check if table cells still have offsetWidth/Height when they are set\n // to display:none and there are still other visible table cells in a\n // table row; if so, offsetWidth/Height are not reliable for use when\n // determining if an element has been hidden directly using\n // display:none (it is still safe to use offsets if a parent element is\n // hidden; don safety goggles and see bug #4512 for more information).\n // (only IE 8 fails this test)\n div.innerHTML = \"
t
\";\n tds = div.getElementsByTagName(\"td\");\n tds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n isSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n tds[ 0 ].style.display = \"\";\n tds[ 1 ].style.display = \"none\";\n\n // Check if empty table cells still have offsetWidth/Height\n // (IE <= 8 fail this test)\n support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n // Check box-sizing and margin behavior\n div.innerHTML = \"\";\n div.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n support.boxSizing = ( div.offsetWidth === 4 );\n support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );\n\n // NOTE: To any future maintainer, we've window.getComputedStyle\n // because jsdom on node.js will break without it.\n if ( window.getComputedStyle ) {\n support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n // Check if div with explicit width and no margin-right incorrectly\n // gets computed margin-right based on width of container. For more\n // info see bug #3333\n // Fails in WebKit before Feb 2011 nightlies\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n marginDiv = document.createElement(\"div\");\n marginDiv.style.cssText = div.style.cssText = divReset;\n marginDiv.style.marginRight = marginDiv.style.width = \"0\";\n div.style.width = \"1px\";\n div.appendChild( marginDiv );\n support.reliableMarginRight =\n !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n }\n\n if ( typeof div.style.zoom !== \"undefined\" ) {\n // Check if natively block-level elements act like inline-block\n // elements when setting their display to 'inline' and giving\n // them layout\n // (IE < 8 does this)\n div.innerHTML = \"\";\n div.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n // Check if elements with layout shrink-wrap their children\n // (IE 6 does this)\n div.style.display = \"block\";\n div.style.overflow = \"visible\";\n div.innerHTML = \"
\";\n div.firstChild.style.width = \"5px\";\n support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n container.style.zoom = 1;\n }\n\n // Null elements to avoid leaks in IE\n body.removeChild( container );\n container = div = tds = marginDiv = null;\n });\n\n // Null elements to avoid leaks in IE\n fragment.removeChild( div );\n all = a = select = opt = input = fragment = div = null;\n\n return support;\n})();\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n rmultiDash = /([A-Z])/g;\n\njQuery.extend({\n cache: {},\n\n deletedIds: [],\n\n // Remove at next major release (1.9/2.0)\n uuid: 0,\n\n // Unique for each copy of jQuery on the page\n // Non-digits removed to match rinlinejQuery\n expando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n // The following elements throw uncatchable exceptions if you\n // attempt to add expando properties to them.\n noData: {\n \"embed\": true,\n // Ban all objects except for Flash (which handle expandos)\n \"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n \"applet\": true\n },\n\n hasData: function( elem ) {\n elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n return !!elem && !isEmptyDataObject( elem );\n },\n\n data: function( elem, name, data, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, ret,\n internalKey = jQuery.expando,\n getByName = typeof name === \"string\",\n\n // We have to handle DOM nodes and JS objects differently because IE6-7\n // can't GC object references properly across the DOM-JS boundary\n isNode = elem.nodeType,\n\n // Only DOM nodes need the global jQuery cache; JS object data is\n // attached directly to the object so GC can occur automatically\n cache = isNode ? jQuery.cache : elem,\n\n // Only defining an ID for JS objects if its cache already exists allows\n // the code to shortcut on the same path as a DOM node with no cache\n id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n // Avoid doing any more work than we need to when trying to get data on an\n // object that has no data at all\n if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {\n return;\n }\n\n if ( !id ) {\n // Only DOM nodes need a new unique ID for each element since their data\n // ends up in the global cache\n if ( isNode ) {\n elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;\n } else {\n id = internalKey;\n }\n }\n\n if ( !cache[ id ] ) {\n cache[ id ] = {};\n\n // Avoids exposing jQuery metadata on plain JS objects when the object\n // is serialized using JSON.stringify\n if ( !isNode ) {\n cache[ id ].toJSON = jQuery.noop;\n }\n }\n\n // An object can be passed to jQuery.data instead of a key/value pair; this gets\n // shallow copied over onto the existing cache\n if ( typeof name === \"object\" || typeof name === \"function\" ) {\n if ( pvt ) {\n cache[ id ] = jQuery.extend( cache[ id ], name );\n } else {\n cache[ id ].data = jQuery.extend( cache[ id ].data, name );\n }\n }\n\n thisCache = cache[ id ];\n\n // jQuery data() is stored in a separate object inside the object's internal data\n // cache in order to avoid key collisions between internal data and user-defined\n // data.\n if ( !pvt ) {\n if ( !thisCache.data ) {\n thisCache.data = {};\n }\n\n thisCache = thisCache.data;\n }\n\n if ( data !== undefined ) {\n thisCache[ jQuery.camelCase( name ) ] = data;\n }\n\n // Check for both converted-to-camel and non-converted data property names\n // If a data property was specified\n if ( getByName ) {\n\n // First Try to find as-is property data\n ret = thisCache[ name ];\n\n // Test for null|undefined property data\n if ( ret == null ) {\n\n // Try to find the camelCased property\n ret = thisCache[ jQuery.camelCase( name ) ];\n }\n } else {\n ret = thisCache;\n }\n\n return ret;\n },\n\n removeData: function( elem, name, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, i, l,\n\n isNode = elem.nodeType,\n\n // See jQuery.data for more information\n cache = isNode ? jQuery.cache : elem,\n id = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n // If there is already no cache entry for this object, there is no\n // purpose in continuing\n if ( !cache[ id ] ) {\n return;\n }\n\n if ( name ) {\n\n thisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n if ( thisCache ) {\n\n // Support array or space separated string names for data keys\n if ( !jQuery.isArray( name ) ) {\n\n // try the string as a key before any manipulation\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n\n // split the camel cased version by spaces unless a key with the spaces exists\n name = jQuery.camelCase( name );\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n name = name.split(\" \");\n }\n }\n }\n\n for ( i = 0, l = name.length; i < l; i++ ) {\n delete thisCache[ name[i] ];\n }\n\n // If there is no data left in the cache, we want to continue\n // and let the cache object itself get destroyed\n if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {\n return;\n }\n }\n }\n\n // See jQuery.data for more information\n if ( !pvt ) {\n delete cache[ id ].data;\n\n // Don't destroy the parent cache unless the internal data object\n // had been the only thing left in it\n if ( !isEmptyDataObject( cache[ id ] ) ) {\n return;\n }\n }\n\n // Destroy the cache\n if ( isNode ) {\n jQuery.cleanData( [ elem ], true );\n\n // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n } else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n delete cache[ id ];\n\n // When all else fails, null\n } else {\n cache[ id ] = null;\n }\n },\n\n // For internal use only.\n _data: function( elem, name, data ) {\n return jQuery.data( elem, name, data, true );\n },\n\n // A method for determining if a DOM node can handle the data expando\n acceptData: function( elem ) {\n var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n // nodes accept data unless otherwise specified; rejection can be conditional\n return !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n }\n});\n\njQuery.fn.extend({\n data: function( key, value ) {\n var parts, part, attr, name, l,\n elem = this[0],\n i = 0,\n data = null;\n\n // Gets all values\n if ( key === undefined ) {\n if ( this.length ) {\n data = jQuery.data( elem );\n\n if ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n attr = elem.attributes;\n for ( l = attr.length; i < l; i++ ) {\n name = attr[i].name;\n\n if ( !name.indexOf( \"data-\" ) ) {\n name = jQuery.camelCase( name.substring(5) );\n\n dataAttr( elem, name, data[ name ] );\n }\n }\n jQuery._data( elem, \"parsedAttrs\", true );\n }\n }\n\n return data;\n }\n\n // Sets multiple values\n if ( typeof key === \"object\" ) {\n return this.each(function() {\n jQuery.data( this, key );\n });\n }\n\n parts = key.split( \".\", 2 );\n parts[1] = parts[1] ? \".\" + parts[1] : \"\";\n part = parts[1] + \"!\";\n\n return jQuery.access( this, function( value ) {\n\n if ( value === undefined ) {\n data = this.triggerHandler( \"getData\" + part, [ parts[0] ] );\n\n // Try to fetch any internally stored data first\n if ( data === undefined && elem ) {\n data = jQuery.data( elem, key );\n data = dataAttr( elem, key, data );\n }\n\n return data === undefined && parts[1] ?\n this.data( parts[0] ) :\n data;\n }\n\n parts[1] = value;\n this.each(function() {\n var self = jQuery( this );\n\n self.triggerHandler( \"setData\" + part, parts );\n jQuery.data( this, key, value );\n self.triggerHandler( \"changeData\" + part, parts );\n });\n }, null, value, arguments.length > 1, null, false );\n },\n\n removeData: function( key ) {\n return this.each(function() {\n jQuery.removeData( this, key );\n });\n }\n});\n\nfunction dataAttr( elem, key, data ) {\n // If nothing was found internally, try to fetch any\n // data from the HTML5 data-* attribute\n if ( data === undefined && elem.nodeType === 1 ) {\n\n var name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n data = elem.getAttribute( name );\n\n if ( typeof data === \"string\" ) {\n try {\n data = data === \"true\" ? true :\n data === \"false\" ? false :\n data === \"null\" ? null :\n // Only convert to a number if it doesn't change the string\n +data + \"\" === data ? +data :\n rbrace.test( data ) ? jQuery.parseJSON( data ) :\n data;\n } catch( e ) {}\n\n // Make sure we set the data so it isn't changed later\n jQuery.data( elem, key, data );\n\n } else {\n data = undefined;\n }\n }\n\n return data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n var name;\n for ( name in obj ) {\n\n // if the public data object is empty, the private is still empty\n if ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n continue;\n }\n if ( name !== \"toJSON\" ) {\n return false;\n }\n }\n\n return true;\n}\njQuery.extend({\n queue: function( elem, type, data ) {\n var queue;\n\n if ( elem ) {\n type = ( type || \"fx\" ) + \"queue\";\n queue = jQuery._data( elem, type );\n\n // Speed up dequeue by getting out quickly if this is just a lookup\n if ( data ) {\n if ( !queue || jQuery.isArray(data) ) {\n queue = jQuery._data( elem, type, jQuery.makeArray(data) );\n } else {\n queue.push( data );\n }\n }\n return queue || [];\n }\n },\n\n dequeue: function( elem, type ) {\n type = type || \"fx\";\n\n var queue = jQuery.queue( elem, type ),\n startLength = queue.length,\n fn = queue.shift(),\n hooks = jQuery._queueHooks( elem, type ),\n next = function() {\n jQuery.dequeue( elem, type );\n };\n\n // If the fx queue is dequeued, always remove the progress sentinel\n if ( fn === \"inprogress\" ) {\n fn = queue.shift();\n startLength--;\n }\n\n if ( fn ) {\n\n // Add a progress sentinel to prevent the fx queue from being\n // automatically dequeued\n if ( type === \"fx\" ) {\n queue.unshift( \"inprogress\" );\n }\n\n // clear up the last queue stop function\n delete hooks.stop;\n fn.call( elem, next, hooks );\n }\n\n if ( !startLength && hooks ) {\n hooks.empty.fire();\n }\n },\n\n // not intended for public consumption - generates a queueHooks object, or returns the current one\n _queueHooks: function( elem, type ) {\n var key = type + \"queueHooks\";\n return jQuery._data( elem, key ) || jQuery._data( elem, key, {\n empty: jQuery.Callbacks(\"once memory\").add(function() {\n jQuery.removeData( elem, type + \"queue\", true );\n jQuery.removeData( elem, key, true );\n })\n });\n }\n});\n\njQuery.fn.extend({\n queue: function( type, data ) {\n var setter = 2;\n\n if ( typeof type !== \"string\" ) {\n data = type;\n type = \"fx\";\n setter--;\n }\n\n if ( arguments.length < setter ) {\n return jQuery.queue( this[0], type );\n }\n\n return data === undefined ?\n this :\n this.each(function() {\n var queue = jQuery.queue( this, type, data );\n\n // ensure a hooks for this queue\n jQuery._queueHooks( this, type );\n\n if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n jQuery.dequeue( this, type );\n }\n });\n },\n dequeue: function( type ) {\n return this.each(function() {\n jQuery.dequeue( this, type );\n });\n },\n // Based off of the plugin by Clint Helfers, with permission.\n // http://blindsignals.com/index.php/2009/07/jquery-delay/\n delay: function( time, type ) {\n time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n type = type || \"fx\";\n\n return this.queue( type, function( next, hooks ) {\n var timeout = setTimeout( next, time );\n hooks.stop = function() {\n clearTimeout( timeout );\n };\n });\n },\n clearQueue: function( type ) {\n return this.queue( type || \"fx\", [] );\n },\n // Get a promise resolved when queues of a certain type\n // are emptied (fx is the type by default)\n promise: function( type, obj ) {\n var tmp,\n count = 1,\n defer = jQuery.Deferred(),\n elements = this,\n i = this.length,\n resolve = function() {\n if ( !( --count ) ) {\n defer.resolveWith( elements, [ elements ] );\n }\n };\n\n if ( typeof type !== \"string\" ) {\n obj = type;\n type = undefined;\n }\n type = type || \"fx\";\n\n while( i-- ) {\n tmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n if ( tmp && tmp.empty ) {\n count++;\n tmp.empty.add( resolve );\n }\n }\n resolve();\n return defer.promise( obj );\n }\n});\nvar nodeHook, boolHook, fixSpecified,\n rclass = /[\\t\\r\\n]/g,\n rreturn = /\\r/g,\n rtype = /^(?:button|input)$/i,\n rfocusable = /^(?:button|input|object|select|textarea)$/i,\n rclickable = /^a(?:rea|)$/i,\n rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n getSetAttribute = jQuery.support.getSetAttribute;\n\njQuery.fn.extend({\n attr: function( name, value ) {\n return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n },\n\n removeAttr: function( name ) {\n return this.each(function() {\n jQuery.removeAttr( this, name );\n });\n },\n\n prop: function( name, value ) {\n return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n },\n\n removeProp: function( name ) {\n name = jQuery.propFix[ name ] || name;\n return this.each(function() {\n // try/catch handles cases where IE balks (such as removing a property on window)\n try {\n this[ name ] = undefined;\n delete this[ name ];\n } catch( e ) {}\n });\n },\n\n addClass: function( value ) {\n var classNames, i, l, elem,\n setClass, c, cl;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).addClass( value.call(this, j, this.className) );\n });\n }\n\n if ( value && typeof value === \"string\" ) {\n classNames = value.split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n\n if ( elem.nodeType === 1 ) {\n if ( !elem.className && classNames.length === 1 ) {\n elem.className = value;\n\n } else {\n setClass = \" \" + elem.className + \" \";\n\n for ( c = 0, cl = classNames.length; c < cl; c++ ) {\n if ( setClass.indexOf( \" \" + classNames[ c ] + \" \" ) < 0 ) {\n setClass += classNames[ c ] + \" \";\n }\n }\n elem.className = jQuery.trim( setClass );\n }\n }\n }\n }\n\n return this;\n },\n\n removeClass: function( value ) {\n var removes, className, elem, c, cl, i, l;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).removeClass( value.call(this, j, this.className) );\n });\n }\n if ( (value && typeof value === \"string\") || value === undefined ) {\n removes = ( value || \"\" ).split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n if ( elem.nodeType === 1 && elem.className ) {\n\n className = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\n // loop over each item in the removal list\n for ( c = 0, cl = removes.length; c < cl; c++ ) {\n // Remove until there is nothing to remove,\n while ( className.indexOf(\" \" + removes[ c ] + \" \") >= 0 ) {\n className = className.replace( \" \" + removes[ c ] + \" \" , \" \" );\n }\n }\n elem.className = value ? jQuery.trim( className ) : \"\";\n }\n }\n }\n\n return this;\n },\n\n toggleClass: function( value, stateVal ) {\n var type = typeof value,\n isBool = typeof stateVal === \"boolean\";\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( i ) {\n jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n });\n }\n\n return this.each(function() {\n if ( type === \"string\" ) {\n // toggle individual class names\n var className,\n i = 0,\n self = jQuery( this ),\n state = stateVal,\n classNames = value.split( core_rspace );\n\n while ( (className = classNames[ i++ ]) ) {\n // check each className given, space separated list\n state = isBool ? state : !self.hasClass( className );\n self[ state ? \"addClass\" : \"removeClass\" ]( className );\n }\n\n } else if ( type === \"undefined\" || type === \"boolean\" ) {\n if ( this.className ) {\n // store className if set\n jQuery._data( this, \"__className__\", this.className );\n }\n\n // toggle whole className\n this.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n }\n });\n },\n\n hasClass: function( selector ) {\n var className = \" \" + selector + \" \",\n i = 0,\n l = this.length;\n for ( ; i < l; i++ ) {\n if ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n return true;\n }\n }\n\n return false;\n },\n\n val: function( value ) {\n var hooks, ret, isFunction,\n elem = this[0];\n\n if ( !arguments.length ) {\n if ( elem ) {\n hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n return ret;\n }\n\n ret = elem.value;\n\n return typeof ret === \"string\" ?\n // handle most common string cases\n ret.replace(rreturn, \"\") :\n // handle cases where value is null/undef or number\n ret == null ? \"\" : ret;\n }\n\n return;\n }\n\n isFunction = jQuery.isFunction( value );\n\n return this.each(function( i ) {\n var val,\n self = jQuery(this);\n\n if ( this.nodeType !== 1 ) {\n return;\n }\n\n if ( isFunction ) {\n val = value.call( this, i, self.val() );\n } else {\n val = value;\n }\n\n // Treat null/undefined as \"\"; convert numbers to string\n if ( val == null ) {\n val = \"\";\n } else if ( typeof val === \"number\" ) {\n val += \"\";\n } else if ( jQuery.isArray( val ) ) {\n val = jQuery.map(val, function ( value ) {\n return value == null ? \"\" : value + \"\";\n });\n }\n\n hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n // If set returns undefined, fall back to normal setting\n if ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n this.value = val;\n }\n });\n }\n});\n\njQuery.extend({\n valHooks: {\n option: {\n get: function( elem ) {\n // attributes.value is undefined in Blackberry 4.7 but\n // uses .value. See #6932\n var val = elem.attributes.value;\n return !val || val.specified ? elem.value : elem.text;\n }\n },\n select: {\n get: function( elem ) {\n var value, option,\n options = elem.options,\n index = elem.selectedIndex,\n one = elem.type === \"select-one\" || index < 0,\n values = one ? null : [],\n max = one ? index + 1 : options.length,\n i = index < 0 ?\n max :\n one ? index : 0;\n\n // Loop through all the selected options\n for ( ; i < max; i++ ) {\n option = options[ i ];\n\n // oldIE doesn't update selected after form reset (#2551)\n if ( ( option.selected || i === index ) &&\n // Don't return options that are disabled or in a disabled optgroup\n ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n // Get the specific value for the option\n value = jQuery( option ).val();\n\n // We don't need an array for one selects\n if ( one ) {\n return value;\n }\n\n // Multi-Selects return an array\n values.push( value );\n }\n }\n\n return values;\n },\n\n set: function( elem, value ) {\n var values = jQuery.makeArray( value );\n\n jQuery(elem).find(\"option\").each(function() {\n this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n });\n\n if ( !values.length ) {\n elem.selectedIndex = -1;\n }\n return values;\n }\n }\n },\n\n // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9\n attrFn: {},\n\n attr: function( elem, name, value, pass ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set attributes on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {\n return jQuery( elem )[ name ]( value );\n }\n\n // Fallback to prop when attributes are not supported\n if ( typeof elem.getAttribute === \"undefined\" ) {\n return jQuery.prop( elem, name, value );\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n // All attributes are lowercase\n // Grab necessary hook if one is defined\n if ( notxml ) {\n name = name.toLowerCase();\n hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );\n }\n\n if ( value !== undefined ) {\n\n if ( value === null ) {\n jQuery.removeAttr( elem, name );\n return;\n\n } else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n elem.setAttribute( name, value + \"\" );\n return value;\n }\n\n } else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n\n ret = elem.getAttribute( name );\n\n // Non-existent attributes return null, we normalize to undefined\n return ret === null ?\n undefined :\n ret;\n }\n },\n\n removeAttr: function( elem, value ) {\n var propName, attrNames, name, isBool,\n i = 0;\n\n if ( value && elem.nodeType === 1 ) {\n\n attrNames = value.split( core_rspace );\n\n for ( ; i < attrNames.length; i++ ) {\n name = attrNames[ i ];\n\n if ( name ) {\n propName = jQuery.propFix[ name ] || name;\n isBool = rboolean.test( name );\n\n // See #9699 for explanation of this approach (setting first, then removal)\n // Do not do this for boolean attributes (see #10870)\n if ( !isBool ) {\n jQuery.attr( elem, name, \"\" );\n }\n elem.removeAttribute( getSetAttribute ? name : propName );\n\n // Set corresponding property to false for boolean attributes\n if ( isBool && propName in elem ) {\n elem[ propName ] = false;\n }\n }\n }\n }\n },\n\n attrHooks: {\n type: {\n set: function( elem, value ) {\n // We can't allow the type property to be changed (since it causes problems in IE)\n if ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n jQuery.error( \"type property can't be changed\" );\n } else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n // Setting the type on a radio button after the value resets the value in IE6-9\n // Reset value to it's default in case type is set after value\n // This is for element creation\n var val = elem.value;\n elem.setAttribute( \"type\", value );\n if ( val ) {\n elem.value = val;\n }\n return value;\n }\n }\n },\n // Use the value property for back compat\n // Use the nodeHook for button elements in IE6/7 (#1954)\n value: {\n get: function( elem, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.get( elem, name );\n }\n return name in elem ?\n elem.value :\n null;\n },\n set: function( elem, value, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.set( elem, value, name );\n }\n // Does not return so that setAttribute is also used\n elem.value = value;\n }\n }\n },\n\n propFix: {\n tabindex: \"tabIndex\",\n readonly: \"readOnly\",\n \"for\": \"htmlFor\",\n \"class\": \"className\",\n maxlength: \"maxLength\",\n cellspacing: \"cellSpacing\",\n cellpadding: \"cellPadding\",\n rowspan: \"rowSpan\",\n colspan: \"colSpan\",\n usemap: \"useMap\",\n frameborder: \"frameBorder\",\n contenteditable: \"contentEditable\"\n },\n\n prop: function( elem, name, value ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set properties on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n if ( notxml ) {\n // Fix name and attach hooks\n name = jQuery.propFix[ name ] || name;\n hooks = jQuery.propHooks[ name ];\n }\n\n if ( value !== undefined ) {\n if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n return ( elem[ name ] = value );\n }\n\n } else {\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n return elem[ name ];\n }\n }\n },\n\n propHooks: {\n tabIndex: {\n get: function( elem ) {\n // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n var attributeNode = elem.getAttributeNode(\"tabindex\");\n\n return attributeNode && attributeNode.specified ?\n parseInt( attributeNode.value, 10 ) :\n rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n 0 :\n undefined;\n }\n }\n }\n});\n\n// Hook for boolean attributes\nboolHook = {\n get: function( elem, name ) {\n // Align boolean attributes with corresponding properties\n // Fall back to attribute presence where some booleans are not supported\n var attrNode,\n property = jQuery.prop( elem, name );\n return property === true || typeof property !== \"boolean\" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\n name.toLowerCase() :\n undefined;\n },\n set: function( elem, value, name ) {\n var propName;\n if ( value === false ) {\n // Remove boolean attributes when set to false\n jQuery.removeAttr( elem, name );\n } else {\n // value is true since we know at this point it's type boolean and not false\n // Set boolean attributes to the same name and set the DOM property\n propName = jQuery.propFix[ name ] || name;\n if ( propName in elem ) {\n // Only set the IDL specifically if it already exists on the element\n elem[ propName ] = true;\n }\n\n elem.setAttribute( name, name.toLowerCase() );\n }\n return name;\n }\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n fixSpecified = {\n name: true,\n id: true,\n coords: true\n };\n\n // Use this for any attribute in IE6/7\n // This fixes almost every IE6/7 issue\n nodeHook = jQuery.valHooks.button = {\n get: function( elem, name ) {\n var ret;\n ret = elem.getAttributeNode( name );\n return ret && ( fixSpecified[ name ] ? ret.value !== \"\" : ret.specified ) ?\n ret.value :\n undefined;\n },\n set: function( elem, value, name ) {\n // Set the existing or create a new attribute node\n var ret = elem.getAttributeNode( name );\n if ( !ret ) {\n ret = document.createAttribute( name );\n elem.setAttributeNode( ret );\n }\n return ( ret.value = value + \"\" );\n }\n };\n\n // Set width and height to auto instead of 0 on empty string( Bug #8150 )\n // This is for removals\n jQuery.each([ \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n set: function( elem, value ) {\n if ( value === \"\" ) {\n elem.setAttribute( name, \"auto\" );\n return value;\n }\n }\n });\n });\n\n // Set contenteditable to false on removals(#10429)\n // Setting to empty string throws an error as an invalid value\n jQuery.attrHooks.contenteditable = {\n get: nodeHook.get,\n set: function( elem, value, name ) {\n if ( value === \"\" ) {\n value = \"false\";\n }\n nodeHook.set( elem, value, name );\n }\n };\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n jQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n get: function( elem ) {\n var ret = elem.getAttribute( name, 2 );\n return ret === null ? undefined : ret;\n }\n });\n });\n}\n\nif ( !jQuery.support.style ) {\n jQuery.attrHooks.style = {\n get: function( elem ) {\n // Return undefined in the case of empty string\n // Normalize to lowercase since IE uppercases css property names\n return elem.style.cssText.toLowerCase() || undefined;\n },\n set: function( elem, value ) {\n return ( elem.style.cssText = value + \"\" );\n }\n };\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n get: function( elem ) {\n var parent = elem.parentNode;\n\n if ( parent ) {\n parent.selectedIndex;\n\n // Make sure that it also works with optgroups, see #5701\n if ( parent.parentNode ) {\n parent.parentNode.selectedIndex;\n }\n }\n return null;\n }\n });\n}\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n jQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n jQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = {\n get: function( elem ) {\n // Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n }\n };\n });\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n set: function( elem, value ) {\n if ( jQuery.isArray( value ) ) {\n return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n }\n }\n });\n});\nvar rformElems = /^(?:textarea|input|select)$/i,\n rtypenamespace = /^([^\\.]*|)(?:\\.(.+)|)$/,\n rhoverHack = /(?:^|\\s)hover(\\.\\S+|)\\b/,\n rkeyEvent = /^key/,\n rmouseEvent = /^(?:mouse|contextmenu)|click/,\n rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n hoverHack = function( events ) {\n return jQuery.event.special.hover ? events : events.replace( rhoverHack, \"mouseenter$1 mouseleave$1\" );\n };\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n add: function( elem, types, handler, data, selector ) {\n\n var elemData, eventHandle, events,\n t, tns, type, namespaces, handleObj,\n handleObjIn, handlers, special;\n\n // Don't attach events to noData or text/comment nodes (allow plain objects tho)\n if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {\n return;\n }\n\n // Caller can pass in an object of custom data in lieu of the handler\n if ( handler.handler ) {\n handleObjIn = handler;\n handler = handleObjIn.handler;\n selector = handleObjIn.selector;\n }\n\n // Make sure that the handler has a unique ID, used to find/remove it later\n if ( !handler.guid ) {\n handler.guid = jQuery.guid++;\n }\n\n // Init the element's event structure and main handler, if this is the first\n events = elemData.events;\n if ( !events ) {\n elemData.events = events = {};\n }\n eventHandle = elemData.handle;\n if ( !eventHandle ) {\n elemData.handle = eventHandle = function( e ) {\n // Discard the second event of a jQuery.event.trigger() and\n // when an event is called after a page has unloaded\n return typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n undefined;\n };\n // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n eventHandle.elem = elem;\n }\n\n // Handle multiple events separated by a space\n // jQuery(...).bind(\"mouseover mouseout\", fn);\n types = jQuery.trim( hoverHack(types) ).split( \" \" );\n for ( t = 0; t < types.length; t++ ) {\n\n tns = rtypenamespace.exec( types[t] ) || [];\n type = tns[1];\n namespaces = ( tns[2] || \"\" ).split( \".\" ).sort();\n\n // If event changes its type, use the special event handlers for the changed type\n special = jQuery.event.special[ type ] || {};\n\n // If selector defined, determine special event api type, otherwise given type\n type = ( selector ? special.delegateType : special.bindType ) || type;\n\n // Update special based on newly reset type\n special = jQuery.event.special[ type ] || {};\n\n // handleObj is passed to all event handlers\n handleObj = jQuery.extend({\n type: type,\n origType: tns[1],\n data: data,\n handler: handler,\n guid: handler.guid,\n selector: selector,\n needsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n namespace: namespaces.join(\".\")\n }, handleObjIn );\n\n // Init the event handler queue if we're the first\n handlers = events[ type ];\n if ( !handlers ) {\n handlers = events[ type ] = [];\n handlers.delegateCount = 0;\n\n // Only use addEventListener/attachEvent if the special events handler returns false\n if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n // Bind the global event handler to the element\n if ( elem.addEventListener ) {\n elem.addEventListener( type, eventHandle, false );\n\n } else if ( elem.attachEvent ) {\n elem.attachEvent( \"on\" + type, eventHandle );\n }\n }\n }\n\n if ( special.add ) {\n special.add.call( elem, handleObj );\n\n if ( !handleObj.handler.guid ) {\n handleObj.handler.guid = handler.guid;\n }\n }\n\n // Add to the element's handler list, delegates in front\n if ( selector ) {\n handlers.splice( handlers.delegateCount++, 0, handleObj );\n } else {\n handlers.push( handleObj );\n }\n\n // Keep track of which events have ever been used, for event optimization\n jQuery.event.global[ type ] = true;\n }\n\n // Nullify elem to prevent memory leaks in IE\n elem = null;\n },\n\n global: {},\n\n // Detach an event or set of events from an element\n remove: function( elem, types, handler, selector, mappedTypes ) {\n\n var t, tns, type, origType, namespaces, origCount,\n j, events, special, eventType, handleObj,\n elemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n if ( !elemData || !(events = elemData.events) ) {\n return;\n }\n\n // Once for each type.namespace in types; type may be omitted\n types = jQuery.trim( hoverHack( types || \"\" ) ).split(\" \");\n for ( t = 0; t < types.length; t++ ) {\n tns = rtypenamespace.exec( types[t] ) || [];\n type = origType = tns[1];\n namespaces = tns[2];\n\n // Unbind all events (on this namespace, if provided) for the element\n if ( !type ) {\n for ( type in events ) {\n jQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n }\n continue;\n }\n\n special = jQuery.event.special[ type ] || {};\n type = ( selector? special.delegateType : special.bindType ) || type;\n eventType = events[ type ] || [];\n origCount = eventType.length;\n namespaces = namespaces ? new RegExp(\"(^|\\\\.)\" + namespaces.split(\".\").sort().join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\n // Remove matching events\n for ( j = 0; j < eventType.length; j++ ) {\n handleObj = eventType[ j ];\n\n if ( ( mappedTypes || origType === handleObj.origType ) &&\n ( !handler || handler.guid === handleObj.guid ) &&\n ( !namespaces || namespaces.test( handleObj.namespace ) ) &&\n ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n eventType.splice( j--, 1 );\n\n if ( handleObj.selector ) {\n eventType.delegateCount--;\n }\n if ( special.remove ) {\n special.remove.call( elem, handleObj );\n }\n }\n }\n\n // Remove generic event handler if we removed something and no more handlers exist\n // (avoids potential for endless recursion during removal of special event handlers)\n if ( eventType.length === 0 && origCount !== eventType.length ) {\n if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n jQuery.removeEvent( elem, type, elemData.handle );\n }\n\n delete events[ type ];\n }\n }\n\n // Remove the expando if it's no longer used\n if ( jQuery.isEmptyObject( events ) ) {\n delete elemData.handle;\n\n // removeData also checks for emptiness and clears the expando if empty\n // so use it instead of delete\n jQuery.removeData( elem, \"events\", true );\n }\n },\n\n // Events that are safe to short-circuit if no handlers are attached.\n // Native DOM events should not be added, they may have inline handlers.\n customEvent: {\n \"getData\": true,\n \"setData\": true,\n \"changeData\": true\n },\n\n trigger: function( event, data, elem, onlyHandlers ) {\n // Don't do events on text and comment nodes\n if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {\n return;\n }\n\n // Event object or event type\n var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,\n type = event.type || event,\n namespaces = [];\n\n // focus/blur morphs to focusin/out; ensure we're not firing them right now\n if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n return;\n }\n\n if ( type.indexOf( \"!\" ) >= 0 ) {\n // Exclusive events trigger only for the exact event (no namespaces)\n type = type.slice(0, -1);\n exclusive = true;\n }\n\n if ( type.indexOf( \".\" ) >= 0 ) {\n // Namespaced trigger; create a regexp to match event type in handle()\n namespaces = type.split(\".\");\n type = namespaces.shift();\n namespaces.sort();\n }\n\n if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n // No jQuery handlers for this event type, and it can't have inline handlers\n return;\n }\n\n // Caller can pass in an Event, Object, or just an event type string\n event = typeof event === \"object\" ?\n // jQuery.Event object\n event[ jQuery.expando ] ? event :\n // Object literal\n new jQuery.Event( type, event ) :\n // Just the event type (string)\n new jQuery.Event( type );\n\n event.type = type;\n event.isTrigger = true;\n event.exclusive = exclusive;\n event.namespace = namespaces.join( \".\" );\n event.namespace_re = event.namespace? new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n ontype = type.indexOf( \":\" ) < 0 ? \"on\" + type : \"\";\n\n // Handle a global trigger\n if ( !elem ) {\n\n // TODO: Stop taunting the data cache; remove global events and always attach to document\n cache = jQuery.cache;\n for ( i in cache ) {\n if ( cache[ i ].events && cache[ i ].events[ type ] ) {\n jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );\n }\n }\n return;\n }\n\n // Clean up the event in case it is being reused\n event.result = undefined;\n if ( !event.target ) {\n event.target = elem;\n }\n\n // Clone any incoming data and prepend the event, creating the handler arg list\n data = data != null ? jQuery.makeArray( data ) : [];\n data.unshift( event );\n\n // Allow special events to draw outside the lines\n special = jQuery.event.special[ type ] || {};\n if ( special.trigger && special.trigger.apply( elem, data ) === false ) {\n return;\n }\n\n // Determine event propagation path in advance, per W3C events spec (#9951)\n // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n eventPath = [[ elem, special.bindType || type ]];\n if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n bubbleType = special.delegateType || type;\n cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;\n for ( old = elem; cur; cur = cur.parentNode ) {\n eventPath.push([ cur, bubbleType ]);\n old = cur;\n }\n\n // Only add window if we got to document (e.g., not plain obj or detached DOM)\n if ( old === (elem.ownerDocument || document) ) {\n eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);\n }\n }\n\n // Fire handlers on the event path\n for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {\n\n cur = eventPath[i][0];\n event.type = eventPath[i][1];\n\n handle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n if ( handle ) {\n handle.apply( cur, data );\n }\n // Note that this is a bare JS function and not a jQuery handler\n handle = ontype && cur[ ontype ];\n if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n event.preventDefault();\n }\n }\n event.type = type;\n\n // If nobody prevented the default action, do it now\n if ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&\n !(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n // Call a native DOM method on the target with the same name name as the event.\n // Can't use an .isFunction() check here because IE6/7 fails that test.\n // Don't do default actions on window, that's where global variables be (#6170)\n // IE<9 dies on focus/blur to hidden element (#1486)\n if ( ontype && elem[ type ] && ((type !== \"focus\" && type !== \"blur\") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {\n\n // Don't re-trigger an onFOO event when we call its FOO() method\n old = elem[ ontype ];\n\n if ( old ) {\n elem[ ontype ] = null;\n }\n\n // Prevent re-triggering of the same event, since we already bubbled it above\n jQuery.event.triggered = type;\n elem[ type ]();\n jQuery.event.triggered = undefined;\n\n if ( old ) {\n elem[ ontype ] = old;\n }\n }\n }\n }\n\n return event.result;\n },\n\n dispatch: function( event ) {\n\n // Make a writable jQuery.Event from the native event object\n event = jQuery.event.fix( event || window.event );\n\n var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,\n handlers = ( (jQuery._data( this, \"events\" ) || {} )[ event.type ] || []),\n delegateCount = handlers.delegateCount,\n args = core_slice.call( arguments ),\n run_all = !event.exclusive && !event.namespace,\n special = jQuery.event.special[ event.type ] || {},\n handlerQueue = [];\n\n // Use the fix-ed jQuery.Event rather than the (read-only) native event\n args[0] = event;\n event.delegateTarget = this;\n\n // Call the preDispatch hook for the mapped type, and let it bail if desired\n if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n return;\n }\n\n // Determine handlers that should run if there are delegated events\n // Avoid non-left-click bubbling in Firefox (#3861)\n if ( delegateCount && !(event.button && event.type === \"click\") ) {\n\n for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {\n\n // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)\n if ( cur.disabled !== true || event.type !== \"click\" ) {\n selMatch = {};\n matches = [];\n for ( i = 0; i < delegateCount; i++ ) {\n handleObj = handlers[ i ];\n sel = handleObj.selector;\n\n if ( selMatch[ sel ] === undefined ) {\n selMatch[ sel ] = handleObj.needsContext ?\n jQuery( sel, this ).index( cur ) >= 0 :\n jQuery.find( sel, this, null, [ cur ] ).length;\n }\n if ( selMatch[ sel ] ) {\n matches.push( handleObj );\n }\n }\n if ( matches.length ) {\n handlerQueue.push({ elem: cur, matches: matches });\n }\n }\n }\n }\n\n // Add the remaining (directly-bound) handlers\n if ( handlers.length > delegateCount ) {\n handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });\n }\n\n // Run delegates first; they may want to stop propagation beneath us\n for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {\n matched = handlerQueue[ i ];\n event.currentTarget = matched.elem;\n\n for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {\n handleObj = matched.matches[ j ];\n\n // Triggered event must either 1) be non-exclusive and have no namespace, or\n // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {\n\n event.data = handleObj.data;\n event.handleObj = handleObj;\n\n ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n .apply( matched.elem, args );\n\n if ( ret !== undefined ) {\n event.result = ret;\n if ( ret === false ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }\n }\n }\n\n // Call the postDispatch hook for the mapped type\n if ( special.postDispatch ) {\n special.postDispatch.call( this, event );\n }\n\n return event.result;\n },\n\n // Includes some event props shared by KeyEvent and MouseEvent\n // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***\n props: \"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n fixHooks: {},\n\n keyHooks: {\n props: \"char charCode key keyCode\".split(\" \"),\n filter: function( event, original ) {\n\n // Add which for key events\n if ( event.which == null ) {\n event.which = original.charCode != null ? original.charCode : original.keyCode;\n }\n\n return event;\n }\n },\n\n mouseHooks: {\n props: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n filter: function( event, original ) {\n var eventDoc, doc, body,\n button = original.button,\n fromElement = original.fromElement;\n\n // Calculate pageX/Y if missing and clientX/Y available\n if ( event.pageX == null && original.clientX != null ) {\n eventDoc = event.target.ownerDocument || document;\n doc = eventDoc.documentElement;\n body = eventDoc.body;\n\n event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n }\n\n // Add relatedTarget, if necessary\n if ( !event.relatedTarget && fromElement ) {\n event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n }\n\n // Add which for click: 1 === left; 2 === middle; 3 === right\n // Note: button is not normalized, so don't use it\n if ( !event.which && button !== undefined ) {\n event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n }\n\n return event;\n }\n },\n\n fix: function( event ) {\n if ( event[ jQuery.expando ] ) {\n return event;\n }\n\n // Create a writable copy of the event object and normalize some properties\n var i, prop,\n originalEvent = event,\n fixHook = jQuery.event.fixHooks[ event.type ] || {},\n copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n event = jQuery.Event( originalEvent );\n\n for ( i = copy.length; i; ) {\n prop = copy[ --i ];\n event[ prop ] = originalEvent[ prop ];\n }\n\n // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)\n if ( !event.target ) {\n event.target = originalEvent.srcElement || document;\n }\n\n // Target should not be a text node (#504, Safari)\n if ( event.target.nodeType === 3 ) {\n event.target = event.target.parentNode;\n }\n\n // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)\n event.metaKey = !!event.metaKey;\n\n return fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n },\n\n special: {\n load: {\n // Prevent triggered image.load events from bubbling to window.load\n noBubble: true\n },\n\n focus: {\n delegateType: \"focusin\"\n },\n blur: {\n delegateType: \"focusout\"\n },\n\n beforeunload: {\n setup: function( data, namespaces, eventHandle ) {\n // We only want to do this special case on windows\n if ( jQuery.isWindow( this ) ) {\n this.onbeforeunload = eventHandle;\n }\n },\n\n teardown: function( namespaces, eventHandle ) {\n if ( this.onbeforeunload === eventHandle ) {\n this.onbeforeunload = null;\n }\n }\n }\n },\n\n simulate: function( type, elem, event, bubble ) {\n // Piggyback on a donor event to simulate a different one.\n // Fake originalEvent to avoid donor's stopPropagation, but if the\n // simulated event prevents default then we do the same on the donor.\n var e = jQuery.extend(\n new jQuery.Event(),\n event,\n { type: type,\n isSimulated: true,\n originalEvent: {}\n }\n );\n if ( bubble ) {\n jQuery.event.trigger( e, null, elem );\n } else {\n jQuery.event.dispatch.call( elem, e );\n }\n if ( e.isDefaultPrevented() ) {\n event.preventDefault();\n }\n }\n};\n\n// Some plugins are using, but it's undocumented/deprecated and will be removed.\n// The 1.7 special event interface should provide all the hooks needed now.\njQuery.event.handle = jQuery.event.dispatch;\n\njQuery.removeEvent = document.removeEventListener ?\n function( elem, type, handle ) {\n if ( elem.removeEventListener ) {\n elem.removeEventListener( type, handle, false );\n }\n } :\n function( elem, type, handle ) {\n var name = \"on\" + type;\n\n if ( elem.detachEvent ) {\n\n // #8545, #7054, preventing memory leaks for custom events in IE6-8\n // detachEvent needed property on element, by name of that event, to properly expose it to GC\n if ( typeof elem[ name ] === \"undefined\" ) {\n elem[ name ] = null;\n }\n\n elem.detachEvent( name, handle );\n }\n };\n\njQuery.Event = function( src, props ) {\n // Allow instantiation without the 'new' keyword\n if ( !(this instanceof jQuery.Event) ) {\n return new jQuery.Event( src, props );\n }\n\n // Event object\n if ( src && src.type ) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if ( props ) {\n jQuery.extend( this, props );\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || jQuery.now();\n\n // Mark it as fixed\n this[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n return false;\n}\nfunction returnTrue() {\n return true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n preventDefault: function() {\n this.isDefaultPrevented = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if ( e.preventDefault ) {\n e.preventDefault();\n\n // otherwise set the returnValue property of the original event to false (IE)\n } else {\n e.returnValue = false;\n }\n },\n stopPropagation: function() {\n this.isPropagationStopped = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n // if stopPropagation exists run it on the original event\n if ( e.stopPropagation ) {\n e.stopPropagation();\n }\n // otherwise set the cancelBubble property of the original event to true (IE)\n e.cancelBubble = true;\n },\n stopImmediatePropagation: function() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n mouseenter: \"mouseover\",\n mouseleave: \"mouseout\"\n}, function( orig, fix ) {\n jQuery.event.special[ orig ] = {\n delegateType: fix,\n bindType: fix,\n\n handle: function( event ) {\n var ret,\n target = this,\n related = event.relatedTarget,\n handleObj = event.handleObj,\n selector = handleObj.selector;\n\n // For mousenter/leave call the handler if related is outside the target.\n // NB: No relatedTarget if the mouse left/entered the browser window\n if ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n event.type = handleObj.origType;\n ret = handleObj.handler.apply( this, arguments );\n event.type = fix;\n }\n return ret;\n }\n };\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n jQuery.event.special.submit = {\n setup: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Lazy-add a submit handler when a descendant form may potentially be submitted\n jQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n // Node name check avoids a VML-related crash in IE (#9807)\n var elem = e.target,\n form = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n if ( form && !jQuery._data( form, \"_submit_attached\" ) ) {\n jQuery.event.add( form, \"submit._submit\", function( event ) {\n event._submit_bubble = true;\n });\n jQuery._data( form, \"_submit_attached\", true );\n }\n });\n // return undefined since we don't need an event listener\n },\n\n postDispatch: function( event ) {\n // If form was submitted by the user, bubble the event up the tree\n if ( event._submit_bubble ) {\n delete event._submit_bubble;\n if ( this.parentNode && !event.isTrigger ) {\n jQuery.event.simulate( \"submit\", this.parentNode, event, true );\n }\n }\n },\n\n teardown: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n jQuery.event.remove( this, \"._submit\" );\n }\n };\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n jQuery.event.special.change = {\n\n setup: function() {\n\n if ( rformElems.test( this.nodeName ) ) {\n // IE doesn't fire change on a check/radio until blur; trigger it on click\n // after a propertychange. Eat the blur-change in special.change.handle.\n // This still fires onchange a second time for check/radio after blur.\n if ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n jQuery.event.add( this, \"propertychange._change\", function( event ) {\n if ( event.originalEvent.propertyName === \"checked\" ) {\n this._just_changed = true;\n }\n });\n jQuery.event.add( this, \"click._change\", function( event ) {\n if ( this._just_changed && !event.isTrigger ) {\n this._just_changed = false;\n }\n // Allow triggered, simulated change events (#11500)\n jQuery.event.simulate( \"change\", this, event, true );\n });\n }\n return false;\n }\n // Delegated event; lazy-add a change handler on descendant inputs\n jQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n var elem = e.target;\n\n if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"_change_attached\" ) ) {\n jQuery.event.add( elem, \"change._change\", function( event ) {\n if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n jQuery.event.simulate( \"change\", this.parentNode, event, true );\n }\n });\n jQuery._data( elem, \"_change_attached\", true );\n }\n });\n },\n\n handle: function( event ) {\n var elem = event.target;\n\n // Swallow native change events from checkbox/radio, we already triggered them above\n if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n return event.handleObj.handler.apply( this, arguments );\n }\n },\n\n teardown: function() {\n jQuery.event.remove( this, \"._change\" );\n\n return !rformElems.test( this.nodeName );\n }\n };\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n jQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n // Attach a single capturing handler while someone wants focusin/focusout\n var attaches = 0,\n handler = function( event ) {\n jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n };\n\n jQuery.event.special[ fix ] = {\n setup: function() {\n if ( attaches++ === 0 ) {\n document.addEventListener( orig, handler, true );\n }\n },\n teardown: function() {\n if ( --attaches === 0 ) {\n document.removeEventListener( orig, handler, true );\n }\n }\n };\n });\n}\n\njQuery.fn.extend({\n\n on: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n var origFn, type;\n\n // Types can be a map of types/handlers\n if ( typeof types === \"object\" ) {\n // ( types-Object, selector, data )\n if ( typeof selector !== \"string\" ) { // && selector != null\n // ( types-Object, data )\n data = data || selector;\n selector = undefined;\n }\n for ( type in types ) {\n this.on( type, selector, data, types[ type ], one );\n }\n return this;\n }\n\n if ( data == null && fn == null ) {\n // ( types, fn )\n fn = selector;\n data = selector = undefined;\n } else if ( fn == null ) {\n if ( typeof selector === \"string\" ) {\n // ( types, selector, fn )\n fn = data;\n data = undefined;\n } else {\n // ( types, data, fn )\n fn = data;\n data = selector;\n selector = undefined;\n }\n }\n if ( fn === false ) {\n fn = returnFalse;\n } else if ( !fn ) {\n return this;\n }\n\n if ( one === 1 ) {\n origFn = fn;\n fn = function( event ) {\n // Can use an empty set, since event contains the info\n jQuery().off( event );\n return origFn.apply( this, arguments );\n };\n // Use same guid so caller can remove using origFn\n fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n }\n return this.each( function() {\n jQuery.event.add( this, types, fn, data, selector );\n });\n },\n one: function( types, selector, data, fn ) {\n return this.on( types, selector, data, fn, 1 );\n },\n off: function( types, selector, fn ) {\n var handleObj, type;\n if ( types && types.preventDefault && types.handleObj ) {\n // ( event ) dispatched jQuery.Event\n handleObj = types.handleObj;\n jQuery( types.delegateTarget ).off(\n handleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n handleObj.selector,\n handleObj.handler\n );\n return this;\n }\n if ( typeof types === \"object\" ) {\n // ( types-object [, selector] )\n for ( type in types ) {\n this.off( type, selector, types[ type ] );\n }\n return this;\n }\n if ( selector === false || typeof selector === \"function\" ) {\n // ( types [, fn] )\n fn = selector;\n selector = undefined;\n }\n if ( fn === false ) {\n fn = returnFalse;\n }\n return this.each(function() {\n jQuery.event.remove( this, types, fn, selector );\n });\n },\n\n bind: function( types, data, fn ) {\n return this.on( types, null, data, fn );\n },\n unbind: function( types, fn ) {\n return this.off( types, null, fn );\n },\n\n live: function( types, data, fn ) {\n jQuery( this.context ).on( types, this.selector, data, fn );\n return this;\n },\n die: function( types, fn ) {\n jQuery( this.context ).off( types, this.selector || \"**\", fn );\n return this;\n },\n\n delegate: function( selector, types, data, fn ) {\n return this.on( types, selector, data, fn );\n },\n undelegate: function( selector, types, fn ) {\n // ( namespace ) or ( selector, types [, fn] )\n return arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n },\n\n trigger: function( type, data ) {\n return this.each(function() {\n jQuery.event.trigger( type, data, this );\n });\n },\n triggerHandler: function( type, data ) {\n if ( this[0] ) {\n return jQuery.event.trigger( type, data, this[0], true );\n }\n },\n\n toggle: function( fn ) {\n // Save reference to arguments for access in closure\n var args = arguments,\n guid = fn.guid || jQuery.guid++,\n i = 0,\n toggler = function( event ) {\n // Figure out which function to execute\n var lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n jQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n // Make sure that clicks stop\n event.preventDefault();\n\n // and execute the function\n return args[ lastToggle ].apply( this, arguments ) || false;\n };\n\n // link all the functions, so any of them can unbind this click handler\n toggler.guid = guid;\n while ( i < args.length ) {\n args[ i++ ].guid = guid;\n }\n\n return this.click( toggler );\n },\n\n hover: function( fnOver, fnOut ) {\n return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n }\n});\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n \"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n // Handle event binding\n jQuery.fn[ name ] = function( data, fn ) {\n if ( fn == null ) {\n fn = data;\n data = null;\n }\n\n return arguments.length > 0 ?\n this.on( name, null, data, fn ) :\n this.trigger( name );\n };\n\n if ( rkeyEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;\n }\n\n if ( rmouseEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;\n }\n});\n/*!\n * Sizzle CSS Selector Engine\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://sizzlejs.com/\n */\n(function( window, undefined ) {\n\nvar cachedruns,\n assertGetIdNotName,\n Expr,\n getText,\n isXML,\n contains,\n compile,\n sortOrder,\n hasDuplicate,\n outermostContext,\n\n baseHasDuplicate = true,\n strundefined = \"undefined\",\n\n expando = ( \"sizcache\" + Math.random() ).replace( \".\", \"\" ),\n\n Token = String,\n document = window.document,\n docElem = document.documentElement,\n dirruns = 0,\n done = 0,\n pop = [].pop,\n push = [].push,\n slice = [].slice,\n // Use a stripped-down indexOf if a native one is unavailable\n indexOf = [].indexOf || function( elem ) {\n var i = 0,\n len = this.length;\n for ( ; i < len; i++ ) {\n if ( this[i] === elem ) {\n return i;\n }\n }\n return -1;\n },\n\n // Augment a function for special use by Sizzle\n markFunction = function( fn, value ) {\n fn[ expando ] = value == null || value;\n return fn;\n },\n\n createCache = function() {\n var cache = {},\n keys = [];\n\n return markFunction(function( key, value ) {\n // Only keep the most recent entries\n if ( keys.push( key ) > Expr.cacheLength ) {\n delete cache[ keys.shift() ];\n }\n\n // Retrieve with (key + \" \") to avoid collision with native Object.prototype properties (see Issue #157)\n return (cache[ key + \" \" ] = value);\n }, cache );\n },\n\n classCache = createCache(),\n tokenCache = createCache(),\n compilerCache = createCache(),\n\n // Regex\n\n // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n // http://www.w3.org/TR/css3-syntax/#characters\n characterEncoding = \"(?:\\\\\\\\.|[-\\\\w]|[^\\\\x00-\\\\xa0])+\",\n\n // Loosely modeled on CSS identifier characters\n // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)\n // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n identifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n operators = \"([*^$|!~]?=)\",\n attributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n \"*(?:\" + operators + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n // Prefer arguments not in parens/brackets,\n // then attribute selectors and non-pseudos (denoted by :),\n // then anything else\n // These preferences are here to reduce the number of selectors\n // needing tokenize in the PSEUDO preFilter\n pseudos = \":(\" + characterEncoding + \")(?:\\\\((?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\2|([^()[\\\\]]*|(?:(?:\" + attributes + \")|[^:]|\\\\\\\\.)*|.*))\\\\)|)\",\n\n // For matchExpr.POS and matchExpr.needsContext\n pos = \":(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\",\n\n // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n rtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n rcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n rcombinators = new RegExp( \"^\" + whitespace + \"*([\\\\x20\\\\t\\\\r\\\\n\\\\f>+~])\" + whitespace + \"*\" ),\n rpseudo = new RegExp( pseudos ),\n\n // Easily-parseable/retrievable ID or TAG or CLASS selectors\n rquickExpr = /^(?:#([\\w\\-]+)|(\\w+)|\\.([\\w\\-]+))$/,\n\n rnot = /^:not/,\n rsibling = /[\\x20\\t\\r\\n\\f]*[+~]/,\n rendsWithNot = /:not\\($/,\n\n rheader = /h\\d/i,\n rinputs = /input|select|textarea|button/i,\n\n rbackslash = /\\\\(?!\\\\)/g,\n\n matchExpr = {\n \"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n \"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n \"NAME\": new RegExp( \"^\\\\[name=['\\\"]?(\" + characterEncoding + \")['\\\"]?\\\\]\" ),\n \"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n \"ATTR\": new RegExp( \"^\" + attributes ),\n \"PSEUDO\": new RegExp( \"^\" + pseudos ),\n \"POS\": new RegExp( pos, \"i\" ),\n \"CHILD\": new RegExp( \"^:(only|nth|first|last)-child(?:\\\\(\" + whitespace +\n \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n // For use in libraries implementing .is()\n \"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|\" + pos, \"i\" )\n },\n\n // Support\n\n // Used for testing something on an element\n assert = function( fn ) {\n var div = document.createElement(\"div\");\n\n try {\n return fn( div );\n } catch (e) {\n return false;\n } finally {\n // release memory in IE\n div = null;\n }\n },\n\n // Check if getElementsByTagName(\"*\") returns only elements\n assertTagNameNoComments = assert(function( div ) {\n div.appendChild( document.createComment(\"\") );\n return !div.getElementsByTagName(\"*\").length;\n }),\n\n // Check if getAttribute returns normalized href attributes\n assertHrefNotNormalized = assert(function( div ) {\n div.innerHTML = \"\";\n return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\n div.firstChild.getAttribute(\"href\") === \"#\";\n }),\n\n // Check if attributes should be retrieved by attribute nodes\n assertAttributes = assert(function( div ) {\n div.innerHTML = \"\";\n var type = typeof div.lastChild.getAttribute(\"multiple\");\n // IE8 returns a string for some attributes even when not present\n return type !== \"boolean\" && type !== \"string\";\n }),\n\n // Check if getElementsByClassName can be trusted\n assertUsableClassName = assert(function( div ) {\n // Opera can't find a second classname (in 9.6)\n div.innerHTML = \"\";\n if ( !div.getElementsByClassName || !div.getElementsByClassName(\"e\").length ) {\n return false;\n }\n\n // Safari 3.2 caches class attributes and doesn't catch changes\n div.lastChild.className = \"e\";\n return div.getElementsByClassName(\"e\").length === 2;\n }),\n\n // Check if getElementById returns elements by name\n // Check if getElementsByName privileges form controls or returns elements by ID\n assertUsableName = assert(function( div ) {\n // Inject content\n div.id = expando + 0;\n div.innerHTML = \"
\";\n docElem.insertBefore( div, docElem.firstChild );\n\n // Test\n var pass = document.getElementsByName &&\n // buggy browsers will return fewer than the correct 2\n document.getElementsByName( expando ).length === 2 +\n // buggy browsers will return more than the correct 0\n document.getElementsByName( expando + 0 ).length;\n assertGetIdNotName = !document.getElementById( expando );\n\n // Cleanup\n docElem.removeChild( div );\n\n return pass;\n });\n\n// If slice is not available, provide a backup\ntry {\n slice.call( docElem.childNodes, 0 )[0].nodeType;\n} catch ( e ) {\n slice = function( i ) {\n var elem,\n results = [];\n for ( ; (elem = this[i]); i++ ) {\n results.push( elem );\n }\n return results;\n };\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n results = results || [];\n context = context || document;\n var match, elem, xml, m,\n nodeType = context.nodeType;\n\n if ( !selector || typeof selector !== \"string\" ) {\n return results;\n }\n\n if ( nodeType !== 1 && nodeType !== 9 ) {\n return [];\n }\n\n xml = isXML( context );\n\n if ( !xml && !seed ) {\n if ( (match = rquickExpr.exec( selector )) ) {\n // Speed-up: Sizzle(\"#ID\")\n if ( (m = match[1]) ) {\n if ( nodeType === 9 ) {\n elem = context.getElementById( m );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE, Opera, and Webkit return items\n // by name instead of ID\n if ( elem.id === m ) {\n results.push( elem );\n return results;\n }\n } else {\n return results;\n }\n } else {\n // Context is not a document\n if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n contains( context, elem ) && elem.id === m ) {\n results.push( elem );\n return results;\n }\n }\n\n // Speed-up: Sizzle(\"TAG\")\n } else if ( match[2] ) {\n push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );\n return results;\n\n // Speed-up: Sizzle(\".CLASS\")\n } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {\n push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );\n return results;\n }\n }\n }\n\n // All others\n return select( selector.replace( rtrim, \"$1\" ), context, results, seed, xml );\n}\n\nSizzle.matches = function( expr, elements ) {\n return Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n};\n\n// Returns a function to use in pseudos for input types\nfunction createInputPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for buttons\nfunction createButtonPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return (name === \"input\" || name === \"button\") && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for positionals\nfunction createPositionalPseudo( fn ) {\n return markFunction(function( argument ) {\n argument = +argument;\n return markFunction(function( seed, matches ) {\n var j,\n matchIndexes = fn( [], seed.length, argument ),\n i = matchIndexes.length;\n\n // Match elements found at the specified indexes\n while ( i-- ) {\n if ( seed[ (j = matchIndexes[i]) ] ) {\n seed[j] = !(matches[j] = seed[j]);\n }\n }\n });\n });\n}\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n var node,\n ret = \"\",\n i = 0,\n nodeType = elem.nodeType;\n\n if ( nodeType ) {\n if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n // Use textContent for elements\n // innerText usage removed for consistency of new lines (see #11153)\n if ( typeof elem.textContent === \"string\" ) {\n return elem.textContent;\n } else {\n // Traverse its children\n for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n ret += getText( elem );\n }\n }\n } else if ( nodeType === 3 || nodeType === 4 ) {\n return elem.nodeValue;\n }\n // Do not include comment or processing instruction nodes\n } else {\n\n // If no nodeType, this is expected to be an array\n for ( ; (node = elem[i]); i++ ) {\n // Do not traverse comment nodes\n ret += getText( node );\n }\n }\n return ret;\n};\n\nisXML = Sizzle.isXML = function( elem ) {\n // documentElement is verified for cases where it doesn't yet exist\n // (such as loading iframes in IE - #4833)\n var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Element contains another\ncontains = Sizzle.contains = docElem.contains ?\n function( a, b ) {\n var adown = a.nodeType === 9 ? a.documentElement : a,\n bup = b && b.parentNode;\n return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\n } :\n docElem.compareDocumentPosition ?\n function( a, b ) {\n return b && !!( a.compareDocumentPosition( b ) & 16 );\n } :\n function( a, b ) {\n while ( (b = b.parentNode) ) {\n if ( b === a ) {\n return true;\n }\n }\n return false;\n };\n\nSizzle.attr = function( elem, name ) {\n var val,\n xml = isXML( elem );\n\n if ( !xml ) {\n name = name.toLowerCase();\n }\n if ( (val = Expr.attrHandle[ name ]) ) {\n return val( elem );\n }\n if ( xml || assertAttributes ) {\n return elem.getAttribute( name );\n }\n val = elem.getAttributeNode( name );\n return val ?\n typeof elem[ name ] === \"boolean\" ?\n elem[ name ] ? name : null :\n val.specified ? val.value : null :\n null;\n};\n\nExpr = Sizzle.selectors = {\n\n // Can be adjusted by the user\n cacheLength: 50,\n\n createPseudo: markFunction,\n\n match: matchExpr,\n\n // IE6/7 return a modified href\n attrHandle: assertHrefNotNormalized ?\n {} :\n {\n \"href\": function( elem ) {\n return elem.getAttribute( \"href\", 2 );\n },\n \"type\": function( elem ) {\n return elem.getAttribute(\"type\");\n }\n },\n\n find: {\n \"ID\": assertGetIdNotName ?\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n return m && m.parentNode ? [m] : [];\n }\n } :\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n\n return m ?\n m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode(\"id\").value === id ?\n [m] :\n undefined :\n [];\n }\n },\n\n \"TAG\": assertTagNameNoComments ?\n function( tag, context ) {\n if ( typeof context.getElementsByTagName !== strundefined ) {\n return context.getElementsByTagName( tag );\n }\n } :\n function( tag, context ) {\n var results = context.getElementsByTagName( tag );\n\n // Filter out possible comments\n if ( tag === \"*\" ) {\n var elem,\n tmp = [],\n i = 0;\n\n for ( ; (elem = results[i]); i++ ) {\n if ( elem.nodeType === 1 ) {\n tmp.push( elem );\n }\n }\n\n return tmp;\n }\n return results;\n },\n\n \"NAME\": assertUsableName && function( tag, context ) {\n if ( typeof context.getElementsByName !== strundefined ) {\n return context.getElementsByName( name );\n }\n },\n\n \"CLASS\": assertUsableClassName && function( className, context, xml ) {\n if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\n return context.getElementsByClassName( className );\n }\n }\n },\n\n relative: {\n \">\": { dir: \"parentNode\", first: true },\n \" \": { dir: \"parentNode\" },\n \"+\": { dir: \"previousSibling\", first: true },\n \"~\": { dir: \"previousSibling\" }\n },\n\n preFilter: {\n \"ATTR\": function( match ) {\n match[1] = match[1].replace( rbackslash, \"\" );\n\n // Move the given value to match[3] whether quoted or unquoted\n match[3] = ( match[4] || match[5] || \"\" ).replace( rbackslash, \"\" );\n\n if ( match[2] === \"~=\" ) {\n match[3] = \" \" + match[3] + \" \";\n }\n\n return match.slice( 0, 4 );\n },\n\n \"CHILD\": function( match ) {\n /* matches from matchExpr[\"CHILD\"]\n 1 type (only|nth|...)\n 2 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n 3 xn-component of xn+y argument ([+-]?\\d*n|)\n 4 sign of xn-component\n 5 x of xn-component\n 6 sign of y-component\n 7 y of y-component\n */\n match[1] = match[1].toLowerCase();\n\n if ( match[1] === \"nth\" ) {\n // nth-child requires argument\n if ( !match[2] ) {\n Sizzle.error( match[0] );\n }\n\n // numeric x and y parameters for Expr.filter.CHILD\n // remember that false/true cast respectively to 0/1\n match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === \"even\" || match[2] === \"odd\" ) );\n match[4] = +( ( match[6] + match[7] ) || match[2] === \"odd\" );\n\n // other types prohibit arguments\n } else if ( match[2] ) {\n Sizzle.error( match[0] );\n }\n\n return match;\n },\n\n \"PSEUDO\": function( match ) {\n var unquoted, excess;\n if ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n return null;\n }\n\n if ( match[3] ) {\n match[2] = match[3];\n } else if ( (unquoted = match[4]) ) {\n // Only check arguments that contain a pseudo\n if ( rpseudo.test(unquoted) &&\n // Get excess from tokenize (recursively)\n (excess = tokenize( unquoted, true )) &&\n // advance to the next closing parenthesis\n (excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n // excess is a negative index\n unquoted = unquoted.slice( 0, excess );\n match[0] = match[0].slice( 0, excess );\n }\n match[2] = unquoted;\n }\n\n // Return only captures needed by the pseudo filter method (type and argument)\n return match.slice( 0, 3 );\n }\n },\n\n filter: {\n \"ID\": assertGetIdNotName ?\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n return elem.getAttribute(\"id\") === id;\n };\n } :\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n return node && node.value === id;\n };\n },\n\n \"TAG\": function( nodeName ) {\n if ( nodeName === \"*\" ) {\n return function() { return true; };\n }\n nodeName = nodeName.replace( rbackslash, \"\" ).toLowerCase();\n\n return function( elem ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n };\n },\n\n \"CLASS\": function( className ) {\n var pattern = classCache[ expando ][ className + \" \" ];\n\n return pattern ||\n (pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n classCache( className, function( elem ) {\n return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\")) || \"\" );\n });\n },\n\n \"ATTR\": function( name, operator, check ) {\n return function( elem, context ) {\n var result = Sizzle.attr( elem, name );\n\n if ( result == null ) {\n return operator === \"!=\";\n }\n if ( !operator ) {\n return true;\n }\n\n result += \"\";\n\n return operator === \"=\" ? result === check :\n operator === \"!=\" ? result !== check :\n operator === \"^=\" ? check && result.indexOf( check ) === 0 :\n operator === \"*=\" ? check && result.indexOf( check ) > -1 :\n operator === \"$=\" ? check && result.substr( result.length - check.length ) === check :\n operator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n operator === \"|=\" ? result === check || result.substr( 0, check.length + 1 ) === check + \"-\" :\n false;\n };\n },\n\n \"CHILD\": function( type, argument, first, last ) {\n\n if ( type === \"nth\" ) {\n return function( elem ) {\n var node, diff,\n parent = elem.parentNode;\n\n if ( first === 1 && last === 0 ) {\n return true;\n }\n\n if ( parent ) {\n diff = 0;\n for ( node = parent.firstChild; node; node = node.nextSibling ) {\n if ( node.nodeType === 1 ) {\n diff++;\n if ( elem === node ) {\n break;\n }\n }\n }\n }\n\n // Incorporate the offset (or cast to NaN), then check against cycle size\n diff -= last;\n return diff === first || ( diff % first === 0 && diff / first >= 0 );\n };\n }\n\n return function( elem ) {\n var node = elem;\n\n switch ( type ) {\n case \"only\":\n case \"first\":\n while ( (node = node.previousSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n if ( type === \"first\" ) {\n return true;\n }\n\n node = elem;\n\n /* falls through */\n case \"last\":\n while ( (node = node.nextSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n return true;\n }\n };\n },\n\n \"PSEUDO\": function( pseudo, argument ) {\n // pseudo-class names are case-insensitive\n // http://www.w3.org/TR/selectors/#pseudo-classes\n // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n // Remember that setFilters inherits from pseudos\n var args,\n fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n Sizzle.error( \"unsupported pseudo: \" + pseudo );\n\n // The user may use createPseudo to indicate that\n // arguments are needed to create the filter function\n // just as Sizzle does\n if ( fn[ expando ] ) {\n return fn( argument );\n }\n\n // But maintain support for old signatures\n if ( fn.length > 1 ) {\n args = [ pseudo, pseudo, \"\", argument ];\n return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n markFunction(function( seed, matches ) {\n var idx,\n matched = fn( seed, argument ),\n i = matched.length;\n while ( i-- ) {\n idx = indexOf.call( seed, matched[i] );\n seed[ idx ] = !( matches[ idx ] = matched[i] );\n }\n }) :\n function( elem ) {\n return fn( elem, 0, args );\n };\n }\n\n return fn;\n }\n },\n\n pseudos: {\n \"not\": markFunction(function( selector ) {\n // Trim the selector passed to compile\n // to avoid treating leading and trailing\n // spaces as combinators\n var input = [],\n results = [],\n matcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n return matcher[ expando ] ?\n markFunction(function( seed, matches, context, xml ) {\n var elem,\n unmatched = matcher( seed, null, xml, [] ),\n i = seed.length;\n\n // Match elements unmatched by `matcher`\n while ( i-- ) {\n if ( (elem = unmatched[i]) ) {\n seed[i] = !(matches[i] = elem);\n }\n }\n }) :\n function( elem, context, xml ) {\n input[0] = elem;\n matcher( input, null, xml, results );\n return !results.pop();\n };\n }),\n\n \"has\": markFunction(function( selector ) {\n return function( elem ) {\n return Sizzle( selector, elem ).length > 0;\n };\n }),\n\n \"contains\": markFunction(function( text ) {\n return function( elem ) {\n return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n };\n }),\n\n \"enabled\": function( elem ) {\n return elem.disabled === false;\n },\n\n \"disabled\": function( elem ) {\n return elem.disabled === true;\n },\n\n \"checked\": function( elem ) {\n // In CSS3, :checked should return both checked and selected elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n var nodeName = elem.nodeName.toLowerCase();\n return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n },\n\n \"selected\": function( elem ) {\n // Accessing this property makes selected-by-default\n // options in Safari work properly\n if ( elem.parentNode ) {\n elem.parentNode.selectedIndex;\n }\n\n return elem.selected === true;\n },\n\n \"parent\": function( elem ) {\n return !Expr.pseudos[\"empty\"]( elem );\n },\n\n \"empty\": function( elem ) {\n // http://www.w3.org/TR/selectors/#empty-pseudo\n // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n // not comment, processing instructions, or others\n // Thanks to Diego Perini for the nodeName shortcut\n // Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n var nodeType;\n elem = elem.firstChild;\n while ( elem ) {\n if ( elem.nodeName > \"@\" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {\n return false;\n }\n elem = elem.nextSibling;\n }\n return true;\n },\n\n \"header\": function( elem ) {\n return rheader.test( elem.nodeName );\n },\n\n \"text\": function( elem ) {\n var type, attr;\n // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n // use getAttribute instead to test this case\n return elem.nodeName.toLowerCase() === \"input\" &&\n (type = elem.type) === \"text\" &&\n ( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === type );\n },\n\n // Input types\n \"radio\": createInputPseudo(\"radio\"),\n \"checkbox\": createInputPseudo(\"checkbox\"),\n \"file\": createInputPseudo(\"file\"),\n \"password\": createInputPseudo(\"password\"),\n \"image\": createInputPseudo(\"image\"),\n\n \"submit\": createButtonPseudo(\"submit\"),\n \"reset\": createButtonPseudo(\"reset\"),\n\n \"button\": function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === \"button\" || name === \"button\";\n },\n\n \"input\": function( elem ) {\n return rinputs.test( elem.nodeName );\n },\n\n \"focus\": function( elem ) {\n var doc = elem.ownerDocument;\n return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n },\n\n \"active\": function( elem ) {\n return elem === elem.ownerDocument.activeElement;\n },\n\n // Positional types\n \"first\": createPositionalPseudo(function() {\n return [ 0 ];\n }),\n\n \"last\": createPositionalPseudo(function( matchIndexes, length ) {\n return [ length - 1 ];\n }),\n\n \"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n return [ argument < 0 ? argument + length : argument ];\n }),\n\n \"even\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 0; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 1; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n })\n }\n};\n\nfunction siblingCheck( a, b, ret ) {\n if ( a === b ) {\n return ret;\n }\n\n var cur = a.nextSibling;\n\n while ( cur ) {\n if ( cur === b ) {\n return -1;\n }\n\n cur = cur.nextSibling;\n }\n\n return 1;\n}\n\nsortOrder = docElem.compareDocumentPosition ?\n function( a, b ) {\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n }\n\n return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?\n a.compareDocumentPosition :\n a.compareDocumentPosition(b) & 4\n ) ? -1 : 1;\n } :\n function( a, b ) {\n // The nodes are identical, we can exit early\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n\n // Fallback to using sourceIndex (in IE) if it's available on both nodes\n } else if ( a.sourceIndex && b.sourceIndex ) {\n return a.sourceIndex - b.sourceIndex;\n }\n\n var al, bl,\n ap = [],\n bp = [],\n aup = a.parentNode,\n bup = b.parentNode,\n cur = aup;\n\n // If the nodes are siblings (or identical) we can do a quick check\n if ( aup === bup ) {\n return siblingCheck( a, b );\n\n // If no parents were found then the nodes are disconnected\n } else if ( !aup ) {\n return -1;\n\n } else if ( !bup ) {\n return 1;\n }\n\n // Otherwise they're somewhere else in the tree so we need\n // to build up a full list of the parentNodes for comparison\n while ( cur ) {\n ap.unshift( cur );\n cur = cur.parentNode;\n }\n\n cur = bup;\n\n while ( cur ) {\n bp.unshift( cur );\n cur = cur.parentNode;\n }\n\n al = ap.length;\n bl = bp.length;\n\n // Start walking down the tree looking for a discrepancy\n for ( var i = 0; i < al && i < bl; i++ ) {\n if ( ap[i] !== bp[i] ) {\n return siblingCheck( ap[i], bp[i] );\n }\n }\n\n // We ended someplace up the tree so do a sibling check\n return i === al ?\n siblingCheck( a, bp[i], -1 ) :\n siblingCheck( ap[i], b, 1 );\n };\n\n// Always assume the presence of duplicates if sort doesn't\n// pass them to our comparison function (as in Google Chrome).\n[0, 0].sort( sortOrder );\nbaseHasDuplicate = !hasDuplicate;\n\n// Document sorting and removing duplicates\nSizzle.uniqueSort = function( results ) {\n var elem,\n duplicates = [],\n i = 1,\n j = 0;\n\n hasDuplicate = baseHasDuplicate;\n results.sort( sortOrder );\n\n if ( hasDuplicate ) {\n for ( ; (elem = results[i]); i++ ) {\n if ( elem === results[ i - 1 ] ) {\n j = duplicates.push( i );\n }\n }\n while ( j-- ) {\n results.splice( duplicates[ j ], 1 );\n }\n }\n\n return results;\n};\n\nSizzle.error = function( msg ) {\n throw new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nfunction tokenize( selector, parseOnly ) {\n var matched, match, tokens, type,\n soFar, groups, preFilters,\n cached = tokenCache[ expando ][ selector + \" \" ];\n\n if ( cached ) {\n return parseOnly ? 0 : cached.slice( 0 );\n }\n\n soFar = selector;\n groups = [];\n preFilters = Expr.preFilter;\n\n while ( soFar ) {\n\n // Comma and first run\n if ( !matched || (match = rcomma.exec( soFar )) ) {\n if ( match ) {\n // Don't consume trailing commas as valid\n soFar = soFar.slice( match[0].length ) || soFar;\n }\n groups.push( tokens = [] );\n }\n\n matched = false;\n\n // Combinators\n if ( (match = rcombinators.exec( soFar )) ) {\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n\n // Cast descendant combinators to space\n matched.type = match[0].replace( rtrim, \" \" );\n }\n\n // Filters\n for ( type in Expr.filter ) {\n if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n (match = preFilters[ type ]( match ))) ) {\n\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n matched.type = type;\n matched.matches = match;\n }\n }\n\n if ( !matched ) {\n break;\n }\n }\n\n // Return the length of the invalid excess\n // if we're just parsing\n // Otherwise, throw an error or return tokens\n return parseOnly ?\n soFar.length :\n soFar ?\n Sizzle.error( selector ) :\n // Cache the tokens\n tokenCache( selector, groups ).slice( 0 );\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n var dir = combinator.dir,\n checkNonElements = base && combinator.dir === \"parentNode\",\n doneName = done++;\n\n return combinator.first ?\n // Check against closest ancestor/preceding element\n function( elem, context, xml ) {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n return matcher( elem, context, xml );\n }\n }\n } :\n\n // Check against all ancestor/preceding elements\n function( elem, context, xml ) {\n // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n if ( !xml ) {\n var cache,\n dirkey = dirruns + \" \" + doneName + \" \",\n cachedkey = dirkey + cachedruns;\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( (cache = elem[ expando ]) === cachedkey ) {\n return elem.sizset;\n } else if ( typeof cache === \"string\" && cache.indexOf(dirkey) === 0 ) {\n if ( elem.sizset ) {\n return elem;\n }\n } else {\n elem[ expando ] = cachedkey;\n if ( matcher( elem, context, xml ) ) {\n elem.sizset = true;\n return elem;\n }\n elem.sizset = false;\n }\n }\n }\n } else {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( matcher( elem, context, xml ) ) {\n return elem;\n }\n }\n }\n }\n };\n}\n\nfunction elementMatcher( matchers ) {\n return matchers.length > 1 ?\n function( elem, context, xml ) {\n var i = matchers.length;\n while ( i-- ) {\n if ( !matchers[i]( elem, context, xml ) ) {\n return false;\n }\n }\n return true;\n } :\n matchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n var elem,\n newUnmatched = [],\n i = 0,\n len = unmatched.length,\n mapped = map != null;\n\n for ( ; i < len; i++ ) {\n if ( (elem = unmatched[i]) ) {\n if ( !filter || filter( elem, context, xml ) ) {\n newUnmatched.push( elem );\n if ( mapped ) {\n map.push( i );\n }\n }\n }\n }\n\n return newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n if ( postFilter && !postFilter[ expando ] ) {\n postFilter = setMatcher( postFilter );\n }\n if ( postFinder && !postFinder[ expando ] ) {\n postFinder = setMatcher( postFinder, postSelector );\n }\n return markFunction(function( seed, results, context, xml ) {\n var temp, i, elem,\n preMap = [],\n postMap = [],\n preexisting = results.length,\n\n // Get initial elements from seed or context\n elems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n // Prefilter to get matcher input, preserving a map for seed-results synchronization\n matcherIn = preFilter && ( seed || !selector ) ?\n condense( elems, preMap, preFilter, context, xml ) :\n elems,\n\n matcherOut = matcher ?\n // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n // ...intermediate processing is necessary\n [] :\n\n // ...otherwise use results directly\n results :\n matcherIn;\n\n // Find primary matches\n if ( matcher ) {\n matcher( matcherIn, matcherOut, context, xml );\n }\n\n // Apply postFilter\n if ( postFilter ) {\n temp = condense( matcherOut, postMap );\n postFilter( temp, [], context, xml );\n\n // Un-match failing elements by moving them back to matcherIn\n i = temp.length;\n while ( i-- ) {\n if ( (elem = temp[i]) ) {\n matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n }\n }\n }\n\n if ( seed ) {\n if ( postFinder || preFilter ) {\n if ( postFinder ) {\n // Get the final matcherOut by condensing this intermediate into postFinder contexts\n temp = [];\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) ) {\n // Restore matcherIn since elem is not yet a final match\n temp.push( (matcherIn[i] = elem) );\n }\n }\n postFinder( null, (matcherOut = []), temp, xml );\n }\n\n // Move matched elements from seed to results to keep them synchronized\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) &&\n (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n seed[temp] = !(results[temp] = elem);\n }\n }\n }\n\n // Add elements to results, through postFinder if defined\n } else {\n matcherOut = condense(\n matcherOut === results ?\n matcherOut.splice( preexisting, matcherOut.length ) :\n matcherOut\n );\n if ( postFinder ) {\n postFinder( null, results, matcherOut, xml );\n } else {\n push.apply( results, matcherOut );\n }\n }\n });\n}\n\nfunction matcherFromTokens( tokens ) {\n var checkContext, matcher, j,\n len = tokens.length,\n leadingRelative = Expr.relative[ tokens[0].type ],\n implicitRelative = leadingRelative || Expr.relative[\" \"],\n i = leadingRelative ? 1 : 0,\n\n // The foundational matcher ensures that elements are reachable from top-level context(s)\n matchContext = addCombinator( function( elem ) {\n return elem === checkContext;\n }, implicitRelative, true ),\n matchAnyContext = addCombinator( function( elem ) {\n return indexOf.call( checkContext, elem ) > -1;\n }, implicitRelative, true ),\n matchers = [ function( elem, context, xml ) {\n return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n (checkContext = context).nodeType ?\n matchContext( elem, context, xml ) :\n matchAnyContext( elem, context, xml ) );\n } ];\n\n for ( ; i < len; i++ ) {\n if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n } else {\n matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n // Return special upon seeing a positional matcher\n if ( matcher[ expando ] ) {\n // Find the next relative operator (if any) for proper handling\n j = ++i;\n for ( ; j < len; j++ ) {\n if ( Expr.relative[ tokens[j].type ] ) {\n break;\n }\n }\n return setMatcher(\n i > 1 && elementMatcher( matchers ),\n i > 1 && tokens.slice( 0, i - 1 ).join(\"\").replace( rtrim, \"$1\" ),\n matcher,\n i < j && matcherFromTokens( tokens.slice( i, j ) ),\n j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n j < len && tokens.join(\"\")\n );\n }\n matchers.push( matcher );\n }\n }\n\n return elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n var bySet = setMatchers.length > 0,\n byElement = elementMatchers.length > 0,\n superMatcher = function( seed, context, xml, results, expandContext ) {\n var elem, j, matcher,\n setMatched = [],\n matchedCount = 0,\n i = \"0\",\n unmatched = seed && [],\n outermost = expandContext != null,\n contextBackup = outermostContext,\n // We must always have either seed elements or context\n elems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n // Nested matchers should use non-integer dirruns\n dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\n\n if ( outermost ) {\n outermostContext = context !== document && context;\n cachedruns = superMatcher.el;\n }\n\n // Add elements passing elementMatchers directly to results\n for ( ; (elem = elems[i]) != null; i++ ) {\n if ( byElement && elem ) {\n for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\n if ( matcher( elem, context, xml ) ) {\n results.push( elem );\n break;\n }\n }\n if ( outermost ) {\n dirruns = dirrunsUnique;\n cachedruns = ++superMatcher.el;\n }\n }\n\n // Track unmatched elements for set filters\n if ( bySet ) {\n // They will have gone through all possible matchers\n if ( (elem = !matcher && elem) ) {\n matchedCount--;\n }\n\n // Lengthen the array for every element, matched or not\n if ( seed ) {\n unmatched.push( elem );\n }\n }\n }\n\n // Apply set filters to unmatched elements\n matchedCount += i;\n if ( bySet && i !== matchedCount ) {\n for ( j = 0; (matcher = setMatchers[j]); j++ ) {\n matcher( unmatched, setMatched, context, xml );\n }\n\n if ( seed ) {\n // Reintegrate element matches to eliminate the need for sorting\n if ( matchedCount > 0 ) {\n while ( i-- ) {\n if ( !(unmatched[i] || setMatched[i]) ) {\n setMatched[i] = pop.call( results );\n }\n }\n }\n\n // Discard index placeholder values to get only actual matches\n setMatched = condense( setMatched );\n }\n\n // Add matches to results\n push.apply( results, setMatched );\n\n // Seedless set matches succeeding multiple successful matchers stipulate sorting\n if ( outermost && !seed && setMatched.length > 0 &&\n ( matchedCount + setMatchers.length ) > 1 ) {\n\n Sizzle.uniqueSort( results );\n }\n }\n\n // Override manipulation of globals by nested matchers\n if ( outermost ) {\n dirruns = dirrunsUnique;\n outermostContext = contextBackup;\n }\n\n return unmatched;\n };\n\n superMatcher.el = 0;\n return bySet ?\n markFunction( superMatcher ) :\n superMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n var i,\n setMatchers = [],\n elementMatchers = [],\n cached = compilerCache[ expando ][ selector + \" \" ];\n\n if ( !cached ) {\n // Generate a function of recursive functions that can be used to check each element\n if ( !group ) {\n group = tokenize( selector );\n }\n i = group.length;\n while ( i-- ) {\n cached = matcherFromTokens( group[i] );\n if ( cached[ expando ] ) {\n setMatchers.push( cached );\n } else {\n elementMatchers.push( cached );\n }\n }\n\n // Cache the compiled function\n cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n }\n return cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n var i = 0,\n len = contexts.length;\n for ( ; i < len; i++ ) {\n Sizzle( selector, contexts[i], results );\n }\n return results;\n}\n\nfunction select( selector, context, results, seed, xml ) {\n var i, tokens, token, type, find,\n match = tokenize( selector ),\n j = match.length;\n\n if ( !seed ) {\n // Try to minimize operations if there is only one group\n if ( match.length === 1 ) {\n\n // Take a shortcut and set the context if the root selector is an ID\n tokens = match[0] = match[0].slice( 0 );\n if ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n context.nodeType === 9 && !xml &&\n Expr.relative[ tokens[1].type ] ) {\n\n context = Expr.find[\"ID\"]( token.matches[0].replace( rbackslash, \"\" ), context, xml )[0];\n if ( !context ) {\n return results;\n }\n\n selector = selector.slice( tokens.shift().length );\n }\n\n // Fetch a seed set for right-to-left matching\n for ( i = matchExpr[\"POS\"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\n token = tokens[i];\n\n // Abort if we hit a combinator\n if ( Expr.relative[ (type = token.type) ] ) {\n break;\n }\n if ( (find = Expr.find[ type ]) ) {\n // Search, expanding context for leading sibling combinators\n if ( (seed = find(\n token.matches[0].replace( rbackslash, \"\" ),\n rsibling.test( tokens[0].type ) && context.parentNode || context,\n xml\n )) ) {\n\n // If seed is empty or no tokens remain, we can return early\n tokens.splice( i, 1 );\n selector = seed.length && tokens.join(\"\");\n if ( !selector ) {\n push.apply( results, slice.call( seed, 0 ) );\n return results;\n }\n\n break;\n }\n }\n }\n }\n }\n\n // Compile and execute a filtering function\n // Provide `match` to avoid retokenization if we modified the selector above\n compile( selector, match )(\n seed,\n context,\n xml,\n results,\n rsibling.test( selector )\n );\n return results;\n}\n\nif ( document.querySelectorAll ) {\n (function() {\n var disconnectedMatch,\n oldSelect = select,\n rescape = /'|\\\\/g,\n rattributeQuotes = /\\=[\\x20\\t\\r\\n\\f]*([^'\"\\]]*)[\\x20\\t\\r\\n\\f]*\\]/g,\n\n // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\n // A support test would require too much code (would include document ready)\n rbuggyQSA = [ \":focus\" ],\n\n // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n // A support test would require too much code (would include document ready)\n // just skip matchesSelector for :active\n rbuggyMatches = [ \":active\" ],\n matches = docElem.matchesSelector ||\n docElem.mozMatchesSelector ||\n docElem.webkitMatchesSelector ||\n docElem.oMatchesSelector ||\n docElem.msMatchesSelector;\n\n // Build QSA regex\n // Regex strategy adopted from Diego Perini\n assert(function( div ) {\n // Select is set to empty string on purpose\n // This is to test IE's treatment of not explictly\n // setting a boolean content attribute,\n // since its presence should be enough\n // http://bugs.jquery.com/ticket/12359\n div.innerHTML = \"\";\n\n // IE8 - Some boolean attributes are not treated correctly\n if ( !div.querySelectorAll(\"[selected]\").length ) {\n rbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:checked|disabled|ismap|multiple|readonly|selected|value)\" );\n }\n\n // Webkit/Opera - :checked should return selected option elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n // IE8 throws error here (do not put tests after this one)\n if ( !div.querySelectorAll(\":checked\").length ) {\n rbuggyQSA.push(\":checked\");\n }\n });\n\n assert(function( div ) {\n\n // Opera 10-12/IE9 - ^= $= *= and empty values\n // Should not select anything\n div.innerHTML = \"

\";\n if ( div.querySelectorAll(\"[test^='']\").length ) {\n rbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:\\\"\\\"|'')\" );\n }\n\n // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n // IE8 throws error here (do not put tests after this one)\n div.innerHTML = \"\";\n if ( !div.querySelectorAll(\":enabled\").length ) {\n rbuggyQSA.push(\":enabled\", \":disabled\");\n }\n });\n\n // rbuggyQSA always contains :focus, so no need for a length check\n rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join(\"|\") );\n\n select = function( selector, context, results, seed, xml ) {\n // Only use querySelectorAll when not filtering,\n // when this is not xml,\n // and when no QSA bugs apply\n if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\n var groups, i,\n old = true,\n nid = expando,\n newContext = context,\n newSelector = context.nodeType === 9 && selector;\n\n // qSA works strangely on Element-rooted queries\n // We can work around this by specifying an extra ID on the root\n // and working up from there (Thanks to Andrew Dupont for the technique)\n // IE 8 doesn't work on object elements\n if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n groups = tokenize( selector );\n\n if ( (old = context.getAttribute(\"id\")) ) {\n nid = old.replace( rescape, \"\\\\$&\" );\n } else {\n context.setAttribute( \"id\", nid );\n }\n nid = \"[id='\" + nid + \"'] \";\n\n i = groups.length;\n while ( i-- ) {\n groups[i] = nid + groups[i].join(\"\");\n }\n newContext = rsibling.test( selector ) && context.parentNode || context;\n newSelector = groups.join(\",\");\n }\n\n if ( newSelector ) {\n try {\n push.apply( results, slice.call( newContext.querySelectorAll(\n newSelector\n ), 0 ) );\n return results;\n } catch(qsaError) {\n } finally {\n if ( !old ) {\n context.removeAttribute(\"id\");\n }\n }\n }\n }\n\n return oldSelect( selector, context, results, seed, xml );\n };\n\n if ( matches ) {\n assert(function( div ) {\n // Check to see if it's possible to do matchesSelector\n // on a disconnected node (IE 9)\n disconnectedMatch = matches.call( div, \"div\" );\n\n // This should fail with an exception\n // Gecko does not error, returns false instead\n try {\n matches.call( div, \"[test!='']:sizzle\" );\n rbuggyMatches.push( \"!=\", pseudos );\n } catch ( e ) {}\n });\n\n // rbuggyMatches always contains :active and :focus, so no need for a length check\n rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join(\"|\") );\n\n Sizzle.matchesSelector = function( elem, expr ) {\n // Make sure that attribute selectors are quoted\n expr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n // rbuggyMatches always contains :active, so no need for an existence check\n if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\n try {\n var ret = matches.call( elem, expr );\n\n // IE 9's matchesSelector returns false on disconnected nodes\n if ( ret || disconnectedMatch ||\n // As well, disconnected nodes are said to be in a document\n // fragment in IE 9\n elem.document && elem.document.nodeType !== 11 ) {\n return ret;\n }\n } catch(e) {}\n }\n\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n };\n }\n })();\n}\n\n// Deprecated\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Back-compat\nfunction setFilters() {}\nExpr.filters = setFilters.prototype = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\n// Override sizzle attribute retrieval\nSizzle.attr = jQuery.attr;\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\nvar runtil = /Until$/,\n rparentsprev = /^(?:parents|prev(?:Until|All))/,\n isSimple = /^.[^:#\\[\\.,]*$/,\n rneedsContext = jQuery.expr.match.needsContext,\n // methods guaranteed to produce a unique set when starting from a unique set\n guaranteedUnique = {\n children: true,\n contents: true,\n next: true,\n prev: true\n };\n\njQuery.fn.extend({\n find: function( selector ) {\n var i, l, length, n, r, ret,\n self = this;\n\n if ( typeof selector !== \"string\" ) {\n return jQuery( selector ).filter(function() {\n for ( i = 0, l = self.length; i < l; i++ ) {\n if ( jQuery.contains( self[ i ], this ) ) {\n return true;\n }\n }\n });\n }\n\n ret = this.pushStack( \"\", \"find\", selector );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n length = ret.length;\n jQuery.find( selector, this[i], ret );\n\n if ( i > 0 ) {\n // Make sure that the results are unique\n for ( n = length; n < ret.length; n++ ) {\n for ( r = 0; r < length; r++ ) {\n if ( ret[r] === ret[n] ) {\n ret.splice(n--, 1);\n break;\n }\n }\n }\n }\n }\n\n return ret;\n },\n\n has: function( target ) {\n var i,\n targets = jQuery( target, this ),\n len = targets.length;\n\n return this.filter(function() {\n for ( i = 0; i < len; i++ ) {\n if ( jQuery.contains( this, targets[i] ) ) {\n return true;\n }\n }\n });\n },\n\n not: function( selector ) {\n return this.pushStack( winnow(this, selector, false), \"not\", selector);\n },\n\n filter: function( selector ) {\n return this.pushStack( winnow(this, selector, true), \"filter\", selector );\n },\n\n is: function( selector ) {\n return !!selector && (\n typeof selector === \"string\" ?\n // If this is a positional/relative selector, check membership in the returned set\n // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n rneedsContext.test( selector ) ?\n jQuery( selector, this.context ).index( this[0] ) >= 0 :\n jQuery.filter( selector, this ).length > 0 :\n this.filter( selector ).length > 0 );\n },\n\n closest: function( selectors, context ) {\n var cur,\n i = 0,\n l = this.length,\n ret = [],\n pos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n jQuery( selectors, context || this.context ) :\n 0;\n\n for ( ; i < l; i++ ) {\n cur = this[i];\n\n while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {\n if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n ret.push( cur );\n break;\n }\n cur = cur.parentNode;\n }\n }\n\n ret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n return this.pushStack( ret, \"closest\", selectors );\n },\n\n // Determine the position of an element within\n // the matched set of elements\n index: function( elem ) {\n\n // No argument, return index in parent\n if ( !elem ) {\n return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n }\n\n // index in selector\n if ( typeof elem === \"string\" ) {\n return jQuery.inArray( this[0], jQuery( elem ) );\n }\n\n // Locate the position of the desired element\n return jQuery.inArray(\n // If it receives a jQuery object, the first element is used\n elem.jquery ? elem[0] : elem, this );\n },\n\n add: function( selector, context ) {\n var set = typeof selector === \"string\" ?\n jQuery( selector, context ) :\n jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n all = jQuery.merge( this.get(), set );\n\n return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n all :\n jQuery.unique( all ) );\n },\n\n addBack: function( selector ) {\n return this.add( selector == null ?\n this.prevObject : this.prevObject.filter(selector)\n );\n }\n});\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n return !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\nfunction sibling( cur, dir ) {\n do {\n cur = cur[ dir ];\n } while ( cur && cur.nodeType !== 1 );\n\n return cur;\n}\n\njQuery.each({\n parent: function( elem ) {\n var parent = elem.parentNode;\n return parent && parent.nodeType !== 11 ? parent : null;\n },\n parents: function( elem ) {\n return jQuery.dir( elem, \"parentNode\" );\n },\n parentsUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"parentNode\", until );\n },\n next: function( elem ) {\n return sibling( elem, \"nextSibling\" );\n },\n prev: function( elem ) {\n return sibling( elem, \"previousSibling\" );\n },\n nextAll: function( elem ) {\n return jQuery.dir( elem, \"nextSibling\" );\n },\n prevAll: function( elem ) {\n return jQuery.dir( elem, \"previousSibling\" );\n },\n nextUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"nextSibling\", until );\n },\n prevUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"previousSibling\", until );\n },\n siblings: function( elem ) {\n return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n },\n children: function( elem ) {\n return jQuery.sibling( elem.firstChild );\n },\n contents: function( elem ) {\n return jQuery.nodeName( elem, \"iframe\" ) ?\n elem.contentDocument || elem.contentWindow.document :\n jQuery.merge( [], elem.childNodes );\n }\n}, function( name, fn ) {\n jQuery.fn[ name ] = function( until, selector ) {\n var ret = jQuery.map( this, fn, until );\n\n if ( !runtil.test( name ) ) {\n selector = until;\n }\n\n if ( selector && typeof selector === \"string\" ) {\n ret = jQuery.filter( selector, ret );\n }\n\n ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n if ( this.length > 1 && rparentsprev.test( name ) ) {\n ret = ret.reverse();\n }\n\n return this.pushStack( ret, name, core_slice.call( arguments ).join(\",\") );\n };\n});\n\njQuery.extend({\n filter: function( expr, elems, not ) {\n if ( not ) {\n expr = \":not(\" + expr + \")\";\n }\n\n return elems.length === 1 ?\n jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n jQuery.find.matches(expr, elems);\n },\n\n dir: function( elem, dir, until ) {\n var matched = [],\n cur = elem[ dir ];\n\n while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n if ( cur.nodeType === 1 ) {\n matched.push( cur );\n }\n cur = cur[dir];\n }\n return matched;\n },\n\n sibling: function( n, elem ) {\n var r = [];\n\n for ( ; n; n = n.nextSibling ) {\n if ( n.nodeType === 1 && n !== elem ) {\n r.push( n );\n }\n }\n\n return r;\n }\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n // Can't pass null or undefined to indexOf in Firefox 4\n // Set to 0 to skip string check\n qualifier = qualifier || 0;\n\n if ( jQuery.isFunction( qualifier ) ) {\n return jQuery.grep(elements, function( elem, i ) {\n var retVal = !!qualifier.call( elem, i, elem );\n return retVal === keep;\n });\n\n } else if ( qualifier.nodeType ) {\n return jQuery.grep(elements, function( elem, i ) {\n return ( elem === qualifier ) === keep;\n });\n\n } else if ( typeof qualifier === \"string\" ) {\n var filtered = jQuery.grep(elements, function( elem ) {\n return elem.nodeType === 1;\n });\n\n if ( isSimple.test( qualifier ) ) {\n return jQuery.filter(qualifier, filtered, !keep);\n } else {\n qualifier = jQuery.filter( qualifier, filtered );\n }\n }\n\n return jQuery.grep(elements, function( elem, i ) {\n return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;\n });\n}\nfunction createSafeFragment( document ) {\n var list = nodeNames.split( \"|\" ),\n safeFrag = document.createDocumentFragment();\n\n if ( safeFrag.createElement ) {\n while ( list.length ) {\n safeFrag.createElement(\n list.pop()\n );\n }\n }\n return safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n \"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n rinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n rleadingWhitespace = /^\\s+/,\n rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n rtagName = /<([\\w:]+)/,\n rtbody = /]\", \"i\"),\n rcheckableType = /^(?:checkbox|radio)$/,\n // checked=\"checked\" or checked\n rchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n rscriptType = /\\/(java|ecma)script/i,\n rcleanScript = /^\\s*\\s*$/g,\n wrapMap = {\n option: [ 1, \"\" ],\n legend: [ 1, \"
\", \"
\" ],\n thead: [ 1, \"\", \"
\" ],\n tr: [ 2, \"\", \"
\" ],\n td: [ 3, \"\", \"
\" ],\n col: [ 2, \"\", \"
\" ],\n area: [ 1, \"\", \"\" ],\n _default: [ 0, \"\", \"\" ]\n },\n safeFragment = createSafeFragment( document ),\n fragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n// unless wrapped in a div with non-breaking characters in front of it.\nif ( !jQuery.support.htmlSerialize ) {\n wrapMap._default = [ 1, \"X
\", \"
\" ];\n}\n\njQuery.fn.extend({\n text: function( value ) {\n return jQuery.access( this, function( value ) {\n return value === undefined ?\n jQuery.text( this ) :\n this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n }, null, value, arguments.length );\n },\n\n wrapAll: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapAll( html.call(this, i) );\n });\n }\n\n if ( this[0] ) {\n // The elements to wrap the target around\n var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n if ( this[0].parentNode ) {\n wrap.insertBefore( this[0] );\n }\n\n wrap.map(function() {\n var elem = this;\n\n while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n elem = elem.firstChild;\n }\n\n return elem;\n }).append( this );\n }\n\n return this;\n },\n\n wrapInner: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapInner( html.call(this, i) );\n });\n }\n\n return this.each(function() {\n var self = jQuery( this ),\n contents = self.contents();\n\n if ( contents.length ) {\n contents.wrapAll( html );\n\n } else {\n self.append( html );\n }\n });\n },\n\n wrap: function( html ) {\n var isFunction = jQuery.isFunction( html );\n\n return this.each(function(i) {\n jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n });\n },\n\n unwrap: function() {\n return this.parent().each(function() {\n if ( !jQuery.nodeName( this, \"body\" ) ) {\n jQuery( this ).replaceWith( this.childNodes );\n }\n }).end();\n },\n\n append: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.appendChild( elem );\n }\n });\n },\n\n prepend: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.insertBefore( elem, this.firstChild );\n }\n });\n },\n\n before: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( set, this ), \"before\", this.selector );\n }\n },\n\n after: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this.nextSibling );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( this, set ), \"after\", this.selector );\n }\n },\n\n // keepData is for internal use only--do not document\n remove: function( selector, keepData ) {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n if ( !keepData && elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n jQuery.cleanData( [ elem ] );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n }\n }\n\n return this;\n },\n\n empty: function() {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n // Remove element nodes and prevent memory leaks\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n }\n\n // Remove any remaining nodes\n while ( elem.firstChild ) {\n elem.removeChild( elem.firstChild );\n }\n }\n\n return this;\n },\n\n clone: function( dataAndEvents, deepDataAndEvents ) {\n dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n return this.map( function () {\n return jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n });\n },\n\n html: function( value ) {\n return jQuery.access( this, function( value ) {\n var elem = this[0] || {},\n i = 0,\n l = this.length;\n\n if ( value === undefined ) {\n return elem.nodeType === 1 ?\n elem.innerHTML.replace( rinlinejQuery, \"\" ) :\n undefined;\n }\n\n // See if we can take a shortcut and just use innerHTML\n if ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&\n ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n !wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n value = value.replace( rxhtmlTag, \"<$1>\" );\n\n try {\n for (; i < l; i++ ) {\n // Remove element nodes and prevent memory leaks\n elem = this[i] || {};\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName( \"*\" ) );\n elem.innerHTML = value;\n }\n }\n\n elem = 0;\n\n // If using innerHTML throws an exception, use the fallback method\n } catch(e) {}\n }\n\n if ( elem ) {\n this.empty().append( value );\n }\n }, null, value, arguments.length );\n },\n\n replaceWith: function( value ) {\n if ( !isDisconnected( this[0] ) ) {\n // Make sure that the elements are removed from the DOM before they are inserted\n // this can help fix replacing a parent with child elements\n if ( jQuery.isFunction( value ) ) {\n return this.each(function(i) {\n var self = jQuery(this), old = self.html();\n self.replaceWith( value.call( this, i, old ) );\n });\n }\n\n if ( typeof value !== \"string\" ) {\n value = jQuery( value ).detach();\n }\n\n return this.each(function() {\n var next = this.nextSibling,\n parent = this.parentNode;\n\n jQuery( this ).remove();\n\n if ( next ) {\n jQuery(next).before( value );\n } else {\n jQuery(parent).append( value );\n }\n });\n }\n\n return this.length ?\n this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n this;\n },\n\n detach: function( selector ) {\n return this.remove( selector, true );\n },\n\n domManip: function( args, table, callback ) {\n\n // Flatten any nested arrays\n args = [].concat.apply( [], args );\n\n var results, first, fragment, iNoClone,\n i = 0,\n value = args[0],\n scripts = [],\n l = this.length;\n\n // We can't cloneNode fragments that contain checked, in WebKit\n if ( !jQuery.support.checkClone && l > 1 && typeof value === \"string\" && rchecked.test( value ) ) {\n return this.each(function() {\n jQuery(this).domManip( args, table, callback );\n });\n }\n\n if ( jQuery.isFunction(value) ) {\n return this.each(function(i) {\n var self = jQuery(this);\n args[0] = value.call( this, i, table ? self.html() : undefined );\n self.domManip( args, table, callback );\n });\n }\n\n if ( this[0] ) {\n results = jQuery.buildFragment( args, this, scripts );\n fragment = results.fragment;\n first = fragment.firstChild;\n\n if ( fragment.childNodes.length === 1 ) {\n fragment = first;\n }\n\n if ( first ) {\n table = table && jQuery.nodeName( first, \"tr\" );\n\n // Use the original fragment for the last item instead of the first because it can end up\n // being emptied incorrectly in certain situations (#8070).\n // Fragments from the fragment cache must always be cloned and never used in place.\n for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {\n callback.call(\n table && jQuery.nodeName( this[i], \"table\" ) ?\n findOrAppend( this[i], \"tbody\" ) :\n this[i],\n i === iNoClone ?\n fragment :\n jQuery.clone( fragment, true, true )\n );\n }\n }\n\n // Fix #11809: Avoid leaking memory\n fragment = first = null;\n\n if ( scripts.length ) {\n jQuery.each( scripts, function( i, elem ) {\n if ( elem.src ) {\n if ( jQuery.ajax ) {\n jQuery.ajax({\n url: elem.src,\n type: \"GET\",\n dataType: \"script\",\n async: false,\n global: false,\n \"throws\": true\n });\n } else {\n jQuery.error(\"no ajax\");\n }\n } else {\n jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n });\n }\n }\n\n return this;\n }\n});\n\nfunction findOrAppend( elem, tag ) {\n return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n return;\n }\n\n var type, i, l,\n oldData = jQuery._data( src ),\n curData = jQuery._data( dest, oldData ),\n events = oldData.events;\n\n if ( events ) {\n delete curData.handle;\n curData.events = {};\n\n for ( type in events ) {\n for ( i = 0, l = events[ type ].length; i < l; i++ ) {\n jQuery.event.add( dest, type, events[ type ][ i ] );\n }\n }\n }\n\n // make the cloned public data object a copy from the original\n if ( curData.data ) {\n curData.data = jQuery.extend( {}, curData.data );\n }\n}\n\nfunction cloneFixAttributes( src, dest ) {\n var nodeName;\n\n // We do not need to do anything for non-Elements\n if ( dest.nodeType !== 1 ) {\n return;\n }\n\n // clearAttributes removes the attributes, which we don't want,\n // but also removes the attachEvent events, which we *do* want\n if ( dest.clearAttributes ) {\n dest.clearAttributes();\n }\n\n // mergeAttributes, in contrast, only merges back on the\n // original attributes, not the events\n if ( dest.mergeAttributes ) {\n dest.mergeAttributes( src );\n }\n\n nodeName = dest.nodeName.toLowerCase();\n\n if ( nodeName === \"object\" ) {\n // IE6-10 improperly clones children of object elements using classid.\n // IE10 throws NoModificationAllowedError if parent is null, #12132.\n if ( dest.parentNode ) {\n dest.outerHTML = src.outerHTML;\n }\n\n // This path appears unavoidable for IE9. When cloning an object\n // element in IE9, the outerHTML strategy above is not sufficient.\n // If the src has innerHTML and the destination does not,\n // copy the src.innerHTML into the dest.innerHTML. #10324\n if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {\n dest.innerHTML = src.innerHTML;\n }\n\n } else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n // IE6-8 fails to persist the checked state of a cloned checkbox\n // or radio button. Worse, IE6-7 fail to give the cloned element\n // a checked appearance if the defaultChecked value isn't also set\n\n dest.defaultChecked = dest.checked = src.checked;\n\n // IE6-7 get confused and end up setting the value of a cloned\n // checkbox/radio button to an empty string instead of \"on\"\n if ( dest.value !== src.value ) {\n dest.value = src.value;\n }\n\n // IE6-8 fails to return the selected option to the default selected\n // state when cloning options\n } else if ( nodeName === \"option\" ) {\n dest.selected = src.defaultSelected;\n\n // IE6-8 fails to set the defaultValue to the correct value when\n // cloning other types of input fields\n } else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n dest.defaultValue = src.defaultValue;\n\n // IE blanks contents when cloning scripts\n } else if ( nodeName === \"script\" && dest.text !== src.text ) {\n dest.text = src.text;\n }\n\n // Event data gets referenced instead of copied if the expando\n // gets copied too\n dest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, context, scripts ) {\n var fragment, cacheable, cachehit,\n first = args[ 0 ];\n\n // Set context from what may come in as undefined or a jQuery collection or a node\n // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &\n // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception\n context = context || document;\n context = !context.nodeType && context[0] || context;\n context = context.ownerDocument || context;\n\n // Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n // Cloning options loses the selected state, so don't cache them\n // IE 6 doesn't like it when you put or elements in a fragment\n // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501\n if ( args.length === 1 && typeof first === \"string\" && first.length < 512 && context === document &&\n first.charAt(0) === \"<\" && !rnocache.test( first ) &&\n (jQuery.support.checkClone || !rchecked.test( first )) &&\n (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {\n\n // Mark cacheable and look for a hit\n cacheable = true;\n fragment = jQuery.fragments[ first ];\n cachehit = fragment !== undefined;\n }\n\n if ( !fragment ) {\n fragment = context.createDocumentFragment();\n jQuery.clean( args, context, fragment, scripts );\n\n // Update the cache, but only store false\n // unless this is a second parsing of the same content\n if ( cacheable ) {\n jQuery.fragments[ first ] = cachehit && fragment;\n }\n }\n\n return { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n appendTo: \"append\",\n prependTo: \"prepend\",\n insertBefore: \"before\",\n insertAfter: \"after\",\n replaceAll: \"replaceWith\"\n}, function( name, original ) {\n jQuery.fn[ name ] = function( selector ) {\n var elems,\n i = 0,\n ret = [],\n insert = jQuery( selector ),\n l = insert.length,\n parent = this.length === 1 && this[0].parentNode;\n\n if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {\n insert[ original ]( this[0] );\n return this;\n } else {\n for ( ; i < l; i++ ) {\n elems = ( i > 0 ? this.clone(true) : this ).get();\n jQuery( insert[i] )[ original ]( elems );\n ret = ret.concat( elems );\n }\n\n return this.pushStack( ret, name, insert.selector );\n }\n };\n});\n\nfunction getAll( elem ) {\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n return elem.getElementsByTagName( \"*\" );\n\n } else if ( typeof elem.querySelectorAll !== \"undefined\" ) {\n return elem.querySelectorAll( \"*\" );\n\n } else {\n return [];\n }\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n if ( rcheckableType.test( elem.type ) ) {\n elem.defaultChecked = elem.checked;\n }\n}\n\njQuery.extend({\n clone: function( elem, dataAndEvents, deepDataAndEvents ) {\n var srcElements,\n destElements,\n i,\n clone;\n\n if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n clone = elem.cloneNode( true );\n\n // IE<=8 does not properly clone detached, unknown element nodes\n } else {\n fragmentDiv.innerHTML = elem.outerHTML;\n fragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n }\n\n if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n // IE copies events bound via attachEvent when using cloneNode.\n // Calling detachEvent on the clone will also remove the events\n // from the original. In order to get around this, we use some\n // proprietary methods to clear the events. Thanks to MooTools\n // guys for this hotness.\n\n cloneFixAttributes( elem, clone );\n\n // Using Sizzle here is crazy slow, so we use getElementsByTagName instead\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n // Weird iteration because IE will replace the length property\n // with an element if you are cloning the body and one of the\n // elements on the page has a name or id of \"length\"\n for ( i = 0; srcElements[i]; ++i ) {\n // Ensure that the destination node is not null; Fixes #9587\n if ( destElements[i] ) {\n cloneFixAttributes( srcElements[i], destElements[i] );\n }\n }\n }\n\n // Copy the events from the original to the clone\n if ( dataAndEvents ) {\n cloneCopyEvent( elem, clone );\n\n if ( deepDataAndEvents ) {\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n for ( i = 0; srcElements[i]; ++i ) {\n cloneCopyEvent( srcElements[i], destElements[i] );\n }\n }\n }\n\n srcElements = destElements = null;\n\n // Return the cloned set\n return clone;\n },\n\n clean: function( elems, context, fragment, scripts ) {\n var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,\n safe = context === document && safeFragment,\n ret = [];\n\n // Ensure that context is a document\n if ( !context || typeof context.createDocumentFragment === \"undefined\" ) {\n context = document;\n }\n\n // Use the already-created safe fragment if context permits\n for ( i = 0; (elem = elems[i]) != null; i++ ) {\n if ( typeof elem === \"number\" ) {\n elem += \"\";\n }\n\n if ( !elem ) {\n continue;\n }\n\n // Convert html string into DOM nodes\n if ( typeof elem === \"string\" ) {\n if ( !rhtml.test( elem ) ) {\n elem = context.createTextNode( elem );\n } else {\n // Ensure a safe container in which to render the html\n safe = safe || createSafeFragment( context );\n div = context.createElement(\"div\");\n safe.appendChild( div );\n\n // Fix \"XHTML\"-style tags in all browsers\n elem = elem.replace(rxhtmlTag, \"<$1>\");\n\n // Go to html and back, then peel off extra wrappers\n tag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n wrap = wrapMap[ tag ] || wrapMap._default;\n depth = wrap[0];\n div.innerHTML = wrap[1] + elem + wrap[2];\n\n // Move to the right depth\n while ( depth-- ) {\n div = div.lastChild;\n }\n\n // Remove IE's autoinserted from table fragments\n if ( !jQuery.support.tbody ) {\n\n // String was a , *may* have spurious \n hasBody = rtbody.test(elem);\n tbody = tag === \"table\" && !hasBody ?\n div.firstChild && div.firstChild.childNodes :\n\n // String was a bare or \n wrap[1] === \"
\" && !hasBody ?\n div.childNodes :\n [];\n\n for ( j = tbody.length - 1; j >= 0 ; --j ) {\n if ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n tbody[ j ].parentNode.removeChild( tbody[ j ] );\n }\n }\n }\n\n // IE completely kills leading whitespace when innerHTML is used\n if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n }\n\n elem = div.childNodes;\n\n // Take out of fragment container (we need a fresh div each time)\n div.parentNode.removeChild( div );\n }\n }\n\n if ( elem.nodeType ) {\n ret.push( elem );\n } else {\n jQuery.merge( ret, elem );\n }\n }\n\n // Fix #11356: Clear elements from safeFragment\n if ( div ) {\n elem = div = safe = null;\n }\n\n // Reset defaultChecked for any radios and checkboxes\n // about to be appended to the DOM in IE 6/7 (#8060)\n if ( !jQuery.support.appendChecked ) {\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n if ( jQuery.nodeName( elem, \"input\" ) ) {\n fixDefaultChecked( elem );\n } else if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n jQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n }\n }\n }\n\n // Append elements to a provided document fragment\n if ( fragment ) {\n // Special handling of each script element\n handleScript = function( elem ) {\n // Check if we consider it executable\n if ( !elem.type || rscriptType.test( elem.type ) ) {\n // Detach the script and store it in the scripts array (if provided) or the fragment\n // Return truthy to indicate that it has been handled\n return scripts ?\n scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\n fragment.appendChild( elem );\n }\n };\n\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n // Check if we're done after handling an executable script\n if ( !( jQuery.nodeName( elem, \"script\" ) && handleScript( elem ) ) ) {\n // Append to fragment and handle embedded scripts\n fragment.appendChild( elem );\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\n jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName(\"script\") ), handleScript );\n\n // Splice the scripts into ret after their former ancestor and advance our index beyond them\n ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n i += jsTags.length;\n }\n }\n }\n }\n\n return ret;\n },\n\n cleanData: function( elems, /* internal */ acceptData ) {\n var data, id, elem, type,\n i = 0,\n internalKey = jQuery.expando,\n cache = jQuery.cache,\n deleteExpando = jQuery.support.deleteExpando,\n special = jQuery.event.special;\n\n for ( ; (elem = elems[i]) != null; i++ ) {\n\n if ( acceptData || jQuery.acceptData( elem ) ) {\n\n id = elem[ internalKey ];\n data = id && cache[ id ];\n\n if ( data ) {\n if ( data.events ) {\n for ( type in data.events ) {\n if ( special[ type ] ) {\n jQuery.event.remove( elem, type );\n\n // This is a shortcut to avoid jQuery.event.remove's overhead\n } else {\n jQuery.removeEvent( elem, type, data.handle );\n }\n }\n }\n\n // Remove cache only if it was not already removed by jQuery.event.remove\n if ( cache[ id ] ) {\n\n delete cache[ id ];\n\n // IE does not allow us to delete expando properties from nodes,\n // nor does it have a removeAttribute function on Document nodes;\n // we must handle all of these cases\n if ( deleteExpando ) {\n delete elem[ internalKey ];\n\n } else if ( elem.removeAttribute ) {\n elem.removeAttribute( internalKey );\n\n } else {\n elem[ internalKey ] = null;\n }\n\n jQuery.deletedIds.push( id );\n }\n }\n }\n }\n }\n});\n// Limit scope pollution from any deprecated API\n(function() {\n\nvar matched, browser;\n\n// Use of jQuery.browser is frowned upon.\n// More details: http://api.jquery.com/jQuery.browser\n// jQuery.uaMatch maintained for back-compat\njQuery.uaMatch = function( ua ) {\n ua = ua.toLowerCase();\n\n var match = /(chrome)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(webkit)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(msie) ([\\w.]+)/.exec( ua ) ||\n ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec( ua ) ||\n [];\n\n return {\n browser: match[ 1 ] || \"\",\n version: match[ 2 ] || \"0\"\n };\n};\n\nmatched = jQuery.uaMatch( navigator.userAgent );\nbrowser = {};\n\nif ( matched.browser ) {\n browser[ matched.browser ] = true;\n browser.version = matched.version;\n}\n\n// Chrome is Webkit, but Webkit is also Safari.\nif ( browser.chrome ) {\n browser.webkit = true;\n} else if ( browser.webkit ) {\n browser.safari = true;\n}\n\njQuery.browser = browser;\n\njQuery.sub = function() {\n function jQuerySub( selector, context ) {\n return new jQuerySub.fn.init( selector, context );\n }\n jQuery.extend( true, jQuerySub, this );\n jQuerySub.superclass = this;\n jQuerySub.fn = jQuerySub.prototype = this();\n jQuerySub.fn.constructor = jQuerySub;\n jQuerySub.sub = this.sub;\n jQuerySub.fn.init = function init( selector, context ) {\n if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n context = jQuerySub( context );\n }\n\n return jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n };\n jQuerySub.fn.init.prototype = jQuerySub.fn;\n var rootjQuerySub = jQuerySub(document);\n return jQuerySub;\n};\n\n})();\nvar curCSS, iframe, iframeDoc,\n ralpha = /alpha\\([^)]*\\)/i,\n ropacity = /opacity=([^)]*)/,\n rposition = /^(top|right|bottom|left)$/,\n // swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n rmargin = /^margin/,\n rnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n rnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n rrelNum = new RegExp( \"^([-+])=(\" + core_pnum + \")\", \"i\" ),\n elemdisplay = { BODY: \"block\" },\n\n cssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n cssNormalTransform = {\n letterSpacing: 0,\n fontWeight: 400\n },\n\n cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n cssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\n eventsToggle = jQuery.fn.toggle;\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n // shortcut for names that are not vendor prefixed\n if ( name in style ) {\n return name;\n }\n\n // check for vendor prefixed names\n var capName = name.charAt(0).toUpperCase() + name.slice(1),\n origName = name,\n i = cssPrefixes.length;\n\n while ( i-- ) {\n name = cssPrefixes[ i ] + capName;\n if ( name in style ) {\n return name;\n }\n }\n\n return origName;\n}\n\nfunction isHidden( elem, el ) {\n elem = el || elem;\n return jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n var elem, display,\n values = [],\n index = 0,\n length = elements.length;\n\n for ( ; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n values[ index ] = jQuery._data( elem, \"olddisplay\" );\n if ( show ) {\n // Reset the inline display of this element to learn if it is\n // being hidden by cascaded rules or not\n if ( !values[ index ] && elem.style.display === \"none\" ) {\n elem.style.display = \"\";\n }\n\n // Set elements which have been overridden with display: none\n // in a stylesheet to whatever the default browser style is\n // for such an element\n if ( elem.style.display === \"\" && isHidden( elem ) ) {\n values[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n }\n } else {\n display = curCSS( elem, \"display\" );\n\n if ( !values[ index ] && display !== \"none\" ) {\n jQuery._data( elem, \"olddisplay\", display );\n }\n }\n }\n\n // Set the display of most of the elements in a second loop\n // to avoid the constant reflow\n for ( index = 0; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n if ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n elem.style.display = show ? values[ index ] || \"\" : \"none\";\n }\n }\n\n return elements;\n}\n\njQuery.fn.extend({\n css: function( name, value ) {\n return jQuery.access( this, function( elem, name, value ) {\n return value !== undefined ?\n jQuery.style( elem, name, value ) :\n jQuery.css( elem, name );\n }, name, value, arguments.length > 1 );\n },\n show: function() {\n return showHide( this, true );\n },\n hide: function() {\n return showHide( this );\n },\n toggle: function( state, fn2 ) {\n var bool = typeof state === \"boolean\";\n\n if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {\n return eventsToggle.apply( this, arguments );\n }\n\n return this.each(function() {\n if ( bool ? state : isHidden( this ) ) {\n jQuery( this ).show();\n } else {\n jQuery( this ).hide();\n }\n });\n }\n});\n\njQuery.extend({\n // Add in style property hooks for overriding the default\n // behavior of getting and setting a style property\n cssHooks: {\n opacity: {\n get: function( elem, computed ) {\n if ( computed ) {\n // We should always get a number back from opacity\n var ret = curCSS( elem, \"opacity\" );\n return ret === \"\" ? \"1\" : ret;\n\n }\n }\n }\n },\n\n // Exclude the following css properties to add px\n cssNumber: {\n \"fillOpacity\": true,\n \"fontWeight\": true,\n \"lineHeight\": true,\n \"opacity\": true,\n \"orphans\": true,\n \"widows\": true,\n \"zIndex\": true,\n \"zoom\": true\n },\n\n // Add in properties whose names you wish to fix before\n // setting or getting the value\n cssProps: {\n // normalize float css property\n \"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n },\n\n // Get and set the style property on a DOM Node\n style: function( elem, name, value, extra ) {\n // Don't set styles on text and comment nodes\n if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n return;\n }\n\n // Make sure that we're working with the right name\n var ret, type, hooks,\n origName = jQuery.camelCase( name ),\n style = elem.style;\n\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // Check if we're setting a value\n if ( value !== undefined ) {\n type = typeof value;\n\n // convert relative number strings (+= or -=) to relative numbers. #7345\n if ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n // Fixes bug #9237\n type = \"number\";\n }\n\n // Make sure that NaN and null values aren't set. See: #7116\n if ( value == null || type === \"number\" && isNaN( value ) ) {\n return;\n }\n\n // If a number was passed in, add 'px' to the (except for certain CSS properties)\n if ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n value += \"px\";\n }\n\n // If a hook was provided, use that value, otherwise just set the specified value\n if ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n // Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n // Fixes bug #5509\n try {\n style[ name ] = value;\n } catch(e) {}\n }\n\n } else {\n // If a hook was provided get the non-computed value from there\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n return ret;\n }\n\n // Otherwise just get the value from the style object\n return style[ name ];\n }\n },\n\n css: function( elem, name, numeric, extra ) {\n var val, num, hooks,\n origName = jQuery.camelCase( name );\n\n // Make sure that we're working with the right name\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // If a hook was provided get the computed value from there\n if ( hooks && \"get\" in hooks ) {\n val = hooks.get( elem, true, extra );\n }\n\n // Otherwise, if a way to get the computed value exists, use that\n if ( val === undefined ) {\n val = curCSS( elem, name );\n }\n\n //convert \"normal\" to computed value\n if ( val === \"normal\" && name in cssNormalTransform ) {\n val = cssNormalTransform[ name ];\n }\n\n // Return, converting to number if forced or a qualifier was provided and val looks numeric\n if ( numeric || extra !== undefined ) {\n num = parseFloat( val );\n return numeric || jQuery.isNumeric( num ) ? num || 0 : val;\n }\n return val;\n },\n\n // A method for quickly swapping in/out CSS properties to get correct calculations\n swap: function( elem, options, callback ) {\n var ret, name,\n old = {};\n\n // Remember the old values, and insert the new ones\n for ( name in options ) {\n old[ name ] = elem.style[ name ];\n elem.style[ name ] = options[ name ];\n }\n\n ret = callback.call( elem );\n\n // Revert the old values\n for ( name in options ) {\n elem.style[ name ] = old[ name ];\n }\n\n return ret;\n }\n});\n\n// NOTE: To any future maintainer, we've window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n curCSS = function( elem, name ) {\n var ret, width, minWidth, maxWidth,\n computed = window.getComputedStyle( elem, null ),\n style = elem.style;\n\n if ( computed ) {\n\n // getPropertyValue is only needed for .css('filter') in IE9, see #12537\n ret = computed.getPropertyValue( name ) || computed[ name ];\n\n if ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n ret = jQuery.style( elem, name );\n }\n\n // A tribute to the \"awesome hack by Dean Edwards\"\n // Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n width = style.width;\n minWidth = style.minWidth;\n maxWidth = style.maxWidth;\n\n style.minWidth = style.maxWidth = style.width = ret;\n ret = computed.width;\n\n style.width = width;\n style.minWidth = minWidth;\n style.maxWidth = maxWidth;\n }\n }\n\n return ret;\n };\n} else if ( document.documentElement.currentStyle ) {\n curCSS = function( elem, name ) {\n var left, rsLeft,\n ret = elem.currentStyle && elem.currentStyle[ name ],\n style = elem.style;\n\n // Avoid setting ret to empty string here\n // so we don't default to auto\n if ( ret == null && style && style[ name ] ) {\n ret = style[ name ];\n }\n\n // From the awesome hack by Dean Edwards\n // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n // If we're not dealing with a regular pixel number\n // but a number that has a weird ending, we need to convert it to pixels\n // but not position css attributes, as those are proportional to the parent element instead\n // and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n // Remember the original values\n left = style.left;\n rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;\n\n // Put in the new values to get a computed value out\n if ( rsLeft ) {\n elem.runtimeStyle.left = elem.currentStyle.left;\n }\n style.left = name === \"fontSize\" ? \"1em\" : ret;\n ret = style.pixelLeft + \"px\";\n\n // Revert the changed values\n style.left = left;\n if ( rsLeft ) {\n elem.runtimeStyle.left = rsLeft;\n }\n }\n\n return ret === \"\" ? \"auto\" : ret;\n };\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n var matches = rnumsplit.exec( value );\n return matches ?\n Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n value;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox ) {\n var i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n // If we already have the right measurement, avoid augmentation\n 4 :\n // Otherwise initialize for horizontal or vertical properties\n name === \"width\" ? 1 : 0,\n\n val = 0;\n\n for ( ; i < 4; i += 2 ) {\n // both box models exclude margin, so add it if we want it\n if ( extra === \"margin\" ) {\n // we use jQuery.css instead of curCSS here\n // because of the reliableMarginRight CSS hook!\n val += jQuery.css( elem, extra + cssExpand[ i ], true );\n }\n\n // From this point on we use curCSS for maximum performance (relevant in animations)\n if ( isBorderBox ) {\n // border-box includes padding, so remove it if we want content\n if ( extra === \"content\" ) {\n val -= parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n }\n\n // at this point, extra isn't border nor margin, so remove border\n if ( extra !== \"margin\" ) {\n val -= parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n } else {\n // at this point, extra isn't content, so add padding\n val += parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\n // at this point, extra isn't content nor padding, so add border\n if ( extra !== \"padding\" ) {\n val += parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n }\n }\n\n return val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n // Start with offset property, which is equivalent to the border-box value\n var val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n valueIsBorderBox = true,\n isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\";\n\n // some non-html elements return undefined for offsetWidth, so check for null/undefined\n // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n if ( val <= 0 || val == null ) {\n // Fall back to computed then uncomputed css if necessary\n val = curCSS( elem, name );\n if ( val < 0 || val == null ) {\n val = elem.style[ name ];\n }\n\n // Computed unit is not pixels. Stop here and return.\n if ( rnumnonpx.test(val) ) {\n return val;\n }\n\n // we need the check for style in case a browser which returns unreliable values\n // for getComputedStyle silently falls back to the reliable elem.style\n valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n // Normalize \"\", auto, and prepare for extra\n val = parseFloat( val ) || 0;\n }\n\n // use the active box-sizing model to add/subtract irrelevant styles\n return ( val +\n augmentWidthOrHeight(\n elem,\n name,\n extra || ( isBorderBox ? \"border\" : \"content\" ),\n valueIsBorderBox\n )\n ) + \"px\";\n}\n\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n if ( elemdisplay[ nodeName ] ) {\n return elemdisplay[ nodeName ];\n }\n\n var elem = jQuery( \"<\" + nodeName + \">\" ).appendTo( document.body ),\n display = elem.css(\"display\");\n elem.remove();\n\n // If the simple way fails,\n // get element's real default display by attaching it to a temp iframe\n if ( display === \"none\" || display === \"\" ) {\n // Use the already-created iframe if possible\n iframe = document.body.appendChild(\n iframe || jQuery.extend( document.createElement(\"iframe\"), {\n frameBorder: 0,\n width: 0,\n height: 0\n })\n );\n\n // Create a cacheable copy of the iframe document on first call.\n // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n // document to it; WebKit & Firefox won't allow reusing the iframe document.\n if ( !iframeDoc || !iframe.createElement ) {\n iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n iframeDoc.write(\"\");\n iframeDoc.close();\n }\n\n elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );\n\n display = curCSS( elem, \"display\" );\n document.body.removeChild( iframe );\n }\n\n // Store the correct default display\n elemdisplay[ nodeName ] = display;\n\n return display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n jQuery.cssHooks[ name ] = {\n get: function( elem, computed, extra ) {\n if ( computed ) {\n // certain elements can have dimension info if we invisibly show them\n // however, it must have a current display style that would benefit from this\n if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, \"display\" ) ) ) {\n return jQuery.swap( elem, cssShow, function() {\n return getWidthOrHeight( elem, name, extra );\n });\n } else {\n return getWidthOrHeight( elem, name, extra );\n }\n }\n },\n\n set: function( elem, value, extra ) {\n return setPositiveNumber( elem, value, extra ?\n augmentWidthOrHeight(\n elem,\n name,\n extra,\n jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\"\n ) : 0\n );\n }\n };\n});\n\nif ( !jQuery.support.opacity ) {\n jQuery.cssHooks.opacity = {\n get: function( elem, computed ) {\n // IE uses filters for opacity\n return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n ( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n computed ? \"1\" : \"\";\n },\n\n set: function( elem, value ) {\n var style = elem.style,\n currentStyle = elem.currentStyle,\n opacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n filter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n // IE has trouble with opacity if it does not have layout\n // Force it by setting the zoom level\n style.zoom = 1;\n\n // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n if ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n style.removeAttribute ) {\n\n // Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n // if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n // style.removeAttribute is IE Only, but so apparently is this code path...\n style.removeAttribute( \"filter\" );\n\n // if there there is no filter style applied in a css rule, we are done\n if ( currentStyle && !currentStyle.filter ) {\n return;\n }\n }\n\n // otherwise, set new filter values\n style.filter = ralpha.test( filter ) ?\n filter.replace( ralpha, opacity ) :\n filter + \" \" + opacity;\n }\n };\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n if ( !jQuery.support.reliableMarginRight ) {\n jQuery.cssHooks.marginRight = {\n get: function( elem, computed ) {\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n // Work around by temporarily setting element display to inline-block\n return jQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n if ( computed ) {\n return curCSS( elem, \"marginRight\" );\n }\n });\n }\n };\n }\n\n // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n // getComputedStyle returns percent when specified for top/left/bottom/right\n // rather than make the css module depend on the offset module, we just check for it here\n if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n jQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n jQuery.cssHooks[ prop ] = {\n get: function( elem, computed ) {\n if ( computed ) {\n var ret = curCSS( elem, prop );\n // if curCSS returns percentage, fallback to offset\n return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + \"px\" : ret;\n }\n }\n };\n });\n }\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.hidden = function( elem ) {\n return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, \"display\" )) === \"none\");\n };\n\n jQuery.expr.filters.visible = function( elem ) {\n return !jQuery.expr.filters.hidden( elem );\n };\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n margin: \"\",\n padding: \"\",\n border: \"Width\"\n}, function( prefix, suffix ) {\n jQuery.cssHooks[ prefix + suffix ] = {\n expand: function( value ) {\n var i,\n\n // assumes a single number if not a string\n parts = typeof value === \"string\" ? value.split(\" \") : [ value ],\n expanded = {};\n\n for ( i = 0; i < 4; i++ ) {\n expanded[ prefix + cssExpand[ i ] + suffix ] =\n parts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n }\n\n return expanded;\n }\n };\n\n if ( !rmargin.test( prefix ) ) {\n jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n }\n});\nvar r20 = /%20/g,\n rbracket = /\\[\\]$/,\n rCRLF = /\\r?\\n/g,\n rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n rselectTextarea = /^(?:select|textarea)/i;\n\njQuery.fn.extend({\n serialize: function() {\n return jQuery.param( this.serializeArray() );\n },\n serializeArray: function() {\n return this.map(function(){\n return this.elements ? jQuery.makeArray( this.elements ) : this;\n })\n .filter(function(){\n return this.name && !this.disabled &&\n ( this.checked || rselectTextarea.test( this.nodeName ) ||\n rinput.test( this.type ) );\n })\n .map(function( i, elem ){\n var val = jQuery( this ).val();\n\n return val == null ?\n null :\n jQuery.isArray( val ) ?\n jQuery.map( val, function( val, i ){\n return { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }) :\n { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }).get();\n }\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n var prefix,\n s = [],\n add = function( key, value ) {\n // If value is a function, invoke it and return its value\n value = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n s[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n };\n\n // Set traditional to true for jQuery <= 1.3.2 behavior.\n if ( traditional === undefined ) {\n traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n }\n\n // If an array was passed in, assume that it is an array of form elements.\n if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n // Serialize the form elements\n jQuery.each( a, function() {\n add( this.name, this.value );\n });\n\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for ( prefix in a ) {\n buildParams( prefix, a[ prefix ], traditional, add );\n }\n }\n\n // Return the resulting serialization\n return s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n var name;\n\n if ( jQuery.isArray( obj ) ) {\n // Serialize array item.\n jQuery.each( obj, function( i, v ) {\n if ( traditional || rbracket.test( prefix ) ) {\n // Treat each array item as a scalar.\n add( prefix, v );\n\n } else {\n // If array item is non-scalar (array or object), encode its\n // numeric index to resolve deserialization ambiguity issues.\n // Note that rack (as of 1.0.0) can't currently deserialize\n // nested arrays properly, and attempting to do so may cause\n // a server error. Possible fixes are to modify rack's\n // deserialization algorithm or to provide an option or flag\n // to force array serialization to be shallow.\n buildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n }\n });\n\n } else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n // Serialize object item.\n for ( name in obj ) {\n buildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n }\n\n } else {\n // Serialize scalar item.\n add( prefix, obj );\n }\n}\nvar\n // Document location\n ajaxLocParts,\n ajaxLocation,\n\n rhash = /#.*$/,\n rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n // #7653, #8125, #8152: local protocol detection\n rlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n rnoContent = /^(?:GET|HEAD)$/,\n rprotocol = /^\\/\\//,\n rquery = /\\?/,\n rscript = /)<[^<]*)*<\\/script>/gi,\n rts = /([?&])_=[^&]*/,\n rurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n // Keep a copy of the old load method\n _load = jQuery.fn.load,\n\n /* Prefilters\n * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n * 2) These are called:\n * - BEFORE asking for a transport\n * - AFTER param serialization (s.data is a string if s.processData is true)\n * 3) key is the dataType\n * 4) the catchall symbol \"*\" can be used\n * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n */\n prefilters = {},\n\n /* Transports bindings\n * 1) key is the dataType\n * 2) the catchall symbol \"*\" can be used\n * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n */\n transports = {},\n\n // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n allTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n ajaxLocation = location.href;\n} catch( e ) {\n // Use the href attribute of an A element\n // since IE will modify it given document.location\n ajaxLocation = document.createElement( \"a\" );\n ajaxLocation.href = \"\";\n ajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n // dataTypeExpression is optional and defaults to \"*\"\n return function( dataTypeExpression, func ) {\n\n if ( typeof dataTypeExpression !== \"string\" ) {\n func = dataTypeExpression;\n dataTypeExpression = \"*\";\n }\n\n var dataType, list, placeBefore,\n dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),\n i = 0,\n length = dataTypes.length;\n\n if ( jQuery.isFunction( func ) ) {\n // For each dataType in the dataTypeExpression\n for ( ; i < length; i++ ) {\n dataType = dataTypes[ i ];\n // We control if we're asked to add before\n // any existing element\n placeBefore = /^\\+/.test( dataType );\n if ( placeBefore ) {\n dataType = dataType.substr( 1 ) || \"*\";\n }\n list = structure[ dataType ] = structure[ dataType ] || [];\n // then we add to the structure accordingly\n list[ placeBefore ? \"unshift\" : \"push\" ]( func );\n }\n }\n };\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n dataType /* internal */, inspected /* internal */ ) {\n\n dataType = dataType || options.dataTypes[ 0 ];\n inspected = inspected || {};\n\n inspected[ dataType ] = true;\n\n var selection,\n list = structure[ dataType ],\n i = 0,\n length = list ? list.length : 0,\n executeOnly = ( structure === prefilters );\n\n for ( ; i < length && ( executeOnly || !selection ); i++ ) {\n selection = list[ i ]( options, originalOptions, jqXHR );\n // If we got redirected to another dataType\n // we try there if executing only and not done already\n if ( typeof selection === \"string\" ) {\n if ( !executeOnly || inspected[ selection ] ) {\n selection = undefined;\n } else {\n options.dataTypes.unshift( selection );\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, selection, inspected );\n }\n }\n }\n // If we're only executing or nothing was selected\n // we try the catchall dataType if not done already\n if ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, \"*\", inspected );\n }\n // unnecessary when only executing (prefilters)\n // but it'll be ignored by the caller in that case\n return selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n var key, deep,\n flatOptions = jQuery.ajaxSettings.flatOptions || {};\n for ( key in src ) {\n if ( src[ key ] !== undefined ) {\n ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n }\n }\n if ( deep ) {\n jQuery.extend( true, target, deep );\n }\n}\n\njQuery.fn.load = function( url, params, callback ) {\n if ( typeof url !== \"string\" && _load ) {\n return _load.apply( this, arguments );\n }\n\n // Don't do a request if no elements are being requested\n if ( !this.length ) {\n return this;\n }\n\n var selector, type, response,\n self = this,\n off = url.indexOf(\" \");\n\n if ( off >= 0 ) {\n selector = url.slice( off, url.length );\n url = url.slice( 0, off );\n }\n\n // If it's a function\n if ( jQuery.isFunction( params ) ) {\n\n // We assume that it's the callback\n callback = params;\n params = undefined;\n\n // Otherwise, build a param string\n } else if ( params && typeof params === \"object\" ) {\n type = \"POST\";\n }\n\n // Request the remote document\n jQuery.ajax({\n url: url,\n\n // if \"type\" variable is undefined, then \"GET\" method will be used\n type: type,\n dataType: \"html\",\n data: params,\n complete: function( jqXHR, status ) {\n if ( callback ) {\n self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n }\n }\n }).done(function( responseText ) {\n\n // Save response for use in complete callback\n response = arguments;\n\n // See if a selector was specified\n self.html( selector ?\n\n // Create a dummy div to hold the results\n jQuery(\"
\")\n\n // inject the contents of the document in, removing the scripts\n // to avoid any 'Permission Denied' errors in IE\n .append( responseText.replace( rscript, \"\" ) )\n\n // Locate the specified elements\n .find( selector ) :\n\n // If not, just inject the full result\n responseText );\n\n });\n\n return this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n jQuery.fn[ o ] = function( f ){\n return this.on( o, f );\n };\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n jQuery[ method ] = function( url, data, callback, type ) {\n // shift arguments if data argument was omitted\n if ( jQuery.isFunction( data ) ) {\n type = type || callback;\n callback = data;\n data = undefined;\n }\n\n return jQuery.ajax({\n type: method,\n url: url,\n data: data,\n success: callback,\n dataType: type\n });\n };\n});\n\njQuery.extend({\n\n getScript: function( url, callback ) {\n return jQuery.get( url, undefined, callback, \"script\" );\n },\n\n getJSON: function( url, data, callback ) {\n return jQuery.get( url, data, callback, \"json\" );\n },\n\n // Creates a full fledged settings object into target\n // with both ajaxSettings and settings fields.\n // If target is omitted, writes into ajaxSettings.\n ajaxSetup: function( target, settings ) {\n if ( settings ) {\n // Building a settings object\n ajaxExtend( target, jQuery.ajaxSettings );\n } else {\n // Extending ajaxSettings\n settings = target;\n target = jQuery.ajaxSettings;\n }\n ajaxExtend( target, settings );\n return target;\n },\n\n ajaxSettings: {\n url: ajaxLocation,\n isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n global: true,\n type: \"GET\",\n contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n processData: true,\n async: true,\n /*\n timeout: 0,\n data: null,\n dataType: null,\n username: null,\n password: null,\n cache: null,\n throws: false,\n traditional: false,\n headers: {},\n */\n\n accepts: {\n xml: \"application/xml, text/xml\",\n html: \"text/html\",\n text: \"text/plain\",\n json: \"application/json, text/javascript\",\n \"*\": allTypes\n },\n\n contents: {\n xml: /xml/,\n html: /html/,\n json: /json/\n },\n\n responseFields: {\n xml: \"responseXML\",\n text: \"responseText\"\n },\n\n // List of data converters\n // 1) key format is \"source_type destination_type\" (a single space in-between)\n // 2) the catchall symbol \"*\" can be used for source_type\n converters: {\n\n // Convert anything to text\n \"* text\": window.String,\n\n // Text to html (true = no transformation)\n \"text html\": true,\n\n // Evaluate text as a json expression\n \"text json\": jQuery.parseJSON,\n\n // Parse text as xml\n \"text xml\": jQuery.parseXML\n },\n\n // For options that shouldn't be deep extended:\n // you can add your own custom options here if\n // and when you create one that shouldn't be\n // deep extended (see ajaxExtend)\n flatOptions: {\n context: true,\n url: true\n }\n },\n\n ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n ajaxTransport: addToPrefiltersOrTransports( transports ),\n\n // Main method\n ajax: function( url, options ) {\n\n // If url is an object, simulate pre-1.5 signature\n if ( typeof url === \"object\" ) {\n options = url;\n url = undefined;\n }\n\n // Force options to be an object\n options = options || {};\n\n var // ifModified key\n ifModifiedKey,\n // Response headers\n responseHeadersString,\n responseHeaders,\n // transport\n transport,\n // timeout handle\n timeoutTimer,\n // Cross-domain detection vars\n parts,\n // To know if global events are to be dispatched\n fireGlobals,\n // Loop variable\n i,\n // Create the final options object\n s = jQuery.ajaxSetup( {}, options ),\n // Callbacks context\n callbackContext = s.context || s,\n // Context for global events\n // It's the callbackContext if one was provided in the options\n // and if it's a DOM node or a jQuery collection\n globalEventContext = callbackContext !== s &&\n ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n jQuery( callbackContext ) : jQuery.event,\n // Deferreds\n deferred = jQuery.Deferred(),\n completeDeferred = jQuery.Callbacks( \"once memory\" ),\n // Status-dependent callbacks\n statusCode = s.statusCode || {},\n // Headers (they are sent all at once)\n requestHeaders = {},\n requestHeadersNames = {},\n // The jqXHR state\n state = 0,\n // Default abort message\n strAbort = \"canceled\",\n // Fake xhr\n jqXHR = {\n\n readyState: 0,\n\n // Caches the header\n setRequestHeader: function( name, value ) {\n if ( !state ) {\n var lname = name.toLowerCase();\n name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n requestHeaders[ name ] = value;\n }\n return this;\n },\n\n // Raw string\n getAllResponseHeaders: function() {\n return state === 2 ? responseHeadersString : null;\n },\n\n // Builds headers hashtable if needed\n getResponseHeader: function( key ) {\n var match;\n if ( state === 2 ) {\n if ( !responseHeaders ) {\n responseHeaders = {};\n while( ( match = rheaders.exec( responseHeadersString ) ) ) {\n responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n }\n }\n match = responseHeaders[ key.toLowerCase() ];\n }\n return match === undefined ? null : match;\n },\n\n // Overrides response content-type header\n overrideMimeType: function( type ) {\n if ( !state ) {\n s.mimeType = type;\n }\n return this;\n },\n\n // Cancel the request\n abort: function( statusText ) {\n statusText = statusText || strAbort;\n if ( transport ) {\n transport.abort( statusText );\n }\n done( 0, statusText );\n return this;\n }\n };\n\n // Callback for when everything is done\n // It is defined here because jslint complains if it is declared\n // at the end of the function (which would be more logical and readable)\n function done( status, nativeStatusText, responses, headers ) {\n var isSuccess, success, error, response, modified,\n statusText = nativeStatusText;\n\n // Called once\n if ( state === 2 ) {\n return;\n }\n\n // State is \"done\" now\n state = 2;\n\n // Clear timeout if it exists\n if ( timeoutTimer ) {\n clearTimeout( timeoutTimer );\n }\n\n // Dereference transport for early garbage collection\n // (no matter how long the jqXHR object will be used)\n transport = undefined;\n\n // Cache response headers\n responseHeadersString = headers || \"\";\n\n // Set readyState\n jqXHR.readyState = status > 0 ? 4 : 0;\n\n // Get response data\n if ( responses ) {\n response = ajaxHandleResponses( s, jqXHR, responses );\n }\n\n // If successful, handle type chaining\n if ( status >= 200 && status < 300 || status === 304 ) {\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n\n modified = jqXHR.getResponseHeader(\"Last-Modified\");\n if ( modified ) {\n jQuery.lastModified[ ifModifiedKey ] = modified;\n }\n modified = jqXHR.getResponseHeader(\"Etag\");\n if ( modified ) {\n jQuery.etag[ ifModifiedKey ] = modified;\n }\n }\n\n // If not modified\n if ( status === 304 ) {\n\n statusText = \"notmodified\";\n isSuccess = true;\n\n // If we have data\n } else {\n\n isSuccess = ajaxConvert( s, response );\n statusText = isSuccess.state;\n success = isSuccess.data;\n error = isSuccess.error;\n isSuccess = !error;\n }\n } else {\n // We extract error from statusText\n // then normalize statusText and status for non-aborts\n error = statusText;\n if ( !statusText || status ) {\n statusText = \"error\";\n if ( status < 0 ) {\n status = 0;\n }\n }\n }\n\n // Set data for the fake xhr object\n jqXHR.status = status;\n jqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n // Success/Error\n if ( isSuccess ) {\n deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n } else {\n deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n }\n\n // Status-dependent callbacks\n jqXHR.statusCode( statusCode );\n statusCode = undefined;\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n [ jqXHR, s, isSuccess ? success : error ] );\n }\n\n // Complete\n completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n // Handle the global AJAX counter\n if ( !( --jQuery.active ) ) {\n jQuery.event.trigger( \"ajaxStop\" );\n }\n }\n }\n\n // Attach deferreds\n deferred.promise( jqXHR );\n jqXHR.success = jqXHR.done;\n jqXHR.error = jqXHR.fail;\n jqXHR.complete = completeDeferred.add;\n\n // Status-dependent callbacks\n jqXHR.statusCode = function( map ) {\n if ( map ) {\n var tmp;\n if ( state < 2 ) {\n for ( tmp in map ) {\n statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n }\n } else {\n tmp = map[ jqXHR.status ];\n jqXHR.always( tmp );\n }\n }\n return this;\n };\n\n // Remove hash character (#7531: and string promotion)\n // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n // We also use the url parameter if available\n s.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n // Extract dataTypes list\n s.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( core_rspace );\n\n // A cross-domain request is in order when we have a protocol:host:port mismatch\n if ( s.crossDomain == null ) {\n parts = rurl.exec( s.url.toLowerCase() );\n s.crossDomain = !!( parts &&\n ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n ( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n );\n }\n\n // Convert data if not already a string\n if ( s.data && s.processData && typeof s.data !== \"string\" ) {\n s.data = jQuery.param( s.data, s.traditional );\n }\n\n // Apply prefilters\n inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n // If request was aborted inside a prefilter, stop there\n if ( state === 2 ) {\n return jqXHR;\n }\n\n // We can fire global events as of now if asked to\n fireGlobals = s.global;\n\n // Uppercase the type\n s.type = s.type.toUpperCase();\n\n // Determine if request has content\n s.hasContent = !rnoContent.test( s.type );\n\n // Watch for a new set of requests\n if ( fireGlobals && jQuery.active++ === 0 ) {\n jQuery.event.trigger( \"ajaxStart\" );\n }\n\n // More options handling for requests with no content\n if ( !s.hasContent ) {\n\n // If data is available, append data to url\n if ( s.data ) {\n s.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n // #9682: remove data so that it's not used in an eventual retry\n delete s.data;\n }\n\n // Get ifModifiedKey before adding the anti-cache parameter\n ifModifiedKey = s.url;\n\n // Add anti-cache in url if needed\n if ( s.cache === false ) {\n\n var ts = jQuery.now(),\n // try replacing _= if it is there\n ret = s.url.replace( rts, \"$1_=\" + ts );\n\n // if nothing was replaced, add timestamp to the end\n s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n }\n }\n\n // Set the correct header, if data is being sent\n if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n jqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n }\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n ifModifiedKey = ifModifiedKey || s.url;\n if ( jQuery.lastModified[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n }\n if ( jQuery.etag[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n }\n }\n\n // Set the Accepts header for the server, depending on the dataType\n jqXHR.setRequestHeader(\n \"Accept\",\n s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n s.accepts[ \"*\" ]\n );\n\n // Check for headers option\n for ( i in s.headers ) {\n jqXHR.setRequestHeader( i, s.headers[ i ] );\n }\n\n // Allow custom headers/mimetypes and early abort\n if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n // Abort if not done already and return\n return jqXHR.abort();\n\n }\n\n // aborting is no longer a cancellation\n strAbort = \"abort\";\n\n // Install callbacks on deferreds\n for ( i in { success: 1, error: 1, complete: 1 } ) {\n jqXHR[ i ]( s[ i ] );\n }\n\n // Get transport\n transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n // If no transport, we auto-abort\n if ( !transport ) {\n done( -1, \"No Transport\" );\n } else {\n jqXHR.readyState = 1;\n // Send global event\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n }\n // Timeout\n if ( s.async && s.timeout > 0 ) {\n timeoutTimer = setTimeout( function(){\n jqXHR.abort( \"timeout\" );\n }, s.timeout );\n }\n\n try {\n state = 1;\n transport.send( requestHeaders, done );\n } catch (e) {\n // Propagate exception as error if not done\n if ( state < 2 ) {\n done( -1, e );\n // Simply rethrow otherwise\n } else {\n throw e;\n }\n }\n }\n\n return jqXHR;\n },\n\n // Counter for holding the number of active queries\n active: 0,\n\n // Last-Modified header cache for next request\n lastModified: {},\n etag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n var ct, type, finalDataType, firstDataType,\n contents = s.contents,\n dataTypes = s.dataTypes,\n responseFields = s.responseFields;\n\n // Fill responseXXX fields\n for ( type in responseFields ) {\n if ( type in responses ) {\n jqXHR[ responseFields[type] ] = responses[ type ];\n }\n }\n\n // Remove auto dataType and get content-type in the process\n while( dataTypes[ 0 ] === \"*\" ) {\n dataTypes.shift();\n if ( ct === undefined ) {\n ct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n }\n }\n\n // Check if we're dealing with a known content-type\n if ( ct ) {\n for ( type in contents ) {\n if ( contents[ type ] && contents[ type ].test( ct ) ) {\n dataTypes.unshift( type );\n break;\n }\n }\n }\n\n // Check to see if we have a response for the expected dataType\n if ( dataTypes[ 0 ] in responses ) {\n finalDataType = dataTypes[ 0 ];\n } else {\n // Try convertible dataTypes\n for ( type in responses ) {\n if ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n finalDataType = type;\n break;\n }\n if ( !firstDataType ) {\n firstDataType = type;\n }\n }\n // Or just use first one\n finalDataType = finalDataType || firstDataType;\n }\n\n // If we found a dataType\n // We add the dataType to the list if needed\n // and return the corresponding response\n if ( finalDataType ) {\n if ( finalDataType !== dataTypes[ 0 ] ) {\n dataTypes.unshift( finalDataType );\n }\n return responses[ finalDataType ];\n }\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n var conv, conv2, current, tmp,\n // Work with a copy of dataTypes in case we need to modify it for conversion\n dataTypes = s.dataTypes.slice(),\n prev = dataTypes[ 0 ],\n converters = {},\n i = 0;\n\n // Apply the dataFilter if provided\n if ( s.dataFilter ) {\n response = s.dataFilter( response, s.dataType );\n }\n\n // Create converters map with lowercased keys\n if ( dataTypes[ 1 ] ) {\n for ( conv in s.converters ) {\n converters[ conv.toLowerCase() ] = s.converters[ conv ];\n }\n }\n\n // Convert to each sequential dataType, tolerating list modification\n for ( ; (current = dataTypes[++i]); ) {\n\n // There's only work to do if current dataType is non-auto\n if ( current !== \"*\" ) {\n\n // Convert response if prev dataType is non-auto and differs from current\n if ( prev !== \"*\" && prev !== current ) {\n\n // Seek a direct converter\n conv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n // If none found, seek a pair\n if ( !conv ) {\n for ( conv2 in converters ) {\n\n // If conv2 outputs current\n tmp = conv2.split(\" \");\n if ( tmp[ 1 ] === current ) {\n\n // If prev can be converted to accepted input\n conv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n converters[ \"* \" + tmp[ 0 ] ];\n if ( conv ) {\n // Condense equivalence converters\n if ( conv === true ) {\n conv = converters[ conv2 ];\n\n // Otherwise, insert the intermediate dataType\n } else if ( converters[ conv2 ] !== true ) {\n current = tmp[ 0 ];\n dataTypes.splice( i--, 0, current );\n }\n\n break;\n }\n }\n }\n }\n\n // Apply converter (if not an equivalence)\n if ( conv !== true ) {\n\n // Unless errors are allowed to bubble, catch and return them\n if ( conv && s[\"throws\"] ) {\n response = conv( response );\n } else {\n try {\n response = conv( response );\n } catch ( e ) {\n return { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n }\n }\n }\n }\n\n // Update prev for next iteration\n prev = current;\n }\n }\n\n return { state: \"success\", data: response };\n}\nvar oldCallbacks = [],\n rquestion = /\\?/,\n rjsonp = /(=)\\?(?=&|$)|\\?\\?/,\n nonce = jQuery.now();\n\n// Default jsonp settings\njQuery.ajaxSetup({\n jsonp: \"callback\",\n jsonpCallback: function() {\n var callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n this[ callback ] = true;\n return callback;\n }\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n var callbackName, overwritten, responseContainer,\n data = s.data,\n url = s.url,\n hasCallback = s.jsonp !== false,\n replaceInUrl = hasCallback && rjsonp.test( url ),\n replaceInData = hasCallback && !replaceInUrl && typeof data === \"string\" &&\n !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") &&\n rjsonp.test( data );\n\n // Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n if ( s.dataTypes[ 0 ] === \"jsonp\" || replaceInUrl || replaceInData ) {\n\n // Get callback name, remembering preexisting value associated with it\n callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n s.jsonpCallback() :\n s.jsonpCallback;\n overwritten = window[ callbackName ];\n\n // Insert callback into url or form data\n if ( replaceInUrl ) {\n s.url = url.replace( rjsonp, \"$1\" + callbackName );\n } else if ( replaceInData ) {\n s.data = data.replace( rjsonp, \"$1\" + callbackName );\n } else if ( hasCallback ) {\n s.url += ( rquestion.test( url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n }\n\n // Use data converter to retrieve json after script execution\n s.converters[\"script json\"] = function() {\n if ( !responseContainer ) {\n jQuery.error( callbackName + \" was not called\" );\n }\n return responseContainer[ 0 ];\n };\n\n // force json dataType\n s.dataTypes[ 0 ] = \"json\";\n\n // Install callback\n window[ callbackName ] = function() {\n responseContainer = arguments;\n };\n\n // Clean-up function (fires after converters)\n jqXHR.always(function() {\n // Restore preexisting value\n window[ callbackName ] = overwritten;\n\n // Save back as free\n if ( s[ callbackName ] ) {\n // make sure that re-using the options doesn't screw things around\n s.jsonpCallback = originalSettings.jsonpCallback;\n\n // save the callback name for future use\n oldCallbacks.push( callbackName );\n }\n\n // Call if it was a function and we have a response\n if ( responseContainer && jQuery.isFunction( overwritten ) ) {\n overwritten( responseContainer[ 0 ] );\n }\n\n responseContainer = overwritten = undefined;\n });\n\n // Delegate to script\n return \"script\";\n }\n});\n// Install script dataType\njQuery.ajaxSetup({\n accepts: {\n script: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n },\n contents: {\n script: /javascript|ecmascript/\n },\n converters: {\n \"text script\": function( text ) {\n jQuery.globalEval( text );\n return text;\n }\n }\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n if ( s.cache === undefined ) {\n s.cache = false;\n }\n if ( s.crossDomain ) {\n s.type = \"GET\";\n s.global = false;\n }\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n // This transport only deals with cross domain requests\n if ( s.crossDomain ) {\n\n var script,\n head = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n return {\n\n send: function( _, callback ) {\n\n script = document.createElement( \"script\" );\n\n script.async = \"async\";\n\n if ( s.scriptCharset ) {\n script.charset = s.scriptCharset;\n }\n\n script.src = s.url;\n\n // Attach handlers for all browsers\n script.onload = script.onreadystatechange = function( _, isAbort ) {\n\n if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n // Handle memory leak in IE\n script.onload = script.onreadystatechange = null;\n\n // Remove the script\n if ( head && script.parentNode ) {\n head.removeChild( script );\n }\n\n // Dereference the script\n script = undefined;\n\n // Callback if not abort\n if ( !isAbort ) {\n callback( 200, \"success\" );\n }\n }\n };\n // Use insertBefore instead of appendChild to circumvent an IE6 bug.\n // This arises when a base node is used (#2709 and #4378).\n head.insertBefore( script, head.firstChild );\n },\n\n abort: function() {\n if ( script ) {\n script.onload( 0, 1 );\n }\n }\n };\n }\n});\nvar xhrCallbacks,\n // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n xhrOnUnloadAbort = window.ActiveXObject ? function() {\n // Abort all pending requests\n for ( var key in xhrCallbacks ) {\n xhrCallbacks[ key ]( 0, 1 );\n }\n } : false,\n xhrId = 0;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n try {\n return new window.XMLHttpRequest();\n } catch( e ) {}\n}\n\nfunction createActiveXHR() {\n try {\n return new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n } catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n /* Microsoft failed to properly\n * implement the XMLHttpRequest in IE7 (can't request local files),\n * so we use the ActiveXObject when it is available\n * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n * we need a fallback.\n */\n function() {\n return !this.isLocal && createStandardXHR() || createActiveXHR();\n } :\n // For all other browsers, use the standard XMLHttpRequest object\n createStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n jQuery.extend( jQuery.support, {\n ajax: !!xhr,\n cors: !!xhr && ( \"withCredentials\" in xhr )\n });\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n jQuery.ajaxTransport(function( s ) {\n // Cross domain only allowed if supported through XMLHttpRequest\n if ( !s.crossDomain || jQuery.support.cors ) {\n\n var callback;\n\n return {\n send: function( headers, complete ) {\n\n // Get a new xhr\n var handle, i,\n xhr = s.xhr();\n\n // Open the socket\n // Passing null username, generates a login popup on Opera (#2865)\n if ( s.username ) {\n xhr.open( s.type, s.url, s.async, s.username, s.password );\n } else {\n xhr.open( s.type, s.url, s.async );\n }\n\n // Apply custom fields if provided\n if ( s.xhrFields ) {\n for ( i in s.xhrFields ) {\n xhr[ i ] = s.xhrFields[ i ];\n }\n }\n\n // Override mime type if needed\n if ( s.mimeType && xhr.overrideMimeType ) {\n xhr.overrideMimeType( s.mimeType );\n }\n\n // X-Requested-With header\n // For cross-domain requests, seeing as conditions for a preflight are\n // akin to a jigsaw puzzle, we simply never set it to be sure.\n // (it can always be set on a per-request basis or even using ajaxSetup)\n // For same-domain requests, won't change header if already provided.\n if ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n headers[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n }\n\n // Need an extra try/catch for cross domain requests in Firefox 3\n try {\n for ( i in headers ) {\n xhr.setRequestHeader( i, headers[ i ] );\n }\n } catch( _ ) {}\n\n // Do send the request\n // This may raise an exception which is actually\n // handled in jQuery.ajax (so no try/catch here)\n xhr.send( ( s.hasContent && s.data ) || null );\n\n // Listener\n callback = function( _, isAbort ) {\n\n var status,\n statusText,\n responseHeaders,\n responses,\n xml;\n\n // Firefox throws exceptions when accessing properties\n // of an xhr when a network error occurred\n // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n try {\n\n // Was never called and is aborted or complete\n if ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n // Only called once\n callback = undefined;\n\n // Do not keep as active anymore\n if ( handle ) {\n xhr.onreadystatechange = jQuery.noop;\n if ( xhrOnUnloadAbort ) {\n delete xhrCallbacks[ handle ];\n }\n }\n\n // If it's an abort\n if ( isAbort ) {\n // Abort it manually if needed\n if ( xhr.readyState !== 4 ) {\n xhr.abort();\n }\n } else {\n status = xhr.status;\n responseHeaders = xhr.getAllResponseHeaders();\n responses = {};\n xml = xhr.responseXML;\n\n // Construct response list\n if ( xml && xml.documentElement /* #4958 */ ) {\n responses.xml = xml;\n }\n\n // When requesting binary data, IE6-9 will throw an exception\n // on any attempt to access responseText (#11426)\n try {\n responses.text = xhr.responseText;\n } catch( e ) {\n }\n\n // Firefox throws an exception when accessing\n // statusText for faulty cross-domain requests\n try {\n statusText = xhr.statusText;\n } catch( e ) {\n // We normalize with Webkit giving an empty statusText\n statusText = \"\";\n }\n\n // Filter status for non standard behaviors\n\n // If the request is local and we have data: assume a success\n // (success with no data won't get notified, that's the best we\n // can do given current implementations)\n if ( !status && s.isLocal && !s.crossDomain ) {\n status = responses.text ? 200 : 404;\n // IE - #1450: sometimes returns 1223 when it should be 204\n } else if ( status === 1223 ) {\n status = 204;\n }\n }\n }\n } catch( firefoxAccessException ) {\n if ( !isAbort ) {\n complete( -1, firefoxAccessException );\n }\n }\n\n // Call complete if needed\n if ( responses ) {\n complete( status, statusText, responses, responseHeaders );\n }\n };\n\n if ( !s.async ) {\n // if we're in sync mode we fire the callback\n callback();\n } else if ( xhr.readyState === 4 ) {\n // (IE6 & IE7) if it's in cache and has been\n // retrieved directly we need to fire the callback\n setTimeout( callback, 0 );\n } else {\n handle = ++xhrId;\n if ( xhrOnUnloadAbort ) {\n // Create the active xhrs callbacks list if needed\n // and attach the unload handler\n if ( !xhrCallbacks ) {\n xhrCallbacks = {};\n jQuery( window ).unload( xhrOnUnloadAbort );\n }\n // Add to list of active xhrs callbacks\n xhrCallbacks[ handle ] = callback;\n }\n xhr.onreadystatechange = callback;\n }\n },\n\n abort: function() {\n if ( callback ) {\n callback(0,1);\n }\n }\n };\n }\n });\n}\nvar fxNow, timerId,\n rfxtypes = /^(?:toggle|show|hide)$/,\n rfxnum = new RegExp( \"^(?:([-+])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n rrun = /queueHooks$/,\n animationPrefilters = [ defaultPrefilter ],\n tweeners = {\n \"*\": [function( prop, value ) {\n var end, unit,\n tween = this.createTween( prop, value ),\n parts = rfxnum.exec( value ),\n target = tween.cur(),\n start = +target || 0,\n scale = 1,\n maxIterations = 20;\n\n if ( parts ) {\n end = +parts[2];\n unit = parts[3] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\n // We need to compute starting value\n if ( unit !== \"px\" && start ) {\n // Iteratively approximate from a nonzero starting point\n // Prefer the current property, because this process will be trivial if it uses the same units\n // Fallback to end or a simple constant\n start = jQuery.css( tween.elem, prop, true ) || end || 1;\n\n do {\n // If previous iteration zeroed out, double until we get *something*\n // Use a string for doubling factor so we don't accidentally see scale as unchanged below\n scale = scale || \".5\";\n\n // Adjust and apply\n start = start / scale;\n jQuery.style( tween.elem, prop, start + unit );\n\n // Update scale, tolerating zero or NaN from tween.cur()\n // And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n }\n\n tween.unit = unit;\n tween.start = start;\n // If a +=/-= token was provided, we're doing a relative animation\n tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;\n }\n return tween;\n }]\n };\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n setTimeout(function() {\n fxNow = undefined;\n }, 0 );\n return ( fxNow = jQuery.now() );\n}\n\nfunction createTweens( animation, props ) {\n jQuery.each( props, function( prop, value ) {\n var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n index = 0,\n length = collection.length;\n for ( ; index < length; index++ ) {\n if ( collection[ index ].call( animation, prop, value ) ) {\n\n // we're done with this property\n return;\n }\n }\n });\n}\n\nfunction Animation( elem, properties, options ) {\n var result,\n index = 0,\n tweenerIndex = 0,\n length = animationPrefilters.length,\n deferred = jQuery.Deferred().always( function() {\n // don't match elem in the :animated selector\n delete tick.elem;\n }),\n tick = function() {\n var currentTime = fxNow || createFxNow(),\n remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n temp = remaining / animation.duration || 0,\n percent = 1 - temp,\n index = 0,\n length = animation.tweens.length;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( percent );\n }\n\n deferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n if ( percent < 1 && length ) {\n return remaining;\n } else {\n deferred.resolveWith( elem, [ animation ] );\n return false;\n }\n },\n animation = deferred.promise({\n elem: elem,\n props: jQuery.extend( {}, properties ),\n opts: jQuery.extend( true, { specialEasing: {} }, options ),\n originalProperties: properties,\n originalOptions: options,\n startTime: fxNow || createFxNow(),\n duration: options.duration,\n tweens: [],\n createTween: function( prop, end, easing ) {\n var tween = jQuery.Tween( elem, animation.opts, prop, end,\n animation.opts.specialEasing[ prop ] || animation.opts.easing );\n animation.tweens.push( tween );\n return tween;\n },\n stop: function( gotoEnd ) {\n var index = 0,\n // if we are going to the end, we want to run all the tweens\n // otherwise we skip this part\n length = gotoEnd ? animation.tweens.length : 0;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( 1 );\n }\n\n // resolve when we played the last frame\n // otherwise, reject\n if ( gotoEnd ) {\n deferred.resolveWith( elem, [ animation, gotoEnd ] );\n } else {\n deferred.rejectWith( elem, [ animation, gotoEnd ] );\n }\n return this;\n }\n }),\n props = animation.props;\n\n propFilter( props, animation.opts.specialEasing );\n\n for ( ; index < length ; index++ ) {\n result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n if ( result ) {\n return result;\n }\n }\n\n createTweens( animation, props );\n\n if ( jQuery.isFunction( animation.opts.start ) ) {\n animation.opts.start.call( elem, animation );\n }\n\n jQuery.fx.timer(\n jQuery.extend( tick, {\n anim: animation,\n queue: animation.opts.queue,\n elem: elem\n })\n );\n\n // attach callbacks from options\n return animation.progress( animation.opts.progress )\n .done( animation.opts.done, animation.opts.complete )\n .fail( animation.opts.fail )\n .always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n var index, name, easing, value, hooks;\n\n // camelCase, specialEasing and expand cssHook pass\n for ( index in props ) {\n name = jQuery.camelCase( index );\n easing = specialEasing[ name ];\n value = props[ index ];\n if ( jQuery.isArray( value ) ) {\n easing = value[ 1 ];\n value = props[ index ] = value[ 0 ];\n }\n\n if ( index !== name ) {\n props[ name ] = value;\n delete props[ index ];\n }\n\n hooks = jQuery.cssHooks[ name ];\n if ( hooks && \"expand\" in hooks ) {\n value = hooks.expand( value );\n delete props[ name ];\n\n // not quite $.extend, this wont overwrite keys already present.\n // also - reusing 'index' from above because we have the correct \"name\"\n for ( index in value ) {\n if ( !( index in props ) ) {\n props[ index ] = value[ index ];\n specialEasing[ index ] = easing;\n }\n }\n } else {\n specialEasing[ name ] = easing;\n }\n }\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n tweener: function( props, callback ) {\n if ( jQuery.isFunction( props ) ) {\n callback = props;\n props = [ \"*\" ];\n } else {\n props = props.split(\" \");\n }\n\n var prop,\n index = 0,\n length = props.length;\n\n for ( ; index < length ; index++ ) {\n prop = props[ index ];\n tweeners[ prop ] = tweeners[ prop ] || [];\n tweeners[ prop ].unshift( callback );\n }\n },\n\n prefilter: function( callback, prepend ) {\n if ( prepend ) {\n animationPrefilters.unshift( callback );\n } else {\n animationPrefilters.push( callback );\n }\n }\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,\n anim = this,\n style = elem.style,\n orig = {},\n handled = [],\n hidden = elem.nodeType && isHidden( elem );\n\n // handle queue: false promises\n if ( !opts.queue ) {\n hooks = jQuery._queueHooks( elem, \"fx\" );\n if ( hooks.unqueued == null ) {\n hooks.unqueued = 0;\n oldfire = hooks.empty.fire;\n hooks.empty.fire = function() {\n if ( !hooks.unqueued ) {\n oldfire();\n }\n };\n }\n hooks.unqueued++;\n\n anim.always(function() {\n // doing this makes sure that the complete handler will be called\n // before this completes\n anim.always(function() {\n hooks.unqueued--;\n if ( !jQuery.queue( elem, \"fx\" ).length ) {\n hooks.empty.fire();\n }\n });\n });\n }\n\n // height/width overflow pass\n if ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n // Make sure that nothing sneaks out\n // Record all 3 overflow attributes because IE does not\n // change the overflow attribute when overflowX and\n // overflowY are set to the same value\n opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n // Set display property to inline-block for height/width\n // animations on inline elements that are having width/height animated\n if ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n // inline-level elements accept inline-block;\n // block-level elements need to be inline with layout\n if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n style.display = \"inline-block\";\n\n } else {\n style.zoom = 1;\n }\n }\n }\n\n if ( opts.overflow ) {\n style.overflow = \"hidden\";\n if ( !jQuery.support.shrinkWrapBlocks ) {\n anim.done(function() {\n style.overflow = opts.overflow[ 0 ];\n style.overflowX = opts.overflow[ 1 ];\n style.overflowY = opts.overflow[ 2 ];\n });\n }\n }\n\n\n // show/hide pass\n for ( index in props ) {\n value = props[ index ];\n if ( rfxtypes.exec( value ) ) {\n delete props[ index ];\n toggle = toggle || value === \"toggle\";\n if ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n continue;\n }\n handled.push( index );\n }\n }\n\n length = handled.length;\n if ( length ) {\n dataShow = jQuery._data( elem, \"fxshow\" ) || jQuery._data( elem, \"fxshow\", {} );\n if ( \"hidden\" in dataShow ) {\n hidden = dataShow.hidden;\n }\n\n // store state if its toggle - enables .stop().toggle() to \"reverse\"\n if ( toggle ) {\n dataShow.hidden = !hidden;\n }\n if ( hidden ) {\n jQuery( elem ).show();\n } else {\n anim.done(function() {\n jQuery( elem ).hide();\n });\n }\n anim.done(function() {\n var prop;\n jQuery.removeData( elem, \"fxshow\", true );\n for ( prop in orig ) {\n jQuery.style( elem, prop, orig[ prop ] );\n }\n });\n for ( index = 0 ; index < length ; index++ ) {\n prop = handled[ index ];\n tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );\n orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );\n\n if ( !( prop in dataShow ) ) {\n dataShow[ prop ] = tween.start;\n if ( hidden ) {\n tween.end = tween.start;\n tween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n }\n }\n }\n }\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n return new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n constructor: Tween,\n init: function( elem, options, prop, end, easing, unit ) {\n this.elem = elem;\n this.prop = prop;\n this.easing = easing || \"swing\";\n this.options = options;\n this.start = this.now = this.cur();\n this.end = end;\n this.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n },\n cur: function() {\n var hooks = Tween.propHooks[ this.prop ];\n\n return hooks && hooks.get ?\n hooks.get( this ) :\n Tween.propHooks._default.get( this );\n },\n run: function( percent ) {\n var eased,\n hooks = Tween.propHooks[ this.prop ];\n\n if ( this.options.duration ) {\n this.pos = eased = jQuery.easing[ this.easing ](\n percent, this.options.duration * percent, 0, 1, this.options.duration\n );\n } else {\n this.pos = eased = percent;\n }\n this.now = ( this.end - this.start ) * eased + this.start;\n\n if ( this.options.step ) {\n this.options.step.call( this.elem, this.now, this );\n }\n\n if ( hooks && hooks.set ) {\n hooks.set( this );\n } else {\n Tween.propHooks._default.set( this );\n }\n return this;\n }\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n _default: {\n get: function( tween ) {\n var result;\n\n if ( tween.elem[ tween.prop ] != null &&\n (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n return tween.elem[ tween.prop ];\n }\n\n // passing any value as a 4th parameter to .css will automatically\n // attempt a parseFloat and fallback to a string if the parse fails\n // so, simple values such as \"10px\" are parsed to Float.\n // complex values such as \"rotate(1rad)\" are returned as is.\n result = jQuery.css( tween.elem, tween.prop, false, \"\" );\n // Empty strings, null, undefined and \"auto\" are converted to 0.\n return !result || result === \"auto\" ? 0 : result;\n },\n set: function( tween ) {\n // use step hook for back compat - use cssHook if its there - use .style if its\n // available and use plain properties where available\n if ( jQuery.fx.step[ tween.prop ] ) {\n jQuery.fx.step[ tween.prop ]( tween );\n } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n } else {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n }\n};\n\n// Remove in 2.0 - this supports IE8's panic based approach\n// to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n set: function( tween ) {\n if ( tween.elem.nodeType && tween.elem.parentNode ) {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n var cssFn = jQuery.fn[ name ];\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return speed == null || typeof speed === \"boolean\" ||\n // special check for .toggle( handler, handler, ... )\n ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?\n cssFn.apply( this, arguments ) :\n this.animate( genFx( name, true ), speed, easing, callback );\n };\n});\n\njQuery.fn.extend({\n fadeTo: function( speed, to, easing, callback ) {\n\n // show any hidden elements after setting opacity to 0\n return this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n // animate to the value specified\n .end().animate({ opacity: to }, speed, easing, callback );\n },\n animate: function( prop, speed, easing, callback ) {\n var empty = jQuery.isEmptyObject( prop ),\n optall = jQuery.speed( speed, easing, callback ),\n doAnimation = function() {\n // Operate on a copy of prop so per-property easing won't be lost\n var anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n // Empty animations resolve immediately\n if ( empty ) {\n anim.stop( true );\n }\n };\n\n return empty || optall.queue === false ?\n this.each( doAnimation ) :\n this.queue( optall.queue, doAnimation );\n },\n stop: function( type, clearQueue, gotoEnd ) {\n var stopQueue = function( hooks ) {\n var stop = hooks.stop;\n delete hooks.stop;\n stop( gotoEnd );\n };\n\n if ( typeof type !== \"string\" ) {\n gotoEnd = clearQueue;\n clearQueue = type;\n type = undefined;\n }\n if ( clearQueue && type !== false ) {\n this.queue( type || \"fx\", [] );\n }\n\n return this.each(function() {\n var dequeue = true,\n index = type != null && type + \"queueHooks\",\n timers = jQuery.timers,\n data = jQuery._data( this );\n\n if ( index ) {\n if ( data[ index ] && data[ index ].stop ) {\n stopQueue( data[ index ] );\n }\n } else {\n for ( index in data ) {\n if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n stopQueue( data[ index ] );\n }\n }\n }\n\n for ( index = timers.length; index--; ) {\n if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n timers[ index ].anim.stop( gotoEnd );\n dequeue = false;\n timers.splice( index, 1 );\n }\n }\n\n // start the next in the queue if the last step wasn't forced\n // timers currently will call their complete callbacks, which will dequeue\n // but only if they were gotoEnd\n if ( dequeue || !gotoEnd ) {\n jQuery.dequeue( this, type );\n }\n });\n }\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n var which,\n attrs = { height: type },\n i = 0;\n\n // if we include width, step value is 1 to do all cssExpand values,\n // if we don't include width, step value is 2 to skip over Left and Right\n includeWidth = includeWidth? 1 : 0;\n for( ; i < 4 ; i += 2 - includeWidth ) {\n which = cssExpand[ i ];\n attrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n }\n\n if ( includeWidth ) {\n attrs.opacity = attrs.width = type;\n }\n\n return attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n slideDown: genFx(\"show\"),\n slideUp: genFx(\"hide\"),\n slideToggle: genFx(\"toggle\"),\n fadeIn: { opacity: \"show\" },\n fadeOut: { opacity: \"hide\" },\n fadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return this.animate( props, speed, easing, callback );\n };\n});\n\njQuery.speed = function( speed, easing, fn ) {\n var opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n complete: fn || !fn && easing ||\n jQuery.isFunction( speed ) && speed,\n duration: speed,\n easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n };\n\n opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n // normalize opt.queue - true/undefined/null -> \"fx\"\n if ( opt.queue == null || opt.queue === true ) {\n opt.queue = \"fx\";\n }\n\n // Queueing\n opt.old = opt.complete;\n\n opt.complete = function() {\n if ( jQuery.isFunction( opt.old ) ) {\n opt.old.call( this );\n }\n\n if ( opt.queue ) {\n jQuery.dequeue( this, opt.queue );\n }\n };\n\n return opt;\n};\n\njQuery.easing = {\n linear: function( p ) {\n return p;\n },\n swing: function( p ) {\n return 0.5 - Math.cos( p*Math.PI ) / 2;\n }\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n var timer,\n timers = jQuery.timers,\n i = 0;\n\n fxNow = jQuery.now();\n\n for ( ; i < timers.length; i++ ) {\n timer = timers[ i ];\n // Checks the timer has not already been removed\n if ( !timer() && timers[ i ] === timer ) {\n timers.splice( i--, 1 );\n }\n }\n\n if ( !timers.length ) {\n jQuery.fx.stop();\n }\n fxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n if ( timer() && jQuery.timers.push( timer ) && !timerId ) {\n timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n }\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.stop = function() {\n clearInterval( timerId );\n timerId = null;\n};\n\njQuery.fx.speeds = {\n slow: 600,\n fast: 200,\n // Default speed\n _default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.animated = function( elem ) {\n return jQuery.grep(jQuery.timers, function( fn ) {\n return elem === fn.elem;\n }).length;\n };\n}\nvar rroot = /^(?:body|html)$/i;\n\njQuery.fn.offset = function( options ) {\n if ( arguments.length ) {\n return options === undefined ?\n this :\n this.each(function( i ) {\n jQuery.offset.setOffset( this, options, i );\n });\n }\n\n var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,\n box = { top: 0, left: 0 },\n elem = this[ 0 ],\n doc = elem && elem.ownerDocument;\n\n if ( !doc ) {\n return;\n }\n\n if ( (body = doc.body) === elem ) {\n return jQuery.offset.bodyOffset( elem );\n }\n\n docElem = doc.documentElement;\n\n // Make sure it's not a disconnected DOM node\n if ( !jQuery.contains( docElem, elem ) ) {\n return box;\n }\n\n // If we don't have gBCR, just use 0,0 rather than error\n // BlackBerry 5, iOS 3 (original iPhone)\n if ( typeof elem.getBoundingClientRect !== \"undefined\" ) {\n box = elem.getBoundingClientRect();\n }\n win = getWindow( doc );\n clientTop = docElem.clientTop || body.clientTop || 0;\n clientLeft = docElem.clientLeft || body.clientLeft || 0;\n scrollTop = win.pageYOffset || docElem.scrollTop;\n scrollLeft = win.pageXOffset || docElem.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n};\n\njQuery.offset = {\n\n bodyOffset: function( body ) {\n var top = body.offsetTop,\n left = body.offsetLeft;\n\n if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {\n top += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n left += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n }\n\n return { top: top, left: left };\n },\n\n setOffset: function( elem, options, i ) {\n var position = jQuery.css( elem, \"position\" );\n\n // set position first, in-case top/left are set even on static elem\n if ( position === \"static\" ) {\n elem.style.position = \"relative\";\n }\n\n var curElem = jQuery( elem ),\n curOffset = curElem.offset(),\n curCSSTop = jQuery.css( elem, \"top\" ),\n curCSSLeft = jQuery.css( elem, \"left\" ),\n calculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n props = {}, curPosition = {}, curTop, curLeft;\n\n // need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n if ( calculatePosition ) {\n curPosition = curElem.position();\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat( curCSSTop ) || 0;\n curLeft = parseFloat( curCSSLeft ) || 0;\n }\n\n if ( jQuery.isFunction( options ) ) {\n options = options.call( elem, i, curOffset );\n }\n\n if ( options.top != null ) {\n props.top = ( options.top - curOffset.top ) + curTop;\n }\n if ( options.left != null ) {\n props.left = ( options.left - curOffset.left ) + curLeft;\n }\n\n if ( \"using\" in options ) {\n options.using.call( elem, props );\n } else {\n curElem.css( props );\n }\n }\n};\n\n\njQuery.fn.extend({\n\n position: function() {\n if ( !this[0] ) {\n return;\n }\n\n var elem = this[0],\n\n // Get *real* offsetParent\n offsetParent = this.offsetParent(),\n\n // Get correct offsets\n offset = this.offset(),\n parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n // Subtract element margins\n // note: when an element has margin: auto the offsetLeft and marginLeft\n // are the same in Safari causing offset.left to incorrectly be 0\n offset.top -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n offset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n // Add offsetParent borders\n parentOffset.top += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n parentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n // Subtract the two offsets\n return {\n top: offset.top - parentOffset.top,\n left: offset.left - parentOffset.left\n };\n },\n\n offsetParent: function() {\n return this.map(function() {\n var offsetParent = this.offsetParent || document.body;\n while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || document.body;\n });\n }\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n var top = /Y/.test( prop );\n\n jQuery.fn[ method ] = function( val ) {\n return jQuery.access( this, function( elem, method, val ) {\n var win = getWindow( elem );\n\n if ( val === undefined ) {\n return win ? (prop in win) ? win[ prop ] :\n win.document.documentElement[ method ] :\n elem[ method ];\n }\n\n if ( win ) {\n win.scrollTo(\n !top ? val : jQuery( win ).scrollLeft(),\n top ? val : jQuery( win ).scrollTop()\n );\n\n } else {\n elem[ method ] = val;\n }\n }, method, val, arguments.length, null );\n };\n});\n\nfunction getWindow( elem ) {\n return jQuery.isWindow( elem ) ?\n elem :\n elem.nodeType === 9 ?\n elem.defaultView || elem.parentWindow :\n false;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n jQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n // margin is only for outerHeight, outerWidth\n jQuery.fn[ funcName ] = function( margin, value ) {\n var chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n extra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n return jQuery.access( this, function( elem, type, value ) {\n var doc;\n\n if ( jQuery.isWindow( elem ) ) {\n // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n // isn't a whole lot we can do. See pull request at this URL for discussion:\n // https://github.com/jquery/jquery/pull/764\n return elem.document.documentElement[ \"client\" + name ];\n }\n\n // Get document width or height\n if ( elem.nodeType === 9 ) {\n doc = elem.documentElement;\n\n // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n return Math.max(\n elem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n elem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n doc[ \"client\" + name ]\n );\n }\n\n return value === undefined ?\n // Get width or height on the element, requesting but not forcing parseFloat\n jQuery.css( elem, type, value, extra ) :\n\n // Set width or height on the element\n jQuery.style( elem, type, value, extra );\n }, type, chainable ? margin : undefined, chainable, null );\n };\n });\n});\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n\n// Expose jQuery as an AMD module, but only for AMD loaders that\n// understand the issues with loading multiple versions of jQuery\n// in a page that all might call define(). The loader will indicate\n// they have special allowances for multiple jQuery versions by\n// specifying define.amd.jQuery = true. Register as a named module,\n// since jQuery can be concatenated with other files that may use define,\n// but not use a proper concatenation script that understands anonymous\n// AMD modules. A named AMD is safest and most robust way to register.\n// Lowercase jquery is used because AMD module names are derived from\n// file names, and jQuery is normally delivered in a lowercase file name.\n// Do this after creating the global so that if an AMD module wants to call\n// noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd && define.amd.jQuery ) {\n define( \"jquery\", [], function () { return jQuery; } );\n}\n\n})( window );", - "settings": - { - "buffer_size": 287804, - "line_ending": "Unix", - "name": "/*!" - } - }, - { - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "line_ending": "Unix" - } - }, - { - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "line_ending": "Unix" - } - }, - { - "contents": "var CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});", - "settings": - { - "buffer_size": 322, - "line_ending": "Unix" - } - }, - { - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "line_ending": "Unix" - } - } - ], - "build_system": "", - "command_palette": - { - "height": 87.0, - "selected_items": - [ - [ - "Package Control: in", - "Package Control: Install Package" - ], - [ - "Package Control: ins", - "Package Control: Install Package" - ], - [ - "ins", - "Package Control: Install Package" - ], - [ - "insta", - "Package Control: Install Package" - ] - ], - "width": 467.0 - }, - "console": - { - "height": 125.0 - }, - "distraction_free": - { - "menu_visible": true, - "show_minimap": false, - "show_open_files": false, - "show_tabs": false, - "side_bar_visible": false, - "status_bar_visible": false - }, - "file_history": - [ - "/Users/alexi/Dropbox/Projects/node-form-data/test/integration/test-http-respone.js", - "/Users/alexi/Dropbox/Projects/node-form-data/test/run.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config-alt.json", - "/Users/alexi/Desktop/test/file.txt", - "/Users/alexi/Desktop/stuff/kodak/web.js", - "/Users/alexi/Desktop/test/test1.js", - "/Users/alexi/Desktop/test/spdy.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/echo.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/test.html", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/passthrough_stream.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/tests/test-pipes.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/a/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/lib/flickr.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/lib/socket.io.js", - "/var/folders/xn/475pdrpd72n4s6gdh4y_c2dm0000gn/T/sublime-sftp-browse-1342313240/mapped/var/www/libereco.ia.gs/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config.json", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/public/index.html", - "/Users/alexi/Desktop/kodak/dns.js", - "/Users/alexi/Dropbox/Projects/500.ia.gs/htdocs/s/fonts.css", - "/Users/alexi/Dropbox/Projects/ia.gs/sftp-config.json", - "/Users/alexi/Downloads/fabric_plaid.png", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Global.sublime-settings", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/router.js", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/404.html", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/500.html", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/http/index.js", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/SFTP.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/Default (OSX).sublime-keymap", - "/Users/alexi/Sites/new/sftp-config.json", - "/Users/alexi/Sites/new/polarbear.css", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/User/Base File.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Base File.sublime-settings", - "/Users/alexi/Sites/new/include/Controllers/Home/HomepageController.php" - ], - "find": - { - "height": 35.0 - }, - "find_in_files": - { - "height": 0.0, - "where_history": - [ - "" - ] - }, - "find_state": - { - "case_sensitive": false, - "find_history": - [ - "readable", - "argument", - "mikeal", - "return;", - "throw arguments[1]", - "arguments[1]", - "throw arguments", - "throw arguments[1]", - "path", - "conso", - "isStreamLike", - "parseUrl", - "stream", - "node.js", - "stream", - "http://libereco.ia.gs/", - "flickr_message_nopro", - "auth:done", - "con", - "console", - "photos", - "isReadStream", - "Buffer", - "Bufer", - "multipart", - "sig", - "api", - "api_", - "api_sig", - "writeFile", - "googledoodle.png", - "attachment", - "_write", - "fs", - "mime", - "_putOrPost", - "_performSecureRequest", - "8034", - "try", - "paramsToQueryString", - "_executeOAuthAPIRequest", - "oauth_client", - "_createClient", - "authorization", - "body", - "_performSecureRequest", - "query", - "io.", - ".listen", - "io", - "config", - "set", - "console", - "'next'", - "console", - "_asyncEverySeries", - "runlist", - "function", - "async", - "local", - "Find schools", - "What's up" - ], - "highlight": true, - "in_selection": false, - "preserve_case": false, - "regex": false, - "replace_history": - [ - ], - "reverse": false, - "show_context": true, - "use_buffer2": true, - "whole_word": false, - "wrap": true - }, - "groups": - [ - { - "selected": 1, - "sheets": - [ - { - "buffer": 0, - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "regions": - { - }, - "selection": - [ - [ - 654, - 673 - ] - ], - "settings": - { - "function_name_status_row": 18, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 238.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 1, - "file": "package.json", - "settings": - { - "buffer_size": 673, - "regions": - { - }, - "selection": - [ - [ - 282, - 282 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JSON.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 2, - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "regions": - { - }, - "selection": - [ - [ - 1940, - 1940 - ] - ], - "settings": - { - "function_name_status_row": 65, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 658.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 3, - "settings": - { - "buffer_size": 287804, - "regions": - { - }, - "selection": - [ - [ - 8273, - 8279 - ] - ], - "settings": - { - "auto_name": "/*!", - "function_name_status_row": 290, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 5683.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 4, - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "regions": - { - }, - "selection": - [ - [ - 3556, - 3556 - ] - ], - "settings": - { - "function_name_status_row": 111, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1200.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 5, - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "regions": - { - }, - "selection": - [ - [ - 3449, - 3449 - ] - ], - "settings": - { - "function_name_status_row": 104, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1268.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 6, - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "regions": - { - }, - "selection": - [ - [ - 2156, - 2156 - ] - ], - "settings": - { - "function_name_status_row": 88, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 59.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 7, - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "regions": - { - }, - "selection": - [ - [ - 0, - 0 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/Markdown/Markdown.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 996.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 8, - "settings": - { - "buffer_size": 322, - "regions": - { - }, - "selection": - [ - [ - 0, - 322 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 9, - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "regions": - { - }, - "selection": - [ - [ - 76, - 76 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - } - ] - } - ], - "incremental_find": - { - "height": 0.0 - }, - "input": - { - "height": 31.0 - }, - "layout": - { - "cells": - [ - [ - 0, - 0, - 1, - 1 - ] - ], - "cols": - [ - 0.0, - 1.0 - ], - "rows": - [ - 0.0, - 1.0 - ] - }, - "menu_visible": true, - "output.sftp": - { - "height": 108.0 - }, - "replace": - { - "height": 0.0 - }, - "save_all_on_build": true, - "select_file": - { - "height": 0.0, - "selected_items": - [ - [ - "homepagecon", - "include/Controllers/Home/HomepageController.php" - ], - [ - "polar", - "polarbear.css" - ], - [ - "homepageco", - "include/Controllers/Home/HomepageController.php" - ], - [ - "homepage.js", - "include/js/application/homepage/homepage.js" - ] - ], - "width": 0.0 - }, - "select_project": - { - "height": 0.0, - "selected_items": - [ - ], - "width": 0.0 - }, - "show_minimap": true, - "show_open_files": true, - "show_tabs": true, - "side_bar_visible": true, - "side_bar_width": 250.0, - "status_bar_visible": true -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules b/api/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules deleted file mode 100644 index a9aae984f66..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "deps/nodeunit"] - path = deps/nodeunit - url = git://github.com/caolan/nodeunit.git -[submodule "deps/UglifyJS"] - path = deps/UglifyJS - url = https://github.com/mishoo/UglifyJS.git -[submodule "deps/nodelint"] - path = deps/nodelint - url = https://github.com/tav/nodelint.git diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/LICENSE b/api/node_modules/request/node_modules/form-data/node_modules/async/LICENSE deleted file mode 100644 index b7f9d5001c0..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Caolan McMahon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/Makefile b/api/node_modules/request/node_modules/form-data/node_modules/async/Makefile deleted file mode 100644 index 00f07ea02c1..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -PACKAGE = asyncjs -NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) - -BUILDDIR = dist - -all: build - -build: $(wildcard lib/*.js) - mkdir -p $(BUILDDIR) - uglifyjs lib/async.js > $(BUILDDIR)/async.min.js - -test: - nodeunit test - -clean: - rm -rf $(BUILDDIR) - -lint: - nodelint --config nodelint.cfg lib/async.js - -.PHONY: test build all diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/README.md b/api/node_modules/request/node_modules/form-data/node_modules/async/README.md deleted file mode 100644 index 9ff1acfdf57..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/README.md +++ /dev/null @@ -1,1414 +0,0 @@ -# Async.js - -Async is a utility module which provides straight-forward, powerful functions -for working with asynchronous JavaScript. Although originally designed for -use with [node.js](http://nodejs.org), it can also be used directly in the -browser. Also supports [component](https://github.com/component/component). - -Async provides around 20 functions that include the usual 'functional' -suspects (map, reduce, filter, each…) as well as some common patterns -for asynchronous control flow (parallel, series, waterfall…). All these -functions assume you follow the node.js convention of providing a single -callback as the last argument of your async function. - - -## Quick Examples - -```javascript -async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file -}); - -async.filter(['file1','file2','file3'], fs.exists, function(results){ - // results now equals an array of the existing files -}); - -async.parallel([ - function(){ ... }, - function(){ ... } -], callback); - -async.series([ - function(){ ... }, - function(){ ... } -]); -``` - -There are many more functions available so take a look at the docs below for a -full list. This module aims to be comprehensive, so if you feel anything is -missing please create a GitHub issue for it. - -## Common Pitfalls - -### Binding a context to an iterator - -This section is really about bind, not about async. If you are wondering how to -make async execute your iterators in a given context, or are confused as to why -a method of another library isn't working as an iterator, study this example: - -```js -// Here is a simple object with an (unnecessarily roundabout) squaring method -var AsyncSquaringLibrary = { - squareExponent: 2, - square: function(number, callback){ - var result = Math.pow(number, this.squareExponent); - setTimeout(function(){ - callback(null, result); - }, 200); - } -}; - -async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ - // result is [NaN, NaN, NaN] - // This fails because the `this.squareExponent` expression in the square - // function is not evaluated in the context of AsyncSquaringLibrary, and is - // therefore undefined. -}); - -async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ - // result is [1, 4, 9] - // With the help of bind we can attach a context to the iterator before - // passing it to async. Now the square function will be executed in its - // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` - // will be as expected. -}); -``` - -## Download - -The source is available for download from -[GitHub](http://github.com/caolan/async). -Alternatively, you can install using Node Package Manager (npm): - - npm install async - -__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed - -## In the Browser - -So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: - -```html - - -``` - -## Documentation - -### Collections - -* [each](#each) -* [map](#map) -* [filter](#filter) -* [reject](#reject) -* [reduce](#reduce) -* [detect](#detect) -* [sortBy](#sortBy) -* [some](#some) -* [every](#every) -* [concat](#concat) - -### Control Flow - -* [series](#series) -* [parallel](#parallel) -* [whilst](#whilst) -* [doWhilst](#doWhilst) -* [until](#until) -* [doUntil](#doUntil) -* [forever](#forever) -* [waterfall](#waterfall) -* [compose](#compose) -* [applyEach](#applyEach) -* [queue](#queue) -* [cargo](#cargo) -* [auto](#auto) -* [iterator](#iterator) -* [apply](#apply) -* [nextTick](#nextTick) -* [times](#times) -* [timesSeries](#timesSeries) - -### Utils - -* [memoize](#memoize) -* [unmemoize](#unmemoize) -* [log](#log) -* [dir](#dir) -* [noConflict](#noConflict) - - -## Collections - - - -### each(arr, iterator, callback) - -Applies an iterator function to each item in an array, in parallel. -The iterator is called with an item from the list and a callback for when it -has finished. If the iterator passes an error to this callback, the main -callback for the each function is immediately called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err) which must be called once it has - completed. If no error has occured, the callback should be run without - arguments or with an explicit null argument. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - -```js -// assuming openFiles is an array of file names and saveFile is a function -// to save the modified contents of that file: - -async.each(openFiles, saveFile, function(err){ - // if any of the saves produced an error, err would equal that error -}); -``` - ---------------------------------------- - - - -### eachSeries(arr, iterator, callback) - -The same as each only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. This means the iterator functions will complete in order. - - ---------------------------------------- - - - -### eachLimit(arr, limit, iterator, callback) - -The same as each only no more than "limit" iterators will be simultaneously -running at any time. - -Note that the items are not processed in batches, so there is no guarantee that - the first "limit" iterator functions will complete before any others are -started. - -__Arguments__ - -* arr - An array to iterate over. -* limit - The maximum number of iterators to run at any time. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err) which must be called once it has - completed. If no error has occured, the callback should be run without - arguments or with an explicit null argument. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - -```js -// Assume documents is an array of JSON objects and requestApi is a -// function that interacts with a rate-limited REST api. - -async.eachLimit(documents, 20, requestApi, function(err){ - // if any of the saves produced an error, err would equal that error -}); -``` - ---------------------------------------- - - -### map(arr, iterator, callback) - -Produces a new array of values by mapping each value in the given array through -the iterator function. The iterator is called with an item from the array and a -callback for when it has finished processing. The callback takes 2 arguments, -an error and the transformed item from the array. If the iterator passes an -error to this callback, the main callback for the map function is immediately -called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order, however -the results array will be in the same order as the original array. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, transformed) which must be called once - it has completed with an error (which can be null) and a transformed item. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array of the - transformed items from the original array. - -__Example__ - -```js -async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file -}); -``` - ---------------------------------------- - - -### mapSeries(arr, iterator, callback) - -The same as map only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - - ---------------------------------------- - - -### mapLimit(arr, limit, iterator, callback) - -The same as map only no more than "limit" iterators will be simultaneously -running at any time. - -Note that the items are not processed in batches, so there is no guarantee that - the first "limit" iterator functions will complete before any others are -started. - -__Arguments__ - -* arr - An array to iterate over. -* limit - The maximum number of iterators to run at any time. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, transformed) which must be called once - it has completed with an error (which can be null) and a transformed item. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array of the - transformed items from the original array. - -__Example__ - -```js -async.map(['file1','file2','file3'], 1, fs.stat, function(err, results){ - // results is now an array of stats for each file -}); -``` - ---------------------------------------- - - -### filter(arr, iterator, callback) - -__Alias:__ select - -Returns a new array of all the values which pass an async truth test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. This operation is -performed in parallel, but the results array will be in the same order as the -original. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(results) - A callback which is called after all the iterator - functions have finished. - -__Example__ - -```js -async.filter(['file1','file2','file3'], fs.exists, function(results){ - // results now equals an array of the existing files -}); -``` - ---------------------------------------- - - -### filterSeries(arr, iterator, callback) - -__alias:__ selectSeries - -The same as filter only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - ---------------------------------------- - - -### reject(arr, iterator, callback) - -The opposite of filter. Removes values that pass an async truth test. - ---------------------------------------- - - -### rejectSeries(arr, iterator, callback) - -The same as reject, only the iterator is applied to each item in the array -in series. - - ---------------------------------------- - - -### reduce(arr, memo, iterator, callback) - -__aliases:__ inject, foldl - -Reduces a list of values into a single value using an async iterator to return -each successive step. Memo is the initial state of the reduction. This -function only operates in series. For performance reasons, it may make sense to -split a call to this function into a parallel map, then use the normal -Array.prototype.reduce on the results. This function is for situations where -each step in the reduction needs to be async, if you can get the data before -reducing it then it's probably a good idea to do so. - -__Arguments__ - -* arr - An array to iterate over. -* memo - The initial state of the reduction. -* iterator(memo, item, callback) - A function applied to each item in the - array to produce the next step in the reduction. The iterator is passed a - callback(err, reduction) which accepts an optional error as its first - argument, and the state of the reduction as the second. If an error is - passed to the callback, the reduction is stopped and the main callback is - immediately called with the error. -* callback(err, result) - A callback which is called after all the iterator - functions have finished. Result is the reduced value. - -__Example__ - -```js -async.reduce([1,2,3], 0, function(memo, item, callback){ - // pointless async: - process.nextTick(function(){ - callback(null, memo + item) - }); -}, function(err, result){ - // result is now equal to the last value of memo, which is 6 -}); -``` - ---------------------------------------- - - -### reduceRight(arr, memo, iterator, callback) - -__Alias:__ foldr - -Same as reduce, only operates on the items in the array in reverse order. - - ---------------------------------------- - - -### detect(arr, iterator, callback) - -Returns the first value in a list that passes an async truth test. The -iterator is applied in parallel, meaning the first iterator to return true will -fire the detect callback with that result. That means the result might not be -the first item in the original array (in terms of order) that passes the test. - -If order within the original array is important then look at detectSeries. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - the first item in the array that passes the truth test (iterator) or the - value undefined if none passed. - -__Example__ - -```js -async.detect(['file1','file2','file3'], fs.exists, function(result){ - // result now equals the first file in the list that exists -}); -``` - ---------------------------------------- - - -### detectSeries(arr, iterator, callback) - -The same as detect, only the iterator is applied to each item in the array -in series. This means the result is always the first in the original array (in -terms of array order) that passes the truth test. - - ---------------------------------------- - - -### sortBy(arr, iterator, callback) - -Sorts a list by the results of running each value through an async iterator. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, sortValue) which must be called once it - has completed with an error (which can be null) and a value to use as the sort - criteria. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is the items from - the original array sorted by the values returned by the iterator calls. - -__Example__ - -```js -async.sortBy(['file1','file2','file3'], function(file, callback){ - fs.stat(file, function(err, stats){ - callback(err, stats.mtime); - }); -}, function(err, results){ - // results is now the original array of files sorted by - // modified date -}); -``` - ---------------------------------------- - - -### some(arr, iterator, callback) - -__Alias:__ any - -Returns true if at least one element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. Once any iterator -call returns true, the main callback is immediately called. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - either true or false depending on the values of the async tests. - -__Example__ - -```js -async.some(['file1','file2','file3'], fs.exists, function(result){ - // if result is true then at least one of the files exists -}); -``` - ---------------------------------------- - - -### every(arr, iterator, callback) - -__Alias:__ all - -Returns true if every element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called after all the iterator - functions have finished. Result will be either true or false depending on - the values of the async tests. - -__Example__ - -```js -async.every(['file1','file2','file3'], fs.exists, function(result){ - // if result is true then every file exists -}); -``` - ---------------------------------------- - - -### concat(arr, iterator, callback) - -Applies an iterator to each item in a list, concatenating the results. Returns the -concatenated list. The iterators are called in parallel, and the results are -concatenated as they return. There is no guarantee that the results array will -be returned in the original order of the arguments passed to the iterator function. - -__Arguments__ - -* arr - An array to iterate over -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, results) which must be called once it - has completed with an error (which can be null) and an array of results. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array containing - the concatenated results of the iterator function. - -__Example__ - -```js -async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ - // files is now a list of filenames that exist in the 3 directories -}); -``` - ---------------------------------------- - - -### concatSeries(arr, iterator, callback) - -Same as async.concat, but executes in series instead of parallel. - - -## Control Flow - - -### series(tasks, [callback]) - -Run an array of functions in series, each one running once the previous -function has completed. If any functions in the series pass an error to its -callback, no more functions are run and the callback for the series is -immediately called with the value of the error. Once the tasks have completed, -the results are passed to the final callback as an array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.series. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - -__Example__ - -```js -async.series([ - function(callback){ - // do some stuff ... - callback(null, 'one'); - }, - function(callback){ - // do some more stuff ... - callback(null, 'two'); - } -], -// optional callback -function(err, results){ - // results is now equal to ['one', 'two'] -}); - - -// an example using an object instead of an array -async.series({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equal to: {one: 1, two: 2} -}); -``` - ---------------------------------------- - - -### parallel(tasks, [callback]) - -Run an array of functions in parallel, without waiting until the previous -function has completed. If any of the functions pass an error to its -callback, the main callback is immediately called with the value of the error. -Once the tasks have completed, the results are passed to the final callback as an -array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.parallel. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - -__Example__ - -```js -async.parallel([ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - } -], -// optional callback -function(err, results){ - // the results array will equal ['one','two'] even though - // the second function had a shorter timeout. -}); - - -// an example using an object instead of an array -async.parallel({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equals to: {one: 1, two: 2} -}); -``` - ---------------------------------------- - - -### parallelLimit(tasks, limit, [callback]) - -The same as parallel only the tasks are executed in parallel with a maximum of "limit" -tasks executing at any time. - -Note that the tasks are not executed in batches, so there is no guarantee that -the first "limit" tasks will complete before any others are started. - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* limit - The maximum number of tasks to run at any time. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - ---------------------------------------- - - -### whilst(test, fn, callback) - -Repeatedly call fn, while test returns true. Calls the callback when stopped, -or an error occurs. - -__Arguments__ - -* test() - synchronous truth test to perform before each execution of fn. -* fn(callback) - A function to call each time the test passes. The function is - passed a callback(err) which must be called once it has completed with an - optional error argument. -* callback(err) - A callback which is called after the test fails and repeated - execution of fn has stopped. - -__Example__ - -```js -var count = 0; - -async.whilst( - function () { return count < 5; }, - function (callback) { - count++; - setTimeout(callback, 1000); - }, - function (err) { - // 5 seconds have passed - } -); -``` - ---------------------------------------- - - -### doWhilst(fn, test, callback) - -The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. - ---------------------------------------- - - -### until(test, fn, callback) - -Repeatedly call fn, until test returns true. Calls the callback when stopped, -or an error occurs. - -The inverse of async.whilst. - ---------------------------------------- - - -### doUntil(fn, test, callback) - -Like doWhilst except the test is inverted. Note the argument ordering differs from `until`. - ---------------------------------------- - - -### forever(fn, callback) - -Calls the asynchronous function 'fn' repeatedly, in series, indefinitely. -If an error is passed to fn's callback then 'callback' is called with the -error, otherwise it will never be called. - ---------------------------------------- - - -### waterfall(tasks, [callback]) - -Runs an array of functions in series, each passing their results to the next in -the array. However, if any of the functions pass an error to the callback, the -next function is not executed and the main callback is immediately called with -the error. - -__Arguments__ - -* tasks - An array of functions to run, each function is passed a - callback(err, result1, result2, ...) it must call on completion. The first - argument is an error (which can be null) and any further arguments will be - passed as arguments in order to the next task. -* callback(err, [results]) - An optional callback to run once all the functions - have completed. This will be passed the results of the last task's callback. - - - -__Example__ - -```js -async.waterfall([ - function(callback){ - callback(null, 'one', 'two'); - }, - function(arg1, arg2, callback){ - callback(null, 'three'); - }, - function(arg1, callback){ - // arg1 now equals 'three' - callback(null, 'done'); - } -], function (err, result) { - // result now equals 'done' -}); -``` - ---------------------------------------- - -### compose(fn1, fn2...) - -Creates a function which is a composition of the passed asynchronous -functions. Each function consumes the return value of the function that -follows. Composing functions f(), g() and h() would produce the result of -f(g(h())), only this version uses callbacks to obtain the return values. - -Each function is executed with the `this` binding of the composed function. - -__Arguments__ - -* functions... - the asynchronous functions to compose - - -__Example__ - -```js -function add1(n, callback) { - setTimeout(function () { - callback(null, n + 1); - }, 10); -} - -function mul3(n, callback) { - setTimeout(function () { - callback(null, n * 3); - }, 10); -} - -var add1mul3 = async.compose(mul3, add1); - -add1mul3(4, function (err, result) { - // result now equals 15 -}); -``` - ---------------------------------------- - -### applyEach(fns, args..., callback) - -Applies the provided arguments to each function in the array, calling the -callback after all functions have completed. If you only provide the first -argument then it will return a function which lets you pass in the -arguments as if it were a single function call. - -__Arguments__ - -* fns - the asynchronous functions to all call with the same arguments -* args... - any number of separate arguments to pass to the function -* callback - the final argument should be the callback, called when all - functions have completed processing - - -__Example__ - -```js -async.applyEach([enableSearch, updateSchema], 'bucket', callback); - -// partial application example: -async.each( - buckets, - async.applyEach([enableSearch, updateSchema]), - callback -); -``` - ---------------------------------------- - - -### applyEachSeries(arr, iterator, callback) - -The same as applyEach only the functions are applied in series. - ---------------------------------------- - - -### queue(worker, concurrency) - -Creates a queue object with the specified concurrency. Tasks added to the -queue will be processed in parallel (up to the concurrency limit). If all -workers are in progress, the task is queued until one is available. Once -a worker has completed a task, the task's callback is called. - -__Arguments__ - -* worker(task, callback) - An asynchronous function for processing a queued - task, which must call its callback(err) argument when finished, with an - optional error as an argument. -* concurrency - An integer for determining how many worker functions should be - run in parallel. - -__Queue objects__ - -The queue object returned by this function has the following properties and -methods: - -* length() - a function returning the number of items waiting to be processed. -* concurrency - an integer for determining how many worker functions should be - run in parallel. This property can be changed after a queue is created to - alter the concurrency on-the-fly. -* push(task, [callback]) - add a new task to the queue, the callback is called - once the worker has finished processing the task. - instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. -* unshift(task, [callback]) - add a new task to the front of the queue. -* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued -* empty - a callback that is called when the last item from the queue is given to a worker -* drain - a callback that is called when the last item from the queue has returned from the worker - -__Example__ - -```js -// create a queue object with concurrency 2 - -var q = async.queue(function (task, callback) { - console.log('hello ' + task.name); - callback(); -}, 2); - - -// assign a callback -q.drain = function() { - console.log('all items have been processed'); -} - -// add some items to the queue - -q.push({name: 'foo'}, function (err) { - console.log('finished processing foo'); -}); -q.push({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); - -// add some items to the queue (batch-wise) - -q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { - console.log('finished processing bar'); -}); - -// add some items to the front of the queue - -q.unshift({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); -``` - ---------------------------------------- - - -### cargo(worker, [payload]) - -Creates a cargo object with the specified payload. Tasks added to the -cargo will be processed altogether (up to the payload limit). If the -worker is in progress, the task is queued until it is available. Once -the worker has completed some tasks, each callback of those tasks is called. - -__Arguments__ - -* worker(tasks, callback) - An asynchronous function for processing an array of - queued tasks, which must call its callback(err) argument when finished, with - an optional error as an argument. -* payload - An optional integer for determining how many tasks should be - processed per round; if omitted, the default is unlimited. - -__Cargo objects__ - -The cargo object returned by this function has the following properties and -methods: - -* length() - a function returning the number of items waiting to be processed. -* payload - an integer for determining how many tasks should be - process per round. This property can be changed after a cargo is created to - alter the payload on-the-fly. -* push(task, [callback]) - add a new task to the queue, the callback is called - once the worker has finished processing the task. - instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. -* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued -* empty - a callback that is called when the last item from the queue is given to a worker -* drain - a callback that is called when the last item from the queue has returned from the worker - -__Example__ - -```js -// create a cargo object with payload 2 - -var cargo = async.cargo(function (tasks, callback) { - for(var i=0; i -### auto(tasks, [callback]) - -Determines the best order for running functions based on their requirements. -Each function can optionally depend on other functions being completed first, -and each function is run as soon as its requirements are satisfied. If any of -the functions pass an error to their callback, that function will not complete -(so any other functions depending on it will not run) and the main callback -will be called immediately with the error. Functions also receive an object -containing the results of functions which have completed so far. - -Note, all functions are called with a results object as a second argument, -so it is unsafe to pass functions in the tasks object which cannot handle the -extra argument. For example, this snippet of code: - -```js -async.auto({ - readData: async.apply(fs.readFile, 'data.txt', 'utf-8'); -}, callback); -``` - -will have the effect of calling readFile with the results object as the last -argument, which will fail: - -```js -fs.readFile('data.txt', 'utf-8', cb, {}); -``` - -Instead, wrap the call to readFile in a function which does not forward the -results object: - -```js -async.auto({ - readData: function(cb, results){ - fs.readFile('data.txt', 'utf-8', cb); - } -}, callback); -``` - -__Arguments__ - -* tasks - An object literal containing named functions or an array of - requirements, with the function itself the last item in the array. The key - used for each function or array is used when specifying requirements. The - function receives two arguments: (1) a callback(err, result) which must be - called when finished, passing an error (which can be null) and the result of - the function's execution, and (2) a results object, containing the results of - the previously executed functions. -* callback(err, results) - An optional callback which is called when all the - tasks have been completed. The callback will receive an error as an argument - if any tasks pass an error to their callback. Results will always be passed - but if an error occurred, no other tasks will be performed, and the results - object will only contain partial results. - - -__Example__ - -```js -async.auto({ - get_data: function(callback){ - // async code to get some data - }, - make_folder: function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - }, - write_file: ['get_data', 'make_folder', function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - callback(null, filename); - }], - email_link: ['write_file', function(callback, results){ - // once the file is written let's email a link to it... - // results.write_file contains the filename returned by write_file. - }] -}); -``` - -This is a fairly trivial example, but to do this using the basic parallel and -series functions would look like this: - -```js -async.parallel([ - function(callback){ - // async code to get some data - }, - function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - } -], -function(err, results){ - async.series([ - function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - }, - function(callback){ - // once the file is written let's email a link to it... - } - ]); -}); -``` - -For a complicated series of async tasks using the auto function makes adding -new tasks much easier and makes the code more readable. - - ---------------------------------------- - - -### iterator(tasks) - -Creates an iterator function which calls the next function in the array, -returning a continuation to call the next one after that. It's also possible to -'peek' the next iterator by doing iterator.next(). - -This function is used internally by the async module but can be useful when -you want to manually control the flow of functions in series. - -__Arguments__ - -* tasks - An array of functions to run. - -__Example__ - -```js -var iterator = async.iterator([ - function(){ sys.p('one'); }, - function(){ sys.p('two'); }, - function(){ sys.p('three'); } -]); - -node> var iterator2 = iterator(); -'one' -node> var iterator3 = iterator2(); -'two' -node> iterator3(); -'three' -node> var nextfn = iterator2.next(); -node> nextfn(); -'three' -``` - ---------------------------------------- - - -### apply(function, arguments..) - -Creates a continuation function with some arguments already applied, a useful -shorthand when combined with other control flow functions. Any arguments -passed to the returned function are added to the arguments originally passed -to apply. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to automatically apply when the - continuation is called. - -__Example__ - -```js -// using apply - -async.parallel([ - async.apply(fs.writeFile, 'testfile1', 'test1'), - async.apply(fs.writeFile, 'testfile2', 'test2'), -]); - - -// the same process without using apply - -async.parallel([ - function(callback){ - fs.writeFile('testfile1', 'test1', callback); - }, - function(callback){ - fs.writeFile('testfile2', 'test2', callback); - } -]); -``` - -It's possible to pass any number of additional arguments when calling the -continuation: - -```js -node> var fn = async.apply(sys.puts, 'one'); -node> fn('two', 'three'); -one -two -three -``` - ---------------------------------------- - - -### nextTick(callback) - -Calls the callback on a later loop around the event loop. In node.js this just -calls process.nextTick, in the browser it falls back to setImmediate(callback) -if available, otherwise setTimeout(callback, 0), which means other higher priority -events may precede the execution of the callback. - -This is used internally for browser-compatibility purposes. - -__Arguments__ - -* callback - The function to call on a later loop around the event loop. - -__Example__ - -```js -var call_order = []; -async.nextTick(function(){ - call_order.push('two'); - // call_order now equals ['one','two'] -}); -call_order.push('one') -``` - - -### times(n, callback) - -Calls the callback n times and accumulates results in the same manner -you would use with async.map. - -__Arguments__ - -* n - The number of times to run the function. -* callback - The function to call n times. - -__Example__ - -```js -// Pretend this is some complicated async factory -var createUser = function(id, callback) { - callback(null, { - id: 'user' + id - }) -} -// generate 5 users -async.times(5, function(n, next){ - createUser(n, function(err, user) { - next(err, user) - }) -}, function(err, users) { - // we should now have 5 users -}); -``` - - -### timesSeries(n, callback) - -The same as times only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - - -## Utils - - -### memoize(fn, [hasher]) - -Caches the results of an async function. When creating a hash to store function -results against, the callback is omitted from the hash and an optional hash -function can be used. - -The cache of results is exposed as the `memo` property of the function returned -by `memoize`. - -__Arguments__ - -* fn - the function you to proxy and cache results from. -* hasher - an optional function for generating a custom hash for storing - results, it has all the arguments applied to it apart from the callback, and - must be synchronous. - -__Example__ - -```js -var slow_fn = function (name, callback) { - // do something - callback(null, result); -}; -var fn = async.memoize(slow_fn); - -// fn can now be used as if it were slow_fn -fn('some name', function () { - // callback -}); -``` - - -### unmemoize(fn) - -Undoes a memoized function, reverting it to the original, unmemoized -form. Comes handy in tests. - -__Arguments__ - -* fn - the memoized function - - -### log(function, arguments) - -Logs the result of an async function to the console. Only works in node.js or -in browsers that support console.log and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.log is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, 'hello ' + name); - }, 1000); -}; -``` -```js -node> async.log(hello, 'world'); -'hello world' -``` - ---------------------------------------- - - -### dir(function, arguments) - -Logs the result of an async function to the console using console.dir to -display the properties of the resulting object. Only works in node.js or -in browsers that support console.dir and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.dir is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, {hello: name}); - }, 1000); -}; -``` -```js -node> async.dir(hello, 'world'); -{hello: 'world'} -``` - ---------------------------------------- - - -### noConflict() - -Changes the value of async back to its original value, returning a reference to the -async object. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip b/api/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip deleted file mode 100644 index e1c32944465..00000000000 Binary files a/api/node_modules/request/node_modules/form-data/node_modules/async/async.min.js.gzip and /dev/null differ diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/component.json b/api/node_modules/request/node_modules/form-data/node_modules/async/component.json deleted file mode 100644 index bbb011548c0..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/component.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "async", - "repo": "caolan/async", - "description": "Higher-order functions and common patterns for asynchronous code", - "version": "0.1.23", - "keywords": [], - "dependencies": {}, - "development": {}, - "main": "lib/async.js", - "scripts": [ "lib/async.js" ] -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css b/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css deleted file mode 100644 index 274434a4ac8..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.css +++ /dev/null @@ -1,70 +0,0 @@ -/*! - * Styles taken from qunit.css - */ - -h1#nodeunit-header, h1.nodeunit-header { - padding: 15px; - font-size: large; - background-color: #06b; - color: white; - font-family: 'trebuchet ms', verdana, arial; - margin: 0; -} - -h1#nodeunit-header a { - color: white; -} - -h2#nodeunit-banner { - height: 2em; - border-bottom: 1px solid white; - background-color: #eee; - margin: 0; - font-family: 'trebuchet ms', verdana, arial; -} -h2#nodeunit-banner.pass { - background-color: green; -} -h2#nodeunit-banner.fail { - background-color: red; -} - -h2#nodeunit-userAgent, h2.nodeunit-userAgent { - padding: 10px; - background-color: #eee; - color: black; - margin: 0; - font-size: small; - font-weight: normal; - font-family: 'trebuchet ms', verdana, arial; - font-size: 10pt; -} - -div#nodeunit-testrunner-toolbar { - background: #eee; - border-top: 1px solid black; - padding: 10px; - font-family: 'trebuchet ms', verdana, arial; - margin: 0; - font-size: 10pt; -} - -ol#nodeunit-tests { - font-family: 'trebuchet ms', verdana, arial; - font-size: 10pt; -} -ol#nodeunit-tests li strong { - cursor:pointer; -} -ol#nodeunit-tests .pass { - color: green; -} -ol#nodeunit-tests .fail { - color: red; -} - -p#nodeunit-testresult { - margin-left: 1em; - font-size: 10pt; - font-family: 'trebuchet ms', verdana, arial; -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js b/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js deleted file mode 100644 index 59571840cd6..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/deps/nodeunit.js +++ /dev/null @@ -1,1966 +0,0 @@ -/*! - * Nodeunit - * https://github.com/caolan/nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * json2.js - * http://www.JSON.org/json2.js - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -nodeunit = (function(){ -/* - http://www.JSON.org/json2.js - 2010-11-17 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, strict: false, regexp: false */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -if (!this.JSON) { - this.JSON = {}; -} - -(function () { - "use strict"; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) ? - this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? - '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : - '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : - gap ? '[\n' + gap + - partial.join(',\n' + gap) + '\n' + - mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : - gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + - mind + '}' : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ -.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') -.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') -.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); -var assert = this.assert = {}; -var types = {}; -var core = {}; -var nodeunit = {}; -var reporter = {}; -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - var _indexOf = function (arr, item) { - if (arr.indexOf) { - return arr.indexOf(item); - } - for (var i = 0; i < arr.length; i += 1) { - if (arr[i] === item) { - return i; - } - } - return -1; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - async.nextTick = function (fn) { - if (typeof process === 'undefined' || !(process.nextTick)) { - setTimeout(fn, 0); - } - else { - process.nextTick(fn); - } - }; - - async.forEach = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var completed = []; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners, function (fn) { - fn(); - }); - }; - - addListener(function () { - if (completed.length === keys.length) { - callback(null); - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - completed.push(k); - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && _indexOf(completed, x) !== -1); - }, true); - }; - if (ready()) { - task[task.length - 1](taskCallback); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - if (!tasks.length) { - return callback(); - } - callback = callback || function () {}; - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var tasks = []; - var q = { - concurrency: concurrency, - push: function (data, callback) { - tasks.push({data: data, callback: callback}); - async.nextTick(q.process); - }, - process: function () { - if (workers < q.concurrency && tasks.length) { - var task = tasks.splice(0, 1)[0]; - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - q.process(); - }); - } - }, - length: function () { - return tasks.length; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - -}()); -(function(exports){ -/** - * This file is based on the node.js assert module, but with some small - * changes for browser-compatibility - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - */ - - -/** - * Added for browser compatibility - */ - -var _keys = function(obj){ - if(Object.keys) return Object.keys(obj); - var keys = []; - for(var k in obj){ - if(obj.hasOwnProperty(k)) keys.push(k); - } - return keys; -}; - - - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({message: message, actual: actual, expected: expected}) - -assert.AssertionError = function AssertionError (options) { - this.name = "AssertionError"; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// code from util.inherits in node -assert.AssertionError.super_ = Error; - - -// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call -// TODO: test what effect this may have -var ctor = function () { this.constructor = assert.AssertionError; }; -ctor.prototype = Error.prototype; -assert.AssertionError.prototype = new ctor(); - - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name+":", this.message].join(' '); - } else { - return [ this.name+":" - , JSON.stringify(this.expected ) - , this.operator - , JSON.stringify(this.actual) - ].join(" "); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, "==", assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, "==", assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, "!=", assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, "deepEqual", assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == "object", - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical "prototype" property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull (value) { - return value === null || value === undefined; -} - -function isArguments (object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv (a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical "prototype" property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try{ - var ka = _keys(a), - kb = _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; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, "===", assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, "!==", assert.notStrictEqual); - } -}; - -function _throws (shouldThrow, block, err, message) { - var exception = null, - threw = false, - typematters = true; - - message = message || ""; - - //handle optional arguments - if (arguments.length == 3) { - if (typeof(err) == "string") { - message = err; - typematters = false; - } - } else if (arguments.length == 2) { - typematters = false; - } - - try { - block(); - } catch (e) { - threw = true; - exception = e; - } - - if (shouldThrow && !threw) { - fail( "Missing expected exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if (!shouldThrow && threw && typematters && exception instanceof err) { - fail( "Got unwanted exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if ((shouldThrow && threw && typematters && !(exception instanceof err)) || - (!shouldThrow && threw)) { - throw exception; - } -}; - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function (err) { if (err) {throw err;}}; -})(assert); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - - - -/** - * Creates assertion objects representing the result of an assert call. - * Accepts an object or AssertionError as its argument. - * - * @param {object} obj - * @api public - */ - -exports.assertion = function (obj) { - return { - method: obj.method || '', - message: obj.message || (obj.error && obj.error.message) || '', - error: obj.error, - passed: function () { - return !this.error; - }, - failed: function () { - return Boolean(this.error); - } - }; -}; - -/** - * Creates an assertion list object representing a group of assertions. - * Accepts an array of assertion objects. - * - * @param {Array} arr - * @param {Number} duration - * @api public - */ - -exports.assertionList = function (arr, duration) { - var that = arr || []; - that.failures = function () { - var failures = 0; - for (var i=0; i(' + - '' + assertions.failures() + ', ' + - '' + assertions.passes() + ', ' + - assertions.length + - ')'; - test.className = assertions.failures() ? 'fail': 'pass'; - test.appendChild(strong); - - var aList = document.createElement('ol'); - aList.style.display = 'none'; - test.onclick = function () { - var d = aList.style.display; - aList.style.display = (d == 'none') ? 'block': 'none'; - }; - for (var i=0; i' + (a.error.stack || a.error) + ''; - li.className = 'fail'; - } - else { - li.innerHTML = a.message || a.method || 'no message'; - li.className = 'pass'; - } - aList.appendChild(li); - } - test.appendChild(aList); - tests.appendChild(test); - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - - var failures = assertions.failures(); - banner.className = failures ? 'fail': 'pass'; - - result.innerHTML = 'Tests completed in ' + duration + - ' milliseconds.
' + - assertions.passes() + ' assertions of ' + - '' + assertions.length + ' passed, ' + - assertions.failures() + ' failed.'; - } - }); -}; -})(reporter); -nodeunit = core; -nodeunit.assert = assert; -nodeunit.reporter = reporter; -nodeunit.run = reporter.run; -return nodeunit; })(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js b/api/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js deleted file mode 100644 index f89741e36fd..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/dist/async.min.js +++ /dev/null @@ -1 +0,0 @@ -/*global setTimeout: false, console: false */(function(){var a={};var b=this,c=b.async;typeof module!=="undefined"&&module.exports?module.exports=a:b.async=a,a.noConflict=function(){b.async=c;return a};var d=function(a,b){if(a.forEach)return a.forEach(b);for(var c=0;cd?1:0};d(null,e(b.sort(c),function(a){return a.value}))})},a.auto=function(a,b){b=b||function(){};var c=g(a);if(!c.length)return b(null);var e=[];var i=[];var j=function(a){i.unshift(a)};var k=function(a){for(var b=0;b= arr.length) { - callback(null); - } - } - })); - }); - }; - async.forEach = async.each; - - async.eachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(null); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - async.forEachSeries = async.eachSeries; - - async.eachLimit = function (arr, limit, iterator, callback) { - var fn = _eachLimit(limit); - fn.apply(null, [arr, iterator, callback]); - }; - async.forEachLimit = async.eachLimit; - - var _eachLimit = function (limit) { - - return function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); - } - var completed = 0; - var started = 0; - var running = 0; - - (function replenish () { - if (completed >= arr.length) { - return callback(); - } - - while (running < limit && started < arr.length) { - started += 1; - running += 1; - iterator(arr[started - 1], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - running -= 1; - if (completed >= arr.length) { - callback(); - } - else { - replenish(); - } - } - }); - } - })(); - }; - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.each].concat(args)); - }; - }; - var doParallelLimit = function(limit, fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [_eachLimit(limit)].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.eachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - async.mapLimit = function (arr, limit, iterator, callback) { - return _mapLimit(limit)(arr, iterator, callback); - }; - - var _mapLimit = function(limit) { - return doParallelLimit(limit, _asyncMap); - }; - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.eachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var results = {}; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _each(listeners.slice(0), function (fn) { - fn(); - }); - }; - - addListener(function () { - if (_keys(results).length === keys.length) { - callback(null, results); - callback = function () {}; - } - }); - - _each(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - if (err) { - var safeResults = {}; - _each(_keys(results), function(rkey) { - safeResults[rkey] = results[rkey]; - }); - safeResults[k] = args; - callback(err, safeResults); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - results[k] = args; - async.setImmediate(taskComplete); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); - }; - if (ready()) { - task[task.length - 1](taskCallback, results); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor !== Array) { - var err = new Error('First argument to waterfall must be an array of functions'); - return callback(err); - } - if (!tasks.length) { - return callback(); - } - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback.apply(null, arguments); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.setImmediate(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - var _parallel = function(eachfn, tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - eachfn.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - eachfn.each(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.parallel = function (tasks, callback) { - _parallel({ map: async.map, each: async.each }, tasks, callback); - }; - - async.parallelLimit = function(tasks, limit, callback) { - _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.eachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doWhilst = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - if (test()) { - async.doWhilst(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doUntil = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - if (!test()) { - async.doUntil(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.queue = function (worker, concurrency) { - if (concurrency === undefined) { - concurrency = 1; - } - function _insert(q, data, pos, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _each(data, function(task) { - var item = { - data: task, - callback: typeof callback === 'function' ? callback : null - }; - - if (pos) { - q.tasks.unshift(item); - } else { - q.tasks.push(item); - } - - if (q.saturated && q.tasks.length === concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); - } - - var workers = 0; - var q = { - tasks: [], - concurrency: concurrency, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - _insert(q, data, false, callback); - }, - unshift: function (data, callback) { - _insert(q, data, true, callback); - }, - process: function () { - if (workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if (q.empty && q.tasks.length === 0) { - q.empty(); - } - workers += 1; - var next = function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if (q.drain && q.tasks.length + workers === 0) { - q.drain(); - } - q.process(); - }; - var cb = only_once(next); - worker(task.data, cb); - } - }, - length: function () { - return q.tasks.length; - }, - running: function () { - return workers; - } - }; - return q; - }; - - async.cargo = function (worker, payload) { - var working = false, - tasks = []; - - var cargo = { - tasks: tasks, - payload: payload, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _each(data, function(task) { - tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - if (cargo.saturated && tasks.length === payload) { - cargo.saturated(); - } - }); - async.setImmediate(cargo.process); - }, - process: function process() { - if (working) return; - if (tasks.length === 0) { - if(cargo.drain) cargo.drain(); - return; - } - - var ts = typeof payload === 'number' - ? tasks.splice(0, payload) - : tasks.splice(0); - - var ds = _map(ts, function (task) { - return task.data; - }); - - if(cargo.empty) cargo.empty(); - working = true; - worker(ds, function () { - working = false; - - var args = arguments; - _each(ts, function (data) { - if (data.callback) { - data.callback.apply(null, args); - } - }); - - process(); - }); - }, - length: function () { - return tasks.length; - }, - running: function () { - return working; - } - }; - return cargo; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _each(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else if (key in queues) { - queues[key].push(callback); - } - else { - queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); - } - }])); - } - }; - memoized.memo = memo; - memoized.unmemoized = fn; - return memoized; - }; - - async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - }; - - async.times = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.map(counter, iterator, callback); - }; - - async.timesSeries = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.mapSeries(counter, iterator, callback); - }; - - async.compose = function (/* functions... */) { - var fns = Array.prototype.reverse.call(arguments); - return function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - async.reduce(fns, args, function (newargs, fn, cb) { - fn.apply(that, newargs.concat([function () { - var err = arguments[0]; - var nextargs = Array.prototype.slice.call(arguments, 1); - cb(err, nextargs); - }])) - }, - function (err, results) { - callback.apply(that, [err].concat(results)); - }); - }; - }; - - var _applyEach = function (eachfn, fns /*args...*/) { - var go = function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - return eachfn(fns, function (fn, cb) { - fn.apply(that, args.concat([cb])); - }, - callback); - }; - if (arguments.length > 2) { - var args = Array.prototype.slice.call(arguments, 2); - return go.apply(this, args); - } - else { - return go; - } - }; - async.applyEach = doParallel(_applyEach); - async.applyEachSeries = doSeries(_applyEach); - - async.forever = function (fn, callback) { - function next(err) { - if (err) { - if (callback) { - return callback(err); - } - throw err; - } - fn(next); - } - next(); - }; - - // AMD / RequireJS - if (typeof define !== 'undefined' && define.amd) { - define([], function () { - return async; - }); - } - // Node.js - else if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - // included directly via \n\n```\n\n## Documentation\n\n### Collections\n\n* [each](#each)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [doWhilst](#doWhilst)\n* [until](#until)\n* [doUntil](#doUntil)\n* [forever](#forever)\n* [waterfall](#waterfall)\n* [compose](#compose)\n* [applyEach](#applyEach)\n* [queue](#queue)\n* [cargo](#cargo)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n* [times](#times)\n* [timesSeries](#timesSeries)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n
\n\n### each(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the each function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n\n\n### eachSeries(arr, iterator, callback)\n\nThe same as each only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n\n\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as each only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as map only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], 1, fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as reject, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then it's probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback(err, reduction) which accepts an optional error as its first \n argument, and the state of the reduction as the second. If an error is \n passed to the callback, the reduction is stopped and the main callback is \n immediately called with the error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n}, function(err, result){\n // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], fs.exists, function(result){\n // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, sortValue) which must be called once it\n has completed with an error (which can be null) and a value to use as the sort\n criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n}, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n});\n```\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, results) which must be called once it \n has completed with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n }\n],\n// optional callback\nfunction(err, results){\n // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n }\n],\n// optional callback\nfunction(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallelLimit(tasks, limit, [callback])\n\nThe same as parallel only the tasks are executed in parallel with a maximum of \"limit\" \ntasks executing at any time.\n\nNote that the tasks are not executed in batches, so there is no guarantee that \nthe first \"limit\" tasks will complete before any others are started.\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* limit - The maximum number of tasks to run at any time.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback(err) which must be called once it has completed with an \n optional error argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n);\n```\n\n---------------------------------------\n\n\n### doWhilst(fn, test, callback)\n\nThe post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n---------------------------------------\n\n\n### doUntil(fn, test, callback)\n\nLike doWhilst except the test is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n\n### forever(fn, callback)\n\nCalls the asynchronous function 'fn' repeatedly, in series, indefinitely.\nIf an error is passed to fn's callback then 'callback' is called with the\nerror, otherwise it will never be called.\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a \n callback(err, result1, result2, ...) it must call on completion. The first\n argument is an error (which can be null) and any further arguments will be \n passed as arguments in order to the next task.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n], function (err, result) {\n // result now equals 'done' \n});\n```\n\n---------------------------------------\n\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions f(), g() and h() would produce the result of\nf(g(h())), only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n setTimeout(function () {\n callback(null, n + 1);\n }, 10);\n}\n\nfunction mul3(n, callback) {\n setTimeout(function () {\n callback(null, n * 3);\n }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n // result now equals 15\n});\n```\n\n---------------------------------------\n\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling the\ncallback after all functions have completed. If you only provide the first\nargument then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* fns - the asynchronous functions to all call with the same arguments\n* args... - any number of separate arguments to pass to the function\n* callback - the final argument should be the callback, called when all\n functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n buckets,\n async.applyEach([enableSearch, updateSchema]),\n callback\n);\n```\n\n---------------------------------------\n\n\n### applyEachSeries(arr, iterator, callback)\n\nThe same as applyEach only the functions are applied in series.\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task, which must call its callback(err) argument when finished, with an \n optional error as an argument.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* unshift(task, [callback]) - add a new task to the front of the queue.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n```\n\n---------------------------------------\n\n\n### cargo(worker, [payload])\n\nCreates a cargo object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the payload limit). If the\nworker is in progress, the task is queued until it is available. Once\nthe worker has completed some tasks, each callback of those tasks is called.\n\n__Arguments__\n\n* worker(tasks, callback) - An asynchronous function for processing an array of\n queued tasks, which must call its callback(err) argument when finished, with \n an optional error as an argument.\n* payload - An optional integer for determining how many tasks should be\n processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe cargo object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* payload - an integer for determining how many tasks should be\n process per round. This property can be changed after a cargo is created to\n alter the payload on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n for(var i=0; i\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\nNote, all functions are called with a results object as a second argument, \nso it is unsafe to pass functions in the tasks object which cannot handle the\nextra argument. For example, this snippet of code:\n\n```js\nasync.auto({\n readData: async.apply(fs.readFile, 'data.txt', 'utf-8');\n}, callback);\n```\n\nwill have the effect of calling readFile with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to readFile in a function which does not forward the \nresults object:\n\n```js\nasync.auto({\n readData: function(cb, results){\n fs.readFile('data.txt', 'utf-8', cb);\n }\n}, callback);\n```\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The \n function receives two arguments: (1) a callback(err, result) which must be \n called when finished, passing an error (which can be null) and the result of \n the function's execution, and (2) a results object, containing the results of\n the previously executed functions.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. Results will always be passed\n\tbut if an error occurred, no other tasks will be performed, and the results\n\tobject will only contain partial results.\n \n\n__Example__\n\n```js\nasync.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n],\nfunction(err, results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n});\n```\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. It's also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setImmediate(callback)\nif available, otherwise setTimeout(callback, 0), which means other higher priority\nevents may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n\n### times(n, callback)\n\nCalls the callback n times and accumulates results in the same manner\nyou would use with async.map.\n\n__Arguments__\n\n* n - The number of times to run the function.\n* callback - The function to call n times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n callback(null, {\n id: 'user' + id\n })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n createUser(n, function(err, user) {\n next(err, user)\n })\n}, function(err, users) {\n // we should now have 5 users\n});\n```\n\n\n### timesSeries(n, callback)\n\nThe same as times only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n // callback\n});\n```\n\n\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", - "readmeFilename": "README.md", - "_id": "async@0.2.9", - "_from": "async@~0.2.7" -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/test/.swp b/api/node_modules/request/node_modules/form-data/node_modules/async/test/.swp deleted file mode 100644 index ece9b6bb6a4..00000000000 Binary files a/api/node_modules/request/node_modules/form-data/node_modules/async/test/.swp and /dev/null differ diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js b/api/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js deleted file mode 100644 index 8c2cebd5ec6..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/test/test-async.js +++ /dev/null @@ -1,1367 +0,0 @@ -var async = require('../lib/async'); - - -exports['auto'] = function(test){ - var callOrder = []; - var testdata = [{test: 'test'}]; - async.auto({ - task1: ['task2', function(callback){ - setTimeout(function(){ - callOrder.push('task1'); - callback(); - }, 25); - }], - task2: function(callback){ - setTimeout(function(){ - callOrder.push('task2'); - callback(); - }, 50); - }, - task3: ['task2', function(callback){ - callOrder.push('task3'); - callback(); - }], - task4: ['task1', 'task2', function(callback){ - callOrder.push('task4'); - callback(); - }] - }, - function(err){ - test.same(callOrder, ['task2','task3','task1','task4']); - test.done(); - }); -}; - -exports['auto empty object'] = function(test){ - async.auto({}, function(err){ - test.done(); - }); -}; - -exports['auto error'] = function(test){ - test.expect(1); - async.auto({ - task1: function(callback){ - callback('testerror'); - }, - task2: ['task1', function(callback){ - test.ok(false, 'task2 should not be called'); - callback(); - }], - task3: function(callback){ - callback('testerror2'); - } - }, - function(err){ - test.equals(err, 'testerror'); - }); - setTimeout(test.done, 100); -}; - -exports['auto no callback'] = function(test){ - async.auto({ - task1: function(callback){callback();}, - task2: ['task1', function(callback){callback(); test.done();}] - }); -}; - -exports['waterfall'] = function(test){ - test.expect(6); - var call_order = []; - async.waterfall([ - function(callback){ - call_order.push('fn1'); - setTimeout(function(){callback(null, 'one', 'two');}, 0); - }, - function(arg1, arg2, callback){ - call_order.push('fn2'); - test.equals(arg1, 'one'); - test.equals(arg2, 'two'); - setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25); - }, - function(arg1, arg2, arg3, callback){ - call_order.push('fn3'); - test.equals(arg1, 'one'); - test.equals(arg2, 'two'); - test.equals(arg3, 'three'); - callback(null, 'four'); - }, - function(arg4, callback){ - call_order.push('fn4'); - test.same(call_order, ['fn1','fn2','fn3','fn4']); - callback(null, 'test'); - } - ], function(err){ - test.done(); - }); -}; - -exports['waterfall empty array'] = function(test){ - async.waterfall([], function(err){ - test.done(); - }); -}; - -exports['waterfall no callback'] = function(test){ - async.waterfall([ - function(callback){callback();}, - function(callback){callback(); test.done();} - ]); -}; - -exports['waterfall async'] = function(test){ - var call_order = []; - async.waterfall([ - function(callback){ - call_order.push(1); - callback(); - call_order.push(2); - }, - function(callback){ - call_order.push(3); - callback(); - }, - function(){ - test.same(call_order, [1,2,3]); - test.done(); - } - ]); -}; - -exports['waterfall error'] = function(test){ - test.expect(1); - async.waterfall([ - function(callback){ - callback('error'); - }, - function(callback){ - test.ok(false, 'next function should not be called'); - callback(); - } - ], function(err){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['waterfall multiple callback calls'] = function(test){ - var call_order = []; - var arr = [ - function(callback){ - call_order.push(1); - // call the callback twice. this should call function 2 twice - callback(null, 'one', 'two'); - callback(null, 'one', 'two'); - }, - function(arg1, arg2, callback){ - call_order.push(2); - callback(null, arg1, arg2, 'three'); - }, - function(arg1, arg2, arg3, callback){ - call_order.push(3); - callback(null, 'four'); - }, - function(arg4){ - call_order.push(4); - arr[3] = function(){ - call_order.push(4); - test.same(call_order, [1,2,2,3,3,4,4]); - test.done(); - }; - } - ]; - async.waterfall(arr); -}; - - -exports['parallel'] = function(test){ - var call_order = []; - async.parallel([ - function(callback){ - setTimeout(function(){ - call_order.push(1); - callback(null, 1); - }, 25); - }, - function(callback){ - setTimeout(function(){ - call_order.push(2); - callback(null, 2); - }, 50); - }, - function(callback){ - setTimeout(function(){ - call_order.push(3); - callback(null, 3,3); - }, 15); - } - ], - function(err, results){ - test.equals(err, null); - test.same(call_order, [3,1,2]); - test.same(results, [1,2,[3,3]]); - test.done(); - }); -}; - -exports['parallel empty array'] = function(test){ - async.parallel([], function(err, results){ - test.equals(err, null); - test.same(results, []); - test.done(); - }); -}; - -exports['parallel error'] = function(test){ - async.parallel([ - function(callback){ - callback('error', 1); - }, - function(callback){ - callback('error2', 2); - } - ], - function(err, results){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 100); -}; - -exports['parallel no callback'] = function(test){ - async.parallel([ - function(callback){callback();}, - function(callback){callback(); test.done();}, - ]); -}; - -exports['parallel object'] = function(test){ - var call_order = []; - async.parallel({ - one: function(callback){ - setTimeout(function(){ - call_order.push(1); - callback(null, 1); - }, 25); - }, - two: function(callback){ - setTimeout(function(){ - call_order.push(2); - callback(null, 2); - }, 50); - }, - three: function(callback){ - setTimeout(function(){ - call_order.push(3); - callback(null, 3,3); - }, 15); - } - }, - function(err, results){ - test.equals(err, null); - test.same(call_order, [3,1,2]); - test.same(results, { - one: 1, - two: 2, - three: [3,3] - }); - test.done(); - }); -}; - -exports['series'] = function(test){ - var call_order = []; - async.series([ - function(callback){ - setTimeout(function(){ - call_order.push(1); - callback(null, 1); - }, 25); - }, - function(callback){ - setTimeout(function(){ - call_order.push(2); - callback(null, 2); - }, 50); - }, - function(callback){ - setTimeout(function(){ - call_order.push(3); - callback(null, 3,3); - }, 15); - } - ], - function(err, results){ - test.equals(err, null); - test.same(results, [1,2,[3,3]]); - test.same(call_order, [1,2,3]); - test.done(); - }); -}; - -exports['series empty array'] = function(test){ - async.series([], function(err, results){ - test.equals(err, null); - test.same(results, []); - test.done(); - }); -}; - -exports['series error'] = function(test){ - test.expect(1); - async.series([ - function(callback){ - callback('error', 1); - }, - function(callback){ - test.ok(false, 'should not be called'); - callback('error2', 2); - } - ], - function(err, results){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 100); -}; - -exports['series no callback'] = function(test){ - async.series([ - function(callback){callback();}, - function(callback){callback(); test.done();}, - ]); -}; - -exports['series object'] = function(test){ - var call_order = []; - async.series({ - one: function(callback){ - setTimeout(function(){ - call_order.push(1); - callback(null, 1); - }, 25); - }, - two: function(callback){ - setTimeout(function(){ - call_order.push(2); - callback(null, 2); - }, 50); - }, - three: function(callback){ - setTimeout(function(){ - call_order.push(3); - callback(null, 3,3); - }, 15); - } - }, - function(err, results){ - test.equals(err, null); - test.same(results, { - one: 1, - two: 2, - three: [3,3] - }); - test.same(call_order, [1,2,3]); - test.done(); - }); -}; - -exports['iterator'] = function(test){ - var call_order = []; - var iterator = async.iterator([ - function(){call_order.push(1);}, - function(arg1){ - test.equals(arg1, 'arg1'); - call_order.push(2); - }, - function(arg1, arg2){ - test.equals(arg1, 'arg1'); - test.equals(arg2, 'arg2'); - call_order.push(3); - } - ]); - iterator(); - test.same(call_order, [1]); - var iterator2 = iterator(); - test.same(call_order, [1,1]); - var iterator3 = iterator2('arg1'); - test.same(call_order, [1,1,2]); - var iterator4 = iterator3('arg1', 'arg2'); - test.same(call_order, [1,1,2,3]); - test.equals(iterator4, undefined); - test.done(); -}; - -exports['iterator empty array'] = function(test){ - var iterator = async.iterator([]); - test.equals(iterator(), undefined); - test.equals(iterator.next(), undefined); - test.done(); -}; - -exports['iterator.next'] = function(test){ - var call_order = []; - var iterator = async.iterator([ - function(){call_order.push(1);}, - function(arg1){ - test.equals(arg1, 'arg1'); - call_order.push(2); - }, - function(arg1, arg2){ - test.equals(arg1, 'arg1'); - test.equals(arg2, 'arg2'); - call_order.push(3); - } - ]); - var fn = iterator.next(); - var iterator2 = fn('arg1'); - test.same(call_order, [2]); - iterator2('arg1','arg2'); - test.same(call_order, [2,3]); - test.equals(iterator2.next(), undefined); - test.done(); -}; - -exports['forEach'] = function(test){ - var args = []; - async.forEach([1,3,2], function(x, callback){ - setTimeout(function(){ - args.push(x); - callback(); - }, x*25); - }, function(err){ - test.same(args, [1,2,3]); - test.done(); - }); -}; - -exports['forEach empty array'] = function(test){ - test.expect(1); - async.forEach([], function(x, callback){ - test.ok(false, 'iterator should not be called'); - callback(); - }, function(err){ - test.ok(true, 'should call callback'); - }); - setTimeout(test.done, 25); -}; - -exports['forEach error'] = function(test){ - test.expect(1); - async.forEach([1,2,3], function(x, callback){ - callback('error'); - }, function(err){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['forEachSeries'] = function(test){ - var args = []; - async.forEachSeries([1,3,2], function(x, callback){ - setTimeout(function(){ - args.push(x); - callback(); - }, x*25); - }, function(err){ - test.same(args, [1,3,2]); - test.done(); - }); -}; - -exports['forEachSeries empty array'] = function(test){ - test.expect(1); - async.forEachSeries([], function(x, callback){ - test.ok(false, 'iterator should not be called'); - callback(); - }, function(err){ - test.ok(true, 'should call callback'); - }); - setTimeout(test.done, 25); -}; - -exports['forEachSeries error'] = function(test){ - test.expect(2); - var call_order = []; - async.forEachSeries([1,2,3], function(x, callback){ - call_order.push(x); - callback('error'); - }, function(err){ - test.same(call_order, [1]); - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['map'] = function(test){ - var call_order = []; - async.map([1,3,2], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(null, x*2); - }, x*25); - }, function(err, results){ - test.same(call_order, [1,2,3]); - test.same(results, [2,6,4]); - test.done(); - }); -}; - -exports['map original untouched'] = function(test){ - var a = [1,2,3]; - async.map(a, function(x, callback){ - callback(null, x*2); - }, function(err, results){ - test.same(results, [2,4,6]); - test.same(a, [1,2,3]); - test.done(); - }); -}; - -exports['map error'] = function(test){ - test.expect(1); - async.map([1,2,3], function(x, callback){ - callback('error'); - }, function(err, results){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['mapSeries'] = function(test){ - var call_order = []; - async.mapSeries([1,3,2], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(null, x*2); - }, x*25); - }, function(err, results){ - test.same(call_order, [1,3,2]); - test.same(results, [2,6,4]); - test.done(); - }); -}; - -exports['mapSeries error'] = function(test){ - test.expect(1); - async.mapSeries([1,2,3], function(x, callback){ - callback('error'); - }, function(err, results){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['reduce'] = function(test){ - var call_order = []; - async.reduce([1,2,3], 0, function(a, x, callback){ - call_order.push(x); - callback(null, a + x); - }, function(err, result){ - test.equals(result, 6); - test.same(call_order, [1,2,3]); - test.done(); - }); -}; - -exports['reduce async with non-reference memo'] = function(test){ - async.reduce([1,3,2], 0, function(a, x, callback){ - setTimeout(function(){callback(null, a + x)}, Math.random()*100); - }, function(err, result){ - test.equals(result, 6); - test.done(); - }); -}; - -exports['reduce error'] = function(test){ - test.expect(1); - async.reduce([1,2,3], 0, function(a, x, callback){ - callback('error'); - }, function(err, result){ - test.equals(err, 'error'); - }); - setTimeout(test.done, 50); -}; - -exports['inject alias'] = function(test){ - test.equals(async.inject, async.reduce); - test.done(); -}; - -exports['foldl alias'] = function(test){ - test.equals(async.foldl, async.reduce); - test.done(); -}; - -exports['reduceRight'] = function(test){ - var call_order = []; - var a = [1,2,3]; - async.reduceRight(a, 0, function(a, x, callback){ - call_order.push(x); - callback(null, a + x); - }, function(err, result){ - test.equals(result, 6); - test.same(call_order, [3,2,1]); - test.same(a, [1,2,3]); - test.done(); - }); -}; - -exports['foldr alias'] = function(test){ - test.equals(async.foldr, async.reduceRight); - test.done(); -}; - -exports['filter'] = function(test){ - async.filter([3,1,2], function(x, callback){ - setTimeout(function(){callback(x % 2);}, x*25); - }, function(results){ - test.same(results, [3,1]); - test.done(); - }); -}; - -exports['filter original untouched'] = function(test){ - var a = [3,1,2]; - async.filter(a, function(x, callback){ - callback(x % 2); - }, function(results){ - test.same(results, [3,1]); - test.same(a, [3,1,2]); - test.done(); - }); -}; - -exports['filterSeries'] = function(test){ - async.filterSeries([3,1,2], function(x, callback){ - setTimeout(function(){callback(x % 2);}, x*25); - }, function(results){ - test.same(results, [3,1]); - test.done(); - }); -}; - -exports['select alias'] = function(test){ - test.equals(async.select, async.filter); - test.done(); -}; - -exports['selectSeries alias'] = function(test){ - test.equals(async.selectSeries, async.filterSeries); - test.done(); -}; - -exports['reject'] = function(test){ - async.reject([3,1,2], function(x, callback){ - setTimeout(function(){callback(x % 2);}, x*25); - }, function(results){ - test.same(results, [2]); - test.done(); - }); -}; - -exports['reject original untouched'] = function(test){ - var a = [3,1,2]; - async.reject(a, function(x, callback){ - callback(x % 2); - }, function(results){ - test.same(results, [2]); - test.same(a, [3,1,2]); - test.done(); - }); -}; - -exports['rejectSeries'] = function(test){ - async.rejectSeries([3,1,2], function(x, callback){ - setTimeout(function(){callback(x % 2);}, x*25); - }, function(results){ - test.same(results, [2]); - test.done(); - }); -}; - -exports['some true'] = function(test){ - async.some([3,1,2], function(x, callback){ - setTimeout(function(){callback(x === 1);}, 0); - }, function(result){ - test.equals(result, true); - test.done(); - }); -}; - -exports['some false'] = function(test){ - async.some([3,1,2], function(x, callback){ - setTimeout(function(){callback(x === 10);}, 0); - }, function(result){ - test.equals(result, false); - test.done(); - }); -}; - -exports['some early return'] = function(test){ - var call_order = []; - async.some([1,2,3], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(x === 1); - }, x*25); - }, function(result){ - call_order.push('callback'); - }); - setTimeout(function(){ - test.same(call_order, [1,'callback',2,3]); - test.done(); - }, 100); -}; - -exports['any alias'] = function(test){ - test.equals(async.any, async.some); - test.done(); -}; - -exports['every true'] = function(test){ - async.every([1,2,3], function(x, callback){ - setTimeout(function(){callback(true);}, 0); - }, function(result){ - test.equals(result, true); - test.done(); - }); -}; - -exports['every false'] = function(test){ - async.every([1,2,3], function(x, callback){ - setTimeout(function(){callback(x % 2);}, 0); - }, function(result){ - test.equals(result, false); - test.done(); - }); -}; - -exports['every early return'] = function(test){ - var call_order = []; - async.every([1,2,3], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(x === 1); - }, x*25); - }, function(result){ - call_order.push('callback'); - }); - setTimeout(function(){ - test.same(call_order, [1,2,'callback',3]); - test.done(); - }, 100); -}; - -exports['all alias'] = function(test){ - test.equals(async.all, async.every); - test.done(); -}; - -exports['detect'] = function(test){ - var call_order = []; - async.detect([3,2,1], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(x == 2); - }, x*25); - }, function(result){ - call_order.push('callback'); - test.equals(result, 2); - }); - setTimeout(function(){ - test.same(call_order, [1,2,'callback',3]); - test.done(); - }, 100); -}; - -exports['detectSeries'] = function(test){ - var call_order = []; - async.detectSeries([3,2,1], function(x, callback){ - setTimeout(function(){ - call_order.push(x); - callback(x == 2); - }, x*25); - }, function(result){ - call_order.push('callback'); - test.equals(result, 2); - }); - setTimeout(function(){ - test.same(call_order, [3,2,'callback']); - test.done(); - }, 200); -}; - -exports['sortBy'] = function(test){ - async.sortBy([{a:1},{a:15},{a:6}], function(x, callback){ - setTimeout(function(){callback(null, x.a);}, 0); - }, function(err, result){ - test.same(result, [{a:1},{a:6},{a:15}]); - test.done(); - }); -}; - -exports['apply'] = function(test){ - test.expect(6); - var fn = function(){ - test.same(Array.prototype.slice.call(arguments), [1,2,3,4]) - }; - async.apply(fn, 1, 2, 3, 4)(); - async.apply(fn, 1, 2, 3)(4); - async.apply(fn, 1, 2)(3, 4); - async.apply(fn, 1)(2, 3, 4); - async.apply(fn)(1, 2, 3, 4); - test.equals( - async.apply(function(name){return 'hello ' + name}, 'world')(), - 'hello world' - ); - test.done(); -}; - - -// generates tests for console functions such as async.log -var console_fn_tests = function(name){ - - if (typeof console !== 'undefined') { - exports[name] = function(test){ - test.expect(5); - var fn = function(arg1, callback){ - test.equals(arg1, 'one'); - setTimeout(function(){callback(null, 'test');}, 0); - }; - var fn_err = function(arg1, callback){ - test.equals(arg1, 'one'); - setTimeout(function(){callback('error');}, 0); - }; - var _console_fn = console[name]; - var _error = console.error; - console[name] = function(val){ - test.equals(val, 'test'); - test.equals(arguments.length, 1); - console.error = function(val){ - test.equals(val, 'error'); - console[name] = _console_fn; - console.error = _error; - test.done(); - }; - async[name](fn_err, 'one'); - }; - async[name](fn, 'one'); - }; - - exports[name + ' with multiple result params'] = function(test){ - var fn = function(callback){callback(null,'one','two','three');}; - var _console_fn = console[name]; - var called_with = []; - console[name] = function(x){ - called_with.push(x); - }; - async[name](fn); - test.same(called_with, ['one','two','three']); - console[name] = _console_fn; - test.done(); - }; - } - - // browser-only test - exports[name + ' without console.' + name] = function(test){ - if (typeof window !== 'undefined') { - var _console = window.console; - window.console = undefined; - var fn = function(callback){callback(null, 'val');}; - var fn_err = function(callback){callback('error');}; - async[name](fn); - async[name](fn_err); - window.console = _console; - } - test.done(); - }; - -}; - -console_fn_tests('log'); -console_fn_tests('dir'); -/*console_fn_tests('info'); -console_fn_tests('warn'); -console_fn_tests('error');*/ - -exports['nextTick'] = function(test){ - var call_order = []; - async.nextTick(function(){call_order.push('two');}); - call_order.push('one'); - setTimeout(function(){ - test.same(call_order, ['one','two']); - test.done(); - }, 50); -}; - -exports['nextTick in the browser'] = function(test){ - if (typeof process !== 'undefined') { - // skip this test in node - return test.done(); - } - test.expect(1); - - var call_order = []; - async.nextTick(function(){call_order.push('two');}); - - call_order.push('one'); - setTimeout(function(){ - if (typeof process !== 'undefined') { - process.nextTick = _nextTick; - } - test.same(call_order, ['one','two']); - }, 50); - setTimeout(test.done, 100); -}; - -exports['noConflict - node only'] = function(test){ - if (typeof process !== 'undefined') { - // node only test - test.expect(3); - var fs = require('fs'); - var filename = __dirname + '/../lib/async.js'; - fs.readFile(filename, function(err, content){ - if(err) return test.done(); - var Script = process.binding('evals').Script; - - var s = new Script(content, filename); - var s2 = new Script( - content + 'this.async2 = this.async.noConflict();', - filename - ); - - var sandbox1 = {async: 'oldvalue'}; - s.runInNewContext(sandbox1); - test.ok(sandbox1.async); - - var sandbox2 = {async: 'oldvalue'}; - s2.runInNewContext(sandbox2); - test.equals(sandbox2.async, 'oldvalue'); - test.ok(sandbox2.async2); - - test.done(); - }); - } - else test.done(); -}; - -exports['concat'] = function(test){ - var call_order = []; - var iterator = function (x, cb) { - setTimeout(function(){ - call_order.push(x); - var r = []; - while (x > 0) { - r.push(x); - x--; - } - cb(null, r); - }, x*25); - }; - async.concat([1,3,2], iterator, function(err, results){ - test.same(results, [1,2,1,3,2,1]); - test.same(call_order, [1,2,3]); - test.ok(!err); - test.done(); - }); -}; - -exports['concat error'] = function(test){ - var iterator = function (x, cb) { - cb(new Error('test error')); - }; - async.concat([1,2,3], iterator, function(err, results){ - test.ok(err); - test.done(); - }); -}; - -exports['concatSeries'] = function(test){ - var call_order = []; - var iterator = function (x, cb) { - setTimeout(function(){ - call_order.push(x); - var r = []; - while (x > 0) { - r.push(x); - x--; - } - cb(null, r); - }, x*25); - }; - async.concatSeries([1,3,2], iterator, function(err, results){ - test.same(results, [1,3,2,1,2,1]); - test.same(call_order, [1,3,2]); - test.ok(!err); - test.done(); - }); -}; - -exports['until'] = function (test) { - var call_order = []; - - var count = 0; - async.until( - function () { - call_order.push(['test', count]); - return (count == 5); - }, - function (cb) { - call_order.push(['iterator', count]); - count++; - cb(); - }, - function (err) { - test.same(call_order, [ - ['test', 0], - ['iterator', 0], ['test', 1], - ['iterator', 1], ['test', 2], - ['iterator', 2], ['test', 3], - ['iterator', 3], ['test', 4], - ['iterator', 4], ['test', 5], - ]); - test.equals(count, 5); - test.done(); - } - ); -}; - -exports['whilst'] = function (test) { - var call_order = []; - - var count = 0; - async.whilst( - function () { - call_order.push(['test', count]); - return (count < 5); - }, - function (cb) { - call_order.push(['iterator', count]); - count++; - cb(); - }, - function (err) { - test.same(call_order, [ - ['test', 0], - ['iterator', 0], ['test', 1], - ['iterator', 1], ['test', 2], - ['iterator', 2], ['test', 3], - ['iterator', 3], ['test', 4], - ['iterator', 4], ['test', 5], - ]); - test.equals(count, 5); - test.done(); - } - ); -}; - -exports['queue'] = function (test) { - var call_order = [], - delays = [40,20,60,20]; - - // worker1: --1-4 - // worker2: -2---3 - // order of completion: 2,1,4,3 - - var q = async.queue(function (task, callback) { - setTimeout(function () { - call_order.push('process ' + task); - callback('error', 'arg'); - }, delays.splice(0,1)[0]); - }, 2); - - q.push(1, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 1); - call_order.push('callback ' + 1); - }); - q.push(2, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 2); - call_order.push('callback ' + 2); - }); - q.push(3, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 0); - call_order.push('callback ' + 3); - }); - q.push(4, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 0); - call_order.push('callback ' + 4); - }); - test.equal(q.length(), 4); - test.equal(q.concurrency, 2); - - setTimeout(function () { - test.same(call_order, [ - 'process 2', 'callback 2', - 'process 1', 'callback 1', - 'process 4', 'callback 4', - 'process 3', 'callback 3' - ]); - test.equal(q.concurrency, 2); - test.equal(q.length(), 0); - test.done(); - }, 200); -}; - -exports['queue changing concurrency'] = function (test) { - var call_order = [], - delays = [40,20,60,20]; - - // worker1: --1-2---3-4 - // order of completion: 1,2,3,4 - - var q = async.queue(function (task, callback) { - setTimeout(function () { - call_order.push('process ' + task); - callback('error', 'arg'); - }, delays.splice(0,1)[0]); - }, 2); - - q.push(1, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 3); - call_order.push('callback ' + 1); - }); - q.push(2, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 2); - call_order.push('callback ' + 2); - }); - q.push(3, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 1); - call_order.push('callback ' + 3); - }); - q.push(4, function (err, arg) { - test.equal(err, 'error'); - test.equal(arg, 'arg'); - test.equal(q.length(), 0); - call_order.push('callback ' + 4); - }); - test.equal(q.length(), 4); - test.equal(q.concurrency, 2); - q.concurrency = 1; - - setTimeout(function () { - test.same(call_order, [ - 'process 1', 'callback 1', - 'process 2', 'callback 2', - 'process 3', 'callback 3', - 'process 4', 'callback 4' - ]); - test.equal(q.concurrency, 1); - test.equal(q.length(), 0); - test.done(); - }, 250); -}; - -exports['queue push without callback'] = function (test) { - var call_order = [], - delays = [40,20,60,20]; - - // worker1: --1-4 - // worker2: -2---3 - // order of completion: 2,1,4,3 - - var q = async.queue(function (task, callback) { - setTimeout(function () { - call_order.push('process ' + task); - callback('error', 'arg'); - }, delays.splice(0,1)[0]); - }, 2); - - q.push(1); - q.push(2); - q.push(3); - q.push(4); - - setTimeout(function () { - test.same(call_order, [ - 'process 2', - 'process 1', - 'process 4', - 'process 3' - ]); - test.done(); - }, 200); -}; - -exports['memoize'] = function (test) { - test.expect(4); - var call_order = []; - - var fn = function (arg1, arg2, callback) { - call_order.push(['fn', arg1, arg2]); - callback(null, arg1 + arg2); - }; - - var fn2 = async.memoize(fn); - fn2(1, 2, function (err, result) { - test.equal(result, 3); - }); - fn2(1, 2, function (err, result) { - test.equal(result, 3); - }); - fn2(2, 2, function (err, result) { - test.equal(result, 4); - }); - - test.same(call_order, [['fn',1,2], ['fn',2,2]]); - test.done(); -}; - -exports['memoize error'] = function (test) { - test.expect(1); - var testerr = new Error('test'); - var fn = function (arg1, arg2, callback) { - callback(testerr, arg1 + arg2); - }; - async.memoize(fn)(1, 2, function (err, result) { - test.equal(err, testerr); - }); - test.done(); -}; - -exports['memoize custom hash function'] = function (test) { - test.expect(2); - var testerr = new Error('test'); - - var fn = function (arg1, arg2, callback) { - callback(testerr, arg1 + arg2); - }; - var fn2 = async.memoize(fn, function () { - return 'custom hash'; - }); - fn2(1, 2, function (err, result) { - test.equal(result, 3); - }); - fn2(2, 2, function (err, result) { - test.equal(result, 3); - }); - test.done(); -}; - -// Issue 10 on github: https://github.com/caolan/async/issues#issue/10 -exports['falsy return values in series'] = function (test) { - function taskFalse(callback) { - async.nextTick(function() { - callback(null, false); - }); - }; - function taskUndefined(callback) { - async.nextTick(function() { - callback(null, undefined); - }); - }; - function taskEmpty(callback) { - async.nextTick(function() { - callback(null); - }); - }; - function taskNull(callback) { - async.nextTick(function() { - callback(null, null); - }); - }; - async.series( - [taskFalse, taskUndefined, taskEmpty, taskNull], - function(err, results) { - test.same(results, [false, undefined, undefined, null]); - test.strictEqual(results[0], false); - test.strictEqual(results[1], undefined); - test.strictEqual(results[2], undefined); - test.strictEqual(results[3], null); - test.done(); - } - ); -}; - -// Issue 10 on github: https://github.com/caolan/async/issues#issue/10 -exports['falsy return values in parallel'] = function (test) { - function taskFalse(callback) { - async.nextTick(function() { - callback(null, false); - }); - }; - function taskUndefined(callback) { - async.nextTick(function() { - callback(null, undefined); - }); - }; - function taskEmpty(callback) { - async.nextTick(function() { - callback(null); - }); - }; - function taskNull(callback) { - async.nextTick(function() { - callback(null, null); - }); - }; - async.parallel( - [taskFalse, taskUndefined, taskEmpty, taskNull], - function(err, results) { - test.same(results, [false, undefined, undefined, null]); - test.strictEqual(results[0], false); - test.strictEqual(results[1], undefined); - test.strictEqual(results[2], undefined); - test.strictEqual(results[3], null); - test.done(); - } - ); -}; - -exports['queue events'] = function(test) { - var calls = []; - var q = async.queue(function(task, cb) { - // nop - calls.push('process ' + task); - cb(); - }, 3); - - q.saturated = function() { - test.ok(q.length() == 3, 'queue should be saturated now'); - calls.push('saturated'); - }; - q.empty = function() { - test.ok(q.length() == 0, 'queue should be empty now'); - calls.push('empty'); - }; - q.drain = function() { - test.ok( - q.length() == 0 && q.running() == 0, - 'queue should be empty now and no more workers should be running' - ); - calls.push('drain'); - test.same(calls, [ - 'saturated', - 'process foo', - 'foo cb', - 'process bar', - 'bar cb', - 'process zoo', - 'zoo cb', - 'process poo', - 'poo cb', - 'empty', - 'process moo', - 'moo cb', - 'drain', - ]); - test.done(); - }; - q.push('foo', function () {calls.push('foo cb');}); - q.push('bar', function () {calls.push('bar cb');}); - q.push('zoo', function () {calls.push('zoo cb');}); - q.push('poo', function () {calls.push('poo cb');}); - q.push('moo', function () {calls.push('moo cb');}); -}; diff --git a/api/node_modules/request/node_modules/form-data/node_modules/async/test/test.html b/api/node_modules/request/node_modules/form-data/node_modules/async/test/test.html deleted file mode 100644 index 2450e2dcff1..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/async/test/test.html +++ /dev/null @@ -1,24 +0,0 @@ - - - Async.js Test Suite - - - - - - - - -

Async.js Test Suite

- - - diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore deleted file mode 100644 index aba34f0127c..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -*.un~ -/node_modules -/test/tmp diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/License b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/License deleted file mode 100644 index 4804b7ab411..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Debuggable Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md deleted file mode 100644 index 1a9999eb0e1..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md +++ /dev/null @@ -1,132 +0,0 @@ -# combined-stream - -A stream that emits multiple other streams one after another. - -## Installation - -``` bash -npm install combined-stream -``` - -## Usage - -Here is a simple example that shows how you can use combined-stream to combine -two files into one: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create(); -combinedStream.append(fs.createReadStream('file1.txt')); -combinedStream.append(fs.createReadStream('file2.txt')); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -While the example above works great, it will pause all source streams until -they are needed. If you don't want that to happen, you can set `pauseStreams` -to `false`: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create({pauseStreams: false}); -combinedStream.append(fs.createReadStream('file1.txt')); -combinedStream.append(fs.createReadStream('file2.txt')); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -However, what if you don't have all the source streams yet, or you don't want -to allocate the resources (file descriptors, memory, etc.) for them right away? -Well, in that case you can simply provide a callback that supplies the stream -by calling a `next()` function: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create(); -combinedStream.append(function(next) { - next(fs.createReadStream('file1.txt')); -}); -combinedStream.append(function(next) { - next(fs.createReadStream('file2.txt')); -}); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -## API - -### CombinedStream.create([options]) - -Returns a new combined stream object. Available options are: - -* `maxDataSize` -* `pauseStreams` - -The effect of those options is described below. - -### combinedStream.pauseStreams = true - -Whether to apply back pressure to the underlaying streams. If set to `false`, -the underlaying streams will never be paused. If set to `true`, the -underlaying streams will be paused right after being appended, as well as when -`delayedStream.pipe()` wants to throttle. - -### combinedStream.maxDataSize = 2 * 1024 * 1024 - -The maximum amount of bytes (or characters) to buffer for all source streams. -If this value is exceeded, `combinedStream` emits an `'error'` event. - -### combinedStream.dataSize = 0 - -The amount of bytes (or characters) currently buffered by `combinedStream`. - -### combinedStream.append(stream) - -Appends the given `stream` to the combinedStream object. If `pauseStreams` is -set to `true, this stream will also be paused right away. - -`streams` can also be a function that takes one parameter called `next`. `next` -is a function that must be invoked in order to provide the `next` stream, see -example above. - -Regardless of how the `stream` is appended, combined-stream always attaches an -`'error'` listener to it, so you don't have to do that manually. - -Special case: `stream` can also be a String or Buffer. - -### combinedStream.write(data) - -You should not call this, `combinedStream` takes care of piping the appended -streams into itself for you. - -### combinedStream.resume() - -Causes `combinedStream` to start drain the streams it manages. The function is -idempotent, and also emits a `'resume'` event each time which usually goes to -the stream that is currently being drained. - -### combinedStream.pause(); - -If `combinedStream.pauseStreams` is set to `false`, this does nothing. -Otherwise a `'pause'` event is emitted, this goes to the stream that is -currently being drained, so you can use it to apply back pressure. - -### combinedStream.end(); - -Sets `combinedStream.writable` to false, emits an `'end'` event, and removes -all streams from the queue. - -### combinedStream.destroy(); - -Same as `combinedStream.end()`, except it emits a `'close'` event instead of -`'end'`. - -## License - -combined-stream is licensed under the MIT license. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js deleted file mode 100644 index 32849fd109e..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js +++ /dev/null @@ -1,185 +0,0 @@ -var util = require('util'); -var Stream = require('stream').Stream; -var DelayedStream = require('delayed-stream'); - -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; - - this._released = false; - this._streams = []; - this._currentStream = null; -} -util.inherits(CombinedStream, Stream); - -CombinedStream.create = function(options) { - var combinedStream = new this(); - - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; - } - - return combinedStream; -}; - -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; - -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - stream.on('data', this._checkDataSize.bind(this)); - - stream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - } - - this._handleErrors(stream); - - if (this.pauseStreams) { - stream.pause(); - } - } - - this._streams.push(stream); - return this; -}; - -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); -}; - -CombinedStream.prototype._getNext = function() { - this._currentStream = null; - var stream = this._streams.shift(); - - - if (typeof stream == 'undefined') { - this.end(); - return; - } - - if (typeof stream !== 'function') { - this._pipeNext(stream); - return; - } - - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); - } - - this._pipeNext(stream); - }.bind(this)); -}; - -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; - - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)) - stream.pipe(this, {end: false}); - return; - } - - var value = stream; - this.write(value); - this._getNext(); -}; - -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; - -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; - -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; - } - - this.emit('pause'); -}; - -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); - } - - this.emit('resume'); -}; - -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; - -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; - -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; -}; - -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; - } - - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this._emitError(new Error(message)); -}; - -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; - - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } - - self.dataSize += stream.dataSize; - }); - - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } -}; - -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore deleted file mode 100644 index 2fedb26cce9..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.un~ -/node_modules/* diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License deleted file mode 100644 index 4804b7ab411..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Debuggable Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md deleted file mode 100644 index 5cb5b35e5bb..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md +++ /dev/null @@ -1,154 +0,0 @@ -# delayed-stream - -Buffers events from a stream until you are ready to handle them. - -## Installation - -``` bash -npm install delayed-stream -``` - -## Usage - -The following example shows how to write a http echo server that delays its -response by 1000 ms. - -``` javascript -var DelayedStream = require('delayed-stream'); -var http = require('http'); - -http.createServer(function(req, res) { - var delayed = DelayedStream.create(req); - - setTimeout(function() { - res.writeHead(200); - delayed.pipe(res); - }, 1000); -}); -``` - -If you are not using `Stream#pipe`, you can also manually release the buffered -events by calling `delayedStream.resume()`: - -``` javascript -var delayed = DelayedStream.create(req); - -setTimeout(function() { - // Emit all buffered events and resume underlaying source - delayed.resume(); -}, 1000); -``` - -## Implementation - -In order to use this meta stream properly, here are a few things you should -know about the implementation. - -### Event Buffering / Proxying - -All events of the `source` stream are hijacked by overwriting the `source.emit` -method. Until node implements a catch-all event listener, this is the only way. - -However, delayed-stream still continues to emit all events it captures on the -`source`, regardless of whether you have released the delayed stream yet or -not. - -Upon creation, delayed-stream captures all `source` events and stores them in -an internal event buffer. Once `delayedStream.release()` is called, all -buffered events are emitted on the `delayedStream`, and the event buffer is -cleared. After that, delayed-stream merely acts as a proxy for the underlaying -source. - -### Error handling - -Error events on `source` are buffered / proxied just like any other events. -However, `delayedStream.create` attaches a no-op `'error'` listener to the -`source`. This way you only have to handle errors on the `delayedStream` -object, rather than in two places. - -### Buffer limits - -delayed-stream provides a `maxDataSize` property that can be used to limit -the amount of data being buffered. In order to protect you from bad `source` -streams that don't react to `source.pause()`, this feature is enabled by -default. - -## API - -### DelayedStream.create(source, [options]) - -Returns a new `delayedStream`. Available options are: - -* `pauseStream` -* `maxDataSize` - -The description for those properties can be found below. - -### delayedStream.source - -The `source` stream managed by this object. This is useful if you are -passing your `delayedStream` around, and you still want to access properties -on the `source` object. - -### delayedStream.pauseStream = true - -Whether to pause the underlaying `source` when calling -`DelayedStream.create()`. Modifying this property afterwards has no effect. - -### delayedStream.maxDataSize = 1024 * 1024 - -The amount of data to buffer before emitting an `error`. - -If the underlaying source is emitting `Buffer` objects, the `maxDataSize` -refers to bytes. - -If the underlaying source is emitting JavaScript strings, the size refers to -characters. - -If you know what you are doing, you can set this property to `Infinity` to -disable this feature. You can also modify this property during runtime. - -### delayedStream.maxDataSize = 1024 * 1024 - -The amount of data to buffer before emitting an `error`. - -If the underlaying source is emitting `Buffer` objects, the `maxDataSize` -refers to bytes. - -If the underlaying source is emitting JavaScript strings, the size refers to -characters. - -If you know what you are doing, you can set this property to `Infinity` to -disable this feature. - -### delayedStream.dataSize = 0 - -The amount of data buffered so far. - -### delayedStream.readable - -An ECMA5 getter that returns the value of `source.readable`. - -### delayedStream.resume() - -If the `delayedStream` has not been released so far, `delayedStream.release()` -is called. - -In either case, `source.resume()` is called. - -### delayedStream.pause() - -Calls `source.pause()`. - -### delayedStream.pipe(dest) - -Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. - -### delayedStream.release() - -Emits and clears all events that have been buffered up so far. This does not -resume the underlaying source, use `delayedStream.resume()` instead. - -## License - -delayed-stream is licensed under the MIT license. diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js deleted file mode 100644 index 7c10d482531..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js +++ /dev/null @@ -1,99 +0,0 @@ -var Stream = require('stream').Stream; -var util = require('util'); - -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; - - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); - -DelayedStream.create = function(source, options) { - var delayedStream = new this(); - - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } - - delayedStream.source = source; - - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; - - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } - - return delayedStream; -}; - -DelayedStream.prototype.__defineGetter__('readable', function() { - return this.source.readable; -}); - -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); - } - - this.source.resume(); -}; - -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; - -DelayedStream.prototype.release = function() { - this._released = true; - - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; - -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; - -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; - } - - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); - } - - this._bufferedEvents.push(args); -}; - -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; - } - - if (this.dataSize <= this.maxDataSize) { - return; - } - - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); -}; diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json deleted file mode 100644 index 38341b8a08f..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "delayed-stream", - "description": "Buffers events from a stream until you are ready to handle them.", - "version": "0.0.5", - "homepage": "https://github.com/felixge/node-delayed-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-delayed-stream.git" - }, - "main": "./lib/delayed_stream", - "engines": { - "node": ">=0.4.0" - }, - "dependencies": {}, - "devDependencies": { - "fake": "0.2.0", - "far": "0.0.1" - }, - "readme": "# delayed-stream\n\nBuffers events from a stream until you are ready to handle them.\n\n## Installation\n\n``` bash\nnpm install delayed-stream\n```\n\n## Usage\n\nThe following example shows how to write a http echo server that delays its\nresponse by 1000 ms.\n\n``` javascript\nvar DelayedStream = require('delayed-stream');\nvar http = require('http');\n\nhttp.createServer(function(req, res) {\n var delayed = DelayedStream.create(req);\n\n setTimeout(function() {\n res.writeHead(200);\n delayed.pipe(res);\n }, 1000);\n});\n```\n\nIf you are not using `Stream#pipe`, you can also manually release the buffered\nevents by calling `delayedStream.resume()`:\n\n``` javascript\nvar delayed = DelayedStream.create(req);\n\nsetTimeout(function() {\n // Emit all buffered events and resume underlaying source\n delayed.resume();\n}, 1000);\n```\n\n## Implementation\n\nIn order to use this meta stream properly, here are a few things you should\nknow about the implementation.\n\n### Event Buffering / Proxying\n\nAll events of the `source` stream are hijacked by overwriting the `source.emit`\nmethod. Until node implements a catch-all event listener, this is the only way.\n\nHowever, delayed-stream still continues to emit all events it captures on the\n`source`, regardless of whether you have released the delayed stream yet or\nnot.\n\nUpon creation, delayed-stream captures all `source` events and stores them in\nan internal event buffer. Once `delayedStream.release()` is called, all\nbuffered events are emitted on the `delayedStream`, and the event buffer is\ncleared. After that, delayed-stream merely acts as a proxy for the underlaying\nsource.\n\n### Error handling\n\nError events on `source` are buffered / proxied just like any other events.\nHowever, `delayedStream.create` attaches a no-op `'error'` listener to the\n`source`. This way you only have to handle errors on the `delayedStream`\nobject, rather than in two places.\n\n### Buffer limits\n\ndelayed-stream provides a `maxDataSize` property that can be used to limit\nthe amount of data being buffered. In order to protect you from bad `source`\nstreams that don't react to `source.pause()`, this feature is enabled by\ndefault.\n\n## API\n\n### DelayedStream.create(source, [options])\n\nReturns a new `delayedStream`. Available options are:\n\n* `pauseStream`\n* `maxDataSize`\n\nThe description for those properties can be found below.\n\n### delayedStream.source\n\nThe `source` stream managed by this object. This is useful if you are\npassing your `delayedStream` around, and you still want to access properties\non the `source` object.\n\n### delayedStream.pauseStream = true\n\nWhether to pause the underlaying `source` when calling\n`DelayedStream.create()`. Modifying this property afterwards has no effect.\n\n### delayedStream.maxDataSize = 1024 * 1024\n\nThe amount of data to buffer before emitting an `error`.\n\nIf the underlaying source is emitting `Buffer` objects, the `maxDataSize`\nrefers to bytes.\n\nIf the underlaying source is emitting JavaScript strings, the size refers to\ncharacters.\n\nIf you know what you are doing, you can set this property to `Infinity` to\ndisable this feature. You can also modify this property during runtime.\n\n### delayedStream.maxDataSize = 1024 * 1024\n\nThe amount of data to buffer before emitting an `error`.\n\nIf the underlaying source is emitting `Buffer` objects, the `maxDataSize`\nrefers to bytes.\n\nIf the underlaying source is emitting JavaScript strings, the size refers to\ncharacters.\n\nIf you know what you are doing, you can set this property to `Infinity` to\ndisable this feature.\n\n### delayedStream.dataSize = 0\n\nThe amount of data buffered so far.\n\n### delayedStream.readable\n\nAn ECMA5 getter that returns the value of `source.readable`.\n\n### delayedStream.resume()\n\nIf the `delayedStream` has not been released so far, `delayedStream.release()`\nis called.\n\nIn either case, `source.resume()` is called.\n\n### delayedStream.pause()\n\nCalls `source.pause()`.\n\n### delayedStream.pipe(dest)\n\nCalls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.\n\n### delayedStream.release()\n\nEmits and clears all events that have been buffered up so far. This does not\nresume the underlaying source, use `delayedStream.resume()` instead.\n\n## License\n\ndelayed-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-delayed-stream/issues" - }, - "_id": "delayed-stream@0.0.5", - "_from": "delayed-stream@0.0.5" -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js deleted file mode 100644 index 4d71b8a6471..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js +++ /dev/null @@ -1,6 +0,0 @@ -var common = module.exports; - -common.DelayedStream = require('..'); -common.assert = require('assert'); -common.fake = require('fake'); -common.PORT = 49252; diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js deleted file mode 100644 index 9ecad5b8ad1..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js +++ /dev/null @@ -1,38 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var DelayedStream = common.DelayedStream; -var http = require('http'); - -var UPLOAD = new Buffer(10 * 1024 * 1024); - -var server = http.createServer(function(req, res) { - var delayed = DelayedStream.create(req, {maxDataSize: UPLOAD.length}); - - setTimeout(function() { - res.writeHead(200); - delayed.pipe(res); - }, 10); -}); -server.listen(common.PORT, function() { - var request = http.request({ - method: 'POST', - port: common.PORT, - }); - - request.write(UPLOAD); - request.end(); - - request.on('response', function(res) { - var received = 0; - res - .on('data', function(chunk) { - received += chunk.length; - }) - .on('end', function() { - assert.equal(received, UPLOAD.length); - server.close(); - }); - }); -}); - - diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js deleted file mode 100644 index 6f417f3e90f..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js +++ /dev/null @@ -1,21 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testAutoPause() { - var source = new Stream(); - - fake.expect(source, 'pause', 1); - var delayedStream = DelayedStream.create(source); - fake.verify(); -})(); - -(function testDisableAutoPause() { - var source = new Stream(); - fake.expect(source, 'pause', 0); - - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - fake.verify(); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js deleted file mode 100644 index b50c39783a0..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testDelayEventsUntilResume() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - fake.expect(source, 'pause'); - delayedStream.pause(); - fake.verify(); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js deleted file mode 100644 index fc4047e08b2..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js +++ /dev/null @@ -1,48 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testDelayEventsUntilResume() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - // delayedStream must not emit until we resume - fake.expect(delayedStream, 'emit', 0); - - // but our original source must emit - var params = []; - source.on('foo', function(param) { - params.push(param); - }); - - source.emit('foo', 1); - source.emit('foo', 2); - - // Make sure delayedStream did not emit, and source did - assert.deepEqual(params, [1, 2]); - fake.verify(); - - // After resume, delayedStream must playback all events - fake - .stub(delayedStream, 'emit') - .times(Infinity) - .withArg(1, 'newListener'); - fake.expect(delayedStream, 'emit', ['foo', 1]); - fake.expect(delayedStream, 'emit', ['foo', 2]); - fake.expect(source, 'resume'); - - delayedStream.resume(); - fake.verify(); - - // Calling resume again will delegate to source - fake.expect(source, 'resume'); - delayedStream.resume(); - fake.verify(); - - // Emitting more events directly leads to them being emitted - fake.expect(delayedStream, 'emit', ['foo', 3]); - source.emit('foo', 3); - fake.verify(); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js deleted file mode 100644 index a9d35e72ca2..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js +++ /dev/null @@ -1,15 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testHandleSourceErrors() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - // We deal with this by attaching a no-op listener to 'error' on the source - // when creating a new DelayedStream. This way error events on the source - // won't throw. - source.emit('error', new Error('something went wrong')); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js deleted file mode 100644 index 7638a2bf040..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js +++ /dev/null @@ -1,18 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testMaxDataSize() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {maxDataSize: 1024, pauseStream: false}); - - source.emit('data', new Buffer(1024)); - - fake - .expect(delayedStream, 'emit') - .withArg(1, 'error'); - source.emit('data', new Buffer(1)); - fake.verify(); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js deleted file mode 100644 index 7d312ab1f88..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js +++ /dev/null @@ -1,13 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testPipeReleases() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - fake.expect(delayedStream, 'resume'); - delayedStream.pipe(new Stream()); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js deleted file mode 100644 index d436163b7cd..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js +++ /dev/null @@ -1,13 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testProxyReadableProperty() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - source.readable = fake.value('source.readable'); - assert.strictEqual(delayedStream.readable, source.readable); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json deleted file mode 100644 index 0dd41416227..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "combined-stream", - "description": "A stream that emits multiple other streams one after another.", - "version": "0.0.4", - "homepage": "https://github.com/felixge/node-combined-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-combined-stream.git" - }, - "main": "./lib/combined_stream", - "engines": { - "node": "*" - }, - "dependencies": { - "delayed-stream": "0.0.5" - }, - "devDependencies": { - "far": "0.0.1" - }, - "readme": "# combined-stream\n\nA stream that emits multiple other streams one after another.\n\n## Installation\n\n``` bash\nnpm install combined-stream\n```\n\n## Usage\n\nHere is a simple example that shows how you can use combined-stream to combine\ntwo files into one:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nWhile the example above works great, it will pause all source streams until\nthey are needed. If you don't want that to happen, you can set `pauseStreams`\nto `false`:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create({pauseStreams: false});\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nHowever, what if you don't have all the source streams yet, or you don't want\nto allocate the resources (file descriptors, memory, etc.) for them right away?\nWell, in that case you can simply provide a callback that supplies the stream\nby calling a `next()` function:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file1.txt'));\n});\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file2.txt'));\n});\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\n## API\n\n### CombinedStream.create([options])\n\nReturns a new combined stream object. Available options are:\n\n* `maxDataSize`\n* `pauseStreams`\n\nThe effect of those options is described below.\n\n### combinedStream.pauseStreams = true\n\nWhether to apply back pressure to the underlaying streams. If set to `false`,\nthe underlaying streams will never be paused. If set to `true`, the\nunderlaying streams will be paused right after being appended, as well as when\n`delayedStream.pipe()` wants to throttle.\n\n### combinedStream.maxDataSize = 2 * 1024 * 1024\n\nThe maximum amount of bytes (or characters) to buffer for all source streams.\nIf this value is exceeded, `combinedStream` emits an `'error'` event.\n\n### combinedStream.dataSize = 0\n\nThe amount of bytes (or characters) currently buffered by `combinedStream`.\n\n### combinedStream.append(stream)\n\nAppends the given `stream` to the combinedStream object. If `pauseStreams` is\nset to `true, this stream will also be paused right away.\n\n`streams` can also be a function that takes one parameter called `next`. `next`\nis a function that must be invoked in order to provide the `next` stream, see\nexample above.\n\nRegardless of how the `stream` is appended, combined-stream always attaches an\n`'error'` listener to it, so you don't have to do that manually.\n\nSpecial case: `stream` can also be a String or Buffer.\n\n### combinedStream.write(data)\n\nYou should not call this, `combinedStream` takes care of piping the appended\nstreams into itself for you.\n\n### combinedStream.resume()\n\nCauses `combinedStream` to start drain the streams it manages. The function is\nidempotent, and also emits a `'resume'` event each time which usually goes to\nthe stream that is currently being drained.\n\n### combinedStream.pause();\n\nIf `combinedStream.pauseStreams` is set to `false`, this does nothing.\nOtherwise a `'pause'` event is emitted, this goes to the stream that is\ncurrently being drained, so you can use it to apply back pressure.\n\n### combinedStream.end();\n\nSets `combinedStream.writable` to false, emits an `'end'` event, and removes\nall streams from the queue.\n\n### combinedStream.destroy();\n\nSame as `combinedStream.end()`, except it emits a `'close'` event instead of\n`'end'`.\n\n## License\n\ncombined-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-combined-stream/issues" - }, - "_id": "combined-stream@0.0.4", - "_from": "combined-stream@~0.0.4" -} diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js deleted file mode 100644 index 81543485e02..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js +++ /dev/null @@ -1,23 +0,0 @@ -var common = module.exports; - -var path = require('path'); -var fs = require('fs'); -var root = path.join(__dirname, '..'); - -common.dir = { - fixture: root + '/test/fixture', - tmp: root + '/test/tmp', -}; - -// Create tmp directory if it does not exist -// Not using fs.exists so as to be node 0.6.x compatible -try { - fs.statSync(common.dir.tmp); -} -catch (e) { - // Dir does not exist - fs.mkdirSync(common.dir.tmp); -} - -common.CombinedStream = require(root); -common.assert = require('assert'); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt deleted file mode 100644 index 50e0218df4d..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt +++ /dev/null @@ -1,256 +0,0 @@ -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt deleted file mode 100644 index da1d821fe80..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt +++ /dev/null @@ -1,256 +0,0 @@ -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js deleted file mode 100644 index 44ecabab69c..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js +++ /dev/null @@ -1,27 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(function(next) { - next(fs.createReadStream(FILE1)); - }); - combinedStream.append(function(next) { - next(fs.createReadStream(FILE2)); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('end', function() { - var written = fs.readFileSync(tmpFile, 'utf8'); - assert.strictEqual(written, EXPECTED); - }); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js deleted file mode 100644 index e3fbd1842f8..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js +++ /dev/null @@ -1,34 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; - -(function testDataSizeGetter() { - var combinedStream = CombinedStream.create(); - - assert.strictEqual(combinedStream.dataSize, 0); - - // Test one stream - combinedStream._streams.push({dataSize: 10}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 10); - - // Test two streams - combinedStream._streams.push({dataSize: 23}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); - - // Test currentStream - combinedStream._currentStream = {dataSize: 20}; - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 53); - - // Test currentStream without dataSize - combinedStream._currentStream = {}; - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); - - // Test stream function - combinedStream._streams.push(function() {}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js deleted file mode 100644 index c678575c07b..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js +++ /dev/null @@ -1,38 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var BUFFER = new Buffer('Bacon is delicious'); -var FILE2 = common.dir.fixture + '/file2.txt'; -var STRING = 'The € kicks the $\'s ass!'; - -var EXPECTED = - fs.readFileSync(FILE1) - + BUFFER - + fs.readFileSync(FILE2) - + STRING; -var GOT; - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(BUFFER); - combinedStream.append(fs.createReadStream(FILE2)); - combinedStream.append(function(next) { - next(STRING); - }); - - var tmpFile = common.dir.tmp + '/combined-file1-buffer-file2-string.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('close', function() { - GOT = fs.readFileSync(tmpFile, 'utf8'); - }); -})(); - -process.on('exit', function() { - assert.strictEqual(GOT, EXPECTED); -}); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js deleted file mode 100644 index 263cfdf7222..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js +++ /dev/null @@ -1,35 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); -var GOT; - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var stream1 = combinedStream._streams[0]; - var stream2 = combinedStream._streams[1]; - - stream1.on('end', function() { - assert.equal(stream2.dataSize, 0); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('close', function() { - GOT = fs.readFileSync(tmpFile, 'utf8'); - }); -})(); - -process.on('exit', function() { - console.error(GOT.length, EXPECTED.length); - assert.strictEqual(GOT, EXPECTED); -}); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js deleted file mode 100644 index c3d288d013c..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js +++ /dev/null @@ -1,39 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var util = require('util'); -var Stream = require('stream').Stream; - -var s = CombinedStream.create(); - - -function StringStream(){ - this.writable=true; - this.str="" -} -util.inherits(StringStream,Stream); - -StringStream.prototype.write=function(chunk,encoding){ - this.str+=chunk.toString(); - this.emit('data',chunk); -} - -StringStream.prototype.end=function(chunk,encoding){ - this.emit('end'); -} - -StringStream.prototype.toString=function(){ - return this.str; -} - - -s.append("foo."); -s.append(""); -s.append("bar"); - -var ss = new StringStream(); - -s.pipe(ss); -s.resume(); - -assert.equal(ss.toString(),"foo.bar"); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js deleted file mode 100644 index aefa36e6b7a..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js +++ /dev/null @@ -1,17 +0,0 @@ -var fs = require('fs'); -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var FILE1 = common.dir.fixture + '/file1.txt'; -var fileStream = fs.createReadStream(FILE1); - -var foo = function(){}; - -(function testIsStreamLike() { - assert(! CombinedStream.isStreamLike(true)); - assert(! CombinedStream.isStreamLike("I am a string")); - assert(! CombinedStream.isStreamLike(7)); - assert(! CombinedStream.isStreamLike(foo)); - - assert(CombinedStream.isStreamLike(fileStream)); -})(); \ No newline at end of file diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js deleted file mode 100644 index 25f47a47c3a..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js +++ /dev/null @@ -1,24 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create({pauseStreams: false, maxDataSize: 20736}); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var gotErr = null; - combinedStream.on('error', function(err) { - gotErr = err; - }); - - process.on('exit', function() { - assert.ok(gotErr); - assert.ok(gotErr.message.match(/bytes/)); - }); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js deleted file mode 100644 index 30a3a6f84e5..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js +++ /dev/null @@ -1,30 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create({pauseStreams: false}); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var stream1 = combinedStream._streams[0]; - var stream2 = combinedStream._streams[1]; - - stream1.on('end', function() { - assert.ok(stream2.dataSize > 0); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('end', function() { - var written = fs.readFileSync(tmpFile, 'utf8'); - assert.strictEqual(written, EXPECTED); - }); -})(); diff --git a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js b/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/api/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/api/node_modules/request/node_modules/form-data/package.json b/api/node_modules/request/node_modules/form-data/package.json deleted file mode 100644 index 48236848166..00000000000 --- a/api/node_modules/request/node_modules/form-data/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "form-data", - "description": "A module to create readable `\"multipart/form-data\"` streams. Can be used to submit forms and file uploads to other web applications.", - "version": "0.0.8", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-form-data.git" - }, - "main": "./lib/form_data", - "scripts": { - "test": "node test/run.js" - }, - "engines": { - "node": ">= 0.6" - }, - "dependencies": { - "combined-stream": "~0.0.4", - "mime": "~1.2.2", - "async": "~0.2.7" - }, - "devDependencies": { - "fake": "~0.2.1", - "far": "~0.0.7", - "formidable": "~1.0.13", - "request": "~2.16.6" - }, - "readme": "# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data)\n\nA module to create readable `\"multipart/form-data\"` streams. Can be used to\nsubmit forms and file uploads to other web applications.\n\nThe API of this module is inspired by the\n[XMLHttpRequest-2 FormData Interface][xhr2-fd].\n\n[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface\n\n## Install\n\n```\nnpm install form-data\n```\n\n## Usage\n\nIn this example we are constructing a form with 3 fields that contain a string,\na buffer and a file stream.\n\n``` javascript\nvar FormData = require('form-data');\nvar fs = require('fs');\n\nvar form = new FormData();\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_file', fs.createReadStream('/foo/bar.jpg'));\n```\n\nAlso you can use http-response stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar http = require('http');\n\nvar form = new FormData();\n\nhttp.request('http://nodejs.org/images/logo.png', function(response) {\n form.append('my_field', 'my value');\n form.append('my_buffer', new Buffer(10));\n form.append('my_logo', response);\n});\n```\n\nOr @mikeal's request stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar request = require('request');\n\nvar form = new FormData();\n\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_logo', request('http://nodejs.org/images/logo.png'));\n```\n\nIn order to submit this form to a web application, you can use node's http\nclient interface:\n\n``` javascript\nvar http = require('http');\n\nvar request = http.request({\n method: 'post',\n host: 'example.org',\n path: '/upload',\n headers: form.getHeaders()\n});\n\nform.pipe(request);\n\nrequest.on('response', function(res) {\n console.log(res.statusCode);\n});\n```\n\nOr if you would prefer the `'Content-Length'` header to be set for you:\n\n``` javascript\nform.submit('example.org/upload', function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nTo use custom headers and pre-known length in parts:\n\n``` javascript\nvar CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});\n```\n\nForm-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide \"file\"-related information manually:\n\n``` javascript\nsomeModule.stream(function(err, stdout, stderr) {\n if (err) throw err;\n\n var form = new FormData();\n\n form.append('file', stdout, {\n filename: 'unicycle.jpg',\n contentType: 'image/jpg',\n knownLength: 19806\n });\n\n form.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n });\n});\n```\n\nFor edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/probably.php?extra=params',\n auth: 'username:password'\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\n## TODO\n\n- Add new streams (0.10) support and try really hard not to break it for 0.8.x.\n\n## License\n\nForm-Data is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-form-data/issues" - }, - "_id": "form-data@0.0.8", - "_from": "form-data@0.0.8" -} diff --git a/api/node_modules/request/node_modules/form-data/sftp-config.json b/api/node_modules/request/node_modules/form-data/sftp-config.json deleted file mode 100644 index ad9ed2623d5..00000000000 --- a/api/node_modules/request/node_modules/form-data/sftp-config.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - // The tab key will cycle through the settings when first created - // Visit http://wbond.net/sublime_packages/sftp/settings for help - - // sftp, ftp or ftps - "type": "sftp", - - "save_before_upload": true, - "upload_on_save": true, - "sync_down_on_open": false, - "sync_skip_deletes": false, - "confirm_downloads": false, - "confirm_sync": true, - "confirm_overwrite_newer": false, - - "host": "amber.exposeapp.com", - "user": "alex", - //"password": "password", - //"port": "22", - - "remote_path": "/var/www/_playground/form-data/", - "ignore_regexes": [ - "node_modules", - "\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json", - "sftp-settings\\.json", "/venv/", "\\.svn", "\\.hg", "\\.git", - "\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini" - ], - //"file_permissions": "664", - //"dir_permissions": "775", - - //"extra_list_connections": 0, - - "connect_timeout": 30, - //"keepalive": 120, - //"ftp_passive_mode": true, - //"ssh_key_file": "~/.ssh/id_rsa", - //"sftp_flags": ["-F", "/path/to/ssh_config"], - - //"preserve_modification_times": false, - //"remote_time_offset_in_hours": 0, - //"remote_encoding": "utf-8", - //"remote_locale": "C", -} diff --git a/api/node_modules/request/node_modules/form-data/test/common.js b/api/node_modules/request/node_modules/form-data/test/common.js deleted file mode 100644 index 8a26482e1ea..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/common.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = module.exports; -var path = require('path'); - -var rootDir = path.join(__dirname, '..'); -common.dir = { - lib: rootDir + '/lib', - fixture: rootDir + '/test/fixture', - tmp: rootDir + '/test/tmp', -}; - -common.assert = require('assert'); -common.fake = require('fake'); - -common.port = 8432; diff --git a/api/node_modules/request/node_modules/form-data/test/fixture/bacon.txt b/api/node_modules/request/node_modules/form-data/test/fixture/bacon.txt deleted file mode 100644 index 9804bbdc63c..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/fixture/bacon.txt +++ /dev/null @@ -1 +0,0 @@ -Bacon is delicious. diff --git a/api/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg b/api/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg deleted file mode 100644 index 7cea4dd71dc..00000000000 Binary files a/api/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg and /dev/null differ diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js b/api/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js deleted file mode 100644 index 05f3fc036ef..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js +++ /dev/null @@ -1,52 +0,0 @@ -/* -test custom filename and content-type: -re: https://github.com/felixge/node-form-data/issues/29 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var fs = require('fs'); - -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var options = { - filename: 'test.png', - contentType: 'image/gif' -}; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('file', function(name, file) { - assert.strictEqual(name, 'my_file'); - assert.strictEqual(file.name, options.filename); - assert.strictEqual(file.type, options.contentType); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - form.append('my_file', fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), options); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js b/api/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js deleted file mode 100644 index 1c9b6adad56..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* -test custom headers, added in pull request: -https://github.com/felixge/node-form-data/pull/17 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); - -var FormData = require(common.dir.lib + '/form_data'); - -var CRLF = '\r\n'; - -var testHeader = 'X-Test-Fake: 123'; - -var expectedLength; - - -var server = http.createServer(function(req, res) { - var data = ''; - req.setEncoding('utf8'); - - req.on('data', function(d) { - data += d; - }); - - req.on('end', function() { - assert.ok( data.indexOf( testHeader ) != -1 ); - - // content-length would be 1000+ w/actual buffer size, - // but smaller w/overridden size. - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); - assert.equal(req.headers['content-length'], expectedLength); - - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - var options = { - header: - CRLF + '--' + form.getBoundary() + CRLF + - testHeader + - CRLF + CRLF, - - // override content-length, - // much lower than actual buffer size (1000) - knownLength: 1 - }; - - var bufferData = []; - for (var z = 0; z < 1000; z++) { - bufferData.push(1); - } - var buffer = new Buffer(bufferData); - - form.append('my_buffer', buffer, options); - - // (available to req handler) - expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength; - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js b/api/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js deleted file mode 100644 index 44d3b4dc276..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js +++ /dev/null @@ -1,93 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var FormData = require(common.dir.lib + '/form_data'); -var fake = require('fake').create(); -var fs = require('fs'); - -(function testEmptyForm() { - var form = new FormData(); - var callback = fake.callback(arguments.callee.name + '-getLength'); - var calls = fake.expectAnytime(callback, [null, 0]).calls; - - form.getLength(callback); - - // Make sure our response is async - assert.strictEqual(calls.length, 0); -})(); - -(function testUtf8String() { - var FIELD = 'my_field'; - var VALUE = 'May the € be with you'; - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - Buffer.byteLength(VALUE) + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - -(function testBuffer() { - var FIELD = 'my_field'; - var VALUE = new Buffer(23); - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - VALUE.length + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - -(function testStringFileBufferFile() { - var fields = [ - { - name: 'my_field', - value: 'Test 123', - }, - { - name: 'my_image', - value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), - }, - { - name: 'my_buffer', - value: new Buffer('123'), - }, - { - name: 'my_txt', - value: fs.createReadStream(common.dir.fixture + '/bacon.txt'), - }, - ]; - - var form = new FormData(); - var expectedLength = 0; - - fields.forEach(function(field) { - form.append(field.name, field.value); - if (field.value.path) { - var stat = fs.statSync(field.value.path); - expectedLength += stat.size; - } else { - expectedLength += field.value.length; - } - }); - - expectedLength += form._overheadLength + form._lastBoundary().length; - - var callback = fake.callback(arguments.callee.name + '-getLength'); - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js b/api/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js deleted file mode 100644 index 6dc2fb2bdde..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js +++ /dev/null @@ -1,18 +0,0 @@ -var common = require('../common'); -var assert = common.assert; - -var FormData = require(common.dir.lib + '/form_data'); - -(function testOneBoundaryPerForm() { - var form = new FormData(); - var boundary = form.getBoundary(); - - assert.equal(boundary, form.getBoundary()); - assert.equal(boundary.length, 50); -})(); - -(function testUniqueBoundaryPerForm() { - var formA = new FormData(); - var formB = new FormData(); - assert.notEqual(formA.getBoundary(), formB.getBoundary()); -})(); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-http-response.js b/api/node_modules/request/node_modules/form-data/test/integration/test-http-response.js deleted file mode 100644 index bebb26b35f4..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-http-response.js +++ /dev/null @@ -1,83 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var parseUrl = require('url').parse; -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -var FIELDS; -var server; - -var parsedUrl = parseUrl(remoteFile) - , options = { - method: 'get', - port: parsedUrl.port || 80, - path: parsedUrl.pathname, - host: parsedUrl.hostname - } - ; - -http.request(options, function(res) { - - FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: new Buffer([1, 2, 3])}, - {name: 'remote_file', value: res } - ]; - - var form = new FormData(); - FIELDS.forEach(function(field) { - form.append(field.name, field.value); - }); - - server.listen(common.port, function() { - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - - }); - -}).end(); - -server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - // http response doesn't have path property - assert.strictEqual(file.name, path.basename(field.value.path || remoteFile)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-pipe.js b/api/node_modules/request/node_modules/form-data/test/integration/test-pipe.js deleted file mode 100644 index a9264f92ebc..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-pipe.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - var form = new FormData(); - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - var request = http.request({ - method: 'post', - port: common.port, - path: '/upload', - headers: form.getHeaders() - }); - - form.pipe(request); - - request.on('response', function(res) { - server.close(); - }); -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js b/api/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js deleted file mode 100644 index f0d8f088cd6..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js +++ /dev/null @@ -1,77 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - // custom params object passed to submit - form.submit({ - port: common.port, - path: '/' - }, function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/api/node_modules/request/node_modules/form-data/test/integration/test-submit.js b/api/node_modules/request/node_modules/form-data/test/integration/test-submit.js deleted file mode 100644 index f90cc7f285b..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/integration/test-submit.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/api/node_modules/request/node_modules/form-data/test/run.js b/api/node_modules/request/node_modules/form-data/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/api/node_modules/request/node_modules/form-data/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/api/node_modules/request/node_modules/hawk/.npmignore b/api/node_modules/request/node_modules/hawk/.npmignore deleted file mode 100644 index 77ba16cb055..00000000000 --- a/api/node_modules/request/node_modules/hawk/.npmignore +++ /dev/null @@ -1,18 +0,0 @@ -.idea -*.iml -npm-debug.log -dump.rdb -node_modules -results.tap -results.xml -npm-shrinkwrap.json -config.json -.DS_Store -*/.DS_Store -*/*/.DS_Store -._* -*/._* -*/*/._* -coverage.* -lib-cov - diff --git a/api/node_modules/request/node_modules/hawk/.travis.yml b/api/node_modules/request/node_modules/hawk/.travis.yml deleted file mode 100644 index 047f7e3d5e1..00000000000 --- a/api/node_modules/request/node_modules/hawk/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js - -node_js: - - 0.10 - diff --git a/api/node_modules/request/node_modules/hawk/LICENSE b/api/node_modules/request/node_modules/hawk/LICENSE deleted file mode 100644 index e699a7bdbaa..00000000000 --- a/api/node_modules/request/node_modules/hawk/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2012-2013, Eran Hammer. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Eran Hammer nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ERAN HAMMER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/api/node_modules/request/node_modules/hawk/Makefile b/api/node_modules/request/node_modules/hawk/Makefile deleted file mode 100644 index 9e7138c2a6f..00000000000 --- a/api/node_modules/request/node_modules/hawk/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -test: - @./node_modules/.bin/lab -test-cov: - @./node_modules/.bin/lab -r threshold -t 100 -test-cov-html: - @./node_modules/.bin/lab -r html -o coverage.html -complexity: - @./node_modules/.bin/cr -o complexity.md -f markdown lib - -.PHONY: test test-cov test-cov-html complexity - diff --git a/api/node_modules/request/node_modules/hawk/README.md b/api/node_modules/request/node_modules/hawk/README.md deleted file mode 100644 index 7061a706c1d..00000000000 --- a/api/node_modules/request/node_modules/hawk/README.md +++ /dev/null @@ -1,620 +0,0 @@ -![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png) - - **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial -HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz). - -Current version: **0.13** - -[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk) - -# Table of Content - -- [**Introduction**](#introduction) - - [Replay Protection](#replay-protection) - - [Usage Example](#usage-example) - - [Protocol Example](#protocol-example) - - [Payload Validation](#payload-validation) - - [Response Payload Validation](#response-payload-validation) - - [Browser Support and Considerations](#browser-support-and-considerations) -

-- [**Single URI Authorization**](#single-uri-authorization) - - [Usage Example](#bewit-usage-example) -

-- [**Security Considerations**](#security-considerations) - - [MAC Keys Transmission](#mac-keys-transmission) - - [Confidentiality of Requests](#confidentiality-of-requests) - - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers) - - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials) - - [Entropy of Keys](#entropy-of-keys) - - [Coverage Limitations](#coverage-limitations) - - [Future Time Manipulation](#future-time-manipulation) - - [Client Clock Poisoning](#client-clock-poisoning) - - [Bewit Limitations](#bewit-limitations) -

-- [**Frequently Asked Questions**](#frequently-asked-questions) -

-- [**Acknowledgements**](#acknowledgements) - -# Introduction - -**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with -partial cryptographic verification of the request and response, covering the HTTP method, request URI, host, -and optionally the request payload. - -Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of -client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme, -the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is -included in its place. - -However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of -replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less -"chattiness" (interaction with the server). - -Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because -the client and server must both have access to the key material in the clear. - -The primary design goals of this scheme are to: -* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources, -* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where - to send an authenticated request), and -* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client - failure to validate the server's identity as part of its TLS handshake. - -In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using -a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk). - -The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server, -which is beyond the scope of this module. Typically, the shared credentials are established via an initial -TLS-protected phase or derived from some other shared confidential information available to both the client -and the server. - - -## Replay Protection - -Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more -than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when -making requests. This gives the server enough information to prevent replay attacks. - -The nonce is generated by the client, and is a string unique across all requests with the same timestamp and -key identifier combination. - -The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards -are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks. -By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in -practice translates to a maximum of 2 minutes as the skew can be positive or negative). - -Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client -clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types -(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response -to a bad timestamp. - -There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a -potential attack vector). Instead, the client only uses the server's time to calculate an offset used only -for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing -the number of round trips required to authenticate the first request. - - -## Usage Example - -Server code: - -```javascript -var Http = require('http'); -var Hawk = require('hawk'); - - -// Credentials lookup function - -var credentialsFunc = function (id, callback) { - - var credentials = { - key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', - algorithm: 'sha256', - user: 'Steve' - }; - - return callback(null, credentials); -}; - -// Create HTTP server - -var handler = function (req, res) { - - // Authenticate incoming request - - Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { - - // Prepare response - - var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!'); - var headers = { 'Content-Type': 'text/plain' }; - - // Generate Server-Authorization response header - - var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] }); - headers['Server-Authorization'] = header; - - // Send the response back - - res.writeHead(!err ? 200 : 401, headers); - res.end(payload); - }); -}; - -// Start server - -Http.createServer(handler).listen(8000, 'example.com'); -``` - -Client code: - -```javascript -var Request = require('request'); -var Hawk = require('hawk'); - - -// Client credentials - -var credentials = { - id: 'dh37fgj492je', - key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', - algorithm: 'sha256' -} - -// Request options - -var requestOptions = { - uri: 'http://example.com:8000/resource/1?b=1&a=2', - method: 'GET', - headers: {} -}; - -// Generate Authorization request header - -var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' }); -requestOptions.headers.Authorization = header.field; - -// Send authenticated request - -Request(requestOptions, function (error, response, body) { - - // Authenticate the server's response - - var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body }); - - // Output results - - console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)')); -}); -``` - -**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local -machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method. - -```javascript -Hawk.sntp.start(); -``` - - -## Protocol Example - -The client attempts to access a protected resource without authentication, sending the following HTTP request to -the resource server: - -``` -GET /resource/1?b=1&a=2 HTTP/1.1 -Host: example.com:8000 -``` - -The resource server returns an authentication challenge. - -``` -HTTP/1.1 401 Unauthorized -WWW-Authenticate: Hawk -``` - -The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/" -server. The **Hawk** credentials issued to the client include the following attributes: - -* Key identifier: dh37fgj492je -* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn -* Algorithm: sha256 - -The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1, -1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline -character): - -``` -hawk.1.header -1353832234 -j4h3g2 -GET -/resource?a=1&b=2 -example.com -8000 - -some-app-ext-data - -``` - -The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string. -The result is base64-encoded to produce the request MAC: - -``` -6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE= -``` - -The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using -the HTTP `Authorization` request header field: - -``` -GET /resource/1?b=1&a=2 HTTP/1.1 -Host: example.com:8000 -Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=" -``` - -The server validates the request by calculating the request MAC again based on the request received and verifies the validity -and scope of the **Hawk** credentials. If valid, the server responds with the requested resource. - - -### Payload Validation - -**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash -using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character): -* `hawk.1.payload` -* the content-type in lowercase, without any parameters (e.g. `application/json`) -* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability) - -For example: - -* Payload: `Thank you for flying Hawk` -* Content Type: `text/plain` -* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=` - -Results in the following input to the payload hash function (newline terminated values): - -``` -hawk.1.payload -text/plain -Thank you for flying Hawk - -``` - -Which produces the following hash value: - -``` -Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= -``` - -The client constructs the normalized request string (newline terminated values): - -``` -hawk.1.header -1353832234 -j4h3g2 -POST -/resource?a=1&b=2 -example.com -8000 -Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= -some-app-ext-data - -``` - -Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data, -and request MAC, with the request using the HTTP `Authorization` request header field: - -``` -POST /resource/1 HTTP/1.1 -Host: example.com:8000 -Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=" -``` - -It is up to the server if and when it validates the payload for any given request, based solely on it's security policy -and the nature of the data included. - -If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct -the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value -with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash. - -However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed -at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value -provided by the client after validating the MAC. - -It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value -included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided -by the client, the payload may be modified by an attacker. - - -## Response Payload Validation - -**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the -client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header -as a response header using the exact same syntax as the `Authorization` request header field. - -The header is contructed using the same process as the client's request header. The server uses the same credentials and other -artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with -new values based on the server response. The rest as identical to those used by the client. - -The result MAC digest is included with the optional `hash` and `ext` values: - -``` -Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific" -``` - - -## Browser Support and Considerations - -A browser script is provided for including using a `'); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml('')); - expect(boom.response.payload.message).to.not.contain(''); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml(' -``` - -Or in node.js: - -``` -npm install node-uuid -``` - -```javascript -var uuid = require('node-uuid'); -``` - -Then create some ids ... - -```javascript -// Generate a v1 (time-based) id -uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' - -// Generate a v4 (random) id -uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' -``` - -## API - -### uuid.v1([`options` [, `buffer` [, `offset`]]]) - -Generate and return a RFC4122 v1 (timestamp-based) UUID. - -* `options` - (Object) Optional uuid state to apply. Properties may include: - - * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID. See note 1. - * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used. - * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used. - * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2. - -* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. -* `offset` - (Number) Starting index in `buffer` at which to begin writing. - -Returns `buffer`, if specified, otherwise the string form of the UUID - -Notes: - -1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.) - -Example: Generate string UUID with fully-specified options - -```javascript -uuid.v1({ - node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab], - clockseq: 0x1234, - msecs: new Date('2011-11-01').getTime(), - nsecs: 5678 -}); // -> "710b962e-041c-11e1-9234-0123456789ab" -``` - -Example: In-place generation of two binary IDs - -```javascript -// Generate two ids in an array -var arr = new Array(32); // -> [] -uuid.v1(null, arr, 0); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15] -uuid.v1(null, arr, 16); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15] - -// Optionally use uuid.unparse() to get stringify the ids -uuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115' -uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115' -``` - -### uuid.v4([`options` [, `buffer` [, `offset`]]]) - -Generate and return a RFC4122 v4 UUID. - -* `options` - (Object) Optional uuid state to apply. Properties may include: - - * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values - * `rng` - (Function) Random # generator to use. Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values. - -* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. -* `offset` - (Number) Starting index in `buffer` at which to begin writing. - -Returns `buffer`, if specified, otherwise the string form of the UUID - -Example: Generate string UUID with fully-specified options - -```javascript -uuid.v4({ - random: [ - 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea, - 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36 - ] -}); -// -> "109156be-c4fb-41ea-b1b4-efe1671c5836" -``` - -Example: Generate two IDs in a single buffer - -```javascript -var buffer = new Array(32); // (or 'new Buffer' in node.js) -uuid.v4(null, buffer, 0); -uuid.v4(null, buffer, 16); -``` - -### uuid.parse(id[, buffer[, offset]]) -### uuid.unparse(buffer[, offset]) - -Parse and unparse UUIDs - - * `id` - (String) UUID(-like) string - * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used - * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0 - -Example parsing and unparsing a UUID string - -```javascript -var bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> -var string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10' -``` - -### uuid.noConflict() - -(Browsers only) Set `uuid` property back to it's previous value. - -Returns the node-uuid object. - -Example: - -```javascript -var myUuid = uuid.noConflict(); -myUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' -``` - -## Deprecated APIs - -Support for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version. - -### uuid([format [, buffer [, offset]]]) - -uuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary). - -### uuid.BufferClass - -The class of container created when generating binary uuid data if no buffer argument is specified. This is expected to go away, with no replacement API. - -## Testing - -In node.js - -``` -> cd test -> node test.js -``` - -In Browser - -``` -open test/test.html -``` - -### Benchmarking - -Requires node.js - -``` -npm install uuid uuid-js -node benchmark/benchmark.js -``` - -For a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark) - -For browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance). - -## Release notes - -v1.4 -* Improved module context detection -* Removed public RNG functions - -v1.3.2: -* Improve tests and handling of v1() options (Issue #24) -* Expose RNG option to allow for perf testing with different generators - -v1.3: -* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)! -* Support for node.js crypto API -* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code diff --git a/api/node_modules/request/node_modules/node-uuid/benchmark/README.md b/api/node_modules/request/node_modules/node-uuid/benchmark/README.md deleted file mode 100644 index aaeb2ea0132..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/benchmark/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# node-uuid Benchmarks - -### Results - -To see the results of our benchmarks visit https://github.com/broofa/node-uuid/wiki/Benchmark - -### Run them yourself - -node-uuid comes with some benchmarks to measure performance of generating UUIDs. These can be run using node.js. node-uuid is being benchmarked against some other uuid modules, that are available through npm namely `uuid` and `uuid-js`. - -To prepare and run the benchmark issue; - -``` -npm install uuid uuid-js -node benchmark/benchmark.js -``` - -You'll see an output like this one: - -``` -# v4 -nodeuuid.v4(): 854700 uuids/second -nodeuuid.v4('binary'): 788643 uuids/second -nodeuuid.v4('binary', buffer): 1336898 uuids/second -uuid(): 479386 uuids/second -uuid('binary'): 582072 uuids/second -uuidjs.create(4): 312304 uuids/second - -# v1 -nodeuuid.v1(): 938086 uuids/second -nodeuuid.v1('binary'): 683060 uuids/second -nodeuuid.v1('binary', buffer): 1644736 uuids/second -uuidjs.create(1): 190621 uuids/second -``` - -* The `uuid()` entries are for Nikhil Marathe's [uuid module](https://bitbucket.org/nikhilm/uuidjs) which is a wrapper around the native libuuid library. -* The `uuidjs()` entries are for Patrick Negri's [uuid-js module](https://github.com/pnegri/uuid-js) which is a pure javascript implementation based on [UUID.js](https://github.com/LiosK/UUID.js) by LiosK. - -If you want to get more reliable results you can run the benchmark multiple times and write the output into a log file: - -``` -for i in {0..9}; do node benchmark/benchmark.js >> benchmark/bench_0.4.12.log; done; -``` - -If you're interested in how performance varies between different node versions, you can issue the above command multiple times. - -You can then use the shell script `bench.sh` provided in this directory to calculate the averages over all benchmark runs and draw a nice plot: - -``` -(cd benchmark/ && ./bench.sh) -``` - -This assumes you have [gnuplot](http://www.gnuplot.info/) and [ImageMagick](http://www.imagemagick.org/) installed. You'll find a nice `bench.png` graph in the `benchmark/` directory then. diff --git a/api/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu b/api/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu deleted file mode 100644 index a342fbbe04e..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu +++ /dev/null @@ -1,174 +0,0 @@ -#!/opt/local/bin/gnuplot -persist -# -# -# G N U P L O T -# Version 4.4 patchlevel 3 -# last modified March 2011 -# System: Darwin 10.8.0 -# -# Copyright (C) 1986-1993, 1998, 2004, 2007-2010 -# Thomas Williams, Colin Kelley and many others -# -# gnuplot home: http://www.gnuplot.info -# faq, bugs, etc: type "help seeking-assistance" -# immediate help: type "help" -# plot window: hit 'h' -set terminal postscript eps noenhanced defaultplex \ - leveldefault color colortext \ - solid linewidth 1.2 butt noclip \ - palfuncparam 2000,0.003 \ - "Helvetica" 14 -set output 'bench.eps' -unset clip points -set clip one -unset clip two -set bar 1.000000 front -set border 31 front linetype -1 linewidth 1.000 -set xdata -set ydata -set zdata -set x2data -set y2data -set timefmt x "%d/%m/%y,%H:%M" -set timefmt y "%d/%m/%y,%H:%M" -set timefmt z "%d/%m/%y,%H:%M" -set timefmt x2 "%d/%m/%y,%H:%M" -set timefmt y2 "%d/%m/%y,%H:%M" -set timefmt cb "%d/%m/%y,%H:%M" -set boxwidth -set style fill empty border -set style rectangle back fc lt -3 fillstyle solid 1.00 border lt -1 -set style circle radius graph 0.02, first 0, 0 -set dummy x,y -set format x "% g" -set format y "% g" -set format x2 "% g" -set format y2 "% g" -set format z "% g" -set format cb "% g" -set angles radians -unset grid -set key title "" -set key outside left top horizontal Right noreverse enhanced autotitles columnhead nobox -set key noinvert samplen 4 spacing 1 width 0 height 0 -set key maxcolumns 2 maxrows 0 -unset label -unset arrow -set style increment default -unset style line -set style line 1 linetype 1 linewidth 2.000 pointtype 1 pointsize default pointinterval 0 -unset style arrow -set style histogram clustered gap 2 title offset character 0, 0, 0 -unset logscale -set offsets graph 0.05, 0.15, 0, 0 -set pointsize 1.5 -set pointintervalbox 1 -set encoding default -unset polar -unset parametric -unset decimalsign -set view 60, 30, 1, 1 -set samples 100, 100 -set isosamples 10, 10 -set surface -unset contour -set clabel '%8.3g' -set mapping cartesian -set datafile separator whitespace -unset hidden3d -set cntrparam order 4 -set cntrparam linear -set cntrparam levels auto 5 -set cntrparam points 5 -set size ratio 0 1,1 -set origin 0,0 -set style data points -set style function lines -set xzeroaxis linetype -2 linewidth 1.000 -set yzeroaxis linetype -2 linewidth 1.000 -set zzeroaxis linetype -2 linewidth 1.000 -set x2zeroaxis linetype -2 linewidth 1.000 -set y2zeroaxis linetype -2 linewidth 1.000 -set ticslevel 0.5 -set mxtics default -set mytics default -set mztics default -set mx2tics default -set my2tics default -set mcbtics default -set xtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set xtics norangelimit -set xtics () -set ytics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set ytics autofreq norangelimit -set ztics border in scale 1,0.5 nomirror norotate offset character 0, 0, 0 -set ztics autofreq norangelimit -set nox2tics -set noy2tics -set cbtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set cbtics autofreq norangelimit -set title "" -set title offset character 0, 0, 0 font "" norotate -set timestamp bottom -set timestamp "" -set timestamp offset character 0, 0, 0 font "" norotate -set rrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] ) -set autoscale rfixmin -set autoscale rfixmax -set trange [ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000] ) -set autoscale tfixmin -set autoscale tfixmax -set urange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale ufixmin -set autoscale ufixmax -set vrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale vfixmin -set autoscale vfixmax -set xlabel "" -set xlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate -set x2label "" -set x2label offset character 0, 0, 0 font "" textcolor lt -1 norotate -set xrange [ * : * ] noreverse nowriteback # (currently [-0.150000:3.15000] ) -set autoscale xfixmin -set autoscale xfixmax -set x2range [ * : * ] noreverse nowriteback # (currently [0.00000:3.00000] ) -set autoscale x2fixmin -set autoscale x2fixmax -set ylabel "" -set ylabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set y2label "" -set y2label offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set yrange [ 0.00000 : 1.90000e+06 ] noreverse nowriteback # (currently [:] ) -set autoscale yfixmin -set autoscale yfixmax -set y2range [ * : * ] noreverse nowriteback # (currently [0.00000:1.90000e+06] ) -set autoscale y2fixmin -set autoscale y2fixmax -set zlabel "" -set zlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate -set zrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale zfixmin -set autoscale zfixmax -set cblabel "" -set cblabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set cbrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] ) -set autoscale cbfixmin -set autoscale cbfixmax -set zero 1e-08 -set lmargin -1 -set bmargin -1 -set rmargin -1 -set tmargin -1 -set pm3d explicit at s -set pm3d scansautomatic -set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean -set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB -set palette rgbformulae 7, 5, 15 -set colorbox default -set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 front bdefault -set loadpath -set fontpath -set fit noerrorvariables -GNUTERM = "aqua" -plot 'bench_results.txt' using 2:xticlabel(1) w lp lw 2, '' using 3:xticlabel(1) w lp lw 2, '' using 4:xticlabel(1) w lp lw 2, '' using 5:xticlabel(1) w lp lw 2, '' using 6:xticlabel(1) w lp lw 2, '' using 7:xticlabel(1) w lp lw 2, '' using 8:xticlabel(1) w lp lw 2, '' using 9:xticlabel(1) w lp lw 2 -# EOF diff --git a/api/node_modules/request/node_modules/node-uuid/benchmark/bench.sh b/api/node_modules/request/node_modules/node-uuid/benchmark/bench.sh deleted file mode 100644 index d870a0cb098..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/benchmark/bench.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# for a given node version run: -# for i in {0..9}; do node benchmark.js >> bench_0.6.2.log; done; - -PATTERNS=('nodeuuid.v1()' "nodeuuid.v1('binary'," 'nodeuuid.v4()' "nodeuuid.v4('binary'," "uuid()" "uuid('binary')" 'uuidjs.create(1)' 'uuidjs.create(4)' '140byte') -FILES=(node_uuid_v1_string node_uuid_v1_buf node_uuid_v4_string node_uuid_v4_buf libuuid_v4_string libuuid_v4_binary uuidjs_v1_string uuidjs_v4_string 140byte_es) -INDICES=(2 3 2 3 2 2 2 2 2) -VERSIONS=$( ls bench_*.log | sed -e 's/^bench_\([0-9\.]*\)\.log/\1/' | tr "\\n" " " ) -TMPJOIN="tmp_join" -OUTPUT="bench_results.txt" - -for I in ${!FILES[*]}; do - F=${FILES[$I]} - P=${PATTERNS[$I]} - INDEX=${INDICES[$I]} - echo "version $F" > $F - for V in $VERSIONS; do - (VAL=$( grep "$P" bench_$V.log | LC_ALL=en_US awk '{ sum += $'$INDEX' } END { print sum/NR }' ); echo $V $VAL) >> $F - done - if [ $I == 0 ]; then - cat $F > $TMPJOIN - else - join $TMPJOIN $F > $OUTPUT - cp $OUTPUT $TMPJOIN - fi - rm $F -done - -rm $TMPJOIN - -gnuplot bench.gnu -convert -density 200 -resize 800x560 -flatten bench.eps bench.png -rm bench.eps diff --git a/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c b/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c deleted file mode 100644 index dbfc75f6d71..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c +++ /dev/null @@ -1,34 +0,0 @@ -/* -Test performance of native C UUID generation - -To Compile: cc -luuid benchmark-native.c -o benchmark-native -*/ - -#include -#include -#include -#include - -int main() { - uuid_t myid; - char buf[36+1]; - int i; - struct timeval t; - double start, finish; - - gettimeofday(&t, NULL); - start = t.tv_sec + t.tv_usec/1e6; - - int n = 2e5; - for (i = 0; i < n; i++) { - uuid_generate(myid); - uuid_unparse(myid, buf); - } - - gettimeofday(&t, NULL); - finish = t.tv_sec + t.tv_usec/1e6; - double dur = finish - start; - - printf("%d uuids/sec", (int)(n/dur)); - return 0; -} diff --git a/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js b/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js deleted file mode 100644 index 40e6efbe762..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js +++ /dev/null @@ -1,84 +0,0 @@ -try { - var nodeuuid = require('../uuid'); -} catch (e) { - console.error('node-uuid require failed - skipping tests'); -} - -try { - var uuid = require('uuid'); -} catch (e) { - console.error('uuid require failed - skipping tests'); -} - -try { - var uuidjs = require('uuid-js'); -} catch (e) { - console.error('uuid-js require failed - skipping tests'); -} - -var N = 5e5; - -function rate(msg, t) { - console.log(msg + ': ' + - (N / (Date.now() - t) * 1e3 | 0) + - ' uuids/second'); -} - -console.log('# v4'); - -// node-uuid - string form -if (nodeuuid) { - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4(); - rate('nodeuuid.v4() - using node.js crypto RNG', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4({rng: nodeuuid.mathRNG}); - rate('nodeuuid.v4() - using Math.random() RNG', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary'); - rate('nodeuuid.v4(\'binary\')', t); - - var buffer = new nodeuuid.BufferClass(16); - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary', buffer); - rate('nodeuuid.v4(\'binary\', buffer)', t); -} - -// libuuid - string form -if (uuid) { - for (var i = 0, t = Date.now(); i < N; i++) uuid(); - rate('uuid()', t); - - for (var i = 0, t = Date.now(); i < N; i++) uuid('binary'); - rate('uuid(\'binary\')', t); -} - -// uuid-js - string form -if (uuidjs) { - for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(4); - rate('uuidjs.create(4)', t); -} - -// 140byte.es -for (var i = 0, t = Date.now(); i < N; i++) 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(s,r){r=Math.random()*16|0;return (s=='x'?r:r&0x3|0x8).toString(16)}); -rate('140byte.es_v4', t); - -console.log(''); -console.log('# v1'); - -// node-uuid - v1 string form -if (nodeuuid) { - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1(); - rate('nodeuuid.v1()', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary'); - rate('nodeuuid.v1(\'binary\')', t); - - var buffer = new nodeuuid.BufferClass(16); - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary', buffer); - rate('nodeuuid.v1(\'binary\', buffer)', t); -} - -// uuid-js - v1 string form -if (uuidjs) { - for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(1); - rate('uuidjs.create(1)', t); -} diff --git a/api/node_modules/request/node_modules/node-uuid/package.json b/api/node_modules/request/node_modules/node-uuid/package.json deleted file mode 100644 index 11733e8f54d..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "node-uuid", - "description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.", - "url": "http://github.com/broofa/node-uuid", - "keywords": [ - "uuid", - "guid", - "rfc4122" - ], - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com" - }, - "contributors": [ - { - "name": "Christoph Tavan", - "email": "dev@tavan.de" - } - ], - "lib": ".", - "main": "./uuid.js", - "repository": { - "type": "git", - "url": "https://github.com/broofa/node-uuid.git" - }, - "version": "1.4.0", - "readme": "# node-uuid\n\nSimple, fast generation of [RFC4122](http://www.ietf.org/rfc/rfc4122.txt) UUIDS.\n\nFeatures:\n\n* Generate RFC4122 version 1 or version 4 UUIDs\n* Runs in node.js and all browsers.\n* Cryptographically strong random # generation on supporting platforms\n* 1.1K minified and gzip'ed (Want something smaller? Check this [crazy shit](https://gist.github.com/982883) out! )\n* [Annotated source code](http://broofa.github.com/node-uuid/docs/uuid.html)\n\n## Getting Started\n\nInstall it in your browser:\n\n```html\n\n```\n\nOr in node.js:\n\n```\nnpm install node-uuid\n```\n\n```javascript\nvar uuid = require('node-uuid');\n```\n\nThen create some ids ...\n\n```javascript\n// Generate a v1 (time-based) id\nuuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'\n\n// Generate a v4 (random) id\nuuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'\n```\n\n## API\n\n### uuid.v1([`options` [, `buffer` [, `offset`]]])\n\nGenerate and return a RFC4122 v1 (timestamp-based) UUID.\n\n* `options` - (Object) Optional uuid state to apply. Properties may include:\n\n * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID. See note 1.\n * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used.\n * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used.\n * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.\n\n* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.\n* `offset` - (Number) Starting index in `buffer` at which to begin writing.\n\nReturns `buffer`, if specified, otherwise the string form of the UUID\n\nNotes:\n\n1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.)\n\nExample: Generate string UUID with fully-specified options\n\n```javascript\nuuid.v1({\n node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],\n clockseq: 0x1234,\n msecs: new Date('2011-11-01').getTime(),\n nsecs: 5678\n}); // -> \"710b962e-041c-11e1-9234-0123456789ab\"\n```\n\nExample: In-place generation of two binary IDs\n\n```javascript\n// Generate two ids in an array\nvar arr = new Array(32); // -> []\nuuid.v1(null, arr, 0); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15]\nuuid.v1(null, arr, 16); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15]\n\n// Optionally use uuid.unparse() to get stringify the ids\nuuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'\nuuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'\n```\n\n### uuid.v4([`options` [, `buffer` [, `offset`]]])\n\nGenerate and return a RFC4122 v4 UUID.\n\n* `options` - (Object) Optional uuid state to apply. Properties may include:\n\n * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values\n * `rng` - (Function) Random # generator to use. Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values.\n\n* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.\n* `offset` - (Number) Starting index in `buffer` at which to begin writing.\n\nReturns `buffer`, if specified, otherwise the string form of the UUID\n\nExample: Generate string UUID with fully-specified options\n\n```javascript\nuuid.v4({\n random: [\n 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea,\n 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36\n ]\n});\n// -> \"109156be-c4fb-41ea-b1b4-efe1671c5836\"\n```\n\nExample: Generate two IDs in a single buffer\n\n```javascript\nvar buffer = new Array(32); // (or 'new Buffer' in node.js)\nuuid.v4(null, buffer, 0);\nuuid.v4(null, buffer, 16);\n```\n\n### uuid.parse(id[, buffer[, offset]])\n### uuid.unparse(buffer[, offset])\n\nParse and unparse UUIDs\n\n * `id` - (String) UUID(-like) string\n * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used\n * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0\n\nExample parsing and unparsing a UUID string\n\n```javascript\nvar bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> \nvar string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10'\n```\n\n### uuid.noConflict()\n\n(Browsers only) Set `uuid` property back to it's previous value.\n\nReturns the node-uuid object.\n\nExample:\n\n```javascript\nvar myUuid = uuid.noConflict();\nmyUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'\n```\n\n## Deprecated APIs\n\nSupport for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version.\n\n### uuid([format [, buffer [, offset]]])\n\nuuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary).\n\n### uuid.BufferClass\n\nThe class of container created when generating binary uuid data if no buffer argument is specified. This is expected to go away, with no replacement API.\n\n## Testing\n\nIn node.js\n\n```\n> cd test\n> node test.js\n```\n\nIn Browser\n\n```\nopen test/test.html\n```\n\n### Benchmarking\n\nRequires node.js\n\n```\nnpm install uuid uuid-js\nnode benchmark/benchmark.js\n```\n\nFor a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark)\n\nFor browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance).\n\n## Release notes\n\nv1.4\n* Improved module context detection\n* Removed public RNG functions\n\nv1.3.2:\n* Improve tests and handling of v1() options (Issue #24)\n* Expose RNG option to allow for perf testing with different generators\n\nv1.3:\n* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)!\n* Support for node.js crypto API\n* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-uuid/issues" - }, - "_id": "node-uuid@1.4.0", - "_from": "node-uuid@~1.4.0" -} diff --git a/api/node_modules/request/node_modules/node-uuid/test/compare_v1.js b/api/node_modules/request/node_modules/node-uuid/test/compare_v1.js deleted file mode 100644 index 05af82215fd..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/test/compare_v1.js +++ /dev/null @@ -1,63 +0,0 @@ -var assert = require('assert'), - nodeuuid = require('../uuid'), - uuidjs = require('uuid-js'), - libuuid = require('uuid').generate, - util = require('util'), - exec = require('child_process').exec, - os = require('os'); - -// On Mac Os X / macports there's only the ossp-uuid package that provides uuid -// On Linux there's uuid-runtime which provides uuidgen -var uuidCmd = os.type() === 'Darwin' ? 'uuid -1' : 'uuidgen -t'; - -function compare(ids) { - console.log(ids); - for (var i = 0; i < ids.length; i++) { - var id = ids[i].split('-'); - id = [id[2], id[1], id[0]].join(''); - ids[i] = id; - } - var sorted = ([].concat(ids)).sort(); - - if (sorted.toString() !== ids.toString()) { - console.log('Warning: sorted !== ids'); - } else { - console.log('everything in order!'); - } -} - -// Test time order of v1 uuids -var ids = []; -while (ids.length < 10e3) ids.push(nodeuuid.v1()); - -var max = 10; -console.log('node-uuid:'); -ids = []; -for (var i = 0; i < max; i++) ids.push(nodeuuid.v1()); -compare(ids); - -console.log(''); -console.log('uuidjs:'); -ids = []; -for (var i = 0; i < max; i++) ids.push(uuidjs.create(1).toString()); -compare(ids); - -console.log(''); -console.log('libuuid:'); -ids = []; -var count = 0; -var last = function() { - compare(ids); -} -var cb = function(err, stdout, stderr) { - ids.push(stdout.substring(0, stdout.length-1)); - count++; - if (count < max) { - return next(); - } - last(); -}; -var next = function() { - exec(uuidCmd, cb); -}; -next(); diff --git a/api/node_modules/request/node_modules/node-uuid/test/test.html b/api/node_modules/request/node_modules/node-uuid/test/test.html deleted file mode 100644 index d80326ec5a8..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/test/test.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/api/node_modules/request/node_modules/node-uuid/test/test.js b/api/node_modules/request/node_modules/node-uuid/test/test.js deleted file mode 100644 index 24692256161..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/test/test.js +++ /dev/null @@ -1,228 +0,0 @@ -if (!this.uuid) { - // node.js - uuid = require('../uuid'); -} - -// -// x-platform log/assert shims -// - -function _log(msg, type) { - type = type || 'log'; - - if (typeof(document) != 'undefined') { - document.write('
' + msg.replace(/\n/g, '
') + '
'); - } - if (typeof(console) != 'undefined') { - var color = { - log: '\033[39m', - warn: '\033[33m', - error: '\033[31m' - }; - console[type](color[type] + msg + color.log); - } -} - -function log(msg) {_log(msg, 'log');} -function warn(msg) {_log(msg, 'warn');} -function error(msg) {_log(msg, 'error');} - -function assert(res, msg) { - if (!res) { - error('FAIL: ' + msg); - } else { - log('Pass: ' + msg); - } -} - -// -// Unit tests -// - -// Verify ordering of v1 ids created with explicit times -var TIME = 1321644961388; // 2011-11-18 11:36:01.388-08:00 - -function compare(name, ids) { - ids = ids.map(function(id) { - return id.split('-').reverse().join('-'); - }).sort(); - var sorted = ([].concat(ids)).sort(); - - assert(sorted.toString() == ids.toString(), name + ' have expected order'); -} - -// Verify ordering of v1 ids created using default behavior -compare('uuids with current time', [ - uuid.v1(), - uuid.v1(), - uuid.v1(), - uuid.v1(), - uuid.v1() -]); - -// Verify ordering of v1 ids created with explicit times -compare('uuids with time option', [ - uuid.v1({msecs: TIME - 10*3600*1000}), - uuid.v1({msecs: TIME - 1}), - uuid.v1({msecs: TIME}), - uuid.v1({msecs: TIME + 1}), - uuid.v1({msecs: TIME + 28*24*3600*1000}) -]); - -assert( - uuid.v1({msecs: TIME}) != uuid.v1({msecs: TIME}), - 'IDs created at same msec are different' -); - -// Verify throw if too many ids created -var thrown = false; -try { - uuid.v1({msecs: TIME, nsecs: 10000}); -} catch (e) { - thrown = true; -} -assert(thrown, 'Exception thrown when > 10K ids created in 1 ms'); - -// Verify clock regression bumps clockseq -var uidt = uuid.v1({msecs: TIME}); -var uidtb = uuid.v1({msecs: TIME - 1}); -assert( - parseInt(uidtb.split('-')[3], 16) - parseInt(uidt.split('-')[3], 16) === 1, - 'Clock regression by msec increments the clockseq' -); - -// Verify clock regression bumps clockseq -var uidtn = uuid.v1({msecs: TIME, nsecs: 10}); -var uidtnb = uuid.v1({msecs: TIME, nsecs: 9}); -assert( - parseInt(uidtnb.split('-')[3], 16) - parseInt(uidtn.split('-')[3], 16) === 1, - 'Clock regression by nsec increments the clockseq' -); - -// Verify explicit options produce expected id -var id = uuid.v1({ - msecs: 1321651533573, - nsecs: 5432, - clockseq: 0x385c, - node: [ 0x61, 0xcd, 0x3c, 0xbb, 0x32, 0x10 ] -}); -assert(id == 'd9428888-122b-11e1-b85c-61cd3cbb3210', 'Explicit options produce expected id'); - -// Verify adjacent ids across a msec boundary are 1 time unit apart -var u0 = uuid.v1({msecs: TIME, nsecs: 9999}); -var u1 = uuid.v1({msecs: TIME + 1, nsecs: 0}); - -var before = u0.split('-')[0], after = u1.split('-')[0]; -var dt = parseInt(after, 16) - parseInt(before, 16); -assert(dt === 1, 'Ids spanning 1ms boundary are 100ns apart'); - -// -// Test parse/unparse -// - -id = '00112233445566778899aabbccddeeff'; -assert(uuid.unparse(uuid.parse(id.substr(0,10))) == - '00112233-4400-0000-0000-000000000000', 'Short parse'); -assert(uuid.unparse(uuid.parse('(this is the uuid -> ' + id + id)) == - '00112233-4455-6677-8899-aabbccddeeff', 'Dirty parse'); - -// -// Perf tests -// - -var generators = { - v1: uuid.v1, - v4: uuid.v4 -}; - -var UUID_FORMAT = { - v1: /[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i, - v4: /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i -}; - -var N = 1e4; - -// Get %'age an actual value differs from the ideal value -function divergence(actual, ideal) { - return Math.round(100*100*(actual - ideal)/ideal)/100; -} - -function rate(msg, t) { - log(msg + ': ' + (N / (Date.now() - t) * 1e3 | 0) + ' uuids\/second'); -} - -for (var version in generators) { - var counts = {}, max = 0; - var generator = generators[version]; - var format = UUID_FORMAT[version]; - - log('\nSanity check ' + N + ' ' + version + ' uuids'); - for (var i = 0, ok = 0; i < N; i++) { - id = generator(); - if (!format.test(id)) { - throw Error(id + ' is not a valid UUID string'); - } - - if (id != uuid.unparse(uuid.parse(id))) { - assert(fail, id + ' is not a valid id'); - } - - // Count digits for our randomness check - if (version == 'v4') { - var digits = id.replace(/-/g, '').split(''); - for (var j = digits.length-1; j >= 0; j--) { - var c = digits[j]; - max = Math.max(max, counts[c] = (counts[c] || 0) + 1); - } - } - } - - // Check randomness for v4 UUIDs - if (version == 'v4') { - // Limit that we get worried about randomness. (Purely empirical choice, this!) - var limit = 2*100*Math.sqrt(1/N); - - log('\nChecking v4 randomness. Distribution of Hex Digits (% deviation from ideal)'); - - for (var i = 0; i < 16; i++) { - var c = i.toString(16); - var bar = '', n = counts[c], p = Math.round(n/max*100|0); - - // 1-3,5-8, and D-F: 1:16 odds over 30 digits - var ideal = N*30/16; - if (i == 4) { - // 4: 1:1 odds on 1 digit, plus 1:16 odds on 30 digits - ideal = N*(1 + 30/16); - } else if (i >= 8 && i <= 11) { - // 8-B: 1:4 odds on 1 digit, plus 1:16 odds on 30 digits - ideal = N*(1/4 + 30/16); - } else { - // Otherwise: 1:16 odds on 30 digits - ideal = N*30/16; - } - var d = divergence(n, ideal); - - // Draw bar using UTF squares (just for grins) - var s = n/max*50 | 0; - while (s--) bar += '='; - - assert(Math.abs(d) < limit, c + ' |' + bar + '| ' + counts[c] + ' (' + d + '% < ' + limit + '%)'); - } - } -} - -// Perf tests -for (var version in generators) { - log('\nPerformance testing ' + version + ' UUIDs'); - var generator = generators[version]; - var buf = new uuid.BufferClass(16); - - for (var i = 0, t = Date.now(); i < N; i++) generator(); - rate('uuid.' + version + '()', t); - - for (var i = 0, t = Date.now(); i < N; i++) generator('binary'); - rate('uuid.' + version + '(\'binary\')', t); - - for (var i = 0, t = Date.now(); i < N; i++) generator('binary', buf); - rate('uuid.' + version + '(\'binary\', buffer)', t); -} diff --git a/api/node_modules/request/node_modules/node-uuid/uuid.js b/api/node_modules/request/node_modules/node-uuid/uuid.js deleted file mode 100644 index 4795b9d8a68..00000000000 --- a/api/node_modules/request/node_modules/node-uuid/uuid.js +++ /dev/null @@ -1,245 +0,0 @@ -// uuid.js -// -// (c) 2010-2012 Robert Kieffer -// MIT License -// https://github.com/broofa/node-uuid -(function() { - var _global = this; - - // Unique ID creation requires a high quality random # generator. We feature - // detect to determine the best RNG source, normalizing to a function that - // returns 128-bits of randomness, since that's what's usually required - var _rng; - - // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html - // - // Moderately fast, high quality - if (typeof(require) == 'function') { - try { - var _rb = require('crypto').randomBytes; - _rng = _rb && function() {return _rb(16);}; - } catch(e) {} - } - - if (!_rng && _global.crypto && crypto.getRandomValues) { - // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto - // - // Moderately fast, high quality - var _rnds8 = new Uint8Array(16); - _rng = function whatwgRNG() { - crypto.getRandomValues(_rnds8); - return _rnds8; - }; - } - - if (!_rng) { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var _rnds = new Array(16); - _rng = function() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return _rnds; - }; - } - - // Buffer class to use - var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array; - - // Maps for number <-> hex string conversion - var _byteToHex = []; - var _hexToByte = {}; - for (var i = 0; i < 256; i++) { - _byteToHex[i] = (i + 0x100).toString(16).substr(1); - _hexToByte[_byteToHex[i]] = i; - } - - // **`parse()` - Parse a UUID into it's component bytes** - function parse(s, buf, offset) { - var i = (buf && offset) || 0, ii = 0; - - buf = buf || []; - s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { - if (ii < 16) { // Don't overflow! - buf[i + ii++] = _hexToByte[oct]; - } - }); - - // Zero out remaining bytes if string was short - while (ii < 16) { - buf[i + ii++] = 0; - } - - return buf; - } - - // **`unparse()` - Convert UUID byte array (ala parse()) into a string** - function unparse(buf, offset) { - var i = offset || 0, bth = _byteToHex; - return bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]]; - } - - // **`v1()` - Generate time-based UUID** - // - // Inspired by https://github.com/LiosK/UUID.js - // and http://docs.python.org/library/uuid.html - - // random #'s we need to init node and clockseq - var _seedBytes = _rng(); - - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - var _nodeId = [ - _seedBytes[0] | 0x01, - _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] - ]; - - // Per 4.2.2, randomize (14 bit) clockseq - var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; - - // Previous uuid creation time - var _lastMSecs = 0, _lastNSecs = 0; - - // See https://github.com/broofa/node-uuid for API details - function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - - var clockseq = options.clockseq != null ? options.clockseq : _clockseq; - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs != null ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq == null) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - var node = options.node || _nodeId; - for (var n = 0; n < 6; n++) { - b[i + n] = node[n]; - } - - return buf ? buf : unparse(b); - } - - // **`v4()` - Generate random UUID** - - // See https://github.com/broofa/node-uuid for API details - function v4(options, buf, offset) { - // Deprecated - 'format' argument, as supported in v1.2 - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options == 'binary' ? new BufferClass(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || _rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ii++) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || unparse(rnds); - } - - // Export public API - var uuid = v4; - uuid.v1 = v1; - uuid.v4 = v4; - uuid.parse = parse; - uuid.unparse = unparse; - uuid.BufferClass = BufferClass; - - if (_global.define && define.amd) { - // Publish as AMD module - define(function() {return uuid;}); - } else if (typeof(module) != 'undefined' && module.exports) { - // Publish as node.js module - module.exports = uuid; - } else { - // Publish as global (in browsers) - var _previousRoot = _global.uuid; - - // **`noConflict()` - (browser only) to reset global 'uuid' var** - uuid.noConflict = function() { - _global.uuid = _previousRoot; - return uuid; - }; - - _global.uuid = uuid; - } -}()); diff --git a/api/node_modules/request/node_modules/oauth-sign/LICENSE b/api/node_modules/request/node_modules/oauth-sign/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/api/node_modules/request/node_modules/oauth-sign/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/api/node_modules/request/node_modules/oauth-sign/README.md b/api/node_modules/request/node_modules/oauth-sign/README.md deleted file mode 100644 index 34c4a85d2dd..00000000000 --- a/api/node_modules/request/node_modules/oauth-sign/README.md +++ /dev/null @@ -1,4 +0,0 @@ -oauth-sign -========== - -OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. diff --git a/api/node_modules/request/node_modules/oauth-sign/index.js b/api/node_modules/request/node_modules/oauth-sign/index.js deleted file mode 100644 index e35bfa67075..00000000000 --- a/api/node_modules/request/node_modules/oauth-sign/index.js +++ /dev/null @@ -1,43 +0,0 @@ -var crypto = require('crypto') - , qs = require('querystring') - ; - -function sha1 (key, body) { - return crypto.createHmac('sha1', key).update(body).digest('base64') -} - -function rfc3986 (str) { - return encodeURIComponent(str) - .replace(/!/g,'%21') - .replace(/\*/g,'%2A') - .replace(/\(/g,'%28') - .replace(/\)/g,'%29') - .replace(/'/g,'%27') - ; -} - -function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { - // adapted from https://dev.twitter.com/docs/auth/oauth and - // https://dev.twitter.com/docs/auth/creating-signature - - var querystring = Object.keys(params).sort().map(function(key){ - // big WTF here with the escape + encoding but it's what twitter wants - return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key])) - }).join('%26') - - var base = [ - httpMethod ? httpMethod.toUpperCase() : 'GET', - rfc3986(base_uri), - querystring - ].join('&') - - var key = [ - consumer_secret, - token_secret || '' - ].map(rfc3986).join('&') - - return sha1(key, base) -} - -exports.hmacsign = hmacsign -exports.rfc3986 = rfc3986 diff --git a/api/node_modules/request/node_modules/oauth-sign/package.json b/api/node_modules/request/node_modules/oauth-sign/package.json deleted file mode 100644 index f211ed34eb8..00000000000 --- a/api/node_modules/request/node_modules/oauth-sign/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "oauth-sign", - "description": "OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/oauth-sign" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "scripts": { - "test": "node test.js" - }, - "readme": "oauth-sign\n==========\n\nOAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. \n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/oauth-sign/issues" - }, - "_id": "oauth-sign@0.3.0", - "_from": "oauth-sign@~0.3.0" -} diff --git a/api/node_modules/request/node_modules/oauth-sign/test.js b/api/node_modules/request/node_modules/oauth-sign/test.js deleted file mode 100644 index 46955ff6939..00000000000 --- a/api/node_modules/request/node_modules/oauth-sign/test.js +++ /dev/null @@ -1,49 +0,0 @@ -var hmacsign = require('./index').hmacsign - , assert = require('assert') - , qs = require('querystring') - ; - -// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth - -var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', - { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_timestamp: '1272323042' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") - -console.log(reqsign) -console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') -assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') - -var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', - { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , oauth_timestamp: '1272323047' - , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") - -console.log(accsign) -console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') -assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') - -var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', - { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" - , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , oauth_signature_method: "HMAC-SHA1" - , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , oauth_timestamp: "1272325550" - , oauth_version: "1.0" - , status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") - -console.log(upsign) -console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') -assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') - - diff --git a/api/node_modules/request/node_modules/qs/.gitmodules b/api/node_modules/request/node_modules/qs/.gitmodules deleted file mode 100644 index 49e31dac7d7..00000000000 --- a/api/node_modules/request/node_modules/qs/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "support/expresso"] - path = support/expresso - url = git://github.com/visionmedia/expresso.git -[submodule "support/should"] - path = support/should - url = git://github.com/visionmedia/should.js.git diff --git a/api/node_modules/request/node_modules/qs/.npmignore b/api/node_modules/request/node_modules/qs/.npmignore deleted file mode 100644 index e85ce2afa21..00000000000 --- a/api/node_modules/request/node_modules/qs/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -test -.travis.yml -benchmark.js -component.json -examples.js -History.md -Makefile diff --git a/api/node_modules/request/node_modules/qs/Readme.md b/api/node_modules/request/node_modules/qs/Readme.md deleted file mode 100644 index 27e54a4af18..00000000000 --- a/api/node_modules/request/node_modules/qs/Readme.md +++ /dev/null @@ -1,58 +0,0 @@ -# node-querystring - - query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. - -## Installation - - $ npm install qs - -## Examples - -```js -var qs = require('qs'); - -qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); -// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } - -qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) -// => user[name]=Tobi&user[email]=tobi%40learnboost.com -``` - -## Testing - -Install dev dependencies: - - $ npm install -d - -and execute: - - $ make test - -browser: - - $ open test/browser/index.html - -## License - -(The MIT License) - -Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/api/node_modules/request/node_modules/qs/index.js b/api/node_modules/request/node_modules/qs/index.js deleted file mode 100644 index 590491e31ed..00000000000 --- a/api/node_modules/request/node_modules/qs/index.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * Object#toString() ref for stringify(). - */ - -var toString = Object.prototype.toString; - -/** - * Object#hasOwnProperty ref - */ - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Array#indexOf shim. - */ - -var indexOf = typeof Array.prototype.indexOf === 'function' - ? function(arr, el) { return arr.indexOf(el); } - : function(arr, el) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] === el) return i; - } - return -1; - }; - -/** - * Array.isArray shim. - */ - -var isArray = Array.isArray || function(arr) { - return toString.call(arr) == '[object Array]'; -}; - -/** - * Object.keys shim. - */ - -var objectKeys = Object.keys || function(obj) { - var ret = []; - for (var key in obj) ret.push(key); - return ret; -}; - -/** - * Array#forEach shim. - */ - -var forEach = typeof Array.prototype.forEach === 'function' - ? function(arr, fn) { return arr.forEach(fn); } - : function(arr, fn) { - for (var i = 0; i < arr.length; i++) fn(arr[i]); - }; - -/** - * Array#reduce shim. - */ - -var reduce = function(arr, fn, initial) { - if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); - var res = initial; - for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); - return res; -}; - -/** - * Create a nullary object if possible - */ - -function createObject() { - return Object.create - ? Object.create(null) - : {}; -} - -/** - * Cache non-integer test regexp. - */ - -var isint = /^[0-9]+$/; - -function promote(parent, key) { - if (parent[key].length == 0) return parent[key] = createObject(); - var t = createObject(); - for (var i in parent[key]) { - if (hasOwnProperty.call(parent[key], i)) { - t[i] = parent[key][i]; - } - } - parent[key] = t; - return t; -} - -function parse(parts, parent, key, val) { - var part = parts.shift(); - // end - if (!part) { - if (isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } - // array - } else { - var obj = parent[key] = parent[key] || []; - if (']' == part) { - if (isArray(obj)) { - if ('' != val) obj.push(val); - } else if ('object' == typeof obj) { - obj[objectKeys(obj).length] = val; - } else { - obj = parent[key] = [parent[key], val]; - } - // prop - } else if (~indexOf(part, ']')) { - part = part.substr(0, part.length - 1); - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - // key - } else { - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - } - } -} - -/** - * Merge parent key/val pair. - */ - -function merge(parent, key, val){ - if (~indexOf(key, ']')) { - var parts = key.split('[') - , len = parts.length - , last = len - 1; - parse(parts, parent, 'base', val); - // optimize - } else { - if (!isint.test(key) && isArray(parent.base)) { - var t = createObject(); - for (var k in parent.base) t[k] = parent.base[k]; - parent.base = t; - } - set(parent.base, key, val); - } - - return parent; -} - -/** - * Compact sparse arrays. - */ - -function compact(obj) { - if ('object' != typeof obj) return obj; - - if (isArray(obj)) { - var ret = []; - - for (var i in obj) { - if (hasOwnProperty.call(obj, i)) { - ret.push(obj[i]); - } - } - - return ret; - } - - for (var key in obj) { - obj[key] = compact(obj[key]); - } - - return obj; -} - -/** - * Restore Object.prototype. - * see pull-request #58 - */ - -function restoreProto(obj) { - if (!Object.create) return obj; - if (isArray(obj)) return obj; - if (obj && 'object' != typeof obj) return obj; - - for (var key in obj) { - if (hasOwnProperty.call(obj, key)) { - obj[key] = restoreProto(obj[key]); - } - } - - obj.__proto__ = Object.prototype; - return obj; -} - -/** - * Parse the given obj. - */ - -function parseObject(obj){ - var ret = { base: {} }; - - forEach(objectKeys(obj), function(name){ - merge(ret, name, obj[name]); - }); - - return compact(ret.base); -} - -/** - * Parse the given str. - */ - -function parseString(str){ - var ret = reduce(String(str).split('&'), function(ret, pair){ - var eql = indexOf(pair, '=') - , brace = lastBraceInKey(pair) - , key = pair.substr(0, brace || eql) - , val = pair.substr(brace || eql, pair.length) - , val = val.substr(indexOf(val, '=') + 1, val.length); - - // ?foo - if ('' == key) key = pair, val = ''; - if ('' == key) return ret; - - return merge(ret, decode(key), decode(val)); - }, { base: createObject() }).base; - - return restoreProto(compact(ret)); -} - -/** - * Parse the given query `str` or `obj`, returning an object. - * - * @param {String} str | {Object} obj - * @return {Object} - * @api public - */ - -exports.parse = function(str){ - if (null == str || '' == str) return {}; - return 'object' == typeof str - ? parseObject(str) - : parseString(str); -}; - -/** - * Turn the given `obj` into a query string - * - * @param {Object} obj - * @return {String} - * @api public - */ - -var stringify = exports.stringify = function(obj, prefix) { - if (isArray(obj)) { - return stringifyArray(obj, prefix); - } else if ('[object Object]' == toString.call(obj)) { - return stringifyObject(obj, prefix); - } else if ('string' == typeof obj) { - return stringifyString(obj, prefix); - } else { - return prefix + '=' + encodeURIComponent(String(obj)); - } -}; - -/** - * Stringify the given `str`. - * - * @param {String} str - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyString(str, prefix) { - if (!prefix) throw new TypeError('stringify expects an object'); - return prefix + '=' + encodeURIComponent(str); -} - -/** - * Stringify the given `arr`. - * - * @param {Array} arr - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyArray(arr, prefix) { - var ret = []; - if (!prefix) throw new TypeError('stringify expects an object'); - for (var i = 0; i < arr.length; i++) { - ret.push(stringify(arr[i], prefix + '[' + i + ']')); - } - return ret.join('&'); -} - -/** - * Stringify the given `obj`. - * - * @param {Object} obj - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyObject(obj, prefix) { - var ret = [] - , keys = objectKeys(obj) - , key; - - for (var i = 0, len = keys.length; i < len; ++i) { - key = keys[i]; - if ('' == key) continue; - if (null == obj[key]) { - ret.push(encodeURIComponent(key) + '='); - } else { - ret.push(stringify(obj[key], prefix - ? prefix + '[' + encodeURIComponent(key) + ']' - : encodeURIComponent(key))); - } - } - - return ret.join('&'); -} - -/** - * Set `obj`'s `key` to `val` respecting - * the weird and wonderful syntax of a qs, - * where "foo=bar&foo=baz" becomes an array. - * - * @param {Object} obj - * @param {String} key - * @param {String} val - * @api private - */ - -function set(obj, key, val) { - var v = obj[key]; - if (undefined === v) { - obj[key] = val; - } else if (isArray(v)) { - v.push(val); - } else { - obj[key] = [v, val]; - } -} - -/** - * Locate last brace in `str` within the key. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function lastBraceInKey(str) { - var len = str.length - , brace - , c; - for (var i = 0; i < len; ++i) { - c = str[i]; - if (']' == c) brace = false; - if ('[' == c) brace = true; - if ('=' == c && !brace) return i; - } -} - -/** - * Decode `str`. - * - * @param {String} str - * @return {String} - * @api private - */ - -function decode(str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (err) { - return str; - } -} diff --git a/api/node_modules/request/node_modules/qs/package.json b/api/node_modules/request/node_modules/qs/package.json deleted file mode 100644 index d1475f93466..00000000000 --- a/api/node_modules/request/node_modules/qs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "qs", - "description": "querystring parser", - "version": "0.6.5", - "keywords": [ - "query string", - "parser", - "component" - ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/node-querystring.git" - }, - "devDependencies": { - "mocha": "*", - "expect.js": "*" - }, - "scripts": { - "test": "make test" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "main": "index", - "engines": { - "node": "*" - }, - "readme": "# node-querystring\n\n query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others.\n\n## Installation\n\n $ npm install qs\n\n## Examples\n\n```js\nvar qs = require('qs');\n\nqs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com');\n// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } }\n\nqs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }})\n// => user[name]=Tobi&user[email]=tobi%40learnboost.com\n```\n\n## Testing\n\nInstall dev dependencies:\n\n $ npm install -d\n\nand execute:\n\n $ make test\n\nbrowser:\n\n $ open test/browser/index.html\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/node-querystring/issues" - }, - "_id": "qs@0.6.5", - "_from": "qs@~0.6.0" -} diff --git a/api/node_modules/request/node_modules/tunnel-agent/LICENSE b/api/node_modules/request/node_modules/tunnel-agent/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/api/node_modules/request/node_modules/tunnel-agent/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/api/node_modules/request/node_modules/tunnel-agent/README.md b/api/node_modules/request/node_modules/tunnel-agent/README.md deleted file mode 100644 index bb533d56b1a..00000000000 --- a/api/node_modules/request/node_modules/tunnel-agent/README.md +++ /dev/null @@ -1,4 +0,0 @@ -tunnel-agent -============ - -HTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module. diff --git a/api/node_modules/request/node_modules/tunnel-agent/index.js b/api/node_modules/request/node_modules/tunnel-agent/index.js deleted file mode 100644 index 3f7bbb909fd..00000000000 --- a/api/node_modules/request/node_modules/tunnel-agent/index.js +++ /dev/null @@ -1,227 +0,0 @@ -'use strict' - -var net = require('net') - , tls = require('tls') - , http = require('http') - , https = require('https') - , events = require('events') - , assert = require('assert') - , util = require('util') - ; - -exports.httpOverHttp = httpOverHttp -exports.httpsOverHttp = httpsOverHttp -exports.httpOverHttps = httpOverHttps -exports.httpsOverHttps = httpsOverHttps - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - return agent -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - agent.createSocket = createSecureSocket - return agent -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - return agent -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - agent.createSocket = createSecureSocket - return agent -} - - -function TunnelingAgent(options) { - var self = this - self.options = options || {} - self.proxyOptions = self.options.proxy || {} - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets - self.requests = [] - self.sockets = [] - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i] - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1) - pending.request.onSocket(socket) - return - } - } - socket.destroy() - self.removeSocket(socket) - }) -} -util.inherits(TunnelingAgent, events.EventEmitter) - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { - var self = this - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: host, port: port, request: req}) - return - } - - // If we are under maxSockets create a new one. - self.createSocket({host: host, port: port, request: req}, function(socket) { - socket.on('free', onFree) - socket.on('close', onCloseOrRemove) - socket.on('agentRemove', onCloseOrRemove) - req.onSocket(socket) - - function onFree() { - self.emit('free', socket, host, port) - } - - function onCloseOrRemove(err) { - self.removeSocket() - socket.removeListener('free', onFree) - socket.removeListener('close', onCloseOrRemove) - socket.removeListener('agentRemove', onCloseOrRemove) - } - }) -} - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this - var placeholder = {} - self.sockets.push(placeholder) - - var connectOptions = mergeOptions({}, self.proxyOptions, - { method: 'CONNECT' - , path: options.host + ':' + options.port - , agent: false - } - ) - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {} - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64') - } - - debug('making CONNECT request') - var connectReq = self.request(connectOptions) - connectReq.useChunkedEncodingByDefault = false // for v0.6 - connectReq.once('response', onResponse) // for v0.6 - connectReq.once('upgrade', onUpgrade) // for v0.6 - connectReq.once('connect', onConnect) // for v0.7 or later - connectReq.once('error', onError) - connectReq.end() - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head) - }) - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners() - socket.removeAllListeners() - - if (res.statusCode === 200) { - assert.equal(head.length, 0) - debug('tunneling connection has established') - self.sockets[self.sockets.indexOf(placeholder)] = socket - cb(socket) - } else { - debug('tunneling socket could not be established, statusCode=%d', res.statusCode) - var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } - } - - function onError(cause) { - connectReq.removeAllListeners() - - debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) - var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } -} - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) return - - this.sockets.splice(pos, 1) - - var pending = this.requests.shift() - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket) - }) - } -} - -function createSecureSocket(options, cb) { - var self = this - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, - { servername: options.host - , socket: socket - } - )) - cb(secureSocket) - }) -} - - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i] - if (typeof overrides === 'object') { - var keys = Object.keys(overrides) - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j] - if (overrides[k] !== undefined) { - target[k] = overrides[k] - } - } - } - } - return target -} - - -var debug -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments) - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0] - } else { - args.unshift('TUNNEL:') - } - console.error.apply(console, args) - } -} else { - debug = function() {} -} -exports.debug = debug // for test diff --git a/api/node_modules/request/node_modules/tunnel-agent/package.json b/api/node_modules/request/node_modules/tunnel-agent/package.json deleted file mode 100644 index 9b14d25863d..00000000000 --- a/api/node_modules/request/node_modules/tunnel-agent/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "tunnel-agent", - "description": "HTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/tunnel-agent" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "tunnel-agent\n============\n\nHTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/tunnel-agent/issues" - }, - "_id": "tunnel-agent@0.3.0", - "_from": "tunnel-agent@~0.3.0" -} diff --git a/api/node_modules/request/oauth.js b/api/node_modules/request/oauth.js deleted file mode 100644 index e35bfa67075..00000000000 --- a/api/node_modules/request/oauth.js +++ /dev/null @@ -1,43 +0,0 @@ -var crypto = require('crypto') - , qs = require('querystring') - ; - -function sha1 (key, body) { - return crypto.createHmac('sha1', key).update(body).digest('base64') -} - -function rfc3986 (str) { - return encodeURIComponent(str) - .replace(/!/g,'%21') - .replace(/\*/g,'%2A') - .replace(/\(/g,'%28') - .replace(/\)/g,'%29') - .replace(/'/g,'%27') - ; -} - -function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { - // adapted from https://dev.twitter.com/docs/auth/oauth and - // https://dev.twitter.com/docs/auth/creating-signature - - var querystring = Object.keys(params).sort().map(function(key){ - // big WTF here with the escape + encoding but it's what twitter wants - return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key])) - }).join('%26') - - var base = [ - httpMethod ? httpMethod.toUpperCase() : 'GET', - rfc3986(base_uri), - querystring - ].join('&') - - var key = [ - consumer_secret, - token_secret || '' - ].map(rfc3986).join('&') - - return sha1(key, base) -} - -exports.hmacsign = hmacsign -exports.rfc3986 = rfc3986 diff --git a/api/node_modules/request/package.json b/api/node_modules/request/package.json deleted file mode 100644 index c6383dd4d03..00000000000 --- a/api/node_modules/request/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "request", - "description": "Simplified HTTP request client.", - "tags": [ - "http", - "simple", - "util", - "utility" - ], - "version": "2.21.0", - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com" - }, - "repository": { - "type": "git", - "url": "http://github.com/mikeal/request.git" - }, - "bugs": { - "url": "http://github.com/mikeal/request/issues" - }, - "engines": [ - "node >= 0.8.0" - ], - "main": "index.js", - "dependencies": { - "qs": "~0.6.0", - "json-stringify-safe": "~4.0.0", - "forever-agent": "~0.5.0", - "tunnel-agent": "~0.3.0", - "http-signature": "~0.9.11", - "hawk": "~0.13.0", - "aws-sign": "~0.3.0", - "oauth-sign": "~0.3.0", - "cookie-jar": "~0.3.0", - "node-uuid": "~1.4.0", - "mime": "~1.2.9", - "form-data": "0.0.8" - }, - "scripts": { - "test": "node tests/run.js" - }, - "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n
\n  npm install request\n
\n\nOr from source:\n\n
\n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n
\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## Forms\n\n`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.\n\nUrl encoded forms are simple\n\n```javascript\nrequest.post('http://service.com/upload', {form:{key:'value'}})\n// or\nrequest.post('http://service.com/upload').form({key:'value'})\n```\n\nFor `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.\n\n```javascript\nvar r = request.post('http://service.com/upload')\nvar form = r.form()\nform.append('my_field', 'my_value')\nform.append('my_buffer', new Buffer([1, 2, 3]))\nform.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))\nform.append('remote_file', request('http://google.com/doodle.png'))\n```\n\n## HTTP Authentication\n\n```javascript\nrequest.auth('username', 'password', false).get('http://some.server.com/');\n// or\nrequest.get('http://some.server.com/', {\n 'auth': {\n 'user': 'username',\n 'pass': 'password',\n 'sendImmediately': false\n }\n});\n```\n\nIf passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`.\n\n`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method).\n\nDigest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail).\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Ideally, you would take the body in the response\n // and construct a URL that a user clicks on (like a sign in button).\n // The verifier is only available in the response after a user has \n // verified with twitter that they are authorizing your app.\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: access_token.oauth_verifier\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string.\n* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.\n* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example).\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)\n* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options.\n* `localAddress` - Local interface to bind for network connections.\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.patch\n\nSame as request() but defaults to `method: \"PATCH\"`.\n\n```javascript\nrequest.patch(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", - "readmeFilename": "README.md", - "_id": "request@2.21.0", - "dist": { - "shasum": "4f663d654e7b80af10a0c4b7900f9d3f83f350e8" - }, - "_from": "request@2.21.0", - "_resolved": "https://registry.npmjs.org/request/-/request-2.21.0.tgz" -} diff --git a/api/node_modules/request/tests/googledoodle.jpg b/api/node_modules/request/tests/googledoodle.jpg deleted file mode 100644 index f80c9c52d3c..00000000000 Binary files a/api/node_modules/request/tests/googledoodle.jpg and /dev/null differ diff --git a/api/node_modules/request/tests/googledoodle.png b/api/node_modules/request/tests/googledoodle.png deleted file mode 100644 index f80c9c52d3c..00000000000 Binary files a/api/node_modules/request/tests/googledoodle.png and /dev/null differ diff --git a/api/node_modules/request/tests/run.js b/api/node_modules/request/tests/run.js deleted file mode 100644 index e717f02a31b..00000000000 --- a/api/node_modules/request/tests/run.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn - , exitCode = 0 - , timeout = 10000 - , fs = require('fs') - ; - -fs.readdir(__dirname, function (e, files) { - if (e) throw e - - var tests = files.filter(function (f) {return f.slice(0, 'test-'.length) === 'test-'}) - - var next = function () { - if (tests.length === 0) process.exit(exitCode); - - var file = tests.shift() - console.log(file) - var proc = spawn('node', [ 'tests/' + file ]) - - var killed = false - var t = setTimeout(function () { - proc.kill() - exitCode += 1 - console.error(file + ' timeout') - killed = true - }, timeout) - - proc.stdout.pipe(process.stdout) - proc.stderr.pipe(process.stderr) - proc.on('exit', function (code) { - if (code && !killed) console.error(file + ' failed') - exitCode += code || 0 - clearTimeout(t) - next() - }) - } - next() - -}) - - diff --git a/api/node_modules/request/tests/server.js b/api/node_modules/request/tests/server.js deleted file mode 100644 index b6eacbadc05..00000000000 --- a/api/node_modules/request/tests/server.js +++ /dev/null @@ -1,90 +0,0 @@ -var fs = require('fs') - , http = require('http') - , path = require('path') - , https = require('https') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - ; - -exports.createServer = function (port) { - port = port || 6767 - var s = http.createServer(function (req, resp) { - s.emit(req.url, req, resp); - }) - s.port = port - s.url = 'http://localhost:'+port - return s; -} - -exports.createSSLServer = function(port, opts) { - port = port || 16767 - - var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') - , 'cert': path.join(__dirname, 'ssl', 'test.crt') - } - if (opts) { - for (var i in opts) options[i] = opts[i] - } - - for (var i in options) { - options[i] = fs.readFileSync(options[i]) - } - - var s = https.createServer(options, function (req, resp) { - s.emit(req.url, req, resp); - }) - s.port = port - s.url = 'https://localhost:'+port - return s; -} - -exports.createPostStream = function (text) { - var postStream = new stream.Stream(); - postStream.writeable = true; - postStream.readable = true; - setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0); - return postStream; -} -exports.createPostValidator = function (text, reqContentType) { - var l = function (req, resp) { - var r = ''; - req.on('data', function (chunk) {r += chunk}) - req.on('end', function () { - if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) { - var boundary = req.headers['content-type'].split('boundary=')[1]; - text = text.replace(/__BOUNDARY__/g, boundary); - } - if (r !== text) console.log(r, text); - assert.equal(r, text) - if (reqContentType) { - assert.ok(req.headers['content-type']) - assert.ok(~req.headers['content-type'].indexOf(reqContentType)) - } - resp.writeHead(200, {'content-type':'text/plain'}) - resp.write('OK') - resp.end() - }) - } - return l; -} -exports.createGetResponse = function (text, contentType) { - var l = function (req, resp) { - contentType = contentType || 'text/plain' - resp.writeHead(200, {'content-type':contentType}) - resp.write(text) - resp.end() - } - return l; -} -exports.createChunkResponse = function (chunks, contentType) { - var l = function (req, resp) { - contentType = contentType || 'text/plain' - resp.writeHead(200, {'content-type':contentType}) - chunks.forEach(function (chunk) { - resp.write(chunk) - }) - resp.end() - } - return l; -} diff --git a/api/node_modules/request/tests/squid.conf b/api/node_modules/request/tests/squid.conf deleted file mode 100644 index 0d4a3b6fe7a..00000000000 --- a/api/node_modules/request/tests/squid.conf +++ /dev/null @@ -1,77 +0,0 @@ -# -# Recommended minimum configuration: -# -acl manager proto cache_object -acl localhost src 127.0.0.1/32 ::1 -acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 - -# Example rule allowing access from your local networks. -# Adapt to list your (internal) IP networks from where browsing -# should be allowed -acl localnet src 10.0.0.0/8 # RFC1918 possible internal network -acl localnet src 172.16.0.0/12 # RFC1918 possible internal network -acl localnet src 192.168.0.0/16 # RFC1918 possible internal network -acl localnet src fc00::/7 # RFC 4193 local private network range -acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines - -acl SSL_ports port 443 -acl Safe_ports port 80 # http -acl Safe_ports port 21 # ftp -acl Safe_ports port 443 # https -acl Safe_ports port 70 # gopher -acl Safe_ports port 210 # wais -acl Safe_ports port 1025-65535 # unregistered ports -acl Safe_ports port 280 # http-mgmt -acl Safe_ports port 488 # gss-http -acl Safe_ports port 591 # filemaker -acl Safe_ports port 777 # multiling http -acl CONNECT method CONNECT - -# -# Recommended minimum Access Permission configuration: -# -# Only allow cachemgr access from localhost -http_access allow manager localhost -http_access deny manager - -# Deny requests to certain unsafe ports -http_access deny !Safe_ports - -# Deny CONNECT to other than secure SSL ports -#http_access deny CONNECT !SSL_ports - -# We strongly recommend the following be uncommented to protect innocent -# web applications running on the proxy server who think the only -# one who can access services on "localhost" is a local user -#http_access deny to_localhost - -# -# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS -# - -# Example rule allowing access from your local networks. -# Adapt localnet in the ACL section to list your (internal) IP networks -# from where browsing should be allowed -http_access allow localnet -http_access allow localhost - -# And finally deny all other access to this proxy -http_access deny all - -# Squid normally listens to port 3128 -http_port 3128 - -# We recommend you to use at least the following line. -hierarchy_stoplist cgi-bin ? - -# Uncomment and adjust the following to add a disk cache directory. -#cache_dir ufs /usr/local/var/cache 100 16 256 - -# Leave coredumps in the first cache dir -coredump_dir /usr/local/var/cache - -# Add any of your own refresh_pattern entries above these. -refresh_pattern ^ftp: 1440 20% 10080 -refresh_pattern ^gopher: 1440 0% 1440 -refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 -refresh_pattern . 0 20% 4320 diff --git a/api/node_modules/request/tests/ssl/ca/ca.cnf b/api/node_modules/request/tests/ssl/ca/ca.cnf deleted file mode 100644 index 425a889156b..00000000000 --- a/api/node_modules/request/tests/ssl/ca/ca.cnf +++ /dev/null @@ -1,20 +0,0 @@ -[ req ] -default_bits = 1024 -days = 3650 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no -output_password = password - -[ req_distinguished_name ] -C = US -ST = CA -L = Oakland -O = request -OU = request Certificate Authority -CN = requestCA -emailAddress = mikeal@mikealrogers.com - -[ req_attributes ] -challengePassword = password challenge - diff --git a/api/node_modules/request/tests/ssl/ca/ca.crt b/api/node_modules/request/tests/ssl/ca/ca.crt deleted file mode 100644 index b4524e44baa..00000000000 --- a/api/node_modules/request/tests/ssl/ca/ca.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 -ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG -A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n -ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT -B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl -YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4 -5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ -5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD -xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB -ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm -D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo -88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj ------END CERTIFICATE----- diff --git a/api/node_modules/request/tests/ssl/ca/ca.csr b/api/node_modules/request/tests/ssl/ca/ca.csr deleted file mode 100644 index e48c56eefee..00000000000 --- a/api/node_modules/request/tests/ssl/ca/ca.csr +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE -BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD -ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG -SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0 -deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br -44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB -AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3 -DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj -bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia -SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X ------END CERTIFICATE REQUEST----- diff --git a/api/node_modules/request/tests/ssl/ca/ca.key b/api/node_modules/request/tests/ssl/ca/ca.key deleted file mode 100644 index a53e7f75d66..00000000000 --- a/api/node_modules/request/tests/ssl/ca/ca.key +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,C8B5887048377F02 - -nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q -nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+ -GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH -gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38 -VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3 -/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb -4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U -gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR -Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh -FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf -dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC -uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb -EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w== ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/request/tests/ssl/ca/ca.srl b/api/node_modules/request/tests/ssl/ca/ca.srl deleted file mode 100644 index 17128db3ac4..00000000000 --- a/api/node_modules/request/tests/ssl/ca/ca.srl +++ /dev/null @@ -1 +0,0 @@ -ADF62016AA40C9C3 diff --git a/api/node_modules/request/tests/ssl/ca/server.cnf b/api/node_modules/request/tests/ssl/ca/server.cnf deleted file mode 100644 index cd1fd1e396b..00000000000 --- a/api/node_modules/request/tests/ssl/ca/server.cnf +++ /dev/null @@ -1,19 +0,0 @@ -[ req ] -default_bits = 1024 -days = 3650 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no - -[ req_distinguished_name ] -C = US -ST = CA -L = Oakland -O = request -OU = testing -CN = testing.request.mikealrogers.com -emailAddress = mikeal@mikealrogers.com - -[ req_attributes ] -challengePassword = password challenge - diff --git a/api/node_modules/request/tests/ssl/ca/server.crt b/api/node_modules/request/tests/ssl/ca/server.crt deleted file mode 100644 index efe96cefc3a..00000000000 --- a/api/node_modules/request/tests/ssl/ca/server.crt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 -ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG -A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n -ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT -B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx -dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr -ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM -20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh -DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj -7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB -kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC -yapjN3RxZbInGhWR+jA= ------END CERTIFICATE----- diff --git a/api/node_modules/request/tests/ssl/ca/server.csr b/api/node_modules/request/tests/ssl/ca/server.csr deleted file mode 100644 index a8e7595a561..00000000000 --- a/api/node_modules/request/tests/ssl/ca/server.csr +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE -BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp -MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq -hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB -BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg -cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU -ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw -7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A -HidVJ/3u ------END CERTIFICATE REQUEST----- diff --git a/api/node_modules/request/tests/ssl/ca/server.js b/api/node_modules/request/tests/ssl/ca/server.js deleted file mode 100644 index 05e21c1162c..00000000000 --- a/api/node_modules/request/tests/ssl/ca/server.js +++ /dev/null @@ -1,28 +0,0 @@ -var fs = require("fs") -var https = require("https") -var options = { key: fs.readFileSync("./server.key") - , cert: fs.readFileSync("./server.crt") } - -var server = https.createServer(options, function (req, res) { - res.writeHead(200) - res.end() - server.close() -}) -server.listen(1337) - -var ca = fs.readFileSync("./ca.crt") -var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca }) - -https.request({ host: "localhost" - , method: "HEAD" - , port: 1337 - , headers: { host: "testing.request.mikealrogers.com" } - , agent: agent - , ca: [ ca ] - , path: "/" }, function (res) { - if (res.client.authorized) { - console.log("node test: OK") - } else { - throw new Error(res.client.authorizationError) - } -}).end() diff --git a/api/node_modules/request/tests/ssl/ca/server.key b/api/node_modules/request/tests/ssl/ca/server.key deleted file mode 100644 index 72d86984f18..00000000000 --- a/api/node_modules/request/tests/ssl/ca/server.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg -cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB -iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW -gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0 -JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ -rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ -0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw== ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/request/tests/ssl/npm-ca.crt b/api/node_modules/request/tests/ssl/npm-ca.crt deleted file mode 100644 index fde2fe933d8..00000000000 --- a/api/node_modules/request/tests/ssl/npm-ca.crt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x -IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w -bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y -MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV -BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj -YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA -aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE -OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz -Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl -y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC -l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv -yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl -ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op ------END CERTIFICATE----- diff --git a/api/node_modules/request/tests/ssl/test.crt b/api/node_modules/request/tests/ssl/test.crt deleted file mode 100644 index b357f8641f3..00000000000 --- a/api/node_modules/request/tests/ssl/test.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU -SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo -ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx -MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV -BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz -dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto -wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj -eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC -AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV -l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4 -L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE -c7U8F6MWLQ== ------END CERTIFICATE----- diff --git a/api/node_modules/request/tests/ssl/test.key b/api/node_modules/request/tests/ssl/test.key deleted file mode 100644 index b85810dda8b..00000000000 --- a/api/node_modules/request/tests/ssl/test.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt -NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE -mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB -AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt -Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ -fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb -rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6 -V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF -+WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb -G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf -Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ -fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w -kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w== ------END RSA PRIVATE KEY----- diff --git a/api/node_modules/request/tests/test-basic-auth.js b/api/node_modules/request/tests/test-basic-auth.js deleted file mode 100644 index 3f4804883f7..00000000000 --- a/api/node_modules/request/tests/test-basic-auth.js +++ /dev/null @@ -1,143 +0,0 @@ -var assert = require('assert') - , http = require('http') - , request = require('../index') - ; - -var numBasicRequests = 0; - -var basicServer = http.createServer(function (req, res) { - console.error('Basic auth server: ', req.method, req.url); - numBasicRequests++; - - var ok; - - if (req.headers.authorization) { - if (req.headers.authorization == 'Basic ' + new Buffer('test:testing2').toString('base64')) { - ok = true; - } else if ( req.headers.authorization == 'Basic ' + new Buffer(':apassword').toString('base64')) { - ok = true; - } else { - // Bad auth header, don't send back WWW-Authenticate header - ok = false; - } - } else { - // No auth header, send back WWW-Authenticate header - ok = false; - res.setHeader('www-authenticate', 'Basic realm="Private"'); - } - - if (req.url == '/post/') { - var expectedContent = 'data_key=data_value'; - req.on('data', function(data) { - assert.equal(data, expectedContent); - console.log('received request data: ' + data); - }); - assert.equal(req.method, 'POST'); - assert.equal(req.headers['content-length'], '' + expectedContent.length); - assert.equal(req.headers['content-type'], 'application/x-www-form-urlencoded; charset=utf-8'); - } - - if (ok) { - console.log('request ok'); - res.end('ok'); - } else { - console.log('status=401'); - res.statusCode = 401; - res.end('401'); - } -}); - -basicServer.listen(6767); - -var tests = [ - function(next) { - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing2', - 'sendImmediately': false - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 2); - next(); - }); - }, - - function(next) { - // If we don't set sendImmediately = false, request will send basic auth - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test2/', - 'auth': { - 'user': 'test', - 'pass': 'testing2' - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 3); - next(); - }); - }, - - function(next) { - request({ - 'method': 'GET', - 'uri': 'http://test:testing2@localhost:6767/test2/' - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 4); - next(); - }); - }, - - function(next) { - request({ - 'method': 'POST', - 'form': { 'data_key': 'data_value' }, - 'uri': 'http://localhost:6767/post/', - 'auth': { - 'user': 'test', - 'pass': 'testing2', - 'sendImmediately': false - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 6); - next(); - }); - }, - - function(next) { - assert.doesNotThrow( function() { - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/allow_empty_user/', - 'auth': { - 'user': '', - 'pass': 'apassword', - 'sendImmediately': false - } - }, function(error, res, body ) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 8); - next(); - }); - }) - } -]; - -function runTest(i) { - if (i < tests.length) { - tests[i](function() { - runTest(i + 1); - }); - } else { - console.log('All tests passed'); - basicServer.close(); - } -} - -runTest(0); diff --git a/api/node_modules/request/tests/test-body.js b/api/node_modules/request/tests/test-body.js deleted file mode 100644 index 186de123f6f..00000000000 --- a/api/node_modules/request/tests/test-body.js +++ /dev/null @@ -1,122 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetBuffer : - { resp : server.createGetResponse(new Buffer("TESTING!")) - , encoding: null - , expectBody: new Buffer("TESTING!") - } - , testGetEncoding : - { resp : server.createGetResponse(new Buffer('efa3bfcea9e29883', 'hex')) - , encoding: 'hex' - , expectBody: "efa3bfcea9e29883" - } - , testGetUTF8: - { resp: server.createGetResponse(new Buffer([0xEF, 0xBB, 0xBF, 226, 152, 131])) - , encoding: "utf8" - , expectBody: "☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - , testPutMultipartPreambleCRLF : - { resp: server.createPostValidator( - '\r\n--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , preambleCRLF: true - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) - diff --git a/api/node_modules/request/tests/test-cookie.js b/api/node_modules/request/tests/test-cookie.js deleted file mode 100644 index 6c6a7a7798c..00000000000 --- a/api/node_modules/request/tests/test-cookie.js +++ /dev/null @@ -1,29 +0,0 @@ -var Cookie = require('../vendor/cookie') - , assert = require('assert'); - -var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; -var cookie = new Cookie(str); - -// test .toString() -assert.equal(cookie.toString(), str); - -// test .path -assert.equal(cookie.path, '/'); - -// test .httpOnly -assert.equal(cookie.httpOnly, true); - -// test .name -assert.equal(cookie.name, 'Sid'); - -// test .value -assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); - -// test .expires -assert.equal(cookie.expires instanceof Date, true); - -// test .path default -var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); -assert.equal(cookie.path, '/bar'); - -console.log('All tests passed'); diff --git a/api/node_modules/request/tests/test-cookiejar.js b/api/node_modules/request/tests/test-cookiejar.js deleted file mode 100644 index 76fcd716122..00000000000 --- a/api/node_modules/request/tests/test-cookiejar.js +++ /dev/null @@ -1,90 +0,0 @@ -var Cookie = require('../vendor/cookie') - , Jar = require('../vendor/cookie/jar') - , assert = require('assert'); - -function expires(ms) { - return new Date(Date.now() + ms).toUTCString(); -} - -// test .get() expiration -(function() { - var jar = new Jar; - var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); - jar.add(cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 0); - }, 1000); - }, 5); -})(); - -// test .get() path support -(function() { - var jar = new Jar; - var a = new Cookie('sid=1234; path=/'); - var b = new Cookie('sid=1111; path=/foo/bar'); - var c = new Cookie('sid=2222; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - - // should remove the duplicates - assert.equal(jar.cookies.length, 2); - - // same name, same path, latter prevails - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], c); - - // same name, diff path, path specifity prevails, latter prevails - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], a); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=3333; path=/foo/bar'); - var c = new Cookie('pid=3333; path=/foo/bar'); - var d = new Cookie('sid=2222; path=/foo/'); - var e = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - jar.add(d); - jar.add(e); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 2); - assert.equal(cookies[0], b); - assert.equal(cookies[1], c); - - var cookies = jar.get({ url: 'http://foo.com/foo/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], d); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], e); -})(); - -setTimeout(function() { - console.log('All tests passed'); -}, 1200); diff --git a/api/node_modules/request/tests/test-defaults.js b/api/node_modules/request/tests/test-defaults.js deleted file mode 100644 index f6c40246020..00000000000 --- a/api/node_modules/request/tests/test-defaults.js +++ /dev/null @@ -1,129 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -s.listen(s.port, function () { - var counter = 0; - s.on('/get', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'GET') - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end('TESTING!'); - }); - - // test get(string, function) - request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){ - if (e) throw e; - assert.deepEqual("TESTING!", b); - counter += 1; - }); - - s.on('/post', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], null); - assert.equal(req.method, 'POST') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) - request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/patch', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], null); - assert.equal(req.method, 'PATCH') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) - request.defaults({headers:{foo:"bar"}}).patch(s.url + '/patch', {json: true}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/post-body', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], 'application/json'); - assert.equal(req.method, 'POST') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) with body - request.defaults({headers:{foo:"bar"}}).post(s.url + '/post-body', {json: true, body:{bar:"baz"}}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/del', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'DELETE') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test .del(string, function) - request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/head', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'HEAD') - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end(); - }); - - // test head.(object, function) - request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){ - if (e) throw e; - counter += 1; - }); - - s.on('/get_custom', function(req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers.x, 'y'); - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end(); - }); - - // test custom request handler function - var defaultRequest = request.defaults({ - headers:{foo:"bar"} - , body: 'TESTING!' - }, function(uri, options, callback) { - var params = request.initParams(uri, options, callback); - options = params.options; - options.headers.x = 'y'; - - return request(params.uri, params.options, params.callback); - }); - - var msg = 'defaults test failed. head request should throw earlier'; - assert.throws(function() { - defaultRequest.head(s.url + '/get_custom', function(e, r, b) { - throw new Error(msg); - }); - counter+=1; - }, msg); - - defaultRequest.get(s.url + '/get_custom', function(e, r, b) { - if(e) throw e; - counter += 1; - console.log(counter.toString() + " tests passed."); - s.close(); - }); -}) diff --git a/api/node_modules/request/tests/test-digest-auth.js b/api/node_modules/request/tests/test-digest-auth.js deleted file mode 100644 index 5f2d6eb7dd0..00000000000 --- a/api/node_modules/request/tests/test-digest-auth.js +++ /dev/null @@ -1,69 +0,0 @@ -var assert = require('assert') - , http = require('http') - , request = require('../index') - ; - -// Test digest auth -// Using header values captured from interaction with Apache - -var numDigestRequests = 0; - -var digestServer = http.createServer(function (req, res) { - console.error('Digest auth server: ', req.method, req.url); - numDigestRequests++; - - var ok; - - if (req.headers.authorization) { - if (req.headers.authorization == 'Digest username="test", realm="Private", nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93", uri="/test/", qop="auth", response="54753ce37c10cb20b09b769f0bed730e", nc="1", cnonce=""') { - ok = true; - } else { - // Bad auth header, don't send back WWW-Authenticate header - ok = false; - } - } else { - // No auth header, send back WWW-Authenticate header - ok = false; - res.setHeader('www-authenticate', 'Digest realm="Private", nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93", algorithm=MD5, qop="auth"'); - } - - if (ok) { - console.log('request ok'); - res.end('ok'); - } else { - console.log('status=401'); - res.statusCode = 401; - res.end('401'); - } -}); - -digestServer.listen(6767); - -request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing', - 'sendImmediately': false - } -}, function(error, response, body) { - assert.equal(response.statusCode, 200); - assert.equal(numDigestRequests, 2); - - // If we don't set sendImmediately = false, request will send basic auth - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing' - } - }, function(error, response, body) { - assert.equal(response.statusCode, 401); - assert.equal(numDigestRequests, 3); - - console.log('All tests passed'); - digestServer.close(); - }); -}); diff --git a/api/node_modules/request/tests/test-emptyBody.js b/api/node_modules/request/tests/test-emptyBody.js deleted file mode 100644 index 338c92e5e6b..00000000000 --- a/api/node_modules/request/tests/test-emptyBody.js +++ /dev/null @@ -1,20 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200 - resp.end('') -}).listen(8080, function () { - var r = request('http://localhost:8080', function (e, resp, body) { - assert.equal(resp.statusCode, 200) - assert.equal(body, "") - - var r2 = request({ url: 'http://localhost:8080', json: {} }, function (e, resp, body) { - assert.equal(resp.statusCode, 200) - assert.equal(body, undefined) - s.close() - }); - }) -}) diff --git a/api/node_modules/request/tests/test-errors.js b/api/node_modules/request/tests/test-errors.js deleted file mode 100644 index 4df1302a095..00000000000 --- a/api/node_modules/request/tests/test-errors.js +++ /dev/null @@ -1,37 +0,0 @@ -var server = require('./server') - , events = require('events') - , assert = require('assert') - , request = require('../index') - ; - -var local = 'http://localhost:8888/asdf' - -try { - request({uri:local, body:{}}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Argument error, options.body.') -} - -try { - request({uri:local, multipart: 'foo'}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Argument error, options.multipart.') -} - -try { - request({uri:local, multipart: [{}]}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Body attribute missing in multipart.') -} - -try { - request(local, {multipart: [{}]}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Body attribute missing in multipart.') -} - -console.log("All tests passed.") diff --git a/api/node_modules/request/tests/test-follow-all-303.js b/api/node_modules/request/tests/test-follow-all-303.js deleted file mode 100644 index 956e386d14b..00000000000 --- a/api/node_modules/request/tests/test-follow-all-303.js +++ /dev/null @@ -1,30 +0,0 @@ -var request = require('../index'); -var http = require('http'); -var requests = 0; -var assert = require('assert'); - -var server = http.createServer(function (req, res) { - console.error(req.method, req.url); - requests ++; - - if (req.method === 'POST') { - console.error('send 303'); - res.setHeader('location', req.url); - res.statusCode = 303; - res.end('try again, i guess\n'); - } else { - console.error('send 200') - res.end('ok: ' + requests); - } -}); -server.listen(6767); - -request.post({ url: 'http://localhost:6767/foo', - followAllRedirects: true, - form: { foo: 'bar' } }, function (er, req, body) { - if (er) throw er; - assert.equal(body, 'ok: 2'); - assert.equal(requests, 2); - console.error('ok - ' + process.version); - server.close(); -}); diff --git a/api/node_modules/request/tests/test-follow-all.js b/api/node_modules/request/tests/test-follow-all.js deleted file mode 100644 index 035d6326fa4..00000000000 --- a/api/node_modules/request/tests/test-follow-all.js +++ /dev/null @@ -1,35 +0,0 @@ -var request = require('../index'); -var http = require('http'); -var requests = 0; -var assert = require('assert'); - -var server = http.createServer(function (req, res) { - requests ++; - - // redirect everything 3 times, no matter what. - var c = req.headers.cookie; - - if (!c) c = 0; - else c = +c.split('=')[1] || 0; - - if (c > 3) { - res.end('ok: '+requests); - return; - } - - res.setHeader('set-cookie', 'c=' + (c + 1)); - res.setHeader('location', req.url); - res.statusCode = 302; - res.end('try again, i guess\n'); -}); -server.listen(6767); - -request.post({ url: 'http://localhost:6767/foo', - followAllRedirects: true, - form: { foo: 'bar' } }, function (er, req, body) { - if (er) throw er; - assert.equal(body, 'ok: 5'); - assert.equal(requests, 5); - console.error('ok - ' + process.version); - server.close(); -}); diff --git a/api/node_modules/request/tests/test-form.js b/api/node_modules/request/tests/test-form.js deleted file mode 100644 index 91b9230d42d..00000000000 --- a/api/node_modules/request/tests/test-form.js +++ /dev/null @@ -1,79 +0,0 @@ -var assert = require('assert') -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('../index'); -var fs = require('fs'); - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: new Buffer([1, 2, 3])}, - {name: 'my_file', value: fs.createReadStream(__dirname + '/unicycle.jpg')}, - {name: 'remote_file', value: request(remoteFile) } -]; - -var server = http.createServer(function(req, res) { - - // temp workaround - var data = ''; - req.setEncoding('utf8'); - - req.on('data', function(d) { - data += d; - }); - - req.on('end', function() { - // check for the fields' traces - - // 1st field : my_field - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf(field.value) != -1 ); - - // 2nd field : my_buffer - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf(field.value) != -1 ); - - // 3rd field : my_file - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 ); - // check for unicycle.jpg traces - assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 ); - assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 ); - - // 4th field : remote_file - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 ); - // check for http://nodejs.org/images/logo.png traces - assert.ok( data.indexOf('ImageReady') != -1 ); - assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 ); - - res.writeHead(200); - res.end('done'); - - }); - - -}); - -server.listen(8080, function() { - - var req = request.post('http://localhost:8080/upload', function () { - server.close(); - }) - var form = req.form() - - FIELDS.forEach(function(field) { - form.append(field.name, field.value); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/api/node_modules/request/tests/test-hawk.js b/api/node_modules/request/tests/test-hawk.js deleted file mode 100644 index 84546258059..00000000000 --- a/api/node_modules/request/tests/test-hawk.js +++ /dev/null @@ -1,33 +0,0 @@ -var createServer = require('http').createServer - , request = require('../index') - , hawk = require('hawk') - , assert = require('assert') - ; - -var server = createServer(function (req, resp) { - - var getCred = function (id, callback) { - assert.equal(id, 'dh37fgj492je') - var credentials = - { key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn' - , algorithm: 'sha256' - , user: 'Steve' - } - return callback(null, credentials) - } - - hawk.server.authenticate(req, getCred, {}, function (err, credentials, attributes) { - resp.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' }) - resp.end(!err ? 'Hello ' + credentials.user : 'Shoosh!') - }) - -}) - -server.listen(8080, function () { - var creds = {key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', algorithm: 'sha256', id:'dh37fgj492je'} - request('http://localhost:8080', {hawk:{credentials:creds}}, function (e, r, b) { - assert.equal(200, r.statusCode) - assert.equal(b, 'Hello Steve') - server.close() - }) -}) \ No newline at end of file diff --git a/api/node_modules/request/tests/test-headers.js b/api/node_modules/request/tests/test-headers.js deleted file mode 100644 index 3982b9be0e5..00000000000 --- a/api/node_modules/request/tests/test-headers.js +++ /dev/null @@ -1,52 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , Cookie = require('cookie-jar') - , Jar = Cookie.Jar - , s = server.createServer() - -s.listen(s.port, function () { - var serverUri = 'http://localhost:' + s.port - , numTests = 0 - , numOutstandingTests = 0 - - function createTest(requestObj, serverAssertFn) { - var testNumber = numTests; - numTests += 1; - numOutstandingTests += 1; - s.on('/' + testNumber, function (req, res) { - serverAssertFn(req, res); - res.writeHead(200); - res.end(); - }); - requestObj.url = serverUri + '/' + testNumber - request(requestObj, function (err, res, body) { - assert.ok(!err) - assert.equal(res.statusCode, 200) - numOutstandingTests -= 1 - if (numOutstandingTests === 0) { - console.log(numTests + ' tests passed.') - s.close() - } - }) - } - - // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified - createTest({headers: {cookie: 'foo=bar'}}, function (req, res) { - assert.ok(req.headers.cookie) - assert.equal(req.headers.cookie, 'foo=bar') - }) - - // Issue #125: headers.cookie + cookie jar - var jar = new Jar() - jar.add(new Cookie('quux=baz')); - createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) { - assert.ok(req.headers.cookie) - assert.equal(req.headers.cookie, 'foo=bar; quux=baz') - }) - - // There should be no cookie header when neither headers.cookie nor a cookie jar is specified - createTest({}, function (req, res) { - assert.ok(!req.headers.cookie) - }) -}) diff --git a/api/node_modules/request/tests/test-http-signature.js b/api/node_modules/request/tests/test-http-signature.js deleted file mode 100644 index 93004732011..00000000000 --- a/api/node_modules/request/tests/test-http-signature.js +++ /dev/null @@ -1,106 +0,0 @@ -var createServer = require('http').createServer - , request = require('../index') - , httpSignature = require('http-signature') - , assert = require('assert') - ; - -var privateKeyPEMs = {} - -privateKeyPEMs['key-1'] = - '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAzWSJl+Z9Bqv00FVL5N3+JCUoqmQPjIlya1BbeqQroNQ5yG1i\n' + - 'VbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9diDMnrzijAnYlTLOl84CK2vOxkj5b6\n' + - '8zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcuVi2lT9VjygFs1ILG4RyeX1BXUumu\n' + - 'Y8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u114wS7OQPigu6G99dpn/iPHa3zBm8\n' + - '7baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADPTdnO/SO+kvXy7fqd8atSn+HlQcx6\n' + - 'tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft2QIDAQABAoIBAG1exe3/LEBrPLfb\n' + - 'U8iRdY0lxFvHYIhDgIwohC3wUdMYb5SMurpNdEZn+7Sh/fkUVgp/GKJViu1mvh52\n' + - 'bKd2r52DwG9NQBQjVgkqY/auRYSglIPpr8PpYNSZlcneunCDGeqEY9hMmXc5Ssqs\n' + - 'PQYoEKKPN+IlDTg6PguDgAfLR4IUvt9KXVvmB/SSgV9tSeTy35LECt1Lq3ozbUgu\n' + - '30HZI3U6/7H+X22Pxxf8vzBtzkg5rRCLgv+OeNPo16xMnqbutt4TeqEkxRv5rtOo\n' + - '/A1i9khBeki0OJAFJsE82qnaSZodaRsxic59VnN8sWBwEKAt87tEu5A3K3j4XSDU\n' + - '/avZxAECgYEA+pS3DvpiQLtHlaO3nAH6MxHRrREOARXWRDe5nUQuUNpS1xq9wte6\n' + - 'DkFtba0UCvDLic08xvReTCbo9kH0y6zEy3zMpZuJlKbcWCkZf4S5miYPI0RTZtF8\n' + - 'yps6hWqzYFSiO9hMYws9k4OJLxX0x3sLK7iNZ32ujcSrkPBSiBr0gxkCgYEA0dWl\n' + - '637K41AJ/zy0FP0syq+r4eIkfqv+/t6y2aQVUBvxJYrj9ci6XHBqoxpDV8lufVYj\n' + - 'fUAfeI9/MZaWvQJRbnYLre0I6PJfLuCBIL5eflO77BGso165AF7QJZ+fwtgKv3zv\n' + - 'ZX75eudCSS/cFo0po9hlbcLMT4B82zEkgT8E2MECgYEAnz+3/wrdOmpLGiyL2dff\n' + - '3GjsqmJ2VfY8z+niSrI0BSpbD11tT9Ct67VlCBjA7hsOH6uRfpd6/kaUMzzDiFVq\n' + - 'VDAiFvV8QD6zNkwYalQ9aFvbrvwTTPrBpjl0vamMCiJ/YC0cjq1sGr2zh3sar1Ph\n' + - 'S43kP+s97dcZeelhaiJHVrECgYEAsx61q/loJ/LDFeYzs1cLTVn4V7I7hQY9fkOM\n' + - 'WM0AhInVqD6PqdfXfeFYpjJdGisQ7l0BnoGGW9vir+nkcyPvb2PFRIr6+B8tsU5j\n' + - '7BeVgjDoUfQkcrEBK5fEBtnj/ud9BUkY8oMZZBjVNLRuI7IMwZiPvMp0rcj4zAN/\n' + - 'LfUlpgECgYArBvFcBxSkNAzR3Rtteud1YDboSKluRM37Ey5plrn4BS0DD0jm++aD\n' + - '0pG2Hsik000hibw92lCkzvvBVAqF8BuAcnPlAeYfsOaa97PGEjSKEN5bJVWZ9/om\n' + - '9FV1axotRN2XWlwrhixZLEaagkREXhgQc540FS5O8IaI2Vpa80Atzg==\n' + - '-----END RSA PRIVATE KEY-----' - -var publicKeyPEMs = {} - -publicKeyPEMs['key-1'] = - '-----BEGIN PUBLIC KEY-----\n' + - 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzWSJl+Z9Bqv00FVL5N3+\n' + - 'JCUoqmQPjIlya1BbeqQroNQ5yG1iVbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9di\n' + - 'DMnrzijAnYlTLOl84CK2vOxkj5b68zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcu\n' + - 'Vi2lT9VjygFs1ILG4RyeX1BXUumuY8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u1\n' + - '14wS7OQPigu6G99dpn/iPHa3zBm87baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADP\n' + - 'TdnO/SO+kvXy7fqd8atSn+HlQcx6tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft\n' + - '2QIDAQAB\n' + - '-----END PUBLIC KEY-----' - -publicKeyPEMs['key-2'] = - '-----BEGIN PUBLIC KEY-----\n' + - 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqp04VVr9OThli9b35Omz\n' + - 'VqSfWbsoQuRrgyWsrNRn3XkFmbWw4FzZwQ42OgGMzQ84Ta4d9zGKKQyFriTiPjPf\n' + - 'xhhrsaJnDuybcpVhcr7UNKjSZ0S59tU3hpRiEz6hO+Nc/OSSLkvalG0VKrxOln7J\n' + - 'LK/h3rNS/l6wDZ5S/KqsI6CYtV2ZLpn3ahLrizvEYNY038Qcm38qMWx+VJAvZ4di\n' + - 'qqmW7RLIsLT59SWmpXdhFKnkYYGhxrk1Mwl22dBTJNY5SbriU5G3gWgzYkm8pgHr\n' + - '6CtrXch9ciJAcDJehPrKXNvNDOdUh8EW3fekNJerF1lWcwQg44/12v8sDPyfbaKB\n' + - 'dQIDAQAB\n' + - '-----END PUBLIC KEY-----' - -var server = createServer(function (req, res) { - var parsed = httpSignature.parseRequest(req) - var publicKeyPEM = publicKeyPEMs[parsed.keyId] - var verified = httpSignature.verifySignature(parsed, publicKeyPEM) - res.writeHead(verified ? 200 : 400) - res.end() -}) - -server.listen(8080, function () { - function correctKeyTest(callback) { - var options = { - httpSignature: { - keyId: 'key-1', - key: privateKeyPEMs['key-1'] - } - } - request('http://localhost:8080', options, function (e, r, b) { - assert.equal(200, r.statusCode) - callback() - }) - } - - function incorrectKeyTest(callback) { - var options = { - httpSignature: { - keyId: 'key-2', - key: privateKeyPEMs['key-1'] - } - } - request('http://localhost:8080', options, function (e, r, b) { - assert.equal(400, r.statusCode) - callback() - }) - } - - var tests = [correctKeyTest, incorrectKeyTest] - var todo = tests.length; - for(var i = 0; i < tests.length; ++i) { - tests[i](function() { - if(!--todo) { - server.close() - } - }) - } -}) diff --git a/api/node_modules/request/tests/test-httpModule.js b/api/node_modules/request/tests/test-httpModule.js deleted file mode 100644 index 2c19615f763..00000000000 --- a/api/node_modules/request/tests/test-httpModule.js +++ /dev/null @@ -1,94 +0,0 @@ -var http = require('http') - , https = require('https') - , server = require('./server') - , assert = require('assert') - , request = require('../index') - - -var faux_requests_made = {'http':0, 'https':0} -function wrap_request(name, module) { - // Just like the http or https module, but note when a request is made. - var wrapped = {} - Object.keys(module).forEach(function(key) { - var value = module[key]; - - if(key != 'request') - wrapped[key] = value; - else - wrapped[key] = function(options, callback) { - faux_requests_made[name] += 1 - return value.apply(this, arguments) - } - }) - - return wrapped; -} - - -var faux_http = wrap_request('http', http) - , faux_https = wrap_request('https', https) - , plain_server = server.createServer() - , https_server = server.createSSLServer() - - -plain_server.listen(plain_server.port, function() { - plain_server.on('/plain', function (req, res) { - res.writeHead(200) - res.end('plain') - }) - plain_server.on('/to_https', function (req, res) { - res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'}) - res.end() - }) - - https_server.listen(https_server.port, function() { - https_server.on('/https', function (req, res) { - res.writeHead(200) - res.end('https') - }) - https_server.on('/to_plain', function (req, res) { - res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'}) - res.end() - }) - - run_tests() - run_tests({}) - run_tests({'http:':faux_http}) - run_tests({'https:':faux_https}) - run_tests({'http:':faux_http, 'https:':faux_https}) - }) -}) - -function run_tests(httpModules) { - var to_https = 'http://localhost:'+plain_server.port+'/to_https' - var to_plain = 'https://localhost:'+https_server.port+'/to_plain' - - request(to_https, {'httpModules':httpModules, strictSSL:false}, function (er, res, body) { - if (er) throw er - assert.equal(body, 'https', 'Received HTTPS server body') - done() - }) - - request(to_plain, {'httpModules':httpModules, strictSSL:false}, function (er, res, body) { - if (er) throw er - assert.equal(body, 'plain', 'Received HTTPS server body') - done() - }) -} - - -var passed = 0; -function done() { - passed += 1 - var expected = 10 - - if(passed == expected) { - plain_server.close() - https_server.close() - - assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately') - assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately') - - console.log((expected+2) + ' tests passed.') - } -} diff --git a/api/node_modules/request/tests/test-https-strict.js b/api/node_modules/request/tests/test-https-strict.js deleted file mode 100644 index d49a9afcb90..00000000000 --- a/api/node_modules/request/tests/test-https-strict.js +++ /dev/null @@ -1,97 +0,0 @@ -// a test where we validate the siguature of the keys -// otherwise exactly the same as the ssl test - -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , fs = require('fs') - , path = require('path') - , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key') - , cert: path.resolve(__dirname, 'ssl/ca/server.crt') } - , s = server.createSSLServer(null, opts) - , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt') - , ca = fs.readFileSync(caFile) - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - test.strictSSL = true - test.ca = ca - test.headers = { host: 'testing.request.mikealrogers.com' } - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/api/node_modules/request/tests/test-https.js b/api/node_modules/request/tests/test-https.js deleted file mode 100644 index b6858d433be..00000000000 --- a/api/node_modules/request/tests/test-https.js +++ /dev/null @@ -1,87 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - -var s = server.createSSLServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - test.rejectUnauthorized = false - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/api/node_modules/request/tests/test-localAddress.js b/api/node_modules/request/tests/test-localAddress.js deleted file mode 100644 index 11a1bd125ca..00000000000 --- a/api/node_modules/request/tests/test-localAddress.js +++ /dev/null @@ -1,15 +0,0 @@ -var request = require('../index') - , assert = require('assert') - ; - -request.get({ - uri: 'http://www.google.com', localAddress: '1.2.3.4' // some invalid address -}, function(err, res) { - assert(!res) // asserting that no response received -}) - -request.get({ - uri: 'http://www.google.com', localAddress: '127.0.0.1' -}, function(err, res) { - assert(!res) // asserting that no response received -}) diff --git a/api/node_modules/request/tests/test-oauth.js b/api/node_modules/request/tests/test-oauth.js deleted file mode 100644 index 3269483d8f2..00000000000 --- a/api/node_modules/request/tests/test-oauth.js +++ /dev/null @@ -1,117 +0,0 @@ -var hmacsign = require('oauth-sign').hmacsign - , assert = require('assert') - , qs = require('querystring') - , request = require('../index') - ; - -function getsignature (r) { - var sign - r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) { - if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1) - }) - return decodeURIComponent(sign) -} - -// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth - -var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', - { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_timestamp: '1272323042' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") - -console.log(reqsign) -console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') -assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') - -var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', - { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , oauth_timestamp: '1272323047' - , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") - -console.log(accsign) -console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') -assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') - -var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', - { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" - , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , oauth_signature_method: "HMAC-SHA1" - , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , oauth_timestamp: "1272325550" - , oauth_version: "1.0" - , status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") - -console.log(upsign) -console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') -assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') - - -var rsign = request.post( - { url: 'https://api.twitter.com/oauth/request_token' - , oauth: - { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , consumer_key: 'GDdmIQH6jhtmLUypg82g' - , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , timestamp: '1272323042' - , version: '1.0' - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - } - }) - -setTimeout(function () { - console.log(getsignature(rsign)) - assert.equal(reqsign, getsignature(rsign)) -}) - -var raccsign = request.post( - { url: 'https://api.twitter.com/oauth/access_token' - , oauth: - { consumer_key: 'GDdmIQH6jhtmLUypg82g' - , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , signature_method: 'HMAC-SHA1' - , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , timestamp: '1272323047' - , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , version: '1.0' - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" - } - }) - -setTimeout(function () { - console.log(getsignature(raccsign)) - assert.equal(accsign, getsignature(raccsign)) -}, 1) - -var rupsign = request.post( - { url: 'http://api.twitter.com/1/statuses/update.json' - , oauth: - { consumer_key: "GDdmIQH6jhtmLUypg82g" - , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , signature_method: "HMAC-SHA1" - , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , timestamp: "1272325550" - , version: "1.0" - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA" - } - , form: {status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹'} - }) -setTimeout(function () { - console.log(getsignature(rupsign)) - assert.equal(upsign, getsignature(rupsign)) -}, 1) - - - - diff --git a/api/node_modules/request/tests/test-onelineproxy.js b/api/node_modules/request/tests/test-onelineproxy.js deleted file mode 100644 index c239f8921cf..00000000000 --- a/api/node_modules/request/tests/test-onelineproxy.js +++ /dev/null @@ -1,46 +0,0 @@ -var http = require('http') - , assert = require('assert') - , request = require('../index') - ; - -var server = http.createServer(function (req, resp) { - resp.statusCode = 200 - if (req.url === '/get') { - assert.equal(req.method, 'GET') - resp.write('content') - resp.end() - return - } - if (req.url === '/put') { - var x = '' - assert.equal(req.method, 'PUT') - req.on('data', function (chunk) { - x += chunk - }) - req.on('end', function () { - assert.equal(x, 'content') - resp.write('success') - resp.end() - }) - return - } - if (req.url === '/proxy') { - assert.equal(req.method, 'PUT') - return req.pipe(request('http://localhost:8080/put')).pipe(resp) - } - - if (req.url === '/test') { - return request('http://localhost:8080/get').pipe(request.put('http://localhost:8080/proxy')).pipe(resp) - } - throw new Error('Unknown url', req.url) -}).listen(8080, function () { - request('http://localhost:8080/test', function (e, resp, body) { - if (e) throw e - if (resp.statusCode !== 200) throw new Error('statusCode not 200 ' + resp.statusCode) - assert.equal(body, 'success') - server.close() - }) -}) - - - diff --git a/api/node_modules/request/tests/test-params.js b/api/node_modules/request/tests/test-params.js deleted file mode 100644 index a5831a14071..00000000000 --- a/api/node_modules/request/tests/test-params.js +++ /dev/null @@ -1,93 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetBuffer : - { resp : server.createGetResponse(new Buffer("TESTING!")) - , encoding: null - , expectBody: new Buffer("TESTING!") - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - //test.uri = s.url + '/' + i - request(s.url + '/' + i, test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - assert.notEqual(typeof test.callback, 'function') - console.log(1 + Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/api/node_modules/request/tests/test-piped-redirect.js b/api/node_modules/request/tests/test-piped-redirect.js deleted file mode 100644 index e295ec7fa91..00000000000 --- a/api/node_modules/request/tests/test-piped-redirect.js +++ /dev/null @@ -1,42 +0,0 @@ -var http = require('http') - , assert = require('assert') - , request = require('../index') - ; - -var portOne = 8968 - , portTwo = 8969 - ; - - -// server one -var s1 = http.createServer(function (req, resp) { - if (req.url == '/original') { - resp.writeHeader(302, {'location': '/redirected'}) - resp.end() - } else if (req.url == '/redirected') { - resp.writeHeader(200, {'content-type': 'text/plain'}) - resp.write('OK') - resp.end() - } - -}).listen(portOne); - - -// server two -var s2 = http.createServer(function (req, resp) { - var x = request('http://localhost:'+portOne+'/original') - req.pipe(x) - x.pipe(resp) - -}).listen(portTwo, function () { - var r = request('http://localhost:'+portTwo+'/original', function (err, res, body) { - assert.equal(body, 'OK') - - s1.close() - s2.close() - }); - - // it hangs, so wait a second :) - r.timeout = 1000; - -}) diff --git a/api/node_modules/request/tests/test-pipes.js b/api/node_modules/request/tests/test-pipes.js deleted file mode 100644 index 52a15cc7e85..00000000000 --- a/api/node_modules/request/tests/test-pipes.js +++ /dev/null @@ -1,216 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , fs = require('fs') - , request = require('../index') - , path = require('path') - , util = require('util') - ; - -var s = server.createServer(3453); - -function ValidationStream(str) { - this.str = str - this.buf = '' - this.on('data', function (data) { - this.buf += data - }) - this.on('end', function () { - assert.equal(this.str, this.buf) - }) - this.writable = true -} -util.inherits(ValidationStream, stream.Stream) -ValidationStream.prototype.write = function (chunk) { - this.emit('data', chunk) -} -ValidationStream.prototype.end = function (chunk) { - if (chunk) emit('data', chunk) - this.emit('end') -} - -s.listen(s.port, function () { - counter = 0; - - var check = function () { - counter = counter - 1 - if (counter === 0) { - console.log('All tests passed.') - setTimeout(function () { - process.exit(); - }, 500) - } - } - - // Test pipeing to a request object - s.once('/push', server.createPostValidator("mydata")); - - var mydata = new stream.Stream(); - mydata.readable = true - - counter++ - var r1 = request.put({url:'http://localhost:3453/push'}, function () { - check(); - }) - mydata.pipe(r1) - - mydata.emit('data', 'mydata'); - mydata.emit('end'); - - // Test pipeing to a request object with a json body - s.once('/push-json', server.createPostValidator("{\"foo\":\"bar\"}", "application/json")); - - var mybodydata = new stream.Stream(); - mybodydata.readable = true - - counter++ - var r2 = request.put({url:'http://localhost:3453/push-json',json:true}, function () { - check(); - }) - mybodydata.pipe(r2) - - mybodydata.emit('data', JSON.stringify({foo:"bar"})); - mybodydata.emit('end'); - - // Test pipeing from a request object. - s.once('/pull', server.createGetResponse("mypulldata")); - - var mypulldata = new stream.Stream(); - mypulldata.writable = true - - counter++ - request({url:'http://localhost:3453/pull'}).pipe(mypulldata) - - var d = ''; - - mypulldata.write = function (chunk) { - d += chunk; - } - mypulldata.end = function () { - assert.equal(d, 'mypulldata'); - check(); - }; - - - s.on('/cat', function (req, resp) { - if (req.method === "GET") { - resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); - resp.end('asdf') - } else if (req.method === "PUT") { - assert.equal(req.headers['content-type'], 'text/plain-test'); - assert.equal(req.headers['content-length'], 4) - var validate = ''; - - req.on('data', function (chunk) {validate += chunk}) - req.on('end', function () { - resp.writeHead(201); - resp.end(); - assert.equal(validate, 'asdf'); - check(); - }) - } - }) - s.on('/pushjs', function (req, resp) { - if (req.method === "PUT") { - assert.equal(req.headers['content-type'], 'application/javascript'); - check(); - } - }) - s.on('/catresp', function (req, resp) { - request.get('http://localhost:3453/cat').pipe(resp) - }) - s.on('/doodle', function (req, resp) { - if (req.headers['x-oneline-proxy']) { - resp.setHeader('x-oneline-proxy', 'yup') - } - resp.writeHead('200', {'content-type':'image/jpeg'}) - fs.createReadStream(path.join(__dirname, 'googledoodle.jpg')).pipe(resp) - }) - s.on('/onelineproxy', function (req, resp) { - var x = request('http://localhost:3453/doodle') - req.pipe(x) - x.pipe(resp) - }) - - counter++ - fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) - - counter++ - request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) - - counter++ - request.get('http://localhost:3453/catresp', function (e, resp, body) { - assert.equal(resp.headers['content-type'], 'text/plain-test'); - assert.equal(resp.headers['content-length'], 4) - check(); - }) - - var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.jpg')) - - counter++ - request.get('http://localhost:3453/doodle').pipe(doodleWrite) - - doodleWrite.on('close', function () { - assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')), fs.readFileSync(path.join(__dirname, 'test.jpg'))) - check() - }) - - process.on('exit', function () { - fs.unlinkSync(path.join(__dirname, 'test.jpg')) - }) - - counter++ - request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { - assert.equal(resp.headers['x-oneline-proxy'], 'yup') - check() - }) - - s.on('/afterresponse', function (req, resp) { - resp.write('d') - resp.end() - }) - - counter++ - var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { - var v = new ValidationStream('d') - afterresp.pipe(v) - v.on('end', check) - }) - - s.on('/forward1', function (req, resp) { - resp.writeHead(302, {location:'/forward2'}) - resp.end() - }) - s.on('/forward2', function (req, resp) { - resp.writeHead('200', {'content-type':'image/png'}) - resp.write('d') - resp.end() - }) - - counter++ - var validateForward = new ValidationStream('d') - validateForward.on('end', check) - request.get('http://localhost:3453/forward1').pipe(validateForward) - - // Test pipe options - s.once('/opts', server.createGetResponse('opts response')); - - var optsStream = new stream.Stream(); - optsStream.writable = true - - var optsData = ''; - optsStream.write = function (buf) { - optsData += buf; - if (optsData === 'opts response') { - setTimeout(check, 10); - } - } - - optsStream.end = function () { - assert.fail('end called') - }; - - counter++ - request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false }) -}) diff --git a/api/node_modules/request/tests/test-pool.js b/api/node_modules/request/tests/test-pool.js deleted file mode 100644 index 791ee8b9398..00000000000 --- a/api/node_modules/request/tests/test-pool.js +++ /dev/null @@ -1,16 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200; - resp.end('asdf'); -}).listen(8080, function () { - request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) { - var agent = resp.request.agent; - assert.strictEqual(typeof agent, 'boolean'); - assert.strictEqual(agent, false); - s.close(); - }); -}); \ No newline at end of file diff --git a/api/node_modules/request/tests/test-protocol-changing-redirect.js b/api/node_modules/request/tests/test-protocol-changing-redirect.js deleted file mode 100644 index 7e83a41bd90..00000000000 --- a/api/node_modules/request/tests/test-protocol-changing-redirect.js +++ /dev/null @@ -1,61 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - - -var s = server.createServer() -var ss = server.createSSLServer() -var sUrl = 'http://localhost:' + s.port -var ssUrl = 'https://localhost:' + ss.port - -s.listen(s.port, bouncy(s, ssUrl)) -ss.listen(ss.port, bouncy(ss, sUrl)) - -var hits = {} -var expect = {} -var pending = 0 -function bouncy (s, server) { return function () { - - var redirs = { a: 'b' - , b: 'c' - , c: 'd' - , d: 'e' - , e: 'f' - , f: 'g' - , g: 'h' - , h: 'end' } - - var perm = true - Object.keys(redirs).forEach(function (p) { - var t = redirs[p] - - // switch type each time - var type = perm ? 301 : 302 - perm = !perm - s.on('/' + p, function (req, res) { - res.writeHead(type, { location: server + '/' + t }) - res.end() - }) - }) - - s.on('/end', function (req, res) { - var h = req.headers['x-test-key'] - hits[h] = true - pending -- - if (pending === 0) done() - }) -}} - -for (var i = 0; i < 5; i ++) { - pending ++ - var val = 'test_' + i - expect[val] = true - request({ url: (i % 2 ? sUrl : ssUrl) + '/a' - , headers: { 'x-test-key': val } - , rejectUnauthorized: false }) -} - -function done () { - assert.deepEqual(hits, expect) - process.exit(0) -} diff --git a/api/node_modules/request/tests/test-proxy.js b/api/node_modules/request/tests/test-proxy.js deleted file mode 100644 index e183d68d172..00000000000 --- a/api/node_modules/request/tests/test-proxy.js +++ /dev/null @@ -1,39 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , fs = require('fs') - , request = require('../index') - , path = require('path') - , util = require('util') - ; - -var port = 6768 - , called = false - , proxiedHost = 'google.com' - ; - -var s = server.createServer(port) -s.listen(port, function () { - s.on('http://google.com/', function (req, res) { - called = true - assert.equal(req.headers.host, proxiedHost) - res.writeHeader(200) - res.end() - }) - request ({ - url: 'http://'+proxiedHost, - proxy: 'http://localhost:'+port - /* - //should behave as if these arguments where passed: - url: 'http://localhost:'+port, - headers: {host: proxiedHost} - //*/ - }, function (err, res, body) { - s.close() - }) -}) - -process.on('exit', function () { - assert.ok(called, 'the request must be made to the proxy server') -}) diff --git a/api/node_modules/request/tests/test-qs.js b/api/node_modules/request/tests/test-qs.js deleted file mode 100644 index 65958e6a322..00000000000 --- a/api/node_modules/request/tests/test-qs.js +++ /dev/null @@ -1,42 +0,0 @@ -var request = request = require('../index') - , assert = require('assert') - ; - - -// Test adding a querystring -var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?q=search', req1.path) -}, 1) - -// Test replacing a querystring value -var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?q=search', req2.path) -}, 1) - -// Test appending a querystring value to the ones present in the uri -var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?x=y&q=search', req3.path) -}, 1) - -// Test leaving a querystring alone -var req4 = request.get({ uri: 'http://www.google.com?x=y'}) -setTimeout(function() { - assert.equal('/?x=y', req4.path) -}, 1) - -// Test giving empty qs property -var req5 = request.get({ uri: 'http://www.google.com', qs: {}}) -setTimeout(function(){ - assert.equal('/', req5.path) -}, 1) - - -// Test modifying the qs after creating the request -var req6 = request.get({ uri: 'http://www.google.com', qs: {}}); -req6.qs({ q: "test" }); -process.nextTick(function() { - assert.equal('/?q=test', req6.path); -}); diff --git a/api/node_modules/request/tests/test-redirect.js b/api/node_modules/request/tests/test-redirect.js deleted file mode 100644 index cdd46066695..00000000000 --- a/api/node_modules/request/tests/test-redirect.js +++ /dev/null @@ -1,155 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , Cookie = require('cookie-jar') - , Jar = Cookie.Jar - ; - -var s = server.createServer() - -s.listen(s.port, function () { - var server = 'http://localhost:' + s.port; - var hits = {} - var passed = 0; - - bouncer(301, 'temp') - bouncer(302, 'perm') - bouncer(302, 'nope') - - function bouncer(code, label) { - var landing = label+'_landing'; - - s.on('/'+label, function (req, res) { - hits[label] = true; - res.writeHead(code, { - 'location':server + '/'+landing, - 'set-cookie': 'ham=eggs' - }) - res.end() - }) - - s.on('/'+landing, function (req, res) { - if (req.method !== 'GET') { // We should only accept GET redirects - console.error("Got a non-GET request to the redirect destination URL"); - res.writeHead(400); - res.end(); - return; - } - // Make sure the cookie doesn't get included twice, see #139: - // Make sure cookies are set properly after redirect - assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs'); - hits[landing] = true; - res.writeHead(200) - res.end(landing) - }) - } - - // Permanent bounce - var jar = new Jar() - jar.add(new Cookie('quux=baz')) - request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.perm, 'Original request is to /perm') - assert.ok(hits.perm_landing, 'Forward to permanent landing URL') - assert.equal(body, 'perm_landing', 'Got permanent landing content') - passed += 1 - done() - }) - - // Temporary bounce - request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - // Prevent bouncing. - request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode) - assert.ok(hits.nope, 'Original request to /nope') - assert.ok(!hits.nope_landing, 'No chasing the redirect') - assert.equal(res.statusCode, 302, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow post redirects by default - request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when post') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should follow post redirects when followAllRedirects true - request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow delete redirects by default - request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode < 301) throw new Error('Status is not a redirect.') - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow delete redirects even if followRedirect is set to true - request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should follow delete redirects when followAllRedirects true - request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - var reqs_done = 0; - function done() { - reqs_done += 1; - if(reqs_done == 9) { - console.log(passed + ' tests passed.') - s.close() - } - } -}) diff --git a/api/node_modules/request/tests/test-s3.js b/api/node_modules/request/tests/test-s3.js deleted file mode 100644 index 0f6a832b6da..00000000000 --- a/api/node_modules/request/tests/test-s3.js +++ /dev/null @@ -1,13 +0,0 @@ -var request = require('../index') - -var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', - { aws: - { key: 'AKIAI6KIQRRVMGK3WK5Q' - , secret: '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' - , bucket: 'log.curlybracecast.com' - } - }, function (e, resp, body) { - console.log(r.headers) - console.log(body) - } -) \ No newline at end of file diff --git a/api/node_modules/request/tests/test-timeout.js b/api/node_modules/request/tests/test-timeout.js deleted file mode 100644 index 70363670ff8..00000000000 --- a/api/node_modules/request/tests/test-timeout.js +++ /dev/null @@ -1,87 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); -var expectedBody = "waited"; -var remainingTests = 5; - -s.listen(s.port, function () { - // Request that waits for 200ms - s.on('/timeout', function (req, resp) { - setTimeout(function(){ - resp.writeHead(200, {'content-type':'text/plain'}) - resp.write(expectedBody) - resp.end() - }, 200); - }); - - // Scenario that should timeout - var shouldTimeout = { - url: s.url + "/timeout", - timeout:100 - } - - - request(shouldTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - - // Scenario that shouldn't timeout - var shouldntTimeout = { - url: s.url + "/timeout", - timeout:300 - } - - request(shouldntTimeout, function (err, resp, body) { - assert.equal(err, null); - assert.equal(expectedBody, body) - checkDone(); - }) - - // Scenario with no timeout set, so shouldn't timeout - var noTimeout = { - url: s.url + "/timeout" - } - - request(noTimeout, function (err, resp, body) { - assert.equal(err); - assert.equal(expectedBody, body) - checkDone(); - }) - - // Scenario with a negative timeout value, should be treated a zero or the minimum delay - var negativeTimeout = { - url: s.url + "/timeout", - timeout:-1000 - } - - request(negativeTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - // Scenario with a float timeout value, should be rounded by setTimeout anyway - var floatTimeout = { - url: s.url + "/timeout", - timeout: 100.76 - } - - request(floatTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - function checkDone() { - if(--remainingTests == 0) { - s.close(); - console.log("All tests passed."); - } - } -}) - diff --git a/api/node_modules/request/tests/test-toJSON.js b/api/node_modules/request/tests/test-toJSON.js deleted file mode 100644 index 6d5f92aaa56..00000000000 --- a/api/node_modules/request/tests/test-toJSON.js +++ /dev/null @@ -1,14 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200 - resp.end('asdf') -}).listen(8080, function () { - var r = request('http://localhost:8080', function (e, resp) { - assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200) - s.close() - }) -}) \ No newline at end of file diff --git a/api/node_modules/request/tests/test-tunnel.js b/api/node_modules/request/tests/test-tunnel.js deleted file mode 100644 index 2ee3f393ed7..00000000000 --- a/api/node_modules/request/tests/test-tunnel.js +++ /dev/null @@ -1,75 +0,0 @@ -// test that we can tunnel a https request over an http proxy -// keeping all the CA and whatnot intact. -// -// Note: this requires that squid is installed. -// If the proxy fails to start, we'll just log a warning and assume success. - -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , fs = require('fs') - , path = require('path') - , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt') - , ca = fs.readFileSync(caFile) - , child_process = require('child_process') - , sqConf = path.resolve(__dirname, 'squid.conf') - , sqArgs = ['-f', sqConf, '-N', '-d', '5'] - , proxy = 'http://localhost:3128' - , hadError = null - -var squid = child_process.spawn('squid', sqArgs); -var ready = false - -squid.stderr.on('data', function (c) { - console.error('SQUIDERR ' + c.toString().trim().split('\n') - .join('\nSQUIDERR ')) - ready = c.toString().match(/ready to serve requests|Accepting HTTP Socket connections/i) -}) - -squid.stdout.on('data', function (c) { - console.error('SQUIDOUT ' + c.toString().trim().split('\n') - .join('\nSQUIDOUT ')) -}) - -squid.on('error', function (c) { - console.error('squid: error '+c) - if (c && !ready) { - notInstalled() - return - } -}) - -squid.on('exit', function (c) { - console.error('squid: exit '+c) - if (c && !ready) { - notInstalled() - return - } - - if (c) { - hadError = hadError || new Error('Squid exited with '+c) - } - if (hadError) throw hadError -}) - -setTimeout(function F () { - if (!ready) return setTimeout(F, 100) - request({ uri: 'https://registry.npmjs.org/' - , proxy: 'http://localhost:3128' - , strictSSL: true - , ca: ca - , json: true }, function (er, body) { - hadError = er - console.log(er || typeof body) - if (!er) console.log("ok") - squid.kill('SIGKILL') - }) -}, 100) - -function notInstalled() { - console.error('squid must be installed to run this test.') - console.error('skipping this test. please install squid and run again if you need to test tunneling.') - c = null - hadError = null - process.exit(0) -} diff --git a/api/node_modules/request/tests/unicycle.jpg b/api/node_modules/request/tests/unicycle.jpg deleted file mode 100644 index 7cea4dd71dc..00000000000 Binary files a/api/node_modules/request/tests/unicycle.jpg and /dev/null differ diff --git a/api/node_modules/request/tunnel.js b/api/node_modules/request/tunnel.js deleted file mode 100644 index 3f7bbb909fd..00000000000 --- a/api/node_modules/request/tunnel.js +++ /dev/null @@ -1,227 +0,0 @@ -'use strict' - -var net = require('net') - , tls = require('tls') - , http = require('http') - , https = require('https') - , events = require('events') - , assert = require('assert') - , util = require('util') - ; - -exports.httpOverHttp = httpOverHttp -exports.httpsOverHttp = httpsOverHttp -exports.httpOverHttps = httpOverHttps -exports.httpsOverHttps = httpsOverHttps - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - return agent -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - agent.createSocket = createSecureSocket - return agent -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - return agent -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - agent.createSocket = createSecureSocket - return agent -} - - -function TunnelingAgent(options) { - var self = this - self.options = options || {} - self.proxyOptions = self.options.proxy || {} - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets - self.requests = [] - self.sockets = [] - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i] - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1) - pending.request.onSocket(socket) - return - } - } - socket.destroy() - self.removeSocket(socket) - }) -} -util.inherits(TunnelingAgent, events.EventEmitter) - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { - var self = this - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: host, port: port, request: req}) - return - } - - // If we are under maxSockets create a new one. - self.createSocket({host: host, port: port, request: req}, function(socket) { - socket.on('free', onFree) - socket.on('close', onCloseOrRemove) - socket.on('agentRemove', onCloseOrRemove) - req.onSocket(socket) - - function onFree() { - self.emit('free', socket, host, port) - } - - function onCloseOrRemove(err) { - self.removeSocket() - socket.removeListener('free', onFree) - socket.removeListener('close', onCloseOrRemove) - socket.removeListener('agentRemove', onCloseOrRemove) - } - }) -} - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this - var placeholder = {} - self.sockets.push(placeholder) - - var connectOptions = mergeOptions({}, self.proxyOptions, - { method: 'CONNECT' - , path: options.host + ':' + options.port - , agent: false - } - ) - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {} - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64') - } - - debug('making CONNECT request') - var connectReq = self.request(connectOptions) - connectReq.useChunkedEncodingByDefault = false // for v0.6 - connectReq.once('response', onResponse) // for v0.6 - connectReq.once('upgrade', onUpgrade) // for v0.6 - connectReq.once('connect', onConnect) // for v0.7 or later - connectReq.once('error', onError) - connectReq.end() - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head) - }) - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners() - socket.removeAllListeners() - - if (res.statusCode === 200) { - assert.equal(head.length, 0) - debug('tunneling connection has established') - self.sockets[self.sockets.indexOf(placeholder)] = socket - cb(socket) - } else { - debug('tunneling socket could not be established, statusCode=%d', res.statusCode) - var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } - } - - function onError(cause) { - connectReq.removeAllListeners() - - debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) - var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } -} - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) return - - this.sockets.splice(pos, 1) - - var pending = this.requests.shift() - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket) - }) - } -} - -function createSecureSocket(options, cb) { - var self = this - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, - { servername: options.host - , socket: socket - } - )) - cb(secureSocket) - }) -} - - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i] - if (typeof overrides === 'object') { - var keys = Object.keys(overrides) - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j] - if (overrides[k] !== undefined) { - target[k] = overrides[k] - } - } - } - } - return target -} - - -var debug -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments) - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0] - } else { - args.unshift('TUNNEL:') - } - console.error.apply(console, args) - } -} else { - debug = function() {} -} -exports.debug = debug // for test diff --git a/api/node_modules/request/uuid.js b/api/node_modules/request/uuid.js deleted file mode 100644 index fc0588b2b77..00000000000 --- a/api/node_modules/request/uuid.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = function () { - var s = [], itoh = '0123456789ABCDEF' - - // Make array of random hex digits. The UUID only has 32 digits in it, but we - // allocate an extra items to make room for the '-'s we'll be inserting. - for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10) - - // Conform to RFC-4122, section 4.4 - s[14] = 4; // Set 4 high bits of time_high field to version - s[19] = (s[19] & 0x3) | 0x8 // Specify 2 high bits of clock sequence - - // Convert to hex chars - for (var i = 0; i <36; i++) s[i] = itoh[s[i]] - - // Insert '-'s - s[8] = s[13] = s[18] = s[23] = '-' - - return s.join('') -} diff --git a/api/node_modules/request/vendor/cookie/index.js b/api/node_modules/request/vendor/cookie/index.js deleted file mode 100644 index ff44b3e6292..00000000000 --- a/api/node_modules/request/vendor/cookie/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/*! - * Tobi - Cookie - * Copyright(c) 2010 LearnBoost - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var url = require('url'); - -/** - * Initialize a new `Cookie` with the given cookie `str` and `req`. - * - * @param {String} str - * @param {IncomingRequest} req - * @api private - */ - -var Cookie = exports = module.exports = function Cookie(str, req) { - this.str = str; - - // Map the key/val pairs - str.split(/ *; */).reduce(function(obj, pair){ - var p = pair.indexOf('='); - var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); - var lowerCasedKey = key.toLowerCase(); - var value = p > 0 ? pair.substring(p + 1).trim() : true; - - if (!obj.name) { - // First key is the name - obj.name = key; - obj.value = value; - } - else if (lowerCasedKey === 'httponly') { - obj.httpOnly = value; - } - else { - obj[lowerCasedKey] = value; - } - return obj; - }, this); - - // Expires - this.expires = this.expires - ? new Date(this.expires) - : Infinity; - - // Default or trim path - this.path = this.path - ? this.path.trim(): req - ? url.parse(req.url).pathname: '/'; -}; - -/** - * Return the original cookie string. - * - * @return {String} - * @api public - */ - -Cookie.prototype.toString = function(){ - return this.str; -}; diff --git a/api/node_modules/request/vendor/cookie/jar.js b/api/node_modules/request/vendor/cookie/jar.js deleted file mode 100644 index 34920e06201..00000000000 --- a/api/node_modules/request/vendor/cookie/jar.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! -* Tobi - CookieJar -* Copyright(c) 2010 LearnBoost -* MIT Licensed -*/ - -/** -* Module dependencies. -*/ - -var url = require('url'); - -/** -* Initialize a new `CookieJar`. -* -* @api private -*/ - -var CookieJar = exports = module.exports = function CookieJar() { - this.cookies = []; -}; - -/** -* Add the given `cookie` to the jar. -* -* @param {Cookie} cookie -* @api private -*/ - -CookieJar.prototype.add = function(cookie){ - this.cookies = this.cookies.filter(function(c){ - // Avoid duplication (same path, same name) - return !(c.name == cookie.name && c.path == cookie.path); - }); - this.cookies.push(cookie); -}; - -/** -* Get cookies for the given `req`. -* -* @param {IncomingRequest} req -* @return {Array} -* @api private -*/ - -CookieJar.prototype.get = function(req){ - var path = url.parse(req.url).pathname - , now = new Date - , specificity = {}; - return this.cookies.filter(function(cookie){ - if (0 == path.indexOf(cookie.path) && now < cookie.expires - && cookie.path.length > (specificity[cookie.name] || 0)) - return specificity[cookie.name] = cookie.path.length; - }); -}; - -/** -* Return Cookie string for the given `req`. -* -* @param {IncomingRequest} req -* @return {String} -* @api private -*/ - -CookieJar.prototype.cookieString = function(req){ - var cookies = this.get(req); - if (cookies.length) { - return cookies.map(function(cookie){ - return cookie.name + '=' + cookie.value; - }).join('; '); - } -}; diff --git a/api/node_modules/underscore/.npmignore b/api/node_modules/underscore/.npmignore deleted file mode 100644 index 4e5886deaa5..00000000000 --- a/api/node_modules/underscore/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -test/ -Rakefile -docs/ -raw/ diff --git a/api/node_modules/underscore/.travis.yml b/api/node_modules/underscore/.travis.yml deleted file mode 100644 index 99dc7712c82..00000000000 --- a/api/node_modules/underscore/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.8 -notifications: - email: false diff --git a/api/node_modules/underscore/CNAME b/api/node_modules/underscore/CNAME deleted file mode 100644 index a007e65c42a..00000000000 --- a/api/node_modules/underscore/CNAME +++ /dev/null @@ -1 +0,0 @@ -underscorejs.org diff --git a/api/node_modules/underscore/CONTRIBUTING.md b/api/node_modules/underscore/CONTRIBUTING.md deleted file mode 100644 index de5d5626fd9..00000000000 --- a/api/node_modules/underscore/CONTRIBUTING.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to contribute to Underscore.js - -* Before you open a ticket or send a pull request, [search](https://github.com/documentcloud/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one. - -* Before sending a pull request for a feature, be sure to have [tests](http://underscorejs.org/test/). - -* Use the same coding style as the rest of the [codebase](https://github.com/documentcloud/underscore/blob/master/underscore.js). - -* In your pull request, do not add documentation or re-build the minified `underscore-min.js` file. We'll do those things before cutting a new release. diff --git a/api/node_modules/underscore/LICENSE b/api/node_modules/underscore/LICENSE deleted file mode 100644 index 0d8dbe40bba..00000000000 --- a/api/node_modules/underscore/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/api/node_modules/underscore/README.md b/api/node_modules/underscore/README.md deleted file mode 100644 index b1f3e50a87d..00000000000 --- a/api/node_modules/underscore/README.md +++ /dev/null @@ -1,19 +0,0 @@ - __ - /\ \ __ - __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ - /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ - \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ - \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ - \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ - \ \____/ - \/___/ - -Underscore.js is a utility-belt library for JavaScript that provides -support for the usual functional suspects (each, map, reduce, filter...) -without extending any core JavaScript objects. - -For Docs, License, Tests, and pre-packed downloads, see: -http://underscorejs.org - -Many thanks to our contributors: -https://github.com/documentcloud/underscore/contributors diff --git a/api/node_modules/underscore/favicon.ico b/api/node_modules/underscore/favicon.ico deleted file mode 100644 index 03049683875..00000000000 Binary files a/api/node_modules/underscore/favicon.ico and /dev/null differ diff --git a/api/node_modules/underscore/index.html b/api/node_modules/underscore/index.html deleted file mode 100644 index 8c5793ab4ff..00000000000 --- a/api/node_modules/underscore/index.html +++ /dev/null @@ -1,2467 +0,0 @@ - - - - - - - - - Underscore.js - - - - -
- -
- -

- -

- -

- Underscore is a - utility-belt library for JavaScript that provides a lot of the - functional programming support that you would expect in - Prototype.js - (or Ruby), - but without extending any of the built-in JavaScript objects. It's the - tie to go along with jQuery's tux, - and Backbone.js's suspenders. -

- -

- Underscore provides 80-odd functions that support both the usual - functional suspects: map, select, invoke — - as well as more specialized helpers: function binding, javascript - templating, deep equality testing, and so on. It delegates to built-in - functions, if present, so modern browsers will use the - native implementations of forEach, map, reduce, - filter, every, some and indexOf. -

- -

- A complete Test & Benchmark Suite - is included for your perusal. -

- -

- You may also read through the annotated source code. -

- -

- The project is - hosted on GitHub. - You can report bugs and discuss features on the - issues page, - on Freenode in the #documentcloud channel, - or send tweets to @documentcloud. -

- -

- Underscore is an open-source component of DocumentCloud. -

- -

Downloads (Right-click, and use "Save As")

- -
- - - - - - - - - - - - - - - -
Development Version (1.4.4)40kb, Uncompressed with Plentiful Comments
Production Version (1.4.4)4kb, Minified and Gzipped
Edge VersionUnreleased, current master, use at your own risk
- -
- -

Collection Functions (Arrays or Objects)

- -

- each_.each(list, iterator, [context]) - Alias: forEach -
- Iterates over a list of elements, yielding each in turn to an iterator - function. The iterator is bound to the context object, if one is - passed. Each invocation of iterator is called with three arguments: - (element, index, list). If list is a JavaScript object, iterator's - arguments will be (value, key, list). Delegates to the native - forEach function if it exists. -

-
-_.each([1, 2, 3], alert);
-=> alerts each number in turn...
-_.each({one : 1, two : 2, three : 3}, alert);
-=> alerts each number value in turn...
- -

- map_.map(list, iterator, [context]) - Alias: collect -
- Produces a new array of values by mapping each value in list - through a transformation function (iterator). If the native map method - exists, it will be used instead. If list is a JavaScript object, - iterator's arguments will be (value, key, list). -

-
-_.map([1, 2, 3], function(num){ return num * 3; });
-=> [3, 6, 9]
-_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
-=> [3, 6, 9]
- -

- reduce_.reduce(list, iterator, memo, [context]) - Aliases: inject, foldl -
- Also known as inject and foldl, reduce boils down a - list of values into a single value. Memo is the initial state - of the reduction, and each successive step of it should be returned by - iterator. The iterator is passed four arguments: the memo, - then the value and index (or key) of the iteration, - and finally a reference to the entire list. -

-
-var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
-=> 6
-
- -

- reduceRight_.reduceRight(list, iterator, memo, [context]) - Alias: foldr -
- The right-associative version of reduce. Delegates to the - JavaScript 1.8 version of reduceRight, if it exists. Foldr - is not as useful in JavaScript as it would be in a language with lazy - evaluation. -

-
-var list = [[0, 1], [2, 3], [4, 5]];
-var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-=> [4, 5, 2, 3, 0, 1]
-
- -

- find_.find(list, iterator, [context]) - Alias: detect -
- Looks through each value in the list, returning the first one that - passes a truth test (iterator). The function returns as - soon as it finds an acceptable element, and doesn't traverse the - entire list. -

-
-var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> 2
-
- -

- filter_.filter(list, iterator, [context]) - Alias: select -
- Looks through each value in the list, returning an array of all - the values that pass a truth test (iterator). Delegates to the - native filter method, if it exists. -

-
-var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> [2, 4, 6]
-
- -

- where_.where(list, properties) -
- Looks through each value in the list, returning an array of all - the values that contain all of the key-value pairs listed in properties. -

-
-_.where(listOfPlays, {author: "Shakespeare", year: 1611});
-=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
-    {title: "The Tempest", author: "Shakespeare", year: 1611}]
-
- -

- findWhere_.findWhere(list, properties) -
- Looks through the list and returns the first value that matches - all of the key-value pairs listed in properties. -

-
-_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
-=> {year: 1918, newsroom: "The New York Times",
-  reason: "For its public service in publishing in full so many official reports,
-  documents and speeches by European statesmen relating to the progress and
-  conduct of the war."}
-
- -

- reject_.reject(list, iterator, [context]) -
- Returns the values in list without the elements that the truth - test (iterator) passes. The opposite of filter. -

-
-var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
-=> [1, 3, 5]
-
- -

- every_.every(list, iterator, [context]) - Alias: all -
- Returns true if all of the values in the list pass the iterator - truth test. Delegates to the native method every, if present. -

-
-_.every([true, 1, null, 'yes'], _.identity);
-=> false
-
- -

- some_.some(list, [iterator], [context]) - Alias: any -
- Returns true if any of the values in the list pass the - iterator truth test. Short-circuits and stops traversing the list - if a true element is found. Delegates to the native method some, - if present. -

-
-_.some([null, 0, 'yes', false]);
-=> true
-
- -

- contains_.contains(list, value) - Alias: include -
- Returns true if the value is present in the list. - Uses indexOf internally, if list is an Array. -

-
-_.contains([1, 2, 3], 3);
-=> true
-
- -

- invoke_.invoke(list, methodName, [*arguments]) -
- Calls the method named by methodName on each value in the list. - Any extra arguments passed to invoke will be forwarded on to the - method invocation. -

-
-_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-=> [[1, 5, 7], [1, 2, 3]]
-
- -

- pluck_.pluck(list, propertyName) -
- A convenient version of what is perhaps the most common use-case for - map: extracting a list of property values. -

-
-var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
-_.pluck(stooges, 'name');
-=> ["moe", "larry", "curly"]
-
- -

- max_.max(list, [iterator], [context]) -
- Returns the maximum value in list. If iterator is passed, - it will be used on each value to generate the criterion by which the - value is ranked. -

-
-var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
-_.max(stooges, function(stooge){ return stooge.age; });
-=> {name : 'curly', age : 60};
-
- -

- min_.min(list, [iterator], [context]) -
- Returns the minimum value in list. If iterator is passed, - it will be used on each value to generate the criterion by which the - value is ranked. -

-
-var numbers = [10, 5, 100, 2, 1000];
-_.min(numbers);
-=> 2
-
- -

- sortBy_.sortBy(list, iterator, [context]) -
- Returns a sorted copy of list, ranked in ascending order by the - results of running each value through iterator. Iterator may - also be the string name of the property to sort by (eg. length). -

-
-_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
-=> [5, 4, 6, 3, 1, 2]
-
- -

- groupBy_.groupBy(list, iterator, [context]) -
- Splits a collection into sets, grouped by the result of running each - value through iterator. If iterator is a string instead of - a function, groups by the property named by iterator on each of - the values. -

-
-_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
-=> {1: [1.3], 2: [2.1, 2.4]}
-
-_.groupBy(['one', 'two', 'three'], 'length');
-=> {3: ["one", "two"], 5: ["three"]}
-
- -

- countBy_.countBy(list, iterator, [context]) -
- Sorts a list into groups and returns a count for the number of objects - in each group. - Similar to groupBy, but instead of returning a list of values, - returns a count for the number of values in that group. -

-
-_.countBy([1, 2, 3, 4, 5], function(num) {
-  return num % 2 == 0 ? 'even' : 'odd';
-});
-=> {odd: 3, even: 2}
-
- -

- shuffle_.shuffle(list) -
- Returns a shuffled copy of the list, using a version of the - Fisher-Yates shuffle. -

-
-_.shuffle([1, 2, 3, 4, 5, 6]);
-=> [4, 1, 6, 3, 5, 2]
-
- -

- toArray_.toArray(list) -
- Converts the list (anything that can be iterated over), into a - real Array. Useful for transmuting the arguments object. -

-
-(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-=> [2, 3, 4]
-
- -

- size_.size(list) -
- Return the number of values in the list. -

-
-_.size({one : 1, two : 2, three : 3});
-=> 3
-
- -

Array Functions

- -

- - Note: All array functions will also work on the arguments object. - However, Underscore functions are not designed to work on "sparse" arrays. - -

- -

- first_.first(array, [n]) - Alias: head, take -
- Returns the first element of an array. Passing n will - return the first n elements of the array. -

-
-_.first([5, 4, 3, 2, 1]);
-=> 5
-
- -

- initial_.initial(array, [n]) -
- Returns everything but the last entry of the array. Especially useful on - the arguments object. Pass n to exclude the last n elements - from the result. -

-
-_.initial([5, 4, 3, 2, 1]);
-=> [5, 4, 3, 2]
-
- -

- last_.last(array, [n]) -
- Returns the last element of an array. Passing n will return - the last n elements of the array. -

-
-_.last([5, 4, 3, 2, 1]);
-=> 1
-
- -

- rest_.rest(array, [index]) - Alias: tail, drop -
- Returns the rest of the elements in an array. Pass an index - to return the values of the array from that index onward. -

-
-_.rest([5, 4, 3, 2, 1]);
-=> [4, 3, 2, 1]
-
- -

- compact_.compact(array) -
- Returns a copy of the array with all falsy values removed. - In JavaScript, false, null, 0, "", - undefined and NaN are all falsy. -

-
-_.compact([0, 1, false, 2, '', 3]);
-=> [1, 2, 3]
-
- -

- flatten_.flatten(array, [shallow]) -
- Flattens a nested array (the nesting can be to any depth). If you - pass shallow, the array will only be flattened a single level. -

-
-_.flatten([1, [2], [3, [[4]]]]);
-=> [1, 2, 3, 4];
-
-_.flatten([1, [2], [3, [[4]]]], true);
-=> [1, 2, 3, [[4]]];
-
- -

- without_.without(array, [*values]) -
- Returns a copy of the array with all instances of the values - removed. -

-
-_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
-=> [2, 3, 4]
-
- -

- union_.union(*arrays) -
- Computes the union of the passed-in arrays: the list of unique items, - in order, that are present in one or more of the arrays. -

-
-_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
-=> [1, 2, 3, 101, 10]
-
- -

- intersection_.intersection(*arrays) -
- Computes the list of values that are the intersection of all the arrays. - Each value in the result is present in each of the arrays. -

-
-_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
-=> [1, 2]
-
- -

- difference_.difference(array, *others) -
- Similar to without, but returns the values from array that - are not present in the other arrays. -

-
-_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-=> [1, 3, 4]
-
- -

- uniq_.uniq(array, [isSorted], [iterator]) - Alias: unique -
- Produces a duplicate-free version of the array, using === to test - object equality. If you know in advance that the array is sorted, - passing true for isSorted will run a much faster algorithm. - If you want to compute unique items based on a transformation, pass an - iterator function. -

-
-_.uniq([1, 2, 1, 3, 1, 4]);
-=> [1, 2, 3, 4]
-
- -

- zip_.zip(*arrays) -
- Merges together the values of each of the arrays with the - values at the corresponding position. Useful when you have separate - data sources that are coordinated through matching array indexes. - If you're working with a matrix of nested arrays, zip.apply - can transpose the matrix in a similar fashion. -

-
-_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
-=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
-
- -

- object_.object(list, [values]) -
- Converts arrays into objects. Pass either a single list of - [key, value] pairs, or a list of keys, and a list of values. -

-
-_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
-=> {moe: 30, larry: 40, curly: 50}
-
-_.object([['moe', 30], ['larry', 40], ['curly', 50]]);
-=> {moe: 30, larry: 40, curly: 50}
-
- -

- indexOf_.indexOf(array, value, [isSorted]) -
- Returns the index at which value can be found in the array, - or -1 if value is not present in the array. Uses the native - indexOf function unless it's missing. If you're working with a - large array, and you know that the array is already sorted, pass true - for isSorted to use a faster binary search ... or, pass a number as - the third argument in order to look for the first matching value in the - array after the given index. -

-
-_.indexOf([1, 2, 3], 2);
-=> 1
-
- -

- lastIndexOf_.lastIndexOf(array, value, [fromIndex]) -
- Returns the index of the last occurrence of value in the array, - or -1 if value is not present. Uses the native lastIndexOf - function if possible. Pass fromIndex to start your search at a - given index. -

-
-_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-=> 4
-
- -

- sortedIndex_.sortedIndex(list, value, [iterator], [context]) -
- Uses a binary search to determine the index at which the value - should be inserted into the list in order to maintain the list's - sorted order. If an iterator is passed, it will be used to compute - the sort ranking of each value, including the value you pass. -

-
-_.sortedIndex([10, 20, 30, 40, 50], 35);
-=> 3
-
- -

- range_.range([start], stop, [step]) -
- A function to create flexibly-numbered lists of integers, handy for - each and map loops. start, if omitted, defaults - to 0; step defaults to 1. Returns a list of integers - from start to stop, incremented (or decremented) by step, - exclusive. -

-
-_.range(10);
-=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-_.range(1, 11);
-=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-_.range(0, 30, 5);
-=> [0, 5, 10, 15, 20, 25]
-_.range(0, -10, -1);
-=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
-_.range(0);
-=> []
-
- -

Function (uh, ahem) Functions

- -

- bind_.bind(function, object, [*arguments]) -
- Bind a function to an object, meaning that whenever - the function is called, the value of this will be the object. - Optionally, pass arguments to the function to pre-fill them, - also known as partial application. -

-
-var func = function(greeting){ return greeting + ': ' + this.name };
-func = _.bind(func, {name : 'moe'}, 'hi');
-func();
-=> 'hi: moe'
-
- -

- bindAll_.bindAll(object, [*methodNames]) -
- Binds a number of methods on the object, specified by - methodNames, to be run in the context of that object whenever they - are invoked. Very handy for binding functions that are going to be used - as event handlers, which would otherwise be invoked with a fairly useless - this. If no methodNames are provided, all of the object's - function properties will be bound to it. -

-
-var buttonView = {
-  label   : 'underscore',
-  onClick : function(){ alert('clicked: ' + this.label); },
-  onHover : function(){ console.log('hovering: ' + this.label); }
-};
-_.bindAll(buttonView);
-jQuery('#underscore_button').bind('click', buttonView.onClick);
-=> When the button is clicked, this.label will have the correct value...
-
- -

- partial_.partial(function, [*arguments]) -
- Partially apply a function by filling in any number of its arguments, - without changing its dynamic this value. A close cousin - of bind. -

-
-var add = function(a, b) { return a + b; };
-add5 = _.partial(add, 5);
-add5(10);
-=> 15
-
- -

- memoize_.memoize(function, [hashFunction]) -
- Memoizes a given function by caching the computed result. Useful - for speeding up slow-running computations. If passed an optional - hashFunction, it will be used to compute the hash key for storing - the result, based on the arguments to the original function. The default - hashFunction just uses the first argument to the memoized function - as the key. -

-
-var fibonacci = _.memoize(function(n) {
-  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
-});
-
- -

- delay_.delay(function, wait, [*arguments]) -
- Much like setTimeout, invokes function after wait - milliseconds. If you pass the optional arguments, they will be - forwarded on to the function when it is invoked. -

-
-var log = _.bind(console.log, console);
-_.delay(log, 1000, 'logged later');
-=> 'logged later' // Appears after one second.
-
- -

- defer_.defer(function, [*arguments]) -
- Defers invoking the function until the current call stack has cleared, - similar to using setTimeout with a delay of 0. Useful for performing - expensive computations or HTML rendering in chunks without blocking the UI thread - from updating. If you pass the optional arguments, they will be - forwarded on to the function when it is invoked. -

-
-_.defer(function(){ alert('deferred'); });
-// Returns from the function before the alert runs.
-
- -

- throttle_.throttle(function, wait) -
- Creates and returns a new, throttled version of the passed function, - that, when invoked repeatedly, will only actually call the original function - at most once per every wait - milliseconds. Useful for rate-limiting events that occur faster than you - can keep up with. -

-
-var throttled = _.throttle(updatePosition, 100);
-$(window).scroll(throttled);
-
- -

- debounce_.debounce(function, wait, [immediate]) -
- Creates and returns a new debounced version of the passed function that - will postpone its execution until after - wait milliseconds have elapsed since the last time it - was invoked. Useful for implementing behavior that should only happen - after the input has stopped arriving. For example: rendering a - preview of a Markdown comment, recalculating a layout after the window - has stopped being resized, and so on. -

- -

- Pass true for the immediate parameter to cause - debounce to trigger the function on the leading instead of the - trailing edge of the wait interval. Useful in circumstances like - preventing accidental double-clicks on a "submit" button from firing a - second time. -

- -
-var lazyLayout = _.debounce(calculateLayout, 300);
-$(window).resize(lazyLayout);
-
- -

- once_.once(function) -
- Creates a version of the function that can only be called one time. - Repeated calls to the modified function will have no effect, returning - the value from the original call. Useful for initialization functions, - instead of having to set a boolean flag and then check it later. -

-
-var initialize = _.once(createApplication);
-initialize();
-initialize();
-// Application is only created once.
-
- -

- after_.after(count, function) -
- Creates a version of the function that will only be run after first - being called count times. Useful for grouping asynchronous responses, - where you want to be sure that all the async calls have finished, before - proceeding. -

-
-var renderNotes = _.after(notes.length, render);
-_.each(notes, function(note) {
-  note.asyncSave({success: renderNotes});
-});
-// renderNotes is run once, after all notes have saved.
-
- -

- wrap_.wrap(function, wrapper) -
- Wraps the first function inside of the wrapper function, - passing it as the first argument. This allows the wrapper to - execute code before and after the function runs, adjust the arguments, - and execute it conditionally. -

-
-var hello = function(name) { return "hello: " + name; };
-hello = _.wrap(hello, function(func) {
-  return "before, " + func("moe") + ", after";
-});
-hello();
-=> 'before, hello: moe, after'
-
- -

- compose_.compose(*functions) -
- Returns the composition of a list of functions, where each function - consumes the return value of the function that follows. In math terms, - composing the functions f(), g(), and h() produces - f(g(h())). -

-
-var greet    = function(name){ return "hi: " + name; };
-var exclaim  = function(statement){ return statement + "!"; };
-var welcome = _.compose(exclaim, greet);
-welcome('moe');
-=> 'hi: moe!'
-
- -

Object Functions

- -

- keys_.keys(object) -
- Retrieve all the names of the object's properties. -

-
-_.keys({one : 1, two : 2, three : 3});
-=> ["one", "two", "three"]
-
- -

- values_.values(object) -
- Return all of the values of the object's properties. -

-
-_.values({one : 1, two : 2, three : 3});
-=> [1, 2, 3]
-
- -

- pairs_.pairs(object) -
- Convert an object into a list of [key, value] pairs. -

-
-_.pairs({one: 1, two: 2, three: 3});
-=> [["one", 1], ["two", 2], ["three", 3]]
-
- -

- invert_.invert(object) -
- Returns a copy of the object where the keys have become the values - and the values the keys. For this to work, all of your object's values - should be unique and string serializable. -

-
-_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
-=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};
-
- -

- functions_.functions(object) - Alias: methods -
- Returns a sorted list of the names of every method in an object — - that is to say, the name of every function property of the object. -

-
-_.functions(_);
-=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
-
- -

- extend_.extend(destination, *sources) -
- Copy all of the properties in the source objects over to the - destination object, and return the destination object. - It's in-order, so the last source will override properties of the same - name in previous arguments. -

-
-_.extend({name : 'moe'}, {age : 50});
-=> {name : 'moe', age : 50}
-
- -

- pick_.pick(object, *keys) -
- Return a copy of the object, filtered to only have values for - the whitelisted keys (or array of valid keys). -

-
-_.pick({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age');
-=> {name : 'moe', age : 50}
-
- -

- omit_.omit(object, *keys) -
- Return a copy of the object, filtered to omit the blacklisted - keys (or array of keys). -

-
-_.omit({name : 'moe', age : 50, userid : 'moe1'}, 'userid');
-=> {name : 'moe', age : 50}
-
- -

- defaults_.defaults(object, *defaults) -
- Fill in null and undefined properties in object with values from the - defaults objects, and return the object. As soon as the - property is filled, further defaults will have no effect. -

-
-var iceCream = {flavor : "chocolate"};
-_.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"});
-=> {flavor : "chocolate", sprinkles : "lots"}
-
- -

- clone_.clone(object) -
- Create a shallow-copied clone of the object. Any nested objects - or arrays will be copied by reference, not duplicated. -

-
-_.clone({name : 'moe'});
-=> {name : 'moe'};
-
- -

- tap_.tap(object, interceptor) -
- Invokes interceptor with the object, and then returns object. - The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. -

-
-_.chain([1,2,3,200])
-  .filter(function(num) { return num % 2 == 0; })
-  .tap(alert)
-  .map(function(num) { return num * num })
-  .value();
-=> // [2, 200] (alerted)
-=> [4, 40000]
-
- -

- has_.has(object, key) -
- Does the object contain the given key? Identical to - object.hasOwnProperty(key), but uses a safe reference to the - hasOwnProperty function, in case it's been - overridden accidentally. -

-
-_.has({a: 1, b: 2, c: 3}, "b");
-=> true
-
- -

- isEqual_.isEqual(object, other) -
- Performs an optimized deep comparison between the two objects, to determine - if they should be considered equal. -

-
-var moe   = {name : 'moe', luckyNumbers : [13, 27, 34]};
-var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
-moe == clone;
-=> false
-_.isEqual(moe, clone);
-=> true
-
- -

- isEmpty_.isEmpty(object) -
- Returns true if object contains no values. -

-
-_.isEmpty([1, 2, 3]);
-=> false
-_.isEmpty({});
-=> true
-
- -

- isElement_.isElement(object) -
- Returns true if object is a DOM element. -

-
-_.isElement(jQuery('body')[0]);
-=> true
-
- -

- isArray_.isArray(object) -
- Returns true if object is an Array. -

-
-(function(){ return _.isArray(arguments); })();
-=> false
-_.isArray([1,2,3]);
-=> true
-
- -

- isObject_.isObject(value) -
- Returns true if value is an Object. Note that JavaScript - arrays and functions are objects, while (normal) strings and numbers are not. -

-
-_.isObject({});
-=> true
-_.isObject(1);
-=> false
-
- -

- isArguments_.isArguments(object) -
- Returns true if object is an Arguments object. -

-
-(function(){ return _.isArguments(arguments); })(1, 2, 3);
-=> true
-_.isArguments([1,2,3]);
-=> false
-
- -

- isFunction_.isFunction(object) -
- Returns true if object is a Function. -

-
-_.isFunction(alert);
-=> true
-
- -

- isString_.isString(object) -
- Returns true if object is a String. -

-
-_.isString("moe");
-=> true
-
- -

- isNumber_.isNumber(object) -
- Returns true if object is a Number (including NaN). -

-
-_.isNumber(8.4 * 5);
-=> true
-
- -

- isFinite_.isFinite(object) -
- Returns true if object is a finite Number. -

-
-_.isFinite(-101);
-=> true
-
-_.isFinite(-Infinity);
-=> false
-
- -

- isBoolean_.isBoolean(object) -
- Returns true if object is either true or false. -

-
-_.isBoolean(null);
-=> false
-
- -

- isDate_.isDate(object) -
- Returns true if object is a Date. -

-
-_.isDate(new Date());
-=> true
-
- -

- isRegExp_.isRegExp(object) -
- Returns true if object is a RegExp. -

-
-_.isRegExp(/moe/);
-=> true
-
- -

- isNaN_.isNaN(object) -
- Returns true if object is NaN.
Note: this is not - the same as the native isNaN function, which will also return - true if the variable is undefined. -

-
-_.isNaN(NaN);
-=> true
-isNaN(undefined);
-=> true
-_.isNaN(undefined);
-=> false
-
- -

- isNull_.isNull(object) -
- Returns true if the value of object is null. -

-
-_.isNull(null);
-=> true
-_.isNull(undefined);
-=> false
-
- -

- isUndefined_.isUndefined(value) -
- Returns true if value is undefined. -

-
-_.isUndefined(window.missingVariable);
-=> true
-
- -

Utility Functions

- -

- noConflict_.noConflict() -
- Give control of the "_" variable back to its previous owner. Returns - a reference to the Underscore object. -

-
-var underscore = _.noConflict();
- -

- identity_.identity(value) -
- Returns the same value that is used as the argument. In math: - f(x) = x
- This function looks useless, but is used throughout Underscore as - a default iterator. -

-
-var moe = {name : 'moe'};
-moe === _.identity(moe);
-=> true
- -

- times_.times(n, iterator, [context]) -
- Invokes the given iterator function n times. Each invocation of - iterator is called with an index argument. -
- Note: this example uses the chaining syntax. -

-
-_(3).times(function(n){ genie.grantWishNumber(n); });
- -

- random_.random(min, max) -
- Returns a random integer between min and max, inclusive. - If you only pass one argument, it will return a number between 0 - and that number. -

-
-_.random(0, 100);
-=> 42
- -

- mixin_.mixin(object) -
- Allows you to extend Underscore with your own utility functions. Pass - a hash of {name: function} definitions to have your functions - added to the Underscore object, as well as the OOP wrapper. -

-
-_.mixin({
-  capitalize : function(string) {
-    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
-  }
-});
-_("fabio").capitalize();
-=> "Fabio"
-
- -

- uniqueId_.uniqueId([prefix]) -
- Generate a globally-unique id for client-side models or DOM elements - that need one. If prefix is passed, the id will be appended to it. -

-
-_.uniqueId('contact_');
-=> 'contact_104'
- -

- escape_.escape(string) -
- Escapes a string for insertion into HTML, replacing - &, <, >, ", ', and / characters. -

-
-_.escape('Curly, Larry & Moe');
-=> "Curly, Larry &amp; Moe"
- -

- unescape_.unescape(string) -
- The opposite of escape, replaces - &amp;, &lt;, &gt;, - &quot;, &#x27;, and &#x2F; - with their unescaped counterparts. -

-
-_.unescape('Curly, Larry &amp; Moe');
-=> "Curly, Larry & Moe"
- -

- result_.result(object, property) -
- If the value of the named property is a function then invoke it; otherwise, return it. -

-
-var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
-_.result(object, 'cheese');
-=> "crumpets"
-_.result(object, 'stuff');
-=> "nonsense"
- -

- template_.template(templateString, [data], [settings]) -
- Compiles JavaScript templates into functions that can be evaluated - for rendering. Useful for rendering complicated bits of HTML from JSON - data sources. Template functions can both interpolate variables, using - <%= … %>, as well as execute arbitrary JavaScript code, with - <% … %>. If you wish to interpolate a value, and have - it be HTML-escaped, use <%- … %> When you evaluate a template function, pass in a - data object that has properties corresponding to the template's free - variables. If you're writing a one-off, you can pass the data - object as the second parameter to template in order to render - immediately instead of returning a template function. The settings argument - should be a hash containing any _.templateSettings that should be overridden. -

- -
-var compiled = _.template("hello: <%= name %>");
-compiled({name : 'moe'});
-=> "hello: moe"
-
-var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
-_.template(list, {people : ['moe', 'curly', 'larry']});
-=> "<li>moe</li><li>curly</li><li>larry</li>"
-
-var template = _.template("<b><%- value %></b>");
-template({value : '<script>'});
-=> "<b>&lt;script&gt;</b>"
- -

- You can also use print from within JavaScript code. This is - sometimes more convenient than using <%= ... %>. -

- -
-var compiled = _.template("<% print('Hello ' + epithet); %>");
-compiled({epithet: "stooge"});
-=> "Hello stooge."
- -

- If ERB-style delimiters aren't your cup of tea, you can change Underscore's - template settings to use different symbols to set off interpolated code. - Define an interpolate regex to match expressions that should be - interpolated verbatim, an escape regex to match expressions that should - be inserted after being HTML escaped, and an evaluate regex to match - expressions that should be evaluated without insertion into the resulting - string. You may define or omit any combination of the three. - For example, to perform - Mustache.js - style templating: -

- -
-_.templateSettings = {
-  interpolate : /\{\{(.+?)\}\}/g
-};
-
-var template = _.template("Hello {{ name }}!");
-template({name : "Mustache"});
-=> "Hello Mustache!"
- -

- By default, template places the values from your data in the local scope - via the with statement. However, you can specify a single variable name - with the variable setting. This can significantly improve the speed - at which a template is able to render. -

- -
-_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
-=> "Using 'with': no"
- -

- Precompiling your templates can be a big help when debugging errors you can't - reproduce. This is because precompiled templates can provide line numbers and - a stack trace, something that is not possible when compiling templates on the client. - The source property is available on the compiled template - function for easy precompilation. -

- -
<script>
-  JST.project = <%= _.template(jstText).source %>;
-</script>
- - -

Chaining

- -

- You can use Underscore in either an object-oriented or a functional style, - depending on your preference. The following two lines of code are - identical ways to double a list of numbers. -

- -
-_.map([1, 2, 3], function(n){ return n * 2; });
-_([1, 2, 3]).map(function(n){ return n * 2; });
- -

- Calling chain will cause all future method calls to return - wrapped objects. When you've finished the computation, use - value to retrieve the final value. Here's an example of chaining - together a map/flatten/reduce, in order to get the word count of - every word in a song. -

- -
-var lyrics = [
-  {line : 1, words : "I'm a lumberjack and I'm okay"},
-  {line : 2, words : "I sleep all night and I work all day"},
-  {line : 3, words : "He's a lumberjack and he's okay"},
-  {line : 4, words : "He sleeps all night and he works all day"}
-];
-
-_.chain(lyrics)
-  .map(function(line) { return line.words.split(' '); })
-  .flatten()
-  .reduce(function(counts, word) {
-    counts[word] = (counts[word] || 0) + 1;
-    return counts;
-  }, {})
-  .value();
-
-=> {lumberjack : 2, all : 4, night : 2 ... }
- -

- In addition, the - Array prototype's methods - are proxied through the chained Underscore object, so you can slip a - reverse or a push into your chain, and continue to - modify the array. -

- -

- chain_.chain(obj) -
- Returns a wrapped object. Calling methods on this object will continue - to return wrapped objects until value is used. -

-
-var stooges = [{name : 'curly', age : 25}, {name : 'moe', age : 21}, {name : 'larry', age : 23}];
-var youngest = _.chain(stooges)
-  .sortBy(function(stooge){ return stooge.age; })
-  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
-  .first()
-  .value();
-=> "moe is 21"
-
- -

- value_(obj).value() -
- Extracts the value of a wrapped object. -

-
-_([1, 2, 3]).value();
-=> [1, 2, 3]
-
- - - -

- The Underscore documentation is also available in - Simplified Chinese. -

- -

- Underscore.lua, - a Lua port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - (source) -

- -

- Underscore.m, an Objective-C port - of many of the Underscore.js functions, using a syntax that encourages - chaining. - (source) -

- -

- _.m, an alternative - Objective-C port that tries to stick a little closer to the original - Underscore.js API. - (source) -

- -

- Underscore.php, - a PHP port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - (source) -

- -

- Underscore-perl, - a Perl port of many of the Underscore.js functions, - aimed at on Perl hashes and arrays. - (source) -

- -

- Underscore.cfc, - a Coldfusion port of many of the Underscore.js functions. - (source) -

- -

- Underscore.string, - an Underscore extension that adds functions for string-manipulation: - trim, startsWith, contains, capitalize, - reverse, sprintf, and more. -

- -

- Ruby's Enumerable module. -

- -

- Prototype.js, which provides - JavaScript with collection functions in the manner closest to Ruby's Enumerable. -

- -

- Oliver Steele's - Functional JavaScript, - which includes comprehensive higher-order function support as well as string lambdas. -

- -

- Michael Aufreiter's Data.js, - a data manipulation + persistence library for JavaScript. -

- -

- Python's itertools. -

- -

Change Log

- -

- 1.4.4Jan. 30, 2013Diff
-

    -
  • - Added _.findWhere, for finding the first element in a list - that matches a particular set of keys and values. -
  • -
  • - Added _.partial, for partially applying a function without - changing its dynamic reference to this. -
  • -
  • - Simplified bind by removing some edge cases involving - constructor functions. In short: don't _.bind your - constructors. -
  • -
  • - A minor optimization to invoke. -
  • -
  • - Fix bug in the minified version due to the minifier incorrectly - optimizing-away isFunction. -
  • -
-

- -

- 1.4.3Dec. 4, 2012Diff
-

    -
  • - Improved Underscore compatibility with Adobe's JS engine that can be - used to script Illustrator, Photoshop, and friends. -
  • -
  • - Added a default _.identity iterator to countBy and - groupBy. -
  • -
  • - The uniq function can now take array, iterator, context - as the argument list. -
  • -
  • - The times function now returns the mapped array of iterator - results. -
  • -
  • - Simplified and fixed bugs in throttle. -
  • -
-

- -

- 1.4.2Oct. 1, 2012Diff
-

    -
  • - For backwards compatibility, returned to pre-1.4.0 behavior when - passing null to iteration functions. They now become no-ops - again. -
  • -
-

- -

- 1.4.1Oct. 1, 2012Diff
-

    -
  • - Fixed a 1.4.0 regression in the lastIndexOf function. -
  • -
-

- -

- 1.4.0Sept. 27, 2012Diff
-

    -
  • - Added a pairs function, for turning a JavaScript object - into [key, value] pairs ... as well as an object - function, for converting an array of [key, value] pairs - into an object. -
  • -
  • - Added a countBy function, for counting the number of objects - in a list that match a certain criteria. -
  • -
  • - Added an invert function, for performing a simple inversion - of the keys and values in an object. -
  • -
  • - Added a where function, for easy cases of filtering a list - for objects with specific values. -
  • -
  • - Added an omit function, for filtering an object to remove - certain keys. -
  • -
  • - Added a random function, to return a random number in a - given range. -
  • -
  • - _.debounce'd functions now return their last updated value, - just like _.throttle'd functions do. -
  • -
  • - The sortBy function now runs a stable sort algorithm. -
  • -
  • - Added the optional fromIndex option to indexOf and - lastIndexOf. -
  • -
  • - "Sparse" arrays are no longer supported in Underscore iteration - functions. Use a for loop instead (or better yet, an object). -
  • -
  • - The min and max functions may now be called on - very large arrays. -
  • -
  • - Interpolation in templates now represents null and - undefined as the empty string. -
  • -
  • - Underscore iteration functions no longer accept null values - as a no-op argument. You'll get an early error instead. -
  • -
  • - A number of edge-cases fixes and tweaks, which you can spot in the - diff. - Depending on how you're using Underscore, 1.4.0 may be more - backwards-incompatible than usual — please test when you upgrade. -
  • -
-

- -

- 1.3.3April 10, 2012
-

    -
  • - Many improvements to _.template, which now provides the - source of the template function as a property, for potentially - even more efficient pre-compilation on the server-side. You may now - also set the variable option when creating a template, - which will cause your passed-in data to be made available under the - variable you named, instead of using a with statement — - significantly improving the speed of rendering the template. -
  • -
  • - Added the pick function, which allows you to filter an - object literal with a whitelist of allowed property names. -
  • -
  • - Added the result function, for convenience when working - with APIs that allow either functions or raw properties. -
  • -
  • - Added the isFinite function, because sometimes knowing that - a value is a number just ain't quite enough. -
  • -
  • - The sortBy function may now also be passed the string name - of a property to use as the sort order on each object. -
  • -
  • - Fixed uniq to work with sparse arrays. -
  • -
  • - The difference function now performs a shallow flatten - instead of a deep one when computing array differences. -
  • -
  • - The debounce function now takes an immediate - parameter, which will cause the callback to fire on the leading - instead of the trailing edge. -
  • -
-

- -

- 1.3.1Jan. 23, 2012
-

    -
  • - Added an _.has function, as a safer way to use hasOwnProperty. -
  • -
  • - Added _.collect as an alias for _.map. Smalltalkers, rejoice. -
  • -
  • - Reverted an old change so that _.extend will correctly copy - over keys with undefined values again. -
  • -
  • - Bugfix to stop escaping slashes within interpolations in _.template. -
  • -
-

- -

- 1.3.0Jan. 11, 2012
-

    -
  • - Removed AMD (RequireJS) support from Underscore. If you'd like to use - Underscore with RequireJS, you can load it as a normal script, wrap - or patch your copy, or download a forked version. -
  • -
-

- -

- 1.2.4Jan. 4, 2012
-

    -
  • - You now can (and probably should, as it's simpler) - write _.chain(list) - instead of _(list).chain(). -
  • -
  • - Fix for escaped characters in Underscore templates, and for supporting - customizations of _.templateSettings that only define one or - two of the required regexes. -
  • -
  • - Fix for passing an array as the first argument to an _.wrap'd function. -
  • -
  • - Improved compatibility with ClojureScript, which adds a call - function to String.prototype. -
  • -
-

- -

- 1.2.3Dec. 7, 2011
-

    -
  • - Dynamic scope is now preserved for compiled _.template functions, - so you can use the value of this if you like. -
  • -
  • - Sparse array support of _.indexOf, _.lastIndexOf. -
  • -
  • - Both _.reduce and _.reduceRight can now be passed an - explicitly undefined value. (There's no reason why you'd - want to do this.) -
  • -
-

- -

- 1.2.2Nov. 14, 2011
-

    -
  • - Continued tweaks to _.isEqual semantics. Now JS primitives are - considered equivalent to their wrapped versions, and arrays are compared - by their numeric properties only (#351). -
  • -
  • - _.escape no longer tries to be smart about not double-escaping - already-escaped HTML entities. Now it just escapes regardless (#350). -
  • -
  • - In _.template, you may now leave semicolons out of evaluated - statements if you wish: <% }) %> (#369). -
  • -
  • - _.after(callback, 0) will now trigger the callback immediately, - making "after" easier to use with asynchronous APIs (#366). -
  • -
-

- -

- 1.2.1Oct. 24, 2011
-

    -
  • - Several important bug fixes for _.isEqual, which should now - do better on mutated Arrays, and on non-Array objects with - length properties. (#329) -
  • -
  • - jrburke contributed Underscore exporting for AMD module loaders, - and tonylukasavage for Appcelerator Titanium. - (#335, #338) -
  • -
  • - You can now _.groupBy(list, 'property') as a shortcut for - grouping values by a particular common property. -
  • -
  • - _.throttle'd functions now fire immediately upon invocation, - and are rate-limited thereafter (#170, #266). -
  • -
  • - Most of the _.is[Type] checks no longer ducktype. -
  • -
  • - The _.bind function now also works on constructors, a-la - ES5 ... but you would never want to use _.bind on a - constructor function. -
  • -
  • - _.clone no longer wraps non-object types in Objects. -
  • -
  • - _.find and _.filter are now the preferred names for - _.detect and _.select. -
  • -
-

- -

- 1.2.0Oct. 5, 2011
-

    -
  • - The _.isEqual function now - supports true deep equality comparisons, with checks for cyclic structures, - thanks to Kit Cambridge. -
  • -
  • - Underscore templates now support HTML escaping interpolations, using - <%- ... %> syntax. -
  • -
  • - Ryan Tenney contributed _.shuffle, which uses a modified - Fisher-Yates to give you a shuffled copy of an array. -
  • -
  • - _.uniq can now be passed an optional iterator, to determine by - what criteria an object should be considered unique. -
  • -
  • - _.last now takes an optional argument which will return the last - N elements of the list. -
  • -
  • - A new _.initial function was added, as a mirror of _.rest, - which returns all the initial values of a list (except the last N). -
  • -
-

- -

- 1.1.7July 13, 2011
- Added _.groupBy, which aggregates a collection into groups of like items. - Added _.union and _.difference, to complement the - (re-named) _.intersection. - Various improvements for support of sparse arrays. - _.toArray now returns a clone, if directly passed an array. - _.functions now also returns the names of functions that are present - in the prototype chain. -

- -

- 1.1.6April 18, 2011
- Added _.after, which will return a function that only runs after - first being called a specified number of times. - _.invoke can now take a direct function reference. - _.every now requires an iterator function to be passed, which - mirrors the ECMA5 API. - _.extend no longer copies keys when the value is undefined. - _.bind now errors when trying to bind an undefined value. -

- -

- 1.1.5Mar 20, 2011
- Added an _.defaults function, for use merging together JS objects - representing default options. - Added an _.once function, for manufacturing functions that should - only ever execute a single time. - _.bind now delegates to the native ECMAScript 5 version, - where available. - _.keys now throws an error when used on non-Object values, as in - ECMAScript 5. - Fixed a bug with _.keys when used over sparse arrays. -

- -

- 1.1.4Jan 9, 2011
- Improved compliance with ES5's Array methods when passing null - as a value. _.wrap now correctly sets this for the - wrapped function. _.indexOf now takes an optional flag for - finding the insertion index in an array that is guaranteed to already - be sorted. Avoiding the use of .callee, to allow _.isArray - to work properly in ES5's strict mode. -

- -

- 1.1.3Dec 1, 2010
- In CommonJS, Underscore may now be required with just:
- var _ = require("underscore"). - Added _.throttle and _.debounce functions. - Removed _.breakLoop, in favor of an ECMA5-style un-break-able - each implementation — this removes the try/catch, and you'll now have - better stack traces for exceptions that are thrown within an Underscore iterator. - Improved the isType family of functions for better interoperability - with Internet Explorer host objects. - _.template now correctly escapes backslashes in templates. - Improved _.reduce compatibility with the ECMA5 version: - if you don't pass an initial value, the first item in the collection is used. - _.each no longer returns the iterated collection, for improved - consistency with ES5's forEach. -

- -

- 1.1.2
- Fixed _.contains, which was mistakenly pointing at - _.intersect instead of _.include, like it should - have been. Added _.unique as an alias for _.uniq. -

- -

- 1.1.1
- Improved the speed of _.template, and its handling of multiline - interpolations. Ryan Tenney contributed optimizations to many Underscore - functions. An annotated version of the source code is now available. -

- -

- 1.1.0
- The method signature of _.reduce has been changed to match - the ECMAScript 5 signature, instead of the Ruby/Prototype.js version. - This is a backwards-incompatible change. _.template may now be - called with no arguments, and preserves whitespace. _.contains - is a new alias for _.include. -

- -

- 1.0.4
- Andri Möll contributed the _.memoize - function, which can be used to speed up expensive repeated computations - by caching the results. -

- -

- 1.0.3
- Patch that makes _.isEqual return false if any property - of the compared object has a NaN value. Technically the correct - thing to do, but of questionable semantics. Watch out for NaN comparisons. -

- -

- 1.0.2
- Fixes _.isArguments in recent versions of Opera, which have - arguments objects as real Arrays. -

- -

- 1.0.1
- Bugfix for _.isEqual, when comparing two objects with the same - number of undefined keys, but with different names. -

- -

- 1.0.0
- Things have been stable for many months now, so Underscore is now - considered to be out of beta, at 1.0. Improvements since 0.6 - include _.isBoolean, and the ability to have _.extend - take multiple source objects. -

- -

- 0.6.0
- Major release. Incorporates a number of - Mile Frawley's refactors for - safer duck-typing on collection functions, and cleaner internals. A new - _.mixin method that allows you to extend Underscore with utility - functions of your own. Added _.times, which works the same as in - Ruby or Prototype.js. Native support for ECMAScript 5's Array.isArray, - and Object.keys. -

- -

- 0.5.8
- Fixed Underscore's collection functions to work on - NodeLists and - HTMLCollections - once more, thanks to - Justin Tulloss. -

- -

- 0.5.7
- A safer implementation of _.isArguments, and a - faster _.isNumber,
thanks to - Jed Schmidt. -

- -

- 0.5.6
- Customizable delimiters for _.template, contributed by - Noah Sloan. -

- -

- 0.5.5
- Fix for a bug in MobileSafari's OOP-wrapper, with the arguments object. -

- -

- 0.5.4
- Fix for multiple single quotes within a template string for - _.template. See: - Rick Strahl's blog post. -

- -

- 0.5.2
- New implementations of isArray, isDate, isFunction, - isNumber, isRegExp, and isString, thanks to - a suggestion from - Robert Kieffer. - Instead of doing Object#toString - comparisons, they now check for expected properties, which is less safe, - but more than an order of magnitude faster. Most other Underscore - functions saw minor speed improvements as a result. - Evgeniy Dolzhenko - contributed _.tap, - similar to Ruby 1.9's, - which is handy for injecting side effects (like logging) into chained calls. -

- -

- 0.5.1
- Added an _.isArguments function. Lots of little safety checks - and optimizations contributed by - Noah Sloan and - Andri Möll. -

- -

- 0.5.0
- [API Changes] _.bindAll now takes the context object as - its first parameter. If no method names are passed, all of the context - object's methods are bound to it, enabling chaining and easier binding. - _.functions now takes a single argument and returns the names - of its Function properties. Calling _.functions(_) will get you - the previous behavior. - Added _.isRegExp so that isEqual can now test for RegExp equality. - All of the "is" functions have been shrunk down into a single definition. - Karl Guertin contributed patches. -

- -

- 0.4.7
- Added isDate, isNaN, and isNull, for completeness. - Optimizations for isEqual when checking equality between Arrays - or Dates. _.keys is now 25%–2X faster (depending on your - browser) which speeds up the functions that rely on it, such as _.each. -

- -

- 0.4.6
- Added the range function, a port of the - Python - function of the same name, for generating flexibly-numbered lists - of integers. Original patch contributed by - Kirill Ishanov. -

- -

- 0.4.5
- Added rest for Arrays and arguments objects, and aliased - first as head, and rest as tail, - thanks to Luke Sutton's patches. - Added tests ensuring that all Underscore Array functions also work on - arguments objects. -

- -

- 0.4.4
- Added isString, and isNumber, for consistency. Fixed - _.isEqual(NaN, NaN) to return true (which is debatable). -

- -

- 0.4.3
- Started using the native StopIteration object in browsers that support it. - Fixed Underscore setup for CommonJS environments. -

- -

- 0.4.2
- Renamed the unwrapping function to value, for clarity. -

- -

- 0.4.1
- Chained Underscore objects now support the Array prototype methods, so - that you can perform the full range of operations on a wrapped array - without having to break your chain. Added a breakLoop method - to break in the middle of any Underscore iteration. Added an - isEmpty function that works on arrays and objects. -

- -

- 0.4.0
- All Underscore functions can now be called in an object-oriented style, - like so: _([1, 2, 3]).map(...);. Original patch provided by - Marc-André Cournoyer. - Wrapped objects can be chained through multiple - method invocations. A functions method - was added, providing a sorted list of all the functions in Underscore. -

- -

- 0.3.3
- Added the JavaScript 1.8 function reduceRight. Aliased it - as foldr, and aliased reduce as foldl. -

- -

- 0.3.2
- Now runs on stock Rhino - interpreters with: load("underscore.js"). - Added identity as a utility function. -

- -

- 0.3.1
- All iterators are now passed in the original collection as their third - argument, the same as JavaScript 1.6's forEach. Iterating over - objects is now called with (value, key, collection), for details - see _.each. -

- -

- 0.3.0
- Added Dmitry Baranovskiy's - comprehensive optimizations, merged in - Kris Kowal's patches to make Underscore - CommonJS and - Narwhal compliant. -

- -

- 0.2.0
- Added compose and lastIndexOf, renamed inject to - reduce, added aliases for inject, filter, - every, some, and forEach. -

- -

- 0.1.1
- Added noConflict, so that the "Underscore" object can be assigned to - other variables. -

- -

- 0.1.0
- Initial release of Underscore.js. -

- -

- - A DocumentCloud Project - -

- -
- - - - - - - - diff --git a/api/node_modules/underscore/index.js b/api/node_modules/underscore/index.js deleted file mode 100644 index 2cf0ca5b091..00000000000 --- a/api/node_modules/underscore/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./underscore'); diff --git a/api/node_modules/underscore/package.json b/api/node_modules/underscore/package.json deleted file mode 100644 index c967f2fff94..00000000000 --- a/api/node_modules/underscore/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "underscore", - "description": "JavaScript's functional programming helper library.", - "homepage": "http://underscorejs.org", - "keywords": [ - "util", - "functional", - "server", - "client", - "browser" - ], - "author": { - "name": "Jeremy Ashkenas", - "email": "jeremy@documentcloud.org" - }, - "repository": { - "type": "git", - "url": "git://github.com/documentcloud/underscore.git" - }, - "main": "underscore.js", - "version": "1.4.4", - "devDependencies": { - "phantomjs": "0.2.2" - }, - "scripts": { - "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true" - }, - "readme": " __\n /\\ \\ __\n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____\n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\\n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/\n \\ \\____/\n \\/___/\n\nUnderscore.js is a utility-belt library for JavaScript that provides\nsupport for the usual functional suspects (each, map, reduce, filter...)\nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://underscorejs.org\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n", - "readmeFilename": "README.md", - "_id": "underscore@1.4.4", - "dist": { - "shasum": "5ddcb24ff3c58ca2c867ae6760e7a9c3f41b06dc" - }, - "_from": "underscore" -} diff --git a/api/node_modules/underscore/underscore-min.js b/api/node_modules/underscore/underscore-min.js deleted file mode 100644 index c1d9d3aed08..00000000000 --- a/api/node_modules/underscore/underscore-min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.indexi;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); \ No newline at end of file diff --git a/api/node_modules/underscore/underscore.js b/api/node_modules/underscore/underscore.js deleted file mode 100644 index a12f0d96cfb..00000000000 --- a/api/node_modules/underscore/underscore.js +++ /dev/null @@ -1,1226 +0,0 @@ -// Underscore.js 1.4.4 -// http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.4.4'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results[results.length] = iterator.call(context, value, index, list); - }); - return results; - }; - - var reduceError = 'Reduce of empty array with no initial value'; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; - } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); - each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - return _.filter(obj, function(value, index, list) { - return !iterator.call(context, value, index, list); - }, context); - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); - each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); - each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - return any(obj, function(value) { - return value === target; - }); - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? null : []; - return _[first ? 'find' : 'filter'](obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.where(obj, attrs, true); - }; - - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See: https://bugs.webkit.org/show_bug.cgi?id=80797 - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity, value: -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity, value: Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - index : index, - criteria : iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index < right.index ? -1 : 1; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(obj, value, context, behavior) { - var result = {}; - var iterator = lookupIterator(value || _.identity); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - return result; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(value); - }); - }; - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = function(obj, value, context) { - return group(obj, value, context, function(result, key) { - if (!_.has(result, key)) result[key] = 0; - result[key]++; - }); - }; - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, (n == null) || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, output) { - each(input, function(value) { - if (_.isArray(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator, context) { - if (_.isFunction(isSorted)) { - context = iterator; - iterator = isSorted; - isSorted = false; - } - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(concat.apply(ArrayProto, arguments)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); - return _.filter(array, function(value){ return !_.contains(rest, value); }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(args, "" + i); - } - return results; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - if (list == null) return {}; - var result = {}; - for (var i = 0, l = list.length; i < l; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, l = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < l; i++) if (array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - var args = slice.call(arguments, 2); - return function() { - return func.apply(context, args.concat(slice.call(arguments))); - }; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. - _.partial = function(func) { - var args = slice.call(arguments, 1); - return function() { - return func.apply(this, args.concat(slice.call(arguments))); - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length === 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. - _.throttle = function(func, wait) { - var context, args, timeout, result; - var previous = 0; - var later = function() { - previous = new Date; - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) result = func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(context, args); - return result; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var values = []; - for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var pairs = []; - for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; - } - return copy; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] == a) return bStack[length] == b; - } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor))) { - return false; - } - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj != +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function(n, iterator, context) { - var accum = Array(n); - for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - } - }; - entityMap.unescape = _.invert(entityMap.escape); - - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; - - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - each(_.functions(obj), function(name){ - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - var render; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = new RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset) - .replace(escaper, function(match) { return '\\' + escapes[match]; }); - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } - if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } - if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - index = offset + match.length; - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + "return __p;\n"; - - try { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - _.extend(_.prototype, { - - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, - - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - - }); - -}).call(this); diff --git a/api/package.json b/api/package.json new file mode 100644 index 00000000000..008203c79d7 --- /dev/null +++ b/api/package.json @@ -0,0 +1,12 @@ +{ + "name": "countly-server-api", + "dependencies": { + "geoip-lite": "*", + "moment": "1.7.2", + "mongoskin": "1.4.11", + "nodemailer": "0.4.4", + "request":"2.51.0", + "time":"*", + "underscore":"1.7.0" + } +} \ No newline at end of file diff --git a/api/parts/data/events.js b/api/parts/data/events.js index bb973e96f16..f7bf4c261ee 100644 --- a/api/parts/data/events.js +++ b/api/parts/data/events.js @@ -1,17 +1,98 @@ -var events = {}, +var countlyEvents = {}, common = require('./../../utils/common.js'), - async = require('./../../utils/async.min.js'); + async = require('./../../utils/async.min.js'), + crypto = require('crypto'), + plugins = require('../../../plugins/pluginManager.js'); -(function (events) { +(function (countlyEvents) { - events.processEvents = function(params) { + countlyEvents.processEvents = function(params) { + common.db.collection("events").findOne({'_id':params.app_id}, {list:1, segments:1}, function (err, eventColl) { + var appEvents = [], + appSegments = {}, + metaToFetch = []; + + if (!err && eventColl) { + if (eventColl.list) { + appEvents = eventColl.list; + } + + if (eventColl.segments) { + appSegments = eventColl.segments; + } + } + + for (var i=0; i < params.qstring.events.length; i++) { + var currEvent = params.qstring.events[i], + shortEventName = "", + eventCollectionName = ""; + + if (!currEvent.key || !currEvent.count || !common.isNumber(currEvent.count)) { + continue; + } + + if (common.config.api.event_limit && + appEvents.length >= common.config.api.event_limit && + appEvents.indexOf(currEvent.key) === -1) { + continue; + } + + shortEventName = common.fixEventKey(currEvent.key); + + if (!shortEventName) { + continue; + } + + eventCollectionName = "events" + crypto.createHash('sha1').update(shortEventName + params.app_id).digest('hex'); + + if (params.qstring.events[i].timestamp) { + params.time = common.initTimeObj(params.appTimezone, params.qstring.events[i].timestamp); + } + + metaToFetch.push({ + coll: eventCollectionName, + id: "no-segment_" + common.getDateIds(params).zero + }); + } + + async.map(metaToFetch, fetchEventMeta, function (err, eventMetaDocs) { + var appSgValues = {}; + + for (var i = 0; i < eventMetaDocs.length; i++) { + if (eventMetaDocs[i].coll && eventMetaDocs[i].meta) { + appSgValues[eventMetaDocs[i].coll] = eventMetaDocs[i].meta; + } + } + + processEvents(appEvents, appSegments, appSgValues, params); + }); + + function fetchEventMeta(metaToFetch, callback) { + common.db.collection(metaToFetch.coll).findOne({'_id':metaToFetch.id}, {meta:1}, function (err, eventMetaDoc) { + var retObj = eventMetaDoc || {}; + retObj.coll = metaToFetch.coll; + + callback(false, retObj); + }); + } + }); + }; + + function processEvents(appEvents, appSegments, appSgValues, params) { var events = [], eventCollections = {}, eventSegments = {}, + eventSegmentsZeroes = {}, tmpEventObj = {}, tmpEventColl = {}, - shortCollectionName = "", - eventCollectionName = ""; + shortEventName = "", + eventCollectionName = "", + eventHashMap = {}, + forbiddenSegValues = []; + + for (var i = 1; i < 32; i++) { + forbiddenSegValues.push(i + ""); + } for (var i=0; i < params.qstring.events.length; i++) { @@ -24,101 +105,119 @@ var events = {}, continue; } - // Mongodb collection names can not contain system. or $ - shortCollectionName = currEvent.key.replace(/system\.|\.\.|\$/g, ""); - eventCollectionName = shortCollectionName + params.app_id; + if (common.config.api.event_limit && + appEvents.length >= common.config.api.event_limit && + appEvents.indexOf(currEvent.key) === -1) { + continue; + } + + plugins.dispatch("/i/events", {params:params, currEvent:currEvent}); + + shortEventName = common.fixEventKey(currEvent.key); - // Mongodb collection names can not be longer than 128 characters - if (eventCollectionName.length > 128) { + if (!shortEventName) { continue; } + // Create new collection name for the event + eventCollectionName = "events" + crypto.createHash('sha1').update(shortEventName + params.app_id).digest('hex'); + + eventHashMap[eventCollectionName] = shortEventName; + // If present use timestamp inside each event while recording if (params.qstring.events[i].timestamp) { params.time = common.initTimeObj(params.appTimezone, params.qstring.events[i].timestamp); } - common.arrayAddUniq(events, shortCollectionName); + common.arrayAddUniq(events, shortEventName); if (currEvent.sum && common.isNumber(currEvent.sum)) { - common.fillTimeObject(params, tmpEventObj, common.dbMap['sum'], currEvent.sum); + currEvent.sum = parseFloat(currEvent.sum.toFixed(5)); + common.fillTimeObjectMonth(params, tmpEventObj, common.dbMap['sum'], currEvent.sum); } - common.fillTimeObject(params, tmpEventObj, common.dbMap['count'], currEvent.count); - tmpEventColl["no-segment"] = tmpEventObj; + common.fillTimeObjectMonth(params, tmpEventObj, common.dbMap['count'], currEvent.count); + + var dateIds = common.getDateIds(params); + + tmpEventColl["no-segment" + "." + dateIds.month] = tmpEventObj; if (currEvent.segmentation) { + for (var segKey in currEvent.segmentation){ + var tmpSegKey = ""; + if(segKey.indexOf('.') != -1 || segKey.substr(0,1) == '$'){ + tmpSegKey = segKey.replace(/^\$|\./g, ""); + currEvent.segmentation[tmpSegKey] = currEvent.segmentation[segKey]; + delete currEvent.segmentation[segKey]; + } + } + for (var segKey in currEvent.segmentation) { - if (!currEvent.segmentation[segKey]) { + if (common.config.api.event_segmentation_limit && + appSegments[currEvent.key] && + appSegments[currEvent.key].indexOf(segKey) === -1 && + appSegments[currEvent.key].length >= common.config.api.event_segmentation_limit) { continue; } tmpEventObj = {}; var tmpSegVal = currEvent.segmentation[segKey] + ""; + if (tmpSegVal == "") { + continue; + } + // Mongodb field names can't start with $ or contain . tmpSegVal = tmpSegVal.replace(/^\$/, "").replace(/\./g, ":"); - if (currEvent.sum && common.isNumber(currEvent.sum)) { - common.fillTimeObject(params, tmpEventObj, tmpSegVal + '.' + common.dbMap['sum'], currEvent.sum); + if (forbiddenSegValues.indexOf(tmpSegVal) !== -1) { + tmpSegVal = "[CLY]" + tmpSegVal; } - common.fillTimeObject(params, tmpEventObj, tmpSegVal + '.' + common.dbMap['count'], currEvent.count); - if (!eventSegments[eventCollectionName]) { - eventSegments[eventCollectionName] = {}; + if (common.config.api.event_segmentation_value_limit && + appSgValues[eventCollectionName] && + appSgValues[eventCollectionName][segKey] && + appSgValues[eventCollectionName][segKey].indexOf(tmpSegVal) === -1 && + appSgValues[eventCollectionName][segKey].length >= common.config.api.event_segmentation_value_limit) { + continue; } - if (!eventSegments[eventCollectionName]['meta.' + segKey]) { - eventSegments[eventCollectionName]['meta.' + segKey] = {}; + if (currEvent.sum && common.isNumber(currEvent.sum)) { + common.fillTimeObjectMonth(params, tmpEventObj, tmpSegVal + '.' + common.dbMap['sum'], currEvent.sum); } - if (eventSegments[eventCollectionName]['meta.' + segKey]["$each"] && eventSegments[eventCollectionName]['meta.' + segKey]["$each"].length) { - common.arrayAddUniq(eventSegments[eventCollectionName]['meta.' + segKey]["$each"], tmpSegVal); + common.fillTimeObjectMonth(params, tmpEventObj, tmpSegVal + '.' + common.dbMap['count'], currEvent.count); + + if (!eventSegmentsZeroes[eventCollectionName]) { + eventSegmentsZeroes[eventCollectionName] = []; + common.arrayAddUniq(eventSegmentsZeroes[eventCollectionName], dateIds.zero); } else { - eventSegments[eventCollectionName]['meta.' + segKey]["$each"] = [tmpSegVal]; + common.arrayAddUniq(eventSegmentsZeroes[eventCollectionName], dateIds.zero); } - if (!eventSegments[eventCollectionName]["meta.segments"]) { - eventSegments[eventCollectionName]["meta.segments"] = {}; - eventSegments[eventCollectionName]["meta.segments"]["$each"] = []; + if (!eventSegments[eventCollectionName + "." + dateIds.zero]) { + eventSegments[eventCollectionName + "." + dateIds.zero] = {}; } - common.arrayAddUniq(eventSegments[eventCollectionName]["meta.segments"]["$each"], segKey); - tmpEventColl[segKey] = tmpEventObj; - } - } else if (currEvent.seg_val && currEvent.seg_key) { - tmpEventObj = {}; - - // Mongodb field names can't start with $ or contain . - currEvent.seg_val = currEvent.seg_val.replace(/^\$/, "").replace(/\./g, ":"); - - if (currEvent.sum && common.isNumber(currEvent.sum)) { - common.fillTimeObject(params, tmpEventObj, currEvent.seg_val + '.' + common.dbMap['sum'], currEvent.sum); - } - common.fillTimeObject(params, tmpEventObj, currEvent.seg_val + '.' + common.dbMap['count'], currEvent.count); - - if (!eventSegments[eventCollectionName]) { - eventSegments[eventCollectionName] = {}; - } + if (!eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey]) { + eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey] = {}; + } - if (!eventSegments[eventCollectionName]['meta.' + currEvent.seg_key]) { - eventSegments[eventCollectionName]['meta.' + currEvent.seg_key] = {}; - } + if (eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey]["$each"] && eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey]["$each"].length) { + common.arrayAddUniq(eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey]["$each"], tmpSegVal); + } else { + eventSegments[eventCollectionName + "." + dateIds.zero]['meta.' + segKey]["$each"] = [tmpSegVal]; + } - if (eventSegments[eventCollectionName]['meta.' + currEvent.seg_key]["$each"] && eventSegments[eventCollectionName]['meta.' + currEvent.seg_key]["$each"].length) { - common.arrayAddUniq(eventSegments[eventCollectionName]['meta.' + currEvent.seg_key]["$each"], currEvent.seg_val); - } else { - eventSegments[eventCollectionName]['meta.' + currEvent.seg_key]["$each"] = [currEvent.seg_val]; - } + if (!eventSegments[eventCollectionName + "." + dateIds.zero]["meta.segments"]) { + eventSegments[eventCollectionName + "." + dateIds.zero]["meta.segments"] = {}; + eventSegments[eventCollectionName + "." + dateIds.zero]["meta.segments"]["$each"] = []; + } - if (!eventSegments[eventCollectionName]["meta.segments"]) { - eventSegments[eventCollectionName]["meta.segments"] = {}; - eventSegments[eventCollectionName]["meta.segments"]["$each"] = []; + common.arrayAddUniq(eventSegments[eventCollectionName + "." + dateIds.zero]["meta.segments"]["$each"], segKey); + tmpEventColl[segKey + "." + dateIds.month] = tmpEventObj; } - - common.arrayAddUniq(eventSegments[eventCollectionName]["meta.segments"]["$each"], currEvent.seg_key); - tmpEventColl[currEvent.seg_key] = tmpEventObj; } if (!eventCollections[eventCollectionName]) { @@ -130,20 +229,59 @@ var events = {}, if (!common.config.api.safe) { for (var collection in eventCollections) { - for (var segment in eventCollections[collection]) { - if (segment == "no-segment" && eventSegments[collection]) { - common.db.collection(collection).update({'_id': segment}, {'$inc': eventCollections[collection][segment], '$addToSet': eventSegments[collection]}, {'upsert': true}); - } else { - common.db.collection(collection).update({'_id': segment}, {'$inc': eventCollections[collection][segment]}, {'upsert': true}); + if (eventSegmentsZeroes[collection] && eventSegmentsZeroes[collection].length) { + for (var i = 0; i < eventSegmentsZeroes[collection].length; i++) { + var zeroId = ""; + + if (!eventSegmentsZeroes[collection] || !eventSegmentsZeroes[collection][i]) { + continue; + } else { + zeroId = eventSegmentsZeroes[collection][i]; + } + + common.db.collection(collection).update({'_id': "no-segment_" + zeroId}, {$set: {"m":zeroId, "s":"no-segment"}, '$addToSet': eventSegments[collection + "." + zeroId]}, {'upsert': true}, function(err, res) {}); } } + + for (var segment in eventCollections[collection]) { + var collIdSplits = segment.split("."), + collId = segment.replace(".","_"); + + common.db.collection(collection).update({'_id': collId}, {$set: {"m":collIdSplits[1], "s":collIdSplits[0]}, "$inc":eventCollections[collection][segment]}, {'upsert': true}, function(err, res) {}); + } } } else { var eventDocs = []; for (var collection in eventCollections) { + if (eventSegmentsZeroes[collection] && eventSegmentsZeroes[collection].length) { + for (var i = 0; i < eventSegmentsZeroes[collection].length; i++) { + var zeroId = ""; + + if (!eventSegmentsZeroes[collection] || !eventSegmentsZeroes[collection][i]) { + continue; + } else { + zeroId = eventSegmentsZeroes[collection][i]; + } + + eventDocs.push({ + "collection": collection, + "_id": "no-segment_" + zeroId, + "updateObj": {$set: {"m":zeroId, "s":"no-segment"}, '$addToSet': eventSegments[collection + "." + zeroId]} + }); + } + } + for (var segment in eventCollections[collection]) { - eventDocs.push({c: collection, s: segment}); + var collIdSplits = segment.split("."), + collId = segment.replace(".","_"); + + eventDocs.push({ + "collection": collection, + "_id": collId, + "updateObj": {$set: {"m":collIdSplits[1], "s":collIdSplits[0]}, "$inc":eventCollections[collection][segment]}, + "rollbackObj":eventCollections[collection][segment] + }); } } @@ -167,23 +305,13 @@ var events = {}, }); function updateEventDb(eventDoc, callback) { - if (eventDoc.s == "no-segment" && eventSegments[eventDoc.c]) { - common.db.collection(eventDoc.c).update({'_id': eventDoc.s}, {'$inc': eventCollections[eventDoc.c][eventDoc.s], '$addToSet': eventSegments[eventDoc.c]}, {'upsert': true, 'safe': true}, function(err, result) { - if (err || result != 1) { - callback(false, {status: "failed", obj: eventDoc}); - } else { - callback(false, {status: "ok", obj: eventDoc}); - } - }); - } else { - common.db.collection(eventDoc.c).update({'_id': eventDoc.s}, {'$inc': eventCollections[eventDoc.c][eventDoc.s]}, {'upsert': true, 'safe': true}, function(err, result) { - if (err || result != 1) { - callback(false, {status: "failed", obj: eventDoc}); - } else { - callback(false, {status: "ok", obj: eventDoc}); - } - }); - } + common.db.collection(eventDoc.collection).update({'_id': eventDoc._id}, eventDoc.updateObj, {'upsert': true, 'safe': true}, function(err, result) { + if (err || result != 1) { + callback(false, {status: "failed", obj: eventDoc}); + } else { + callback(false, {status: "ok", obj: eventDoc}); + } + }); } function rollbackEventDb(eventUpdateResult, callback) { @@ -192,8 +320,12 @@ var events = {}, } else { var eventDoc = eventUpdateResult.obj; - common.db.collection(eventDoc.c).update({'_id': eventDoc.s}, {'$inc': getInvertedValues(eventCollections[eventDoc.c][eventDoc.s])}, {'upsert': false}, function(err, result) {}); - callback(true, {}); + if (eventDoc.rollbackObj) { + common.db.collection(eventDoc.collection).update({'_id': eventDoc._id}, {'$inc': getInvertedValues(eventDoc.rollbackObj)}, {'upsert': false}, function(err, result) {}); + callback(true, {}); + } else { + callback(true, {}); + } } } @@ -212,18 +344,27 @@ var events = {}, var eventSegmentList = {'$addToSet': {'list': {'$each': events}}}; for (var event in eventSegments) { - if (!eventSegmentList['$addToSet']["segments." + event.replace(params.app_id, "")]) { - eventSegmentList['$addToSet']["segments." + event.replace(params.app_id, "")] = {}; + var eventSplits = event.split("."), + eventKey = eventSplits[0]; + + var realEventKey = (eventHashMap[eventKey] + "").replace(/\./g,':'); + + if (!eventSegmentList['$addToSet']["segments." + realEventKey]) { + eventSegmentList['$addToSet']["segments." + realEventKey] = {}; } if (eventSegments[event]['meta.segments']) { - eventSegmentList['$addToSet']["segments." + event.replace(params.app_id, "")] = eventSegments[event]['meta.segments']; + if (eventSegmentList['$addToSet']["segments." + realEventKey] && eventSegmentList['$addToSet']["segments." + realEventKey]["$each"]) { + common.arrayAddUniq(eventSegmentList['$addToSet']["segments." + realEventKey]["$each"], eventSegments[event]['meta.segments']["$each"]); + } else { + eventSegmentList['$addToSet']["segments." + realEventKey] = eventSegments[event]['meta.segments']; + } } } common.db.collection('events').update({'_id': params.app_id}, eventSegmentList, {'upsert': true}, function(err, res){}); } - }; + } function mergeEvents(firstObj, secondObj) { for (var firstLevel in secondObj) { @@ -252,6 +393,6 @@ var events = {}, } } -}(events)); +}(countlyEvents)); -module.exports = events; +module.exports = countlyEvents; \ No newline at end of file diff --git a/api/parts/data/fetch.js b/api/parts/data/fetch.js index b8836950c17..87cb3264068 100644 --- a/api/parts/data/fetch.js +++ b/api/parts/data/fetch.js @@ -5,7 +5,10 @@ var fetch = {}, countlyCarrier = require('../../lib/countly.carrier.js'), countlyDeviceDetails = require('../../lib/countly.device.detail.js'), countlyLocation = require('../../lib/countly.location.js'), - countlyCommon = require('../../lib/countly.common.js'); + countlyCommon = require('../../lib/countly.common.js'), + moment = require('moment'), + _ = require('../../node_modules/underscore/underscore.js'), + crypto = require('crypto'); (function (fetch) { @@ -13,20 +16,22 @@ var fetch = {}, if (!params.qstring.event) { common.db.collection('events').findOne({'_id':params.app_id}, function (err, result) { if (result && result.list) { - if (result.order) { + if (result.order && result.order.length) { collection = result.order[0]; } else { result.list.sort(); collection = result.list[0]; } - fetch.fetchEventData(collection + params.app_id, params); + var collectionName = "events" + crypto.createHash('sha1').update(collection + params.app_id).digest('hex'); + fetch.fetchTimeObj(collectionName, params, true); } else { common.returnOutput(params, {}); } }); } else { - fetch.fetchEventData(params.qstring.event + params.app_id, params); + var collectionName = "events" + crypto.createHash('sha1').update(params.qstring.event + params.app_id).digest('hex'); + fetch.fetchTimeObj(collectionName, params, true); } }; @@ -38,8 +43,15 @@ var fetch = {}, fetchFields['meta'] = 1; } - common.db.collection(collection).find({}, fetchFields).toArray(function (err, result) { - if (!result || !result.length) { + if (params.qstring.date == "today") { + fetchFields[params.time.daily + "." + common.dbMap.count] = 1; + fetchFields[params.time.daily + "." + common.dbMap.sum] = 1; + } + + var idToFetch = params.qstring.segmentation || "no-segment"; + + common.db.collection(collection).findOne({_id: idToFetch}, fetchFields, function (err, result) { + if (err || !result) { now = new common.time.Date(); result = {}; result[now.getFullYear()] = {}; @@ -135,9 +147,10 @@ var fetch = {}, } function getEventData(eventKey, callback) { - common.db.collection(eventKey).findOne({"_id": "no-segment"}, {"_id": 0}, function (err, eventData) { - callback(err, eventData || {}); - }); + var collectionName = "events" + crypto.createHash('sha1').update(eventKey).digest('hex'); + fetchTimeObj(collectionName, params, true, function(output) { + callback(null, output || {}); + }); } }; @@ -175,11 +188,11 @@ var fetch = {}, }; fetch.fetchDashboard = function(params) { + params.qstring.period = "30days"; - common.db.collection("sessions").findOne({'_id': params.app_id}, function (err, sessionsDoc) { - common.db.collection("device_details").findOne({'_id': params.app_id}, function (err, deviceDetailsDoc) { - common.db.collection("carriers").findOne({'_id': params.app_id}, function (err, carriersDoc) { - + fetchTimeObj('users', params, false, function(usersDoc) { + fetchTimeObj('device_details', params, false, function(deviceDetailsDoc) { + fetchTimeObj('carriers', params, false, function(carriersDoc) { var output = {}, periods = [ {period: "30days", out: "30days"}, @@ -188,7 +201,7 @@ var fetch = {}, ]; countlyCommon.setTimezone(params.appTimezone); - countlySession.setDb(sessionsDoc || {}); + countlySession.setDb(usersDoc || {}); countlyDeviceDetails.setDb(deviceDetailsDoc || {}); countlyCarrier.setDb(carriersDoc || {}); @@ -214,8 +227,9 @@ var fetch = {}, }; fetch.fetchCountries = function(params) { + params.qstring.period = "30days"; - common.db.collection("locations").findOne({'_id': params.app_id}, function (err, locationsDoc) { + fetchTimeObj('users', params, false, function(locationsDoc) { var output = {}, periods = [ {period: "30days", out: "30days"}, @@ -234,8 +248,342 @@ var fetch = {}, common.returnOutput(params, output); }); + }; + + fetch.fetchSessions = function(params) { + fetchTimeObj('users', params, false, function(usersDoc) { + countlySession.setDb(usersDoc || {}); + common.returnOutput(params, countlySession.getSubperiodData()); + }); + }; + + fetch.fetchMetric = function(params) { + function getMetric(metric){ + fetchTimeObj(metric, params, false, function(doc) { + var clearMetricObject = function (obj) { + if (obj) { + if (!obj["t"]) obj["t"] = 0; + if (!obj["n"]) obj["n"] = 0; + if (!obj["u"]) obj["u"] = 0; + } + else { + obj = {"t":0, "n":0, "u":0}; + } + + return obj; + }; + if (doc['meta'] && doc['meta'][params.qstring.metric]) { + var data = countlyCommon.extractMetricData(doc, doc['meta'][params.qstring.metric], clearMetricObject, [ + { + name:params.qstring.metric, + func:function (rangeArr, dataObj) { + return rangeArr; + } + }, + { "name":"t" }, + { "name":"u" }, + { "name":"n" } + ]); + common.returnOutput(params, data); + } + else{ + common.returnOutput(params, []); + } + }); + } + if(!params.qstring.metric) + common.returnMessage(params, 400, 'Must provide metric'); + else{ + switch (params.qstring.metric) { + case 'locations': + case 'sessions': + case 'users': + getMetric('users'); + break; + case 'app_versions': + case 'device_details': + getMetric('device_details'); + break; + case 'cities': + if (common.config.api.city_data !== false) { + getMetric(params.qstring.metric); + } else { + common.returnOutput(params, []); + } + break; + default: + getMetric(params.qstring.metric); + break; + } + } + }; + + fetch.fetchTimeObj = function (collection, params, isCustomEvent) { + fetchTimeObj(collection, params, isCustomEvent, function(output) { + common.returnOutput(params, output); + }); + }; + + function fetchTimeObj(collection, params, isCustomEvent, callback) { + if (params.qstring.action == "refresh") { + var dbDateIds = common.getDateIds(params), + fetchFromZero = {}, + fetchFromMonth = {}; + + if (isCustomEvent) { + fetchFromZero['meta'] = 1; + fetchFromZero['m'] = 1; + fetchFromMonth["d." + params.time.day] = 1; + fetchFromMonth["m"] = 1; + } else { + fetchFromZero["d." + common.dbMap.unique] = 1; + fetchFromZero["d." + params.time.month + "." + common.dbMap.unique] = 1; + fetchFromZero['meta'] = 1; + fetchFromZero['m'] = 1; + + fetchFromMonth["d.w" + params.time.weekly + "." + common.dbMap.unique] = 1; + fetchFromMonth["d." + params.time.day] = 1; + fetchFromMonth["m"] = 1; + + if (collection == 'users') { + fetchFromZero["d." + common.dbMap.frequency] = 1; + fetchFromZero["d." + common.dbMap.loyalty] = 1; + fetchFromZero["d." + params.time.month + "." + common.dbMap.frequency] = 1; + fetchFromZero["d." + params.time.month + "." + common.dbMap.loyalty] = 1; + + fetchFromMonth["d.w" + params.time.weekly + "." + common.dbMap.frequency] = 1; + fetchFromMonth["d.w" + params.time.weekly + "." + common.dbMap.loyalty] = 1; + } + } + + var zeroIdToFetch = "", + monthIdToFetch = ""; + + if (isCustomEvent) { + var segment = params.qstring.segmentation || "no-segment"; + + zeroIdToFetch = "no-segment_" + dbDateIds.zero; + monthIdToFetch = segment + "_" + dbDateIds.month; + } else { + zeroIdToFetch = params.app_id + "_" + dbDateIds.zero; + monthIdToFetch = params.app_id + "_" + dbDateIds.month; + } + + common.db.collection(collection).findOne({'_id': zeroIdToFetch}, fetchFromZero, function(err, zeroObject) { + common.db.collection(collection).findOne({'_id': monthIdToFetch}, fetchFromMonth, function(err, monthObject) { + var tmpDataArr = []; + tmpDataArr.push(zeroObject); + tmpDataArr.push(monthObject); + + callback(getMergedObj(tmpDataArr, true)); + }); + }); + } else { + var periodObj = getPeriodObj(params), + documents = []; + + if (isCustomEvent) { + var segment = params.qstring.segmentation || "no-segment"; + + for (var i = 0; i < periodObj.reqZeroDbDateIds.length; i++) { + documents.push("no-segment_" + periodObj.reqZeroDbDateIds[i]); + } + + for (var i = 0; i < periodObj.reqMonthDbDateIds.length; i++) { + documents.push(segment + "_" + periodObj.reqMonthDbDateIds[i]); + } + } else { + for (var i = 0; i < periodObj.reqZeroDbDateIds.length; i++) { + documents.push(params.app_id + "_" + periodObj.reqZeroDbDateIds[i]); + } + + for (var i = 0; i < periodObj.reqMonthDbDateIds.length; i++) { + documents.push(params.app_id + "_" + periodObj.reqMonthDbDateIds[i]); + } + } + + common.db.collection(collection).find({'_id': {$in: documents}}, {}).toArray(function(err, dataObjects) { + callback(getMergedObj(dataObjects)); + }); + } + + function getMergedObj(dataObjects, isRefresh) { + var mergedDataObj = {}; + + for (var i = 0; i < dataObjects.length; i++) { + if (!dataObjects[i] || !dataObjects[i].m) { + continue; + } + + var mSplit = dataObjects[i].m.split(":"), + year = mSplit[0], + month = mSplit[1]; + + if (!mergedDataObj[year]) { + mergedDataObj[year] = {}; + } + + if (month == 0) { + if (mergedDataObj['meta']) { + for (var metaEl in dataObjects[i]['meta']) { + if (mergedDataObj['meta'][metaEl]) { + mergedDataObj['meta'][metaEl] = union(mergedDataObj['meta'][metaEl], dataObjects[i]['meta'][metaEl]); + } else { + mergedDataObj['meta'][metaEl] = dataObjects[i]['meta'][metaEl]; + } + } + } else { + mergedDataObj['meta'] = dataObjects[i]['meta'] || []; + } + + if (mergedDataObj[year]) { + for (var prop in dataObjects[i]['d']) { + mergedDataObj[year][prop] = dataObjects[i]['d'][prop]; + } + } else { + mergedDataObj[year] = dataObjects[i]['d'] || {}; + } + } else { + if (mergedDataObj[year][month]) { + for (var prop in dataObjects[i]['d']) { + mergedDataObj[year][month][prop] = dataObjects[i]['d'][prop]; + } + } else { + mergedDataObj[year][month] = dataObjects[i]['d'] || {}; + } + + if (!isRefresh) { + for (var day in dataObjects[i]['d']) { + for (var prop in dataObjects[i]['d'][day]) { + if ((collection == 'users' || dataObjects[i]['s'] == 'no-segment') && prop <= 23 && prop >= 0) { + continue; + } + + if (typeof dataObjects[i]['d'][day][prop] === 'object') { + for (var secondLevel in dataObjects[i]['d'][day][prop]) { + if (secondLevel == common.dbMap.total || secondLevel == common.dbMap.new || + secondLevel == common.dbEventMap.count || secondLevel == common.dbEventMap.sum) { + if (!mergedDataObj[year][month][prop]) { + mergedDataObj[year][month][prop] = {}; + } + + if (mergedDataObj[year][month][prop][secondLevel]) { + mergedDataObj[year][month][prop][secondLevel] += dataObjects[i]['d'][day][prop][secondLevel]; + } else { + mergedDataObj[year][month][prop][secondLevel] = dataObjects[i]['d'][day][prop][secondLevel]; + } + + if (!mergedDataObj[year][prop]) { + mergedDataObj[year][prop] = {}; + } + + if (mergedDataObj[year][prop][secondLevel]) { + mergedDataObj[year][prop][secondLevel] += dataObjects[i]['d'][day][prop][secondLevel]; + } else { + mergedDataObj[year][prop][secondLevel] = dataObjects[i]['d'][day][prop][secondLevel]; + } + } + } + } else if (prop == common.dbMap.total || prop == common.dbMap.new || + prop == common.dbMap.duration || prop == common.dbMap.events || + prop == common.dbEventMap.count || prop == common.dbEventMap.sum) { + + if (mergedDataObj[year][month][prop]) { + mergedDataObj[year][month][prop] += dataObjects[i]['d'][day][prop]; + } else { + mergedDataObj[year][month][prop] = dataObjects[i]['d'][day][prop]; + } + + if (mergedDataObj[year][prop]) { + mergedDataObj[year][prop] += dataObjects[i]['d'][day][prop]; + } else { + mergedDataObj[year][prop] = dataObjects[i]['d'][day][prop]; + } + } + } + } + } + } + } + + return mergedDataObj; + } + } + + fetch.getPeriodObj = function(coll, params) { + common.returnOutput(params, getPeriodObj(params)); + }; + + function getDateName(date, bucket) { + var dateName; + switch (bucket){ + case "daily": + dateName = date.year() + "." + (date.month() + 1) + "." + date.format("D"); + break; + case"weekly": + dateName = date.isoyear() + ".w" + date.isoweek(); + break; + case "monthly": + dateName = date.year() + ".m" + (date.month() + 1); + break; + case "hourly": + dateName = date.year() + "." + (date.month() + 1) + "." + date.format("D") + ".h" + date.format("H"); + break; + } + return dateName; + } + + //returns the union of two arrays + function union(x, y) { + var obj = {}; + for (var i = x.length-1; i >= 0; -- i) { + obj[x[i]] = x[i]; + } + + for (var i = y.length-1; i >= 0; -- i) { + obj[y[i]] = y[i]; + } + + var res = []; + + for (var k in obj) { + res.push(obj[k]); + } + + return res; + } + + //removes the duplicates from array + function unique(x){ + var obj = {}; + for (var i = x.length-1; i >= 0; -- i) { + obj[x[i]] = x[i]; + } + + var res = []; + + for (var k in obj) { + res.push(obj[k]); + } + + return res; } + function getPeriodObj(params) { + params.qstring.period = params.qstring.period || "month"; + if (params.qstring.period && params.qstring.period.indexOf(",") !== -1) { + try { + params.qstring.period = JSON.parse(params.qstring.period); + } catch (SyntaxError) { + return false; + } + } + + countlyCommon.setPeriod(params.qstring.period); + countlyCommon.setTimezone(params.appTimezone); + + return countlyCommon.periodObj; + } }(fetch)); module.exports = fetch; \ No newline at end of file diff --git a/api/parts/data/usage.js b/api/parts/data/usage.js index 5a8c008697e..9bef1a3c28a 100644 --- a/api/parts/data/usage.js +++ b/api/parts/data/usage.js @@ -1,7 +1,7 @@ var usage = {}, common = require('./../../utils/common.js'), geoip = require('geoip-lite'), - time = require('time')(Date); + plugins = require('../../../plugins/pluginManager.js'); (function (usage) { @@ -11,14 +11,12 @@ var usage = {}, var locationData = geoip.lookup(params.ip_address); if (locationData) { - if (locationData.country) { + if (params.user.country == "Unknown" && locationData.country) { params.user.country = locationData.country; } - if (locationData.city) { + if (params.user.city == "Unknown" && locationData.city) { params.user.city = locationData.city; - } else { - params.user.city = 'Unknown'; } // Coordinate values of the user location has no use for now @@ -27,7 +25,6 @@ var usage = {}, params.user.lng = locationData.ll[1]; } } - common.db.collection('app_users' + params.app_id).findOne({'_id': params.app_user_id }, function (err, dbAppUser){ processUserSession(dbAppUser, params); }); @@ -52,7 +49,7 @@ var usage = {}, // We can't use the params.time.timestamp since we are inside a setTimeout // and we need the actual timestamp - currDateWithoutTimestamp.setTimezone(params.appTimezone); + currDateWithoutTimestamp.setTimezone(params.appTimezone); var currTimestamp = Math.round(currDateWithoutTimestamp.getTime() / 1000); @@ -69,11 +66,12 @@ var usage = {}, } else { endSession(); } - function endSession(overrideFlag) { // If user does not have an ongoing session end it // Ongoing session flag is set inside processUserSession if (overrideFlag || !dbAppUser[common.dbUserMap['has_ongoing_session']]) { + + plugins.dispatch("/session/end", {params:params, dbAppUser:dbAppUser}); // If the user does not exist in the app_users collection or she does not have any // previous session duration stored than we dont need to calculate the session @@ -89,27 +87,33 @@ var usage = {}, }; usage.processSessionDuration = function (params, callback) { - - var updateSessions = {}, + var updateUsers = {}, session_duration = parseInt(params.qstring.session_duration); - if (!isNaN(session_duration) && session_duration > 0) { + if (session_duration == (session_duration | 0)) { if (common.config.api.session_duration_limit && session_duration > common.config.api.session_duration_limit) { session_duration = common.config.api.session_duration_limit; } - common.fillTimeObject(params, updateSessions, common.dbMap['duration'], session_duration); + if (session_duration < 0) { + session_duration = 30; + } + + common.fillTimeObjectMonth(params, updateUsers, common.dbMap['events']); + common.fillTimeObjectMonth(params, updateUsers, common.dbMap['duration'], session_duration); - common.db.collection('sessions').update({'_id': params.app_id}, {'$inc': updateSessions}, {'upsert': false}); + var dbDateIds = common.getDateIds(params); + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.month}, {'$inc': updateUsers}, function(){}); // sd: session duration, tsd: total session duration. common.dbUserMap is not used here for readability purposes. common.db.collection('app_users' + params.app_id).update({'_id': params.app_user_id}, {'$inc': {'sd': session_duration, 'tsd': session_duration}}, {'upsert': true}, function() { + + plugins.dispatch("/session/duration", {params:params, session_duration:session_duration}); + if (callback) { callback(); } }); - } else if (callback) { // session_duration was a bad value, but callback still needs to be called - callback(); } }; @@ -125,7 +129,10 @@ var usage = {}, ], durationMax = 3601, calculatedDurationRange, - updateSessions = {}; + updateUsers = {}, + updateUsersZero = {}, + dbDateIds = common.getDateIds(params), + monthObjUpdate = []; if (totalSessionDuration >= durationMax) { calculatedDurationRange = (durationRanges.length) + ''; @@ -138,26 +145,22 @@ var usage = {}, } } - // check that calculatedDurationRange is not undefined; shouldn't happen now that the server - // rejects session durations less than 1 second, but check anyways to make sure we don't put - // 'ds.undefined' into the database, or add 'null' to 'meta.d-ranges'. - if (calculatedDurationRange != undefined) { - common.fillTimeObject(params, updateSessions, common.dbMap['durations'] + '.' + calculatedDurationRange); - common.db.collection('sessions').update({'_id': params.app_id}, {'$inc': updateSessions, '$addToSet': {'meta.d-ranges': calculatedDurationRange}}, {'upsert': false}); - } + monthObjUpdate.push(common.dbMap['events']); + monthObjUpdate.push(common.dbMap['durations'] + '.' + calculatedDurationRange); + common.fillTimeObjectMonth(params, updateUsers, monthObjUpdate); + common.fillTimeObjectZero(params, updateUsersZero, common.dbMap['durations'] + '.' + calculatedDurationRange); + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.month}, {'$inc': updateUsers}, function(){}); + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.zero}, {'$inc': updateUsersZero, '$addToSet': {'meta.d-ranges': calculatedDurationRange}}, function(){}); // sd: session duration. common.dbUserMap is not used here for readability purposes. - // regardless of whether or not the 'sessions' collection was updated above, still need to - // clear user's current session duration - common.db.collection('app_users' + params.app_id).update({'_id': params.app_user_id}, {'$set': {'sd': 0}}, {'upsert': true}); + common.db.collection('app_users' + params.app_id).update({'_id': params.app_user_id}, {'$set': {'sd': 0}}, {'upsert': true}, function(){}); } function processUserSession(dbAppUser, params) { - var updateSessions = {}, - updateUsers = {}, - updateLocations = {}, + var updateUsersZero = {}, + updateUsersMonth = {}, updateCities = {}, - userRanges = {}, + usersMeta = {}, loyaltyRanges = [ [0,1], [2,2], @@ -186,14 +189,16 @@ var usage = {}, loyaltyMax = 500, calculatedLoyaltyRange, uniqueLevels = [], - isNewUser = false; + uniqueLevelsZero = [], + uniqueLevelsMonth = [], + isNewUser = false, + zeroObjUpdate = [], + monthObjUpdate = [], + dbDateIds = common.getDateIds(params); - common.fillTimeObject(params, updateSessions, common.dbMap['total']); - common.fillTimeObject(params, updateLocations, params.user.country + '.' + common.dbMap['total']); - - if (common.config.api.city_data !== false) { - common.fillTimeObject(params, updateCities, params.user.city + '.' + common.dbMap['total']); - } + monthObjUpdate.push(common.dbMap['events']); + monthObjUpdate.push(common.dbMap['total']); + monthObjUpdate.push(params.user.country + '.' + common.dbMap['total']); if (dbAppUser && dbAppUser[common.dbUserMap['first_seen']]) { var userLastSeenTimestamp = dbAppUser[common.dbUserMap['last_seen']], @@ -209,6 +214,8 @@ var usage = {}, var lastEndSession = dbAppUser[common.dbUserMap['last_end_session_timestamp']]; if (lastEndSession && (params.time.nowWithoutTimestamp.unix() - lastEndSession) < 15) { + plugins.dispatch("/session/extend", {params:params}); + var userProps = {}; userProps[common.dbUserMap['has_ongoing_session']] = true; userProps[common.dbUserMap['last_begin_session_timestamp']] = params.time.nowWithoutTimestamp.unix(); @@ -247,84 +254,104 @@ var usage = {}, } } - if (userLastSeenDate.getFullYear() == params.time.yearly && - Math.ceil(common.moment(userLastSeenDate).format("DDD") / 7) < params.time.weekly) { - uniqueLevels[uniqueLevels.length] = params.time.yearly + ".w" + params.time.weekly; - } - if (userLastSeenTimestamp < (params.time.timestamp - secInMin)) { // We don't need to put hourly fragment to the unique levels array since // we will store hourly data only in sessions collection - updateSessions[params.time.hourly + '.' + common.dbMap['unique']] = 1; + updateUsersMonth['d.' + params.time.day + '.' + params.time.hour + '.' + common.dbMap['unique']] = 1; } if (userLastSeenTimestamp < (params.time.timestamp - secInHour)) { uniqueLevels[uniqueLevels.length] = params.time.daily; + uniqueLevelsMonth.push(params.time.day); + } + + if (userLastSeenDate.getFullYear() == params.time.yearly && + Math.ceil(common.moment(userLastSeenDate).format("DDD") / 7) < params.time.weekly) { + uniqueLevels[uniqueLevels.length] = params.time.yearly + ".w" + params.time.weekly; + uniqueLevelsZero.push("w" + params.time.weekly); } if (userLastSeenTimestamp < (params.time.timestamp - secInMonth)) { uniqueLevels[uniqueLevels.length] = params.time.monthly; + uniqueLevelsZero.push(params.time.month); } if (userLastSeenTimestamp < (params.time.timestamp - secInYear)) { uniqueLevels[uniqueLevels.length] = params.time.yearly; + uniqueLevelsZero.push("Y"); } - for (var i = 0; i < uniqueLevels.length; i++) { - updateSessions[uniqueLevels[i] + '.' + common.dbMap['unique']] = 1; - updateLocations[uniqueLevels[i] + '.' + params.user.country + '.' + common.dbMap['unique']] = 1; - updateUsers[uniqueLevels[i] + '.' + common.dbMap['frequency'] + '.' + calculatedFrequency] = 1; - updateUsers[uniqueLevels[i] + '.' + common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange] = 1; - - if (common.config.api.city_data !== false) { - updateCities[uniqueLevels[i] + '.' + params.user.city + '.' + common.dbMap['unique']] = 1; + for (var k = 0; k < uniqueLevelsZero.length; k++) { + if (uniqueLevelsZero[k] == "Y") { + updateUsersZero['d.' + common.dbMap['unique']] = 1; + updateUsersZero['d.' + common.dbMap['frequency'] + '.' + calculatedFrequency] = 1; + updateUsersZero['d.' + common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange] = 1; + updateUsersZero['d.' + params.user.country + '.' + common.dbMap['unique']] = 1; + } else { + updateUsersZero['d.' + uniqueLevelsZero[k] + '.' + common.dbMap['unique']] = 1; + updateUsersZero['d.' + uniqueLevelsZero[k] + '.' + common.dbMap['frequency'] + '.' + calculatedFrequency] = 1; + updateUsersZero['d.' + uniqueLevelsZero[k] + '.' + common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange] = 1; + updateUsersZero['d.' + uniqueLevelsZero[k] + '.' + params.user.country + '.' + common.dbMap['unique']] = 1; } } - if (uniqueLevels.length != 0) { - userRanges['meta.' + 'f-ranges'] = calculatedFrequency; - userRanges['meta.' + 'l-ranges'] = calculatedLoyaltyRange; - common.db.collection('users').update({'_id': params.app_id}, {'$inc': updateUsers, '$addToSet': userRanges}, {'upsert': true}); + for (var l = 0; l < uniqueLevelsMonth.length; l++) { + updateUsersMonth['d.' + uniqueLevelsMonth[l] + '.' + common.dbMap['unique']] = 1; + updateUsersMonth['d.' + uniqueLevelsMonth[l] + '.' + common.dbMap['frequency'] + '.' + calculatedFrequency] = 1; + updateUsersMonth['d.' + uniqueLevelsMonth[l] + '.' + common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange] = 1; + updateUsersMonth['d.' + uniqueLevelsMonth[l] + '.' + params.user.country + '.' + common.dbMap['unique']] = 1; } + + if (uniqueLevelsZero.length != 0 || uniqueLevelsMonth.length != 0) { + usersMeta['meta.f-ranges'] = calculatedFrequency; + usersMeta['meta.l-ranges'] = calculatedLoyaltyRange; + } + + plugins.dispatch("/session/begin", {params:params, isNewUser:isNewUser}); } else { isNewUser = true; // User is not found in app_users collection so this means she is both a new and unique user. - common.fillTimeObject(params, updateSessions, common.dbMap['new']); - common.fillTimeObject(params, updateSessions, common.dbMap['unique']); - common.fillTimeObject(params, updateLocations, params.user.country + '.' + common.dbMap['new']); - common.fillTimeObject(params, updateLocations, params.user.country + '.' + common.dbMap['unique']); - - if (common.config.api.city_data !== false) { - common.fillTimeObject(params, updateCities, params.user.city + '.' + common.dbMap['new']); - common.fillTimeObject(params, updateCities, params.user.city + '.' + common.dbMap['unique']); - } + zeroObjUpdate.push(common.dbMap['unique']); + monthObjUpdate.push(common.dbMap['new']); + monthObjUpdate.push(common.dbMap['unique']); + + zeroObjUpdate.push(params.user.country + '.' + common.dbMap['unique']); + monthObjUpdate.push(params.user.country + '.' + common.dbMap['new']); + monthObjUpdate.push(params.user.country + '.' + common.dbMap['unique']); // First time user. calculatedLoyaltyRange = '0'; calculatedFrequency = '0'; - common.fillTimeObject(params, updateUsers, common.dbMap['frequency'] + '.' + calculatedFrequency); - userRanges['meta.' + 'f-ranges'] = calculatedFrequency; + zeroObjUpdate.push(common.dbMap['frequency'] + '.' + calculatedFrequency); + monthObjUpdate.push(common.dbMap['frequency'] + '.' + calculatedFrequency); + zeroObjUpdate.push(common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange); + monthObjUpdate.push(common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange); - common.fillTimeObject(params, updateUsers, common.dbMap['loyalty'] + '.' + calculatedLoyaltyRange); - userRanges['meta.' + 'l-ranges'] = calculatedLoyaltyRange; + usersMeta['meta.f-ranges'] = calculatedFrequency; + usersMeta['meta.l-ranges'] = calculatedLoyaltyRange; - common.db.collection('users').update({'_id': params.app_id}, {'$inc': updateUsers, '$addToSet': userRanges}, {'upsert': true}); + plugins.dispatch("/session/begin", {params:params, isNewUser:isNewUser}); } - common.db.collection('sessions').update({'_id': params.app_id}, {'$inc': updateSessions}, {'upsert': true}); - common.db.collection('locations').update({'_id': params.app_id}, {'$inc': updateLocations, '$addToSet': {'meta.countries': params.user.country}}, {'upsert': true}); + usersMeta['meta.countries'] = params.user.country; - if (common.config.api.city_data !== false && params.app_cc == params.user.country) { - common.db.collection('cities').update({'_id': params.app_id}, {'$inc': updateCities, '$set': {'country': params.user.country}, '$addToSet': {'meta.cities': params.user.city}}, {'upsert': true}); + common.fillTimeObjectZero(params, updateUsersZero, zeroObjUpdate); + common.fillTimeObjectMonth(params, updateUsersMonth, monthObjUpdate); + + if (Object.keys(updateUsersZero).length || Object.keys(usersMeta).length) { + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.zero}, {$set: {m: dbDateIds.zero, a: params.app_id + ""}, '$inc': updateUsersZero, '$addToSet': usersMeta}, {'upsert': true}, function(){}); } - processMetrics(dbAppUser, uniqueLevels, params); - } + common.db.collection('users').update({'_id': params.app_id + "_" + dbDateIds.month}, {$set: {m: dbDateIds.month, a: params.app_id + ""}, '$inc': updateUsersMonth}, {'upsert': true}, function(){}); + + processMetrics(dbAppUser, uniqueLevelsZero, uniqueLevelsMonth, params); - function processMetrics(user, uniqueLevels, params) { + plugins.dispatch("/session/user", {params:params, dbAppUser:dbAppUser}); + } + function processMetrics(user, uniqueLevelsZero, uniqueLevelsMonth, params) { var userProps = {}, isNewUser = (user && user[common.dbUserMap['first_seen']])? false : true; @@ -352,69 +379,145 @@ var usage = {}, } } - if (!params.qstring.metrics) { - // sc: session count. common.dbUserMap is not used here for readability purposes. - common.db.collection('app_users' + params.app_id).update({'_id':params.app_user_id}, {'$inc':{'sc':1}, '$set':userProps}, {'upsert':true}, function () { - }); - return false; - } - var predefinedMetrics = [ - { db: "devices", metrics: [{ name: "_device", set: "devices", short_code: common.dbUserMap['device'] }] }, - { db: "carriers", metrics: [{ name: "_carrier", set: "carriers", short_code: common.dbUserMap['carrier'] }] }, - { db: "device_details", metrics: [ - { name: "_os", set: "os", short_code: common.dbUserMap['platform'] }, - { name: "_os_version", set: "os_versions", short_code: common.dbUserMap['platform_version'] }, - { name: "_resolution", set: "resolutions" }, - { name: "_density", set: "densities" }] }, - { db: "app_versions", metrics: [{ name: "_app_version", set: "app_versions", short_code: common.dbUserMap['app_version'] }] } + { + db: "carriers", + metrics: [{ name: "_carrier", set: "carriers", short_code: common.dbUserMap['carrier'] }] + }, + { + db: "devices", + metrics: [{ name: "_device", set: "devices", short_code: common.dbUserMap['device'] }] + }, + { + db: "device_details", + metrics: [ + { name: "_app_version", set: "app_versions", short_code: common.dbUserMap['app_version'] }, + { name: "_os", set: "os", short_code: common.dbUserMap['platform'] }, + { name: "_os_version", set: "os_versions", short_code: common.dbUserMap['platform_version'] }, + { name: "_resolution", set: "resolutions", short_code: common.dbUserMap['resolution'] } + ] + }, + { + db: "cities", + metrics: [{ is_user_prop:true, name: "city", set: "cities", short_code: common.dbUserMap['city'] }] + } ]; + + plugins.dispatch("/session/metrics", {params:params, predefinedMetrics:predefinedMetrics, userProps:userProps, user:user, isNewUser:isNewUser}); for (var i=0; i < predefinedMetrics.length; i++) { - var tmpTimeObj = {}, + var tmpTimeObjZero = {}, + tmpTimeObjMonth = {}, tmpSet = {}, - needsUpdate = false; + needsUpdate = false, + zeroObjUpdate = [], + monthObjUpdate = []; for (var j=0; j < predefinedMetrics[i].metrics.length; j++) { var tmpMetric = predefinedMetrics[i].metrics[j], + recvMetricValue = "", + escapedMetricVal = ""; + + if (tmpMetric.is_user_prop) { + recvMetricValue = params.user[tmpMetric.name]; + } else if (params.qstring.metrics && params.qstring.metrics[tmpMetric.name]) { recvMetricValue = params.qstring.metrics[tmpMetric.name]; + } + + // We check if city data logging is on and user's country is the configured country of the app + if (tmpMetric.name == "city" && (common.config.api.city_data === false || params.app_cc != params.user.country)) { + continue; + } if (recvMetricValue) { - var escapedMetricVal = (recvMetricValue+"").replace(/^\$/, "").replace(/\./g, ":"); + //making sure metrics are strings + escapedMetricVal = (recvMetricValue+"").replace(/^\$/, "").replace(/\./g, ":"); needsUpdate = true; tmpSet["meta." + tmpMetric.set] = escapedMetricVal; - common.fillTimeObject(params, tmpTimeObj, escapedMetricVal + '.' + common.dbMap['total']); + + monthObjUpdate.push(escapedMetricVal + '.' + common.dbMap['total']); if (isNewUser) { - common.fillTimeObject(params, tmpTimeObj, escapedMetricVal + '.' + common.dbMap['new']); - common.fillTimeObject(params, tmpTimeObj, escapedMetricVal + '.' + common.dbMap['unique']); - } else if (tmpMetric.short_code && user[tmpMetric.short_code] != escapedMetricVal) { - common.fillTimeObject(params, tmpTimeObj, escapedMetricVal + '.' + common.dbMap['unique']); + zeroObjUpdate.push(escapedMetricVal + '.' + common.dbMap['unique']); + monthObjUpdate.push(escapedMetricVal + '.' + common.dbMap['new']); + monthObjUpdate.push(escapedMetricVal + '.' + common.dbMap['unique']); + } else if (!tmpMetric.is_user_prop && tmpMetric.short_code && user[tmpMetric.short_code] != escapedMetricVal) { + zeroObjUpdate.push(escapedMetricVal + '.' + common.dbMap['unique']); + monthObjUpdate.push(escapedMetricVal + '.' + common.dbMap['unique']) } else { - for (var k=0; k < uniqueLevels.length; k++) { - tmpTimeObj[uniqueLevels[k] + '.' + escapedMetricVal + '.' + common.dbMap['unique']] = 1; + for (var k=0; k < uniqueLevelsZero.length; k++) { + if (uniqueLevelsZero[k] == "Y") { + tmpTimeObjZero['d.' + escapedMetricVal + '.' + common.dbMap['unique']] = 1; + } else { + tmpTimeObjZero['d.' + uniqueLevelsZero[k] + '.' + escapedMetricVal + '.' + common.dbMap['unique']] = 1; + } + } + + for (var l=0; l < uniqueLevelsMonth.length; l++) { + tmpTimeObjMonth['d.' + uniqueLevelsMonth[l] + '.' + escapedMetricVal + '.' + common.dbMap['unique']] = 1; } } // Assign properties to app_users document of the current user - if (tmpMetric.short_code) { - if (isNewUser || (!isNewUser && user[tmpMetric.short_code] != escapedMetricVal)) { - userProps[tmpMetric.short_code] = escapedMetricVal; - } + if (isNewUser || (!isNewUser && user[tmpMetric.short_code] != escapedMetricVal)) { + userProps[tmpMetric.short_code] = escapedMetricVal; } } } + common.fillTimeObjectZero(params, tmpTimeObjZero, zeroObjUpdate); + common.fillTimeObjectMonth(params, tmpTimeObjMonth, monthObjUpdate); + if (needsUpdate) { - common.db.collection(predefinedMetrics[i].db).update({'_id': params.app_id}, {'$inc': tmpTimeObj, '$addToSet': tmpSet}, {'upsert': true}); + var dateIds = common.getDateIds(params), + tmpZeroId = params.app_id + "_" + dateIds.zero, + tmpMonthId = params.app_id + "_" + dateIds.month; + + if (Object.keys(tmpTimeObjZero).length || Object.keys(tmpSet).length) { + common.db.collection(predefinedMetrics[i].db).update({'_id': tmpZeroId}, {$set: {m: dateIds.zero, a: params.app_id + ""}, '$inc': tmpTimeObjZero, '$addToSet': tmpSet}, {'upsert': true}, function(){}); + } + + common.db.collection(predefinedMetrics[i].db).update({'_id': tmpMonthId}, {$set: {m: dateIds.month, a: params.app_id + ""}, '$inc': tmpTimeObjMonth}, {'upsert': true}, function(){}); } } - // sc: session count. common.dbUserMap is not used here for readability purposes. - common.db.collection('app_users' + params.app_id).update({'_id':params.app_user_id}, {'$inc':{'sc':1}, '$set':userProps}, {'upsert':true}, function () { - }); + if (isNewUser) { + common.db.collection('app_users' + params.app_id).findAndModify({_id:"uid-sequence"},{},{$inc:{seq:1}},{new:true}, function(err,result){ + if (result && result.length != 0) { + userProps[common.dbUserMap['user_id']] = parseSequence(result.seq); + } + common.db.collection('app_users' + params.app_id).update({'_id': params.app_user_id}, {'$inc': {'sc': 1}, '$set': userProps}, {'upsert': true}, function() { + //Perform user retention analysis + plugins.dispatch("/session/retention", {params:params, user:user, isNewUser:isNewUser}); + }); + }); + } else { + // sc: session count. common.dbUserMap is not used here for readability purposes. + common.db.collection('app_users' + params.app_id).update({'_id': params.app_user_id}, {'$inc': {'sc': 1}, '$set': userProps}, {'upsert': true}, function() { + //Perform user retention analysis + plugins.dispatch("/session/retention", {params:params, user:user, isNewUser:isNewUser}); + }); + } + + return true; + } + + function parseSequence(num){ + var valSeq = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]; + var digits = []; + var base = valSeq.length; + while (num > base-1){ + digits.push(num % base); + num = Math.floor(num / base); + } + digits.push(num); + var result = ""; + for(var i = digits.length-1; i>=0; --i){ + result = result + valSeq[digits[i]]; + } + return result; } }(usage)); -module.exports = usage; \ No newline at end of file +module.exports = usage; diff --git a/api/parts/mgmt/apps.js b/api/parts/mgmt/apps.js index fc87623d991..5c9a6c97227 100644 --- a/api/parts/mgmt/apps.js +++ b/api/parts/mgmt/apps.js @@ -1,5 +1,7 @@ var appsApi = {}, common = require('./../../utils/common.js'), + crypto = require('crypto'), + plugins = require('../../../plugins/pluginManager.js'), fs = require('fs'); (function (appsApi) { @@ -88,6 +90,8 @@ var appsApi = {}, newApp._id = app[0]._id; newApp.key = appKey; + common.db.collection('app_users' + app[0]._id).insert({_id:"uid-sequence", seq:0},function(err,res){}); + plugins.dispatch("/i/apps/create", {params:params, appId:app[0]._id}); common.returnOutput(params, newApp); }); }; @@ -114,21 +118,26 @@ var appsApi = {}, processAppProps(updatedApp); - if (params.member && params.member.global_admin) { - common.db.collection('apps').update({'_id': common.db.ObjectID(params.qstring.args.app_id)}, {$set: updatedApp}, function(err, app) { - common.returnOutput(params, updatedApp); - }); - } else { - common.db.collection('members').findOne({'_id': params.member._id}, {admin_of: 1}, function(err, member){ - if (member.admin_of && member.admin_of.indexOf(params.qstring.args.app_id) !== -1) { - common.db.collection('apps').update({'_id': common.db.ObjectID(params.qstring.args.app_id)}, {$set: updatedApp}, function(err, app) { - common.returnOutput(params, updatedApp); - }); - } else { - common.returnMessage(params, 401, 'User does not have admin rights for this app'); - } - }); - } + common.db.collection('apps').findOne(common.db.ObjectID(params.qstring.args.app_id), function(err, app){ + if (err || !app) common.returnMessage(params, 404, 'App not found'); + else { + if (params.member && params.member.global_admin) { + common.db.collection('apps').update({'_id': common.db.ObjectID(params.qstring.args.app_id)}, {$set: updatedApp}, function(err, app) { + common.returnOutput(params, updatedApp); + }); + } else { + common.db.collection('members').findOne({'_id': params.member._id}, {admin_of: 1}, function(err, member){ + if (member.admin_of && member.admin_of.indexOf(params.qstring.args.app_id) !== -1) { + common.db.collection('apps').update({'_id': common.db.ObjectID(params.qstring.args.app_id)}, {$set: updatedApp}, function(err, app) { + common.returnOutput(params, updatedApp); + }); + } else { + common.returnMessage(params, 401, 'User does not have admin rights for this app'); + } + }); + } + } + }); return true; }; @@ -161,7 +170,7 @@ var appsApi = {}, common.db.collection('members').update({}, {$pull: {'apps': appId, 'admin_of': appId, 'user_of': appId}}, {multi: true}, function(err, app) {}); - deleteAppData(appId); + deleteAppData(appId, true); common.returnMessage(params, 200, 'Success'); return true; }); @@ -197,26 +206,37 @@ var appsApi = {}, return true; }; - function deleteAppData(appId) { - common.db.collection('sessions').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('users').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('carriers').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('locations').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('cities').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('app_users' + appId).drop(); - common.db.collection('devices').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('device_details').remove({'_id': common.db.ObjectID(appId)}); - common.db.collection('app_versions').remove({'_id': common.db.ObjectID(appId)}); + function deleteAppData(appId, fromAppDelete) { + common.db.collection('users').remove({'_id': {$regex: appId + ".*"}},function(){}); + common.db.collection('carriers').remove({'_id': {$regex: appId + ".*"}},function(){}); + common.db.collection('devices').remove({'_id': {$regex: appId + ".*"}},function(){}); + common.db.collection('device_details').remove({'_id': {$regex: appId + ".*"}},function(){}); + common.db.collection('cities').remove({'_id': {$regex: appId + ".*"}},function(){}); + + common.db.collection('app_users' + appId).drop(function() { + if (!fromAppDelete) { + common.db.collection('app_users' + appId).insert({_id:"uid-sequence", seq:0},function(){}); + } + }); + if (!fromAppDelete) + plugins.dispatch("/i/apps/reset", {appId:appId}); + else + plugins.dispatch("/i/apps/delete", {appId:appId}); common.db.collection('events').findOne({'_id': common.db.ObjectID(appId)}, function(err, events) { if (!err && events && events.list) { for (var i = 0; i < events.list.length; i++) { - common.db.collection(events.list[i] + appId).drop(); + var collectionNameWoPrefix = crypto.createHash('sha1').update(events.list[i] + appId).digest('hex'); + common.db.collection("events" + collectionNameWoPrefix).drop(function(){}); } - common.db.collection('events').remove({'_id': common.db.ObjectID(appId)}); + common.db.collection('events').remove({'_id': common.db.ObjectID(appId)},function(){}); } }); + + if (fromAppDelete) { + common.db.collection('graph_notes').remove({'_id': common.db.ObjectID(appId)},function(){}); + } } function packApps(apps) { diff --git a/api/parts/mgmt/users.js b/api/parts/mgmt/users.js index 5083e86cb0f..31448fc727a 100644 --- a/api/parts/mgmt/users.js +++ b/api/parts/mgmt/users.js @@ -34,8 +34,8 @@ var usersApi = {}, 'full_name':members[i].full_name, 'username':members[i].username, 'email':members[i].email, - 'admin_of':members[i].admin_of, - 'user_of':members[i].user_of, + 'admin_of':((members[i].admin_of && members[i].admin_of.length > 0 && members[i].admin_of[0] != "") ? members[i].admin_of : []), + 'user_of':((members[i].user_of && members[i].user_of.length > 0 && members[i].user_of[0] != "") ? members[i].user_of : []), 'global_admin':(members[i].global_admin === true), 'is_current_user':(members[i].api_key == params.member.api_key) }; @@ -89,7 +89,7 @@ var usersApi = {}, if (member && member.length && !err) { member[0].api_key = common.md5Hash(member[0]._id + (new Date().getTime())); - common.db.collection('members').update({'_id': member[0]._id}, {$set: {api_key: member[0].api_key}}); + common.db.collection('members').update({'_id': member[0]._id}, {$set: {api_key: member[0].api_key}},function(){}); mail.sendToNewMember(member[0], passwordNoHash); @@ -169,10 +169,10 @@ var usersApi = {}, for (var i = 0; i < userIds.length; i++) { // Each user id should be 24 chars long and a user can't delete his own account - if (userIds[i] === params.member._id || userIds[i].length !== 24) { + if (!userIds[i] || userIds[i] === params.member._id || userIds[i].length !== 24) { continue; } else { - common.db.collection('members').remove({'_id': common.db.ObjectID(userIds[i])}); + common.db.collection('members').remove({'_id': common.db.ObjectID(userIds[i])},function(){}); } } diff --git a/api/utils/common.js b/api/utils/common.js index bb61715d8e7..d88dd3bb81c 100644 --- a/api/utils/common.js +++ b/api/utils/common.js @@ -22,8 +22,10 @@ var common = {}, common.dbUserMap = { 'device_id': 'did', + 'user_id' : 'uid', 'first_seen': 'fs', 'last_seen': 'ls', + 'last_payment': 'lp', 'session_duration': 'sd', 'total_session_duration': 'tsd', 'session_count': 'sc', @@ -36,22 +38,47 @@ var common = {}, 'app_version': 'av', 'last_begin_session_timestamp': 'lbst', 'last_end_session_timestamp': 'lest', - 'has_ongoing_session': 'hos' + 'has_ongoing_session': 'hos', + 'resolution': 'r' }; - var dbName; - var dbOptions = { safe:false, maxPoolSize: countlyConfig.mongodb.max_pool_size || 1000 }; + common.dbEventMap = { + 'user_properties':'up', + 'timestamp':'ts', + 'segmentations':'sg', + 'count':'c', + 'sum':'s' + }; + //mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] + var dbName; + var dbOptions = {db:{safe:false}, server:{auto_reconnect:true}}; + var optString = "?maxPoolSize="+(countlyConfig.mongodb.max_pool_size || 500); + countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; if (typeof countlyConfig.mongodb === "string") { dbName = countlyConfig.mongodb; } else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ - dbName = countlyConfig.mongodb.replSetServers; - dbOptions.database = countlyConfig.mongodb.db || 'countly'; + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(",")+"/"+countlyConfig.mongodb.db; + dbOptions.replSet = {auto_reconnect:true, poolSize: countlyConfig.mongodb.max_pool_size || 500 }; + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } } else { - dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port + '/' + countlyConfig.mongodb.db + '?auto_reconnect=true'); + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port + '/' + countlyConfig.mongodb.db); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } } - + if(dbName.indexOf("mongodb://") !== 0){ + dbName = "mongodb://"+dbName; + } + dbName = dbName+optString; + common.db = mongo.db(dbName, dbOptions); + common.db._emitter.setMaxListeners(0); + if(!common.db.ObjectID) + common.db.ObjectID = mongo.ObjectID; common.config = countlyConfig; @@ -78,6 +105,15 @@ var common = {}, return !isNaN(parseFloat(n)) && isFinite(n); }; + common.safeDivision = function(dividend, divisor) { + var tmpAvgVal; + tmpAvgVal = dividend / divisor; + if(!tmpAvgVal || tmpAvgVal == Number.POSITIVE_INFINITY){ + tmpAvgVal = 0; + } + return tmpAvgVal; + } + common.zeroFill = function(number, width) { width -= number.toString().length; @@ -89,8 +125,20 @@ var common = {}, }; common.arrayAddUniq = function (arr, item) { - if (arr.indexOf(item) === -1) { - arr[arr.length] = item; + if (!arr) { + arr = []; + } + + if (toString.call(item) === "[object Array]") { + for (var i = 0; i < item.length; i++) { + if (arr.indexOf(item[i]) === -1) { + arr[arr.length] = item[i]; + } + } + } else { + if (arr.indexOf(item) === -1) { + arr[arr.length] = item; + } } }; @@ -127,7 +175,8 @@ var common = {}, property == common.dbMap["unique"] || property.substr(0,2) == (common.dbMap["frequency"] + ".") || property.substr(0,2) == (common.dbMap["loyalty"] + ".") || - property.substr(0,3) == (common.dbMap["durations"] + ".")) + property.substr(0,3) == (common.dbMap["durations"] + ".") || + property == common.dbMap["paying"]) { object[timeObj.yearly + ".w" + timeObj.weekly + '.' + property] = increment; } @@ -139,18 +188,22 @@ var common = {}, currDate, currDateWithoutTimestamp = new Date(); - // Check if the timestamp parameter exists in the request and is a 10 digit integer + // Check if the timestamp parameter exists in the request and is a 10 or 13 digit integer if (reqTimestamp && (reqTimestamp + "").length === 10 && common.isNumber(reqTimestamp)) { // If the received timestamp is greater than current time use the current time as timestamp currTimestamp = (reqTimestamp > time.time()) ? time.time() : parseInt(reqTimestamp, 10); currDate = new Date(currTimestamp * 1000); + } else if (reqTimestamp && (reqTimestamp + "").length === 13 && common.isNumber(reqTimestamp)) { + var tmpTimestamp = Math.round(parseInt(reqTimestamp, 10) / 1000); + currTimestamp = (tmpTimestamp > time.time()) ? time.time() : tmpTimestamp; + currDate = new Date(currTimestamp * 1000); } else { currTimestamp = time.time(); // UTC currDate = new Date(); } - - currDate.setTimezone(appTimezone); - currDateWithoutTimestamp.setTimezone(appTimezone); + + currDate.setTimezone(appTimezone); + currDateWithoutTimestamp.setTimezone(appTimezone); var tmpMoment = moment(currDate); @@ -163,7 +216,10 @@ var common = {}, monthly: tmpMoment.format("YYYY.M"), daily: tmpMoment.format("YYYY.M.D"), hourly: tmpMoment.format("YYYY.M.D.H"), - weekly: Math.ceil(tmpMoment.format("DDD") / 7) + weekly: Math.ceil(tmpMoment.format("DDD") / 7), + month: tmpMoment.format("M"), + day: tmpMoment.format("D"), + hour: tmpMoment.format("H") }; }; @@ -172,7 +228,7 @@ var common = {}, var tmpDate = (timestamp)? new Date(timestamp * 1000) : new Date(); if (timezone) { - tmpDate.setTimezone(timezone); + tmpDate.setTimezone(timezone); } return tmpDate; @@ -182,13 +238,13 @@ var common = {}, var endDate = (timestamp)? new Date(timestamp * 1000) : new Date(); if (timezone) { - endDate.setTimezone(timezone); + endDate.setTimezone(timezone); } var startDate = (timestamp)? new Date(timestamp * 1000) : new Date(); if (timezone) { - startDate.setTimezone(timezone); + startDate.setTimezone(timezone); } startDate.setMonth(0); @@ -205,6 +261,23 @@ var common = {}, return currDay; }; + common.getDaysInYear = function (year) { + if(new Date(year, 1, 29).getMonth() === 1) { + return 366; + } else { + return 365; + } + }; + + common.getISOWeeksInYear = function (year) { + var d = new Date(year, 0, 1), + isLeap = new Date(year, 1, 29).getMonth() === 1; + + //Check for a Jan 1 that's a Thursday or a leap year that has a + //Wednesday Jan 1. Otherwise it's 52 + return d.getDay() === 4 || isLeap && d.getDay() === 3 ? 53 : 52 + }; + /* argProperties = { argName: { required: true, type: 'String', max-length: 25, min-length: 25, exclude-from-ret-obj: false }}; */ @@ -273,27 +346,174 @@ var common = {}, return returnObj; }; - common.returnMessage = function (params, returnCode, message) { - params.res.writeHead(returnCode, {'Content-Type': 'application/json; charset=utf-8'}); - if (params.qstring.callback) { - params.res.write(params.qstring.callback + '(' + JSON.stringify({result: message}) + ')'); + common.fixEventKey = function (eventKey) { + var shortEventName = eventKey.replace(/system\.|\.\.|\$/g, ""); + + if (shortEventName.length >= 128) { + return false; } else { - params.res.write(JSON.stringify({result: message})); + return shortEventName; + } + }; + + common.returnMessage = function (params, returnCode, message) { + if (params && params.res) { + params.res.writeHead(returnCode, {'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin':'*'}); + if (params.qstring.callback) { + params.res.write(params.qstring.callback + '(' + JSON.stringify({result: message}) + ')'); + } else { + params.res.write(JSON.stringify({result: message})); + } + + params.res.end(); } - params.res.end(); }; common.returnOutput = function (params, output) { - params.res.writeHead(200, {'Content-Type': 'application/json; charset=utf-8'}); - if (params.qstring.callback) { - params.res.write(params.qstring.callback + '(' + JSON.stringify(output) + ')'); + if (params && params.res) { + params.res.writeHead(200, {'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin':'*'}); + if (params.qstring.callback) { + params.res.write(params.qstring.callback + '(' + JSON.stringify(output) + ')'); + } else { + params.res.write(JSON.stringify(output)); + } + + params.res.end(); + } + }; + + common.fillTimeObjectZero = function (params, object, property, increment) { + var tmpIncrement = (increment) ? increment : 1, + timeObj = params.time; + + if (!timeObj || !timeObj.yearly || !timeObj.month) { + return false; + } + + if (property instanceof Array) { + for (var i = 0; i < property.length; i ++) { + object['d.' + property[i]] = tmpIncrement; + object['d.' + timeObj.month + '.' + property[i]] = tmpIncrement; + + // For properties that hold the unique visitor count we store weekly data as well. + if (property[i].substr(-2) == ("." + common.dbMap["unique"]) || + property[i] == common.dbMap["unique"] || + property[i].substr(0,2) == (common.dbMap["frequency"] + ".") || + property[i].substr(0,2) == (common.dbMap["loyalty"] + ".") || + property[i].substr(0,3) == (common.dbMap["durations"] + ".") || + property[i] == common.dbMap["paying"]) + { + object['d.' + "w" + timeObj.weekly + '.' + property[i]] = tmpIncrement; + } + } } else { - params.res.write(JSON.stringify(output)); + object['d.' + property] = tmpIncrement; + object['d.' + timeObj.month + '.' + property] = tmpIncrement; + + if (property.substr(-2) == ("." + common.dbMap["unique"]) || + property == common.dbMap["unique"] || + property.substr(0,2) == (common.dbMap["frequency"] + ".") || + property.substr(0,2) == (common.dbMap["loyalty"] + ".") || + property.substr(0,3) == (common.dbMap["durations"] + ".") || + property == common.dbMap["paying"]) + { + object['d.' + "w" + timeObj.weekly + '.' + property] = tmpIncrement; + } } - params.res.end(); + return true; }; + common.fillTimeObjectMonth = function (params, object, property, increment) { + var tmpIncrement = (increment) ? increment : 1, + timeObj = params.time; + + if (!timeObj || !timeObj.yearly || !timeObj.month || !timeObj.weekly || !timeObj.day || !timeObj.hour) { + return false; + } + + if (property instanceof Array) { + for (var i = 0; i < property.length; i ++) { + object['d.' + timeObj.day + '.' + property[i]] = tmpIncrement; + + // If the property parameter contains a dot, hourly data is not saved in + // order to prevent two level data (such as 2012.7.20.TR.u) to get out of control. + if (property[i].indexOf('.') === -1) { + object['d.' + timeObj.day + '.' + timeObj.hour + '.' + property[i]] = tmpIncrement; + } + } + } else { + object['d.' + timeObj.day + '.' + property] = tmpIncrement; + + if (property.indexOf('.') === -1) { + object['d.' + timeObj.day + '.' + timeObj.hour + '.' + property] = tmpIncrement; + } + } + + return true; + }; + + common.getDateIds = function(params) { + if (!params || !params.time) { + return { + zero: "0000:0", + month: "0000:1" + }; + } + + return { + zero: params.time.yearly + ":0", + month: params.time.yearly + ":" + params.time.month + }; + }; + + common.versionCompare = function(v1, v2, options) { + var lexicographical = options && options.lexicographical, + zeroExtend = options && options.zeroExtend, + v1parts = v1.split(':'), + v2parts = v2.split(':'); + + function isValidPart(x) { + return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x); + } + + if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) { + return NaN; + } + + if (zeroExtend) { + while (v1parts.length < v2parts.length) v1parts.push("0"); + while (v2parts.length < v1parts.length) v2parts.push("0"); + } + + if (!lexicographical) { + v1parts = v1parts.map(Number); + v2parts = v2parts.map(Number); + } + + for (var i = 0; i < v1parts.length; ++i) { + if (v2parts.length == i) { + return 1; + } + + if (v1parts[i] == v2parts[i]) { + continue; + } + else if (v1parts[i] > v2parts[i]) { + return 1; + } + else { + return -1; + } + } + + if (v1parts.length != v2parts.length) { + return -1; + } + + return 0; + }; + }(common)); module.exports = common; \ No newline at end of file diff --git a/bin/config/nginx.conf b/bin/config/nginx.conf new file mode 100644 index 00000000000..8582207be35 --- /dev/null +++ b/bin/config/nginx.conf @@ -0,0 +1,57 @@ +user www-data; +worker_processes 4; +worker_rlimit_nofile 30000; +pid /var/run/nginx.pid; + +events { + worker_connections 10000; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # Logging Settings + ## + + access_log off; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} \ No newline at end of file diff --git a/bin/countly.install.sh b/bin/countly.install.sh index eaaed74d9d3..40484b810fc 100755 --- a/bin/countly.install.sh +++ b/bin/countly.install.sh @@ -14,7 +14,6 @@ echo " / /___/ /_/ / /_/ / / / / /_/ / /_/ / \____/\____/\__,_/_/ /_/\__/_/\__, / http://count.ly/____/ - " DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -29,7 +28,8 @@ if !(command -v apt-add-repository >/dev/null) then fi #add node.js repo -echo | apt-add-repository ppa:chris-lea/node.js +#echo | apt-add-repository ppa:chris-lea/node.js +wget -qO- https://deb.nodesource.com/setup | bash - #add mongodb repo echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" > /etc/apt/sources.list.d/mongodb-10gen-countly.list @@ -57,7 +57,7 @@ apt-get -y install imagemagick apt-get -y install sendmail #install iptables -apt-get -y install iptables +DEBIAN_FRONTEND=noninteractive apt-get -y install iptables-persistent apt-get -y install build-essential || (echo "Failed to install build-essential." ; exit) @@ -69,12 +69,16 @@ iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j #install iptables-persistent apt-get install iptables-persistent -#install time module for node -( cd $DIR/../api ; npm install time ) +#install api modules +( cd $DIR/../api ; npm install --unsafe-perm ) + +#install frontend modules +( cd $DIR/../frontend/express ; npm install --unsafe-perm ) #configure and start nginx cp /etc/nginx/sites-enabled/default $DIR/config/nginx.default.backup cp $DIR/config/nginx.server.conf /etc/nginx/sites-enabled/default +cp $DIR/config/nginx.conf /etc/nginx/nginx.conf /etc/init.d/nginx restart cp $DIR/../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../frontend/express/public/javascripts/countly/countly.config.js @@ -93,3 +97,10 @@ cp $DIR/../frontend/express/config.sample.js $DIR/../frontend/express/config.js #finally start countly api and dashboard start countly-supervisor + +#compile scripts for production +apt-get -y install default-jre +bash $DIR/scripts/compile.js.sh + +#install plugins +bash $DIR/scripts/countly.install.plugins.sh \ No newline at end of file diff --git a/bin/countly.install.travis.sh b/bin/countly.install.travis.sh new file mode 100644 index 00000000000..6ec0a1d9dcb --- /dev/null +++ b/bin/countly.install.travis.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +set -e + +if [[ $EUID -ne 0 ]]; then + echo "Please execute Countly installation script with a superuser..." 1>&2 + exit 1 +fi + +echo " + ______ __ __ + / ____/___ __ ______ / /_/ /_ __ + / / / __ \/ / / / __ \/ __/ / / / / +/ /___/ /_/ / /_/ / / / / /_/ / /_/ / +\____/\____/\__,_/_/ /_/\__/_/\__, / + http://count.ly/____/ +" + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#update package index +apt-get update + +apt-get -y install python-software-properties + +if !(command -v apt-add-repository >/dev/null) then + apt-get -y install software-properties-common +fi + +#add node.js repo +#echo | apt-add-repository ppa:chris-lea/node.js +wget -qO- https://deb.nodesource.com/setup | bash - + +#add mongodb repo +echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" > /etc/apt/sources.list.d/mongodb-10gen-countly.list +apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 + +#update once more after adding new repos +apt-get update + +#install nginx +apt-get -y install nginx || (echo "Failed to install nginx." ; exit) + +#install node.js +apt-get -y --force-yes install nodejs || (echo "Failed to install nodejs." ; exit) + +#install mongodb +apt-get -y --force-yes install mongodb-org || (echo "Failed to install mongodb." ; exit) + +#install supervisor +apt-get -y install supervisor || (echo "Failed to install supervisor." ; exit) + +#install imagemagick +apt-get -y install imagemagick + +#install sendmail +#apt-get -y install sendmail + +#install iptables +#DEBIAN_FRONTEND=noninteractive apt-get -y install iptables-persistent + +apt-get -y install build-essential || (echo "Failed to install build-essential." ; exit) + +#drop packages coming from 0/0 going through mongodb port +#allow those coming from localhost +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s localhost -j ACCEPT +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j DROP + +#install iptables-persistent +#apt-get install iptables-persistent + +#install api modules +( cd $DIR/../api ; npm install --unsafe-perm ) + +#install frontend modules +( cd $DIR/../frontend/express ; npm install --unsafe-perm ) + +#configure and start nginx +cp /etc/nginx/sites-enabled/default $DIR/config/nginx.default.backup +cp $DIR/config/nginx.server.conf /etc/nginx/sites-enabled/default +cp $DIR/config/nginx.conf /etc/nginx/nginx.conf +/etc/init.d/nginx restart + +cp $DIR/../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../frontend/express/public/javascripts/countly/countly.config.js + +#kill existing supervisor process +pkill -SIGTERM supervisord + +#create supervisor upstart script +(cat $DIR/config/countly-supervisor.conf ; echo "exec /usr/bin/supervisord --nodaemon --configuration $DIR/config/supervisord.conf") > /etc/init/countly-supervisor.conf + +#create api configuration file from sample +cp $DIR/../api/config.sample.js $DIR/../api/config.js + +#create app configuration file from sample +cp $DIR/../frontend/express/config.sample.js $DIR/../frontend/express/config.js + +#finally start countly api and dashboard +start countly-supervisor + +#compile scripts for production +apt-get -y install default-jre +bash $DIR/scripts/compile.js.sh + +#install plugins +bash $DIR/scripts/countly.install.plugins.sh \ No newline at end of file diff --git a/bin/countly.install_rhel.sh b/bin/countly.install_rhel.sh new file mode 100644 index 00000000000..1f1840c3bb0 --- /dev/null +++ b/bin/countly.install_rhel.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +if [[ $EUID -ne 0 ]]; then + echo "Please execute Countly installation script with a superuser..." 1>&2 + exit 1 +fi + +echo " + ______ __ __ ______ __ _ + / ____/___ __ ______ / /_/ /_ __ / ____/___ / /____ _________ _____(_)_______ + / / / __ \/ / / / __ \/ __/ / / / / / __/ / __ \/ __/ _ \/ ___/ __ \/ ___/ / ___/ _ \\ +/ /___/ /_/ / /_/ / / / / /_/ / /_/ / / /___/ / / / /_/ __/ / / /_/ / / / (__ ) __/ +\____/\____/\__,_/_/ /_/\__/_/\__, / /_____/_/ /_/\__/\___/_/ / .___/_/ /_/____/\___/ + http://count.ly/____/ /_/ + +" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#install nodejs +sudo yum -y install openssl-devel gcc-c++ make +cd /usr/local/src +wget http://nodejs.org/dist/node-latest.tar.gz +tar zxvf node-latest.tar.gz +cd node-v* +./configure +make +make install + +cd $DIR + +#install mongodb +echo "[10gen] +name=10gen Repository +baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64 +gpgcheck=0 +enabled=1" > /etc/yum.repos.d/10gen.repo + +sudo yum -y install mongodb-org +sudo service mongod start + +#install nginx +echo "[nginx] +name=nginx repo +baseurl=http://nginx.org/packages/rhel/6/x86_64/ +gpgcheck=0 +enabled=1" > /etc/yum.repos.d/nginx.repo + +sudo yum -y install nginx + +#for easy_install +sudo yum -y install python-setuptools + +#install supervisor +sudo easy_install supervisor + +#install imagemagick +sudo yum -y install ImageMagick + +#install sendmail +sudo yum -y install sendmail +sudo service sendmail start + +#install time module for node +( cd $DIR/../api ; /usr/local/bin/npm install time ) + +#configure and start nginx +cp $DIR/config/nginx.server.conf /etc/nginx/conf.d/default.conf +/etc/init.d/nginx start + +cp $DIR/../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../frontend/express/public/javascripts/countly/countly.config.js + +#create supervisor upstart script +(cat $DIR/config/countly-supervisor.conf ; echo "exec /usr/bin/supervisord --nodaemon --configuration $DIR/config/supervisord.conf") > /etc/init/countly-supervisor.conf + +#create api configuration file from sample +cp $DIR/../api/config.sample.js $DIR/../api/config.js + +#create app configuration file from sample +cp $DIR/../frontend/express/config.sample.js $DIR/../frontend/express/config.js + +#finally start countly api and dashboard +start countly-supervisor \ No newline at end of file diff --git a/bin/countly.travis.install.sh b/bin/countly.travis.install.sh deleted file mode 100644 index cc09144cc70..00000000000 --- a/bin/countly.travis.install.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash - -set -e - -if [[ $EUID -ne 0 ]]; then - echo "Please execute Countly installation script with a superuser..." 1>&2 - exit 1 -fi - -echo " - ______ __ __ - / ____/___ __ ______ / /_/ /_ __ - / / / __ \/ / / / __ \/ __/ / / / / -/ /___/ /_/ / /_/ / / / / /_/ / /_/ / -\____/\____/\__,_/_/ /_/\__/_/\__, / - http://count.ly/____/ - -" - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -#update package index -apt-get update - -apt-get -y install python-software-properties - -if !(command -v apt-add-repository >/dev/null) then - apt-get -y install software-properties-common -fi - -#add node.js repo -echo | apt-add-repository ppa:chris-lea/node.js - -#add mongodb repo -#echo "deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen" > /etc/apt/sources.list.d/mongodb-10gen-countly.list -apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 - -#update once more after adding new repos -apt-get update - -#install nginx -apt-get -y install nginx || (echo "Failed to install nginx." ; exit) - -#install node.js -apt-get -y --force-yes install nodejs || (echo "Failed to install nodejs." ; exit) - -#install mongodb -#apt-get -y --force-yes install mongodb-10gen || (echo "Failed to install mongodb." ; exit) - -#install supervisor -apt-get -y install supervisor || (echo "Failed to install supervisor." ; exit) - -#install imagemagick -apt-get -y install imagemagick - -#install sendmail -#apt-get -y install sendmail - -apt-get -y install build-essential || (echo "Failed to install build-essential." ; exit) - -#drop packages coming from 0/0 going through mongodb port -#allow those coming from localhost -iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s localhost -j ACCEPT -iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j DROP - -#install iptables-persistent -#apt-get install iptables-persistent - -#install time module for node -( cd $DIR/../api ; npm install time ) - -#configure and start nginx -cp /etc/nginx/sites-enabled/default $DIR/config/nginx.default.backup -cp $DIR/config/nginx.server.conf /etc/nginx/sites-enabled/default -/etc/init.d/nginx restart - -cp $DIR/../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../frontend/express/public/javascripts/countly/countly.config.js - -#kill existing supervisor process -pkill -SIGTERM supervisord - -#create supervisor upstart script -(cat $DIR/config/countly-supervisor.conf ; echo "exec /usr/bin/supervisord --nodaemon --configuration $DIR/config/supervisord.conf") > /etc/init/countly-supervisor.conf - -#create api configuration file from sample -cp $DIR/../api/config.sample.js $DIR/../api/config.js - -#create app configuration file from sample -cp $DIR/../frontend/express/config.sample.js $DIR/../frontend/express/config.js - -#finally start countly api and dashboard -start countly-supervisor diff --git a/bin/countly.upgrade.sh b/bin/countly.upgrade.sh deleted file mode 100755 index a84847a94f4..00000000000 --- a/bin/countly.upgrade.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -set -e - -if [[ $EUID -ne 0 ]]; then - echo "Please execute Countly upgrade script with a superuser..." 1>&2 - exit 1 -fi - -echo " - ______ __ __ - / ____/___ __ ______ / /_/ /_ __ - / / / __ \/ / / / __ \/ __/ / / / / -/ /___/ /_/ / /_/ / / / / /_/ / /_/ / -\____/\____/\__,_/_/ /_/\__/_/\__, / - http://count.ly/____/ - -" - -#drop packages coming from 0/0 going through mongodb port -#allow those coming from localhost -iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s localhost -j ACCEPT -iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j DROP - -#install iptables-persistent -apt-get install iptables-persistent - -#DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -#mongo countly $DIR/updateCollections.js - -#stop countly -stop countly-supervisor -#start countly -start countly-supervisor diff --git a/bin/compile.js.bat b/bin/scripts/compile.js.bat old mode 100755 new mode 100644 similarity index 89% rename from bin/compile.js.bat rename to bin/scripts/compile.js.bat index e80cc790861..efef919c805 --- a/bin/compile.js.bat +++ b/bin/scripts/compile.js.bat @@ -1,56 +1,62 @@ -java -jar closure-compiler.jar ^ ---js=../frontend/express/public/javascripts/dom/jquery/jquery-1.8.3.min.js ^ ---js=../frontend/express/public/javascripts/dom/jquery.form.js ^ ---js=../frontend/express/public/javascripts/dom/tipsy/jquery.tipsy.js ^ ---js=../frontend/express/public/javascripts/dom/jquery.noisy.min.js ^ ---js=../frontend/express/public/javascripts/dom/jquery.sticky.headers.js ^ ---js=../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-1.8.22.custom.min.js ^ ---js=../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js ^ ---js=../frontend/express/public/javascripts/dom/slimScroll.min.js ^ ---js=../frontend/express/public/javascripts/dom/jquery.easing.1.3.js ^ ---js=../frontend/express/public/javascripts/dom/dataTables/js/jquery.dataTables.js ^ ---js=../frontend/express/public/javascripts/dom/dataTables/js/ZeroClipboard.js ^ ---js=../frontend/express/public/javascripts/dom/dataTables/js/TableTools.js ^ ---js_output_file=../frontend/express/public/javascripts/min/countly.dom.js - -java -jar closure-compiler.jar ^ ---js=../frontend/express/public/javascripts/utils/underscore-min.js ^ ---js=../frontend/express/public/javascripts/utils/prefixfree.min.js ^ ---js=../frontend/express/public/javascripts/utils/moment/moment.min.js ^ ---js=../frontend/express/public/javascripts/utils/moment/moment.isocalendar.min.js ^ ---js=../frontend/express/public/javascripts/utils/moment/lang-all.min.js ^ ---js=../frontend/express/public/javascripts/utils/handlebars.js ^ ---js=../frontend/express/public/javascripts/utils/backbone-min.js ^ ---js=../frontend/express/public/javascripts/utils/jquery.i18n.properties-min-1.0.9.js ^ ---js=../frontend/express/public/javascripts/utils/jstz.min.js ^ ---js=../frontend/express/public/javascripts/utils/store+json2.min.js ^ ---js=../frontend/express/public/javascripts/utils/jquery.idle-timer.js ^ ---js=../frontend/express/public/javascripts/countly/countly.common.js ^ ---js_output_file=../frontend/express/public/javascripts/min/countly.utils.js - -java -jar closure-compiler.jar ^ ---js=../frontend/express/public/javascripts/visualization/jquery.peity.min.js ^ ---js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.js ^ ---js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js ^ ---js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.min.js ^ ---js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js ^ ---js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js ^ ---js=../frontend/express/public/javascripts/visualization/gauge.min.js ^ ---js=../frontend/express/public/javascripts/visualization/d3/d3.v2.min.js ^ ---js=../frontend/express/public/javascripts/visualization/d3/d3.layout.min.js ^ ---js=../frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js ^ ---js_output_file=../frontend/express/public/javascripts/min/countly.visualization.js - -java -jar closure-compiler.jar ^ ---js=../frontend/express/public/javascripts/countly/countly.event.js ^ ---js=../frontend/express/public/javascripts/countly/countly.session.js ^ ---js=../frontend/express/public/javascripts/countly/countly.city.js ^ ---js=../frontend/express/public/javascripts/countly/countly.location.js ^ ---js=../frontend/express/public/javascripts/countly/countly.user.js ^ ---js=../frontend/express/public/javascripts/countly/countly.device.js ^ ---js=../frontend/express/public/javascripts/countly/countly.device.detail.js ^ ---js=../frontend/express/public/javascripts/countly/countly.app.version.js ^ ---js=../frontend/express/public/javascripts/countly/countly.carrier.js ^ ---js=../frontend/express/public/javascripts/countly/countly.allapps.js ^ ---js=../frontend/express/public/javascripts/countly/countly.template.js ^ +java -jar closure-compiler.jar ^ +--js=../frontend/express/public/javascripts/dom/jquery/jquery-1.8.3.min.js ^ +--js=../frontend/express/public/javascripts/dom/jquery.form.js ^ +--js=../frontend/express/public/javascripts/dom/tipsy/jquery.tipsy.js ^ +--js=../frontend/express/public/javascripts/dom/jquery.noisy.min.js ^ +--js=../frontend/express/public/javascripts/dom/jquery.sticky.headers.js ^ +--js=../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-1.8.22.custom.min.js ^ +--js=../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js ^ +--js=../frontend/express/public/javascripts/dom/slimScroll.min.js ^ +--js=../frontend/express/public/javascripts/dom/jquery.easing.1.3.js ^ +--js=../frontend/express/public/javascripts/dom/jsonlite.js ^ +--js=../frontend/express/public/javascripts/dom/dataTables/js/jquery.dataTables.js ^ +--js=../frontend/express/public/javascripts/dom/dataTables/js/ZeroClipboard.js ^ +--js=../frontend/express/public/javascripts/dom/dataTables/js/TableTools.js ^ +--js_output_file=../frontend/express/public/javascripts/min/countly.dom.js + +java -jar closure-compiler.jar ^ +--js=../frontend/express/public/javascripts/utils/underscore-min.js ^ +--js=../frontend/express/public/javascripts/utils/prefixfree.min.js ^ +--js=../frontend/express/public/javascripts/utils/moment/moment.min.js ^ +--js=../frontend/express/public/javascripts/utils/moment/moment.isocalendar.min.js ^ +--js=../frontend/express/public/javascripts/utils/moment/lang-all.min.js ^ +--js=../frontend/express/public/javascripts/utils/handlebars.js ^ +--js=../frontend/express/public/javascripts/utils/backbone-min.js ^ +--js=../frontend/express/public/javascripts/utils/jquery.i18n.properties-min-1.0.9.js ^ +--js=../frontend/express/public/javascripts/utils/jstz.min.js ^ +--js=../frontend/express/public/javascripts/utils/store+json2.min.js ^ +--js=../frontend/express/public/javascripts/utils/jquery.idle-timer.js ^ +--js=../frontend/express/public/javascripts/utils/textcounter.min.js ^ +--js=../frontend/express/public/javascripts/utils/initialAvatar.js ^ +--js=../frontend/express/public/javascripts/utils/messenger/messenger.js ^ +--js=../frontend/express/public/javascripts/utils/messenger/messenger-theme-future.js ^ +--js=../frontend/express/public/javascripts/countly/countly.common.js ^ +--js_output_file=../frontend/express/public/javascripts/min/countly.utils.js + +java -jar closure-compiler.jar ^ +--js=../frontend/express/public/javascripts/visualization/jquery.peity.min.js ^ +--js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.js ^ +--js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js ^ +--js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js ^ +--js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js ^ +--js=../frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js ^ +--js=../frontend/express/public/javascripts/visualization/gauge.min.js ^ +--js=../frontend/express/public/javascripts/visualization/d3/d3.v2.min.js ^ +--js=../frontend/express/public/javascripts/visualization/d3/d3.layout.min.js ^ +--js=../frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js ^ +--js_output_file=../frontend/express/public/javascripts/min/countly.visualization.js + +java -jar closure-compiler.jar ^ +--js=../frontend/express/public/javascripts/countly/countly.map.helper.js ^ +--js=../frontend/express/public/javascripts/countly/countly.event.js ^ +--js=../frontend/express/public/javascripts/countly/countly.session.js ^ +--js=../frontend/express/public/javascripts/countly/countly.city.js ^ +--js=../frontend/express/public/javascripts/countly/countly.location.js ^ +--js=../frontend/express/public/javascripts/countly/countly.user.js ^ +--js=../frontend/express/public/javascripts/countly/countly.device.js ^ +--js=../frontend/express/public/javascripts/countly/countly.device.detail.js ^ +--js=../frontend/express/public/javascripts/countly/countly.app.version.js ^ +--js=../frontend/express/public/javascripts/countly/countly.carrier.js ^ +--js=../frontend/express/public/javascripts/countly/countly.allapps.js ^ +--js=../frontend/express/public/javascripts/countly/countly.template.js ^ --js_output_file=../frontend/express/public/javascripts/min/countly.lib.js \ No newline at end of file diff --git a/bin/scripts/compile.js.sh b/bin/scripts/compile.js.sh new file mode 100644 index 00000000000..f0602ea2f1b --- /dev/null +++ b/bin/scripts/compile.js.sh @@ -0,0 +1,65 @@ +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +java -jar $DIR/closure-compiler.jar \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jquery/jquery-1.8.3.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jquery.form.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/tipsy/jquery.tipsy.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jquery.noisy.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jquery.sticky.headers.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-1.8.22.custom.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/slimScroll.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jquery.easing.1.3.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/jsonlite.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/dataTables/js/jquery.dataTables.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/dataTables/js/ZeroClipboard.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/dataTables/js/TableTools.js \ +--js=$DIR/../../frontend/express/public/javascripts/dom/tablesorter/jquery.tablesorter.min.js \ +--js_output_file=$DIR/../../frontend/express/public/javascripts/min/countly.dom.js + +java -jar $DIR/closure-compiler.jar \ +--js=$DIR/../../frontend/express/public/javascripts/utils/underscore-min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/prefixfree.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/moment/moment.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/moment/moment.isocalendar.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/moment/lang-all.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/handlebars.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/backbone-min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/jquery.i18n.properties-min-1.0.9.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/jstz.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/store+json2.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/jquery.idle-timer.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/textcounter.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/initialAvatar.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/messenger/messenger.js \ +--js=$DIR/../../frontend/express/public/javascripts/utils/messenger/messenger-theme-future.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.common.js \ +--js_output_file=$DIR/../../frontend/express/public/javascripts/min/countly.utils.js + +java -jar $DIR/closure-compiler.jar \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/jquery.peity.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/flot/jquery.flot.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/flot/jquery.flot.tickrotor.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/flot/jquery.flot.pie.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/flot/jquery.flot.resize.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/flot/jquery.flot.stack.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/gauge.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/d3/d3.v2.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/d3/d3.layout.min.js \ +--js=$DIR/../../frontend/express/public/javascripts/visualization/rickshaw/rickshaw.min.js \ +--js_output_file=$DIR/../../frontend/express/public/javascripts/min/countly.visualization.js + +java -jar $DIR/closure-compiler.jar \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.map.helper.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.event.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.session.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.city.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.location.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.user.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.device.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.device.detail.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.app.version.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.carrier.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.allapps.js \ +--js=$DIR/../../frontend/express/public/javascripts/countly/countly.template.js \ +--js_output_file=$DIR/../../frontend/express/public/javascripts/min/countly.lib.js \ No newline at end of file diff --git a/bin/scripts/countly.install.plugins.sh b/bin/scripts/countly.install.plugins.sh new file mode 100644 index 00000000000..449a2943659 --- /dev/null +++ b/bin/scripts/countly.install.plugins.sh @@ -0,0 +1,3 @@ +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +node $DIR/install_plugins +restart countly-supervisor \ No newline at end of file diff --git a/bin/scripts/countly.run.tests.sh b/bin/scripts/countly.run.tests.sh new file mode 100644 index 00000000000..e648d6ded79 --- /dev/null +++ b/bin/scripts/countly.run.tests.sh @@ -0,0 +1,6 @@ +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#install test dependencies +( cd $DIR/../../ ; npm install --unsafe-perm ) +#run tests +( cd $DIR/../../ ; npm test ) \ No newline at end of file diff --git a/bin/scripts/install_plugins.js b/bin/scripts/install_plugins.js new file mode 100644 index 00000000000..7dd556896d3 --- /dev/null +++ b/bin/scripts/install_plugins.js @@ -0,0 +1,13 @@ +var manager = require('../../plugins/pluginManager.js'); +var plugins = manager.getPlugins(); + +if(plugins.length > 0){ + //run install files + for(var i = 0, l = plugins.length; i < l; i++){ + manager.installPlugin(plugins[i]); + } + + //processing plugin files for production mode + console.log("Processing plugin files for production mode"); + manager.prepareProduction(); +} \ No newline at end of file diff --git a/bin/scripts/make.swap.sh b/bin/scripts/make.swap.sh new file mode 100644 index 00000000000..39dce0ebec8 --- /dev/null +++ b/bin/scripts/make.swap.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +#create file +if hash fallocate 2>/dev/null; then + fallocate -l 4G /swapfile +else + dd if=/dev/zero of=/swapfile bs=1G count=4 +fi +chmod 600 /swapfile + +#make file a swap file +mkswap /swapfile +swapon /swapfile + +#persist swap file +echo "/swapfile none swap sw 0 0" >> /etc/fstab + +#set swappiness +sysctl vm.swappiness=60 +echo "vm.swappiness=60" >> /etc/sysctl.conf + +#set cache pressure +sysctl vm.vfs_cache_pressure=50 +echo "vm.vfs_cache_pressure = 50" >> /etc/sysctl.conf \ No newline at end of file diff --git a/bin/updateCollections.js b/bin/updateCollections.js deleted file mode 100644 index ab2c83a28e2..00000000000 --- a/bin/updateCollections.js +++ /dev/null @@ -1,75 +0,0 @@ -function forceLogoutAllUsers() { - db['sessions_'].remove({}); -} - -function cleanupDurations(obj) { - if (obj.hasOwnProperty('ds')) { - delete obj['ds']['undefined']; - } - if (obj.hasOwnProperty('d') && obj['d'] < 1) { - obj['d'] = 1; - } - for (var property in obj) { - if (obj.hasOwnProperty(property) && typeof obj[property] === "object") { - cleanupDurations(obj[property]); - } - } -} - -function cleanupSessionDurationData() { - // in 'sessions' collection: - // for each app id - db['sessions'].find().forEach( function (sessionObj) { - // delete 'null' from meta.d-ranges - sessionObj['meta']['d-ranges'] = sessionObj['meta']['d-ranges'].filter(function(val){ return val !== null }); - // delete "undefined" from *.ds values and fix durations less than 1 - cleanupDurations(sessionObj); - db['sessions'].update({_id: sessionObj._id}, sessionObj); - }); -} - -forceLogoutAllUsers(); - -/* -SUMMARY: -In v13.10 and earlier, some session duration data may be bad due to the following known -issues: - https://github.com/Countly/countly-server/issues/98 - https://github.com/Countly/countly-sdk-android/issues/27 - https://github.com/Countly/countly-sdk-android/issues/28 -The call below to cleanupSessionDurationData will delete some invalid session duration -range data caused by previous bugs and will also set any session durations that are -currently less than 1 second to 1 second. - -DETAILS: -In v13.10 and earlier, the Countly Community Edition server accepted negative session -durations from clients and added that value to the cumulative session durations it keeps -track of (yearly/monthly/weekly/daily/hourly). Due to some bugs in the Countly -client SDKs, sometimes negative values could be sent. The Community Edition server has -been fixed in 14.07 to discard session durations sent from the client that are less than -1 second long. The Android SDK has been fixed in 14.07 to no longer send negative session -durations. Countly SDKs on other platforms may still be sending negative session durations. - -The cleanupSessionDurationData function will look for any cumulative session duration -values that are less than 1 second and will set them to 1 second. This isn't the most -ideal solution, but since bad data may have been stored on the server, this is one way to -clean it up. - -The cleanupSessionDurationData function does not necessarily cleanup *all* negative -session duration data that was sent to the server in the past, because it only looks for -cumulative session durations that are negative *right now*. It is possible that negative -session durations were sent from a client and added to a cumulative session duration, but -not did not make the cumulative number go negative. We took the approach of only -resetting negative data (vs. deleting all cumulative session durations) to minimize the -impact on existing data, even if that data may be incorrect. - -USE: -The call to cleanupSessionDuration below is commented out by default, since it is a -non-reversible destructive operation. Uncomment the call below to clean up some of the -bad session duration data that may be in the Countly Mongo database. - -WARNING: -IMPORTANT!!!!! THIS IS A DESTRUCTIVE OPERATION AND CANNOT BE UNDONE. BE SURE TO BACKUP -YOUR MONGO DATABASE BEFORE DOING THIS IN CASE YOU WANT TO REVERT!!!!! -*/ -//cleanupSessionDurationData(); diff --git a/bin/upgrade/15.02/add_uid_app_users.js b/bin/upgrade/15.02/add_uid_app_users.js new file mode 100644 index 00000000000..54c85738fe6 --- /dev/null +++ b/bin/upgrade/15.02/add_uid_app_users.js @@ -0,0 +1,74 @@ +print("adding uid to app users " + new Date()); +print("This will take about 2 minutes for every 1 million user you have in the system so hang in there..."); + +var currDBAddress = "IP_ADDRESS:PORT"; +var currDBName = "countly"; + +/* + ************************************************** + ****************DO NOT EDIT BELOW***************** + ************************************************** + */ + +load("../../../frontend/express/config.js") + +//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] +var dbName; +countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; +if (typeof countlyConfig.mongodb === "string") { + dbName = countlyConfig.mongodb; +} else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(","); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} else { + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} + +var currDBAddress = dbName; +var currDBName = countlyConfig.mongodb.db; + +if (currDBAddress == "IP_ADDRESS:PORT") { + print("**********************************"); + print("Please configure currDBAddress before running this script..."); + print("**********************************"); + quit(); +} + +var currConn = new Mongo(currDBAddress); +var currDB = currConn.getDB(currDBName); + +function parseSequence(num) { + var valSeq = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]; + var digits = []; + var base = valSeq.length; + while (num > base-1){ + digits.push(num % base); + num = Math.floor(num / base); + } + digits.push(num); + var result = ""; + for(var i = digits.length-1; i>=0; --i){ + result = result + valSeq[digits[i]]; + } + return result; +} + +currDB.getCollectionNames().filter(function(name) { + return name.match(/app_users.*/) +}).forEach(function(name) { + var userCounter = 0; + currDB.getCollection(name).find({_id:{$ne: "uid-sequence"}}).forEach(function(doc) { + currDB.getCollection(name).update({_id:doc._id}, {$set: {uid:parseSequence(userCounter)}}); + userCounter++; + }); + + currDB.getCollection(name).save({_id:"uid-sequence", seq:userCounter}); +}); + +print("adding uid to app users ended " + new Date()); \ No newline at end of file diff --git a/bin/upgrade/15.02/cleanup.js b/bin/upgrade/15.02/cleanup.js new file mode 100644 index 00000000000..1569452f884 --- /dev/null +++ b/bin/upgrade/15.02/cleanup.js @@ -0,0 +1,60 @@ +print("cleanup.js started " + new Date()); + +var currDBAddress = "IP_ADDRESS:PORT"; +var currDBName = "countly"; + +/* + ************************************************** + ****************DO NOT EDIT BELOW***************** + ************************************************** + */ + +load("../../../frontend/express/config.js") + +//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] +var dbName; +countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; +if (typeof countlyConfig.mongodb === "string") { + dbName = countlyConfig.mongodb; +} else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(","); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} else { + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} + +var currDBAddress = dbName; +var currDBName = countlyConfig.mongodb.db; + +if (currDBAddress == "IP_ADDRESS:PORT") { + print("**********************************"); + print("Please configure currDBAddress before running this script..."); + print("**********************************"); + quit(); +} + +var currConn = new Mongo(currDBAddress); +var currDB = currConn.getDB(currDBName); + +currDB.getCollection("sessions").drop(); +currDB.getCollection("locations").drop(); +currDB.getCollection("app_versions").drop(); + +currDB.getCollection("users").remove({old:true}); +currDB.getCollection("devices").remove({old:true}); +currDB.getCollection("device_details").remove({old:true}); +currDB.getCollection("carriers").remove({old:true}); + +currDB.getCollectionNames().filter(function(name) { + return name.match(/events.+/); +}).forEach(function(name) { + currDB.getCollection(name).remove({old:true}); +}); + +print("cleanup.js ended " + new Date()); \ No newline at end of file diff --git a/bin/upgrade/15.02/community.upgrade.sh b/bin/upgrade/15.02/community.upgrade.sh new file mode 100644 index 00000000000..317be49cb88 --- /dev/null +++ b/bin/upgrade/15.02/community.upgrade.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#install iptables +DEBIAN_FRONTEND=noninteractive apt-get -y install iptables-persistent + +#drop packages coming from 0/0 going through mongodb port +#allow those coming from localhost +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s localhost -j ACCEPT +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j DROP + +#install iptables-persistent +apt-get install iptables-persistent + +#install api modules +( cd $DIR/../../../api ; npm install --unsafe-perm ) + +#install frontend modules +( cd $DIR/../../../frontend/express ; npm install --unsafe-perm ) + +cp $DIR/../../../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../../../frontend/express/public/javascripts/countly/countly.config.js + +#create api configuration file from sample +cp $DIR/../../../api/config.sample.js $DIR/../../../api/config.js + +#create app configuration file from sample +cp $DIR/../../../frontend/express/config.sample.js $DIR/../../../frontend/express/config.js + +#compile scripts for production +apt-get -y install default-jre +bash $DIR/../../scripts/compile.js.sh + +( stop countly-supervisor ; +cd $DIR ; +node rename_event_collections.js ; +mongo sessions.js ; +mongo events.js ; +mongo cleanup.js ; +mongo add_uid_app_users.js ; +start countly-supervisor +) + +#install plugins +bash $DIR/../../scripts/countly.install.plugins.sh \ No newline at end of file diff --git a/bin/upgrade/15.02/enterprise.upgrade.sh b/bin/upgrade/15.02/enterprise.upgrade.sh new file mode 100644 index 00000000000..d348aa97aa3 --- /dev/null +++ b/bin/upgrade/15.02/enterprise.upgrade.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#install iptables +DEBIAN_FRONTEND=noninteractive apt-get -y install iptables-persistent + +#drop packages coming from 0/0 going through mongodb port +#allow those coming from localhost +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s localhost -j ACCEPT +iptables -A INPUT -m state --state NEW -p tcp --destination-port 27019 -s 0/0 -j DROP + +#install iptables-persistent +apt-get install iptables-persistent + +#install api modules +( cd $DIR/../../../api ; npm install --unsafe-perm ) + +#install frontend modules +( cd $DIR/../../../frontend/express ; npm install --unsafe-perm ) + +cp $DIR/../../../frontend/express/public/javascripts/countly/countly.config.sample.js $DIR/../../../frontend/express/public/javascripts/countly/countly.config.js + +#create api configuration file from sample +cp $DIR/../../../api/config.sample.js $DIR/../../../api/config.js + +#create app configuration file from sample +cp $DIR/../../../frontend/express/config.sample.js $DIR/../../../frontend/express/config.js + +#compile scripts for production +apt-get -y install default-jre +bash $DIR/../../scripts/compile.js.sh + +#install plugins +bash $DIR/../../scripts/countly.install.plugins.sh \ No newline at end of file diff --git a/bin/upgrade/15.02/events.js b/bin/upgrade/15.02/events.js new file mode 100644 index 00000000000..ef055bc13b7 --- /dev/null +++ b/bin/upgrade/15.02/events.js @@ -0,0 +1,282 @@ +print("events.js started " + new Date()); + +// Test prefix is added to target collection name. Use it for test purposes. +var TEST_PREFIX = ""; + +var currDBAddress = "IP_ADDRESS:PORT"; +var targetDBAddress = "IP_ADDRESS:PORT"; +var currDBName = "countly"; +var targetDBName = "countly"; + +/* + ************************************************** + ****************DO NOT EDIT BELOW***************** + ************************************************** + */ + +load("../../../frontend/express/config.js") + +//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] +var dbName; +countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; +if (typeof countlyConfig.mongodb === "string") { + dbName = countlyConfig.mongodb; +} else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(","); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} else { + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} + +var currDBAddress = dbName; +var targetDBAddress = dbName; +var currDBName = countlyConfig.mongodb.db; +var targetDBName = countlyConfig.mongodb.db; + +if (currDBAddress == "IP_ADDRESS:PORT" || targetDBAddress == "IP_ADDRESS:PORT") { + print("**********************************"); + print("Please configure currDBAddress and targetDBAddress before running this script..."); + print("**********************************"); + quit(); +} + +var currConn = new Mongo(currDBAddress); +var targetConn = new Mongo(targetDBAddress); +var currDB = currConn.getDB(currDBName); +var targetDB = targetConn.getDB(targetDBName); + +var eventCollNames = []; +currDB.getCollectionNames().filter(function(name) { + return name.match(/events.+/); +}).forEach(function(name) { + eventCollNames.push(name); +}); + +/* ++++ START MARKING OLD DOCUMENTS */ +for (var i = 0; i < eventCollNames.length; i++) { + currDB.getCollection(eventCollNames[i]).update({},{$set:{old:true}},{multi:true}); +} +/* ---- END MARKING OLD COLLECTIONS */ + +/* ++++ START SPLITTING AND MOVING COLLECTIONS */ +var months = []; +var days = []; +var weeks = []; +var forbiddenSegValues = []; + +for (var i = 1; i < 13; i++) { months.push(i + ""); } +for (var i = 1; i < 32; i++) { days.push(i + ""); forbiddenSegValues.push(i + ""); } +for (var i = 1; i < 54; i++) { weeks.push("w" + i); } + +function flattenObject(ob) { + var toReturn = {}; + + for (var i in ob) { + if (!ob.hasOwnProperty(i)) continue; + + if ((typeof ob[i]) == 'object') { + var flatObject = flattenObject(ob[i]); + for (var x in flatObject) { + if (!flatObject.hasOwnProperty(x)) continue; + + if (!isNaN(parseFloat(flatObject[x])) && isFinite(flatObject[x])) { + if (x.search(/\.s$/) !== -1 || x == "s") { + toReturn[i + '.' + x] = parseFloat(flatObject[x].toFixed(5)); + } else { + toReturn[i + '.' + x] = NumberInt(flatObject[x]); + } + } else { + toReturn[i + '.' + x] = flatObject[x]; + } + } + } else { + if (!isNaN(parseFloat(ob[i])) && isFinite(ob[i])) { + if (i.search(/\.s$/) !== -1 || i == "s") { + toReturn[i] = parseFloat(ob[i].toFixed(5)); + } else { + toReturn[i] = NumberInt(ob[i]); + } + } else { + toReturn[i] = ob[i]; + } + } + } + + return toReturn; +} + +function skipProperty(prop) { + if (prop == "_id" || + prop == "meta" || + prop == "old" || + prop == "m" || + prop == "d" || + prop == "s" || + prop == "a") { + return true; + } else { + return false; + } +} + +function splitStandart(doc, curr, target) { + var yearsInDoc = []; + + for (var year in doc) { + if (skipProperty(year)) { continue; } + + yearsInDoc.push(year); + + var zeroObjToInsert = { + s: doc._id + "", + m: year + ":0", + d: {} + }; + + for (var month in doc[year]) { + if (months.indexOf(month) === -1) { continue; } + + var monthObjToInsert = { + s: doc._id + "", + m: year + ":" + month, + d: {} + }; + + for (var day in doc[year][month]) { + if (days.indexOf(day) === -1) { continue; } + + monthObjToInsert.d[day] = doc[year][month][day]; + } + + var flatMonthObj = flattenObject(monthObjToInsert); + + if (curr.indexOf("events") !== -1) { + for (var updateProp in flatMonthObj) { + var updatePropSplit = updateProp.split("."); + if (updatePropSplit.length == 4 && forbiddenSegValues.indexOf(updatePropSplit[2]) !== -1) { + flatMonthObj[updatePropSplit[0] + "." + updatePropSplit[1] + ".[CLY]" + updatePropSplit[2] + "." + updatePropSplit[3]] = flatMonthObj[updateProp]; + delete flatMonthObj[updateProp]; + } + } + } + + targetDB.getCollection(target).update({_id: doc._id + "_" + year + ":" + month}, {$set:flatMonthObj}, {upsert:true}); + } + + if (Object.keys(zeroObjToInsert.d).length) { + targetDB.getCollection(target).update({_id:doc._id + "_" + year + ":0"}, {$set:flattenObject(zeroObjToInsert)},{upsert:true}); + } + } + + return yearsInDoc; +} + +function splitEventNoSegment(doc, curr, target) { + var yearsInDoc = []; + + for (var year in doc) { + if (skipProperty(year)) { continue; } + + yearsInDoc.push(year); + + for (var month in doc[year]) { + if (months.indexOf(month) === -1) { continue; } + + var monthObjToInsert = { + s: doc._id + "", + m: year + ":" + month, + d: {} + }; + + for (var day in doc[year][month]) { + if (days.indexOf(day) === -1) { continue; } + + monthObjToInsert.d[day] = doc[year][month][day]; + } + + targetDB.getCollection(target).update({_id: doc._id + "_" + year + ":" + month}, {$set:flattenObject(monthObjToInsert)}, {upsert:true}); + } + } + + return yearsInDoc; +} + +function splitCollections(curr, target) { + var omitSegments = [], + omitCounts = []; + + currDB.getCollection(curr).find({_id:"no-segment"},{meta:1}).forEach(function(doc) { + if (doc && doc.meta) { + for (var segment in doc.meta) { + if (doc.meta[segment].length > 1000) { + omitSegments.push(segment); + omitCounts.push(doc.meta[segment].length); + } + } + } + }); + + currDB.getCollection(curr).find().forEach(function(doc) { + if (omitSegments.indexOf(doc._id) !== -1) { + //print("omitted " + curr + " - " + doc._id + " count: " + omitCounts[omitSegments.indexOf(doc._id)]); + return; + } + + var yearsInDoc = []; + + if (doc._id == "no-segment") { + yearsInDoc = splitEventNoSegment(doc, curr, target); + } else { + yearsInDoc = splitStandart(doc, curr, target); + } + + if (doc.meta) { + for (var i = 0; i < yearsInDoc.length; i++) { + var zeroObjToInsert = { + m: yearsInDoc[i] + ":0" + }; + + if (curr.indexOf("events") !== -1) { + zeroObjToInsert.s = doc._id + ""; + + for (var metaArr in doc.meta) { + var tmpMetaArr = []; + for (var j = 0; j < doc.meta[metaArr].length; j++) { + if (forbiddenSegValues.indexOf(doc.meta[metaArr][j]) !== -1) { + tmpMetaArr.push("[CLY]" + doc.meta[metaArr][j]); + } else { + tmpMetaArr.push(doc.meta[metaArr][j]); + } + } + + zeroObjToInsert["meta." + metaArr] = tmpMetaArr; + } + } else { + zeroObjToInsert.a = doc._id + ""; + + for (var metaArr in doc.meta) { + zeroObjToInsert["meta." + metaArr] = doc.meta[metaArr]; + } + } + + if (Object.keys(zeroObjToInsert).length) { + targetDB.getCollection(target).update({_id: doc._id + "_" + yearsInDoc[i] + ":0"}, {$set:zeroObjToInsert}, {upsert:true}); + } + } + } + }); +} + +// Split documents in all event collections +for (var i = 0; i < eventCollNames.length; i++) { + splitCollections(eventCollNames[i], TEST_PREFIX + eventCollNames[i]); +} +/* ---- END SPLITTING AND MOVING COLLECTIONS */ + +print("events.js ended " + new Date()); \ No newline at end of file diff --git a/bin/upgrade/15.02/instructions.txt b/bin/upgrade/15.02/instructions.txt new file mode 100644 index 00000000000..dcf3cd12c92 --- /dev/null +++ b/bin/upgrade/15.02/instructions.txt @@ -0,0 +1,30 @@ +Before upgrading: + +Assuming countly is installed at /var/countly +0) Download new countly version 15.02 +1) Rename old countly folder to /var/countly.old +2) Put new countly files in /var/countly +3) Back up your database, for example by making copy of it in ssh: +#assuming your countly database is name countly, execute +mongo +use countly +db.copyDatabase("countly", "countly_backup") + +#to verify there is also a backup dbs execute +show dbs + +(Optionally) you can add plugins by modifying /var/countly/plugins/plugins.json files (adding plugin directory name in the json array) +That will save you node script restart + +Upgrading +go to countly directory by typing + +cd /var/countly + +If you are using countly community edition then type + +bash bin/upgrade/15.02/community.upgrade.sh + +If you are using countly enterprise edition then type + +bash bin/upgrade/15.02/enterprise.upgrade.sh \ No newline at end of file diff --git a/bin/upgrade/15.02/rename_event_collections.js b/bin/upgrade/15.02/rename_event_collections.js new file mode 100644 index 00000000000..eede53f97ab --- /dev/null +++ b/bin/upgrade/15.02/rename_event_collections.js @@ -0,0 +1,42 @@ +console.log("renaming event collections " + new Date()); + +var common = require('../../../api/utils/common.js'), + async = require('../../../api/utils/async.min.js'), + crypto = require('crypto'); + +common.db.collection('events').find({}, {list:1}).toArray(function (err, events) { + if (!err && events && events.length) { + var eventCollsToRename = []; + + for (var i = 0; i < events.length; i++) { + if (events[i].list) { + for (var j = 0; j < events[i].list.length; j++) { + + var oldCollName = events[i].list[j] + events[i]._id; + var hash = crypto.createHash('sha1').update(oldCollName).digest('hex'); + var newCollName = "events" + hash; + + if (newCollName && oldCollName) { + eventCollsToRename.push({o:oldCollName, n:newCollName}); + } + } + } + } + + async.map(eventCollsToRename, renameColl, function (err, results) { + console.log("renaming event collections finished " + new Date()); + process.exit(0); + }); + } +}); + +function renameColl(obj, callback) { + common.db.renameCollection(obj.o, obj.n, {dropTarget: true}, function(err, coll) { + if (err) { + console.log(obj.o); + console.log(err); + } else { + callback(); + } + }); +} \ No newline at end of file diff --git a/bin/upgrade/15.02/revert.js b/bin/upgrade/15.02/revert.js new file mode 100644 index 00000000000..ef888c53fff --- /dev/null +++ b/bin/upgrade/15.02/revert.js @@ -0,0 +1,29 @@ +var dbAddress = "IP_ADDRESS:PORT"; +var dbName = "countly"; + +/* + ************************************************** + ****************DO NOT EDIT BELOW***************** + ************************************************** + */ + +if (dbAddress == "IP_ADDRESS:PORT") { + print("**********************************"); + print("Please configure dbAddress before running this script..."); + print("**********************************"); + quit(); +} + +var conn = new Mongo(dbAddress); +var db = conn.getDB(dbName); + +db.getCollection("users").remove({m:{$exists:true}, a:{$exists:true}}); +db.getCollection("devices").remove({m:{$exists:true}, a:{$exists:true}}); +db.getCollection("device_details").remove({m:{$exists:true}, a:{$exists:true}}); +db.getCollection("carriers").remove({m:{$exists:true}, a:{$exists:true}}); + +db.getCollectionNames().filter(function(name) { + return name.match(/events.+/); +}).forEach(function(name) { + db.getCollection(name).remove({m:{$exists:true}, s:{$exists:true}}) +}); \ No newline at end of file diff --git a/bin/upgrade/15.02/sessions.js b/bin/upgrade/15.02/sessions.js new file mode 100644 index 00000000000..66be6b77c6e --- /dev/null +++ b/bin/upgrade/15.02/sessions.js @@ -0,0 +1,402 @@ +print("sessions.js started " + new Date()); + +// Test prefix is added to target collection name. Use it for test purposes. +var TEST_PREFIX = ""; + +var currDBAddress = "IP_ADDRESS:PORT"; +var targetDBAddress = "IP_ADDRESS:PORT"; +var currDBName = "countly"; +var targetDBName = "countly"; + +/* + ************************************************** + ****************DO NOT EDIT BELOW***************** + ************************************************** + */ + +load("../../../frontend/express/config.js") + +//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] +var dbName; +countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; +if (typeof countlyConfig.mongodb === "string") { + dbName = countlyConfig.mongodb; +} else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(","); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} else { + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} + +var currDBAddress = dbName; +var targetDBAddress = dbName; +var currDBName = countlyConfig.mongodb.db; +var targetDBName = countlyConfig.mongodb.db; + + +if (currDBAddress == "IP_ADDRESS:PORT" || targetDBAddress == "IP_ADDRESS:PORT") { + print("**********************************"); + print("Please configure currDBAddress and targetDBAddress before running this script..."); + print("**********************************"); + quit(); +} + +var currConn = new Mongo(currDBAddress); +var targetConn = new Mongo(targetDBAddress); +var currDB = currConn.getDB(currDBName); +var targetDB = targetConn.getDB(targetDBName); + +/* ++++ START MARKING OLD DOCUMENTS */ +currDB.getCollection("users").update({},{$set:{old:true}},{multi:true}); +currDB.getCollection("devices").update({},{$set:{old:true}},{multi:true}); +currDB.getCollection("device_details").update({},{$set:{old:true}},{multi:true}); +currDB.getCollection("carriers").update({},{$set:{old:true}},{multi:true}); +/* ---- END MARKING OLD COLLECTIONS */ + +/* ++++ START SPLITTING AND MOVING COLLECTIONS */ +var months = []; +var days = []; +var weeks = []; + +for (var i = 1; i < 13; i++) { months.push(i + ""); } +for (var i = 1; i < 32; i++) { days.push(i + ""); } +for (var i = 1; i < 54; i++) { weeks.push("w" + i); } + +function flattenObject(ob) { + var toReturn = {}; + + for (var i in ob) { + if (!ob.hasOwnProperty(i)) continue; + + if ((typeof ob[i]) == 'object') { + var flatObject = flattenObject(ob[i]); + for (var x in flatObject) { + if (!flatObject.hasOwnProperty(x)) continue; + + if (!isNaN(parseFloat(flatObject[x])) && isFinite(flatObject[x])) { + toReturn[i + '.' + x] = NumberInt(flatObject[x]); + } else { + toReturn[i + '.' + x] = flatObject[x]; + } + } + } else { + if (!isNaN(parseFloat(ob[i])) && isFinite(ob[i])) { + toReturn[i] = NumberInt(ob[i]); + } else { + toReturn[i] = ob[i]; + } + } + } + return toReturn; +} + +function skipProperty(prop) { + if (prop == "_id" || + prop == "meta" || + prop == "old" || + prop == "m" || + prop == "d" || + prop == "s" || + prop == "a") { + return true; + } else { + return false; + } +} + +/* Split documents in users collection */ +currDB.getCollection("users").find({}).forEach(function(doc) { + var yearsInDoc = []; + + for (var year in doc) { + if (skipProperty(year)) { continue; } + + yearsInDoc.push(year); + + var zeroObjToInsert = { + a: doc._id + "", + m: year + ":0", + d: {} + }; + + for (var month in doc[year]) { + if (months.indexOf(month) === -1) { continue; } + + if (doc[year][month].f) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + zeroObjToInsert.d[month].f = doc[year][month].f; + } + + if (doc[year][month].l) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + zeroObjToInsert.d[month].l = doc[year][month].l; + } + + var monthObjToInsert = { + a: doc._id + "", + m: year + ":" + month, + d: {} + }; + + for (var day in doc[year][month]) { + if (days.indexOf(day) === -1) { continue; } + + monthObjToInsert.d[day] = doc[year][month][day]; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id: doc._id + "_" + year + ":" + month}, {$set:flattenObject(monthObjToInsert)}, {upsert:true}); + } + + for (var week in doc[year]) { + if (weeks.indexOf(week) === -1) { continue; } + + if (doc[year][week].f) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + zeroObjToInsert.d[week].f = doc[year][week].f; + } + + if (doc[year][week].l) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + zeroObjToInsert.d[week].l = doc[year][week].l; + } + } + + if (doc[year].f) { + zeroObjToInsert.d.f = doc[year].f; + } + + if (doc[year].l) { + zeroObjToInsert.d.l = doc[year].l; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id:doc._id + "_" + year + ":0"}, {$set:flattenObject(zeroObjToInsert)},{upsert:true}); + } + + if (doc.meta) { + for (var i = 0; i < yearsInDoc.length; i++) { + var zeroObjToInsert = { + a: doc._id + "", + m: yearsInDoc[i] + ":0" + }; + + for (var metaArr in doc.meta) { + zeroObjToInsert["meta." + metaArr] = doc.meta[metaArr]; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id: doc._id + "_" + yearsInDoc[i] + ":0"}, {$set:zeroObjToInsert}, {upsert:true}); + } + } +}); + +/* Split and move documents in sessions collection to users collection */ +currDB.getCollection("sessions").find({}).forEach(function(doc) { + var yearsInDoc = []; + + for (var year in doc) { + if (skipProperty(year)) { continue; } + + yearsInDoc.push(year); + + var zeroObjToInsert = { + a: doc._id + "", + m: year + ":0", + d: {} + }; + + for (var month in doc[year]) { + if (months.indexOf(month) === -1) { continue; } + + if (doc[year][month].u) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + zeroObjToInsert.d[month].u = doc[year][month].u; + } + + if (doc[year][month].ds) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + zeroObjToInsert.d[month].ds = doc[year][month].ds; + } + + if (doc[year][month].p) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + zeroObjToInsert.d[month].p = doc[year][month].p; + } + + var monthObjToInsert = { + a: doc._id + "", + m: year + ":" + month, + d: {} + }; + + for (var day in doc[year][month]) { + if (days.indexOf(day) === -1) { continue; } + + monthObjToInsert.d[day] = doc[year][month][day]; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id: doc._id + "_" + year + ":" + month}, {$set:flattenObject(monthObjToInsert)}, {upsert:true}); + } + + for (var week in doc[year]) { + if (weeks.indexOf(week) === -1) { continue; } + + if (doc[year][week].u) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + zeroObjToInsert.d[week].u = doc[year][week].u; + } + + if (doc[year][week].ds) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + zeroObjToInsert.d[week].ds = doc[year][week].ds; + } + + if (doc[year][week].p) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + zeroObjToInsert.d[week].p = doc[year][week].p; + } + } + + if (doc[year].u) { + zeroObjToInsert.d.u = doc[year].u; + } + + if (doc[year].ds) { + zeroObjToInsert.d.ds = doc[year].ds; + } + + if (doc[year].p) { + zeroObjToInsert.d.p = doc[year].p; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id:doc._id + "_" + year + ":0"}, {$set:flattenObject(zeroObjToInsert)},{upsert:true}); + } + + if (doc.meta) { + for (var i = 0; i < yearsInDoc.length; i++) { + var zeroObjToInsert = { + a: doc._id + "", + m: yearsInDoc[i] + ":0" + }; + + for (var metaArr in doc.meta) { + zeroObjToInsert["meta." + metaArr] = doc.meta[metaArr]; + } + + targetDB.getCollection(TEST_PREFIX + "users").update({_id: doc._id + "_" + yearsInDoc[i] + ":0"}, {$set:zeroObjToInsert}, {upsert:true}); + } + } +}); + +function splitStandart(doc, curr, target) { + var yearsInDoc = []; + + for (var year in doc) { + if (skipProperty(year)) { continue; } + + yearsInDoc.push(year); + + var zeroObjToInsert = { + a: doc._id + "", + m: year + ":0", + d: {} + }; + + for (var month in doc[year]) { + if (months.indexOf(month) === -1) { continue; } + + var monthObjToInsert = { + a: doc._id + "", + m: year + ":" + month, + d: {} + }; + + for (var day in doc[year][month]) { + if (days.indexOf(day) === -1) { continue; } + + monthObjToInsert.d[day] = doc[year][month][day]; + } + + for (var segment in doc[year][month]) { + if (days.indexOf(segment) !== -1) { continue; } + + if (doc[year][month][segment].u) { + if (!zeroObjToInsert.d[month]) { zeroObjToInsert.d[month] = {}; } + if (!zeroObjToInsert.d[month][segment]) { zeroObjToInsert.d[month][segment] = {}; } + + zeroObjToInsert.d[month][segment].u = doc[year][month][segment].u; + } + } + + targetDB.getCollection(target).update({_id: doc._id + "_" + year + ":" + month}, {$set:flattenObject(monthObjToInsert)}, {upsert:true}); + } + + for (var week in doc[year]) { + if (weeks.indexOf(week) === -1) { continue; } + + for (var segment in doc[year][week]) { + if (doc[year][week] && doc[year][week][segment] && doc[year][week][segment].u) { + if (!zeroObjToInsert.d[week]) { zeroObjToInsert.d[week] = {}; } + if (!zeroObjToInsert.d[week][segment]) { zeroObjToInsert.d[week][segment] = {}; } + + zeroObjToInsert.d[week][segment].u = doc[year][week][segment].u; + } + } + } + + for (var segment in doc[year]) { + if (doc[year] && doc[year][segment].u) { + if (!zeroObjToInsert.d[segment]) { zeroObjToInsert.d[segment] = {}}; + zeroObjToInsert.d[segment].u = doc[year][segment].u; + } + } + + if (Object.keys(zeroObjToInsert.d).length) { + targetDB.getCollection(target).update({_id:doc._id + "_" + year + ":0"}, {$set:flattenObject(zeroObjToInsert)},{upsert:true}); + } + } + + return yearsInDoc; +} + +function splitCollections(curr, target) { + currDB.getCollection(curr).find({}).forEach(function(doc) { + var yearsInDoc = splitStandart(doc, curr, target); + + if (doc.meta) { + for (var i = 0; i < yearsInDoc.length; i++) { + var zeroObjToInsert = { + a: doc._id + "", + m: yearsInDoc[i] + ":0" + }; + + for (var metaArr in doc.meta) { + zeroObjToInsert["meta." + metaArr] = doc.meta[metaArr]; + } + + if (Object.keys(zeroObjToInsert).length) { + targetDB.getCollection(target).update({_id: doc._id + "_" + yearsInDoc[i] + ":0"}, {$set:zeroObjToInsert}, {upsert:true}); + } + } + } + }); +} + +var splits = [ + {curr:"locations", target:TEST_PREFIX + "users"}, + {curr:"app_versions", target:TEST_PREFIX + "device_details"}, + {curr:"device_details", target:TEST_PREFIX + "device_details"}, + {curr:"carriers", target:TEST_PREFIX + "carriers"}, + {curr:"devices", target:TEST_PREFIX + "devices"} +]; + +for (var i = 0 ; i < splits.length; i++) { + splitCollections(splits[i].curr, splits[i].target); +} +/* ---- END SPLITTING AND MOVING COLLECTIONS */ + +print("sessions.js ended " + new Date()); \ No newline at end of file diff --git a/frontend/express/app.js b/frontend/express/app.js index 84831e6bb45..92eda1e7a3b 100644 --- a/frontend/express/app.js +++ b/frontend/express/app.js @@ -1,4 +1,7 @@ -var http = require('http'), +var COUNTLY_VERSION = "15.02", + COUNTLY_TYPE = "2fb8d2c65f7919fa1ce594302618febe0a46cb2f", + COUNTLY_LICENCE_KEY = "", + http = require('http'), express = require('express'), SkinStore = require('connect-mongoskin'), expose = require('express-expose'), @@ -7,23 +10,39 @@ var http = require('http'), fs = require('fs'), im = require('imagemagick'), request = require('request'), + async = require('./../../api/utils/async.min.js'), + stringJS = require('string'), countlyMail = require('../../api/parts/mgmt/mail.js'), countlyStats = require('../../api/parts/data/stats.js'), + plugins = require('../../plugins/pluginManager.js'), countlyConfig = require('./config'); - - var dbName; - var dbOptions = { safe:true }; - - if (typeof countlyConfig.mongodb === "string"){ - dbName = countlyConfig.mongodb; - } else if (typeof countlyConfig.mongodb.replSetServers === 'object') { - dbName = countlyConfig.mongodb.replSetServers; - dbOptions.database = countlyConfig.mongodb.db || 'countly'; - } else { - dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port + '/' + countlyConfig.mongodb.db + '?auto_reconnect=true'); - } - var countlyDb = mongo.db(dbName, dbOptions); +//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] +var dbName; +var dbOptions = {db:{safe:false},server:{auto_reconnect:true}}; +countlyConfig.mongodb.db = countlyConfig.mongodb.db || 'countly'; +if (typeof countlyConfig.mongodb === "string") { + dbName = countlyConfig.mongodb; +} else if ( typeof countlyConfig.mongodb.replSetServers === 'object'){ + //mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test + dbName = countlyConfig.mongodb.replSetServers.join(",")+"/"+countlyConfig.mongodb.db; + dbOptions.replSet = {auto_reconnect:true}; + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} else { + dbName = (countlyConfig.mongodb.host + ':' + countlyConfig.mongodb.port + '/' + countlyConfig.mongodb.db); + if(countlyConfig.mongodb.username && countlyConfig.mongodb.password){ + dbName = countlyConfig.mongodb.username + ":" + countlyConfig.mongodb.password +"@" + dbName; + } +} +if(dbName.indexOf("mongodb://") !== 0){ + dbName = "mongodb://"+dbName; +} + +var countlyDb = mongo.db(dbName, dbOptions); +if(!countlyDb.ObjectID) + countlyDb.ObjectID = mongo.ObjectID; function sha1Hash(str, addSalt) { var salt = (addSalt) ? new Date().getTime() : ""; @@ -90,7 +109,8 @@ app.configure(function () { app.use(express.csrf()); app.use(app.router); var oneYear = 31557600000; - app.use(express.static(__dirname + '/public'), { maxAge:oneYear }); + plugins.loadAppPlugins(app, countlyDb, express); + app.use(countlyConfig.path, express.static(__dirname + '/public'), { maxAge:oneYear }); }); app.configure('development', function () { @@ -101,11 +121,11 @@ app.configure('production', function () { app.use(express.errorHandler()); }); -app.get('/', function (req, res, next) { - res.redirect('/login'); +app.get(countlyConfig.path+'/', function (req, res, next) { + res.redirect(countlyConfig.path+'/login'); }); -app.get('/logout', function (req, res, next) { +app.get(countlyConfig.path+'/logout', function (req, res, next) { if (req.session) { req.session.uid = null; req.session.gadm = null; @@ -114,12 +134,12 @@ app.get('/logout', function (req, res, next) { req.session.destroy(function () { }); } - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); }); -app.get('/dashboard', function (req, res, next) { +app.get(countlyConfig.path+'/dashboard', function (req, res, next) { if (!req.session.uid) { - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); } else { countlyDb.collection('members').findOne({"_id":countlyDb.ObjectID(req.session.uid)}, function (err, member) { if (member) { @@ -128,27 +148,26 @@ app.get('/dashboard', function (req, res, next) { countlyGlobalApps = {}, countlyGlobalAdminApps = {}; - member.user_id = crypto.createHash('md5').update(member._id + member.email).digest('hex'); - member.user_hash = crypto.createHash('sha1').update('xuiee4eb' + member.user_id).digest('hex'); - if (member['global_admin']) { countlyDb.collection('apps').find({}).toArray(function (err, apps) { adminOfApps = apps; userOfApps = apps; - for (var i = 0; i < apps.length; i++) { - countlyGlobalApps[apps[i]["_id"]] = { - "_id":"" + apps[i]["_id"], - "name":apps[i]["name"], - "key":apps[i]["key"], - "category":apps[i]["category"], - "timezone":apps[i]["timezone"], - "country":apps[i]["country"] - }; - } + countlyDb.collection('graph_notes').find().toArray(function (err, notes) { + var appNotes = []; + for (var i = 0; i < notes.length; i++) { + appNotes[notes[i]["_id"]] = notes[i]["notes"]; + } - countlyGlobalAdminApps = countlyGlobalApps; - renderDashboard(); + for (var i = 0; i < apps.length; i++) { + apps[i]["notes"] = appNotes[apps[i]["_id"]] || null; + countlyGlobalApps[apps[i]["_id"]] = apps[i]; + countlyGlobalApps[apps[i]["_id"]]["_id"] = "" + apps[i]["_id"]; + } + + countlyGlobalAdminApps = countlyGlobalApps; + renderDashboard(); + }); }); } else { var adminOfAppIds = [], @@ -177,32 +196,28 @@ app.get('/dashboard', function (req, res, next) { countlyDb.collection('apps').find({ _id:{ '$in':adminOfAppIds } }).toArray(function (err, admin_of) { for (var i = 0; i < admin_of.length; i++) { - countlyGlobalAdminApps[admin_of[i]["_id"]] = { - "_id":"" + admin_of[i]["_id"], - "name":admin_of[i]["name"], - "key":admin_of[i]["key"], - "category":admin_of[i]["category"], - "timezone":admin_of[i]["timezone"], - "country":admin_of[i]["country"] - }; + countlyGlobalAdminApps[admin_of[i]["_id"]] = admin_of[i]; + countlyGlobalAdminApps[admin_of[i]["_id"]]["_id"] = "" + admin_of[i]["_id"]; } countlyDb.collection('apps').find({ _id:{ '$in':userOfAppIds } }).toArray(function (err, user_of) { adminOfApps = admin_of; userOfApps = user_of; - for (var i = 0; i < user_of.length; i++) { - countlyGlobalApps[user_of[i]["_id"]] = { - "_id":"" + user_of[i]["_id"], - "name":user_of[i]["name"], - "key":user_of[i]["key"], - "category":user_of[i]["category"], - "timezone":user_of[i]["timezone"], - "country":user_of[i]["country"] - }; - } + countlyDb.collection('graph_notes').find({ _id:{ '$in':userOfAppIds } }).toArray(function (err, notes) { + var appNotes = []; + for (var i = 0; i < notes.length; i++) { + appNotes[notes[i]["_id"]] = notes[i]["notes"]; + } - renderDashboard(); + for (var i = 0; i < user_of.length; i++) { + user_of[i]["notes"] = appNotes[user_of[i]["_id"]] || null; + countlyGlobalApps[user_of[i]["_id"]] = user_of[i]; + countlyGlobalApps[user_of[i]["_id"]]["_id"] = "" + user_of[i]["_id"]; + } + + renderDashboard(); + }); }); }); } @@ -220,7 +235,10 @@ app.get('/dashboard', function (req, res, next) { apps:countlyGlobalApps, admin_apps:countlyGlobalAdminApps, csrf_token:req.session._csrf, - member:member + member:member, + plugins:plugins.getPlugins(), + path:countlyConfig.path || "", + cdn:countlyConfig.cdn || "" }, 'countlyGlobal'); if (settings && !err) { @@ -231,10 +249,13 @@ app.get('/dashboard', function (req, res, next) { res.render('dashboard', { adminOfApps:adminOfApps, userOfApps:userOfApps, - countlyVersion:"14.08", member:member, - cdn: countlyConfig.cdn || "", - production: countlyConfig.production || false + intercom:countlyConfig.web.use_intercom, + countlyVersion:COUNTLY_VERSION, + production: countlyConfig.production || false, + plugins:plugins.getPlugins(), + path:countlyConfig.path || "", + cdn:countlyConfig.cdn || "" }); }); } @@ -246,45 +267,45 @@ app.get('/dashboard', function (req, res, next) { res.clearCookie('gadm'); req.session.destroy(function () {}); } - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); } }); } }); -app.get('/setup', function (req, res, next) { +app.get(countlyConfig.path+'/setup', function (req, res, next) { countlyDb.collection('members').count({}, function (err, memberCount) { if (memberCount) { - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); } else { - res.render('setup', { "csrf":req.session._csrf }); + res.render('setup', { "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } }); }); -app.get('/login', function (req, res, next) { +app.get(countlyConfig.path+'/login', function (req, res, next) { if (req.session.uid) { - res.redirect('/dashboard'); + res.redirect(countlyConfig.path+'/dashboard'); } else { countlyDb.collection('members').count({}, function (err, memberCount) { if (memberCount) { - res.render('login', { "message":req.flash('info'), "csrf":req.session._csrf }); + res.render('login', { "message":req.flash('info'), "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } else { - res.redirect('/setup'); + res.redirect(countlyConfig.path+'/setup'); } }); } }); -app.get('/forgot', function (req, res, next) { +app.get(countlyConfig.path+'/forgot', function (req, res, next) { if (req.session.uid) { - res.redirect('/dashboard'); + res.redirect(countlyConfig.path+'/dashboard'); } else { - res.render('forgot', { "csrf":req.session._csrf, "message":req.flash('info') }); + res.render('forgot', { "csrf":req.session._csrf, "message":req.flash('info'), path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } }); -app.get('/reset/:prid', function (req, res, next) { +app.get(countlyConfig.path+'/reset/:prid', function (req, res, next) { if (req.params.prid) { countlyDb.collection('password_reset').findOne({prid:req.params.prid}, function (err, passwordReset) { var timestamp = Math.round(new Date().getTime() / 1000); @@ -292,54 +313,39 @@ app.get('/reset/:prid', function (req, res, next) { if (passwordReset && !err) { if (timestamp > (passwordReset.timestamp + 600)) { req.flash('info', 'reset.invalid'); - res.redirect('/forgot'); + res.redirect(countlyConfig.path+'/forgot'); } else { - res.render('reset', { "csrf":req.session._csrf, "prid":req.params.prid, "message":"" }); + res.render('reset', { "csrf":req.session._csrf, "prid":req.params.prid, "message":"", path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } } else { req.flash('info', 'reset.invalid'); - res.redirect('/forgot'); + res.redirect(countlyConfig.path+'/forgot'); } }); } else { req.flash('info', 'reset.invalid'); - res.redirect('/forgot'); - } -}); - -var auth = express.basicAuth(function(user, pass, callback) { - var password = sha1Hash(pass); - countlyDb.collection('members').findOne({$or: [ {"username":user}, {"email":user} ], "password":password}, function (err, member) { - callback(null, member); - }); -}); - -app.get('/api-key', auth, function (req, res, next) { - if (req.user) { - res.send(req.user.api_key); - } else { - res.send("-1"); + res.redirect(countlyConfig.path+'/forgot'); } }); -app.post('/reset', function (req, res, next) { +app.post(countlyConfig.path+'/reset', function (req, res, next) { if (req.body.password && req.body.again && req.body.prid) { var password = sha1Hash(req.body.password); countlyDb.collection('password_reset').findOne({prid:req.body.prid}, function (err, passwordReset) { countlyDb.collection('members').update({_id:passwordReset.user_id}, {'$set':{ "password":password }}, function (err, member) { req.flash('info', 'reset.result'); - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); }); countlyDb.collection('password_reset').remove({prid:req.body.prid}, function () {}); }); } else { - res.render('reset', { "csrf":req.session._csrf, "prid":req.body.prid, "message":"" }); + res.render('reset', { "csrf":req.session._csrf, "prid":req.body.prid, "message":"", path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } }); -app.post('/forgot', function (req, res, next) { +app.post(countlyConfig.path+'/forgot', function (req, res, next) { if (req.body.email) { countlyDb.collection('members').findOne({"email":req.body.email}, function (err, member) { if (member) { @@ -349,135 +355,121 @@ app.post('/forgot', function (req, res, next) { countlyDb.collection('password_reset').insert({"prid":prid, "user_id":member._id, "timestamp":timestamp}, {safe:true}, function (err, password_reset) { countlyMail.sendPasswordResetInfo(member, prid); - res.render('forgot', { "message":"forgot.result", "csrf":req.session._csrf }); + res.render('forgot', { "message":"forgot.result", "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); }); } else { - res.render('forgot', { "message":"forgot.result", "csrf":req.session._csrf }); + res.render('forgot', { "message":"forgot.result", "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); } }); } else { - res.redirect('/forgot'); + res.redirect(countlyConfig.path+'/forgot'); } }); -app.post('/setup', function (req, res, next) { +app.post(countlyConfig.path+'/setup', function (req, res, next) { countlyDb.collection('members').count({}, function (err, memberCount) { if (memberCount) { - res.redirect('/login'); + res.redirect(countlyConfig.path+'/login'); } else { if (req.body.full_name && req.body.username && req.body.password && req.body.email) { var password = sha1Hash(req.body.password); countlyDb.collection('members').insert({"full_name":req.body.full_name, "username":req.body.username, "password":password, "email":req.body.email, "global_admin":true}, {safe:true}, function (err, member) { - var options = { - uri: 'https://cloud.count.ly/s', - method: 'POST', - timeout: 4000, - json: { - "email": req.body.email, - "full_name": req.body.full_name, - "v": "14.08" - } - }; - - request(options, function (error, response, body) { - var newMember = {}; - - newMember.api_key = md5Hash(member[0]._id + (new Date().getTime())); - - if (body) { - if (body.in_user_id) { - newMember.in_user_id = body.in_user_id; - } - - if (body.in_user_hash) { - newMember.in_user_hash = body.in_user_hash; - } - } - - countlyDb.collection('members').update({'_id':member[0]._id}, {$set:newMember}, function () { - req.session.uid = member[0]["_id"]; - req.session.gadm = true; - res.redirect('/dashboard'); + if (countlyConfig.web.use_intercom) { + var options = {uri:"https://cloud.count.ly/s", method:"POST", timeout:4E3, json:{email:req.body.email, full_name:req.body.full_name, v:COUNTLY_VERSION, t:COUNTLY_TYPE, l:COUNTLY_LICENCE_KEY}}; + request(options, function(a, c, b) { + a = {}; + a.api_key = md5Hash(member[0]._id + (new Date).getTime()); + b && (b.in_user_id && (a.in_user_id = b.in_user_id), b.in_user_hash && (a.in_user_hash = b.in_user_hash)); + + countlyDb.collection("members").update({_id:member[0]._id}, {$set:a}, function() { + req.session.uid = member[0]._id; + req.session.gadm = !0; + res.redirect(countlyConfig.path+"/dashboard") + }) }); - }); + } else { + a = {}; + a.api_key = md5Hash(member[0]._id + (new Date).getTime()); + + countlyDb.collection("members").update({_id:member[0]._id}, {$set:a}, function() { + req.session.uid = member[0]._id; + req.session.gadm = !0; + res.redirect(countlyConfig.path+"/dashboard") + }) + } }); } else { - res.redirect('/setup'); + res.redirect(countlyConfig.path+'/setup'); } } }); }); -app.post('/login', function (req, res, next) { +app.post(countlyConfig.path+'/login', function (req, res, next) { if (req.body.username && req.body.password) { var password = sha1Hash(req.body.password); countlyDb.collection('members').findOne({$or: [ {"username":req.body.username}, {"email":req.body.username} ], "password":password}, function (err, member) { if (member) { - countlyStats.totalUsers(function(userCount, appCount) { - countlyStats.totalEvents(function(eventCount) { - countlyStats.totalReqs(function(reqCount) { - var options = { - uri: 'https://cloud.count.ly/s', - method: 'POST', - timeout: 4000, - json: { - "email": member.email, - "full_name": member.full_name, - "v": "14.08", - "u": userCount, - "e": eventCount, - "r": reqCount, - "a": appCount - } - }; - - request(options, function (error, response, body) { - var updatedMember = {}; + if (countlyConfig.web.use_intercom && member['global_admin']) { + countlyStats.totalUsers(function(c, d) { + countlyStats.totalEvents(function(e) { + countlyStats.totalReqs(function(f) { + request({uri:"https://cloud.count.ly/s", method:"POST", timeout:4E3, json:{email:member.email, full_name:member.full_name, v:COUNTLY_VERSION, t:COUNTLY_TYPE, l:COUNTLY_LICENCE_KEY, u:c, e:e, r:f, a:d}}, function(a, c, b) { + a = {}; + b && (b.in_user_id && !member.in_user_id && (a.in_user_id = b.in_user_id), b.in_user_hash && !member.in_user_hash && (a.in_user_hash = b.in_user_hash)); + Object.keys(a).length && countlyDb.collection("members").update({_id:member._id}, {$set:a}, function() {}) + }) + }) + }) + }); + } - if (body) { - if (body.in_user_id && !member.in_user_id) { - updatedMember.in_user_id = body.in_user_id; - } + req.session.uid = member["_id"]; + req.session.gadm = (member["global_admin"] == true); + res.redirect(countlyConfig.path+'/dashboard'); + } else { + res.render('login', { "message":"login.result", "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); + } + }); + } else { + res.render('login', { "message":"login.result", "csrf":req.session._csrf, path:countlyConfig.path || "", cdn:countlyConfig.cdn || "" }); + } +}); - if (body.in_user_hash && !member.in_user_hash) { - updatedMember.in_user_hash = body.in_user_hash; - } - } +var auth = express.basicAuth(function(user, pass, callback) { + var password = sha1Hash(pass); + countlyDb.collection('members').findOne({$or: [ {"username":user}, {"email":user} ], "password":password}, function (err, member) { + callback(null, member); + }); +}); - if (Object.keys(updatedMember).length) { - countlyDb.collection('members').update({'_id':member._id}, {$set:updatedMember}, function () {}); - } - }); - }); - }); - }); +app.get(countlyConfig.path+'/api-key', auth, function (req, res, next) { + if (req.user) { + res.send(req.user.api_key); + } else { + res.send("-1"); + } +}); - if (!member.api_key) { - var apiKey = md5Hash(member._id + (new Date().getTime())); +app.post(countlyConfig.path+'/mobile/login', function (req, res, next) { + if (req.body.username && req.body.password) { + var password = sha1Hash(req.body.password); - countlyDb.collection('members').update({'_id':member._id}, {$set:{'api_key': apiKey}}, function () { - req.session.uid = member["_id"]; - req.session.gadm = (member["global_admin"] == true); - res.redirect('/dashboard'); - }); - } else { - req.session.uid = member["_id"]; - req.session.gadm = (member["global_admin"] == true); - res.redirect('/dashboard'); - } + countlyDb.collection('members').findOne({$or: [ {"username":req.body.username}, {"email":req.body.username} ], "password":password}, function (err, member) { + if (member) { + res.render('mobile/key', { "key": member.api_key || -1 }); } else { - res.render('login', { "message":"login.result", "csrf":req.session._csrf }); + res.render('mobile/login', { "message":"login.result", "csrf":req.session._csrf }); } }); } else { - res.render('login', { "message":"login.result", "csrf":req.session._csrf }); - res.end(); + res.render('mobile/login', { "message":"login.result", "csrf":req.session._csrf }); } }); -app.post('/dashboard/settings', function (req, res, next) { +app.post(countlyConfig.path+'/dashboard/settings', function (req, res, next) { if (!req.session.uid) { res.end(); return false; @@ -498,7 +490,7 @@ app.post('/dashboard/settings', function (req, res, next) { countlyDb.collection('settings').update({}, {'$set':{'appSortList':newAppOrder}}, {'upsert':true}); }); -app.post('/apps/icon', function (req, res) { +app.post(countlyConfig.path+'/apps/icon', function (req, res) { if (!req.files.app_image || !req.body.app_image_id) { res.end(); return true; @@ -524,11 +516,11 @@ app.post('/apps/icon', function (req, res) { height:72 }, function (err, stdout, stderr) {}); - res.send("/appimages/" + req.body.app_image_id + ".png"); + res.send(countlyConfig.path+"/appimages/" + req.body.app_image_id + ".png"); }); }); -app.post('/user/settings', function (req, res, next) { +app.post(countlyConfig.path+'/user/settings', function (req, res, next) { if (!req.session.uid) { res.end(); return false; @@ -573,7 +565,7 @@ app.post('/user/settings', function (req, res, next) { } }); -app.post('/users/check/email', function (req, res, next) { +app.post(countlyConfig.path+'/users/check/email', function (req, res, next) { if (!req.session.uid || !isGlobalAdmin(req) || !req.body.email) { res.send(false); return false; @@ -588,7 +580,7 @@ app.post('/users/check/email', function (req, res, next) { }); }); -app.post('/users/check/username', function (req, res, next) { +app.post(countlyConfig.path+'/users/check/username', function (req, res, next) { if (!req.session.uid || !isGlobalAdmin(req) || !req.body.username) { res.send(false); return false; @@ -603,7 +595,7 @@ app.post('/users/check/username', function (req, res, next) { }); }); -app.post('/events/map/edit', function (req, res, next) { +app.post(countlyConfig.path+'/events/map/edit', function (req, res, next) { if (!req.session.uid || !req.body.app_id) { res.end(); return false; @@ -629,7 +621,7 @@ app.post('/events/map/edit', function (req, res, next) { } }); -app.post('/events/delete', function (req, res, next) { +app.post(countlyConfig.path+'/events/delete', function (req, res, next) { if (!req.session.uid || !req.body.app_id || !req.body.event_key) { res.end(); return false; @@ -643,14 +635,21 @@ app.post('/events/delete', function (req, res, next) { } }; - updateThese["$unset"]["map." + req.body.event_key] = 1; - updateThese["$unset"]["segments." + req.body.event_key] = 1; + if(req.body.event_key.indexOf('.') != -1){ + updateThese["$unset"]["map." + req.body.event_key.replace(/\./g,':')] = 1; + updateThese["$unset"]["segments." + req.body.event_key.replace(/\./g,':')] = 1; + } + else{ + updateThese["$unset"]["map." + req.body.event_key] = 1; + updateThese["$unset"]["segments." + req.body.event_key] = 1; + } + var collectionNameWoPrefix = crypto.createHash('sha1').update(req.body.event_key + req.body.app_id).digest('hex'); if (!isGlobalAdmin(req)) { countlyDb.collection('members').findOne({"_id":countlyDb.ObjectID(req.session.uid)}, function (err, member) { if (!err && member.admin_of && member.admin_of.indexOf(req.body.app_id) != -1) { countlyDb.collection('events').update({"_id":countlyDb.ObjectID(req.body.app_id)}, updateThese, function (err, events) {}); - countlyDb.collection(req.body.event_key + req.body.app_id).drop(); + countlyDb.collection("events" + collectionNameWoPrefix).drop(); res.send(true); return true; @@ -661,11 +660,74 @@ app.post('/events/delete', function (req, res, next) { }); } else { countlyDb.collection('events').update({"_id":countlyDb.ObjectID(req.body.app_id)}, updateThese, function (err, events) {}); - countlyDb.collection(req.body.event_key + req.body.app_id).drop(); + countlyDb.collection("events" + collectionNameWoPrefix).drop(); res.send(true); return true; } }); +app.post(countlyConfig.path+'/graphnotes/create', function (req, res, next) { + if (!req.session.uid || !req.body.app_id || !req.body.date_id || !req.body.note || req.body.note.length > 50) { + res.send(false); + res.end(); + return false; + } + + if (!isGlobalAdmin(req)) { + countlyDb.collection('members').findOne({"_id":countlyDb.ObjectID(req.session.uid)}, function (err, member) { + if (!err && member.user_of && member.user_of.indexOf(req.body.app_id) != -1) { + createNote(); + return true; + } else { + res.send(false); + return false; + } + }); + } else { + createNote(); + return true; + } + + function createNote() { + var noteObj = {}, + sanNote = stringJS(req.body.note).stripTags().s; + + noteObj["notes." + req.body.date_id] = sanNote; + + countlyDb.collection('graph_notes').update({"_id": countlyDb.ObjectID(req.body.app_id)}, { $addToSet: noteObj }, {upsert: true}, function(err, res) {}); + res.send(sanNote); + } +}); + +app.post(countlyConfig.path+'/graphnotes/delete', function (req, res, next) { + if (!req.session.uid || !req.body.app_id || !req.body.date_id || !req.body.note) { + res.end(); + return false; + } + + if (!isGlobalAdmin(req)) { + countlyDb.collection('members').findOne({"_id":countlyDb.ObjectID(req.session.uid)}, function (err, member) { + if (!err && member.user_of && member.user_of.indexOf(req.body.app_id) != -1) { + deleteNote(); + return true; + } else { + res.send(false); + return false; + } + }); + } else { + deleteNote(); + return true; + } + + function deleteNote() { + var noteObj = {}; + noteObj["notes." + req.body.date_id] = req.body.note; + + countlyDb.collection('graph_notes').update({"_id": countlyDb.ObjectID(req.body.app_id)}, { $pull: noteObj }, function(err, res) {}); + res.send(true); + } +}); + app.listen(countlyConfig.web.port, countlyConfig.web.host || ''); \ No newline at end of file diff --git a/frontend/express/config.sample.js b/frontend/express/config.sample.js index e8635c9384f..c16948f405e 100644 --- a/frontend/express/config.sample.js +++ b/frontend/express/config.sample.js @@ -2,26 +2,35 @@ var countlyConfig = { mongodb: { host: "localhost", db: "countly", - port: 27017 + port: 27017, + max_pool_size: 1000, + //username: test, + //password: test }, /* or for a replica set mongodb: { replSetServers : [ - '192.168.3.1:27017/?auto_reconnect=true', - '192.168.3.2:27017/?auto_reconnect=true' + '192.168.3.1:27017', + '192.168.3.2:27017' ], db: "countly", + username: test, + password: test, + max_pool_size: 1000 }, */ /* or define as a url - mongodb: "localhost:27017/countly?auto_reconnect=true", + //mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] + mongodb: "localhost:27017/countly", */ web: { port: 6001, host: "localhost", use_intercom: true }, - production: true + production: false, + path: "", + cdn: "" }; module.exports = countlyConfig; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/.travis.yml b/frontend/express/node_modules/bson/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/frontend/express/node_modules/bson/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/bson/Makefile b/frontend/express/node_modules/bson/Makefile deleted file mode 100644 index 77ce4e04085..00000000000 --- a/frontend/express/node_modules/bson/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit - -all: clean node_gyp - -test: clean node_gyp - npm test - -node_gyp: clean - node-gyp configure build - -clean: - node-gyp clean - -browserify: - node_modules/.bin/onejs build browser_build/package.json browser_build/bson.js - -.PHONY: all diff --git a/frontend/express/node_modules/bson/README.md b/frontend/express/node_modules/bson/README.md deleted file mode 100644 index 1a6fc2bafb0..00000000000 --- a/frontend/express/node_modules/bson/README.md +++ /dev/null @@ -1,45 +0,0 @@ -Javascript + C++ BSON parser -============================ - -This BSON parser is primarily meant for usage with the `mongodb` node.js driver. However thanks to such wonderful tools at `onejs` we are able to package up a BSON parser that will work in the browser aswell. The current build is located in the `browser_build/bson.js` file. - -A simple example on how to use it - - - - - - - - - It's got two simple methods to use in your application. - - * BSON.serialize(object, checkKeys, asBuffer, serializeFunctions) - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)** - * @return {TypedArray/Array} returns a TypedArray or Array depending on what your browser supports - - * BSON.deserialize(buffer, options, isArray) - * Options - * **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * @param {TypedArray/Array} a TypedArray/Array containing the BSON data - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. diff --git a/frontend/express/node_modules/bson/binding.gyp b/frontend/express/node_modules/bson/binding.gyp deleted file mode 100644 index 42445d325d7..00000000000 --- a/frontend/express/node_modules/bson/binding.gyp +++ /dev/null @@ -1,17 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'bson', - 'sources': [ 'ext/bson.cc' ], - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/frontend/express/node_modules/bson/browser_build/bson.js b/frontend/express/node_modules/bson/browser_build/bson.js deleted file mode 100644 index 7132496117d..00000000000 --- a/frontend/express/node_modules/bson/browser_build/bson.js +++ /dev/null @@ -1,4815 +0,0 @@ -var bson = (function(){ - - var pkgmap = {}, - global = {}, - nativeRequire = typeof require != 'undefined' && require, - lib, ties, main, async; - - function exports(){ return main(); }; - - exports.main = exports; - exports.module = module; - exports.packages = pkgmap; - exports.pkg = pkg; - exports.require = function require(uri){ return pkgmap.main.index.require(uri); }; - - - ties = {}; - - aliases = {}; - - - return exports; - -function join() { - return normalize(Array.prototype.join.call(arguments, "/")); -}; - -function normalize(path) { - var ret = [], parts = path.split('/'), cur, prev; - - var i = 0, l = parts.length-1; - for (; i <= l; i++) { - cur = parts[i]; - - if (cur === "." && prev !== undefined) continue; - - if (cur === ".." && ret.length && prev !== ".." && prev !== "." && prev !== undefined) { - ret.pop(); - prev = ret.slice(-1)[0]; - } else { - if (prev === ".") ret.pop(); - ret.push(cur); - prev = cur; - } - } - - return ret.join("/"); -}; - -function dirname(path) { - return path && path.substr(0, path.lastIndexOf("/")) || "."; -}; - -function findModule(workingModule, uri){ - var moduleId = join(dirname(workingModule.id), uri).replace(/\.js$/, ''), - moduleIndexId = join(moduleId, 'index'), - pkg = workingModule.pkg, - module; - - var i = pkg.modules.length, - id; - - while(i-->0){ - id = pkg.modules[i].id; - if(id==moduleId || id == moduleIndexId){ - module = pkg.modules[i]; - break; - } - } - - return module; -} - -function newRequire(callingModule){ - function require(uri){ - var module, pkg; - - if(/^\./.test(uri)){ - module = findModule(callingModule, uri); - } else if ( ties && ties.hasOwnProperty( uri ) ) { - return ties[uri]; - } else if ( aliases && aliases.hasOwnProperty( uri ) ) { - return require(aliases[uri]); - } else { - pkg = pkgmap[uri]; - - if(!pkg && nativeRequire){ - try { - pkg = nativeRequire(uri); - } catch (nativeRequireError) {} - - if(pkg) return pkg; - } - - if(!pkg){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module = pkg.index; - } - - if(!module){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module.parent = callingModule; - return module.call(); - }; - - - return require; -} - - -function module(parent, id, wrapper){ - var mod = { pkg: parent, id: id, wrapper: wrapper }, - cached = false; - - mod.exports = {}; - mod.require = newRequire(mod); - - mod.call = function(){ - if(cached) { - return mod.exports; - } - - cached = true; - - global.require = mod.require; - - mod.wrapper(mod, mod.exports, global, global.require); - return mod.exports; - }; - - if(parent.mainModuleId == mod.id){ - parent.index = mod; - parent.parents.length === 0 && ( main = mod.call ); - } - - parent.modules.push(mod); -} - -function pkg(/* [ parentId ...], wrapper */){ - var wrapper = arguments[ arguments.length - 1 ], - parents = Array.prototype.slice.call(arguments, 0, arguments.length - 1), - ctx = wrapper(parents); - - - pkgmap[ctx.name] = ctx; - - arguments.length == 1 && ( pkgmap.main = ctx ); - - return function(modules){ - var id; - for(id in modules){ - module(ctx, id, modules[id]); - } - }; -} - - -}(this)); - -bson.pkg(function(parents){ - - return { - 'name' : 'bson', - 'mainModuleId' : 'bson', - 'modules' : [], - 'parents' : parents - }; - -})({ 'binary': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - - -}, - - - -'binary_parser': function(module, exports, global, require, undefined){ - /** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; - -}, - - - -'bson': function(module, exports, global, require, undefined){ - var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; - -}, - - - -'code': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; -}, - - - -'db_ref': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; -}, - - - -'double': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; -}, - - - -'float_parser': function(module, exports, global, require, undefined){ - // Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; -}, - - - -'index': function(module, exports, global, require, undefined){ - try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -}, - - - -'long': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; -}, - - - -'max_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; -}, - - - -'min_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; -}, - - - -'objectid': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; -}, - - - -'symbol': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; -}, - - - -'timestamp': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; -}, - - }); - - -if(typeof module != 'undefined' && module.exports ){ - module.exports = bson; - - if( !module.parent ){ - bson(); - } -} diff --git a/frontend/express/node_modules/bson/browser_build/package.json b/frontend/express/node_modules/bson/browser_build/package.json deleted file mode 100644 index 3ebb58761c5..00000000000 --- a/frontend/express/node_modules/bson/browser_build/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ "name" : "bson" -, "description" : "A bson parser for node.js and the browser" -, "main": "../lib/bson/bson" -, "directories" : { "lib" : "../lib/bson" } -, "engines" : { "node" : ">=0.6.0" } -, "licenses" : [ { "type" : "Apache License, Version 2.0" - , "url" : "http://www.apache.org/licenses/LICENSE-2.0" } ] -} diff --git a/frontend/express/node_modules/bson/build/Makefile b/frontend/express/node_modules/bson/build/Makefile deleted file mode 100644 index e1f9d66f66d..00000000000 --- a/frontend/express/node_modules/bson/build/Makefile +++ /dev/null @@ -1,333 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bson.target.mk)))),) - include bson.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/home/b/Desktop/countly/frontend/express/node_modules/bson/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/root/.node-gyp/0.10.11/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/root/.node-gyp/0.10.11" "-Dmodule_root_dir=/home/b/Desktop/countly/frontend/express/node_modules/bson" binding.gyp -Makefile: $(srcdir)/../../../../../../../../root/.node-gyp/0.10.11/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/frontend/express/node_modules/bson/build/Release/.deps/Release/bson.node.d b/frontend/express/node_modules/bson/build/Release/.deps/Release/bson.node.d deleted file mode 100644 index 866c155bc23..00000000000 --- a/frontend/express/node_modules/bson/build/Release/.deps/Release/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bson.node := rm -rf "Release/bson.node" && cp -af "Release/obj.target/bson.node" "Release/bson.node" diff --git a/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d b/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d deleted file mode 100644 index a7317de71b7..00000000000 --- a/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/bson.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m32 -Wl,-soname=bson.node -o Release/obj.target/bson.node -Wl,--start-group Release/obj.target/bson/ext/bson.o -Wl,--end-group diff --git a/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d b/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d deleted file mode 100644 index 5cdc93f8392..00000000000 --- a/frontend/express/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d +++ /dev/null @@ -1,28 +0,0 @@ -cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/root/.node-gyp/0.10.11/src -I/root/.node-gyp/0.10.11/deps/uv/include -I/root/.node-gyp/0.10.11/deps/v8/include -Wall -Wextra -Wno-unused-parameter -pthread -m32 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-tree-sink -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc -Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \ - /root/.node-gyp/0.10.11/deps/v8/include/v8.h \ - /root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/src/node_version.h \ - /root/.node-gyp/0.10.11/src/node_buffer.h ../ext/bson.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h -../ext/bson.cc: -/root/.node-gyp/0.10.11/deps/v8/include/v8.h: -/root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/src/node_version.h: -/root/.node-gyp/0.10.11/src/node_buffer.h: -../ext/bson.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: diff --git a/frontend/express/node_modules/bson/build/Release/bson.node b/frontend/express/node_modules/bson/build/Release/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/bson/build/Release/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/bson/build/Release/obj.target/bson.node b/frontend/express/node_modules/bson/build/Release/obj.target/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/bson/build/Release/obj.target/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/bson/build/Release/obj.target/bson/ext/bson.o b/frontend/express/node_modules/bson/build/Release/obj.target/bson/ext/bson.o deleted file mode 100644 index a2bfc494436..00000000000 Binary files a/frontend/express/node_modules/bson/build/Release/obj.target/bson/ext/bson.o and /dev/null differ diff --git a/frontend/express/node_modules/bson/build/binding.Makefile b/frontend/express/node_modules/bson/build/binding.Makefile deleted file mode 100644 index 90bf8247b39..00000000000 --- a/frontend/express/node_modules/bson/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) bson diff --git a/frontend/express/node_modules/bson/build/bson.target.mk b/frontend/express/node_modules/bson/build/bson.target.mk deleted file mode 100644 index 5359f669c3e..00000000000 --- a/frontend/express/node_modules/bson/build/bson.target.mk +++ /dev/null @@ -1,126 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bson -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti - -INCS_Debug := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-tree-sink - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti - -INCS_Release := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/ext/bson.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m32 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m32 - -LIBS := - -$(obj).target/bson.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/bson.node: LIBS := $(LIBS) -$(obj).target/bson.node: TOOLSET := $(TOOLSET) -$(obj).target/bson.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/bson.node -# Add target alias -.PHONY: bson -bson: $(builddir)/bson.node - -# Copy this to the executable output path. -$(builddir)/bson.node: TOOLSET := $(TOOLSET) -$(builddir)/bson.node: $(obj).target/bson.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/bson.node -# Short alias for building this executable. -.PHONY: bson.node -bson.node: $(obj).target/bson.node $(builddir)/bson.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bson.node - diff --git a/frontend/express/node_modules/bson/build/config.gypi b/frontend/express/node_modules/bson/build/config.gypi deleted file mode 100644 index 69c52b6eb0f..00000000000 --- a/frontend/express/node_modules/bson/build/config.gypi +++ /dev/null @@ -1,114 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 44, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/root/.node-gyp/0.10.11", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "pre": "", - "sign_git_tag": "", - "always_auth": "", - "user_agent": "node/v0.10.11 linux ia32", - "bin_links": "true", - "description": "true", - "fetch_retries": "2", - "init_version": "0.0.0", - "user": "", - "force": "", - "ignore": "", - "cache_min": "10", - "editor": "vi", - "rollback": "true", - "cache_max": "null", - "userconfig": "/root/.npmrc", - "coverage": "", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/root/tmp", - "userignorefile": "/root/.npmignore", - "yes": "", - "depth": "null", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/root/.npm", - "npaturl": "http://npat.npmjs.org/", - "searchsort": "name", - "version": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.11", - "tag": "latest", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/root/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "group": "", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "json": "" - } -} diff --git a/frontend/express/node_modules/bson/build_browser.js b/frontend/express/node_modules/bson/build_browser.js deleted file mode 100644 index bb802384453..00000000000 --- a/frontend/express/node_modules/bson/build_browser.js +++ /dev/null @@ -1,7 +0,0 @@ -require('one'); - -one('./package.json') - .tie('bson', BSON) - // .exclude('buffer') - .tie('buffer', {}) - .save('./browser_build/bson.js') \ No newline at end of file diff --git a/frontend/express/node_modules/bson/ext/Makefile b/frontend/express/node_modules/bson/ext/Makefile deleted file mode 100644 index 435999ee960..00000000000 --- a/frontend/express/node_modules/bson/ext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/bson/ext/bson.cc b/frontend/express/node_modules/bson/ext/bson.cc deleted file mode 100644 index 8a2ec8b7e7a..00000000000 --- a/frontend/express/node_modules/bson/ext/bson.cc +++ /dev/null @@ -1,1006 +0,0 @@ -//=========================================================================== - -#include -#include -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -// this and the above block must be around the v8.h header otherwise -// v8 is not happy -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __sun - #include -#endif - -#include "bson.h" - -using namespace v8; -using namespace node; - -//=========================================================================== - -void DataStream::WriteObjectId(const Handle& object, const Handle& key) -{ - uint16_t buffer[12]; - object->Get(key)->ToString()->Write(buffer, 0, 12); - for(uint32_t i = 0; i < 12; ++i) - { - *p++ = (char) buffer[i]; - } -} - -void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...) -{ - va_list args; - va_start(args, format); - char* string = (char*) malloc(allocationSize); - vsprintf(string, format, args); - va_end(args); - - throw string; -} - -void DataStream::CheckKey(const Local& keyName) -{ - size_t keyLength = keyName->Utf8Length(); - if(keyLength == 0) return; - - char* keyStringBuffer = (char*) alloca(keyLength+1); - keyName->WriteUtf8(keyStringBuffer); - - if(keyStringBuffer[0] == '$') - { - ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer); - } - - if(strchr(keyStringBuffer, '.') != NULL) - { - ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer); - } -} - -template void BSONSerializer::SerializeDocument(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - Local object = bson->GetSerializeObject(value); - - // Get the object property names - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local propertyNames = object->GetPropertyNames(); - #else - Local propertyNames = object->GetOwnPropertyNames(); - #endif - - // Length of the property - int propertyLength = propertyNames->Length(); - for(int i = 0; i < propertyLength; ++i) - { - const Local& propertyName = propertyNames->Get(i)->ToString(); - if(checkKeys) this->CheckKey(propertyName); - - const Local& propertyValue = object->Get(propertyName); - - if(serializeFunctions || !propertyValue->IsFunction()) - { - void* typeLocation = this->BeginWriteType(); - this->WriteString(propertyName); - SerializeValue(typeLocation, propertyValue); - } - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -template void BSONSerializer::SerializeArray(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - - Local array = Local::Cast(value->ToObject()); - uint32_t arrayLength = array->Length(); - - for(uint32_t i = 0; i < arrayLength; ++i) - { - void* typeLocation = this->BeginWriteType(); - this->WriteUInt32String(i); - SerializeValue(typeLocation, array->Get(i)); - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes. -// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths) -// and ensures that there is always consistency between bytes counted and bytes written by design. -template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value) -{ - if(value->IsNumber()) - { - double doubleValue = value->NumberValue(); - int intValue = (int) doubleValue; - if(intValue == doubleValue) - { - this->CommitType(typeLocation, BSON_TYPE_INT); - this->WriteInt32(intValue); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(doubleValue); - } - } - else if(value->IsString()) - { - this->CommitType(typeLocation, BSON_TYPE_STRING); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsBoolean()) - { - this->CommitType(typeLocation, BSON_TYPE_BOOLEAN); - this->WriteBool(value); - } - else if(value->IsArray()) - { - this->CommitType(typeLocation, BSON_TYPE_ARRAY); - SerializeArray(value); - } - else if(value->IsDate()) - { - this->CommitType(typeLocation, BSON_TYPE_DATE); - this->WriteInt64(value); - } - else if(value->IsRegExp()) - { - this->CommitType(typeLocation, BSON_TYPE_REGEXP); - const Handle& regExp = Handle::Cast(value); - - this->WriteString(regExp->GetSource()); - - int flags = regExp->GetFlags(); - if(flags & RegExp::kGlobal) this->WriteByte('s'); - if(flags & RegExp::kIgnoreCase) this->WriteByte('i'); - if(flags & RegExp::kMultiline) this->WriteByte('m'); - this->WriteByte(0); - } - else if(value->IsFunction()) - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsObject()) - { - const Local& object = value->ToObject(); - if(object->Has(bson->_bsontypeString)) - { - const Local& constructorString = object->GetConstructorName(); - if(bson->longString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_LONG); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->timestampString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->objectIDString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OID); - this->WriteObjectId(object, bson->_objectIDidString); - } - else if(bson->binaryString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value(); - Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject(); - - this->WriteInt32(length); - this->WriteByte(object, bson->_binarySubTypeString); // write subtype - // If type 0x02 write the array length aswell - if(object->Get(bson->_binarySubTypeString)->Int32Value() == 0x02) { - this->WriteInt32(length); - } - // Write the actual data - this->WriteData(Buffer::Data(bufferObj), length); - } - else if(bson->doubleString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(object, bson->_doubleValueString); - } - else if(bson->symbolString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_SYMBOL); - this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString()); - } - else if(bson->codeString->StrictEquals(constructorString)) - { - const Local& function = object->Get(bson->_codeCodeString)->ToString(); - const Local& scope = object->Get(bson->_codeScopeString)->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - if(propertyNameLength > 0) - { - this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE); - void* codeWidthScopeSize = this->BeginWriteSize(); - this->WriteLengthPrefixedString(function->ToString()); - SerializeDocument(scope); - this->CommitSize(codeWidthScopeSize); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(function->ToString()); - } - } - else if(bson->dbrefString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - - void* dbRefSize = this->BeginWriteSize(); - - void* refType = this->BeginWriteType(); - this->WriteData("$ref", 5); - SerializeValue(refType, object->Get(bson->_dbRefNamespaceString)); - - void* idType = this->BeginWriteType(); - this->WriteData("$id", 4); - SerializeValue(idType, object->Get(bson->_dbRefOidString)); - - const Local& refDbValue = object->Get(bson->_dbRefDbString); - if(!refDbValue->IsUndefined()) - { - void* dbType = this->BeginWriteType(); - this->WriteData("$db", 4); - SerializeValue(dbType, refDbValue); - } - - this->WriteByte(0); - this->CommitSize(dbRefSize); - } - else if(bson->minKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MIN_KEY); - } - else if(bson->maxKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MAX_KEY); - } - } - else if(Buffer::HasInstance(value)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(value->ToObject()); - uint32_t length = object->length(); - #else - uint32_t length = Buffer::Length(value->ToObject()); - #endif - - this->WriteInt32(length); - this->WriteByte(0); - this->WriteData(Buffer::Data(value->ToObject()), length); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - SerializeDocument(value); - } - } - else if(value->IsNull() || value->IsUndefined()) - { - this->CommitType(typeLocation, BSON_TYPE_NULL); - } -} - -// Data points to start of element list, length is length of entire document including '\0' but excluding initial size -BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length) -: bson(aBson), - pStart(data), - p(data), - pEnd(data + length - 1) -{ - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length) -: bson(parentSerializer.bson), - pStart(parentSerializer.p), - p(parentSerializer.p), - pEnd(parentSerializer.p + length - 1) -{ - parentSerializer.p += length; - if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds"); - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -Local BSONDeserializer::ReadCString() -{ - char* start = p; - while(*p++) { } - return String::New(start, (int32_t) (p-start-1) ); -} - -int32_t BSONDeserializer::ReadRegexOptions() -{ - int32_t options = 0; - for(;;) - { - switch(*p++) - { - case '\0': return options; - case 's': options |= RegExp::kGlobal; break; - case 'i': options |= RegExp::kIgnoreCase; break; - case 'm': options |= RegExp::kMultiline; break; - } - } -} - -uint32_t BSONDeserializer::ReadIntegerString() -{ - uint32_t value = 0; - while(*p) - { - if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array"); - value = value * 10 + *p++ - '0'; - } - ++p; - return value; -} - -Local BSONDeserializer::ReadString() -{ - uint32_t length = ReadUInt32(); - char* start = p; - p += length; - return String::New(start, length-1); -} - -Local BSONDeserializer::ReadObjectId() -{ - uint16_t objectId[12]; - for(size_t i = 0; i < 12; ++i) - { - objectId[i] = *reinterpret_cast(p++); - } - return String::New(objectId, 12); -} - -Handle BSONDeserializer::DeserializeDocument() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeDocumentInternal(); -} - -Handle BSONDeserializer::DeserializeDocumentInternal() -{ - Local returnObject = Object::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - const Local& name = ReadCString(); - const Handle& value = DeserializeValue(type); - returnObject->ForceSet(name, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes"); - - // From JavaScript: - // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - if(returnObject->Has(bson->_dbRefIdRefString)) - { - Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) }; - return bson->dbrefConstructor->NewInstance(3, argv); - } - else - { - return returnObject; - } -} - -Handle BSONDeserializer::DeserializeArray() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeArrayInternal(); -} - -Handle BSONDeserializer::DeserializeArrayInternal() -{ - Local returnArray = Array::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - uint32_t index = ReadIntegerString(); - const Handle& value = DeserializeValue(type); - returnArray->Set(index, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes"); - - return returnArray; -} - -Handle BSONDeserializer::DeserializeValue(BsonType type) -{ - switch(type) - { - case BSON_TYPE_STRING: - return ReadString(); - - case BSON_TYPE_INT: - return Integer::New(ReadInt32()); - - case BSON_TYPE_NUMBER: - return Number::New(ReadDouble()); - - case BSON_TYPE_NULL: - return Null(); - - case BSON_TYPE_UNDEFINED: - return Undefined(); - - case BSON_TYPE_TIMESTAMP: - { - int32_t lowBits = ReadInt32(); - int32_t highBits = ReadInt32(); - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->timestampConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_BOOLEAN: - return (ReadByte() != 0) ? True() : False(); - - case BSON_TYPE_REGEXP: - { - const Local& regex = ReadCString(); - int32_t options = ReadRegexOptions(); - return RegExp::New(regex, (RegExp::Flags) options); - } - - case BSON_TYPE_CODE: - { - const Local& code = ReadString(); - const Local& scope = Object::New(); - Local argv[] = { code, scope }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_CODE_W_SCOPE: - { - ReadUInt32(); - const Local& code = ReadString(); - const Handle& scope = DeserializeDocument(); - Local argv[] = { code, scope->ToObject() }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_OID: - { - Local argv[] = { ReadObjectId() }; - return bson->objectIDConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_BINARY: - { - uint32_t length = ReadUInt32(); - uint32_t subType = ReadByte(); - if(subType == 0x02) { - length = ReadInt32(); - } - - Buffer* buffer = Buffer::New(p, length); - p += length; - - Handle argv[] = { buffer->handle_, Uint32::New(subType) }; - return bson->binaryConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_LONG: - { - // Read 32 bit integers - int32_t lowBits = (int32_t) ReadInt32(); - int32_t highBits = (int32_t) ReadInt32(); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - // Adjust the pointer and read as 64 bit value - p -= 8; - // Read the 64 bit value - int64_t finalValue = (int64_t) ReadInt64(); - return Number::New(finalValue); - } - - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->longConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_DATE: - return Date::New((double) ReadInt64()); - - case BSON_TYPE_ARRAY: - return DeserializeArray(); - - case BSON_TYPE_OBJECT: - return DeserializeDocument(); - - case BSON_TYPE_SYMBOL: - { - const Local& string = ReadString(); - Local argv[] = { string }; - return bson->symbolConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_MIN_KEY: - return bson->minKeyConstructor->NewInstance(); - - case BSON_TYPE_MAX_KEY: - return bson->maxKeyConstructor->NewInstance(); - - default: - ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type); - } - - return v8::Null(); -} - - -static Handle VException(const char *msg) -{ - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Persistent BSON::constructor_template; - -BSON::BSON() : ObjectWrap() -{ - // Setup pre-allocated comparision objects - _bsontypeString = Persistent::New(String::New("_bsontype")); - _longLowString = Persistent::New(String::New("low_")); - _longHighString = Persistent::New(String::New("high_")); - _objectIDidString = Persistent::New(String::New("id")); - _binaryPositionString = Persistent::New(String::New("position")); - _binarySubTypeString = Persistent::New(String::New("sub_type")); - _binaryBufferString = Persistent::New(String::New("buffer")); - _doubleValueString = Persistent::New(String::New("value")); - _symbolValueString = Persistent::New(String::New("value")); - _dbRefRefString = Persistent::New(String::New("$ref")); - _dbRefIdRefString = Persistent::New(String::New("$id")); - _dbRefDbRefString = Persistent::New(String::New("$db")); - _dbRefNamespaceString = Persistent::New(String::New("namespace")); - _dbRefDbString = Persistent::New(String::New("db")); - _dbRefOidString = Persistent::New(String::New("oid")); - _codeCodeString = Persistent::New(String::New("code")); - _codeScopeString = Persistent::New(String::New("scope")); - _toBSONString = Persistent::New(String::New("toBSON")); - - longString = Persistent::New(String::New("Long")); - objectIDString = Persistent::New(String::New("ObjectID")); - binaryString = Persistent::New(String::New("Binary")); - codeString = Persistent::New(String::New("Code")); - dbrefString = Persistent::New(String::New("DBRef")); - symbolString = Persistent::New(String::New("Symbol")); - doubleString = Persistent::New(String::New("Double")); - timestampString = Persistent::New(String::New("Timestamp")); - minKeyString = Persistent::New(String::New("MinKey")); - maxKeyString = Persistent::New(String::New("MaxKey")); -} - -void BSON::Initialize(v8::Handle target) -{ - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and passing it the existing context -Handle BSON::New(const Arguments &args) -{ - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) - { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) - { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - uint32_t foundClassesMask = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(bson->longString)) { - bson->longConstructor = Persistent::New(func); - foundClassesMask |= 1; - } else if(functionName->StrictEquals(bson->objectIDString)) { - bson->objectIDConstructor = Persistent::New(func); - foundClassesMask |= 2; - } else if(functionName->StrictEquals(bson->binaryString)) { - bson->binaryConstructor = Persistent::New(func); - foundClassesMask |= 4; - } else if(functionName->StrictEquals(bson->codeString)) { - bson->codeConstructor = Persistent::New(func); - foundClassesMask |= 8; - } else if(functionName->StrictEquals(bson->dbrefString)) { - bson->dbrefConstructor = Persistent::New(func); - foundClassesMask |= 0x10; - } else if(functionName->StrictEquals(bson->symbolString)) { - bson->symbolConstructor = Persistent::New(func); - foundClassesMask |= 0x20; - } else if(functionName->StrictEquals(bson->doubleString)) { - bson->doubleConstructor = Persistent::New(func); - foundClassesMask |= 0x40; - } else if(functionName->StrictEquals(bson->timestampString)) { - bson->timestampConstructor = Persistent::New(func); - foundClassesMask |= 0x80; - } else if(functionName->StrictEquals(bson->minKeyString)) { - bson->minKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x100; - } else if(functionName->StrictEquals(bson->maxKeyString)) { - bson->maxKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x200; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(foundClassesMask != 0x3ff) { - delete bson; - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } - else - { - return VException("No types passed in"); - } - } - else - { - return VException("Argument passed in must be an array of types"); - } -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ - -Handle BSON::BSONDeserialize(const Arguments &args) -{ - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) - { -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Validate that we have at least 5 bytes - if(length < 5) return VException("corrupt bson message < 5 bytes long"); - - try - { - BSONDeserializer deserializer(bson, data, length); - return deserializer.DeserializeDocument(); - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - } - else - { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) return VException("corrupt bson message < 5 bytes long"); - - // Let's define the buffer size - char* data = (char *)malloc(len); - DecodeWrite(data, len, args[0], BINARY); - - try - { - BSONDeserializer deserializer(bson, data, len); - Handle result = deserializer.DeserializeDocument(); - free(data); - return result; - - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - free(data); - return error; - } - } -} - -Local BSON::GetSerializeObject(const Handle& argValue) -{ - Local object = argValue->ToObject(); - if(object->Has(_toBSONString)) - { - const Local& toBSON = object->Get(_toBSONString); - if(!toBSON->IsFunction()) ThrowAllocatedStringException(64, "toBSON is not a function"); - - Local result = Local::Cast(toBSON)->Call(object, 0, NULL); - if(!result->IsObject()) ThrowAllocatedStringException(64, "toBSON function did not return an object"); - return result->ToObject(); - } - else - { - return object; - } -} - -Handle BSON::BSONSerialize(const Arguments &args) -{ - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - bool serializeFunctions = (args.Length() >= 4) && args[3]->BooleanValue(); - - char *serialized_object = NULL; - size_t object_size; - try - { - Local object = bson->GetSerializeObject(args[0]); - - BSONSerializer counter(bson, false, serializeFunctions); - counter.SerializeDocument(object); - object_size = counter.GetSerializeSize(); - - // Allocate the memory needed for the serialization - serialized_object = (char *)malloc(object_size); - - // Check if we have a boolean value - bool checkKeys = args.Length() >= 3 && args[1]->IsBoolean() && args[1]->BooleanValue(); - BSONSerializer data(bson, checkKeys, serializeFunctions, serialized_object); - data.SerializeDocument(object); - } - catch(char *err_msg) - { - free(serialized_object); - Handle error = VException(err_msg); - free(err_msg); - return error; - } - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) - { - Buffer *buffer = Buffer::New(serialized_object, object_size); - free(serialized_object); - return scope.Close(buffer->handle_); - } - else - { - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - free(serialized_object); - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) -{ - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - bool serializeFunctions = (args.Length() >= 2) && args[1]->BooleanValue(); - BSONSerializer countSerializer(bson, false, serializeFunctions); - countSerializer.SerializeDocument(args[0]); - - // Return the object size - return scope.Close(Uint32::New((uint32_t) countSerializer.GetSerializeSize())); -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) -{ - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, ->, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - uint32_t index; - size_t object_size; - - try - { - BSON *bson = ObjectWrap::Unwrap(args.This()); - - Local obj = args[2]->ToObject(); - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); - - index = args[3]->Uint32Value(); - bool checkKeys = args.Length() >= 4 && args[1]->IsBoolean() && args[1]->BooleanValue(); - bool serializeFunctions = (args.Length() == 5) && args[4]->BooleanValue(); - - BSONSerializer dataSerializer(bson, checkKeys, serializeFunctions, data+index); - dataSerializer.SerializeDocument(bson->GetSerializeObject(args[0])); - object_size = dataSerializer.GetSerializeSize(); - - if(object_size + index > length) return VException("Serious error - overflowed buffer!!"); - } - catch(char *exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - return scope.Close(Uint32::New((uint32_t) (index + object_size - 1))); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) -{ - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) return VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) - { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->Uint32Value(); - uint32_t index = args[1]->Uint32Value(); - uint32_t resultIndex = args[4]->Uint32Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - BSONDeserializer deserializer(bson, data+index, length-index); - for(uint32_t i = 0; i < numberOfDocuments; i++) - { - try - { - documents->Set(i + resultIndex, deserializer.DeserializeDocument()); - } - catch (char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - } - - // Return new index of parsing - return scope.Close(Uint32::New((uint32_t) (index + deserializer.GetSerializeSize()))); -} - -// Exporting function -extern "C" void init(Handle target) -{ - HandleScope scope; - BSON::Initialize(target); -} - -NODE_MODULE(bson, BSON::Initialize); diff --git a/frontend/express/node_modules/bson/ext/bson.h b/frontend/express/node_modules/bson/ext/bson.h deleted file mode 100644 index 00f273b4022..00000000000 --- a/frontend/express/node_modules/bson/ext/bson.h +++ /dev/null @@ -1,277 +0,0 @@ -//=========================================================================== - -#ifndef BSON_H_ -#define BSON_H_ - -//=========================================================================== - -#ifdef __arm__ -#define USE_MISALIGNED_MEMORY_ACCESS 0 -#else -#define USE_MISALIGNED_MEMORY_ACCESS 1 -#endif - -#include -#include -#include - -using namespace v8; -using namespace node; - -//=========================================================================== - -enum BsonType -{ - BSON_TYPE_NUMBER = 1, - BSON_TYPE_STRING = 2, - BSON_TYPE_OBJECT = 3, - BSON_TYPE_ARRAY = 4, - BSON_TYPE_BINARY = 5, - BSON_TYPE_UNDEFINED = 6, - BSON_TYPE_OID = 7, - BSON_TYPE_BOOLEAN = 8, - BSON_TYPE_DATE = 9, - BSON_TYPE_NULL = 10, - BSON_TYPE_REGEXP = 11, - BSON_TYPE_CODE = 13, - BSON_TYPE_SYMBOL = 14, - BSON_TYPE_CODE_W_SCOPE = 15, - BSON_TYPE_INT = 16, - BSON_TYPE_TIMESTAMP = 17, - BSON_TYPE_LONG = 18, - BSON_TYPE_MAX_KEY = 0x7f, - BSON_TYPE_MIN_KEY = 0xff -}; - -//=========================================================================== - -template class BSONSerializer; - -class BSON : public ObjectWrap { -public: - BSON(); - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - -private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparison objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - Persistent _codeCodeString; - Persistent _codeScopeString; - Persistent _toBSONString; - - Local GetSerializeObject(const Handle& object); - - template friend class BSONSerializer; - friend class BSONDeserializer; -}; - -//=========================================================================== - -class CountStream -{ -public: - CountStream() : count(0) { } - - void WriteByte(int value) { ++count; } - void WriteByte(const Handle&, const Handle&) { ++count; } - void WriteBool(const Handle& value) { ++count; } - void WriteInt32(int32_t value) { count += 4; } - void WriteInt32(const Handle& value) { count += 4; } - void WriteInt32(const Handle& object, const Handle& key) { count += 4; } - void WriteInt64(int64_t value) { count += 8; } - void WriteInt64(const Handle& value) { count += 8; } - void WriteDouble(double value) { count += 8; } - void WriteDouble(const Handle& value) { count += 8; } - void WriteDouble(const Handle&, const Handle&) { count += 8; } - void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { count += value->Utf8Length()+5; } - void WriteObjectId(const Handle& object, const Handle& key) { count += 12; } - void WriteString(const Local& value) { count += value->Utf8Length() + 1; } // This returns the number of bytes exclusive of the NULL terminator - void WriteData(const char* data, size_t length) { count += length; } - - void* BeginWriteType() { ++count; return NULL; } - void CommitType(void*, BsonType) { } - void* BeginWriteSize() { count += 4; return NULL; } - void CommitSize(void*) { } - - size_t GetSerializeSize() const { return count; } - - // Do nothing. CheckKey is implemented for DataStream - void CheckKey(const Local&) { } - -private: - size_t count; -}; - -class DataStream -{ -public: - DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { } - - void WriteByte(int value) { *p++ = value; } - void WriteByte(const Handle& object, const Handle& key) { *p++ = object->Get(key)->Int32Value(); } -#if USE_MISALIGNED_MEMORY_ACCESS - void WriteInt32(int32_t value) { *reinterpret_cast(p) = value; p += 4; } - void WriteInt64(int64_t value) { *reinterpret_cast(p) = value; p += 8; } - void WriteDouble(double value) { *reinterpret_cast(p) = value; p += 8; } -#else - void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; } - void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; } - void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; } -#endif - void WriteBool(const Handle& value) { WriteByte(value->BooleanValue() ? 1 : 0); } - void WriteInt32(const Handle& value) { WriteInt32(value->Int32Value()); } - void WriteInt32(const Handle& object, const Handle& key) { WriteInt32(object->Get(key)); } - void WriteInt64(const Handle& value) { WriteInt64(value->IntegerValue()); } - void WriteDouble(const Handle& value) { WriteDouble(value->NumberValue()); } - void WriteDouble(const Handle& object, const Handle& key) { WriteDouble(object->Get(key)); } - void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); } - void WriteObjectId(const Handle& object, const Handle& key); - void WriteString(const Local& value) { p += value->WriteUtf8(p); } // This returns the number of bytes inclusive of the NULL terminator. - void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; } - - void* BeginWriteType() { void* returnValue = p; p++; return returnValue; } - void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast(beginPoint) = value; } - void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; } - -#if USE_MISALIGNED_MEMORY_ACCESS - void CommitSize(void* beginPoint) { *reinterpret_cast(beginPoint) = (int32_t) (p - (char*) beginPoint); } -#else - void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); } -#endif - - size_t GetSerializeSize() const { return p - destinationBuffer; } - - void CheckKey(const Local& keyName); - -protected: - char *const destinationBuffer; // base, never changes - char* p; // cursor into buffer -}; - -template class BSONSerializer : public T -{ -private: - typedef T Inherited; - -public: - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - - void SerializeDocument(const Handle& value); - void SerializeArray(const Handle& value); - void SerializeValue(void* typeLocation, const Handle& value); - -private: - bool checkKeys; - bool serializeFunctions; - BSON* bson; -}; - -//=========================================================================== - -class BSONDeserializer -{ -public: - BSONDeserializer(BSON* aBson, char* data, size_t length); - BSONDeserializer(BSONDeserializer& parentSerializer, size_t length); - - Handle DeserializeDocument(); - - bool HasMoreData() const { return p < pEnd; } - Local ReadCString(); - uint32_t ReadIntegerString(); - int32_t ReadRegexOptions(); - Local ReadString(); - Local ReadObjectId(); - - unsigned char ReadByte() { return *reinterpret_cast(p++); } -#if USE_MISALIGNED_MEMORY_ACCESS - int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast(p); p += 8; return returnValue; } - double ReadDouble() { double returnValue = *reinterpret_cast(p); p += 8; return returnValue; } -#else - int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } - double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } -#endif - - size_t GetSerializeSize() const { return p - pStart; } - -private: - Handle DeserializeArray(); - Handle DeserializeValue(BsonType type); - Handle DeserializeDocumentInternal(); - Handle DeserializeArrayInternal(); - - BSON* bson; - char* const pStart; - char* p; - char* const pEnd; -}; - -//=========================================================================== - -#endif // BSON_H_ - -//=========================================================================== diff --git a/frontend/express/node_modules/bson/ext/index.js b/frontend/express/node_modules/bson/ext/index.js deleted file mode 100644 index 85e243cc2e1..00000000000 --- a/frontend/express/node_modules/bson/ext/index.js +++ /dev/null @@ -1,30 +0,0 @@ -var bson = null; - -// Load the precompiled win32 binary -if(process.platform == "win32" && process.arch == "x64") { - bson = require('./win32/x64/bson'); -} else if(process.platform == "win32" && process.arch == "ia32") { - bson = require('./win32/ia32/bson'); -} else { - bson = require('../build/Release/bson'); -} - -exports.BSON = bson.BSON; -exports.Long = require('../lib/bson/long').Long; -exports.ObjectID = require('../lib/bson/objectid').ObjectID; -exports.DBRef = require('../lib/bson/db_ref').DBRef; -exports.Code = require('../lib/bson/code').Code; -exports.Timestamp = require('../lib/bson/timestamp').Timestamp; -exports.Binary = require('../lib/bson/binary').Binary; -exports.Double = require('../lib/bson/double').Double; -exports.MaxKey = require('../lib/bson/max_key').MaxKey; -exports.MinKey = require('../lib/bson/min_key').MinKey; -exports.Symbol = require('../lib/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/bson/ext/win32/ia32/bson.node b/frontend/express/node_modules/bson/ext/win32/ia32/bson.node deleted file mode 100644 index b27819bb1a8..00000000000 Binary files a/frontend/express/node_modules/bson/ext/win32/ia32/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/bson/ext/win32/x64/bson.node b/frontend/express/node_modules/bson/ext/win32/x64/bson.node deleted file mode 100644 index a544c8ed638..00000000000 Binary files a/frontend/express/node_modules/bson/ext/win32/x64/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/bson/ext/wscript b/frontend/express/node_modules/bson/ext/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/bson/ext/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/bson/install.js b/frontend/express/node_modules/bson/install.js deleted file mode 100644 index c9cc91d0742..00000000000 --- a/frontend/express/node_modules/bson/install.js +++ /dev/null @@ -1,41 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_config_mongodb_native'] != null ? process.env['npm_config_mongodb_native'] : 'false'; -build_native = build_native == 'true' ? true : false; - -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total'], {cwd:process.env['PWD']}); - } else { - make = spawn('gmake', ['total'], {cwd:process.env['PWD']}); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/frontend/express/node_modules/bson/lib/bson/binary.js b/frontend/express/node_modules/bson/lib/bson/binary.js deleted file mode 100644 index 82d4d04c10b..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/binary.js +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/frontend/express/node_modules/bson/lib/bson/binary_parser.js b/frontend/express/node_modules/bson/lib/bson/binary_parser.js deleted file mode 100644 index d2fc811f416..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/binary_parser.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; diff --git a/frontend/express/node_modules/bson/lib/bson/bson.js b/frontend/express/node_modules/bson/lib/bson/bson.js deleted file mode 100644 index 7da82492be1..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/bson.js +++ /dev/null @@ -1,1519 +0,0 @@ -var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; diff --git a/frontend/express/node_modules/bson/lib/bson/code.js b/frontend/express/node_modules/bson/lib/bson/code.js deleted file mode 100644 index 69b56a3ff51..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/code.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/db_ref.js b/frontend/express/node_modules/bson/lib/bson/db_ref.js deleted file mode 100644 index 56b651029bd..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/db_ref.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/double.js b/frontend/express/node_modules/bson/lib/bson/double.js deleted file mode 100644 index ae5146378f0..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/double.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/float_parser.js b/frontend/express/node_modules/bson/lib/bson/float_parser.js deleted file mode 100644 index 6fca3924f6c..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/float_parser.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/index.js b/frontend/express/node_modules/bson/lib/bson/index.js deleted file mode 100644 index 950fcad343d..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/index.js +++ /dev/null @@ -1,74 +0,0 @@ -try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} diff --git a/frontend/express/node_modules/bson/lib/bson/long.js b/frontend/express/node_modules/bson/lib/bson/long.js deleted file mode 100644 index f8f37a6b865..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/long.js +++ /dev/null @@ -1,854 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/max_key.js b/frontend/express/node_modules/bson/lib/bson/max_key.js deleted file mode 100644 index 0825408d0c9..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/max_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/min_key.js b/frontend/express/node_modules/bson/lib/bson/min_key.js deleted file mode 100644 index 230c2e64a1d..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/min_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/objectid.js b/frontend/express/node_modules/bson/lib/bson/objectid.js deleted file mode 100644 index 183bbc3c939..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/objectid.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation date (accurate up to the second) that this ID was generated. -* -* @return {Date} the generation date -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; diff --git a/frontend/express/node_modules/bson/lib/bson/symbol.js b/frontend/express/node_modules/bson/lib/bson/symbol.js deleted file mode 100644 index 8e2838d1783..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/lib/bson/timestamp.js b/frontend/express/node_modules/bson/lib/bson/timestamp.js deleted file mode 100644 index c650d1536c8..00000000000 --- a/frontend/express/node_modules/bson/lib/bson/timestamp.js +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/frontend/express/node_modules/bson/package.json b/frontend/express/node_modules/bson/package.json deleted file mode 100644 index e9eb5f1638c..00000000000 --- a/frontend/express/node_modules/bson/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "bson", - "description": "A bson parser for node.js and the browser", - "keywords": [ - "mongodb", - "bson", - "parser" - ], - "version": "0.1.9", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [], - "repository": { - "type": "git", - "url": "git://github.com/mongodb/js-bson.git" - }, - "bugs": { - "url": "https://github.com/mongodb/js-bson/issues" - }, - "devDependencies": { - "nodeunit": "0.7.3", - "gleak": "0.2.3", - "one": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/bson/index", - "directories": { - "lib": "./lib/bson" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "nodeunit ./test/node && TEST_NATIVE=TRUE nodeunit ./test/node" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Javascript + C++ BSON parser\n============================\n\nThis BSON parser is primarily meant for usage with the `mongodb` node.js driver. However thanks to such wonderful tools at `onejs` we are able to package up a BSON parser that will work in the browser aswell. The current build is located in the `browser_build/bson.js` file.\n\nA simple example on how to use it\n\n \n \n \n \n \n \n\n It's got two simple methods to use in your application.\n\n * BSON.serialize(object, checkKeys, asBuffer, serializeFunctions)\n * @param {Object} object the Javascript object to serialize.\n * @param {Boolean} checkKeys the serializer will check if keys are valid.\n * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**.\n * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**\n * @return {TypedArray/Array} returns a TypedArray or Array depending on what your browser supports\n \n * BSON.deserialize(buffer, options, isArray)\n * Options\n * **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.\n * **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.\n * **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.\n * @param {TypedArray/Array} a TypedArray/Array containing the BSON data\n * @param {Object} [options] additional options used for the deserialization.\n * @param {Boolean} [isArray] ignore used for recursive parsing.\n * @return {Object} returns the deserialized Javascript Object.\n", - "readmeFilename": "README.md", - "_id": "bson@0.1.9", - "_from": "bson@0.1.9" -} diff --git a/frontend/express/node_modules/bson/test/browser/bson_test.js b/frontend/express/node_modules/bson/test/browser/bson_test.js deleted file mode 100644 index 84d8ffc78a9..00000000000 --- a/frontend/express/node_modules/bson/test/browser/bson_test.js +++ /dev/null @@ -1,260 +0,0 @@ -this.bson_test = { - 'Full document serialization and deserialization': function (test) { - var motherOfAllDocuments = { - 'string': "客家è¯", - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary('hello world'), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSON.serialize(motherOfAllDocuments, true, true, false); - // Deserialize the object - var object = BSON.deserialize(data); - - // Asserts - test.equal(Utf8.decode(motherOfAllDocuments.string), object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - test.ok(assertArrayEqual(motherOfAllDocuments.binary.value(true), object.binary.value(true))); - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); - }, - - 'exercise all the binary object constructor methods': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - test.done(); - }, - - 'exercise the put binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); - }, - - 'exercise the write binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); - }, - - 'exercise the read binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(assertArrayEqual(stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(assertArrayEqual(stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(assertArrayEqual(stringToArrayBuffer('world'), data)); - test.done(); - }, - - 'Should correctly handle toBson function for an object': function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = BSON.serialize(doc, false, true); - var deserialized_doc = BSON.deserialize(serialized_data); - test.equal(1, deserialized_doc.b); - test.done(); - } -}; - -var assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -var stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -var stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -var Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/bson/test/browser/nodeunit.js b/frontend/express/node_modules/bson/test/browser/nodeunit.js deleted file mode 100644 index af7fd0b5867..00000000000 --- a/frontend/express/node_modules/bson/test/browser/nodeunit.js +++ /dev/null @@ -1,2034 +0,0 @@ -/*! - * Nodeunit - * https://github.com/caolan/nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * json2.js - * http://www.JSON.org/json2.js - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -nodeunit = (function(){ -/* - http://www.JSON.org/json2.js - 2010-11-17 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, strict: false, regexp: false */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -var JSON = {}; - -(function () { - "use strict"; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) ? - this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? - '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : - '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : - gap ? '[\n' + gap + - partial.join(',\n' + gap) + '\n' + - mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : - gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + - mind + '}' : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ -.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') -.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') -.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); -var assert = this.assert = {}; -var types = {}; -var core = {}; -var nodeunit = {}; -var reporter = {}; -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - var _indexOf = function (arr, item) { - if (arr.indexOf) { - return arr.indexOf(item); - } - for (var i = 0; i < arr.length; i += 1) { - if (arr[i] === item) { - return i; - } - } - return -1; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var completed = []; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners, function (fn) { - fn(); - }); - }; - - addListener(function () { - if (completed.length === keys.length) { - callback(null); - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - completed.push(k); - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && _indexOf(completed, x) !== -1); - }, true); - }; - if (ready()) { - task[task.length - 1](taskCallback); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - if (!tasks.length) { - return callback(); - } - callback = callback || function () {}; - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var tasks = []; - var q = { - concurrency: concurrency, - push: function (data, callback) { - tasks.push({data: data, callback: callback}); - async.nextTick(q.process); - }, - process: function () { - if (workers < q.concurrency && tasks.length) { - var task = tasks.splice(0, 1)[0]; - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - q.process(); - }); - } - }, - length: function () { - return tasks.length; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - hasher = hasher || function (x) { - return x; - }; - return function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else { - fn.apply(null, args.concat([function () { - memo[key] = arguments; - callback.apply(null, arguments); - }])); - } - }; - }; - -}()); -(function(exports){ -/** - * This file is based on the node.js assert module, but with some small - * changes for browser-compatibility - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - */ - - -/** - * Added for browser compatibility - */ - -var _keys = function(obj){ - if(Object.keys) return Object.keys(obj); - if (typeof obj != 'object' && typeof obj != 'function') { - throw new TypeError('-'); - } - var keys = []; - for(var k in obj){ - if(obj.hasOwnProperty(k)) keys.push(k); - } - return keys; -}; - - - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({message: message, actual: actual, expected: expected}) - -assert.AssertionError = function AssertionError (options) { - this.name = "AssertionError"; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// code from util.inherits in node -assert.AssertionError.super_ = Error; - - -// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call -// TODO: test what effect this may have -var ctor = function () { this.constructor = assert.AssertionError; }; -ctor.prototype = Error.prototype; -assert.AssertionError.prototype = new ctor(); - - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name+":", this.message].join(' '); - } else { - return [ this.name+":" - , JSON.stringify(this.expected ) - , this.operator - , JSON.stringify(this.actual) - ].join(" "); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, "==", assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, "==", assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, "!=", assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, "deepEqual", assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == "object", - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical "prototype" property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull (value) { - return value === null || value === undefined; -} - -function isArguments (object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv (a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical "prototype" property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try{ - var ka = _keys(a), - kb = _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; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, "===", assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, "!==", assert.notStrictEqual); - } -}; - -function _throws (shouldThrow, block, err, message) { - var exception = null, - threw = false, - typematters = true; - - message = message || ""; - - //handle optional arguments - if (arguments.length == 3) { - if (typeof(err) == "string") { - message = err; - typematters = false; - } - } else if (arguments.length == 2) { - typematters = false; - } - - try { - block(); - } catch (e) { - threw = true; - exception = e; - } - - if (shouldThrow && !threw) { - fail( "Missing expected exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if (!shouldThrow && threw && typematters && exception instanceof err) { - fail( "Got unwanted exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if ((shouldThrow && threw && typematters && !(exception instanceof err)) || - (!shouldThrow && threw)) { - throw exception; - } -}; - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function (err) { if (err) {throw err;}}; -})(assert); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var assert = require('./assert'), //@REMOVE_LINE_FOR_BROWSER -// async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Creates assertion objects representing the result of an assert call. - * Accepts an object or AssertionError as its argument. - * - * @param {object} obj - * @api public - */ - -exports.assertion = function (obj) { - return { - method: obj.method || '', - message: obj.message || (obj.error && obj.error.message) || '', - error: obj.error, - passed: function () { - return !this.error; - }, - failed: function () { - return Boolean(this.error); - } - }; -}; - -/** - * Creates an assertion list object representing a group of assertions. - * Accepts an array of assertion objects. - * - * @param {Array} arr - * @param {Number} duration - * @api public - */ - -exports.assertionList = function (arr, duration) { - var that = arr || []; - that.failures = function () { - var failures = 0; - for (var i = 0; i < this.length; i += 1) { - if (this[i].failed()) { - failures += 1; - } - } - return failures; - }; - that.passes = function () { - return that.length - that.failures(); - }; - that.duration = duration || 0; - return that; -}; - -/** - * Create a wrapper function for assert module methods. Executes a callback - * after the it's complete with an assertion object representing the result. - * - * @param {Function} callback - * @api private - */ - -var assertWrapper = function (callback) { - return function (new_method, assert_method, arity) { - return function () { - var message = arguments[arity - 1]; - var a = exports.assertion({method: new_method, message: message}); - try { - assert[assert_method].apply(null, arguments); - } - catch (e) { - a.error = e; - } - callback(a); - }; - }; -}; - -/** - * Creates the 'test' object that gets passed to every test function. - * Accepts the name of the test function as its first argument, followed by - * the start time in ms, the options object and a callback function. - * - * @param {String} name - * @param {Number} start - * @param {Object} options - * @param {Function} callback - * @api public - */ - -exports.test = function (name, start, options, callback) { - var expecting; - var a_list = []; - - var wrapAssert = assertWrapper(function (a) { - a_list.push(a); - if (options.log) { - async.nextTick(function () { - options.log(a); - }); - } - }); - - var test = { - done: function (err) { - if (expecting !== undefined && expecting !== a_list.length) { - var e = new Error( - 'Expected ' + expecting + ' assertions, ' + - a_list.length + ' ran' - ); - var a1 = exports.assertion({method: 'expect', error: e}); - a_list.push(a1); - if (options.log) { - async.nextTick(function () { - options.log(a1); - }); - } - } - if (err) { - var a2 = exports.assertion({error: err}); - a_list.push(a2); - if (options.log) { - async.nextTick(function () { - options.log(a2); - }); - } - } - var end = new Date().getTime(); - async.nextTick(function () { - var assertion_list = exports.assertionList(a_list, end - start); - options.testDone(name, assertion_list); - callback(null, a_list); - }); - }, - ok: wrapAssert('ok', 'ok', 2), - same: wrapAssert('same', 'deepEqual', 3), - equals: wrapAssert('equals', 'equal', 3), - expect: function (num) { - expecting = num; - }, - _assertion_list: a_list - }; - // add all functions from the assert module - for (var k in assert) { - if (assert.hasOwnProperty(k)) { - test[k] = wrapAssert(k, k, assert[k].length); - } - } - return test; -}; - -/** - * Ensures an options object has all callbacks, adding empty callback functions - * if any are missing. - * - * @param {Object} opt - * @return {Object} - * @api public - */ - -exports.options = function (opt) { - var optionalCallback = function (name) { - opt[name] = opt[name] || function () {}; - }; - - optionalCallback('moduleStart'); - optionalCallback('moduleDone'); - optionalCallback('testStart'); - optionalCallback('testDone'); - //optionalCallback('log'); - - // 'done' callback is not optional. - - return opt; -}; -})(types); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER -// types = require('./types'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Added for browser compatibility - */ - -var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; -}; - - -var _copy = function (obj) { - var nobj = {}; - var keys = _keys(obj); - for (var i = 0; i < keys.length; i += 1) { - nobj[keys[i]] = obj[keys[i]]; - } - return nobj; -}; - - -/** - * Runs a test function (fn) from a loaded module. After the test function - * calls test.done(), the callback is executed with an assertionList as its - * second argument. - * - * @param {String} name - * @param {Function} fn - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runTest = function (name, fn, opt, callback) { - var options = types.options(opt); - - options.testStart(name); - var start = new Date().getTime(); - var test = types.test(name, start, options, callback); - - try { - fn(test); - } - catch (e) { - test.done(e); - } -}; - -/** - * Takes an object containing test functions or other test suites as properties - * and runs each in series. After all tests have completed, the callback is - * called with a list of all assertions as the second argument. - * - * If a name is passed to this function it is prepended to all test and suite - * names that run within it. - * - * @param {String} name - * @param {Object} suite - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runSuite = function (name, suite, opt, callback) { - var keys = _keys(suite); - - async.concatSeries(keys, function (k, cb) { - var prop = suite[k], _name; - - _name = name ? [].concat(name, k) : [k]; - - _name.toString = function () { - // fallback for old one - return this.join(' - '); - }; - - if (typeof prop === 'function') { - var in_name = false; - for (var i = 0; i < _name.length; i += 1) { - if (_name[i] === opt.testspec) { - in_name = true; - } - } - if (!opt.testspec || in_name) { - if (opt.moduleStart) { - opt.moduleStart(); - } - exports.runTest(_name, suite[k], opt, cb); - } - else { - return cb(); - } - } - else { - exports.runSuite(_name, suite[k], opt, cb); - } - }, callback); -}; - -/** - * Run each exported test function or test suite from a loaded module. - * - * @param {String} name - * @param {Object} mod - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runModule = function (name, mod, opt, callback) { - var options = _copy(types.options(opt)); - - var _run = false; - var _moduleStart = options.moduleStart; - function run_once() { - if (!_run) { - _run = true; - _moduleStart(name); - } - } - options.moduleStart = run_once; - - var start = new Date().getTime(); - - exports.runSuite(null, mod, options, function (err, a_list) { - var end = new Date().getTime(); - var assertion_list = types.assertionList(a_list, end - start); - options.moduleDone(name, assertion_list); - callback(null, a_list); - }); -}; - -/** - * Treats an object literal as a list of modules keyed by name. Runs each - * module and finished with calling 'done'. You can think of this as a browser - * safe alternative to runFiles in the nodeunit module. - * - * @param {Object} modules - * @param {Object} opt - * @api public - */ - -// TODO: add proper unit tests for this function -exports.runModules = function (modules, opt) { - var all_assertions = []; - var options = types.options(opt); - var start = new Date().getTime(); - - async.concatSeries(_keys(modules), function (k, cb) { - exports.runModule(k, modules[k], options, cb); - }, - function (err, all_assertions) { - var end = new Date().getTime(); - options.done(types.assertionList(all_assertions, end - start)); - }); -}; - - -/** - * Wraps a test function with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Function} fn - * @api private - */ - -var wrapTest = function (setUp, tearDown, fn) { - return function (test) { - var context = {}; - if (tearDown) { - var done = test.done; - test.done = function (err) { - try { - tearDown.call(context, function (err2) { - if (err && err2) { - test._assertion_list.push( - types.assertion({error: err}) - ); - return done(err2); - } - done(err || err2); - }); - } - catch (e) { - done(e); - } - }; - } - if (setUp) { - setUp.call(context, function (err) { - if (err) { - return test.done(err); - } - fn.call(context, test); - }); - } - else { - fn.call(context, test); - } - }; -}; - - -/** - * Wraps a group of tests with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Object} group - * @api private - */ - -var wrapGroup = function (setUp, tearDown, group) { - var tests = {}; - var keys = _keys(group); - for (var i = 0; i < keys.length; i += 1) { - var k = keys[i]; - if (typeof group[k] === 'function') { - tests[k] = wrapTest(setUp, tearDown, group[k]); - } - else if (typeof group[k] === 'object') { - tests[k] = wrapGroup(setUp, tearDown, group[k]); - } - } - return tests; -}; - - -/** - * Utility for wrapping a suite of test functions with setUp and tearDown - * functions. - * - * @param {Object} suite - * @return {Object} - * @api public - */ - -exports.testCase = function (suite) { - var setUp = suite.setUp; - var tearDown = suite.tearDown; - delete suite.setUp; - delete suite.tearDown; - return wrapGroup(setUp, tearDown, suite); -}; -})(core); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - - -/** - * NOTE: this test runner is not listed in index.js because it cannot be - * used with the command-line tool, only inside the browser. - */ - - -/** - * Reporter info string - */ - -exports.info = "Browser-based test reporter"; - - -/** - * Run all tests within each module, reporting the results - * - * @param {Array} files - * @api public - */ - -exports.run = function (modules, options) { - var start = new Date().getTime(); - - function setText(el, txt) { - if ('innerText' in el) { - el.innerText = txt; - } - else if ('textContent' in el){ - el.textContent = txt; - } - } - - function getOrCreate(tag, id) { - var el = document.getElementById(id); - if (!el) { - el = document.createElement(tag); - el.id = id; - document.body.appendChild(el); - } - return el; - }; - - var header = getOrCreate('h1', 'nodeunit-header'); - var banner = getOrCreate('h2', 'nodeunit-banner'); - var userAgent = getOrCreate('h2', 'nodeunit-userAgent'); - var tests = getOrCreate('ol', 'nodeunit-tests'); - var result = getOrCreate('p', 'nodeunit-testresult'); - - setText(userAgent, navigator.userAgent); - - nodeunit.runModules(modules, { - moduleStart: function (name) { - /*var mheading = document.createElement('h2'); - mheading.innerText = name; - results.appendChild(mheading); - module = document.createElement('ol'); - results.appendChild(module);*/ - }, - testDone: function (name, assertions) { - var test = document.createElement('li'); - var strong = document.createElement('strong'); - strong.innerHTML = name + ' (' + - '' + assertions.failures() + ', ' + - '' + assertions.passes() + ', ' + - assertions.length + - ')'; - test.className = assertions.failures() ? 'fail': 'pass'; - test.appendChild(strong); - - var aList = document.createElement('ol'); - aList.style.display = 'none'; - test.onclick = function () { - var d = aList.style.display; - aList.style.display = (d == 'none') ? 'block': 'none'; - }; - for (var i=0; i' + (a.error.stack || a.error) + ''; - li.className = 'fail'; - } - else { - li.innerHTML = a.message || a.method || 'no message'; - li.className = 'pass'; - } - aList.appendChild(li); - } - test.appendChild(aList); - tests.appendChild(test); - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - - var failures = assertions.failures(); - banner.className = failures ? 'fail': 'pass'; - - result.innerHTML = 'Tests completed in ' + duration + - ' milliseconds.
' + - assertions.passes() + ' assertions of ' + - '' + assertions.length + ' passed, ' + - assertions.failures() + ' failed.'; - } - }); -}; -})(reporter); -nodeunit = core; -nodeunit.assert = assert; -nodeunit.reporter = reporter; -nodeunit.run = reporter.run; -return nodeunit; })(); diff --git a/frontend/express/node_modules/bson/test/browser/suite2.js b/frontend/express/node_modules/bson/test/browser/suite2.js deleted file mode 100644 index c7288e8d875..00000000000 --- a/frontend/express/node_modules/bson/test/browser/suite2.js +++ /dev/null @@ -1,13 +0,0 @@ -this.suite2 = { - 'another test': function (test) { - setTimeout(function () { - // lots of assertions - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.done(); - }, 10); - } -}; diff --git a/frontend/express/node_modules/bson/test/browser/suite3.js b/frontend/express/node_modules/bson/test/browser/suite3.js deleted file mode 100644 index 89297419bf1..00000000000 --- a/frontend/express/node_modules/bson/test/browser/suite3.js +++ /dev/null @@ -1,7 +0,0 @@ -this.suite3 = { - 'test for ie6,7,8': function (test) { - test.deepEqual(["test"], ["test"]); - test.notDeepEqual(["a"], ["b"]); - test.done(); - } -}; diff --git a/frontend/express/node_modules/bson/test/browser/test.html b/frontend/express/node_modules/bson/test/browser/test.html deleted file mode 100644 index 56d4d9643b6..00000000000 --- a/frontend/express/node_modules/bson/test/browser/test.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Example tests - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/bson/test/node/bson_array_test.js b/frontend/express/node_modules/bson/test/node/bson_array_test.js deleted file mode 100644 index 5304bef45c8..00000000000 --- a/frontend/express/node_modules/bson/test/node/bson_array_test.js +++ /dev/null @@ -1,240 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -var _Uint8Array = null; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - _Uint8Array = global.Uint8Array; - delete global['Uint8Array']; - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - global['Uint8Array'] = _Uint8Array; - callback(); -} - -// /** -// * @ignore -// */ -// exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { -// var motherOfAllDocuments = { -// 'string': '客家è¯', -// 'array': [1,2,3], -// 'hash': {'a':1, 'b':2}, -// 'date': new Date(), -// 'oid': new ObjectID(), -// 'binary': new Binary(new Buffer("hello")), -// 'int': 42, -// 'float': 33.3333, -// 'regexp': /regexp/, -// 'boolean': true, -// 'long': Long.fromNumber(100), -// 'where': new Code('this.a > i', {i:1}), -// 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), -// 'minkey': new MinKey(), -// 'maxkey': new MaxKey() -// } -// -// // Let's serialize it -// var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); -// // Build a typed array -// var arr = new Uint8Array(new ArrayBuffer(data.length)); -// // Iterate over all the fields and copy -// for(var i = 0; i < data.length; i++) { -// arr[i] = data[i] -// } -// -// // Deserialize the object -// var object = BSONDE.BSON.deserialize(arr); -// // Asserts -// test.equal(motherOfAllDocuments.string, object.string); -// test.deepEqual(motherOfAllDocuments.array, object.array); -// test.deepEqual(motherOfAllDocuments.date, object.date); -// test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); -// // Assert the values of the binary -// for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { -// test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); -// } -// test.deepEqual(motherOfAllDocuments.int, object.int); -// test.deepEqual(motherOfAllDocuments.float, object.float); -// test.deepEqual(motherOfAllDocuments.regexp, object.regexp); -// test.deepEqual(motherOfAllDocuments.boolean, object.boolean); -// test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); -// test.deepEqual(motherOfAllDocuments.where, object.where); -// test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); -// test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); -// test.deepEqual(motherOfAllDocuments.minkey, object.minkey); -// test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); -// test.done(); -// } - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/bson/test/node/bson_parser_comparision_test.js b/frontend/express/node_modules/bson/test/node/bson_parser_comparision_test.js deleted file mode 100644 index 2029022ef30..00000000000 --- a/frontend/express/node_modules/bson/test/node/bson_parser_comparision_test.js +++ /dev/null @@ -1,469 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../../ext/bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple edge value'] = function(test) { - // Simple serialization and deserialization of edge value - var doc = {doc:0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly execute toJSON'] = function(test) { - var a = Long.fromNumber(10); - assert.equal(10, a); - - var a = Long.fromNumber(9223372036854775807); - assert.equal(9223372036854775807, a); - - // Simple serialization and deserialization test for a Single String value - var doc = {doc:'Serialize'}; - var simple_string_serialized = bsonC.serialize(doc, true, false); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize nested document'] = function(test) { - // Nested doc - var doc = {a:{b:{c:1}}}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple integer serialization/deserialization test, including testing boundary conditions'] = function(test) { - var doc = {doc:-1}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization test for a Long value'] = function(test) { - var doc = {doc:Long.fromNumber(9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:Long.fromNumber(-9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Float value'] = function(test) { - var doc = {doc:2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a null value'] = function(test) { - var doc = {doc:null}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:true}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a date value'] = function(test) { - var date = new Date(); - var doc = {doc:date}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:/abcd/mi}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - - var doc = {doc:/abcd/}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a objectId value'] = function(test) { - var doc = {doc:new ObjectID()}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value'] = function(test) { - var binary = new Binary(); - var string = 'binstring' - for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Code value'] = function(test) { - var code = new Code('this.a > i', {'i': 1}); - var simple_string_serialized_2 = bsonJS.serialize({doc:code}, false, true); - var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for an Object'] = function(test) { - var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - - // Simple serialization and deserialization for an Array - var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a DBRef'] = function(test) { - var oid = new ObjectID() - var oid2 = new ObjectID.createFromHexString(oid.toHexString()) - var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - // Ensure we have the same values for the dbref - var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object_c = bsonC.deserialize(simple_string_serialized); - - assert.equal(object_js.doc.namespace, object_c.doc.namespace); - assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); - assert.equal(object_js.doc.db, object_c.doc.db); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize bytes array'] = function(test) { - // Serialized document - var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal('Patty', object.name) - assert.equal(34, object.age) - assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize utf8'] = function(test) { - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.equal(doc.name, object.name) - assert.equal(doc.name1, object.name1) - assert.equal(doc.name2, object.name2) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize object with array'] = function(test) { - var doc = {b:[1, 2, 3]}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc, object) - test.done(); -} - -/** - * @ignore - */ -exports['Test equality of an object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id_2 = new ObjectID(); - assert.ok(object_id.equals(object_id)); - assert.ok(!(object_id.equals(object_id_2))) - test.done(); -} - -/** - * @ignore - */ -exports['Test same serialization for Object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id2 = ObjectID.createFromHexString(object_id.toString()) - var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - - assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object2 = bsonC.deserialize(simple_string_serialized); - assert.equal(object.doc.id, object2.doc.id) - test.done(); -} - -/** - * @ignore - */ -exports['Complex object serialization'] = function(test) { - // JS Object - var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; - var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - - // C++ Object - var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; - var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) - }; - - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - - for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); - } - - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc._id.id, doc1._id.id) - assert.equal(doc._id.id, doc2._id.id) - assert.equal(doc1._id.id, doc2._id.id) - - var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize function'] = function(test) { - var doc = { - _id: 'testid', - key1: function() {} - } - - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Deserialize the string - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize document with special operators'] = function(test) { - var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Should serialize to the same value - assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) - var doc1 = bsonJS.deserialize(simple_string_serialized_2); - var doc2 = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc1, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Create ObjectID from hex string'] = function(test) { - // Hex Id - var hexId = new ObjectID().toString(); - var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docJSBin = bsonJS.serialize(docJS, false, true, true); - var docCBin = bsonC.serialize(docC, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize big complex document'] = function(test) { - // Complex document serialization - var doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} - var docJSBin = bsonJS.serialize(doc, false, true, true); - var docCBin = bsonC.serialize(doc, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/bson/test/node/bson_test.js b/frontend/express/node_modules/bson/test/node/bson_test.js deleted file mode 100644 index a2a723bc39d..00000000000 --- a/frontend/express/node_modules/bson/test/node/bson_test.js +++ /dev/null @@ -1,1671 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - ObjectId = mongoO.ObjectId, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - vm = require('vm'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly create ObjectID and do deep equals'] = function(test) { - var test_string = {hello: new ObjectID()}; - test_string.hello.toHexString(); - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly get BSON types from require'] = function(test) { - var _mongodb = require('../../lib/bson'); - test.ok(_mongodb.ObjectID === ObjectID); - test.ok(_mongodb.Binary === Binary); - test.ok(_mongodb.Long === Long); - test.ok(_mongodb.Timestamp === Timestamp); - test.ok(_mongodb.Code === Code); - test.ok(_mongodb.DBRef === DBRef); - test.ok(_mongodb.Symbol === Symbol); - test.ok(_mongodb.MinKey === MinKey); - test.ok(_mongodb.MaxKey === MaxKey); - test.ok(_mongodb.Double === Double); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary')); - test.equal("a_1", object.name); - test.equal(false, object.unique); - test.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary'));//, false, true); - // Perform tests - test.equal("hello", object.string); - test.deepEqual([1,2,3], object.array); - test.equal(1, object.hash.a); - test.equal(2, object.hash.b); - test.ok(object.date != null); - test.ok(object.oid != null); - test.ok(object.binary != null); - test.equal(42, object.int); - test.equal(33.3333, object.float); - test.ok(object.regexp != null); - test.equal(true, object.boolean); - test.ok(object.where != null); - test.ok(object.dbref != null); - test.ok(object[null] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize Empty String'] = function(test) { - var test_string = {hello: ''}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data2)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_null, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_null)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_null, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(null, object.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -5600}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: 2147483647}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -2147483648}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.age, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.age); - test.deepEqual(doc.doc.name, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.name); - test.deepEqual(doc.doc.shoe_size, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.shoe_size); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - Array.prototype.toXml = function() {}; - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize a nested object'] = function(test) { - var doc = {doc: {doc:1}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date(); - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date from another VM'] = function(test) { - var script = "date1 = new Date();", - ctx = vm.createContext({ - date1 : null - }); - vm.runInContext(script, ctx, 'myfile.vm'); - - var date = ctx.date1; - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize nested doc'] = function(test) { - var doc = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - - subObject: { - moreText: "Bacon ipsum dolor.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string" - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()}; - var doc2 = {doc: ObjectID.createFromHexString(doc.doc.toHexString())}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var decoded_hash = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc; - var keys = []; - - for(var name in decoded_hash) keys.push(name); - test.deepEqual(['b', 'a', 'c', 'd'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - // Serialize the regular expression - var doc = {doc: /foobar/mi}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.toString(), doc2.doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary(); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary(); - bin.write(data); - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports["Should Correctly Serialize and Deserialize DBRef"] = function(test) { - var oid = new ObjectID(); - var doc = {dbref: new DBRef('namespace', oid, null)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal("namespace", doc2.dbref.namespace); - test.deepEqual(doc2.dbref.oid.toHexString(), oid.toHexString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize partial DBRef'] = function(test) { - var id = new ObjectID(); - var doc = {'name':'something', 'user':{'$ref':'username', '$id': id}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal('something', doc2.name); - test.equal('username', doc2.user.namespace); - test.equal(id.toString(), doc2.user.oid.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple Int'] = function(test) { - var doc = {doc:2147483648}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, doc2.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer'] = function(test) { - var doc = {doc: Long.fromNumber(9223372036854775807)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775809)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Deserialize Large Integers as Number not Long'] = function(test) { - function roundTrip(val) { - var doc = {doc: val}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - }; - - roundTrip(Math.pow(2,52)); - roundTrip(Math.pow(2,53) - 1); - roundTrip(Math.pow(2,53)); - roundTrip(-Math.pow(2,52)); - roundTrip(-Math.pow(2,53) + 1); - roundTrip(-Math.pow(2,53)); - roundTrip(Math.pow(2,65)); // Too big for Long. - roundTrip(-Math.pow(2,65)); - roundTrip(9223372036854775807); - roundTrip(1234567890123456800); // Bigger than 2^53, stays a double. - roundTrip(-1234567890123456800); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer and Timestamp as different types'] = function(test) { - var long = Long.fromNumber(9223372036854775807); - var timestamp = Timestamp.fromNumber(9223372036854775807); - test.ok(long instanceof Long); - test.ok(!(long instanceof Timestamp)); - test.ok(timestamp instanceof Timestamp); - test.ok(!(timestamp instanceof Long)); - - var test_int = {doc: long, doc2: timestamp}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(test_int.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Always put the id as the first item in a hash'] = function(test) { - var hash = {doc: {not_id:1, '_id':2}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(hash, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(hash)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(hash, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - var keys = []; - - for(var name in deserialized_data.doc) { - keys.push(name); - } - - test.deepEqual(['not_id', '_id'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a User defined Binary object'] = function(test) { - var bin = new Binary(); - bin.sub_type = BSON.BSON_BINARY_SUBTYPE_USER_DEFINED; - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(deserialized_data.doc.sub_type, BSON.BSON_BINARY_SUBTYPE_USER_DEFINED); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correclty Serialize and Deserialize a Code object'] = function(test) { - var doc = {'doc': {'doc2': new Code('this.a > i', {i:1})}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.doc2.code, deserialized_data.doc.doc2.code); - test.deepEqual(doc.doc.doc2.scope.i, deserialized_data.doc.doc2.scope.i); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly serialize and deserialize and embedded array'] = function(test) { - var doc = {'a':0, - 'b':['tmp1', 'tmp2', 'tmp3', 'tmp4', 'tmp5', 'tmp6', 'tmp7', 'tmp8', 'tmp9', 'tmp10', 'tmp11', 'tmp12', 'tmp13', 'tmp14', 'tmp15', 'tmp16'] - }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.a, deserialized_data.a); - test.deepEqual(doc.b, deserialized_data.b); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize UTF8'] = function(test) { - // Serialize utf8 - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize query object'] = function(test) { - var doc = { count: 'remove_with_no_callback_bug_test', query: {}, fields: null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize empty query object'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize array based doc'] = function(test) { - var doc = { b: [ 1, 2, 3 ], _id: new ObjectID() }; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Symbol'] = function(test) { - if(Symbol != null) { - var doc = { b: [ new Symbol('test') ]}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.ok(deserialized_data.b[0] instanceof Symbol); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should handle Deeply nested document'] = function(test) { - var doc = {a:{b:{c:{d:2}}}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should handle complicated all typed object'] = function(test) { - // First doc - var date = new Date(); - var oid = new ObjectID(); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - // Second doc - var oid = new ObjectID.createFromHexString(oid.toHexString()); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc2 = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize Complex Nested Object'] = function(test) { - var doc = { email: 'email@email.com', - encrypted_password: 'password', - friends: [ '4db96b973d01205364000006', - '4dc77b24c5ba38be14000002' ], - location: [ 72.4930088, 23.0431957 ], - name: 'Amit Kumar', - password_salt: 'salty', - profile_fields: [], - username: 'amit', - _id: new ObjectID() } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = doc; - doc2._id = ObjectID.createFromHexString(doc2._id.toHexString()); - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly massive doc'] = function(test) { - var oid1 = new ObjectID(); - var oid2 = new ObjectID(); - - // JS doc - var doc = { dbref2: new DBRef('namespace', oid1, 'integration_tests_'), - _id: oid2 }; - - var doc2 = { dbref2: new DBRef('namespace', ObjectID.createFromHexString(oid1.toHexString()), 'integration_tests_'), - _id: new ObjectID.createFromHexString(oid2.toHexString()) }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize regexp object'] = function(test) { - var doc = {'b':/foobaré/}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize complicated object'] = function(test) { - var doc = {a:{b:{c:[new ObjectID(), new ObjectID()]}}, d:{f:1332.3323}}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object'] = function(test) { - var doc = { "_id" : { "date" : new Date(), "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object with even more nesting'] = function(test) { - var doc = { "_id" : { "date" : {a:1, b:2, c:new Date()}, "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize empty name object'] = function(test) { - var doc = {'':'test', - 'bbbb':1}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc2[''], 'test'); - test.equal(doc2['bbbb'], 1); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly handle Forced Doubles to ensure we allocate enough space for cap collections'] = function(test) { - if(Double != null) { - var doubleValue = new Double(100); - var doc = {value:doubleValue}; - - // Serialize - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({value:100}, doc2); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should deserialize correctly'] = function(test) { - var doc = { - "_id" : new ObjectID("4e886e687ff7ef5e00000162"), - "str" : "foreign", - "type" : 2, - "timestamp" : ISODate("2011-10-02T14:00:08.383Z"), - "links" : [ - "http://www.reddit.com/r/worldnews/comments/kybm0/uk_home_secretary_calls_for_the_scrapping_of_the/" - ] - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize and deserialize MinKey and MaxKey values'] = function(test) { - var doc = { - _id : new ObjectID("4e886e687ff7ef5e00000162"), - minKey : new MinKey(), - maxKey : new MaxKey() - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.ok(doc2.minKey instanceof MinKey); - test.ok(doc2.maxKey instanceof MaxKey); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize Double value'] = function(test) { - var doc = { - value : new Double(34343.2222) - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.ok(doc.value.valueOf(), doc2.value); - test.ok(doc.value.value, doc2.value); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly create objects'] = function(test) { - try { - var object1 = ObjectID.createFromHexString('000000000000000000000001') - var object2 = ObjectID.createFromHexString('00000000000000000000001') - test.ok(false); - } catch(err) { - test.ok(err != null); - } - - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly retrieve timestamp'] = function(test) { - var testDate = new Date(); - var object1 = new ObjectID(); - test.equal(Math.floor(testDate.getTime()/1000), Math.floor(object1.getTimestamp().getTime()/1000)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly throw error on bsonparser errors'] = function(test) { - var data = new Buffer(3); - var parser = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - - // Catch to small buffer error - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - data = new Buffer(5); - data[0] = 0xff; - data[1] = 0xff; - // Catch illegal size - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - // Finish up - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function BSON.calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the object without serializing the function - var size = BSON.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = BSON.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object using instance method'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the object without serializing the function - var size = bson.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = bson.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function BSON.serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object using a BSON instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function BSON.serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = BSON.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object using a bson instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = bson.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function BSON.deserialize - * @ignore - */ - exports['Should correctly deserialize a buffer using the BSON class level parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = BSON.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = BSON.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function deserialize - * @ignore - */ -exports['Should correctly deserialize a buffer using the BSON instance parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = bson.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = bson.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function BSON.deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should have a correct cached representation of the hexString'] = function (test) { - ObjectID.cacheHexString = true; - var a = new ObjectID; - var __id = a.__id; - test.equal(__id, a.toHexString()); - - // hexString - a = new ObjectID(__id); - test.equal(__id, a.toHexString()); - - // fromHexString - a = ObjectID.createFromHexString(__id); - test.equal(a.__id, a.toHexString()); - test.equal(__id, a.toHexString()); - - // number - var genTime = a.generationTime; - a = new ObjectID(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - - // generationTime - delete a.__id; - a.generationTime = genTime; - test.equal(__id, a.toHexString()); - - // createFromTime - a = ObjectId.createFromTime(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - ObjectId.cacheHexString = false; - - test.done(); -} - -/** - * @ignore - */ -// 'Should Correctly Function' = function(test) { -// var doc = {b:1, func:function() { -// this.b = 2; -// }}; -// -// var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); -// -// debug("----------------------------------------------------------------------") -// debug(inspect(serialized_data)) -// -// // var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); -// // new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); -// // assertBuffersEqual(test, serialized_data, serialized_data2, 0); -// var COUNT = 100000; -// -// // var b = null; -// // eval("b = function(x) { return x+x; }"); -// // var b = new Function("x", "return x+x;"); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// for (i=COUNT; --i>=0; ) { -// var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// } -// -// end = new Date -// console.log("time = ", end - start, "ms -", COUNT * 1000 / (end - start), " ops/sec") -// -// // debug(inspect(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).functionCache)) -// // -// // var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // // test.deepEqual(doc, doc2) -// // // -// // debug(inspect(doc2)) -// // doc2.func() -// // debug(inspect(doc2)) -// // -// // var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); -// // var doc3 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // -// // debug("-----------------------------------------------") -// // debug(inspect(doc3)) -// -// // var key = "0" -// // for(var i = 1; i < 10000; i++) { -// // key = key + " " + i -// // } -// -// test.done(); -// -// -// // var car = { -// // model : "Volvo", -// // country : "Sweden", -// // -// // isSwedish : function() { -// // return this.country == "Sweden"; -// // } -// // } -// -// }, - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/bson/test/node/bson_typed_array_test.js b/frontend/express/node_modules/bson/test/node/bson_typed_array_test.js deleted file mode 100644 index cde83f8fd03..00000000000 --- a/frontend/express/node_modules/bson/test/node/bson_typed_array_test.js +++ /dev/null @@ -1,392 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': '客家è¯', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); - // Build a typed array - var arr = new Uint8Array(new ArrayBuffer(data.length)); - // Iterate over all the fields and copy - for(var i = 0; i < data.length; i++) { - arr[i] = data[i] - } - - // Deserialize the object - var object = BSONDE.BSON.deserialize(arr); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports['exercise all the binary object constructor methods'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(utils.stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - test.done(); -}; - -/** - * @ignore - */ -exports['exercise the put binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(utils.assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(utils.assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the write binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the read binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('world'), data)); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/bson/test/node/data/test_gs_weird_bug.png b/frontend/express/node_modules/bson/test/node/data/test_gs_weird_bug.png deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/frontend/express/node_modules/bson/test/node/data/test_gs_weird_bug.png and /dev/null differ diff --git a/frontend/express/node_modules/bson/test/node/test_full_bson.js b/frontend/express/node_modules/bson/test/node/test_full_bson.js deleted file mode 100644 index 3be19d84a68..00000000000 --- a/frontend/express/node_modules/bson/test/node/test_full_bson.js +++ /dev/null @@ -1,305 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - Buffer = require('buffer').Buffer, - BSON = require('../../ext/bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonC.deserialize(serialized_data); - assert.equal("a_1", object.name); - assert.equal(false, object.unique); - assert.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal("hello", object.string); - assert.deepEqual([1, 2, 3], object.array); - assert.equal(1, object.hash.a); - assert.equal(2, object.hash.b); - assert.ok(object.date != null); - assert.ok(object.oid != null); - assert.ok(object.binary != null); - assert.equal(42, object.int); - assert.equal(33.3333, object.float); - assert.ok(object.regexp != null); - assert.equal(true, object.boolean); - assert.ok(object.where != null); - assert.ok(object.dbref != null); - assert.ok(object['null'] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'} - var serialized_data = bsonC.serialize(test_string) - assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null} - var serialized_data = bsonC.serialize(test_null) - var object = bsonC.deserialize(serialized_data); - assert.deepEqual(test_null, object); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize undefined value'] = function(test) { - var test_undefined = {doc:undefined} - var serialized_data = bsonC.serialize(test_undefined) - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal(null, object.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42} - var serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -5600} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: 2147483647} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -2147483648} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date() - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12) - date.setUTCFullYear(2009) - date.setUTCMonth(11 - 1) - date.setUTCHours(12) - date.setUTCMinutes(0) - date.setUTCSeconds(30) - var doc = {doc: date} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var test_code = {} - var serialized_data = bsonC.serialize(test_code) - assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}} - var serialized_data = bsonC.serialize(doc) - var decoded_hash = bsonC.deserialize(serialized_data).doc - var keys = [] - for(var name in decoded_hash) keys.push(name) - assert.deepEqual(['b', 'a', 'c', 'd'], keys) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - var doc = {doc: /foobar/mi} - var serialized_data = bsonC.serialize(doc) - var doc2 = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.toString(), doc2.doc.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary() - var string = 'binstring' - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary() - bin.write(data) - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/bson/test/node/to_bson_test.js b/frontend/express/node_modules/bson/test/node/to_bson_test.js deleted file mode 100644 index e9282e54908..00000000000 --- a/frontend/express/node_modules/bson/test/node/to_bson_test.js +++ /dev/null @@ -1,109 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser; - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should correctly handle toBson function for an object'] = function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var deserialized_doc = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({b:1}, deserialized_doc); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/bson/test/node/tools/utils.js b/frontend/express/node_modules/bson/test/node/tools/utils.js deleted file mode 100644 index 9d7cbe7c6ea..00000000000 --- a/frontend/express/node_modules/bson/test/node/tools/utils.js +++ /dev/null @@ -1,80 +0,0 @@ -exports.assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -exports.stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -exports.stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -exports.Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/bson/tools/gleak.js b/frontend/express/node_modules/bson/tools/gleak.js deleted file mode 100644 index c707cfcb56c..00000000000 --- a/frontend/express/node_modules/bson/tools/gleak.js +++ /dev/null @@ -1,21 +0,0 @@ - -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE b/frontend/express/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE deleted file mode 100644 index 7c435baaec8..00000000000 --- a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js b/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js deleted file mode 100644 index 73834010f60..00000000000 --- a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js +++ /dev/null @@ -1,190 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.css b/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.css deleted file mode 100644 index 6583fe7c66d..00000000000 --- a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.js b/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.js deleted file mode 100644 index c3d2dc7d2d3..00000000000 --- a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png b/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png deleted file mode 100644 index 218f3b43713..00000000000 Binary files a/frontend/express/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-flash/.travis.yml b/frontend/express/node_modules/connect-flash/.travis.yml deleted file mode 100644 index 79eed115739..00000000000 --- a/frontend/express/node_modules/connect-flash/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: "node_js" -node_js: - - 0.4 - - 0.6 - - 0.8 - \ No newline at end of file diff --git a/frontend/express/node_modules/connect-flash/LICENSE b/frontend/express/node_modules/connect-flash/LICENSE deleted file mode 100644 index d61567a21fc..00000000000 --- a/frontend/express/node_modules/connect-flash/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -(The MIT License) - -Copyright (c) 2012-2013 Jared Hanson - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/connect-flash/README.md b/frontend/express/node_modules/connect-flash/README.md deleted file mode 100644 index b3b58b43ea8..00000000000 --- a/frontend/express/node_modules/connect-flash/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# connect-flash - -The flash is a special area of the session used for storing messages. Messages -are written to the flash and cleared after being displayed to the user. The -flash is typically used in combination with redirects, ensuring that the message -is available to the next page that is to be rendered. - -This middleware was extracted from [Express](http://expressjs.com/) 2.x, after -Express 3.x removed direct support for the flash. connect-flash brings this -functionality back to Express 3.x, as well as any other middleware-compatible -framework or application. +1 for [radical reusability](http://substack.net/posts/b96642/the-node-js-aesthetic). - -## Install - - $ npm install connect-flash - -## Usage - -#### Express 3.x - -Flash messages are stored in the session. First, setup sessions as usual by -enabling `cookieParser` and `session` middleware. Then, use `flash` middleware -provided by connect-flash. - -```javascript -var flash = require('connect-flash'); -var app = express(); - -app.configure(function() { - app.use(express.cookieParser('keyboard cat')); - app.use(express.session({ cookie: { maxAge: 60000 }})); - app.use(flash()); -}); -``` - -With the `flash` middleware in place, all requests will have a `req.flash()` function -that can be used for flash messages. - -```javascript -app.get('/flash', function(req, res){ - // Set a flash message by passing the key, followed by the value, to req.flash(). - req.flash('info', 'Flash is back!') - res.redirect('/'); -}); - -app.get('/', function(req, res){ - // Get an array of flash messages by passing the key to req.flash() - res.render('index', { messages: req.flash('info') }); -}); -``` - -## Examples - -For an example using connect-flash in an Express 3.x app, refer to the [express3](https://github.com/jaredhanson/connect-flash/tree/master/examples/express3) -example. - -## Tests - - $ npm install --dev - $ make test - -[![Build Status](https://secure.travis-ci.org/jaredhanson/connect-flash.png)](http://travis-ci.org/jaredhanson/connect-flash) - -## Credits - - - [Jared Hanson](http://github.com/jaredhanson) - - [TJ Holowaychuk](https://github.com/visionmedia) - -## License - -[The MIT License](http://opensource.org/licenses/MIT) - -Copyright (c) 2012-2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)> diff --git a/frontend/express/node_modules/connect-flash/lib/flash.js b/frontend/express/node_modules/connect-flash/lib/flash.js deleted file mode 100644 index a278bc1d2d0..00000000000 --- a/frontend/express/node_modules/connect-flash/lib/flash.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Module dependencies. - */ -var format = require('util').format; -var isArray = require('util').isArray; - - -/** - * Expose `flash()` function on requests. - * - * @return {Function} - * @api public - */ -module.exports = function flash(options) { - options = options || {}; - var safe = (options.unsafe === undefined) ? true : !options.unsafe; - - return function(req, res, next) { - if (req.flash && safe) { return next(); } - req.flash = _flash; - next(); - } -} - -/** - * Queue flash `msg` of the given `type`. - * - * Examples: - * - * req.flash('info', 'email sent'); - * req.flash('error', 'email delivery failed'); - * req.flash('info', 'email re-sent'); - * // => 2 - * - * req.flash('info'); - * // => ['email sent', 'email re-sent'] - * - * req.flash('info'); - * // => [] - * - * req.flash(); - * // => { error: ['email delivery failed'], info: [] } - * - * Formatting: - * - * Flash notifications also support arbitrary formatting support. - * For example you may pass variable arguments to `req.flash()` - * and use the %s specifier to be replaced by the associated argument: - * - * req.flash('info', 'email has been sent to %s.', userName); - * - * Formatting uses `util.format()`, which is available on Node 0.6+. - * - * @param {String} type - * @param {String} msg - * @return {Array|Object|Number} - * @api public - */ -function _flash(type, msg) { - if (this.session === undefined) throw Error('req.flash() requires sessions'); - var msgs = this.session.flash = this.session.flash || {}; - if (type && msg) { - // util.format is available in Node.js 0.6+ - if (arguments.length > 2 && format) { - var args = Array.prototype.slice.call(arguments, 1); - msg = format.apply(undefined, args); - } else if (isArray(msg)) { - msg.forEach(function(val){ - (msgs[type] = msgs[type] || []).push(val); - }); - return msgs[type].length; - } - return (msgs[type] = msgs[type] || []).push(msg); - } else if (type) { - var arr = msgs[type]; - delete msgs[type]; - return arr || []; - } else { - this.session.flash = {}; - return msgs; - } -} diff --git a/frontend/express/node_modules/connect-flash/lib/index.js b/frontend/express/node_modules/connect-flash/lib/index.js deleted file mode 100644 index b4d59611d85..00000000000 --- a/frontend/express/node_modules/connect-flash/lib/index.js +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Expose middleware. - */ -exports = module.exports = require('./flash'); diff --git a/frontend/express/node_modules/connect-flash/package.json b/frontend/express/node_modules/connect-flash/package.json deleted file mode 100644 index 98aeed410b9..00000000000 --- a/frontend/express/node_modules/connect-flash/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "connect-flash", - "version": "0.1.1", - "description": "Flash message middleware for Connect.", - "keywords": [ - "connect", - "express", - "flash", - "messages" - ], - "repository": { - "type": "git", - "url": "git://github.com/jaredhanson/connect-flash.git" - }, - "bugs": { - "url": "http://github.com/jaredhanson/connect-flash/issues" - }, - "author": { - "name": "Jared Hanson", - "email": "jaredhanson@gmail.com", - "url": "http://www.jaredhanson.net/" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" - } - ], - "main": "./lib", - "dependencies": {}, - "devDependencies": { - "vows": "0.6.x" - }, - "scripts": { - "test": "NODE_PATH=lib node_modules/.bin/vows test/*-test.js" - }, - "engines": { - "node": ">= 0.4.0" - }, - "readme": "# connect-flash\n\nThe flash is a special area of the session used for storing messages. Messages\nare written to the flash and cleared after being displayed to the user. The\nflash is typically used in combination with redirects, ensuring that the message\nis available to the next page that is to be rendered.\n\nThis middleware was extracted from [Express](http://expressjs.com/) 2.x, after\nExpress 3.x removed direct support for the flash. connect-flash brings this\nfunctionality back to Express 3.x, as well as any other middleware-compatible\nframework or application. +1 for [radical reusability](http://substack.net/posts/b96642/the-node-js-aesthetic).\n\n## Install\n\n $ npm install connect-flash\n\n## Usage\n\n#### Express 3.x\n\nFlash messages are stored in the session. First, setup sessions as usual by\nenabling `cookieParser` and `session` middleware. Then, use `flash` middleware\nprovided by connect-flash.\n\n```javascript\nvar flash = require('connect-flash');\nvar app = express();\n\napp.configure(function() {\n app.use(express.cookieParser('keyboard cat'));\n app.use(express.session({ cookie: { maxAge: 60000 }}));\n app.use(flash());\n});\n```\n\nWith the `flash` middleware in place, all requests will have a `req.flash()` function\nthat can be used for flash messages.\n\n```javascript\napp.get('/flash', function(req, res){\n // Set a flash message by passing the key, followed by the value, to req.flash().\n req.flash('info', 'Flash is back!')\n res.redirect('/');\n});\n\napp.get('/', function(req, res){\n // Get an array of flash messages by passing the key to req.flash()\n res.render('index', { messages: req.flash('info') });\n});\n```\n\n## Examples\n\nFor an example using connect-flash in an Express 3.x app, refer to the [express3](https://github.com/jaredhanson/connect-flash/tree/master/examples/express3)\nexample.\n\n## Tests\n\n $ npm install --dev\n $ make test\n\n[![Build Status](https://secure.travis-ci.org/jaredhanson/connect-flash.png)](http://travis-ci.org/jaredhanson/connect-flash)\n\n## Credits\n\n - [Jared Hanson](http://github.com/jaredhanson)\n - [TJ Holowaychuk](https://github.com/visionmedia)\n\n## License\n\n[The MIT License](http://opensource.org/licenses/MIT)\n\nCopyright (c) 2012-2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>\n", - "readmeFilename": "README.md", - "_id": "connect-flash@0.1.1", - "dist": { - "shasum": "6e6f199fb1e5789683a6333d8638c7c43bfe9ba6" - }, - "_from": "connect-flash@0.1.1", - "_resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/.npmignore b/frontend/express/node_modules/connect-mongoskin/.npmignore deleted file mode 100644 index 7dccd970766..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/.npmignore +++ /dev/null @@ -1,15 +0,0 @@ -lib-cov -*.seed -*.log -*.csv -*.dat -*.out -*.pid -*.gz - -pids -logs -results - -node_modules -npm-debug.log \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/README.md b/frontend/express/node_modules/connect-mongoskin/README.md deleted file mode 100644 index 75060d25b4d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# MongoSkin Session Store - -Simple Session Store for [Connect() Framework][1] session Middleware that leverages an existing connection from [MongoSkin][3] - -### Motivation - -We were using a `connect-mongodb` which was working great, however we want to keep our connection pool centralized, -have the benefits that an abstraction layer like [mongoskin][3] provides and avoid going twice through the pain -of getting our ReplSetCluster configuration in place. - -## Installation - -Use `git clone` to download the source and make it available in your project wirh `npm link`. - -or - -```bash -npm install connect-mongoskin -``` - -## Usage - -This session store is build to work with [Connect() Framework][1] / [ExpressJS() Framework][2] / [RailwayJS() Framework][3] -Use it like any other middleware. - -### Abstract example - -The lib reuses an existing client, so pass in the SkinDb and options if needed. - - var SkinStore = new SkinStore(`db`, `options`[, callback]); - -### Connect() / ExpressJS() Example - - var express = require('express'), - db = require('mongoskin').db(`your_connection_here`), - SkinStore = require('connect-mongoskin'); - - var app = express.createServer(); - app.use(express.cookieParser()); - app.use(express.session({cookie: { secure: false, maxAge:86400000 }, store: new SkinStore(`db`)})); - -[1]: https://github.com/senchalabs/connect -[2]: https://github.com/visionmedia/express -[3]: https://github.com/kissjs/node-mongoskin - - -### Meta - -Originally written by [@johnnyhalife](http://twitter.com/johnnyhalife) (johnny at mural.ly) \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/index.js b/frontend/express/node_modules/connect-mongoskin/index.js deleted file mode 100644 index 04fb90bd6c7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/index.js +++ /dev/null @@ -1,91 +0,0 @@ -/*! - * connect-mongoskin - * Copyright(c) 2012 Johnny Halife - * Mantained by Mural.ly Team - */ -var Store = require('connect').session.Store, - util = require('util'); - -/** - * Connect Framework Middleware abstraction for - * using it with MongoSkin (https://github.com/kissjs/node-mongoskin) - * - * @param {SkingDb} skinDb - * @param {*=} options - * @param {Function} callback - */ -module.exports = SkinStore = function (skinDb, options, callback) { - if(!skinDb) throw(new Error('You must provide a `db` (SkinDb object)')); - - this.db = skinDb; - this.sessions = this.db.collection('sessions_'); - this.sessions.ensureIndex({expires: 1}, {expireAfterSeconds: 0}, function() {}); - - Store.call(this, options); -}; - -/** SkinStore extendes Store from Connect */ -util.inherits(SkinStore, Store); - -/** - * Gets a session row from the persistance store - * - * @param {string} sid - * @param {Function} callback - */ -SkinStore.prototype.get = function (sid, callback) { - this.sessions.findOne({_id: sid }, function (err, row) { - if(err || !row) return callback(err, row); - - var session = typeof row.session === 'string' ? JSON.parse(row.session) : row.session; - callback(null, session); - }); -}; - -/** - * Stores a session row on the persistance store. - * - * @param {string} sid - * @param {*} session - * @param {Function} callback - */ -SkinStore.prototype.set = function (sid, session, callback) { - var values = {_id: sid, session: JSON.stringify(session) }; - - if(session && session.cookie && session.cookie.expires) { - values.expires = new Date(session.cookie.expires); - } - - this.sessions.update({_id: sid}, values, {upsert: true}, function () { - callback.apply(this, arguments); - }); -}; - -/** - * Destroys a session from the persistance store. - * - * @param {string} sid - * @param {Function} callback - */ -SkinStore.prototype.destroy = function (sid, callback) { - this.sessions.remove({_id: sid}, {safe: false}, callback); -}; - -/** - * Wipes out the persitance store. - * - * @param {Function} callback - */ -SkinStore.prototype.clear = function (callback) { - this.sessions.drop(callback); -}; - -/** - * Returns the number of sessions currently available - * on the persitance store. - * - * @param {Function} callback - */ -SkinStore.prototype.count = function (callback) { - this.sessions.count(callback); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/.npmignore deleted file mode 100644 index 9046dde51c6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -*.markdown -*.md -.git* -Makefile -benchmarks/ -docs/ -examples/ -install.sh -support/ -test/ -.DS_Store -coverage.html diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/LICENSE b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/LICENSE deleted file mode 100644 index 0c5d22d96df..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -(The MIT License) - -Copyright (c) 2010 Sencha Inc. -Copyright (c) 2011 LearnBoost -Copyright (c) 2011 TJ Holowaychuk - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/index.js deleted file mode 100644 index 23240eedaa5..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = process.env.CONNECT_COV - ? require('./lib-cov/connect') - : require('./lib/connect'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/cache.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/cache.js deleted file mode 100644 index 052fcdb3d5c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/cache.js +++ /dev/null @@ -1,81 +0,0 @@ - -/*! - * Connect - Cache - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Expose `Cache`. - */ - -module.exports = Cache; - -/** - * LRU cache store. - * - * @param {Number} limit - * @api private - */ - -function Cache(limit) { - this.store = {}; - this.keys = []; - this.limit = limit; -} - -/** - * Touch `key`, promoting the object. - * - * @param {String} key - * @param {Number} i - * @api private - */ - -Cache.prototype.touch = function(key, i){ - this.keys.splice(i,1); - this.keys.push(key); -}; - -/** - * Remove `key`. - * - * @param {String} key - * @api private - */ - -Cache.prototype.remove = function(key){ - delete this.store[key]; -}; - -/** - * Get the object stored for `key`. - * - * @param {String} key - * @return {Array} - * @api private - */ - -Cache.prototype.get = function(key){ - return this.store[key]; -}; - -/** - * Add a cache `key`. - * - * @param {String} key - * @return {Array} - * @api private - */ - -Cache.prototype.add = function(key){ - // initialize store - var len = this.keys.push(key); - - // limit reached, invalidate LRU - if (len > this.limit) this.remove(this.keys.shift()); - - var arr = this.store[key] = []; - arr.createdAt = new Date; - return arr; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/connect.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/connect.js deleted file mode 100644 index 184262f9790..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/connect.js +++ /dev/null @@ -1,93 +0,0 @@ - -/*! - * Connect - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter - , proto = require('./proto') - , utils = require('./utils') - , path = require('path') - , basename = path.basename - , fs = require('fs'); - -// node patches - -require('./patch'); - -// expose createServer() as the module - -exports = module.exports = createServer; - -/** - * Framework version. - */ - -exports.version = '2.3.9'; - -/** - * Expose mime module. - */ - -exports.mime = require('./middleware/static').mime; - -/** - * Expose the prototype. - */ - -exports.proto = proto; - -/** - * Auto-load middleware getters. - */ - -exports.middleware = {}; - -/** - * Expose utilities. - */ - -exports.utils = utils; - -/** - * Create a new connect server. - * - * @return {Function} - * @api public - */ - -function createServer() { - function app(req, res){ app.handle(req, res); } - utils.merge(app, proto); - utils.merge(app, EventEmitter.prototype); - app.route = '/'; - app.stack = []; - for (var i = 0; i < arguments.length; ++i) { - app.use(arguments[i]); - } - return app; -}; - -/** - * Support old `.createServer()` method. - */ - -createServer.createServer = createServer; - -/** - * Auto-load bundled middleware with getters. - */ - -fs.readdirSync(__dirname + '/middleware').forEach(function(filename){ - if (!/\.js$/.test(filename)) return; - var name = basename(filename, '.js'); - function load(){ return require('./middleware/' + name); } - exports.middleware.__defineGetter__(name, load); - exports.__defineGetter__(name, load); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/index.js deleted file mode 100644 index 76ed8a119ae..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/index.js +++ /dev/null @@ -1,55 +0,0 @@ - -/** - * Connect is a middleware framework for node, - * shipping with over 18 bundled middleware and a rich selection of - * 3rd-party middleware. - * - * var app = connect() - * .use(connect.logger('dev')) - * .use(connect.static('public')) - * .use(function(req, res){ - * res.end('hello world\n'); - * }) - * .listen(3000); - * - * Installation: - * - * $ npm install connect - * - * Middleware: - * - * - [logger](logger.html) request logger with custom format support - * - [csrf](csrf.html) Cross-site request forgery protection - * - [compress](compress.html) Gzip compression middleware - * - [basicAuth](basicAuth.html) basic http authentication - * - [bodyParser](bodyParser.html) extensible request body parser - * - [json](json.html) application/json parser - * - [urlencoded](urlencoded.html) application/x-www-form-urlencoded parser - * - [multipart](multipart.html) multipart/form-data parser - * - [cookieParser](cookieParser.html) cookie parser - * - [session](session.html) session management support with bundled MemoryStore - * - [cookieSession](cookieSession.html) cookie-based session support - * - [methodOverride](methodOverride.html) faux HTTP method support - * - [responseTime](responseTime.html) calculates response-time and exposes via X-Response-Time - * - [staticCache](staticCache.html) memory cache layer for the static() middleware - * - [static](static.html) streaming static file server supporting `Range` and more - * - [directory](directory.html) directory listing middleware - * - [vhost](vhost.html) virtual host sub-domain mapping middleware - * - [favicon](favicon.html) efficient favicon server (with default icon) - * - [limit](limit.html) limit the bytesize of request bodies - * - [query](query.html) automatic querystring parser, populating `req.query` - * - [errorHandler](errorHandler.html) flexible error handler - * - * Internals: - * - * - server [prototype](proto.html) - * - connect [utilities](utils.html) - * - node monkey [patches](patch.html) - * - * Links: - * - * - list of [3rd-party](https://github.com/senchalabs/connect/wiki) middleware - * - GitHub [repository](http://github.com/senchalabs/connect) - * - [test documentation](https://github.com/senchalabs/connect/blob/gh-pages/tests.md) - * - */ \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/basicAuth.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/basicAuth.js deleted file mode 100644 index 5565744b206..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/basicAuth.js +++ /dev/null @@ -1,98 +0,0 @@ - -/*! - * Connect - basicAuth - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , unauthorized = utils.unauthorized; - -/** - * Basic Auth: - * - * Enfore basic authentication by providing a `callback(user, pass)`, - * which must return `true` in order to gain access. Alternatively an async - * method is provided as well, invoking `callback(user, pass, callback)`. Populates - * `req.user`. The final alternative is simply passing username / password - * strings. - * - * Simple username and password - * - * connect(connect.basicAuth('username', 'password')); - * - * Callback verification - * - * connect() - * .use(connect.basicAuth(function(user, pass){ - * return 'tj' == user & 'wahoo' == pass; - * })) - * - * Async callback verification, accepting `fn(err, user)`. - * - * connect() - * .use(connect.basicAuth(function(user, pass, fn){ - * User.authenticate({ user: user, pass: pass }, fn); - * })) - * - * @param {Function|String} callback or username - * @param {String} realm - * @api public - */ - -module.exports = function basicAuth(callback, realm) { - var username, password; - - // user / pass strings - if ('string' == typeof callback) { - username = callback; - password = realm; - if ('string' != typeof password) throw new Error('password argument required'); - realm = arguments[2]; - callback = function(user, pass){ - return user == username && pass == password; - } - } - - realm = realm || 'Authorization Required'; - - return function(req, res, next) { - var authorization = req.headers.authorization; - - if (req.user) return next(); - if (!authorization) return unauthorized(res, realm); - - var parts = authorization.split(' ') - , scheme = parts[0] - , credentials = new Buffer(parts[1], 'base64').toString().split(':') - , user = credentials[0] - , pass = credentials[1]; - - if ('Basic' != scheme) return next(utils.error(400)); - - // async - if (callback.length >= 3) { - var pause = utils.pause(req); - callback(user, pass, function(err, user){ - if (err || !user) return unauthorized(res, realm); - req.user = req.remoteUser = user; - next(); - pause.resume(); - }); - // sync - } else { - if (callback(user, pass)) { - req.user = req.remoteUser = user; - next(); - } else { - unauthorized(res, realm); - } - } - } -}; - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/bodyParser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/bodyParser.js deleted file mode 100644 index 9f692cdcaac..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/bodyParser.js +++ /dev/null @@ -1,61 +0,0 @@ - -/*! - * Connect - bodyParser - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var multipart = require('./multipart') - , urlencoded = require('./urlencoded') - , json = require('./json'); - -/** - * Body parser: - * - * Parse request bodies, supports _application/json_, - * _application/x-www-form-urlencoded_, and _multipart/form-data_. - * - * This is equivalent to: - * - * app.use(connect.json()); - * app.use(connect.urlencoded()); - * app.use(connect.multipart()); - * - * Examples: - * - * connect() - * .use(connect.bodyParser()) - * .use(function(req, res) { - * res.end('viewing user ' + req.body.user.name); - * }); - * - * $ curl -d 'user[name]=tj' http://local/ - * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/ - * - * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function bodyParser(options){ - var _urlencoded = urlencoded(options) - , _multipart = multipart(options) - , _json = json(options); - - return function bodyParser(req, res, next) { - _json(req, res, function(err){ - if (err) return next(err); - _urlencoded(req, res, function(err){ - if (err) return next(err); - _multipart(req, res, next); - }); - }); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/compress.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/compress.js deleted file mode 100644 index 69ab1e35299..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/compress.js +++ /dev/null @@ -1,143 +0,0 @@ - -/*! - * Connect - compress - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var zlib = require('zlib'); - -/** - * Supported content-encoding methods. - */ - -exports.methods = { - gzip: zlib.createGzip - , deflate: zlib.createDeflate -}; - -/** - * Default filter function. - */ - -exports.filter = function(req, res){ - return /json|text|javascript/.test(res.getHeader('Content-Type')); -}; - -/** - * Compress: - * - * Compress response data with gzip/deflate. - * - * Filter: - * - * A `filter` callback function may be passed to - * replace the default logic of: - * - * exports.filter = function(req, res){ - * return /json|text|javascript/.test(res.getHeader('Content-Type')); - * }; - * - * Options: - * - * All remaining options are passed to the gzip/deflate - * creation functions. Consult node's docs for additional details. - * - * - `chunkSize` (default: 16*1024) - * - `windowBits` - * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression - * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more - * - `strategy`: compression strategy - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function compress(options) { - var options = options || {} - , names = Object.keys(exports.methods) - , filter = options.filter || exports.filter; - - return function(req, res, next){ - var accept = req.headers['accept-encoding'] - , write = res.write - , end = res.end - , stream - , method; - - // vary - res.setHeader('Vary', 'Accept-Encoding'); - - // proxy - - res.write = function(chunk, encoding){ - if (!this.headerSent) this._implicitHeader(); - return stream - ? stream.write(chunk, encoding) - : write.call(res, chunk, encoding); - }; - - res.end = function(chunk, encoding){ - if (chunk) this.write(chunk, encoding); - return stream - ? stream.end() - : end.call(res); - }; - - res.on('header', function(){ - // default request filter - if (!filter(req, res)) return; - - // SHOULD use identity - if (!accept) return; - - // head - if ('HEAD' == req.method) return; - - // default to gzip - if ('*' == accept.trim()) method = 'gzip'; - - // compression method - if (!method) { - for (var i = 0, len = names.length; i < len; ++i) { - if (~accept.indexOf(names[i])) { - method = names[i]; - break; - } - } - } - - // compression method - if (!method) return; - - // compression stream - stream = exports.methods[method](options); - - // header fields - res.setHeader('Content-Encoding', method); - res.removeHeader('Content-Length'); - - // compression - - stream.on('data', function(chunk){ - write.call(res, chunk); - }); - - stream.on('end', function(){ - end.call(res); - }); - - stream.on('drain', function() { - res.emit('drain'); - }); - }); - - next(); - }; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieParser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieParser.js deleted file mode 100644 index 876b5d2739b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieParser.js +++ /dev/null @@ -1,62 +0,0 @@ - -/*! - * Connect - cookieParser - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./../utils') - , cookie = require('cookie'); - -/** - * Cookie parser: - * - * Parse _Cookie_ header and populate `req.cookies` - * with an object keyed by the cookie names. Optionally - * you may enabled signed cookie support by passing - * a `secret` string, which assigns `req.secret` so - * it may be used by other middleware. - * - * Examples: - * - * connect() - * .use(connect.cookieParser('optional secret string')) - * .use(function(req, res, next){ - * res.end(JSON.stringify(req.cookies)); - * }) - * - * @param {String} secret - * @return {Function} - * @api public - */ - -module.exports = function cookieParser(secret){ - return function cookieParser(req, res, next) { - if (req.cookies) return next(); - var cookies = req.headers.cookie; - - req.secret = secret; - req.cookies = {}; - req.signedCookies = {}; - - if (cookies) { - try { - req.cookies = cookie.parse(cookies); - if (secret) { - req.signedCookies = utils.parseSignedCookies(req.cookies, secret); - var obj = utils.parseJSONCookies(req.signedCookies); - req.signedCookies = obj; - } - req.cookies = utils.parseJSONCookies(req.cookies); - } catch (err) { - return next(err); - } - } - next(); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieSession.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieSession.js deleted file mode 100644 index 6d64813f753..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/cookieSession.js +++ /dev/null @@ -1,117 +0,0 @@ - -/*! - * Connect - cookieSession - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./../utils') - , Cookie = require('./session/cookie') - , debug = require('debug')('connect:cookieSession') - , crc16 = require('crc').crc16; - -// environment - -var env = process.env.NODE_ENV; - -/** - * Cookie Session: - * - * Cookie session middleware. - * - * var app = connect(); - * app.use(connect.cookieParser()); - * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }})); - * - * Options: - * - * - `key` cookie name defaulting to `connect.sess` - * - `secret` prevents cookie tampering - * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") - * - * Clearing sessions: - * - * To clear the session simply set its value to `null`, - * `cookieSession()` will then respond with a 1970 Set-Cookie. - * - * req.session = null; - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function cookieSession(options){ - // TODO: utilize Session/Cookie to unify API - var options = options || {} - , key = options.key || 'connect.sess' - , trustProxy = options.proxy; - - return function cookieSession(req, res, next) { - - // req.secret is for backwards compatibility - var secret = options.secret || req.secret; - if (!secret) throw new Error('`secret` option required for cookie sessions'); - - // default session - req.session = {}; - var cookie = req.session.cookie = new Cookie(options.cookie); - - // pathname mismatch - if (0 != req.originalUrl.indexOf(cookie.path)) return next(); - - // cookieParser secret - if (!options.secret && req.secret) { - req.session = req.signedCookies[key] || {}; - } else { - // TODO: refactor - var rawCookie = req.cookies[key]; - if (rawCookie) { - var unsigned = utils.parseSignedCookie(rawCookie, secret); - if (unsigned) { - var originalHash = crc16(unsigned); - req.session = utils.parseJSONCookie(unsigned) || {}; - } - } - } - - res.on('header', function(){ - // removed - if (!req.session) { - debug('clear session'); - res.setHeader('Set-Cookie', key + '=; expires=' + new Date(0).toUTCString()); - return; - } - - delete req.session.cookie; - - // check security - var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase() - , tls = req.connection.encrypted || (trustProxy && 'https' == proto) - , secured = cookie.secure && tls; - - // only send secure cookies via https - if (cookie.secure && !secured) return debug('not secured'); - - // serialize - debug('serializing %j', req.session); - var val = 'j:' + JSON.stringify(req.session); - - // compare hashes, no need to set-cookie if unchanged - if (originalHash == crc16(val)) return debug('unmodified session'); - - // set-cookie - val = 's:' + utils.sign(val, secret); - val = cookie.serialize(key, val); - debug('set-cookie %j', cookie); - res.setHeader('Set-Cookie', val); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/csrf.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/csrf.js deleted file mode 100644 index d7a5e05994d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/csrf.js +++ /dev/null @@ -1,73 +0,0 @@ -/*! - * Connect - csrf - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils'); - -/** - * Anti CSRF: - * - * CRSF protection middleware. - * - * By default this middleware generates a token named "_csrf" - * which should be added to requests which mutate - * state, within a hidden form field, query-string etc. This - * token is validated against the visitor's `req.session._csrf` - * property. - * - * The default `value` function checks `req.body` generated - * by the `bodyParser()` middleware, `req.query` generated - * by `query()`, and the "X-CSRF-Token" header field. - * - * This middleware requires session support, thus should be added - * somewhere _below_ `session()` and `cookieParser()`. - * - * Options: - * - * - `value` a function accepting the request, returning the token - * - * @param {Object} options - * @api public - */ - -module.exports = function csrf(options) { - var options = options || {} - , value = options.value || defaultValue; - - return function(req, res, next){ - // generate CSRF token - var token = req.session._csrf || (req.session._csrf = utils.uid(24)); - - // ignore these methods - if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next(); - - // determine value - var val = value(req); - - // check - if (val != token) return next(utils.error(403)); - - next(); - } -}; - -/** - * Default value function, checking the `req.body` - * and `req.query` for the CSRF token. - * - * @param {IncomingMessage} req - * @return {String} - * @api private - */ - -function defaultValue(req) { - return (req.body && req.body._csrf) - || (req.query && req.query._csrf) - || (req.headers['x-csrf-token']); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/directory.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/directory.js deleted file mode 100644 index 7dcfb3cfbc3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/directory.js +++ /dev/null @@ -1,227 +0,0 @@ - -/*! - * Connect - directory - * Copyright(c) 2011 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -// TODO: icon / style for directories -// TODO: arrow key navigation -// TODO: make icons extensible - -/** - * Module dependencies. - */ - -var fs = require('fs') - , parse = require('url').parse - , utils = require('../utils') - , path = require('path') - , normalize = path.normalize - , extname = path.extname - , join = path.join; - -/*! - * Icon cache. - */ - -var cache = {}; - -/** - * Directory: - * - * Serve directory listings with the given `root` path. - * - * Options: - * - * - `hidden` display hidden (dot) files. Defaults to false. - * - `icons` display icons. Defaults to false. - * - `filter` Apply this filter function to files. Defaults to false. - * - * @param {String} root - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function directory(root, options){ - options = options || {}; - - // root required - if (!root) throw new Error('directory() root path required'); - var hidden = options.hidden - , icons = options.icons - , filter = options.filter - , root = normalize(root); - - return function directory(req, res, next) { - var accept = req.headers.accept || 'text/plain' - , url = parse(req.url) - , dir = decodeURIComponent(url.pathname) - , path = normalize(join(root, dir)) - , originalUrl = parse(req.originalUrl) - , originalDir = decodeURIComponent(originalUrl.pathname) - , showUp = path != root && path != root + '/'; - - // null byte(s), bad request - if (~path.indexOf('\0')) return next(utils.error(400)); - - // malicious path, forbidden - if (0 != path.indexOf(root)) return next(utils.error(403)); - - // check if we have a directory - fs.stat(path, function(err, stat){ - if (err) return 'ENOENT' == err.code - ? next() - : next(err); - - if (!stat.isDirectory()) return next(); - - // fetch files - fs.readdir(path, function(err, files){ - if (err) return next(err); - if (!hidden) files = removeHidden(files); - if (filter) files = files.filter(filter); - files.sort(); - - // content-negotiation - for (var key in exports) { - if (~accept.indexOf(key) || ~accept.indexOf('*/*')) { - exports[key](req, res, files, next, originalDir, showUp, icons); - return; - } - } - - // not acceptable - next(utils.error(406)); - }); - }); - }; -}; - -/** - * Respond with text/html. - */ - -exports.html = function(req, res, files, next, dir, showUp, icons){ - fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){ - if (err) return next(err); - fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){ - if (err) return next(err); - if (showUp) files.unshift('..'); - str = str - .replace('{style}', style) - .replace('{files}', html(files, dir, icons)) - .replace('{directory}', dir) - .replace('{linked-path}', htmlPath(dir)); - res.setHeader('Content-Type', 'text/html'); - res.setHeader('Content-Length', str.length); - res.end(str); - }); - }); -}; - -/** - * Respond with application/json. - */ - -exports.json = function(req, res, files){ - files = JSON.stringify(files); - res.setHeader('Content-Type', 'application/json'); - res.setHeader('Content-Length', files.length); - res.end(files); -}; - -/** - * Respond with text/plain. - */ - -exports.plain = function(req, res, files){ - files = files.join('\n') + '\n'; - res.setHeader('Content-Type', 'text/plain'); - res.setHeader('Content-Length', files.length); - res.end(files); -}; - -/** - * Map html `dir`, returning a linked path. - */ - -function htmlPath(dir) { - var curr = []; - return dir.split('/').map(function(part){ - curr.push(part); - return '' + part + ''; - }).join(' / '); -} - -/** - * Map html `files`, returning an html unordered list. - */ - -function html(files, dir, useIcons) { - return '
    ' + files.map(function(file){ - var icon = '' - , classes = []; - - if (useIcons && '..' != file) { - icon = icons[extname(file)] || icons.default; - icon = ''; - classes.push('icon'); - } - - return '
  • ' - + icon + file + '
  • '; - - }).join('\n') + '
'; -} - -/** - * Load and cache the given `icon`. - * - * @param {String} icon - * @return {String} - * @api private - */ - -function load(icon) { - if (cache[icon]) return cache[icon]; - return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64'); -} - -/** - * Filter "hidden" `files`, aka files - * beginning with a `.`. - * - * @param {Array} files - * @return {Array} - * @api private - */ - -function removeHidden(files) { - return files.filter(function(file){ - return '.' != file[0]; - }); -} - -/** - * Icon map. - */ - -var icons = { - '.js': 'page_white_code_red.png' - , '.c': 'page_white_c.png' - , '.h': 'page_white_h.png' - , '.cc': 'page_white_cplusplus.png' - , '.php': 'page_white_php.png' - , '.rb': 'page_white_ruby.png' - , '.cpp': 'page_white_cplusplus.png' - , '.swf': 'page_white_flash.png' - , '.pdf': 'page_white_acrobat.png' - , 'default': 'page_white.png' -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/errorHandler.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/errorHandler.js deleted file mode 100644 index b62aab7117b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/errorHandler.js +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * Connect - errorHandler - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , url = require('url') - , fs = require('fs'); - -// environment - -var env = process.env.NODE_ENV || 'development'; - -/** - * Error handler: - * - * Development error handler, providing stack traces - * and error message responses for requests accepting text, html, - * or json. - * - * Text: - * - * By default, and when _text/plain_ is accepted a simple stack trace - * or error message will be returned. - * - * JSON: - * - * When _application/json_ is accepted, connect will respond with - * an object in the form of `{ "error": error }`. - * - * HTML: - * - * When accepted connect will output a nice html stack trace. - * - * @return {Function} - * @api public - */ - -exports = module.exports = function errorHandler(){ - return function errorHandler(err, req, res, next){ - if (err.status) res.statusCode = err.status; - if (res.statusCode < 400) res.statusCode = 500; - if ('test' != env) console.error(err.stack); - var accept = req.headers.accept || ''; - // html - if (~accept.indexOf('html')) { - fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){ - fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){ - var stack = (err.stack || '') - .split('\n').slice(1) - .map(function(v){ return '
  • ' + v + '
  • '; }).join(''); - html = html - .replace('{style}', style) - .replace('{stack}', stack) - .replace('{title}', exports.title) - .replace('{statusCode}', res.statusCode) - .replace(/\{error\}/g, utils.escape(err.toString())); - res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.end(html); - }); - }); - // json - } else if (~accept.indexOf('json')) { - var error = { message: err.message, stack: err.stack }; - for (var prop in err) error[prop] = err[prop]; - var json = JSON.stringify({ error: error }); - res.setHeader('Content-Type', 'application/json'); - res.end(json); - // plain text - } else { - res.writeHead(res.statusCode, { 'Content-Type': 'text/plain' }); - res.end(err.stack); - } - }; -}; - -/** - * Template title, framework authors may override this value. - */ - -exports.title = 'Connect'; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/favicon.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/favicon.js deleted file mode 100644 index c57bf348ef0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/favicon.js +++ /dev/null @@ -1,81 +0,0 @@ - -/*! - * Connect - favicon - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var fs = require('fs') - , utils = require('../utils'); - -/** - * Favicon: - * - * By default serves the connect favicon, or the favicon - * located by the given `path`. - * - * Options: - * - * - `maxAge` cache-control max-age directive, defaulting to 1 day - * - * Examples: - * - * Serve default favicon: - * - * connect() - * .use(connect.favicon()) - * - * Serve favicon before logging for brevity: - * - * connect() - * .use(connect.favicon()) - * .use(connect.logger('dev')) - * - * Serve custom favicon: - * - * connect() - * .use(connect.favicon('public/favicon.ico)) - * - * @param {String} path - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function favicon(path, options){ - var options = options || {} - , path = path || __dirname + '/../public/favicon.ico' - , maxAge = options.maxAge || 86400000 - , icon; // favicon cache - - return function favicon(req, res, next){ - if ('/favicon.ico' == req.url) { - if (icon) { - res.writeHead(200, icon.headers); - res.end(icon.body); - } else { - fs.readFile(path, function(err, buf){ - if (err) return next(err); - icon = { - headers: { - 'Content-Type': 'image/x-icon' - , 'Content-Length': buf.length - , 'ETag': '"' + utils.md5(buf) + '"' - , 'Cache-Control': 'public, max-age=' + (maxAge / 1000) - }, - body: buf - }; - res.writeHead(200, icon.headers); - res.end(icon.body); - }); - } - } else { - next(); - } - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/json.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/json.js deleted file mode 100644 index 510aa2be19b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/json.js +++ /dev/null @@ -1,69 +0,0 @@ -/*! - * Connect - json - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , _limit = require('./limit'); - -/** - * JSON: - * - * Parse JSON request bodies, providing the - * parsed object as `req.body`. - * - * Options: - * - * - `strict` when `false` anything `JSON.parse()` accepts will be parsed - * - `reviver` used as the second "reviver" argument for JSON.parse - * - `limit` byte limit defaulting to "1mb" - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - var options = options || {} - , strict = options.strict === false - ? false - : true; - - var limit = _limit(options.limit || '1mb'); - - return function json(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - - // check Content-Type - if ('application/json' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - var buf = ''; - req.setEncoding('utf8'); - req.on('data', function(chunk){ buf += chunk }); - req.on('end', function(){ - if (strict && '{' != buf[0] && '[' != buf[0]) return next(utils.error(400, 'invalid json')); - try { - req.body = JSON.parse(buf, options.reviver); - next(); - } catch (err){ - err.body = buf; - err.status = 400; - next(err); - } - }); - }); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/limit.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/limit.js deleted file mode 100644 index 8233b4df31a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/limit.js +++ /dev/null @@ -1,55 +0,0 @@ - -/*! - * Connect - limit - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils'); - -/** - * Limit: - * - * Limit request bodies to the given size in `bytes`. - * - * A string representation of the bytesize may also be passed, - * for example "5mb", "200kb", "1gb", etc. - * - * connect() - * .use(connect.limit('5.5mb')) - * .use(handleImageUpload) - * - * @param {Number|String} bytes - * @return {Function} - * @api public - */ - -module.exports = function limit(bytes){ - if ('string' == typeof bytes) bytes = utils.parseBytes(bytes); - if ('number' != typeof bytes) throw new Error('limit() bytes required'); - return function limit(req, res, next){ - var received = 0 - , len = req.headers['content-length'] - ? parseInt(req.headers['content-length'], 10) - : null; - - // self-awareness - if (req._limit) return next(); - req._limit = true; - - // limit by content-length - if (len && len > bytes) return next(utils.error(413)); - - // limit - req.on('data', function(chunk){ - received += chunk.length; - if (received > bytes) req.destroy(); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/logger.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/logger.js deleted file mode 100644 index c1576140992..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/logger.js +++ /dev/null @@ -1,337 +0,0 @@ - -/*! - * Connect - logger - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var bytes = require('bytes'); - -/*! - * Log buffer. - */ - -var buf = []; - -/*! - * Default log buffer duration. - */ - -var defaultBufferDuration = 1000; - -/** - * Logger: - * - * Log requests with the given `options` or a `format` string. - * - * Options: - * - * - `format` Format string, see below for tokens - * - `stream` Output stream, defaults to _stdout_ - * - `buffer` Buffer duration, defaults to 1000ms when _true_ - * - `immediate` Write log line on request instead of response (for response times) - * - * Tokens: - * - * - `:req[header]` ex: `:req[Accept]` - * - `:res[header]` ex: `:res[Content-Length]` - * - `:http-version` - * - `:response-time` - * - `:remote-addr` - * - `:date` - * - `:method` - * - `:url` - * - `:referrer` - * - `:user-agent` - * - `:status` - * - * Formats: - * - * Pre-defined formats that ship with connect: - * - * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' - * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' - * - `tiny` ':method :url :status :res[content-length] - :response-time ms' - * - `dev` concise output colored by response status for development use - * - * Examples: - * - * connect.logger() // default - * connect.logger('short') - * connect.logger('tiny') - * connect.logger({ immediate: true, format: 'dev' }) - * connect.logger(':method :url - :referrer') - * connect.logger(':req[content-type] -> :res[content-type]') - * connect.logger(function(req, res){ return 'some format string' }) - * - * Defining Tokens: - * - * To define a token, simply invoke `connect.logger.token()` with the - * name and a callback function. The value returned is then available - * as ":type" in this case. - * - * connect.logger.token('type', function(req, res){ return req.headers['content-type']; }) - * - * Defining Formats: - * - * All default formats are defined this way, however it's public API as well: - * - * connect.logger.format('name', 'string or function') - * - * @param {String|Function|Object} format or options - * @return {Function} - * @api public - */ - -exports = module.exports = function logger(options) { - if ('object' == typeof options) { - options = options || {}; - } else if (options) { - options = { format: options }; - } else { - options = {}; - } - - // output on request instead of response - var immediate = options.immediate; - - // format name - var fmt = exports[options.format] || options.format || exports.default; - - // compile format - if ('function' != typeof fmt) fmt = compile(fmt); - - // options - var stream = options.stream || process.stdout - , buffer = options.buffer; - - // buffering support - if (buffer) { - var realStream = stream - , interval = 'number' == typeof buffer - ? buffer - : defaultBufferDuration; - - // flush interval - setInterval(function(){ - if (buf.length) { - realStream.write(buf.join(''), 'ascii'); - buf.length = 0; - } - }, interval); - - // swap the stream - stream = { - write: function(str){ - buf.push(str); - } - }; - } - - return function logger(req, res, next) { - req._startTime = new Date; - - // immediate - if (immediate) { - var line = fmt(exports, req, res); - if (null == line) return; - stream.write(line + '\n', 'ascii'); - // proxy end to output logging - } else { - var end = res.end; - res.end = function(chunk, encoding){ - res.end = end; - res.end(chunk, encoding); - var line = fmt(exports, req, res); - if (null == line) return; - stream.write(line + '\n', 'ascii'); - }; - } - - - next(); - }; -}; - -/** - * Compile `fmt` into a function. - * - * @param {String} fmt - * @return {Function} - * @api private - */ - -function compile(fmt) { - fmt = fmt.replace(/"/g, '\\"'); - var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){ - return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "'; - }) + '";' - return new Function('tokens, req, res', js); -}; - -/** - * Define a token function with the given `name`, - * and callback `fn(req, res)`. - * - * @param {String} name - * @param {Function} fn - * @return {Object} exports for chaining - * @api public - */ - -exports.token = function(name, fn) { - exports[name] = fn; - return this; -}; - -/** - * Define a `fmt` with the given `name`. - * - * @param {String} name - * @param {String|Function} fmt - * @return {Object} exports for chaining - * @api public - */ - -exports.format = function(name, str){ - exports[name] = str; - return this; -}; - -/** - * Default format. - */ - -exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'); - -/** - * Short format. - */ - -exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'); - -/** - * Tiny format. - */ - -exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms'); - -/** - * dev (colored) - */ - -exports.format('dev', function(tokens, req, res){ - var status = res.statusCode - , len = parseInt(res.getHeader('Content-Length'), 10) - , color = 32; - - if (status >= 500) color = 31 - else if (status >= 400) color = 33 - else if (status >= 300) color = 36; - - len = isNaN(len) - ? '' - : len = ' - ' + bytes(len); - - return '\033[90m' + req.method - + ' ' + req.originalUrl + ' ' - + '\033[' + color + 'm' + res.statusCode - + ' \033[90m' - + (new Date - req._startTime) - + 'ms' + len - + '\033[0m'; -}); - -/** - * request url - */ - -exports.token('url', function(req){ - return req.originalUrl; -}); - -/** - * request method - */ - -exports.token('method', function(req){ - return req.method; -}); - -/** - * response time in milliseconds - */ - -exports.token('response-time', function(req){ - return new Date - req._startTime; -}); - -/** - * UTC date - */ - -exports.token('date', function(){ - return new Date().toUTCString(); -}); - -/** - * response status code - */ - -exports.token('status', function(req, res){ - return res.statusCode; -}); - -/** - * normalized referrer - */ - -exports.token('referrer', function(req){ - return req.headers['referer'] || req.headers['referrer']; -}); - -/** - * remote address - */ - -exports.token('remote-addr', function(req){ - return req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress)); -}); - -/** - * HTTP version - */ - -exports.token('http-version', function(req){ - return req.httpVersionMajor + '.' + req.httpVersionMinor; -}); - -/** - * UA string - */ - -exports.token('user-agent', function(req){ - return req.headers['user-agent']; -}); - -/** - * request header - */ - -exports.token('req', function(req, res, field){ - return req.headers[field.toLowerCase()]; -}); - -/** - * response header - */ - -exports.token('res', function(req, res, field){ - return (res._headers || {})[field.toLowerCase()]; -}); - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/methodOverride.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/methodOverride.js deleted file mode 100644 index aaf4014f26f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/methodOverride.js +++ /dev/null @@ -1,40 +0,0 @@ - -/*! - * Connect - methodOverride - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Method Override: - * - * Provides faux HTTP method support. - * - * Pass an optional `key` to use when checking for - * a method override, othewise defaults to _\_method_. - * The original method is available via `req.originalMethod`. - * - * @param {String} key - * @return {Function} - * @api public - */ - -module.exports = function methodOverride(key){ - key = key || "_method"; - return function methodOverride(req, res, next) { - req.originalMethod = req.originalMethod || req.method; - - // req.body - if (req.body && key in req.body) { - req.method = req.body[key].toUpperCase(); - delete req.body[key]; - // check X-HTTP-Method-Override - } else if (req.headers['x-http-method-override']) { - req.method = req.headers['x-http-method-override'].toUpperCase(); - } - - next(); - }; -}; - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/multipart.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/multipart.js deleted file mode 100644 index ed748670ca6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/multipart.js +++ /dev/null @@ -1,110 +0,0 @@ - -/*! - * Connect - multipart - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var formidable = require('formidable') - , _limit = require('./limit') - , utils = require('../utils') - , qs = require('qs'); - -/** - * Multipart: - * - * Parse multipart/form-data request bodies, - * providing the parsed object as `req.body` - * and `req.files`. - * - * Configuration: - * - * The options passed are merged with [formidable](https://github.com/felixge/node-formidable)'s - * `IncomingForm` object, allowing you to configure the upload directory, - * size limits, etc. For example if you wish to change the upload dir do the following. - * - * app.use(connect.multipart({ uploadDir: path })); - * - * Options: - * - * - `limit` byte limit defaulting to "1mb" - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - options = options || {}; - var limit = _limit(options.limit || '20mb'); - - return function multipart(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - req.files = req.files || {}; - - // ignore GET - if ('GET' == req.method || 'HEAD' == req.method) return next(); - - // check Content-Type - if ('multipart/form-data' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - - var form = new formidable.IncomingForm - , data = {} - , files = {} - , done; - - Object.keys(options).forEach(function(key){ - form[key] = options[key]; - }); - - function ondata(name, val, data){ - if (Array.isArray(data[name])) { - data[name].push(val); - } else if (data[name]) { - data[name] = [data[name], val]; - } else { - data[name] = val; - } - } - - form.on('field', function(name, val){ - ondata(name, val, data); - }); - - form.on('file', function(name, val){ - ondata(name, val, files); - }); - - form.on('error', function(err){ - next(err); - done = true; - }); - - form.on('end', function(){ - if (done) return; - try { - req.body = qs.parse(data); - req.files = qs.parse(files); - next(); - } catch (err) { - next(err); - } - }); - - form.parse(req); - }); - } -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/query.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/query.js deleted file mode 100644 index 93fc5d347ba..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/query.js +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * Connect - query - * Copyright(c) 2011 TJ Holowaychuk - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var qs = require('qs') - , parse = require('../utils').parseUrl; - -/** - * Query: - * - * Automatically parse the query-string when available, - * populating the `req.query` object. - * - * Examples: - * - * connect() - * .use(connect.query()) - * .use(function(req, res){ - * res.end(JSON.stringify(req.query)); - * }); - * - * The `options` passed are provided to qs.parse function. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function query(options){ - return function query(req, res, next){ - if (!req.query) { - req.query = ~req.url.indexOf('?') - ? qs.parse(parse(req).query, options) - : {}; - } - - next(); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/responseTime.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/responseTime.js deleted file mode 100644 index 57858f6f5ec..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/responseTime.js +++ /dev/null @@ -1,32 +0,0 @@ - -/*! - * Connect - responseTime - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Reponse time: - * - * Adds the `X-Response-Time` header displaying the response - * duration in milliseconds. - * - * @return {Function} - * @api public - */ - -module.exports = function responseTime(){ - return function(req, res, next){ - var start = new Date; - - if (res._responseTime) return next(); - res._responseTime = true; - - res.on('header', function(header){ - var duration = new Date - start; - res.setHeader('X-Response-time', duration + 'ms'); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session.js deleted file mode 100644 index 05978f84891..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session.js +++ /dev/null @@ -1,344 +0,0 @@ - -/*! - * Connect - session - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var Session = require('./session/session') - , debug = require('debug')('connect:session') - , MemoryStore = require('./session/memory') - , Cookie = require('./session/cookie') - , Store = require('./session/store') - , utils = require('./../utils') - , parse = utils.parseUrl - , crc16 = require('crc').crc16 - , crypto = require('crypto'); - -// environment - -var env = process.env.NODE_ENV; - -/** - * Expose the middleware. - */ - -exports = module.exports = session; - -/** - * Expose constructors. - */ - -exports.Store = Store; -exports.Cookie = Cookie; -exports.Session = Session; -exports.MemoryStore = MemoryStore; - -/** - * Warning message for `MemoryStore` usage in production. - */ - -var warning = 'Warning: connection.session() MemoryStore is not\n' - + 'designed for a production environment, as it will leak\n' - + 'memory, and will not scale past a single process.'; - -/** - * Session: - * - * Setup session store with the given `options`. - * - * Session data is _not_ saved in the cookie itself, however - * cookies are used, so we must use the [cookieParser()](cookieParser.html) - * middleware _before_ `session()`. - * - * Examples: - * - * connect() - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) - * - * Options: - * - * - `key` cookie name defaulting to `connect.sid` - * - `store` session store instance - * - `secret` session cookie is signed with this secret to prevent tampering - * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") - * - * Cookie option: - * - * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set - * so the cookie becomes a browser-session cookie. When the user closes the - * browser the cookie (and session) will be removed. - * - * ## req.session - * - * To store or access session data, simply use the request property `req.session`, - * which is (generally) serialized as JSON by the store, so nested objects - * are typically fine. For example below is a user-specific view counter: - * - * connect() - * .use(connect.favicon()) - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) - * .use(function(req, res, next){ - * var sess = req.session; - * if (sess.views) { - * res.setHeader('Content-Type', 'text/html'); - * res.write('

    views: ' + sess.views + '

    '); - * res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    '); - * res.end(); - * sess.views++; - * } else { - * sess.views = 1; - * res.end('welcome to the session demo. refresh!'); - * } - * } - * )).listen(3000); - * - * ## Session#regenerate() - * - * To regenerate the session simply invoke the method, once complete - * a new SID and `Session` instance will be initialized at `req.session`. - * - * req.session.regenerate(function(err){ - * // will have a new session here - * }); - * - * ## Session#destroy() - * - * Destroys the session, removing `req.session`, will be re-generated next request. - * - * req.session.destroy(function(err){ - * // cannot access session here - * }); - * - * ## Session#reload() - * - * Reloads the session data. - * - * req.session.reload(function(err){ - * // session updated - * }); - * - * ## Session#save() - * - * Save the session. - * - * req.session.save(function(err){ - * // session saved - * }); - * - * ## Session#touch() - * - * Updates the `.maxAge` property. Typically this is - * not necessary to call, as the session middleware does this for you. - * - * ## Session#cookie - * - * Each session has a unique cookie object accompany it. This allows - * you to alter the session cookie per visitor. For example we can - * set `req.session.cookie.expires` to `false` to enable the cookie - * to remain for only the duration of the user-agent. - * - * ## Session#maxAge - * - * Alternatively `req.session.cookie.maxAge` will return the time - * remaining in milliseconds, which we may also re-assign a new value - * to adjust the `.expires` property appropriately. The following - * are essentially equivalent - * - * var hour = 3600000; - * req.session.cookie.expires = new Date(Date.now() + hour); - * req.session.cookie.maxAge = hour; - * - * For example when `maxAge` is set to `60000` (one minute), and 30 seconds - * has elapsed it will return `30000` until the current request has completed, - * at which time `req.session.touch()` is called to reset `req.session.maxAge` - * to its original value. - * - * req.session.cookie.maxAge; - * // => 30000 - * - * Session Store Implementation: - * - * Every session store _must_ implement the following methods - * - * - `.get(sid, callback)` - * - `.set(sid, session, callback)` - * - `.destroy(sid, callback)` - * - * Recommended methods include, but are not limited to: - * - * - `.length(callback)` - * - `.clear(callback)` - * - * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -function session(options){ - var options = options || {} - , key = options.key || 'connect.sid' - , store = options.store || new MemoryStore - , cookie = options.cookie || {} - , trustProxy = options.proxy; - - // notify user that this store is not - // meant for a production environment - if ('production' == env && store instanceof MemoryStore) { - console.warn(warning); - } - - // generates the new session - store.generate = function(req){ - req.sessionID = utils.uid(24); - req.session = new Session(req); - req.session.cookie = new Cookie(cookie); - }; - - return function session(req, res, next) { - // self-awareness - if (req.session) return next(); - - // pathname mismatch - if (0 != req.originalUrl.indexOf(cookie.path || '/')) return next(); - - // backwards compatibility for signed cookies - // req.secret is passed from the cookie parser middleware - var secret = options.secret || req.secret; - - // ensure secret is available or bail - if (!secret) throw new Error('`secret` option required for sessions'); - - // parse url - var url = parse(req) - , path = url.pathname - , originalHash; - - // expose store - req.sessionStore = store; - - // grab the session cookie value and check the signature - var rawCookie = req.cookies[key]; - - // get signedCookies for backwards compat with signed cookies - var unsignedCookie = req.signedCookies[key]; - - if (!unsignedCookie && rawCookie) { - unsignedCookie = utils.parseSignedCookie(rawCookie, secret); - } - - // set-cookie - res.on('header', function(){ - if (!req.session) return; - var cookie = req.session.cookie - , proto = (req.headers['x-forwarded-proto'] || '').toLowerCase() - , tls = req.connection.encrypted || (trustProxy && 'https' == proto) - , secured = cookie.secure && tls - , isNew = unsignedCookie != req.sessionID; - - // only send secure cookies via https - if (cookie.secure && !secured) return debug('not secured'); - - // browser-session length cookie - if (null == cookie.expires) { - if (!isNew) return debug('already set browser-session cookie'); - // compare hashes - } else if (originalHash == hash(req.session)) { - return debug('unmodified session'); - } - - var val = 's:' + utils.sign(req.sessionID, secret); - val = cookie.serialize(key, val); - debug('set-cookie %s', val); - res.setHeader('Set-Cookie', val); - }); - - // proxy end() to commit the session - var end = res.end; - res.end = function(data, encoding){ - res.end = end; - if (!req.session) return res.end(data, encoding); - debug('saving'); - req.session.resetMaxAge(); - req.session.save(function(){ - debug('saved'); - res.end(data, encoding); - }); - }; - - // generate the session - function generate() { - store.generate(req); - } - - // get the sessionID from the cookie - req.sessionID = unsignedCookie; - - // generate a session if the browser doesn't send a sessionID - if (!req.sessionID) { - debug('no SID sent, generating session'); - generate(); - next(); - return; - } - - // generate the session object - var pause = utils.pause(req); - debug('fetching %s', req.sessionID); - store.get(req.sessionID, function(err, sess){ - // proxy to resume() events - var _next = next; - next = function(err){ - _next(err); - pause.resume(); - } - - // error handling - if (err) { - debug('error'); - if ('ENOENT' == err.code) { - generate(); - next(); - } else { - next(err); - } - // no session - } else if (!sess) { - debug('no session found'); - generate(); - next(); - // populate req.session - } else { - debug('session found'); - store.createSession(req, sess); - originalHash = hash(sess); - next(); - } - }); - }; -}; - -/** - * Hash the given `sess` object omitting changes - * to `.cookie`. - * - * @param {Object} sess - * @return {String} - * @api private - */ - -function hash(sess) { - return crc16(JSON.stringify(sess, function(key, val){ - if ('cookie' != key) return val; - })); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/cookie.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/cookie.js deleted file mode 100644 index e8ff862595f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/cookie.js +++ /dev/null @@ -1,128 +0,0 @@ - -/*! - * Connect - session - Cookie - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../../utils') - , cookie = require('cookie'); - -/** - * Initialize a new `Cookie` with the given `options`. - * - * @param {IncomingMessage} req - * @param {Object} options - * @api private - */ - -var Cookie = module.exports = function Cookie(options) { - this.path = '/'; - this.maxAge = null; - this.httpOnly = true; - if (options) utils.merge(this, options); - this.originalMaxAge = undefined == this.originalMaxAge - ? this.maxAge - : this.originalMaxAge; -}; - -/*! - * Prototype. - */ - -Cookie.prototype = { - - /** - * Set expires `date`. - * - * @param {Date} date - * @api public - */ - - set expires(date) { - this._expires = date; - this.originalMaxAge = this.maxAge; - }, - - /** - * Get expires `date`. - * - * @return {Date} - * @api public - */ - - get expires() { - return this._expires; - }, - - /** - * Set expires via max-age in `ms`. - * - * @param {Number} ms - * @api public - */ - - set maxAge(ms) { - this.expires = 'number' == typeof ms - ? new Date(Date.now() + ms) - : ms; - }, - - /** - * Get expires max-age in `ms`. - * - * @return {Number} - * @api public - */ - - get maxAge() { - return this.expires instanceof Date - ? this.expires.valueOf() - Date.now() - : this.expires; - }, - - /** - * Return cookie data object. - * - * @return {Object} - * @api private - */ - - get data() { - return { - originalMaxAge: this.originalMaxAge - , expires: this._expires - , secure: this.secure - , httpOnly: this.httpOnly - , domain: this.domain - , path: this.path - } - }, - - /** - * Return a serialized cookie string. - * - * @return {String} - * @api public - */ - - serialize: function(name, val){ - return cookie.serialize(name, val, this.data); - }, - - /** - * Return JSON representation of this cookie. - * - * @return {Object} - * @api private - */ - - toJSON: function(){ - return this.data; - } -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/memory.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/memory.js deleted file mode 100644 index ec569f5c752..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/memory.js +++ /dev/null @@ -1,131 +0,0 @@ - -/*! - * Connect - session - MemoryStore - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var Store = require('./store') - , utils = require('../../utils') - , Session = require('./session'); - -/** - * Initialize a new `MemoryStore`. - * - * @api public - */ - -var MemoryStore = module.exports = function MemoryStore() { - this.sessions = {}; -}; - -/** - * Inherit from `Store.prototype`. - */ - -MemoryStore.prototype.__proto__ = Store.prototype; - -/** - * Attempt to fetch session by the given `sid`. - * - * @param {String} sid - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.get = function(sid, fn){ - var self = this; - process.nextTick(function(){ - var expires - , sess = self.sessions[sid]; - if (sess) { - sess = JSON.parse(sess); - expires = 'string' == typeof sess.cookie.expires - ? new Date(sess.cookie.expires) - : sess.cookie.expires; - if (!expires || new Date < expires) { - fn(null, sess); - } else { - self.destroy(sid, fn); - } - } else { - fn(); - } - }); -}; - -/** - * Commit the given `sess` object associated with the given `sid`. - * - * @param {String} sid - * @param {Session} sess - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.set = function(sid, sess, fn){ - var self = this; - process.nextTick(function(){ - self.sessions[sid] = JSON.stringify(sess); - fn && fn(); - }); -}; - -/** - * Destroy the session associated with the given `sid`. - * - * @param {String} sid - * @api public - */ - -MemoryStore.prototype.destroy = function(sid, fn){ - var self = this; - process.nextTick(function(){ - delete self.sessions[sid]; - fn && fn(); - }); -}; - -/** - * Invoke the given callback `fn` with all active sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.all = function(fn){ - var arr = [] - , keys = Object.keys(this.sessions); - for (var i = 0, len = keys.length; i < len; ++i) { - arr.push(this.sessions[keys[i]]); - } - fn(null, arr); -}; - -/** - * Clear all sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.clear = function(fn){ - this.sessions = {}; - fn && fn(); -}; - -/** - * Fetch number of sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.length = function(fn){ - fn(null, Object.keys(this.sessions).length); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/session.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/session.js deleted file mode 100644 index 0dd4b400726..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/session.js +++ /dev/null @@ -1,116 +0,0 @@ - -/*! - * Connect - session - Session - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../../utils'); - -/** - * Create a new `Session` with the given request and `data`. - * - * @param {IncomingRequest} req - * @param {Object} data - * @api private - */ - -var Session = module.exports = function Session(req, data) { - Object.defineProperty(this, 'req', { value: req }); - Object.defineProperty(this, 'id', { value: req.sessionID }); - if ('object' == typeof data) utils.merge(this, data); -}; - -/** - * Update reset `.cookie.maxAge` to prevent - * the cookie from expiring when the - * session is still active. - * - * @return {Session} for chaining - * @api public - */ - -Session.prototype.touch = function(){ - return this.resetMaxAge(); -}; - -/** - * Reset `.maxAge` to `.originalMaxAge`. - * - * @return {Session} for chaining - * @api public - */ - -Session.prototype.resetMaxAge = function(){ - this.cookie.maxAge = this.cookie.originalMaxAge; - return this; -}; - -/** - * Save the session data with optional callback `fn(err)`. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.save = function(fn){ - this.req.sessionStore.set(this.id, this, fn || function(){}); - return this; -}; - -/** - * Re-loads the session data _without_ altering - * the maxAge properties. Invokes the callback `fn(err)`, - * after which time if no exception has occurred the - * `req.session` property will be a new `Session` object, - * although representing the same session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.reload = function(fn){ - var req = this.req - , store = this.req.sessionStore; - store.get(this.id, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(new Error('failed to load session')); - store.createSession(req, sess); - fn(); - }); - return this; -}; - -/** - * Destroy `this` session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.destroy = function(fn){ - delete this.req.session; - this.req.sessionStore.destroy(this.id, fn); - return this; -}; - -/** - * Regenerate this request's session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.regenerate = function(fn){ - this.req.sessionStore.regenerate(this.req, fn); - return this; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/store.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/store.js deleted file mode 100644 index 7d6f1cb054e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/session/store.js +++ /dev/null @@ -1,86 +0,0 @@ - -/*! - * Connect - session - Store - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter - , Session = require('./session') - , Cookie = require('./cookie') - , utils = require('../../utils'); - -/** - * Initialize abstract `Store`. - * - * @api private - */ - -var Store = module.exports = function Store(options){}; - -/** - * Inherit from `EventEmitter.prototype`. - */ - -Store.prototype.__proto__ = EventEmitter.prototype; - -/** - * Re-generate the given requests's session. - * - * @param {IncomingRequest} req - * @return {Function} fn - * @api public - */ - -Store.prototype.regenerate = function(req, fn){ - var self = this; - this.destroy(req.sessionID, function(err){ - self.generate(req); - fn(err); - }); -}; - -/** - * Load a `Session` instance via the given `sid` - * and invoke the callback `fn(err, sess)`. - * - * @param {String} sid - * @param {Function} fn - * @api public - */ - -Store.prototype.load = function(sid, fn){ - var self = this; - this.get(sid, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(); - var req = { sessionID: sid, sessionStore: self }; - sess = self.createSession(req, sess); - fn(null, sess); - }); -}; - -/** - * Create session from JSON `sess` data. - * - * @param {IncomingRequest} req - * @param {Object} sess - * @return {Session} - * @api private - */ - -Store.prototype.createSession = function(req, sess){ - var expires = sess.cookie.expires - , orig = sess.cookie.originalMaxAge - , update = null == update ? true : false; - sess.cookie = new Cookie(sess.cookie); - if ('string' == typeof expires) sess.cookie.expires = new Date(expires); - sess.cookie.originalMaxAge = orig; - req.session = new Session(req, sess); - return req.session; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/static.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/static.js deleted file mode 100644 index 1503529c270..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/static.js +++ /dev/null @@ -1,89 +0,0 @@ - -/*! - * Connect - static - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var send = require('send') - , utils = require('../utils') - , parse = utils.parseUrl - , url = require('url'); - -/** - * Static: - * - * Static file server with the given `root` path. - * - * Examples: - * - * var oneDay = 86400000; - * - * connect() - * .use(connect.static(__dirname + '/public')) - * - * connect() - * .use(connect.static(__dirname + '/public', { maxAge: oneDay })) - * - * Options: - * - * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0 - * - `hidden` Allow transfer of hidden files. defaults to false - * - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true - * - * @param {String} root - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function static(root, options){ - options = options || {}; - - // root required - if (!root) throw new Error('static() root path required'); - options.root = root; - - // default redirect - var redirect = false === options.redirect ? false : true; - - return function static(req, res, next) { - if ('GET' != req.method && 'HEAD' != req.method) return next(); - var path = parse(req).pathname; - - function directory() { - if (!redirect) return next(); - var pathname = url.parse(req.originalUrl).pathname; - res.statusCode = 301; - res.setHeader('Location', pathname + '/'); - res.end('Redirecting to ' + utils.escape(pathname) + '/'); - } - - function error(err) { - if (404 == err.status) return next(); - next(err); - } - - send(req, path) - .maxage(options.maxAge || 0) - .root(options.root) - .hidden(options.hidden) - .on('error', error) - .on('directory', directory) - .pipe(res); - }; -}; - -/** - * Expose mime module. - * - * If you wish to extend the mime table use this - * reference to the "mime" module in the npm registry. - */ - -exports.mime = send.mime; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/staticCache.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/staticCache.js deleted file mode 100644 index 54ccc98ca6f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/staticCache.js +++ /dev/null @@ -1,234 +0,0 @@ - -/*! - * Connect - staticCache - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , utils = require('../utils') - , Cache = require('../cache') - , fresh = require('fresh') - , url = require('url') - , fs = require('fs'); - -/** - * Static cache: - * - * Enables a memory cache layer on top of - * the `static()` middleware, serving popular - * static files. - * - * By default a maximum of 128 objects are - * held in cache, with a max of 256k each, - * totalling ~32mb. - * - * A Least-Recently-Used (LRU) cache algo - * is implemented through the `Cache` object, - * simply rotating cache objects as they are - * hit. This means that increasingly popular - * objects maintain their positions while - * others get shoved out of the stack and - * garbage collected. - * - * Benchmarks: - * - * static(): 2700 rps - * node-static: 5300 rps - * static() + staticCache(): 7500 rps - * - * Options: - * - * - `maxObjects` max cache objects [128] - * - `maxLength` max cache object length 256kb - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function staticCache(options){ - var options = options || {} - , cache = new Cache(options.maxObjects || 128) - , maxlen = options.maxLength || 1024 * 256; - - console.warn('connect.staticCache() is deprecated and will be removed in 3.0'); - console.warn('use varnish or similar reverse proxy caches.'); - - return function staticCache(req, res, next){ - var key = cacheKey(req) - , ranges = req.headers.range - , hasCookies = req.headers.cookie - , hit = cache.get(key); - - // cache static - // TODO: change from staticCache() -> cache() - // and make this work for any request - req.on('static', function(stream){ - var headers = res._headers - , cc = utils.parseCacheControl(headers['cache-control'] || '') - , contentLength = headers['content-length'] - , hit; - - // dont cache set-cookie responses - if (headers['set-cookie']) return hasCookies = true; - - // dont cache when cookies are present - if (hasCookies) return; - - // ignore larger files - if (!contentLength || contentLength > maxlen) return; - - // don't cache partial files - if (headers['content-range']) return; - - // dont cache items we shouldn't be - // TODO: real support for must-revalidate / no-cache - if ( cc['no-cache'] - || cc['no-store'] - || cc['private'] - || cc['must-revalidate']) return; - - // if already in cache then validate - if (hit = cache.get(key)){ - if (headers.etag == hit[0].etag) { - hit[0].date = new Date; - return; - } else { - cache.remove(key); - } - } - - // validation notifiactions don't contain a steam - if (null == stream) return; - - // add the cache object - var arr = []; - - // store the chunks - stream.on('data', function(chunk){ - arr.push(chunk); - }); - - // flag it as complete - stream.on('end', function(){ - var cacheEntry = cache.add(key); - delete headers['x-cache']; // Clean up (TODO: others) - cacheEntry.push(200); - cacheEntry.push(headers); - cacheEntry.push.apply(cacheEntry, arr); - }); - }); - - if (req.method == 'GET' || req.method == 'HEAD') { - if (ranges) { - next(); - } else if (!hasCookies && hit && !mustRevalidate(req, hit)) { - res.setHeader('X-Cache', 'HIT'); - respondFromCache(req, res, hit); - } else { - res.setHeader('X-Cache', 'MISS'); - next(); - } - } else { - next(); - } - } -}; - -/** - * Respond with the provided cached value. - * TODO: Assume 200 code, that's iffy. - * - * @param {Object} req - * @param {Object} res - * @param {Object} cacheEntry - * @return {String} - * @api private - */ - -function respondFromCache(req, res, cacheEntry) { - var status = cacheEntry[0] - , headers = utils.merge({}, cacheEntry[1]) - , content = cacheEntry.slice(2); - - headers.age = (new Date - new Date(headers.date)) / 1000 || 0; - - switch (req.method) { - case 'HEAD': - res.writeHead(status, headers); - res.end(); - break; - case 'GET': - if (utils.conditionalGET(req) && fresh(req.headers, headers)) { - headers['content-length'] = 0; - res.writeHead(304, headers); - res.end(); - } else { - res.writeHead(status, headers); - - function write() { - while (content.length) { - if (false === res.write(content.shift())) { - res.once('drain', write); - return; - } - } - res.end(); - } - - write(); - } - break; - default: - // This should never happen. - res.writeHead(500, ''); - res.end(); - } -} - -/** - * Determine whether or not a cached value must be revalidated. - * - * @param {Object} req - * @param {Object} cacheEntry - * @return {String} - * @api private - */ - -function mustRevalidate(req, cacheEntry) { - var cacheHeaders = cacheEntry[1] - , reqCC = utils.parseCacheControl(req.headers['cache-control'] || '') - , cacheCC = utils.parseCacheControl(cacheHeaders['cache-control'] || '') - , cacheAge = (new Date - new Date(cacheHeaders.date)) / 1000 || 0; - - if ( cacheCC['no-cache'] - || cacheCC['must-revalidate'] - || cacheCC['proxy-revalidate']) return true; - - if (reqCC['no-cache']) return true - - if (null != reqCC['max-age']) return reqCC['max-age'] < cacheAge; - - if (null != cacheCC['max-age']) return cacheCC['max-age'] < cacheAge; - - return false; -} - -/** - * The key to use in the cache. For now, this is the URL path and query. - * - * 'http://example.com?key=value' -> '/?key=value' - * - * @param {Object} req - * @return {String} - * @api private - */ - -function cacheKey(req) { - return utils.parseUrl(req).path; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/urlencoded.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/urlencoded.js deleted file mode 100644 index 8f498dee399..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/urlencoded.js +++ /dev/null @@ -1,65 +0,0 @@ - -/*! - * Connect - urlencoded - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , _limit = require('./limit') - , qs = require('qs'); - -/** - * Urlencoded: - * - * Parse x-ww-form-urlencoded request bodies, - * providing the parsed object as `req.body`. - * - * Options: - * - * - `limit` byte limit defaulting to "1mb" - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - options = options || {}; - var limit = _limit(options.limit || '1mb'); - - return function urlencoded(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - - // check Content-Type - if ('application/x-www-form-urlencoded' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - var buf = ''; - req.setEncoding('utf8'); - req.on('data', function(chunk){ buf += chunk }); - req.on('end', function(){ - try { - req.body = buf.length - ? qs.parse(buf, options) - : {}; - next(); - } catch (err){ - err.body = buf; - next(err); - } - }); - }); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/vhost.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/vhost.js deleted file mode 100644 index 897a9d89a96..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/middleware/vhost.js +++ /dev/null @@ -1,40 +0,0 @@ - -/*! - * Connect - vhost - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Vhost: - * - * Setup vhost for the given `hostname` and `server`. - * - * connect() - * .use(connect.vhost('foo.com', fooApp)) - * .use(connect.vhost('bar.com', barApp)) - * .use(connect.vhost('*.com', mainApp)) - * - * The `server` may be a Connect server or - * a regular Node `http.Server`. - * - * @param {String} hostname - * @param {Server} server - * @return {Function} - * @api public - */ - -module.exports = function vhost(hostname, server){ - if (!hostname) throw new Error('vhost hostname required'); - if (!server) throw new Error('vhost server required'); - var regexp = new RegExp('^' + hostname.replace(/[*]/g, '(.*?)') + '$', 'i'); - if (server.onvhost) server.onvhost(hostname); - return function vhost(req, res, next){ - if (!req.headers.host) return next(); - var host = req.headers.host.split(':')[0]; - if (!regexp.test(host)) return next(); - if ('function' == typeof server) return server(req, res, next); - server.emit('request', req, res); - }; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/patch.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/patch.js deleted file mode 100644 index 7cf001255d5..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/patch.js +++ /dev/null @@ -1,79 +0,0 @@ - -/*! - * Connect - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , res = http.ServerResponse.prototype - , setHeader = res.setHeader - , _renderHeaders = res._renderHeaders - , writeHead = res.writeHead; - -// apply only once - -if (!res._hasConnectPatch) { - - /** - * Provide a public "header sent" flag - * until node does. - * - * @return {Boolean} - * @api public - */ - - res.__defineGetter__('headerSent', function(){ - return this._header; - }); - - /** - * Set header `field` to `val`, special-casing - * the `Set-Cookie` field for multiple support. - * - * @param {String} field - * @param {String} val - * @api public - */ - - res.setHeader = function(field, val){ - var key = field.toLowerCase() - , prev; - - // special-case Set-Cookie - if (this._headers && 'set-cookie' == key) { - if (prev = this.getHeader(field)) { - val = Array.isArray(prev) - ? prev.concat(val) - : [prev, val]; - } - // charset - } else if ('content-type' == key && this.charset) { - val += '; charset=' + this.charset; - } - - return setHeader.call(this, field, val); - }; - - /** - * Proxy to emit "header" event. - */ - - res._renderHeaders = function(){ - if (!this._emittedHeader) this.emit('header'); - this._emittedHeader = true; - return _renderHeaders.call(this); - }; - - res.writeHead = function(){ - if (!this._emittedHeader) this.emit('header'); - this._emittedHeader = true; - return writeHead.apply(this, arguments); - }; - - res._hasConnectPatch = true; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/proto.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/proto.js deleted file mode 100644 index bca6ec4911c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/proto.js +++ /dev/null @@ -1,230 +0,0 @@ - -/*! - * Connect - HTTPServer - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , utils = require('./utils') - , debug = require('debug')('connect:dispatcher'); - -// prototype - -var app = module.exports = {}; - -// environment - -var env = process.env.NODE_ENV || 'development'; - -/** - * Utilize the given middleware `handle` to the given `route`, - * defaulting to _/_. This "route" is the mount-point for the - * middleware, when given a value other than _/_ the middleware - * is only effective when that segment is present in the request's - * pathname. - * - * For example if we were to mount a function at _/admin_, it would - * be invoked on _/admin_, and _/admin/settings_, however it would - * not be invoked for _/_, or _/posts_. - * - * Examples: - * - * var app = connect(); - * app.use(connect.favicon()); - * app.use(connect.logger()); - * app.use(connect.static(__dirname + '/public')); - * - * If we wanted to prefix static files with _/public_, we could - * "mount" the `static()` middleware: - * - * app.use('/public', connect.static(__dirname + '/public')); - * - * This api is chainable, so the following is valid: - * - * connect - * .use(connect.favicon()) - * .use(connect.logger()) - * .use(connect.static(__dirname + '/public')) - * .listen(3000); - * - * @param {String|Function|Server} route, callback or server - * @param {Function|Server} callback or server - * @return {Server} for chaining - * @api public - */ - -app.use = function(route, fn){ - // default route to '/' - if ('string' != typeof route) { - fn = route; - route = '/'; - } - - // wrap sub-apps - if ('function' == typeof fn.handle) { - var server = fn; - fn.route = route; - fn = function(req, res, next){ - server.handle(req, res, next); - }; - } - - // wrap vanilla http.Servers - if (fn instanceof http.Server) { - fn = fn.listeners('request')[0]; - } - - // strip trailing slash - if ('/' == route[route.length - 1]) { - route = route.slice(0, -1); - } - - // add the middleware - debug('use %s %s', route || '/', fn.name || 'anonymous'); - this.stack.push({ route: route, handle: fn }); - - return this; -}; - -/** - * Handle server requests, punting them down - * the middleware stack. - * - * @api private - */ - -app.handle = function(req, res, out) { - var stack = this.stack - , fqdn = ~req.url.indexOf('://') - , removed = '' - , slashAdded = false - , index = 0; - - function next(err) { - var layer, path, status, c; - - if (slashAdded) { - req.url = req.url.substr(1); - slashAdded = false; - } - - req.url = removed + req.url; - req.originalUrl = req.originalUrl || req.url; - removed = ''; - - // next callback - layer = stack[index++]; - - // all done - if (!layer || res.headerSent) { - // delegate to parent - if (out) return out(err); - - // unhandled error - if (err) { - // default to 500 - if (res.statusCode < 400) res.statusCode = 500; - debug('default %s', res.statusCode); - - // respect err.status - if (err.status) res.statusCode = err.status; - - // production gets a basic error message - var msg = 'production' == env - ? http.STATUS_CODES[res.statusCode] - : err.stack || err.toString(); - - // log to stderr in a non-test env - if ('test' != env) console.error(err.stack || err.toString()); - if (res.headerSent) return req.socket.destroy(); - res.setHeader('Content-Type', 'text/plain'); - res.setHeader('Content-Length', Buffer.byteLength(msg)); - if ('HEAD' == req.method) return res.end(); - res.end(msg); - } else { - debug('default 404'); - res.statusCode = 404; - res.setHeader('Content-Type', 'text/plain'); - if ('HEAD' == req.method) return res.end(); - res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl)); - } - return; - } - - try { - path = utils.parseUrl(req).pathname; - if (undefined == path) path = '/'; - - // skip this layer if the route doesn't match. - if (0 != path.indexOf(layer.route)) return next(err); - - c = path[layer.route.length]; - if (c && '/' != c && '.' != c) return next(err); - - // Call the layer handler - // Trim off the part of the url that matches the route - removed = layer.route; - req.url = req.url.substr(removed.length); - - // Ensure leading slash - if (!fqdn && '/' != req.url[0]) { - req.url = '/' + req.url; - slashAdded = true; - } - - debug('%s', layer.handle.name || 'anonymous'); - var arity = layer.handle.length; - if (err) { - if (arity === 4) { - layer.handle(err, req, res, next); - } else { - next(err); - } - } else if (arity < 4) { - layer.handle(req, res, next); - } else { - next(); - } - } catch (e) { - next(e); - } - } - next(); -}; - -/** - * Listen for connections. - * - * This method takes the same arguments - * as node's `http.Server#listen()`. - * - * HTTP and HTTPS: - * - * If you run your application both as HTTP - * and HTTPS you may wrap them individually, - * since your Connect "server" is really just - * a JavaScript `Function`. - * - * var connect = require('connect') - * , http = require('http') - * , https = require('https'); - * - * var app = connect(); - * - * http.createServer(app).listen(80); - * https.createServer(options, app).listen(443); - * - * @return {http.Server} - * @api public - */ - -app.listen = function(){ - var server = http.createServer(this); - return server.listen.apply(server, arguments); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/directory.html b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/directory.html deleted file mode 100644 index 15164bba59d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/directory.html +++ /dev/null @@ -1,75 +0,0 @@ - - - listing directory {directory} - - - - - -
    -

    {linked-path}

    - {files} -
    - - \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/error.html b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/error.html deleted file mode 100644 index c5ae73a01da..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/error.html +++ /dev/null @@ -1,13 +0,0 @@ - - - {error} - - - -
    -

    {title}

    -

    {statusCode} {error}

    -
      {stack}
    -
    - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/favicon.ico b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/favicon.ico deleted file mode 100644 index 895fc96a76b..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/favicon.ico and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page.png deleted file mode 100644 index 03ddd799fa0..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_add.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_add.png deleted file mode 100644 index d5bfa0719bc..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_add.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_attach.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_attach.png deleted file mode 100644 index 89ee2da0753..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_attach.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_code.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_code.png deleted file mode 100644 index f7ea90419d9..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_code.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_copy.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_copy.png deleted file mode 100644 index 195dc6d6c36..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_copy.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_delete.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_delete.png deleted file mode 100644 index 3141467c678..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_delete.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_edit.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_edit.png deleted file mode 100644 index 046811ed7a6..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_edit.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_error.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_error.png deleted file mode 100644 index f07f449a44f..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_error.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_excel.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_excel.png deleted file mode 100644 index eb6158eb5ca..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_excel.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_find.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_find.png deleted file mode 100644 index 2f193889f7e..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_find.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_gear.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_gear.png deleted file mode 100644 index 8e83281c5f8..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_gear.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_go.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_go.png deleted file mode 100644 index 80fe1ed0cc7..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_go.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_green.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_green.png deleted file mode 100644 index de8e003f9fb..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_green.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_key.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_key.png deleted file mode 100644 index d6626cb09eb..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_key.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_lightning.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_lightning.png deleted file mode 100644 index 7e568703d64..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_lightning.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_link.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_link.png deleted file mode 100644 index 312eab0914a..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_link.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paintbrush.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paintbrush.png deleted file mode 100644 index 246a2f0b426..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paintbrush.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paste.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paste.png deleted file mode 100644 index 968f073fddd..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_paste.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_red.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_red.png deleted file mode 100644 index 0b18247da58..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_red.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_refresh.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_refresh.png deleted file mode 100644 index cf347c7d468..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_refresh.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_save.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_save.png deleted file mode 100644 index caea546af54..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_save.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white.png deleted file mode 100644 index 8b8b1ca0000..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_acrobat.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_acrobat.png deleted file mode 100644 index 8f8095e46fa..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_acrobat.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_actionscript.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_actionscript.png deleted file mode 100644 index 159b2407519..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_actionscript.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_add.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_add.png deleted file mode 100644 index aa23dde3746..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_add.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_c.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_c.png deleted file mode 100644 index 34a05cccf06..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_c.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_camera.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_camera.png deleted file mode 100644 index f501a593a4e..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_camera.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cd.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cd.png deleted file mode 100644 index 848bdaf3f15..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cd.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code.png deleted file mode 100644 index 0c76bd12977..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code_red.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code_red.png deleted file mode 100644 index 87a69145075..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_code_red.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_coldfusion.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_coldfusion.png deleted file mode 100644 index c66011fb0fb..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_coldfusion.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_compressed.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_compressed.png deleted file mode 100644 index 2b6b1007f33..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_compressed.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_copy.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_copy.png deleted file mode 100644 index a9f31a278e1..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_copy.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cplusplus.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cplusplus.png deleted file mode 100644 index a87cf847cb7..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cplusplus.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_csharp.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_csharp.png deleted file mode 100644 index ffb8fc932f3..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_csharp.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cup.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cup.png deleted file mode 100644 index 0a7d6f4a6f6..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_cup.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_database.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_database.png deleted file mode 100644 index bddba1f98ca..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_database.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_delete.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_delete.png deleted file mode 100644 index af1ecaf2981..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_delete.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_dvd.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_dvd.png deleted file mode 100644 index 4cc537af0b3..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_dvd.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_edit.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_edit.png deleted file mode 100644 index b93e77600de..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_edit.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_error.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_error.png deleted file mode 100644 index 9fc5a0a103d..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_error.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_excel.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_excel.png deleted file mode 100644 index b977d7e52e2..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_excel.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_find.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_find.png deleted file mode 100644 index 58184363707..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_find.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_flash.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_flash.png deleted file mode 100644 index 5769120b1b6..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_flash.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_freehand.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_freehand.png deleted file mode 100644 index 8d719df5205..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_freehand.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_gear.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_gear.png deleted file mode 100644 index 106f5aa3611..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_gear.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_get.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_get.png deleted file mode 100644 index e4a1ecba1b6..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_get.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_go.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_go.png deleted file mode 100644 index 7e62a924bc5..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_go.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_h.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_h.png deleted file mode 100644 index e902abb0767..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_h.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_horizontal.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_horizontal.png deleted file mode 100644 index 1d2d0a49870..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_horizontal.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_key.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_key.png deleted file mode 100644 index d6164845228..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_key.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_lightning.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_lightning.png deleted file mode 100644 index 7215d1e8b06..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_lightning.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_link.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_link.png deleted file mode 100644 index bf7bd1c9bfd..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_link.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_magnify.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_magnify.png deleted file mode 100644 index f6b74cc40f8..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_magnify.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_medal.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_medal.png deleted file mode 100644 index d3fffb6d989..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_medal.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_office.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_office.png deleted file mode 100644 index a65bcb3e1e9..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_office.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paint.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paint.png deleted file mode 100644 index 23a37b891c2..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paint.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paintbrush.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paintbrush.png deleted file mode 100644 index f907e44b333..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paintbrush.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paste.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paste.png deleted file mode 100644 index 5b2cbb3fd02..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_paste.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_php.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_php.png deleted file mode 100644 index 7868a25945c..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_php.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_picture.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_picture.png deleted file mode 100644 index 134b6693687..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_picture.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_powerpoint.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_powerpoint.png deleted file mode 100644 index c4eff0387d5..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_powerpoint.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_put.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_put.png deleted file mode 100644 index 884ffd6f0aa..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_put.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_ruby.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_ruby.png deleted file mode 100644 index f59b7c4365f..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_ruby.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_stack.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_stack.png deleted file mode 100644 index 44084add79b..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_stack.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_star.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_star.png deleted file mode 100644 index 3a1441c9a12..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_star.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_swoosh.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_swoosh.png deleted file mode 100644 index e7708292ada..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_swoosh.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text.png deleted file mode 100644 index 813f712f726..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text_width.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text_width.png deleted file mode 100644 index d9cf13256f4..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_text_width.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_tux.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_tux.png deleted file mode 100644 index 52699bfee0c..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_tux.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_vector.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_vector.png deleted file mode 100644 index 4a05955b337..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_vector.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_visualstudio.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_visualstudio.png deleted file mode 100644 index a0a433dfbb6..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_visualstudio.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_width.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_width.png deleted file mode 100644 index 1eb880947dd..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_width.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_word.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_word.png deleted file mode 100644 index ae8ecbf4767..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_word.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_world.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_world.png deleted file mode 100644 index 6ed2490ed14..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_world.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_wrench.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_wrench.png deleted file mode 100644 index fecadd08afe..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_wrench.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_zip.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_zip.png deleted file mode 100644 index fd4bbccdf16..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_white_zip.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_word.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_word.png deleted file mode 100644 index 834cdfaf48a..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_word.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_world.png b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_world.png deleted file mode 100644 index b8895ddecf5..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/icons/page_world.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/style.css b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/style.css deleted file mode 100644 index 32b65071036..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/public/style.css +++ /dev/null @@ -1,141 +0,0 @@ -body { - margin: 0; - padding: 80px 100px; - font: 13px "Helvetica Neue", "Lucida Grande", "Arial"; - background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9)); - background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9); - background-repeat: no-repeat; - color: #555; - -webkit-font-smoothing: antialiased; -} -h1, h2, h3 { - margin: 0; - font-size: 22px; - color: #343434; -} -h1 em, h2 em { - padding: 0 5px; - font-weight: normal; -} -h1 { - font-size: 60px; -} -h2 { - margin-top: 10px; -} -h3 { - margin: 5px 0 10px 0; - padding-bottom: 5px; - border-bottom: 1px solid #eee; - font-size: 18px; -} -ul { - margin: 0; - padding: 0; -} -ul li { - margin: 5px 0; - padding: 3px 8px; - list-style: none; -} -ul li:hover { - cursor: pointer; - color: #2e2e2e; -} -ul li .path { - padding-left: 5px; - font-weight: bold; -} -ul li .line { - padding-right: 5px; - font-style: italic; -} -ul li:first-child .path { - padding-left: 0; -} -p { - line-height: 1.5; -} -a { - color: #555; - text-decoration: none; -} -a:hover { - color: #303030; -} -#stacktrace { - margin-top: 15px; -} -.directory h1 { - margin-bottom: 15px; - font-size: 18px; -} -ul#files { - width: 100%; - height: 500px; -} -ul#files li { - padding: 0; -} -ul#files li img { - position: absolute; - top: 5px; - left: 5px; -} -ul#files li a { - position: relative; - display: block; - margin: 1px; - width: 30%; - height: 25px; - line-height: 25px; - text-indent: 8px; - float: left; - border: 1px solid transparent; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - overflow: hidden; - text-overflow: ellipsis; -} -ul#files li a.icon { - text-indent: 25px; -} -ul#files li a:focus, -ul#files li a:hover { - outline: none; - background: rgba(255,255,255,0.65); - border: 1px solid #ececec; -} -ul#files li a.highlight { - -webkit-transition: background .4s ease-in-out; - background: #ffff4f; - border-color: #E9DC51; -} -#search { - display: block; - position: fixed; - top: 20px; - right: 20px; - width: 90px; - -webkit-transition: width ease 0.2s, opacity ease 0.4s; - -moz-transition: width ease 0.2s, opacity ease 0.4s; - -webkit-border-radius: 32px; - -moz-border-radius: 32px; - -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); - -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); - -webkit-font-smoothing: antialiased; - text-align: left; - font: 13px "Helvetica Neue", Arial, sans-serif; - padding: 4px 10px; - border: none; - background: transparent; - margin-bottom: 0; - outline: none; - opacity: 0.7; - color: #888; -} -#search:focus { - width: 120px; - opacity: 1.0; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/utils.js deleted file mode 100644 index 5ef47423e93..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/lib/utils.js +++ /dev/null @@ -1,400 +0,0 @@ - -/*! - * Connect - utils - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , crypto = require('crypto') - , parse = require('url').parse - , Path = require('path') - , fs = require('fs'); - -/** - * Extract the mime type from the given request's - * _Content-Type_ header. - * - * @param {IncomingMessage} req - * @return {String} - * @api private - */ - -exports.mime = function(req) { - var str = req.headers['content-type'] || ''; - return str.split(';')[0]; -}; - -/** - * Generate an `Error` from the given status `code` - * and optional `msg`. - * - * @param {Number} code - * @param {String} msg - * @return {Error} - * @api private - */ - -exports.error = function(code, msg){ - var err = new Error(msg || http.STATUS_CODES[code]); - err.status = code; - return err; -}; - -/** - * Return md5 hash of the given string and optional encoding, - * defaulting to hex. - * - * utils.md5('wahoo'); - * // => "e493298061761236c96b02ea6aa8a2ad" - * - * @param {String} str - * @param {String} encoding - * @return {String} - * @api private - */ - -exports.md5 = function(str, encoding){ - return crypto - .createHash('md5') - .update(str) - .digest(encoding || 'hex'); -}; - -/** - * Merge object b with object a. - * - * var a = { foo: 'bar' } - * , b = { bar: 'baz' }; - * - * utils.merge(a, b); - * // => { foo: 'bar', bar: 'baz' } - * - * @param {Object} a - * @param {Object} b - * @return {Object} - * @api private - */ - -exports.merge = function(a, b){ - if (a && b) { - for (var key in b) { - a[key] = b[key]; - } - } - return a; -}; - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; - - -/** - * Return a unique identifier with the given `len`. - * - * utils.uid(10); - * // => "FDaS435D2z" - * - * @param {Number} len - * @return {String} - * @api private - */ - -exports.uid = function(len) { - return crypto.randomBytes(Math.ceil(len * 3 / 4)) - .toString('base64') - .slice(0, len); -}; - -/** - * Sign the given `val` with `secret`. - * - * @param {String} val - * @param {String} secret - * @return {String} - * @api private - */ - -exports.sign = function(val, secret){ - return val + '.' + crypto - .createHmac('sha256', secret) - .update(val) - .digest('base64') - .replace(/=+$/, ''); -}; - -/** - * Unsign and decode the given `val` with `secret`, - * returning `false` if the signature is invalid. - * - * @param {String} val - * @param {String} secret - * @return {String|Boolean} - * @api private - */ - -exports.unsign = function(val, secret){ - var str = val.slice(0, val.lastIndexOf('.')); - return exports.sign(str, secret) == val - ? str - : false; -}; - -/** - * Parse signed cookies, returning an object - * containing the decoded key/value pairs, - * while removing the signed key from `obj`. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.parseSignedCookies = function(obj, secret){ - var ret = {}; - Object.keys(obj).forEach(function(key){ - var val = obj[key]; - if (0 == val.indexOf('s:')) { - val = exports.unsign(val.slice(2), secret); - if (val) { - ret[key] = val; - delete obj[key]; - } - } - }); - return ret; -}; - -/** - * Parse a signed cookie string, return the decoded value - * - * @param {String} str signed cookie string - * @param {String} secret - * @return {String} decoded value - * @api private - */ - -exports.parseSignedCookie = function(str, secret){ - return 0 == str.indexOf('s:') - ? exports.unsign(str.slice(2), secret) - : str; -}; - -/** - * Parse JSON cookies. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.parseJSONCookies = function(obj){ - Object.keys(obj).forEach(function(key){ - var val = obj[key]; - var res = exports.parseJSONCookie(val); - if (res) obj[key] = res; - }); - return obj; -}; - -/** - * Parse JSON cookie string - * - * @param {String} str - * @return {Object} Parsed object or null if not json cookie - * @api private - */ - -exports.parseJSONCookie = function(str) { - if (0 == str.indexOf('j:')) { - try { - return JSON.parse(str.slice(2)); - } catch (err) { - // no op - } - } -} - -/** - * Pause `data` and `end` events on the given `obj`. - * Middleware performing async tasks _should_ utilize - * this utility (or similar), to re-emit data once - * the async operation has completed, otherwise these - * events may be lost. - * - * var pause = utils.pause(req); - * fs.readFile(path, function(){ - * next(); - * pause.resume(); - * }); - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.pause = function(obj){ - var onData - , onEnd - , events = []; - - // buffer data - obj.on('data', onData = function(data, encoding){ - events.push(['data', data, encoding]); - }); - - // buffer end - obj.on('end', onEnd = function(data, encoding){ - events.push(['end', data, encoding]); - }); - - return { - end: function(){ - obj.removeListener('data', onData); - obj.removeListener('end', onEnd); - }, - resume: function(){ - this.end(); - for (var i = 0, len = events.length; i < len; ++i) { - obj.emit.apply(obj, events[i]); - } - } - }; -}; - -/** - * Strip `Content-*` headers from `res`. - * - * @param {ServerResponse} res - * @api private - */ - -exports.removeContentHeaders = function(res){ - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); - } - }); -}; - -/** - * Check if `req` is a conditional GET request. - * - * @param {IncomingMessage} req - * @return {Boolean} - * @api private - */ - -exports.conditionalGET = function(req) { - return req.headers['if-modified-since'] - || req.headers['if-none-match']; -}; - -/** - * Respond with 401 "Unauthorized". - * - * @param {ServerResponse} res - * @param {String} realm - * @api private - */ - -exports.unauthorized = function(res, realm) { - res.statusCode = 401; - res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); - res.end('Unauthorized'); -}; - -/** - * Respond with 304 "Not Modified". - * - * @param {ServerResponse} res - * @param {Object} headers - * @api private - */ - -exports.notModified = function(res) { - exports.removeContentHeaders(res); - res.statusCode = 304; - res.end(); -}; - -/** - * Return an ETag in the form of `"-"` - * from the given `stat`. - * - * @param {Object} stat - * @return {String} - * @api private - */ - -exports.etag = function(stat) { - return '"' + stat.size + '-' + Number(stat.mtime) + '"'; -}; - -/** - * Parse the given Cache-Control `str`. - * - * @param {String} str - * @return {Object} - * @api private - */ - -exports.parseCacheControl = function(str){ - var directives = str.split(',') - , obj = {}; - - for(var i = 0, len = directives.length; i < len; i++) { - var parts = directives[i].split('=') - , key = parts.shift().trim() - , val = parseInt(parts.shift(), 10); - - obj[key] = isNaN(val) ? true : val; - } - - return obj; -}; - -/** - * Parse the `req` url with memoization. - * - * @param {ServerRequest} req - * @return {Object} - * @api private - */ - -exports.parseUrl = function(req){ - var parsed = req._parsedUrl; - if (parsed && parsed.href == req.url) { - return parsed; - } else { - return req._parsedUrl = parse(req.url); - } -}; - -/** - * Parse byte `size` string. - * - * @param {String} size - * @return {Number} - * @api private - */ - -exports.parseBytes = require('bytes'); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/History.md deleted file mode 100644 index db1f75944d0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/History.md +++ /dev/null @@ -1,5 +0,0 @@ - -0.1.0 / 2012-07-04 -================== - - * add bytes to string conversion [yields] diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Readme.md deleted file mode 100644 index 9325d5bf419..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/Readme.md +++ /dev/null @@ -1,51 +0,0 @@ -# node-bytes - - Byte string parser / formatter. - -## Example: - -```js -bytes('1kb') -// => 1024 - -bytes('2mb') -// => 2097152 - -bytes('1gb') -// => 1073741824 - -bytes(1073741824) -// => 1gb -``` - -## Installation - -``` -$ npm install bytes -$ component install visionmedia/bytes.js -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/component.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/component.json deleted file mode 100644 index 76a6057b020..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/component.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "bytes", - "description": "byte size string parser / serializer", - "keywords": ["bytes", "utility"], - "version": "0.1.0", - "scripts": ["index.js"] -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/index.js deleted file mode 100644 index 3eaafc74d3e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/index.js +++ /dev/null @@ -1,39 +0,0 @@ - -/** - * Parse byte `size` string. - * - * @param {String} size - * @return {Number} - * @api public - */ - -module.exports = function(size) { - if ('number' == typeof size) return convert(size); - var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/) - , n = parseFloat(parts[1]) - , type = parts[2]; - - var map = { - kb: 1 << 10 - , mb: 1 << 20 - , gb: 1 << 30 - }; - - return map[type] * n; -}; - -/** - * convert bytes into string. - * - * @param {Number} b - bytes to convert - * @return {String}i - * @api public - */ - -function convert (b) { - var gb = 1 << 30, mb = 1 << 20, kb = 1 << 10; - if (b >= gb) return (Math.round(b / gb * 100) / 100) + 'gb'; - if (b >= mb) return (Math.round(b / mb * 100) / 100) + 'mb'; - if (b >= kb) return (Math.round(b / kb * 100) / 100) + 'kb'; - return b; -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/package.json deleted file mode 100644 index 3a2ebba8de3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/bytes/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "bytes", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "byte size string parser / serializer", - "version": "0.1.0", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "component": { - "scripts": { - "bytes": "index.js" - } - }, - "readme": "# node-bytes\n\n Byte string parser / formatter.\n\n## Example:\n\n```js\nbytes('1kb')\n// => 1024\n\nbytes('2mb')\n// => 2097152\n\nbytes('1gb')\n// => 1073741824\n\nbytes(1073741824)\n// => 1gb\n```\n\n## Installation\n\n```\n$ npm install bytes\n$ component install visionmedia/bytes.js\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "_id": "bytes@0.1.0", - "dist": { - "shasum": "b9aa129c968dd048eac87555161e367bcc3682b8" - }, - "_from": "bytes@0.1.0", - "_resolved": "https://registry.npmjs.org/bytes/-/bytes-0.1.0.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/.travis.yml deleted file mode 100644 index bced1510759..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.6 diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/README.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/README.md deleted file mode 100644 index 5187ed1ccad..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) # - -cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers. - -See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies. - -## how? - -``` -npm install cookie -``` - -```javascript -var cookie = require('cookie'); - -var hdr = cookie.serialize('foo', 'bar'); -// hdr = 'foo=bar'; - -var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff'); -// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' }; -``` - -## more - -The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values. - -### path -> cookie path - -### expires -> absolute expiration date for the cookie (Date object) - -### maxAge -> relative max age of the cookie from when the client receives it (seconds) - -### domain -> domain for the cookie - -### secure -> true or false - -### httpOnly -> true or false - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/index.js deleted file mode 100644 index ce6c9269d1b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/index.js +++ /dev/null @@ -1,57 +0,0 @@ - -/// Serialize the a name value pair into a cookie string suitable for -/// http headers. An optional options object specified cookie parameters -/// -/// serialize('foo', 'bar', { httpOnly: true }) -/// => "foo=bar; httpOnly" -/// -/// @param {String} name -/// @param {String} val -/// @param {Object} options -/// @return {String} -var serialize = function(name, val, opt){ - var pairs = [name + '=' + encode(val)]; - opt = opt || {}; - - if (opt.maxAge) pairs.push('Max-Age=' + opt.maxAge); - if (opt.domain) pairs.push('Domain=' + opt.domain); - if (opt.path) pairs.push('Path=' + opt.path); - if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); - if (opt.httpOnly) pairs.push('HttpOnly'); - if (opt.secure) pairs.push('Secure'); - - return pairs.join('; '); -}; - -/// Parse the given cookie header string into an object -/// The object has the various cookies as keys(names) => values -/// @param {String} str -/// @return {Object} -var parse = function(str) { - var obj = {} - var pairs = str.split(/[;,] */); - - pairs.forEach(function(pair) { - var eq_idx = pair.indexOf('=') - var key = pair.substr(0, eq_idx).trim() - var val = pair.substr(++eq_idx, pair.length).trim(); - - // quoted values - if ('"' == val[0]) { - val = val.slice(1, -1); - } - - // only assign once - if (undefined == obj[key]) { - obj[key] = decode(val); - } - }); - - return obj; -}; - -var encode = encodeURIComponent; -var decode = decodeURIComponent; - -module.exports.serialize = serialize; -module.exports.parse = parse; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/package.json deleted file mode 100644 index 9e834fb2d01..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "author": { - "name": "Roman Shtylman", - "email": "shtylman@gmail.com" - }, - "name": "cookie", - "description": "cookie parsing and serialization", - "version": "0.0.4", - "repository": { - "type": "git", - "url": "git://github.com/shtylman/node-cookie.git" - }, - "keywords": [ - "cookie", - "cookies" - ], - "main": "index.js", - "scripts": { - "test": "mocha" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "1.x.x" - }, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/shtylman/node-cookie/issues" - }, - "_id": "cookie@0.0.4", - "dist": { - "shasum": "74abef43e43c6b5417bd4282118281dce1b0168c" - }, - "_from": "cookie@0.0.4", - "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.0.4.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/mocha.opts b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/mocha.opts deleted file mode 100644 index e2bfcc5ac3f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---ui qunit diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/parse.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/parse.js deleted file mode 100644 index 4b98a20aafb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/parse.js +++ /dev/null @@ -1,25 +0,0 @@ - -var assert = require('assert'); - -var cookie = require('..'); - -suite('parse'); - -test('basic', function() { - assert.deepEqual({ foo: 'bar' }, cookie.parse('foo=bar')); - assert.deepEqual({ foo: '123' }, cookie.parse('foo=123')); -}); - -test('ignore spaces', function() { - assert.deepEqual({ FOO: 'bar', baz: 'raz' }, - cookie.parse('FOO = bar; baz = raz')); -}); - -test('escaping', function() { - assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, - cookie.parse('foo="bar=123456789&name=Magic+Mouse"')); - - assert.deepEqual({ email: ' ",;/' }, - cookie.parse('email=%20%22%2c%3b%2f')); -}); - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/serialize.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/serialize.js deleted file mode 100644 index d38768d6ab3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/cookie/test/serialize.js +++ /dev/null @@ -1,59 +0,0 @@ -// builtin -var assert = require('assert'); - -var cookie = require('..'); - -suite('serialize'); - -test('basic', function() { - assert.equal('foo=bar', cookie.serialize('foo', 'bar')); - assert.equal('foo=bar%20baz', cookie.serialize('foo', 'bar baz')); -}); - -test('path', function() { - assert.equal('foo=bar; Path=/', cookie.serialize('foo', 'bar', { - path: '/' - })); -}); - -test('secure', function() { - assert.equal('foo=bar; Secure', cookie.serialize('foo', 'bar', { - secure: true - })); - - assert.equal('foo=bar', cookie.serialize('foo', 'bar', { - secure: false - })); -}); - -test('domain', function() { - assert.equal('foo=bar; Domain=example.com', cookie.serialize('foo', 'bar', { - domain: 'example.com' - })); -}); - -test('httpOnly', function() { - assert.equal('foo=bar; HttpOnly', cookie.serialize('foo', 'bar', { - httpOnly: true - })); -}); - -test('maxAge', function() { - assert.equal('foo=bar; Max-Age=1000', cookie.serialize('foo', 'bar', { - maxAge: 1000 - })); -}); - -test('escaping', function() { - assert.deepEqual('cat=%2B%20', cookie.serialize('cat', '+ ')); -}); - -test('parse->serialize', function() { - - assert.deepEqual({ cat: 'foo=123&name=baz five' }, cookie.parse( - cookie.serialize('cat', 'foo=123&name=baz five'))); - - assert.deepEqual({ cat: ' ";/' }, cookie.parse( - cookie.serialize('cat', ' ";/'))); -}); - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.gitmodules b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.gitmodules deleted file mode 100644 index 2319e181125..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "tests/nodeunit"] - path = tests/nodeunit - url = git://github.com/caolan/nodeunit.git diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.npmignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/Makefile deleted file mode 100644 index 720bf851128..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/README.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/README.md deleted file mode 100644 index 26ce22fdf44..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# JavaScript CRC 8, 16 and 32. - -This is a basic port/copy of the JavaScript CRC implementation. The module works with any CommonJS system supporting `module.exports` notation as well as in the browser. When loaded in the browser, all functions end up under the `window.crc` "namespace". - -Original code is taken from http://www.digsys.se/JavaScript/CRC.aspx - -## Functions - -The following functions are implemented: - - crc8(String) #=> Number - crcArc(String) #=> Number - crc16(String) #=> Number - fcs16(String) #=> Number - crc32(String) #=> Number - hex8(Number) #=> String - hex16(Number) #=> String - hex32(Number) #=> String - -## Installation - - git clone git://github.com/alexgorbatchev/node-crc.git - -or - - npm install crc - -## Running tests - - $ npm install - $ make test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/lib/crc.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/lib/crc.js deleted file mode 100644 index 8feb5421c72..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/lib/crc.js +++ /dev/null @@ -1,403 +0,0 @@ -(function() -{ - // CRC-8 in table form - // - // Copyright (c) 1989 AnDan Software. You may use this program, or - // code or tables extracted from it, as long as this notice is not - // removed or changed. - var CRC8_TAB = new Array( - // C/C++ language: - // - // unsigned char CRC8_TAB[] = {...}; - 0x00,0x1B,0x36,0x2D,0x6C,0x77,0x5A,0x41,0xD8,0xC3,0xEE,0xF5,0xB4,0xAF,0x82,0x99,0xD3,0xC8,0xE5, - 0xFE,0xBF,0xA4,0x89,0x92,0x0B,0x10,0x3D,0x26,0x67,0x7C,0x51,0x4A,0xC5,0xDE,0xF3,0xE8,0xA9,0xB2, - 0x9F,0x84,0x1D,0x06,0x2B,0x30,0x71,0x6A,0x47,0x5C,0x16,0x0D,0x20,0x3B,0x7A,0x61,0x4C,0x57,0xCE, - 0xD5,0xF8,0xE3,0xA2,0xB9,0x94,0x8F,0xE9,0xF2,0xDF,0xC4,0x85,0x9E,0xB3,0xA8,0x31,0x2A,0x07,0x1C, - 0x5D,0x46,0x6B,0x70,0x3A,0x21,0x0C,0x17,0x56,0x4D,0x60,0x7B,0xE2,0xF9,0xD4,0xCF,0x8E,0x95,0xB8, - 0xA3,0x2C,0x37,0x1A,0x01,0x40,0x5B,0x76,0x6D,0xF4,0xEF,0xC2,0xD9,0x98,0x83,0xAE,0xB5,0xFF,0xE4, - 0xC9,0xD2,0x93,0x88,0xA5,0xBE,0x27,0x3C,0x11,0x0A,0x4B,0x50,0x7D,0x66,0xB1,0xAA,0x87,0x9C,0xDD, - 0xC6,0xEB,0xF0,0x69,0x72,0x5F,0x44,0x05,0x1E,0x33,0x28,0x62,0x79,0x54,0x4F,0x0E,0x15,0x38,0x23, - 0xBA,0xA1,0x8C,0x97,0xD6,0xCD,0xE0,0xFB,0x74,0x6F,0x42,0x59,0x18,0x03,0x2E,0x35,0xAC,0xB7,0x9A, - 0x81,0xC0,0xDB,0xF6,0xED,0xA7,0xBC,0x91,0x8A,0xCB,0xD0,0xFD,0xE6,0x7F,0x64,0x49,0x52,0x13,0x08, - 0x25,0x3E,0x58,0x43,0x6E,0x75,0x34,0x2F,0x02,0x19,0x80,0x9B,0xB6,0xAD,0xEC,0xF7,0xDA,0xC1,0x8B, - 0x90,0xBD,0xA6,0xE7,0xFC,0xD1,0xCA,0x53,0x48,0x65,0x7E,0x3F,0x24,0x09,0x12,0x9D,0x86,0xAB,0xB0, - 0xF1,0xEA,0xC7,0xDC,0x45,0x5E,0x73,0x68,0x29,0x32,0x1F,0x04,0x4E,0x55,0x78,0x63,0x22,0x39,0x14, - 0x0F,0x96,0x8D,0xA0,0xBB,0xFA,0xE1,0xCC,0xD7 - ); - - function crc8Add(crc,c) - // 'crc' should be initialized to 0x00. - { - return CRC8_TAB[(crc^c)&0xFF]; - }; - // C/C++ language: - // - // inline unsigned char crc8Add(unsigned char crc, unsigned char c) - // { - // return CRC8_TAB[crc^c]; - // } - - // CRC-16 (as it is in SEA's ARC) in table form - // - // The logic for this method of calculating the CRC 16 bit polynomial - // is taken from an article by David Schwaderer in the April 1985 - // issue of PC Tech Journal. - var CRC_ARC_TAB = new Array( - // C/C++ language: - // - // unsigned short CRC_ARC_TAB[] = {...}; - 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741,0x0500, - 0xC5C1,0xC481,0x0440,0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,0x0A00,0xCAC1, - 0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81, - 0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,0x1400,0xD4C1,0xD581,0x1540, - 0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,0xF001, - 0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0, - 0x3480,0xF441,0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80, - 0xFB41,0x3900,0xF9C1,0xF881,0x3840,0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41, - 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,0xE401,0x24C0,0x2580,0xE541,0x2700, - 0xE7C1,0xE681,0x2640,0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,0xA001,0x60C0, - 0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480, - 0xA441,0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41, - 0x6900,0xA9C1,0xA881,0x6840,0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,0xBE01, - 0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1, - 0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,0x5000,0x90C1,0x9181, - 0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440, - 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,0x5A00,0x9AC1,0x9B81,0x5B40,0x9901, - 0x59C0,0x5880,0x9841,0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1, - 0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680, - 0x8641,0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040 - ); - - function crcArcAdd(crc,c) - // 'crc' should be initialized to 0x0000. - { - return CRC_ARC_TAB[(crc^c)&0xFF]^((crc>>8)&0xFF); - }; - // C/C++ language: - // - // inline unsigned short crcArcAdd(unsigned short crc, unsigned char c) - // { - // return CRC_ARC_TAB[(unsigned char)crc^c]^(unsigned short)(crc>>8); - // } - - // CRC-16 (as it is in ZMODEM) in table form - // - // Copyright (c) 1989 AnDan Software. You may use this program, or - // code or tables extracted from it, as long as this notice is not - // removed or changed. - var CRC16_TAB = new Array( - // C/C++ language: - // - // unsigned short CRC16_TAB[] = {...}; - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7,0x8108,0x9129,0xA14A,0xB16B,0xC18C, - 0xD1AD,0xE1CE,0xF1EF,0x1231,0x0210,0x3273,0x2252,0x52B5,0x4294,0x72F7,0x62D6,0x9339,0x8318, - 0xB37B,0xA35A,0xD3BD,0xC39C,0xF3FF,0xE3DE,0x2462,0x3443,0x0420,0x1401,0x64E6,0x74C7,0x44A4, - 0x5485,0xA56A,0xB54B,0x8528,0x9509,0xE5EE,0xF5CF,0xC5AC,0xD58D,0x3653,0x2672,0x1611,0x0630, - 0x76D7,0x66F6,0x5695,0x46B4,0xB75B,0xA77A,0x9719,0x8738,0xF7DF,0xE7FE,0xD79D,0xC7BC,0x48C4, - 0x58E5,0x6886,0x78A7,0x0840,0x1861,0x2802,0x3823,0xC9CC,0xD9ED,0xE98E,0xF9AF,0x8948,0x9969, - 0xA90A,0xB92B,0x5AF5,0x4AD4,0x7AB7,0x6A96,0x1A71,0x0A50,0x3A33,0x2A12,0xDBFD,0xCBDC,0xFBBF, - 0xEB9E,0x9B79,0x8B58,0xBB3B,0xAB1A,0x6CA6,0x7C87,0x4CE4,0x5CC5,0x2C22,0x3C03,0x0C60,0x1C41, - 0xEDAE,0xFD8F,0xCDEC,0xDDCD,0xAD2A,0xBD0B,0x8D68,0x9D49,0x7E97,0x6EB6,0x5ED5,0x4EF4,0x3E13, - 0x2E32,0x1E51,0x0E70,0xFF9F,0xEFBE,0xDFDD,0xCFFC,0xBF1B,0xAF3A,0x9F59,0x8F78,0x9188,0x81A9, - 0xB1CA,0xA1EB,0xD10C,0xC12D,0xF14E,0xE16F,0x1080,0x00A1,0x30C2,0x20E3,0x5004,0x4025,0x7046, - 0x6067,0x83B9,0x9398,0xA3FB,0xB3DA,0xC33D,0xD31C,0xE37F,0xF35E,0x02B1,0x1290,0x22F3,0x32D2, - 0x4235,0x5214,0x6277,0x7256,0xB5EA,0xA5CB,0x95A8,0x8589,0xF56E,0xE54F,0xD52C,0xC50D,0x34E2, - 0x24C3,0x14A0,0x0481,0x7466,0x6447,0x5424,0x4405,0xA7DB,0xB7FA,0x8799,0x97B8,0xE75F,0xF77E, - 0xC71D,0xD73C,0x26D3,0x36F2,0x0691,0x16B0,0x6657,0x7676,0x4615,0x5634,0xD94C,0xC96D,0xF90E, - 0xE92F,0x99C8,0x89E9,0xB98A,0xA9AB,0x5844,0x4865,0x7806,0x6827,0x18C0,0x08E1,0x3882,0x28A3, - 0xCB7D,0xDB5C,0xEB3F,0xFB1E,0x8BF9,0x9BD8,0xABBB,0xBB9A,0x4A75,0x5A54,0x6A37,0x7A16,0x0AF1, - 0x1AD0,0x2AB3,0x3A92,0xFD2E,0xED0F,0xDD6C,0xCD4D,0xBDAA,0xAD8B,0x9DE8,0x8DC9,0x7C26,0x6C07, - 0x5C64,0x4C45,0x3CA2,0x2C83,0x1CE0,0x0CC1,0xEF1F,0xFF3E,0xCF5D,0xDF7C,0xAF9B,0xBFBA,0x8FD9, - 0x9FF8,0x6E17,0x7E36,0x4E55,0x5E74,0x2E93,0x3EB2,0x0ED1,0x1EF0 - ); - - function crc16Add(crc,c) - // 'crc' should be initialized to 0x0000. - { - return CRC16_TAB[((crc>>8)^c)&0xFF]^((crc<<8)&0xFFFF); - }; - // C/C++ language: - // - // inline unsigned short crc16Add(unsigned short crc, unsigned char c) - // { - // return CRC16_TAB[(unsigned char)(crc>>8)^c]^(unsigned short)(crc<<8); - // } - - // FCS-16 (as it is in PPP) in table form - // - // Described in RFC-1662 by William Allen Simpson, see RFC-1662 for references. - // - // Modified by Anders Danielsson, March 10, 2006. - var FCS_16_TAB = new Array( - // C/C++ language: - // - // unsigned short FCS_16_TAB[256] = {...}; - 0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF,0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C, - 0xDBE5,0xE97E,0xF8F7,0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E,0x9CC9,0x8D40, - 0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876,0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434, - 0x55BD,0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5,0x3183,0x200A,0x1291,0x0318, - 0x77A7,0x662E,0x54B5,0x453C,0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974,0x4204, - 0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB,0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1, - 0xAB7A,0xBAF3,0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A,0xDECD,0xCF44,0xFDDF, - 0xEC56,0x98E9,0x8960,0xBBFB,0xAA72,0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9, - 0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1,0x7387,0x620E,0x5095,0x411C,0x35A3, - 0x242A,0x16B1,0x0738,0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70,0x8408,0x9581, - 0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7,0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76, - 0x7CFF,0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036,0x18C1,0x0948,0x3BD3,0x2A5A, - 0x5EE5,0x4F6C,0x7DF7,0x6C7E,0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5,0x2942, - 0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD,0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226, - 0xD0BD,0xC134,0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C,0xC60C,0xD785,0xE51E, - 0xF497,0x8028,0x91A1,0xA33A,0xB2B3,0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB, - 0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232,0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1, - 0x0D68,0x3FF3,0x2E7A,0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1,0x6B46,0x7ACF, - 0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9,0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9, - 0x8330,0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78 - ); - - function fcs16Add(fcs,c) - // 'fcs' should be initialized to 0xFFFF and after the computation it should be - // complemented (inverted). - // - // If the FCS-16 is calculated over the data and over the complemented FCS-16, the - // result will always be 0xF0B8 (without the complementation). - { - return FCS_16_TAB[(fcs^c)&0xFF]^((fcs>>8)&0xFF); - }; - - // C/C++ language: - // - // inline unsigned short fcs16Add(unsigned short fcs, unsigned char c) - // { - // return FCS_16_TAB[(unsigned char)fcs^c]^(unsigned short)(fcs>>8); - // } - - // - // CRC-32 (as it is in ZMODEM) in table form - // - // Copyright (C) 1986 Gary S. Brown. You may use this program, or - // code or tables extracted from it, as desired without restriction. - // - // Modified by Anders Danielsson, February 5, 1989 and March 10, 2006. - // - // This is also known as FCS-32 (as it is in PPP), described in - // RFC-1662 by William Allen Simpson, see RFC-1662 for references. - // - var CRC32_TAB = new Array( /* CRC polynomial 0xEDB88320 */ - // C/C++ language: - // - // unsigned long CRC32_TAB[] = {...}; - 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, - 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, - 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, - 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, - 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, - 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, - 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, - 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, - 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, - 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, - 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, - 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, - 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, - 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, - 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, - 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, - 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, - 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, - 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, - 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, - 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, - 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, - 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, - 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, - 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, - 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, - 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, - 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, - 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, - 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, - 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, - 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D - ); - - function crc32Add(crc,c) - // 'crc' should be initialized to 0xFFFFFFFF and after the computation it should be - // complemented (inverted). - // - // CRC-32 is also known as FCS-32. - // - // If the FCS-32 is calculated over the data and over the complemented FCS-32, the - // result will always be 0xDEBB20E3 (without the complementation). - { - return CRC32_TAB[(crc^c)&0xFF]^((crc>>8)&0xFFFFFF); - }; - // - // C/C++ language: - // - // inline unsigned long crc32Add(unsigned long crc, unsigned char c) - // { - // return CRC32_TAB[(unsigned char)crc^c]^(crc>>8); - // } - // - - function crc8(str) - { - var n, - len = str.length, - crc = 0 - ; - - for(var i = 0; i < len; i++) - crc = crc8Add(crc, str.charCodeAt(i)); - - return crc; - }; - - function crc8Buffer(buf) - { - var crc = 0; - - for (var i = 0, len = buf.length; i < len; ++i) - { - crc = crc8Add(crc, buf[i]); - } - - return crc; - } - - function crcArc(str) - { - var i, - len = str.length, - crc = 0 - ; - - for(i = 0; i < len; i++) - crc = crcArcAdd(crc, str.charCodeAt(i)); - - return crc; - }; - - function crc16(str) - { - var i, - len = str.length, - crc = 0 - ; - - for(i = 0; i < len; i++) - crc = crc16Add(crc, str.charCodeAt(i)); - - return crc; - }; - - function crc16Buffer(buf) - { - var crc = 0; - - for (var i = 0, len = buf.length; i < len; ++i) - { - crc = crc16Add(crc, buf[i]); - } - - return crc; - } - - function fcs16(str) - { - var i, - len = str.length, - fcs = 0xFFFF - ; - - for(i = 0; i < len; i++) - fcs = fcs16Add(fcs,str.charCodeAt(i)); - - return fcs^0xFFFF; - }; - - function crc32(str) - { - var i, - len = str.length, - crc = 0xFFFFFFFF - ; - - for(i = 0; i < len; i++) - crc = crc32Add(crc, str.charCodeAt(i)); - - return crc^0xFFFFFFFF; - }; - - function crc32Buffer(buf) - { - var crc = 0xFFFFFFFF; - - for (var i = 0, len = buf.length; i < len; ++i) - { - crc = crc32Add(crc, buf[i]); - } - - return crc ^ 0xFFFFFFFF; - } - - /** - * Convert value as 8-bit unsigned integer to 2 digit hexadecimal number. - */ - function hex8(val) - { - var n = val & 0xFF, - str = n.toString(16).toUpperCase() - ; - - while(str.length < 2) - str = "0" + str; - - return str; - }; - - /** - * Convert value as 16-bit unsigned integer to 4 digit hexadecimal number. - */ - function hex16(val) - { - return hex8(val >> 8) + hex8(val); - }; - - /** - * Convert value as 32-bit unsigned integer to 8 digit hexadecimal number. - */ - function hex32(val) - { - return hex16(val >> 16) + hex16(val); - }; - - var target, property; - - if(typeof(window) == 'undefined') - { - target = module; - property = 'exports'; - } - else - { - target = window; - property = 'crc'; - } - - target[property] = { - 'crc8' : crc8, - 'crcArc' : crcArc, - 'crc16' : crc16, - 'fcs16' : fcs16, - 'crc32' : crc32, - 'hex8' : hex8, - 'hex16' : hex16, - 'hex32' : hex32, - 'buffer' : { - crc8 : crc8Buffer, - crc16 : crc16Buffer, - crc32 : crc32Buffer - } - }; -})(); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/package.json deleted file mode 100644 index 29bc0cc7534..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "crc", - "version": "0.2.0", - "description": "CRC JavaScript implementation", - "author": { - "name": "Alex Gorbatchev", - "email": "alex.gorbatchev@gmail.com" - }, - "contributors": [], - "main": "./lib/crc.js", - "scripts": {}, - "directories": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "repository": { - "type": "git", - "url": "git://github.com/alexgorbatchev/node-crc.git" - }, - "readme": "# JavaScript CRC 8, 16 and 32.\n\nThis is a basic port/copy of the JavaScript CRC implementation. The module works with any CommonJS system supporting `module.exports` notation as well as in the browser. When loaded in the browser, all functions end up under the `window.crc` \"namespace\".\n\nOriginal code is taken from http://www.digsys.se/JavaScript/CRC.aspx \n\n## Functions\n\nThe following functions are implemented:\n\n crc8(String)\t#=> Number\n crcArc(String)\t#=> Number\n crc16(String)\t#=> Number\n fcs16(String)\t#=> Number\n crc32(String)\t#=> Number\n hex8(Number)\t#=> String\n hex16(Number)\t#=> String\n hex32(Number)\t#=> String\n\n## Installation\n\n\tgit clone git://github.com/alexgorbatchev/node-crc.git\n\nor\n\n npm install crc\n\n## Running tests\n\n $ npm install\n $ make test", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/alexgorbatchev/node-crc/issues" - }, - "_id": "crc@0.2.0", - "dist": { - "shasum": "9ace0dee4fbe7336e5146ab5d0b4a58704d5fd36" - }, - "_from": "crc@0.2.0", - "_resolved": "https://registry.npmjs.org/crc/-/crc-0.2.0.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/test/crc.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/test/crc.js deleted file mode 100755 index faf2d1d7de2..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/crc/test/crc.js +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env ./nodeunit/bin/nodeunit - -var crc = require('../lib/crc'); - -describe('crc8()', function(){ - it('should work with strings', function(){ - crc.crc8('hello world').should.equal(64); - }) - - it('should work with Buffers', function(){ - crc.buffer.crc8(new Buffer('hello world')).should.equal(64); - }) -}) - -describe('crc16()', function(){ - it('should work with strings', function(){ - crc.crc16('hello world').should.equal(15332); - }) - - it('should work with Buffers', function(){ - crc.buffer.crc16(new Buffer('hello world')).should.equal(15332); - }) -}) - -describe('crc32()', function(){ - it('should work with strings', function(){ - crc.crc32('hello world').should.equal(222957957); - }) - - it('should work with Buffers', function(){ - crc.buffer.crc32(new Buffer('hello world')).should.equal(222957957); - }) -}) - -describe('crcArc()', function(){ - it('should work with strings', function(){ - crc.crcArc('hello world').should.equal(14785); - }) -}) - -describe('fcs16()', function(){ - it('should work with strings', function(){ - crc.fcs16('hello world').should.equal(44550); - }) -}) - -describe('hex8()', function(){ - it('should work with strings', function(){ - crc.hex8(64).should.equal('40'); - }) -}) - -describe('hex16()', function(){ - it('should work with strings', function(){ - crc.hex16(15332).should.equal('3BE4'); - }) -}) - -describe('hex32()', function(){ - it('should work with strings', function(){ - crc.hex32(222957957).should.equal('0D4A1185'); - }) -}) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/History.md deleted file mode 100644 index f023269bed8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/History.md +++ /dev/null @@ -1,62 +0,0 @@ - -0.7.2 / 2013-02-06 -================== - - * fix package.json - * fix: Mobile Safari (private mode) is broken with debug - * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript - -0.7.1 / 2013-02-05 -================== - - * add repository URL to package.json - * add DEBUG_COLORED to force colored output - * add browserify support - * fix component. Closes #24 - -0.7.0 / 2012-05-04 -================== - - * Added .component to package.json - * Added debug.component.js build - -0.6.0 / 2012-03-16 -================== - - * Added support for "-" prefix in DEBUG [Vinay Pulim] - * Added `.enabled` flag to the node version [TooTallNate] - -0.5.0 / 2012-02-02 -================== - - * Added: humanize diffs. Closes #8 - * Added `debug.disable()` to the CS variant - * Removed padding. Closes #10 - * Fixed: persist client-side variant again. Closes #9 - -0.4.0 / 2012-02-01 -================== - - * Added browser variant support for older browsers [TooTallNate] - * Added `debug.enable('project:*')` to browser variant [TooTallNate] - * Added padding to diff (moved it to the right) - -0.3.0 / 2012-01-26 -================== - - * Added millisecond diff when isatty, otherwise UTC string - -0.2.0 / 2012-01-22 -================== - - * Added wildcard support - -0.1.0 / 2011-12-02 -================== - - * Added: remove colors unless stderr isatty [TooTallNate] - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/Readme.md deleted file mode 100644 index 15ee50193fc..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/Readme.md +++ /dev/null @@ -1,115 +0,0 @@ - -# debug - - tiny node.js debugging utility modelled after node core's debugging technique. - -## Installation - -``` -$ npm install debug -``` - -## Usage - - With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. - -Example _app.js_: - -```js -var debug = require('debug')('http') - , http = require('http') - , name = 'My App'; - -// fake app - -debug('booting %s', name); - -http.createServer(function(req, res){ - debug(req.method + ' ' + req.url); - res.end('hello\n'); -}).listen(3000, function(){ - debug('listening'); -}); - -// fake worker of some kind - -require('./worker'); -``` - -Example _worker.js_: - -```js -var debug = require('debug')('worker'); - -setInterval(function(){ - debug('doing some work'); -}, 1000); -``` - - The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: - - ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) - - ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) - -## Millisecond diff - - When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. - - ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) - - When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: - - ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) - -## Conventions - - If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". - -## Wildcards - - The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. - - You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:". - -## Browser support - - Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. - -```js -a = debug('worker:a'); -b = debug('worker:b'); - -setInterval(function(){ - a('doing some work'); -}, 1000); - -setInterval(function(){ - a('doing some work'); -}, 1200); -``` - -## License - -(The MIT License) - -Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/component.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/component.json deleted file mode 100644 index 4ad09718e3d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/component.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "debug", - "repo": "visionmedia/debug", - "description": "small debugging utility", - "version": "0.7.2", - "keywords": ["debug", "log", "debugger"], - "scripts": ["index.js", "debug.js"], - "dependencies": {} -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/debug.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/debug.js deleted file mode 100644 index e47ba5b0841..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/debug.js +++ /dev/null @@ -1,124 +0,0 @@ - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - if (!debug.enabled(name)) return function(){}; - - return function(fmt){ - var curr = new Date; - var ms = curr - (debug[name] || curr); - debug[name] = curr; - - fmt = name - + ' ' - + fmt - + ' +' + debug.humanize(ms); - - // This hackery is required for IE8 - // where `console.log` doesn't have 'apply' - window.console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); - } -} - -/** - * The currently active debug mode names. - */ - -debug.names = []; -debug.skips = []; - -/** - * Enables a debug mode by name. This can include modes - * separated by a colon and wildcards. - * - * @param {String} name - * @api public - */ - -debug.enable = function(name) { - try { - localStorage.debug = name; - } catch(e){} - - var split = (name || '').split(/[\s,]+/) - , len = split.length; - - for (var i = 0; i < len; i++) { - name = split[i].replace('*', '.*?'); - if (name[0] === '-') { - debug.skips.push(new RegExp('^' + name.substr(1) + '$')); - } - else { - debug.names.push(new RegExp('^' + name + '$')); - } - } -}; - -/** - * Disable debug output. - * - * @api public - */ - -debug.disable = function(){ - debug.enable(''); -}; - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -debug.humanize = function(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -}; - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -debug.enabled = function(name) { - for (var i = 0, len = debug.skips.length; i < len; i++) { - if (debug.skips[i].test(name)) { - return false; - } - } - for (var i = 0, len = debug.names.length; i < len; i++) { - if (debug.names[i].test(name)) { - return true; - } - } - return false; -}; - -// persist - -if (window.localStorage) debug.enable(localStorage.debug); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/app.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/app.js deleted file mode 100644 index 05374d98dd4..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/app.js +++ /dev/null @@ -1,19 +0,0 @@ - -var debug = require('../')('http') - , http = require('http') - , name = 'My App'; - -// fake app - -debug('booting %s', name); - -http.createServer(function(req, res){ - debug(req.method + ' ' + req.url); - res.end('hello\n'); -}).listen(3000, function(){ - debug('listening'); -}); - -// fake worker of some kind - -require('./worker'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/browser.html b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/browser.html deleted file mode 100644 index 7510eee7b4c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/browser.html +++ /dev/null @@ -1,24 +0,0 @@ - - - debug() - - - - - - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/wildcards.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/wildcards.js deleted file mode 100644 index 1fdac20a968..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/wildcards.js +++ /dev/null @@ -1,10 +0,0 @@ - -var debug = { - foo: require('../')('test:foo'), - bar: require('../')('test:bar'), - baz: require('../')('test:baz') -}; - -debug.foo('foo') -debug.bar('bar') -debug.baz('baz') \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/worker.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/worker.js deleted file mode 100644 index 7f6d2886c00..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/example/worker.js +++ /dev/null @@ -1,22 +0,0 @@ - -// DEBUG=* node example/worker -// DEBUG=worker:* node example/worker -// DEBUG=worker:a node example/worker -// DEBUG=worker:b node example/worker - -var a = require('../')('worker:a') - , b = require('../')('worker:b'); - -function work() { - a('doing lots of uninteresting work'); - setTimeout(work, Math.random() * 1000); -} - -work(); - -function workb() { - b('doing some work'); - setTimeout(workb, Math.random() * 2000); -} - -workb(); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/index.js deleted file mode 100644 index e02c13b7f6a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/index.js +++ /dev/null @@ -1,5 +0,0 @@ -if ('undefined' == typeof window) { - module.exports = require('./lib/debug'); -} else { - module.exports = require('./debug'); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/lib/debug.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/lib/debug.js deleted file mode 100644 index 0b07aa1d120..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/lib/debug.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Module dependencies. - */ - -var tty = require('tty'); - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Enabled debuggers. - */ - -var names = [] - , skips = []; - -(process.env.DEBUG || '') - .split(/[\s,]+/) - .forEach(function(name){ - name = name.replace('*', '.*?'); - if (name[0] === '-') { - skips.push(new RegExp('^' + name.substr(1) + '$')); - } else { - names.push(new RegExp('^' + name + '$')); - } - }); - -/** - * Colors. - */ - -var colors = [6, 2, 3, 4, 5, 1]; - -/** - * Previous debug() call. - */ - -var prev = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Is stdout a TTY? Colored output is disabled when `true`. - */ - -var isatty = tty.isatty(2); - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function color() { - return colors[prevColor++ % colors.length]; -} - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -function humanize(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -} - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - function disabled(){} - disabled.enabled = false; - - var match = skips.some(function(re){ - return re.test(name); - }); - - if (match) return disabled; - - match = names.some(function(re){ - return re.test(name); - }); - - if (!match) return disabled; - var c = color(); - - function colored(fmt) { - var curr = new Date; - var ms = curr - (prev[name] || curr); - prev[name] = curr; - - fmt = ' \u001b[9' + c + 'm' + name + ' ' - + '\u001b[3' + c + 'm\u001b[90m' - + fmt + '\u001b[3' + c + 'm' - + ' +' + humanize(ms) + '\u001b[0m'; - - console.error.apply(this, arguments); - } - - function plain(fmt) { - fmt = new Date().toUTCString() - + ' ' + name + ' ' + fmt; - console.error.apply(this, arguments); - } - - colored.enabled = plain.enabled = true; - - return isatty || process.env.DEBUG_COLORS - ? colored - : plain; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/package.json deleted file mode 100644 index 112d22bea19..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/debug/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "debug", - "version": "0.7.2", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/debug.git" - }, - "description": "small debugging utility", - "keywords": [ - "debug", - "log", - "debugger" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "*" - }, - "main": "lib/debug.js", - "browserify": "debug.js", - "engines": { - "node": "*" - }, - "component": { - "scripts": { - "debug/index.js": "index.js", - "debug/debug.js": "debug.js" - } - }, - "readme": "\n# debug\n\n tiny node.js debugging utility modelled after node core's debugging technique.\n\n## Installation\n\n```\n$ npm install debug\n```\n\n## Usage\n\n With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.\n \nExample _app.js_:\n\n```js\nvar debug = require('debug')('http')\n , http = require('http')\n , name = 'My App';\n\n// fake app\n\ndebug('booting %s', name);\n\nhttp.createServer(function(req, res){\n debug(req.method + ' ' + req.url);\n res.end('hello\\n');\n}).listen(3000, function(){\n debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample _worker.js_:\n\n```js\nvar debug = require('debug')('worker');\n\nsetInterval(function(){\n debug('doing some work');\n}, 1000);\n```\n\n The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:\n\n ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)\n\n ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)\n\n## Millisecond diff\n\n When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)\n\n When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:\n \n ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)\n\n## Conventions\n\n If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\". \n\n## Wildcards\n\n The \"*\" character may be used as a wildcard. Suppose for example your library has debuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\n You can also exclude specific debuggers by prefixing them with a \"-\" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with \"connect:\".\n\n## Browser support\n\n Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. \n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n a('doing some work');\n}, 1200);\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/debug/issues" - }, - "_id": "debug@0.7.2", - "_from": "debug@*" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.npmignore deleted file mode 100644 index 4fbabb338d7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -/test/tmp/ -*.upload -*.un~ -*.http diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.travis.yml deleted file mode 100644 index f1d0f13c8a5..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.6 diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Makefile deleted file mode 100644 index 8945872410e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -build: npm test - -npm: - npm install . - -clean: - rm test/tmp/* - -.PHONY: test clean build diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Readme.md deleted file mode 100644 index a5ca104b942..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/Readme.md +++ /dev/null @@ -1,311 +0,0 @@ -# Formidable - -[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable) - -## Purpose - -A node.js module for parsing form data, especially file uploads. - -## Current status - -This module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading -and encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from -a large variety of clients and is considered production-ready. - -## Features - -* Fast (~500mb/sec), non-buffering multipart parser -* Automatically writing file uploads to disk -* Low memory footprint -* Graceful error handling -* Very high test coverage - -## Changelog - -### v1.0.9 - -* Emit progress when content length header parsed (Tim Koschützki) -* Fix Readme syntax due to GitHub changes (goob) -* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara) - -### v1.0.8 - -* Strip potentially unsafe characters when using `keepExtensions: true`. -* Switch to utest / urun for testing -* Add travis build - -### v1.0.7 - -* Remove file from package that was causing problems when installing on windows. (#102) -* Fix typos in Readme (Jason Davies). - -### v1.0.6 - -* Do not default to the default to the field name for file uploads where - filename="". - -### v1.0.5 - -* Support filename="" in multipart parts -* Explain unexpected end() errors in parser better - -**Note:** Starting with this version, formidable emits 'file' events for empty -file input fields. Previously those were incorrectly emitted as regular file -input fields with value = "". - -### v1.0.4 - -* Detect a good default tmp directory regardless of platform. (#88) - -### v1.0.3 - -* Fix problems with utf8 characters (#84) / semicolons in filenames (#58) -* Small performance improvements -* New test suite and fixture system - -### v1.0.2 - -* Exclude node\_modules folder from git -* Implement new `'aborted'` event -* Fix files in example folder to work with recent node versions -* Make gently a devDependency - -[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2) - -### v1.0.1 - -* Fix package.json to refer to proper main directory. (#68, Dean Landolt) - -[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1) - -### v1.0.0 - -* Add support for multipart boundaries that are quoted strings. (Jeff Craig) - -This marks the beginning of development on version 2.0 which will include -several architectural improvements. - -[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0) - -### v0.9.11 - -* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki) -* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class - -**Important:** The old property names of the File class will be removed in a -future release. - -[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11) - -### Older releases - -These releases were done before starting to maintain the above Changelog: - -* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10) -* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9) -* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8) -* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7) -* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6) -* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5) -* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4) -* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3) -* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2) -* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0) - -## Installation - -Via [npm](http://github.com/isaacs/npm): - - npm install formidable@latest - -Manually: - - git clone git://github.com/felixge/node-formidable.git formidable - vim my.js - # var formidable = require('./formidable'); - -Note: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library. - -## Example - -Parse an incoming file upload. - - var formidable = require('formidable'), - http = require('http'), - - util = require('util'); - - http.createServer(function(req, res) { - if (req.url == '/upload' && req.method.toLowerCase() == 'post') { - // parse a file upload - var form = new formidable.IncomingForm(); - form.parse(req, function(err, fields, files) { - res.writeHead(200, {'content-type': 'text/plain'}); - res.write('received upload:\n\n'); - res.end(util.inspect({fields: fields, files: files})); - }); - return; - } - - // show a file upload form - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - }).listen(80); - -## API - -### formidable.IncomingForm - -__new formidable.IncomingForm()__ - -Creates a new incoming form. - -__incomingForm.encoding = 'utf-8'__ - -The encoding to use for incoming form fields. - -__incomingForm.uploadDir = process.env.TMP || '/tmp' || process.cwd()__ - -The directory for placing file uploads in. You can move them later on using -`fs.rename()`. The default directory is picked at module load time depending on -the first existing directory from those listed above. - -__incomingForm.keepExtensions = false__ - -If you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`. - -__incomingForm.type__ - -Either 'multipart' or 'urlencoded' depending on the incoming request. - -__incomingForm.maxFieldsSize = 2 * 1024 * 1024__ - -Limits the amount of memory a field (not file) can allocate in bytes. -If this value is exceeded, an `'error'` event is emitted. The default -size is 2MB. - -__incomingForm.hash = false__ - -If you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`. - -__incomingForm.bytesReceived__ - -The amount of bytes received for this form so far. - -__incomingForm.bytesExpected__ - -The expected number of bytes in this form. - -__incomingForm.parse(request, [cb])__ - -Parses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback: - - incomingForm.parse(req, function(err, fields, files) { - // ... - }); - -__incomingForm.onPart(part)__ - -You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing. - - incomingForm.onPart = function(part) { - part.addListener('data', function() { - // ... - }); - } - -If you want to use formidable to only handle certain parts for you, you can do so: - - incomingForm.onPart = function(part) { - if (!part.filename) { - // let formidable handle all non-file parts - incomingForm.handlePart(part); - } - } - -Check the code in this method for further inspiration. - -__Event: 'progress' (bytesReceived, bytesExpected)__ - -Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar. - -__Event: 'field' (name, value)__ - -Emitted whenever a field / value pair has been received. - -__Event: 'fileBegin' (name, file)__ - -Emitted whenever a new file is detected in the upload stream. Use this even if -you want to stream the file to somewhere else while buffering the upload on -the file system. - -__Event: 'file' (name, file)__ - -Emitted whenever a field / file pair has been received. `file` is an instance of `File`. - -__Event: 'error' (err)__ - -Emitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events. - -__Event: 'aborted'__ - -Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core). - -__Event: 'end' ()__ - -Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response. - -### formidable.File - -__file.size = 0__ - -The size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet. - -__file.path = null__ - -The path this file is being written to. You can modify this in the `'fileBegin'` event in -case you are unhappy with the way formidable generates a temporary path for your files. - -__file.name = null__ - -The name this file had according to the uploading client. - -__file.type = null__ - -The mime type of this file, according to the uploading client. - -__file.lastModifiedDate = null__ - -A date object (or `null`) containing the time this file was last written to. Mostly -here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/). - -__file.hash = null__ - -If hash calculation was set, you can read the hex digest out of this var. - -## License - -Formidable is licensed under the MIT license. - -## Ports - -* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable - -## Credits - -* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/TODO b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/TODO deleted file mode 100644 index e1107f2a55f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- Better bufferMaxSize handling approach -- Add tests for JSON parser pull request and merge it -- Implement QuerystringParser the same way as MultipartParser diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js deleted file mode 100644 index bff41f15c69..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js +++ /dev/null @@ -1,70 +0,0 @@ -require('../test/common'); -var multipartParser = require('../lib/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - parser = new MultipartParser(), - Buffer = require('buffer').Buffer, - boundary = '-----------------------------168072824752491622650073', - mb = 100, - buffer = createMultipartBuffer(boundary, mb * 1024 * 1024), - callbacks = - { partBegin: -1, - partEnd: -1, - headerField: -1, - headerValue: -1, - partData: -1, - end: -1, - }; - - -parser.initWithBoundary(boundary); -parser.onHeaderField = function() { - callbacks.headerField++; -}; - -parser.onHeaderValue = function() { - callbacks.headerValue++; -}; - -parser.onPartBegin = function() { - callbacks.partBegin++; -}; - -parser.onPartData = function() { - callbacks.partData++; -}; - -parser.onPartEnd = function() { - callbacks.partEnd++; -}; - -parser.onEnd = function() { - callbacks.end++; -}; - -var start = +new Date(), - nparsed = parser.write(buffer), - duration = +new Date - start, - mbPerSec = (mb / (duration / 1000)).toFixed(2); - -console.log(mbPerSec+' mb/sec'); - -assert.equal(nparsed, buffer.length); - -function createMultipartBuffer(boundary, size) { - var head = - '--'+boundary+'\r\n' - + 'content-disposition: form-data; name="field1"\r\n' - + '\r\n' - , tail = '\r\n--'+boundary+'--\r\n' - , buffer = new Buffer(size); - - buffer.write(head, 'ascii', 0); - buffer.write(tail, 'ascii', buffer.length - tail.length); - return buffer; -} - -process.on('exit', function() { - for (var k in callbacks) { - assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]); - } -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/post.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/post.js deleted file mode 100644 index f6c15a64c68..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/post.js +++ /dev/null @@ -1,43 +0,0 @@ -require('../test/common'); -var http = require('http'), - util = require('util'), - formidable = require('formidable'), - server; - -server = http.createServer(function(req, res) { - if (req.url == '/') { - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - } else if (req.url == '/post') { - var form = new formidable.IncomingForm(), - fields = []; - - form - .on('error', function(err) { - res.writeHead(200, {'content-type': 'text/plain'}); - res.end('error:\n\n'+util.inspect(err)); - }) - .on('field', function(field, value) { - console.log(field, value); - fields.push([field, value]); - }) - .on('end', function() { - console.log('-> post done'); - res.writeHead(200, {'content-type': 'text/plain'}); - res.end('received fields:\n\n '+util.inspect(fields)); - }); - form.parse(req); - } else { - res.writeHead(404, {'content-type': 'text/plain'}); - res.end('404'); - } -}); -server.listen(TEST_PORT); - -console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/upload.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/upload.js deleted file mode 100644 index 050cdd9de54..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/example/upload.js +++ /dev/null @@ -1,48 +0,0 @@ -require('../test/common'); -var http = require('http'), - util = require('util'), - formidable = require('formidable'), - server; - -server = http.createServer(function(req, res) { - if (req.url == '/') { - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - } else if (req.url == '/upload') { - var form = new formidable.IncomingForm(), - files = [], - fields = []; - - form.uploadDir = TEST_TMP; - - form - .on('field', function(field, value) { - console.log(field, value); - fields.push([field, value]); - }) - .on('file', function(field, file) { - console.log(field, file); - files.push([field, file]); - }) - .on('end', function() { - console.log('-> upload done'); - res.writeHead(200, {'content-type': 'text/plain'}); - res.write('received fields:\n\n '+util.inspect(fields)); - res.write('\n\n'); - res.end('received files:\n\n '+util.inspect(files)); - }); - form.parse(req); - } else { - res.writeHead(404, {'content-type': 'text/plain'}); - res.end('404'); - } -}); -server.listen(TEST_PORT); - -console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/index.js deleted file mode 100644 index be4103252c8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/formidable'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/file.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/file.js deleted file mode 100644 index dad8d5f7193..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/file.js +++ /dev/null @@ -1,73 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -var util = require('./util'), - WriteStream = require('fs').WriteStream, - EventEmitter = require('events').EventEmitter, - crypto = require('crypto'); - -function File(properties) { - EventEmitter.call(this); - - this.size = 0; - this.path = null; - this.name = null; - this.type = null; - this.hash = null; - this.lastModifiedDate = null; - - this._writeStream = null; - - for (var key in properties) { - this[key] = properties[key]; - } - - if(typeof this.hash === 'string') { - this.hash = crypto.createHash(properties.hash); - } - - this._backwardsCompatibility(); -} -module.exports = File; -util.inherits(File, EventEmitter); - -// @todo Next release: Show error messages when accessing these -File.prototype._backwardsCompatibility = function() { - var self = this; - this.__defineGetter__('length', function() { - return self.size; - }); - this.__defineGetter__('filename', function() { - return self.name; - }); - this.__defineGetter__('mime', function() { - return self.type; - }); -}; - -File.prototype.open = function() { - this._writeStream = new WriteStream(this.path); -}; - -File.prototype.write = function(buffer, cb) { - var self = this; - this._writeStream.write(buffer, function() { - if(self.hash) { - self.hash.update(buffer); - } - self.lastModifiedDate = new Date(); - self.size += buffer.length; - self.emit('progress', self.size); - cb(); - }); -}; - -File.prototype.end = function(cb) { - var self = this; - this._writeStream.end(function() { - if(self.hash) { - self.hash = self.hash.digest('hex'); - } - self.emit('end'); - cb(); - }); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/incoming_form.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/incoming_form.js deleted file mode 100644 index 060eac29e59..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/incoming_form.js +++ /dev/null @@ -1,384 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -var fs = require('fs'); -var util = require('./util'), - path = require('path'), - File = require('./file'), - MultipartParser = require('./multipart_parser').MultipartParser, - QuerystringParser = require('./querystring_parser').QuerystringParser, - StringDecoder = require('string_decoder').StringDecoder, - EventEmitter = require('events').EventEmitter, - Stream = require('stream').Stream; - -function IncomingForm(opts) { - if (!(this instanceof IncomingForm)) return new IncomingForm; - EventEmitter.call(this); - - opts=opts||{}; - - this.error = null; - this.ended = false; - - this.maxFieldsSize = opts.maxFieldsSize || 2 * 1024 * 1024; - this.keepExtensions = opts.keepExtensions || false; - this.uploadDir = opts.uploadDir || IncomingForm.UPLOAD_DIR; - this.encoding = opts.encoding || 'utf-8'; - this.headers = null; - this.type = null; - this.hash = false; - - this.bytesReceived = null; - this.bytesExpected = null; - - this._parser = null; - this._flushing = 0; - this._fieldsSize = 0; -}; -util.inherits(IncomingForm, EventEmitter); -exports.IncomingForm = IncomingForm; - -IncomingForm.UPLOAD_DIR = (function() { - var dirs = [process.env.TMP, '/tmp', process.cwd()]; - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; - var isDirectory = false; - - try { - isDirectory = fs.statSync(dir).isDirectory(); - } catch (e) {} - - if (isDirectory) return dir; - } -})(); - -IncomingForm.prototype.parse = function(req, cb) { - this.pause = function() { - try { - req.pause(); - } catch (err) { - // the stream was destroyed - if (!this.ended) { - // before it was completed, crash & burn - this._error(err); - } - return false; - } - return true; - }; - - this.resume = function() { - try { - req.resume(); - } catch (err) { - // the stream was destroyed - if (!this.ended) { - // before it was completed, crash & burn - this._error(err); - } - return false; - } - - return true; - }; - - this.writeHeaders(req.headers); - - var self = this; - req - .on('error', function(err) { - self._error(err); - }) - .on('aborted', function() { - self.emit('aborted'); - }) - .on('data', function(buffer) { - self.write(buffer); - }) - .on('end', function() { - if (self.error) { - return; - } - - var err = self._parser.end(); - if (err) { - self._error(err); - } - }); - - if (cb) { - var fields = {}, files = {}; - this - .on('field', function(name, value) { - fields[name] = value; - }) - .on('file', function(name, file) { - files[name] = file; - }) - .on('error', function(err) { - cb(err, fields, files); - }) - .on('end', function() { - cb(null, fields, files); - }); - } - - return this; -}; - -IncomingForm.prototype.writeHeaders = function(headers) { - this.headers = headers; - this._parseContentLength(); - this._parseContentType(); -}; - -IncomingForm.prototype.write = function(buffer) { - if (!this._parser) { - this._error(new Error('unintialized parser')); - return; - } - - this.bytesReceived += buffer.length; - this.emit('progress', this.bytesReceived, this.bytesExpected); - - var bytesParsed = this._parser.write(buffer); - if (bytesParsed !== buffer.length) { - this._error(new Error('parser error, '+bytesParsed+' of '+buffer.length+' bytes parsed')); - } - - return bytesParsed; -}; - -IncomingForm.prototype.pause = function() { - // this does nothing, unless overwritten in IncomingForm.parse - return false; -}; - -IncomingForm.prototype.resume = function() { - // this does nothing, unless overwritten in IncomingForm.parse - return false; -}; - -IncomingForm.prototype.onPart = function(part) { - // this method can be overwritten by the user - this.handlePart(part); -}; - -IncomingForm.prototype.handlePart = function(part) { - var self = this; - - if (part.filename === undefined) { - var value = '' - , decoder = new StringDecoder(this.encoding); - - part.on('data', function(buffer) { - self._fieldsSize += buffer.length; - if (self._fieldsSize > self.maxFieldsSize) { - self._error(new Error('maxFieldsSize exceeded, received '+self._fieldsSize+' bytes of field data')); - return; - } - value += decoder.write(buffer); - }); - - part.on('end', function() { - self.emit('field', part.name, value); - }); - return; - } - - this._flushing++; - - var file = new File({ - path: this._uploadPath(part.filename), - name: part.filename, - type: part.mime, - hash: self.hash - }); - - this.emit('fileBegin', part.name, file); - - file.open(); - - part.on('data', function(buffer) { - self.pause(); - file.write(buffer, function() { - self.resume(); - }); - }); - - part.on('end', function() { - file.end(function() { - self._flushing--; - self.emit('file', part.name, file); - self._maybeEnd(); - }); - }); -}; - -IncomingForm.prototype._parseContentType = function() { - if (!this.headers['content-type']) { - this._error(new Error('bad content-type header, no content-type')); - return; - } - - if (this.headers['content-type'].match(/urlencoded/i)) { - this._initUrlencoded(); - return; - } - - if (this.headers['content-type'].match(/multipart/i)) { - var m; - if (m = this.headers['content-type'].match(/boundary=(?:"([^"]+)"|([^;]+))/i)) { - this._initMultipart(m[1] || m[2]); - } else { - this._error(new Error('bad content-type header, no multipart boundary')); - } - return; - } - - this._error(new Error('bad content-type header, unknown content-type: '+this.headers['content-type'])); -}; - -IncomingForm.prototype._error = function(err) { - if (this.error) { - return; - } - - this.error = err; - this.pause(); - this.emit('error', err); -}; - -IncomingForm.prototype._parseContentLength = function() { - if (this.headers['content-length']) { - this.bytesReceived = 0; - this.bytesExpected = parseInt(this.headers['content-length'], 10); - this.emit('progress', this.bytesReceived, this.bytesExpected); - } -}; - -IncomingForm.prototype._newParser = function() { - return new MultipartParser(); -}; - -IncomingForm.prototype._initMultipart = function(boundary) { - this.type = 'multipart'; - - var parser = new MultipartParser(), - self = this, - headerField, - headerValue, - part; - - parser.initWithBoundary(boundary); - - parser.onPartBegin = function() { - part = new Stream(); - part.readable = true; - part.headers = {}; - part.name = null; - part.filename = null; - part.mime = null; - headerField = ''; - headerValue = ''; - }; - - parser.onHeaderField = function(b, start, end) { - headerField += b.toString(self.encoding, start, end); - }; - - parser.onHeaderValue = function(b, start, end) { - headerValue += b.toString(self.encoding, start, end); - }; - - parser.onHeaderEnd = function() { - headerField = headerField.toLowerCase(); - part.headers[headerField] = headerValue; - - var m; - if (headerField == 'content-disposition') { - if (m = headerValue.match(/name="([^"]+)"/i)) { - part.name = m[1]; - } - - part.filename = self._fileName(headerValue); - } else if (headerField == 'content-type') { - part.mime = headerValue; - } - - headerField = ''; - headerValue = ''; - }; - - parser.onHeadersEnd = function() { - self.onPart(part); - }; - - parser.onPartData = function(b, start, end) { - part.emit('data', b.slice(start, end)); - }; - - parser.onPartEnd = function() { - part.emit('end'); - }; - - parser.onEnd = function() { - self.ended = true; - self._maybeEnd(); - }; - - this._parser = parser; -}; - -IncomingForm.prototype._fileName = function(headerValue) { - var m = headerValue.match(/filename="(.*?)"($|; )/i) - if (!m) return; - - var filename = m[1].substr(m[1].lastIndexOf('\\') + 1); - filename = filename.replace(/%22/g, '"'); - filename = filename.replace(/&#([\d]{4});/g, function(m, code) { - return String.fromCharCode(code); - }); - return filename; -}; - -IncomingForm.prototype._initUrlencoded = function() { - this.type = 'urlencoded'; - - var parser = new QuerystringParser() - , self = this; - - parser.onField = function(key, val) { - self.emit('field', key, val); - }; - - parser.onEnd = function() { - self.ended = true; - self._maybeEnd(); - }; - - this._parser = parser; -}; - -IncomingForm.prototype._uploadPath = function(filename) { - var name = ''; - for (var i = 0; i < 32; i++) { - name += Math.floor(Math.random() * 16).toString(16); - } - - if (this.keepExtensions) { - var ext = path.extname(filename); - ext = ext.replace(/(\.[a-z0-9]+).*/, '$1') - - name += ext; - } - - return path.join(this.uploadDir, name); -}; - -IncomingForm.prototype._maybeEnd = function() { - if (!this.ended || this._flushing) { - return; - } - - this.emit('end'); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/index.js deleted file mode 100644 index 7a6e3e1097c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/index.js +++ /dev/null @@ -1,3 +0,0 @@ -var IncomingForm = require('./incoming_form').IncomingForm; -IncomingForm.IncomingForm = IncomingForm; -module.exports = IncomingForm; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/multipart_parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/multipart_parser.js deleted file mode 100644 index 9ca567cd4fe..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/multipart_parser.js +++ /dev/null @@ -1,312 +0,0 @@ -var Buffer = require('buffer').Buffer, - s = 0, - S = - { PARSER_UNINITIALIZED: s++, - START: s++, - START_BOUNDARY: s++, - HEADER_FIELD_START: s++, - HEADER_FIELD: s++, - HEADER_VALUE_START: s++, - HEADER_VALUE: s++, - HEADER_VALUE_ALMOST_DONE: s++, - HEADERS_ALMOST_DONE: s++, - PART_DATA_START: s++, - PART_DATA: s++, - PART_END: s++, - END: s++, - }, - - f = 1, - F = - { PART_BOUNDARY: f, - LAST_BOUNDARY: f *= 2, - }, - - LF = 10, - CR = 13, - SPACE = 32, - HYPHEN = 45, - COLON = 58, - A = 97, - Z = 122, - - lower = function(c) { - return c | 0x20; - }; - -for (var s in S) { - exports[s] = S[s]; -} - -function MultipartParser() { - this.boundary = null; - this.boundaryChars = null; - this.lookbehind = null; - this.state = S.PARSER_UNINITIALIZED; - - this.index = null; - this.flags = 0; -}; -exports.MultipartParser = MultipartParser; - -MultipartParser.stateToString = function(stateNumber) { - for (var state in S) { - var number = S[state]; - if (number === stateNumber) return state; - } -}; - -MultipartParser.prototype.initWithBoundary = function(str) { - this.boundary = new Buffer(str.length+4); - this.boundary.write('\r\n--', 'ascii', 0); - this.boundary.write(str, 'ascii', 4); - this.lookbehind = new Buffer(this.boundary.length+8); - this.state = S.START; - - this.boundaryChars = {}; - for (var i = 0; i < this.boundary.length; i++) { - this.boundaryChars[this.boundary[i]] = true; - } -}; - -MultipartParser.prototype.write = function(buffer) { - var self = this, - i = 0, - len = buffer.length, - prevIndex = this.index, - index = this.index, - state = this.state, - flags = this.flags, - lookbehind = this.lookbehind, - boundary = this.boundary, - boundaryChars = this.boundaryChars, - boundaryLength = this.boundary.length, - boundaryEnd = boundaryLength - 1, - bufferLength = buffer.length, - c, - cl, - - mark = function(name) { - self[name+'Mark'] = i; - }, - clear = function(name) { - delete self[name+'Mark']; - }, - callback = function(name, buffer, start, end) { - if (start !== undefined && start === end) { - return; - } - - var callbackSymbol = 'on'+name.substr(0, 1).toUpperCase()+name.substr(1); - if (callbackSymbol in self) { - self[callbackSymbol](buffer, start, end); - } - }, - dataCallback = function(name, clear) { - var markSymbol = name+'Mark'; - if (!(markSymbol in self)) { - return; - } - - if (!clear) { - callback(name, buffer, self[markSymbol], buffer.length); - self[markSymbol] = 0; - } else { - callback(name, buffer, self[markSymbol], i); - delete self[markSymbol]; - } - }; - - for (i = 0; i < len; i++) { - c = buffer[i]; - switch (state) { - case S.PARSER_UNINITIALIZED: - return i; - case S.START: - index = 0; - state = S.START_BOUNDARY; - case S.START_BOUNDARY: - if (index == boundary.length - 2) { - if (c != CR) { - return i; - } - index++; - break; - } else if (index - 1 == boundary.length - 2) { - if (c != LF) { - return i; - } - index = 0; - callback('partBegin'); - state = S.HEADER_FIELD_START; - break; - } - - if (c != boundary[index+2]) { - return i; - } - index++; - break; - case S.HEADER_FIELD_START: - state = S.HEADER_FIELD; - mark('headerField'); - index = 0; - case S.HEADER_FIELD: - if (c == CR) { - clear('headerField'); - state = S.HEADERS_ALMOST_DONE; - break; - } - - index++; - if (c == HYPHEN) { - break; - } - - if (c == COLON) { - if (index == 1) { - // empty header field - return i; - } - dataCallback('headerField', true); - state = S.HEADER_VALUE_START; - break; - } - - cl = lower(c); - if (cl < A || cl > Z) { - return i; - } - break; - case S.HEADER_VALUE_START: - if (c == SPACE) { - break; - } - - mark('headerValue'); - state = S.HEADER_VALUE; - case S.HEADER_VALUE: - if (c == CR) { - dataCallback('headerValue', true); - callback('headerEnd'); - state = S.HEADER_VALUE_ALMOST_DONE; - } - break; - case S.HEADER_VALUE_ALMOST_DONE: - if (c != LF) { - return i; - } - state = S.HEADER_FIELD_START; - break; - case S.HEADERS_ALMOST_DONE: - if (c != LF) { - return i; - } - - callback('headersEnd'); - state = S.PART_DATA_START; - break; - case S.PART_DATA_START: - state = S.PART_DATA - mark('partData'); - case S.PART_DATA: - prevIndex = index; - - if (index == 0) { - // boyer-moore derrived algorithm to safely skip non-boundary data - i += boundaryEnd; - while (i < bufferLength && !(buffer[i] in boundaryChars)) { - i += boundaryLength; - } - i -= boundaryEnd; - c = buffer[i]; - } - - if (index < boundary.length) { - if (boundary[index] == c) { - if (index == 0) { - dataCallback('partData', true); - } - index++; - } else { - index = 0; - } - } else if (index == boundary.length) { - index++; - if (c == CR) { - // CR = part boundary - flags |= F.PART_BOUNDARY; - } else if (c == HYPHEN) { - // HYPHEN = end boundary - flags |= F.LAST_BOUNDARY; - } else { - index = 0; - } - } else if (index - 1 == boundary.length) { - if (flags & F.PART_BOUNDARY) { - index = 0; - if (c == LF) { - // unset the PART_BOUNDARY flag - flags &= ~F.PART_BOUNDARY; - callback('partEnd'); - callback('partBegin'); - state = S.HEADER_FIELD_START; - break; - } - } else if (flags & F.LAST_BOUNDARY) { - if (c == HYPHEN) { - callback('partEnd'); - callback('end'); - state = S.END; - } else { - index = 0; - } - } else { - index = 0; - } - } - - if (index > 0) { - // when matching a possible boundary, keep a lookbehind reference - // in case it turns out to be a false lead - lookbehind[index-1] = c; - } else if (prevIndex > 0) { - // if our boundary turned out to be rubbish, the captured lookbehind - // belongs to partData - callback('partData', lookbehind, 0, prevIndex); - prevIndex = 0; - mark('partData'); - - // reconsider the current character even so it interrupted the sequence - // it could be the beginning of a new sequence - i--; - } - - break; - case S.END: - break; - default: - return i; - } - } - - dataCallback('headerField'); - dataCallback('headerValue'); - dataCallback('partData'); - - this.index = index; - this.state = state; - this.flags = flags; - - return len; -}; - -MultipartParser.prototype.end = function() { - if (this.state != S.END) { - return new Error('MultipartParser.end(): stream ended unexpectedly: ' + this.explain()); - } -}; - -MultipartParser.prototype.explain = function() { - return 'state = ' + MultipartParser.stateToString(this.state); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/querystring_parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/querystring_parser.js deleted file mode 100644 index 63f109ec7cb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/querystring_parser.js +++ /dev/null @@ -1,25 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -// This is a buffering parser, not quite as nice as the multipart one. -// If I find time I'll rewrite this to be fully streaming as well -var querystring = require('querystring'); - -function QuerystringParser() { - this.buffer = ''; -}; -exports.QuerystringParser = QuerystringParser; - -QuerystringParser.prototype.write = function(buffer) { - this.buffer += buffer.toString('ascii'); - return buffer.length; -}; - -QuerystringParser.prototype.end = function() { - var fields = querystring.parse(this.buffer); - for (var field in fields) { - this.onField(field, fields[field]); - } - this.buffer = ''; - - this.onEnd(); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/util.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/util.js deleted file mode 100644 index e9493e9baf3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/lib/util.js +++ /dev/null @@ -1,6 +0,0 @@ -// Backwards compatibility ... -try { - module.exports = require('util'); -} catch (e) { - module.exports = require('sys'); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Makefile deleted file mode 100644 index 01f71404f0d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -test: - @find test/simple/test-*.js | xargs -n 1 -t node - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Readme.md deleted file mode 100644 index f8f0c664968..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/Readme.md +++ /dev/null @@ -1,167 +0,0 @@ -# Gently - -## Purpose - -A node.js module that helps with stubbing and behavior verification. It allows you to test the most remote and nested corners of your code while keeping being fully unobtrusive. - -## Features - -* Overwrite and stub individual object functions -* Verify that all expected calls have been made in the expected order -* Restore stubbed functions to their original behavior -* Detect object / class names from obj.constructor.name and obj.toString() -* Hijack any required module function or class constructor - -## Installation - -Via [npm](http://github.com/isaacs/npm): - - npm install gently@latest - -## Example - -Make sure your dog is working properly: - - function Dog() {} - - Dog.prototype.seeCat = function() { - this.bark('whuf, whuf'); - this.run(); - } - - Dog.prototype.bark = function(bark) { - require('sys').puts(bark); - } - - var gently = new (require('gently')) - , assert = require('assert') - , dog = new Dog(); - - gently.expect(dog, 'bark', function(bark) { - assert.equal(bark, 'whuf, whuf'); - }); - gently.expect(dog, 'run'); - - dog.seeCat(); - -You can also easily test event emitters with this, for example a simple sequence of 2 events emitted by `fs.WriteStream`: - - var gently = new (require('gently')) - , stream = new (require('fs').WriteStream)('my_file.txt'); - - gently.expect(stream, 'emit', function(event) { - assert.equal(event, 'open'); - }); - - gently.expect(stream, 'emit', function(event) { - assert.equal(event, 'drain'); - }); - -For a full read world example, check out this test case: [test-incoming-form.js](http://github.com/felixge/node-formidable/blob/master/test/simple/test-incoming-form.js) (in [node-formdiable](http://github.com/felixge/node-formidable)). - -## API - -### Gently - -#### new Gently() - -Creates a new gently instance. It listens to the process `'exit'` event to make sure all expectations have been verified. - -#### gently.expect(obj, method, [[count], stubFn]) - -Creates an expectation for an objects method to be called. You can optionally specify the call `count` you are expecting, as well as `stubFn` function that will run instead of the original function. - -Returns a reference to the function that is getting overwritten. - -#### gently.expect([count], stubFn) - -Returns a function that is supposed to be executed `count` times, delegating any calls to the provided `stubFn` function. Naming your stubFn closure will help to properly diagnose errors that are being thrown: - - childProcess.exec('ls', gently.expect(function lsCallback(code) { - assert.equal(0, code); - })); - -#### gently.restore(obj, method) - -Restores an object method that has been previously overwritten using `gently.expect()`. - -#### gently.hijack(realRequire) - -Returns a new require functions that catches a reference to all required modules into `gently.hijacked`. - -To use this function, include a line like this in your `'my-module.js'`. - - if (global.GENTLY) require = GENTLY.hijack(require); - - var sys = require('sys'); - exports.hello = function() { - sys.log('world'); - }; - -Now you can write a test for the module above: - - var gently = global.GENTLY = new (require('gently')) - , myModule = require('./my-module'); - - gently.expect(gently.hijacked.sys, 'log', function(str) { - assert.equal(str, 'world'); - }); - - myModule.hello(); - -#### gently.stub(location, [exportsName]) - -Returns a stub class that will be used instead of the real class from the module at `location` with the given `exportsName`. - -This allows to test an OOP version of the previous example, where `'my-module.js'`. - - if (global.GENTLY) require = GENTLY.hijack(require); - - var World = require('./world'); - - exports.hello = function() { - var world = new World(); - world.hello(); - } - -And `world.js` looks like this: - - var sys = require('sys'); - - function World() { - - } - module.exports = World; - - World.prototype.hello = function() { - sys.log('world'); - }; - -Testing `'my-module.js'` can now easily be accomplished: - - var gently = global.GENTLY = new (require('gently')) - , WorldStub = gently.stub('./world') - , myModule = require('./my-module') - , WORLD; - - gently.expect(WorldStub, 'new', function() { - WORLD = this; - }); - - gently.expect(WORLD, 'hello'); - - myModule.hello(); - -#### gently.hijacked - -An object that holds the references to all hijacked modules. - -#### gently.verify([msg]) - -Verifies that all expectations of this gently instance have been satisfied. If not called manually, this method is called when the process `'exit'` event is fired. - -If `msg` is given, it will appear in any error that might be thrown. - -## License - -Gently is licensed under the MIT license. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/dog.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/dog.js deleted file mode 100644 index 022fae0c233..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/dog.js +++ /dev/null @@ -1,22 +0,0 @@ -require('../test/common'); -function Dog() {} - -Dog.prototype.seeCat = function() { - this.bark('whuf, whuf'); - this.run(); -} - -Dog.prototype.bark = function(bark) { - require('sys').puts(bark); -} - -var gently = new (require('gently')) - , assert = require('assert') - , dog = new Dog(); - -gently.expect(dog, 'bark', function(bark) { - assert.equal(bark, 'whuf, whuf'); -}); -gently.expect(dog, 'run'); - -dog.seeCat(); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/event_emitter.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/event_emitter.js deleted file mode 100644 index 7def134fd36..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/example/event_emitter.js +++ /dev/null @@ -1,11 +0,0 @@ -require('../test/common'); -var gently = new (require('gently')) - , stream = new (require('fs').WriteStream)('my_file.txt'); - -gently.expect(stream, 'emit', function(event) { - assert.equal(event, 'open'); -}); - -gently.expect(stream, 'emit', function(event) { - assert.equal(event, 'drain'); -}); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/index.js deleted file mode 100644 index 69122bdb863..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/gently'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/gently.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/gently.js deleted file mode 100644 index 8af0e1ec164..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/gently.js +++ /dev/null @@ -1,184 +0,0 @@ -var path = require('path'); - -function Gently() { - this.expectations = []; - this.hijacked = {}; - - var self = this; - process.addListener('exit', function() { - self.verify('process exit'); - }); -}; -module.exports = Gently; - -Gently.prototype.stub = function(location, exportsName) { - function Stub() { - return Stub['new'].apply(this, arguments); - }; - - Stub['new'] = function () {}; - - var stubName = 'require('+JSON.stringify(location)+')'; - if (exportsName) { - stubName += '.'+exportsName; - } - - Stub.prototype.toString = Stub.toString = function() { - return stubName; - }; - - var exports = this.hijacked[location] || {}; - if (exportsName) { - exports[exportsName] = Stub; - } else { - exports = Stub; - } - - this.hijacked[location] = exports; - return Stub; -}; - -Gently.prototype.hijack = function(realRequire) { - var self = this; - return function(location) { - return self.hijacked[location] = (self.hijacked[location]) - ? self.hijacked[location] - : realRequire(location); - }; -}; - -Gently.prototype.expect = function(obj, method, count, stubFn) { - if (typeof obj != 'function' && typeof obj != 'object' && typeof obj != 'number') { - throw new Error - ( 'Bad 1st argument for gently.expect(), ' - + 'object, function, or number expected, got: '+(typeof obj) - ); - } else if (typeof obj == 'function' && (typeof method != 'string')) { - // expect(stubFn) interface - stubFn = obj; - obj = null; - method = null; - count = 1; - } else if (typeof method == 'function') { - // expect(count, stubFn) interface - count = obj; - stubFn = method; - obj = null; - method = null; - } else if (typeof count == 'function') { - // expect(obj, method, stubFn) interface - stubFn = count; - count = 1; - } else if (count === undefined) { - // expect(obj, method) interface - count = 1; - } - - var name = this._name(obj, method, stubFn); - this.expectations.push({obj: obj, method: method, stubFn: stubFn, name: name, count: count}); - - var self = this; - function delegate() { - return self._stubFn(this, obj, method, name, Array.prototype.slice.call(arguments)); - } - - if (!obj) { - return delegate; - } - - var original = (obj[method]) - ? obj[method]._original || obj[method] - : undefined; - - obj[method] = delegate; - return obj[method]._original = original; -}; - -Gently.prototype.restore = function(obj, method) { - if (!obj[method] || !obj[method]._original) { - throw new Error(this._name(obj, method)+' is not gently stubbed'); - } - obj[method] = obj[method]._original; -}; - -Gently.prototype.verify = function(msg) { - if (!this.expectations.length) { - return; - } - - var validExpectations = []; - for (var i = 0, l = this.expectations.length; i < l; i++) { - var expectation = this.expectations[i]; - - if (expectation.count > 0) { - validExpectations.push(expectation); - } - } - - this.expectations = []; // reset so that no duplicate verification attempts are made - - if (!validExpectations.length) { - return; - } - - var expectation = validExpectations[0]; - - throw new Error - ( 'Expected call to '+expectation.name+' did not happen' - + ( (msg) - ? ' ('+msg+')' - : '' - ) - ); -}; - -Gently.prototype._stubFn = function(self, obj, method, name, args) { - var expectation = this.expectations[0], obj, method; - - if (!expectation) { - throw new Error('Unexpected call to '+name+', no call was expected'); - } - - if (expectation.obj !== obj || expectation.method !== method) { - throw new Error('Unexpected call to '+name+', expected call to '+ expectation.name); - } - - expectation.count -= 1; - if (expectation.count === 0) { - this.expectations.shift(); - - // autorestore original if its not a closure - // and no more expectations on that object - var has_more_expectations = this.expectations.reduce(function (memo, expectation) { - return memo || (expectation.obj === obj && expectation.method === method); - }, false); - if (obj !== null && method !== null && !has_more_expectations) { - if (typeof obj[method]._original !== 'undefined') { - obj[method] = obj[method]._original; - delete obj[method]._original; - } else { - delete obj[method]; - } - } - } - - if (expectation.stubFn) { - return expectation.stubFn.apply(self, args); - } -}; - -Gently.prototype._name = function(obj, method, stubFn) { - if (obj) { - var objectName = obj.toString(); - if (objectName == '[object Object]' && obj.constructor.name) { - objectName = '['+obj.constructor.name+']'; - } - return (objectName)+'.'+method+'()'; - } - - if (stubFn.name) { - return stubFn.name+'()'; - } - - return '>> '+stubFn.toString()+' <<'; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/index.js deleted file mode 100644 index 64c1977b2df..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/lib/gently/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./gently'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/package.json deleted file mode 100644 index 9c1b7a00a59..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "gently", - "version": "0.9.2", - "directories": { - "lib": "./lib/gently" - }, - "main": "./lib/gently/index", - "dependencies": {}, - "devDependencies": {}, - "engines": { - "node": "*" - }, - "optionalDependencies": {} -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/common.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/common.js deleted file mode 100644 index 978b5c5367b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/common.js +++ /dev/null @@ -1,8 +0,0 @@ -var path = require('path') - , sys = require('sys'); - -require.paths.unshift(path.dirname(__dirname)+'/lib'); - -global.puts = sys.puts; -global.p = function() {sys.error(sys.inspect.apply(null, arguments))};; -global.assert = require('assert'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/simple/test-gently.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/simple/test-gently.js deleted file mode 100644 index 4f8fe2ddd7e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/node-gently/test/simple/test-gently.js +++ /dev/null @@ -1,348 +0,0 @@ -require('../common'); -var Gently = require('gently') - , gently; - -function test(test) { - process.removeAllListeners('exit'); - gently = new Gently(); - test(); -} - -test(function constructor() { - assert.deepEqual(gently.expectations, []); - assert.deepEqual(gently.hijacked, {}); - assert.equal(gently.constructor.name, 'Gently'); -}); - -test(function expectBadArgs() { - var BAD_ARG = 'oh no'; - try { - gently.expect(BAD_ARG); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, 'Bad 1st argument for gently.expect(), object, function, or number expected, got: '+(typeof BAD_ARG)); - } -}); - -test(function expectObjMethod() { - var OBJ = {}, NAME = 'foobar'; - OBJ.foo = function(x) { - return x; - }; - - gently._name = function() { - return NAME; - }; - - var original = OBJ.foo - , stubFn = function() {}; - - (function testAddOne() { - assert.strictEqual(gently.expect(OBJ, 'foo', stubFn), original); - - assert.equal(gently.expectations.length, 1); - var expectation = gently.expectations[0]; - assert.strictEqual(expectation.obj, OBJ); - assert.strictEqual(expectation.method, 'foo'); - assert.strictEqual(expectation.stubFn, stubFn); - assert.strictEqual(expectation.name, NAME); - assert.strictEqual(OBJ.foo._original, original); - })(); - - (function testAddTwo() { - gently.expect(OBJ, 'foo', 2, stubFn); - assert.equal(gently.expectations.length, 2); - assert.strictEqual(OBJ.foo._original, original); - })(); - - (function testAddOneWithoutMock() { - gently.expect(OBJ, 'foo'); - assert.equal(gently.expectations.length, 3); - })(); - - var stubFnCalled = 0, SELF = {}; - gently._stubFn = function(self, obj, method, name, args) { - stubFnCalled++; - assert.strictEqual(self, SELF); - assert.strictEqual(obj, OBJ); - assert.strictEqual(method, 'foo'); - assert.strictEqual(name, NAME); - assert.deepEqual(args, [1, 2]); - return 23; - }; - assert.equal(OBJ.foo.apply(SELF, [1, 2]), 23); - assert.equal(stubFnCalled, 1); -}); - -test(function expectClosure() { - var NAME = 'MY CLOSURE'; - function closureFn() {}; - - gently._name = function() { - return NAME; - }; - - var fn = gently.expect(closureFn); - assert.equal(gently.expectations.length, 1); - var expectation = gently.expectations[0]; - assert.strictEqual(expectation.obj, null); - assert.strictEqual(expectation.method, null); - assert.strictEqual(expectation.stubFn, closureFn); - assert.strictEqual(expectation.name, NAME); - - var stubFnCalled = 0, SELF = {}; - gently._stubFn = function(self, obj, method, name, args) { - stubFnCalled++; - assert.strictEqual(self, SELF); - assert.strictEqual(obj, null); - assert.strictEqual(method, null); - assert.strictEqual(name, NAME); - assert.deepEqual(args, [1, 2]); - return 23; - }; - assert.equal(fn.apply(SELF, [1, 2]), 23); - assert.equal(stubFnCalled, 1); -}); - -test(function expectClosureCount() { - var stubFnCalled = 0; - function closureFn() {stubFnCalled++}; - - var fn = gently.expect(2, closureFn); - assert.equal(gently.expectations.length, 1); - fn(); - assert.equal(gently.expectations.length, 1); - fn(); - assert.equal(stubFnCalled, 2); -}); - -test(function restore() { - var OBJ = {}, NAME = '[my object].myFn()'; - OBJ.foo = function(x) { - return x; - }; - - gently._name = function() { - return NAME; - }; - - var original = OBJ.foo; - gently.expect(OBJ, 'foo'); - gently.restore(OBJ, 'foo'); - assert.strictEqual(OBJ.foo, original); - - (function testError() { - try { - gently.restore(OBJ, 'foo'); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, NAME+' is not gently stubbed'); - } - })(); -}); - -test(function _stubFn() { - var OBJ1 = {toString: function() {return '[OBJ 1]'}} - , OBJ2 = {toString: function() {return '[OBJ 2]'}, foo: function () {return 'bar';}} - , SELF = {}; - - gently.expect(OBJ1, 'foo', function(x) { - assert.strictEqual(this, SELF); - return x * 2; - }); - - assert.equal(gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]), 10); - - (function testAutorestore() { - assert.equal(OBJ2.foo(), 'bar'); - - gently.expect(OBJ2, 'foo', function() { - return 'stubbed foo'; - }); - - gently.expect(OBJ2, 'foo', function() { - return "didn't restore yet"; - }); - - assert.equal(gently._stubFn(SELF, OBJ2, 'foo', 'dummy_name', []), 'stubbed foo'); - assert.equal(gently._stubFn(SELF, OBJ2, 'foo', 'dummy_name', []), "didn't restore yet"); - assert.equal(OBJ2.foo(), 'bar'); - assert.deepEqual(gently.expectations, []); - })(); - - (function testNoMoreCallExpected() { - try { - gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, 'Unexpected call to dummy_name, no call was expected'); - } - })(); - - (function testDifferentCallExpected() { - gently.expect(OBJ2, 'bar'); - try { - gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, 'Unexpected call to dummy_name, expected call to '+gently._name(OBJ2, 'bar')); - } - - assert.equal(gently.expectations.length, 1); - })(); - - (function testNoMockCallback() { - OBJ2.bar(); - assert.equal(gently.expectations.length, 0); - })(); -}); - -test(function stub() { - var LOCATION = './my_class'; - - (function testRegular() { - var Stub = gently.stub(LOCATION); - assert.ok(Stub instanceof Function); - assert.strictEqual(gently.hijacked[LOCATION], Stub); - assert.ok(Stub['new'] instanceof Function); - assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+')'); - - (function testConstructor() { - var newCalled = 0 - , STUB - , ARGS = ['foo', 'bar']; - - Stub['new'] = function(a, b) { - assert.equal(a, ARGS[0]); - assert.equal(b, ARGS[1]); - newCalled++; - STUB = this; - }; - - var stub = new Stub(ARGS[0], ARGS[1]); - assert.strictEqual(stub, STUB); - assert.equal(newCalled, 1); - assert.equal(stub.toString(), 'require('+JSON.stringify(LOCATION)+')'); - })(); - - (function testUseReturnValueAsInstance() { - var R = {}; - - Stub['new'] = function() { - return R; - }; - - var stub = new Stub(); - assert.strictEqual(stub, R); - - })(); - })(); - - var EXPORTS_NAME = 'MyClass'; - test(function testExportsName() { - var Stub = gently.stub(LOCATION, EXPORTS_NAME); - assert.strictEqual(gently.hijacked[LOCATION][EXPORTS_NAME], Stub); - assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+').'+EXPORTS_NAME); - - (function testConstructor() { - var stub = new Stub(); - assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+').'+EXPORTS_NAME); - })(); - }); -}); - -test(function hijack() { - var LOCATION = './foo' - , REQUIRE_CALLS = 0 - , EXPORTS = {} - , REQUIRE = function() { - REQUIRE_CALLS++; - return EXPORTS; - }; - - var hijackedRequire = gently.hijack(REQUIRE); - hijackedRequire(LOCATION); - assert.strictEqual(gently.hijacked[LOCATION], EXPORTS); - - assert.equal(REQUIRE_CALLS, 1); - - // make sure we are caching the hijacked module - hijackedRequire(LOCATION); - assert.equal(REQUIRE_CALLS, 1); -}); - -test(function verify() { - var OBJ = {toString: function() {return '[OBJ]'}}; - gently.verify(); - - gently.expect(OBJ, 'foo'); - try { - gently.verify(); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, 'Expected call to [OBJ].foo() did not happen'); - } - - try { - gently.verify('foo'); - assert.ok(false, 'throw needs to happen'); - } catch (e) { - assert.equal(e.message, 'Expected call to [OBJ].foo() did not happen (foo)'); - } -}); - -test(function processExit() { - var verifyCalled = 0; - gently.verify = function(msg) { - verifyCalled++; - assert.equal(msg, 'process exit'); - }; - - process.emit('exit'); - assert.equal(verifyCalled, 1); -}); - -test(function _name() { - (function testNamedClass() { - function Foo() {}; - var foo = new Foo(); - assert.equal(gently._name(foo, 'bar'), '[Foo].bar()'); - })(); - - (function testToStringPreference() { - function Foo() {}; - Foo.prototype.toString = function() { - return '[Superman 123]'; - }; - var foo = new Foo(); - assert.equal(gently._name(foo, 'bar'), '[Superman 123].bar()'); - })(); - - (function testUnamedClass() { - var Foo = function() {}; - var foo = new Foo(); - assert.equal(gently._name(foo, 'bar'), foo.toString()+'.bar()'); - })(); - - (function testNamedClosure() { - function myClosure() {}; - assert.equal(gently._name(null, null, myClosure), myClosure.name+'()'); - })(); - - (function testUnamedClosure() { - var myClosure = function() {2+2 == 5}; - assert.equal(gently._name(null, null, myClosure), '>> '+myClosure.toString()+' <<'); - })(); -}); - -test(function verifyExpectNone() { - var OBJ = {toString: function() {return '[OBJ]'}}; - gently.verify(); - - gently.expect(OBJ, 'foo', 0); - try { - gently.verify(); - } catch (e) { - assert.fail('Exception should not have been thrown'); - } -}); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/package.json deleted file mode 100644 index c12f5011e98..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "formidable", - "version": "1.0.11", - "dependencies": {}, - "devDependencies": { - "gently": "0.8.0", - "findit": "0.1.1", - "hashish": "0.0.4", - "urun": "0.0.4", - "utest": "0.0.3" - }, - "directories": { - "lib": "./lib" - }, - "main": "./lib/index", - "scripts": { - "test": "make test" - }, - "engines": { - "node": "*" - }, - "optionalDependencies": {}, - "readme": "# Formidable\n\n[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable)\n\n## Purpose\n\nA node.js module for parsing form data, especially file uploads.\n\n## Current status\n\nThis module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading\nand encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from\na large variety of clients and is considered production-ready.\n\n## Features\n\n* Fast (~500mb/sec), non-buffering multipart parser\n* Automatically writing file uploads to disk\n* Low memory footprint\n* Graceful error handling\n* Very high test coverage\n\n## Changelog\n\n### v1.0.9\n\n* Emit progress when content length header parsed (Tim Koschützki)\n* Fix Readme syntax due to GitHub changes (goob)\n* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara)\n\n### v1.0.8\n\n* Strip potentially unsafe characters when using `keepExtensions: true`.\n* Switch to utest / urun for testing\n* Add travis build\n\n### v1.0.7\n\n* Remove file from package that was causing problems when installing on windows. (#102)\n* Fix typos in Readme (Jason Davies).\n\n### v1.0.6\n\n* Do not default to the default to the field name for file uploads where\n filename=\"\".\n\n### v1.0.5\n\n* Support filename=\"\" in multipart parts\n* Explain unexpected end() errors in parser better\n\n**Note:** Starting with this version, formidable emits 'file' events for empty\nfile input fields. Previously those were incorrectly emitted as regular file\ninput fields with value = \"\".\n\n### v1.0.4\n\n* Detect a good default tmp directory regardless of platform. (#88)\n\n### v1.0.3\n\n* Fix problems with utf8 characters (#84) / semicolons in filenames (#58)\n* Small performance improvements\n* New test suite and fixture system\n\n### v1.0.2\n\n* Exclude node\\_modules folder from git\n* Implement new `'aborted'` event\n* Fix files in example folder to work with recent node versions\n* Make gently a devDependency\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2)\n\n### v1.0.1\n\n* Fix package.json to refer to proper main directory. (#68, Dean Landolt)\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1)\n\n### v1.0.0\n\n* Add support for multipart boundaries that are quoted strings. (Jeff Craig)\n\nThis marks the beginning of development on version 2.0 which will include\nseveral architectural improvements.\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0)\n\n### v0.9.11\n\n* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki)\n* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class\n\n**Important:** The old property names of the File class will be removed in a\nfuture release.\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11)\n\n### Older releases\n\nThese releases were done before starting to maintain the above Changelog:\n\n* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10)\n* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9)\n* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8)\n* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7)\n* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6)\n* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5)\n* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4)\n* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3)\n* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2)\n* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0)\n\n## Installation\n\nVia [npm](http://github.com/isaacs/npm):\n\n npm install formidable@latest\n\nManually:\n\n git clone git://github.com/felixge/node-formidable.git formidable\n vim my.js\n # var formidable = require('./formidable');\n\nNote: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library.\n\n## Example\n\nParse an incoming file upload.\n\n var formidable = require('formidable'),\n http = require('http'),\n\n util = require('util');\n\n http.createServer(function(req, res) {\n if (req.url == '/upload' && req.method.toLowerCase() == 'post') {\n // parse a file upload\n var form = new formidable.IncomingForm();\n form.parse(req, function(err, fields, files) {\n res.writeHead(200, {'content-type': 'text/plain'});\n res.write('received upload:\\n\\n');\n res.end(util.inspect({fields: fields, files: files}));\n });\n return;\n }\n\n // show a file upload form\n res.writeHead(200, {'content-type': 'text/html'});\n res.end(\n '
    '+\n '
    '+\n '
    '+\n ''+\n '
    '\n );\n }).listen(80);\n\n## API\n\n### formidable.IncomingForm\n\n__new formidable.IncomingForm()__\n\nCreates a new incoming form.\n\n__incomingForm.encoding = 'utf-8'__\n\nThe encoding to use for incoming form fields.\n\n__incomingForm.uploadDir = process.env.TMP || '/tmp' || process.cwd()__\n\nThe directory for placing file uploads in. You can move them later on using\n`fs.rename()`. The default directory is picked at module load time depending on\nthe first existing directory from those listed above.\n\n__incomingForm.keepExtensions = false__\n\nIf you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`.\n\n__incomingForm.type__\n\nEither 'multipart' or 'urlencoded' depending on the incoming request.\n\n__incomingForm.maxFieldsSize = 2 * 1024 * 1024__\n\nLimits the amount of memory a field (not file) can allocate in bytes.\nIf this value is exceeded, an `'error'` event is emitted. The default\nsize is 2MB.\n\n__incomingForm.hash = false__\n\nIf you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`.\n\n__incomingForm.bytesReceived__\n\nThe amount of bytes received for this form so far.\n\n__incomingForm.bytesExpected__\n\nThe expected number of bytes in this form.\n\n__incomingForm.parse(request, [cb])__\n\nParses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback:\n\n incomingForm.parse(req, function(err, fields, files) {\n // ...\n });\n\n__incomingForm.onPart(part)__\n\nYou may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing.\n\n incomingForm.onPart = function(part) {\n part.addListener('data', function() {\n // ...\n });\n }\n\nIf you want to use formidable to only handle certain parts for you, you can do so:\n\n incomingForm.onPart = function(part) {\n if (!part.filename) {\n // let formidable handle all non-file parts\n incomingForm.handlePart(part);\n }\n }\n\nCheck the code in this method for further inspiration.\n\n__Event: 'progress' (bytesReceived, bytesExpected)__\n\nEmitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.\n\n__Event: 'field' (name, value)__\n\nEmitted whenever a field / value pair has been received.\n\n__Event: 'fileBegin' (name, file)__\n\nEmitted whenever a new file is detected in the upload stream. Use this even if\nyou want to stream the file to somewhere else while buffering the upload on\nthe file system.\n\n__Event: 'file' (name, file)__\n\nEmitted whenever a field / file pair has been received. `file` is an instance of `File`.\n\n__Event: 'error' (err)__\n\nEmitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events.\n\n__Event: 'aborted'__\n\nEmitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core).\n\n__Event: 'end' ()__\n\nEmitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.\n\n### formidable.File\n\n__file.size = 0__\n\nThe size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet.\n\n__file.path = null__\n\nThe path this file is being written to. You can modify this in the `'fileBegin'` event in\ncase you are unhappy with the way formidable generates a temporary path for your files.\n\n__file.name = null__\n\nThe name this file had according to the uploading client.\n\n__file.type = null__\n\nThe mime type of this file, according to the uploading client.\n\n__file.lastModifiedDate = null__\n\nA date object (or `null`) containing the time this file was last written to. Mostly\nhere for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).\n\n__file.hash = null__\n\nIf hash calculation was set, you can read the hex digest out of this var.\n\n## License\n\nFormidable is licensed under the MIT license.\n\n## Ports\n\n* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable\n\n## Credits\n\n* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js\n", - "readmeFilename": "Readme.md", - "description": "[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable)", - "_id": "formidable@1.0.11", - "dist": { - "shasum": "46bd0df72e800fcfae8df7aaaef7a177a03b24ab" - }, - "_from": "formidable@1.0.11", - "_resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/common.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/common.js deleted file mode 100644 index eb432ad62ed..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/common.js +++ /dev/null @@ -1,19 +0,0 @@ -var mysql = require('..'); -var path = require('path'); - -var root = path.join(__dirname, '../'); -exports.dir = { - root : root, - lib : root + '/lib', - fixture : root + '/test/fixture', - tmp : root + '/test/tmp', -}; - -exports.port = 13532; - -exports.formidable = require('..'); -exports.assert = require('assert'); - -exports.require = function(lib) { - return require(exports.dir.lib + '/' + lib); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt deleted file mode 100644 index e7a4785e00c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt +++ /dev/null @@ -1 +0,0 @@ -I am a text file with a funky name! diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt deleted file mode 100644 index 9b6903e26fc..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt +++ /dev/null @@ -1 +0,0 @@ -I am a plain text file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md deleted file mode 100644 index 3c9dbe3dd07..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md +++ /dev/null @@ -1,3 +0,0 @@ -* Opera does not allow submitting this file, it shows a warning to the - user that the file could not be found instead. Tested in 9.8, 11.51 on OSX. - Reported to Opera on 08.09.2011 (tracking email DSK-346009@bugs.opera.com). diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js deleted file mode 100644 index 0bae449442a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports['generic.http'] = [ - {type: 'file', name: 'upload', filename: '', fixture: 'plain.txt'}, -]; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js deleted file mode 100644 index eb76fdc147d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +++ /dev/null @@ -1,21 +0,0 @@ -var properFilename = 'funkyfilename.txt'; - -function expect(filename) { - return [ - {type: 'field', name: 'title', value: 'Weird filename'}, - {type: 'file', name: 'upload', filename: filename, fixture: properFilename}, - ]; -}; - -var webkit = " ? % * | \" < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; -var ffOrIe = " ? % * | \" < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; - -module.exports = { - 'osx-chrome-13.http' : expect(webkit), - 'osx-firefox-3.6.http' : expect(ffOrIe), - 'osx-safari-5.http' : expect(webkit), - 'xp-chrome-12.http' : expect(webkit), - 'xp-ie-7.http' : expect(ffOrIe), - 'xp-ie-8.http' : expect(ffOrIe), - 'xp-safari-5.http' : expect(webkit), -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/multipart.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/multipart.js deleted file mode 100644 index a4761699e9c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/fixture/multipart.js +++ /dev/null @@ -1,72 +0,0 @@ -exports['rfc1867'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--\r\n', - parts: - [ { headers: { - 'content-disposition': 'form-data; name="field1"', - }, - data: 'Joe Blow\r\nalmost tricked you!', - }, - { headers: { - 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', - 'Content-Type': 'text/plain', - }, - data: '... contents of file1.txt ...\r', - } - ] - }; - -exports['noTrailing\r\n'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--', - parts: - [ { headers: { - 'content-disposition': 'form-data; name="field1"', - }, - data: 'Joe Blow\r\nalmost tricked you!', - }, - { headers: { - 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', - 'Content-Type': 'text/plain', - }, - data: '... contents of file1.txt ...\r', - } - ] - }; - -exports['emptyHeader'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - ': foo\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--\r\n', - expectError: true, - }; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js deleted file mode 100644 index 66ad259ef3f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js +++ /dev/null @@ -1,89 +0,0 @@ -var hashish = require('hashish'); -var fs = require('fs'); -var findit = require('findit'); -var path = require('path'); -var http = require('http'); -var net = require('net'); -var assert = require('assert'); - -var common = require('../common'); -var formidable = common.formidable; - -var server = http.createServer(); -server.listen(common.port, findFixtures); - -function findFixtures() { - var fixtures = []; - findit - .sync(common.dir.fixture + '/js') - .forEach(function(jsPath) { - if (!/\.js$/.test(jsPath)) return; - - var group = path.basename(jsPath, '.js'); - hashish.forEach(require(jsPath), function(fixture, name) { - fixtures.push({ - name : group + '/' + name, - fixture : fixture, - }); - }); - }); - - testNext(fixtures); -} - -function testNext(fixtures) { - var fixture = fixtures.shift(); - if (!fixture) return server.close(); - - var name = fixture.name; - var fixture = fixture.fixture; - - uploadFixture(name, function(err, parts) { - if (err) throw err; - - fixture.forEach(function(expectedPart, i) { - var parsedPart = parts[i]; - assert.equal(parsedPart.type, expectedPart.type); - assert.equal(parsedPart.name, expectedPart.name); - - if (parsedPart.type === 'file') { - var filename = parsedPart.value.name; - assert.equal(filename, expectedPart.filename); - } - }); - - testNext(fixtures); - }); -}; - -function uploadFixture(name, cb) { - server.once('request', function(req, res) { - var form = new formidable.IncomingForm(); - form.uploadDir = common.dir.tmp; - form.parse(req); - - function callback() { - var realCallback = cb; - cb = function() {}; - realCallback.apply(null, arguments); - } - - var parts = []; - form - .on('error', callback) - .on('fileBegin', function(name, value) { - parts.push({type: 'file', name: name, value: value}); - }) - .on('field', function(name, value) { - parts.push({type: 'field', name: name, value: value}); - }) - .on('end', function() { - callback(null, parts); - }); - }); - - var socket = net.createConnection(common.port); - var file = fs.createReadStream(common.dir.fixture + '/http/' + name); - - file.pipe(socket); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/common.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/common.js deleted file mode 100644 index 2b985981dc8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/common.js +++ /dev/null @@ -1,24 +0,0 @@ -var path = require('path'), - fs = require('fs'); - -try { - global.Gently = require('gently'); -} catch (e) { - throw new Error('this test suite requires node-gently'); -} - -exports.lib = path.join(__dirname, '../../lib'); - -global.GENTLY = new Gently(); - -global.assert = require('assert'); -global.TEST_PORT = 13532; -global.TEST_FIXTURES = path.join(__dirname, '../fixture'); -global.TEST_TMP = path.join(__dirname, '../tmp'); - -// Stupid new feature in node that complains about gently attaching too many -// listeners to process 'exit'. This is a workaround until I can think of a -// better way to deal with this. -if (process.setMaxListeners) { - process.setMaxListeners(10000); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js deleted file mode 100644 index 75232aa43b7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js +++ /dev/null @@ -1,80 +0,0 @@ -var common = require('../common'); -var CHUNK_LENGTH = 10, - multipartParser = require(common.lib + '/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - parser = new MultipartParser(), - fixtures = require(TEST_FIXTURES + '/multipart'), - Buffer = require('buffer').Buffer; - -Object.keys(fixtures).forEach(function(name) { - var fixture = fixtures[name], - buffer = new Buffer(Buffer.byteLength(fixture.raw, 'binary')), - offset = 0, - chunk, - nparsed, - - parts = [], - part = null, - headerField, - headerValue, - endCalled = ''; - - parser.initWithBoundary(fixture.boundary); - parser.onPartBegin = function() { - part = {headers: {}, data: ''}; - parts.push(part); - headerField = ''; - headerValue = ''; - }; - - parser.onHeaderField = function(b, start, end) { - headerField += b.toString('ascii', start, end); - }; - - parser.onHeaderValue = function(b, start, end) { - headerValue += b.toString('ascii', start, end); - } - - parser.onHeaderEnd = function() { - part.headers[headerField] = headerValue; - headerField = ''; - headerValue = ''; - }; - - parser.onPartData = function(b, start, end) { - var str = b.toString('ascii', start, end); - part.data += b.slice(start, end); - } - - parser.onEnd = function() { - endCalled = true; - } - - buffer.write(fixture.raw, 'binary', 0); - - while (offset < buffer.length) { - if (offset + CHUNK_LENGTH < buffer.length) { - chunk = buffer.slice(offset, offset+CHUNK_LENGTH); - } else { - chunk = buffer.slice(offset, buffer.length); - } - offset = offset + CHUNK_LENGTH; - - nparsed = parser.write(chunk); - if (nparsed != chunk.length) { - if (fixture.expectError) { - return; - } - puts('-- ERROR --'); - p(chunk.toString('ascii')); - throw new Error(chunk.length+' bytes written, but only '+nparsed+' bytes parsed!'); - } - } - - if (fixture.expectError) { - throw new Error('expected parse error did not happen'); - } - - assert.ok(endCalled); - assert.deepEqual(parts, fixture.parts); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js deleted file mode 100644 index 52ceedb425d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js +++ /dev/null @@ -1,104 +0,0 @@ -var common = require('../common'); -var WriteStreamStub = GENTLY.stub('fs', 'WriteStream'); - -var File = require(common.lib + '/file'), - EventEmitter = require('events').EventEmitter, - file, - gently; - -function test(test) { - gently = new Gently(); - file = new File(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.ok(file instanceof EventEmitter); - assert.strictEqual(file.size, 0); - assert.strictEqual(file.path, null); - assert.strictEqual(file.name, null); - assert.strictEqual(file.type, null); - assert.strictEqual(file.lastModifiedDate, null); - - assert.strictEqual(file._writeStream, null); - - (function testSetProperties() { - var file2 = new File({foo: 'bar'}); - assert.equal(file2.foo, 'bar'); - })(); -}); - -test(function open() { - var WRITE_STREAM; - file.path = '/foo'; - - gently.expect(WriteStreamStub, 'new', function (path) { - WRITE_STREAM = this; - assert.strictEqual(path, file.path); - }); - - file.open(); - assert.strictEqual(file._writeStream, WRITE_STREAM); -}); - -test(function write() { - var BUFFER = {length: 10}, - CB_STUB, - CB = function() { - CB_STUB.apply(this, arguments); - }; - - file._writeStream = {}; - - gently.expect(file._writeStream, 'write', function (buffer, cb) { - assert.strictEqual(buffer, BUFFER); - - gently.expect(file, 'emit', function (event, bytesWritten) { - assert.ok(file.lastModifiedDate instanceof Date); - assert.equal(event, 'progress'); - assert.equal(bytesWritten, file.size); - }); - - CB_STUB = gently.expect(function writeCb() { - assert.equal(file.size, 10); - }); - - cb(); - - gently.expect(file, 'emit', function (event, bytesWritten) { - assert.equal(event, 'progress'); - assert.equal(bytesWritten, file.size); - }); - - CB_STUB = gently.expect(function writeCb() { - assert.equal(file.size, 20); - }); - - cb(); - }); - - file.write(BUFFER, CB); -}); - -test(function end() { - var CB_STUB, - CB = function() { - CB_STUB.apply(this, arguments); - }; - - file._writeStream = {}; - - gently.expect(file._writeStream, 'end', function (cb) { - gently.expect(file, 'emit', function (event) { - assert.equal(event, 'end'); - }); - - CB_STUB = gently.expect(function endCb() { - }); - - cb(); - }); - - file.end(CB); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js deleted file mode 100644 index 84de439e547..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +++ /dev/null @@ -1,727 +0,0 @@ -var common = require('../common'); -var MultipartParserStub = GENTLY.stub('./multipart_parser', 'MultipartParser'), - QuerystringParserStub = GENTLY.stub('./querystring_parser', 'QuerystringParser'), - EventEmitterStub = GENTLY.stub('events', 'EventEmitter'), - StreamStub = GENTLY.stub('stream', 'Stream'), - FileStub = GENTLY.stub('./file'); - -var formidable = require(common.lib + '/index'), - IncomingForm = formidable.IncomingForm, - events = require('events'), - fs = require('fs'), - path = require('path'), - Buffer = require('buffer').Buffer, - fixtures = require(TEST_FIXTURES + '/multipart'), - form, - gently; - -function test(test) { - gently = new Gently(); - gently.expect(EventEmitterStub, 'call'); - form = new IncomingForm(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.strictEqual(form.error, null); - assert.strictEqual(form.ended, false); - assert.strictEqual(form.type, null); - assert.strictEqual(form.headers, null); - assert.strictEqual(form.keepExtensions, false); - assert.strictEqual(form.uploadDir, '/tmp'); - assert.strictEqual(form.encoding, 'utf-8'); - assert.strictEqual(form.bytesReceived, null); - assert.strictEqual(form.bytesExpected, null); - assert.strictEqual(form.maxFieldsSize, 2 * 1024 * 1024); - assert.strictEqual(form._parser, null); - assert.strictEqual(form._flushing, 0); - assert.strictEqual(form._fieldsSize, 0); - assert.ok(form instanceof EventEmitterStub); - assert.equal(form.constructor.name, 'IncomingForm'); - - (function testSimpleConstructor() { - gently.expect(EventEmitterStub, 'call'); - var form = IncomingForm(); - assert.ok(form instanceof IncomingForm); - })(); - - (function testSimpleConstructorShortcut() { - gently.expect(EventEmitterStub, 'call'); - var form = formidable(); - assert.ok(form instanceof IncomingForm); - })(); -}); - -test(function parse() { - var REQ = {headers: {}} - , emit = {}; - - gently.expect(form, 'writeHeaders', function(headers) { - assert.strictEqual(headers, REQ.headers); - }); - - var events = ['error', 'aborted', 'data', 'end']; - gently.expect(REQ, 'on', events.length, function(event, fn) { - assert.equal(event, events.shift()); - emit[event] = fn; - return this; - }); - - form.parse(REQ); - - (function testPause() { - gently.expect(REQ, 'pause'); - assert.strictEqual(form.pause(), true); - })(); - - (function testPauseCriticalException() { - form.ended = false; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'pause', function() { - throw ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - assert.strictEqual(form.pause(), false); - })(); - - (function testPauseHarmlessException() { - form.ended = true; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'pause', function() { - throw ERR; - }); - - assert.strictEqual(form.pause(), false); - })(); - - (function testResume() { - gently.expect(REQ, 'resume'); - assert.strictEqual(form.resume(), true); - })(); - - (function testResumeCriticalException() { - form.ended = false; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'resume', function() { - throw ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - assert.strictEqual(form.resume(), false); - })(); - - (function testResumeHarmlessException() { - form.ended = true; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'resume', function() { - throw ERR; - }); - - assert.strictEqual(form.resume(), false); - })(); - - (function testEmitError() { - var ERR = new Error('something bad happened'); - gently.expect(form, '_error',function(err) { - assert.strictEqual(err, ERR); - }); - emit.error(ERR); - })(); - - (function testEmitAborted() { - gently.expect(form, 'emit',function(event) { - assert.equal(event, 'aborted'); - }); - - emit.aborted(); - })(); - - - (function testEmitData() { - var BUFFER = [1, 2, 3]; - gently.expect(form, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - }); - emit.data(BUFFER); - })(); - - (function testEmitEnd() { - form._parser = {}; - - (function testWithError() { - var ERR = new Error('haha'); - gently.expect(form._parser, 'end', function() { - return ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - emit.end(); - })(); - - (function testWithoutError() { - gently.expect(form._parser, 'end'); - emit.end(); - })(); - - (function testAfterError() { - form.error = true; - emit.end(); - })(); - })(); - - (function testWithCallback() { - gently.expect(EventEmitterStub, 'call'); - var form = new IncomingForm(), - REQ = {headers: {}}, - parseCalled = 0; - - gently.expect(form, 'writeHeaders'); - gently.expect(REQ, 'on', 4, function() { - return this; - }); - - gently.expect(form, 'on', 4, function(event, fn) { - if (event == 'field') { - fn('field1', 'foo'); - fn('field1', 'bar'); - fn('field2', 'nice'); - } - - if (event == 'file') { - fn('file1', '1'); - fn('file1', '2'); - fn('file2', '3'); - } - - if (event == 'end') { - fn(); - } - return this; - }); - - form.parse(REQ, gently.expect(function parseCbOk(err, fields, files) { - assert.deepEqual(fields, {field1: 'bar', field2: 'nice'}); - assert.deepEqual(files, {file1: '2', file2: '3'}); - })); - - gently.expect(form, 'writeHeaders'); - gently.expect(REQ, 'on', 4, function() { - return this; - }); - - var ERR = new Error('test'); - gently.expect(form, 'on', 3, function(event, fn) { - if (event == 'field') { - fn('foo', 'bar'); - } - - if (event == 'error') { - fn(ERR); - gently.expect(form, 'on'); - } - return this; - }); - - form.parse(REQ, gently.expect(function parseCbErr(err, fields, files) { - assert.strictEqual(err, ERR); - assert.deepEqual(fields, {foo: 'bar'}); - })); - })(); -}); - -test(function pause() { - assert.strictEqual(form.pause(), false); -}); - -test(function resume() { - assert.strictEqual(form.resume(), false); -}); - - -test(function writeHeaders() { - var HEADERS = {}; - gently.expect(form, '_parseContentLength'); - gently.expect(form, '_parseContentType'); - - form.writeHeaders(HEADERS); - assert.strictEqual(form.headers, HEADERS); -}); - -test(function write() { - var parser = {}, - BUFFER = [1, 2, 3]; - - form._parser = parser; - form.bytesExpected = 523423; - - (function testBasic() { - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, BUFFER.length); - assert.equal(bytesExpected, form.bytesExpected); - }); - - gently.expect(parser, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - return buffer.length; - }); - - assert.equal(form.write(BUFFER), BUFFER.length); - assert.equal(form.bytesReceived, BUFFER.length); - })(); - - (function testParserError() { - gently.expect(form, 'emit'); - - gently.expect(parser, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - return buffer.length - 1; - }); - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/parser error/i)); - }); - - assert.equal(form.write(BUFFER), BUFFER.length - 1); - assert.equal(form.bytesReceived, BUFFER.length + BUFFER.length); - })(); - - (function testUninitialized() { - delete form._parser; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/unintialized parser/i)); - }); - form.write(BUFFER); - })(); -}); - -test(function parseContentType() { - var HEADERS = {}; - - form.headers = {'content-type': 'application/x-www-form-urlencoded'}; - gently.expect(form, '_initUrlencoded'); - form._parseContentType(); - - // accept anything that has 'urlencoded' in it - form.headers = {'content-type': 'broken-client/urlencoded-stupid'}; - gently.expect(form, '_initUrlencoded'); - form._parseContentType(); - - var BOUNDARY = '---------------------------57814261102167618332366269'; - form.headers = {'content-type': 'multipart/form-data; boundary='+BOUNDARY}; - - gently.expect(form, '_initMultipart', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - form._parseContentType(); - - (function testQuotedBoundary() { - form.headers = {'content-type': 'multipart/form-data; boundary="' + BOUNDARY + '"'}; - - gently.expect(form, '_initMultipart', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - form._parseContentType(); - })(); - - (function testNoBoundary() { - form.headers = {'content-type': 'multipart/form-data'}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/no multipart boundary/i)); - }); - form._parseContentType(); - })(); - - (function testNoContentType() { - form.headers = {}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/no content-type/i)); - }); - form._parseContentType(); - })(); - - (function testUnknownContentType() { - form.headers = {'content-type': 'invalid'}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/unknown content-type/i)); - }); - form._parseContentType(); - })(); -}); - -test(function parseContentLength() { - var HEADERS = {}; - - form.headers = {}; - form._parseContentLength(); - assert.strictEqual(form.bytesReceived, null); - assert.strictEqual(form.bytesExpected, null); - - form.headers['content-length'] = '8'; - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, 0); - assert.equal(bytesExpected, 8); - }); - form._parseContentLength(); - assert.strictEqual(form.bytesReceived, 0); - assert.strictEqual(form.bytesExpected, 8); - - // JS can be evil, lets make sure we are not - form.headers['content-length'] = '08'; - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, 0); - assert.equal(bytesExpected, 8); - }); - form._parseContentLength(); - assert.strictEqual(form.bytesExpected, 8); -}); - -test(function _initMultipart() { - var BOUNDARY = '123', - PARSER; - - gently.expect(MultipartParserStub, 'new', function() { - PARSER = this; - }); - - gently.expect(MultipartParserStub.prototype, 'initWithBoundary', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - - form._initMultipart(BOUNDARY); - assert.equal(form.type, 'multipart'); - assert.strictEqual(form._parser, PARSER); - - (function testRegularField() { - var PART; - gently.expect(StreamStub, 'new', function() { - PART = this; - }); - - gently.expect(form, 'onPart', function(part) { - assert.strictEqual(part, PART); - assert.deepEqual - ( part.headers - , { 'content-disposition': 'form-data; name="field1"' - , 'foo': 'bar' - } - ); - assert.equal(part.name, 'field1'); - - var strings = ['hello', ' world']; - gently.expect(part, 'emit', 2, function(event, b) { - assert.equal(event, 'data'); - assert.equal(b.toString(), strings.shift()); - }); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'end'); - }); - }); - - PARSER.onPartBegin(); - PARSER.onHeaderField(new Buffer('content-disposition'), 0, 10); - PARSER.onHeaderField(new Buffer('content-disposition'), 10, 19); - PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 0, 14); - PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 14, 24); - PARSER.onHeaderEnd(); - PARSER.onHeaderField(new Buffer('foo'), 0, 3); - PARSER.onHeaderValue(new Buffer('bar'), 0, 3); - PARSER.onHeaderEnd(); - PARSER.onHeadersEnd(); - PARSER.onPartData(new Buffer('hello world'), 0, 5); - PARSER.onPartData(new Buffer('hello world'), 5, 11); - PARSER.onPartEnd(); - })(); - - (function testFileField() { - var PART; - gently.expect(StreamStub, 'new', function() { - PART = this; - }); - - gently.expect(form, 'onPart', function(part) { - assert.deepEqual - ( part.headers - , { 'content-disposition': 'form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"' - , 'content-type': 'text/plain' - } - ); - assert.equal(part.name, 'field2'); - assert.equal(part.filename, 'Sun"et.jpg'); - assert.equal(part.mime, 'text/plain'); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'data'); - assert.equal(b.toString(), '... contents of file1.txt ...'); - }); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'end'); - }); - }); - - PARSER.onPartBegin(); - PARSER.onHeaderField(new Buffer('content-disposition'), 0, 19); - PARSER.onHeaderValue(new Buffer('form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'), 0, 85); - PARSER.onHeaderEnd(); - PARSER.onHeaderField(new Buffer('Content-Type'), 0, 12); - PARSER.onHeaderValue(new Buffer('text/plain'), 0, 10); - PARSER.onHeaderEnd(); - PARSER.onHeadersEnd(); - PARSER.onPartData(new Buffer('... contents of file1.txt ...'), 0, 29); - PARSER.onPartEnd(); - })(); - - (function testEnd() { - gently.expect(form, '_maybeEnd'); - PARSER.onEnd(); - assert.ok(form.ended); - })(); -}); - -test(function _fileName() { - // TODO - return; -}); - -test(function _initUrlencoded() { - var PARSER; - - gently.expect(QuerystringParserStub, 'new', function() { - PARSER = this; - }); - - form._initUrlencoded(); - assert.equal(form.type, 'urlencoded'); - assert.strictEqual(form._parser, PARSER); - - (function testOnField() { - var KEY = 'KEY', VAL = 'VAL'; - gently.expect(form, 'emit', function(field, key, val) { - assert.equal(field, 'field'); - assert.equal(key, KEY); - assert.equal(val, VAL); - }); - - PARSER.onField(KEY, VAL); - })(); - - (function testOnEnd() { - gently.expect(form, '_maybeEnd'); - - PARSER.onEnd(); - assert.equal(form.ended, true); - })(); -}); - -test(function _error() { - var ERR = new Error('bla'); - - gently.expect(form, 'pause'); - gently.expect(form, 'emit', function(event, err) { - assert.equal(event, 'error'); - assert.strictEqual(err, ERR); - }); - - form._error(ERR); - assert.strictEqual(form.error, ERR); - - // make sure _error only does its thing once - form._error(ERR); -}); - -test(function onPart() { - var PART = {}; - gently.expect(form, 'handlePart', function(part) { - assert.strictEqual(part, PART); - }); - - form.onPart(PART); -}); - -test(function handlePart() { - (function testUtf8Field() { - var PART = new events.EventEmitter(); - PART.name = 'my_field'; - - gently.expect(form, 'emit', function(event, field, value) { - assert.equal(event, 'field'); - assert.equal(field, 'my_field'); - assert.equal(value, 'hello world: €'); - }); - - form.handlePart(PART); - PART.emit('data', new Buffer('hello')); - PART.emit('data', new Buffer(' world: ')); - PART.emit('data', new Buffer([0xE2])); - PART.emit('data', new Buffer([0x82, 0xAC])); - PART.emit('end'); - })(); - - (function testBinaryField() { - var PART = new events.EventEmitter(); - PART.name = 'my_field2'; - - gently.expect(form, 'emit', function(event, field, value) { - assert.equal(event, 'field'); - assert.equal(field, 'my_field2'); - assert.equal(value, 'hello world: '+new Buffer([0xE2, 0x82, 0xAC]).toString('binary')); - }); - - form.encoding = 'binary'; - form.handlePart(PART); - PART.emit('data', new Buffer('hello')); - PART.emit('data', new Buffer(' world: ')); - PART.emit('data', new Buffer([0xE2])); - PART.emit('data', new Buffer([0x82, 0xAC])); - PART.emit('end'); - })(); - - (function testFieldSize() { - form.maxFieldsSize = 8; - var PART = new events.EventEmitter(); - PART.name = 'my_field'; - - gently.expect(form, '_error', function(err) { - assert.equal(err.message, 'maxFieldsSize exceeded, received 9 bytes of field data'); - }); - - form.handlePart(PART); - form._fieldsSize = 1; - PART.emit('data', new Buffer(7)); - PART.emit('data', new Buffer(1)); - })(); - - (function testFilePart() { - var PART = new events.EventEmitter(), - FILE = new events.EventEmitter(), - PATH = '/foo/bar'; - - PART.name = 'my_file'; - PART.filename = 'sweet.txt'; - PART.mime = 'sweet.txt'; - - gently.expect(form, '_uploadPath', function(filename) { - assert.equal(filename, PART.filename); - return PATH; - }); - - gently.expect(FileStub, 'new', function(properties) { - assert.equal(properties.path, PATH); - assert.equal(properties.name, PART.filename); - assert.equal(properties.type, PART.mime); - FILE = this; - - gently.expect(form, 'emit', function (event, field, file) { - assert.equal(event, 'fileBegin'); - assert.strictEqual(field, PART.name); - assert.strictEqual(file, FILE); - }); - - gently.expect(FILE, 'open'); - }); - - form.handlePart(PART); - assert.equal(form._flushing, 1); - - var BUFFER; - gently.expect(form, 'pause'); - gently.expect(FILE, 'write', function(buffer, cb) { - assert.strictEqual(buffer, BUFFER); - gently.expect(form, 'resume'); - // @todo handle cb(new Err) - cb(); - }); - - PART.emit('data', BUFFER = new Buffer('test')); - - gently.expect(FILE, 'end', function(cb) { - gently.expect(form, 'emit', function(event, field, file) { - assert.equal(event, 'file'); - assert.strictEqual(file, FILE); - }); - - gently.expect(form, '_maybeEnd'); - - cb(); - assert.equal(form._flushing, 0); - }); - - PART.emit('end'); - })(); -}); - -test(function _uploadPath() { - (function testUniqueId() { - var UUID_A, UUID_B; - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { - assert.equal(uploadDir, form.uploadDir); - UUID_A = uuid; - }); - form._uploadPath(); - - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { - UUID_B = uuid; - }); - form._uploadPath(); - - assert.notEqual(UUID_A, UUID_B); - })(); - - (function testFileExtension() { - form.keepExtensions = true; - var FILENAME = 'foo.jpg', - EXT = '.bar'; - - gently.expect(GENTLY.hijacked.path, 'extname', function(filename) { - assert.equal(filename, FILENAME); - gently.restore(path, 'extname'); - - return EXT; - }); - - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) { - assert.equal(path.extname(name), EXT); - }); - form._uploadPath(FILENAME); - })(); -}); - -test(function _maybeEnd() { - gently.expect(form, 'emit', 0); - form._maybeEnd(); - - form.ended = true; - form._flushing = 1; - form._maybeEnd(); - - gently.expect(form, 'emit', function(event) { - assert.equal(event, 'end'); - }); - - form.ended = true; - form._flushing = 0; - form._maybeEnd(); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js deleted file mode 100644 index d8dc968cf2b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js +++ /dev/null @@ -1,50 +0,0 @@ -var common = require('../common'); -var multipartParser = require(common.lib + '/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - events = require('events'), - Buffer = require('buffer').Buffer, - parser; - -function test(test) { - parser = new MultipartParser(); - test(); -} - -test(function constructor() { - assert.equal(parser.boundary, null); - assert.equal(parser.state, 0); - assert.equal(parser.flags, 0); - assert.equal(parser.boundaryChars, null); - assert.equal(parser.index, null); - assert.equal(parser.lookbehind, null); - assert.equal(parser.constructor.name, 'MultipartParser'); -}); - -test(function initWithBoundary() { - var boundary = 'abc'; - parser.initWithBoundary(boundary); - assert.deepEqual(Array.prototype.slice.call(parser.boundary), [13, 10, 45, 45, 97, 98, 99]); - assert.equal(parser.state, multipartParser.START); - - assert.deepEqual(parser.boundaryChars, {10: true, 13: true, 45: true, 97: true, 98: true, 99: true}); -}); - -test(function parserError() { - var boundary = 'abc', - buffer = new Buffer(5); - - parser.initWithBoundary(boundary); - buffer.write('--ad', 'ascii', 0); - assert.equal(parser.write(buffer), 3); -}); - -test(function end() { - (function testError() { - assert.equal(parser.end().message, 'MultipartParser.end(): stream ended unexpectedly: ' + parser.explain()); - })(); - - (function testRegular() { - parser.state = multipartParser.END; - assert.strictEqual(parser.end(), undefined); - })(); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js deleted file mode 100644 index 54d3e2d55d9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js +++ /dev/null @@ -1,45 +0,0 @@ -var common = require('../common'); -var QuerystringParser = require(common.lib + '/querystring_parser').QuerystringParser, - Buffer = require('buffer').Buffer, - gently, - parser; - -function test(test) { - gently = new Gently(); - parser = new QuerystringParser(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.equal(parser.buffer, ''); - assert.equal(parser.constructor.name, 'QuerystringParser'); -}); - -test(function write() { - var a = new Buffer('a=1'); - assert.equal(parser.write(a), a.length); - - var b = new Buffer('&b=2'); - parser.write(b); - assert.equal(parser.buffer, a + b); -}); - -test(function end() { - var FIELDS = {a: ['b', {c: 'd'}], e: 'f'}; - - gently.expect(GENTLY.hijacked.querystring, 'parse', function(str) { - assert.equal(str, parser.buffer); - return FIELDS; - }); - - gently.expect(parser, 'onField', Object.keys(FIELDS).length, function(key, val) { - assert.deepEqual(FIELDS[key], val); - }); - - gently.expect(parser, 'onEnd'); - - parser.buffer = 'my buffer'; - parser.end(); - assert.equal(parser.buffer, ''); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js deleted file mode 100644 index 479e46d62d8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js +++ /dev/null @@ -1,75 +0,0 @@ -var common = require('../common'); -var BOUNDARY = '---------------------------10102754414578508781458777923', - FIXTURE = TEST_FIXTURES+'/multi_video.upload', - fs = require('fs'), - util = require(common.lib + '/util'), - http = require('http'), - formidable = require(common.lib + '/index'), - server = http.createServer(); - -server.on('request', function(req, res) { - var form = new formidable.IncomingForm(), - uploads = {}; - - form.uploadDir = TEST_TMP; - form.hash = 'sha1'; - form.parse(req); - - form - .on('fileBegin', function(field, file) { - assert.equal(field, 'upload'); - - var tracker = {file: file, progress: [], ended: false}; - uploads[file.filename] = tracker; - file - .on('progress', function(bytesReceived) { - tracker.progress.push(bytesReceived); - assert.equal(bytesReceived, file.length); - }) - .on('end', function() { - tracker.ended = true; - }); - }) - .on('field', function(field, value) { - assert.equal(field, 'title'); - assert.equal(value, ''); - }) - .on('file', function(field, file) { - assert.equal(field, 'upload'); - assert.strictEqual(uploads[file.filename].file, file); - }) - .on('end', function() { - assert.ok(uploads['shortest_video.flv']); - assert.ok(uploads['shortest_video.flv'].ended); - assert.ok(uploads['shortest_video.flv'].progress.length > 3); - assert.equal(uploads['shortest_video.flv'].file.hash, 'd6a17616c7143d1b1438ceeef6836d1a09186b3a'); - assert.equal(uploads['shortest_video.flv'].progress.slice(-1), uploads['shortest_video.flv'].file.length); - assert.ok(uploads['shortest_video.mp4']); - assert.ok(uploads['shortest_video.mp4'].ended); - assert.ok(uploads['shortest_video.mp4'].progress.length > 3); - assert.equal(uploads['shortest_video.mp4'].file.hash, '937dfd4db263f4887ceae19341dcc8d63bcd557f'); - - server.close(); - res.writeHead(200); - res.end('good'); - }); -}); - -server.listen(TEST_PORT, function() { - var client = http.createClient(TEST_PORT), - stat = fs.statSync(FIXTURE), - headers = { - 'content-type': 'multipart/form-data; boundary='+BOUNDARY, - 'content-length': stat.size, - } - request = client.request('POST', '/', headers), - fixture = new fs.ReadStream(FIXTURE); - - fixture - .on('data', function(b) { - request.write(b); - }) - .on('end', function() { - request.end(); - }); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/run.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/run.js deleted file mode 100755 index 50b23610278..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/run.js +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require('urun')(__dirname) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js deleted file mode 100644 index fe2ac1c6cd4..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js +++ /dev/null @@ -1,63 +0,0 @@ -var common = require('../common'); -var test = require('utest'); -var assert = common.assert; -var IncomingForm = common.require('incoming_form').IncomingForm; -var path = require('path'); - -var form; -test('IncomingForm', { - before: function() { - form = new IncomingForm(); - }, - - '#_fileName with regular characters': function() { - var filename = 'foo.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'foo.txt'); - }, - - '#_fileName with unescaped quote': function() { - var filename = 'my".txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); - }, - - '#_fileName with escaped quote': function() { - var filename = 'my%22.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); - }, - - '#_fileName with bad quote and additional sub-header': function() { - var filename = 'my".txt'; - var header = makeHeader(filename) + '; foo="bar"'; - assert.equal(form._fileName(header), filename); - }, - - '#_fileName with semicolon': function() { - var filename = 'my;.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my;.txt'); - }, - - '#_fileName with utf8 character': function() { - var filename = 'my☃.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my☃.txt'); - }, - - '#_uploadPath strips harmful characters from extension when keepExtensions': function() { - form.keepExtensions = true; - - var ext = path.extname(form._uploadPath('fine.jpg?foo=bar')); - assert.equal(ext, '.jpg'); - - var ext = path.extname(form._uploadPath('fine?foo=bar')); - assert.equal(ext, ''); - - var ext = path.extname(form._uploadPath('super.cr2+dsad')); - assert.equal(ext, '.cr2'); - - var ext = path.extname(form._uploadPath('super.bar')); - assert.equal(ext, '.bar'); - }, -}); - -function makeHeader(filename) { - return 'Content-Disposition: form-data; name="upload"; filename="' + filename + '"'; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/tool/record.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/tool/record.js deleted file mode 100644 index 9f1cef86fad..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/formidable/tool/record.js +++ /dev/null @@ -1,47 +0,0 @@ -var http = require('http'); -var fs = require('fs'); -var connections = 0; - -var server = http.createServer(function(req, res) { - var socket = req.socket; - console.log('Request: %s %s -> %s', req.method, req.url, socket.filename); - - req.on('end', function() { - if (req.url !== '/') { - res.end(JSON.stringify({ - method: req.method, - url: req.url, - filename: socket.filename, - })); - return; - } - - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - }); -}); - -server.on('connection', function(socket) { - connections++; - - socket.id = connections; - socket.filename = 'connection-' + socket.id + '.http'; - socket.file = fs.createWriteStream(socket.filename); - socket.pipe(socket.file); - - console.log('--> %s', socket.filename); - socket.on('close', function() { - console.log('<-- %s', socket.filename); - }); -}); - -var port = process.env.PORT || 8080; -server.listen(port, function() { - console.log('Recording connections on port %s', port); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Readme.md deleted file mode 100644 index 273130d4771..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/Readme.md +++ /dev/null @@ -1,32 +0,0 @@ - -# node-fresh - - HTTP response freshness testing - -## fresh(req, res) - - Check freshness of `req` and `res` headers. - - When the cache is "fresh" __true__ is returned, - otherwise __false__ is returned to indicate that - the cache is now stale. - -## Example: - -```js -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'luna' }; -fresh(req, res); -// => false - -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'tobi' }; -fresh(req, res); -// => true -``` - -## Installation - -``` -$ npm install fresh -``` \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/index.js deleted file mode 100644 index b2f4d4132f0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/index.js +++ /dev/null @@ -1,49 +0,0 @@ - -/** - * Expose `fresh()`. - */ - -module.exports = fresh; - -/** - * Check freshness of `req` and `res` headers. - * - * When the cache is "fresh" __true__ is returned, - * otherwise __false__ is returned to indicate that - * the cache is now stale. - * - * @param {Object} req - * @param {Object} res - * @return {Boolean} - * @api public - */ - -function fresh(req, res) { - // defaults - var etagMatches = true; - var notModified = true; - - // fields - var modifiedSince = req['if-modified-since']; - var noneMatch = req['if-none-match']; - var lastModified = res['last-modified']; - var etag = res['etag']; - - // unconditional request - if (!modifiedSince && !noneMatch) return false; - - // parse if-none-match - if (noneMatch) noneMatch = noneMatch.split(/ *, */); - - // if-none-match - if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0]; - - // if-modified-since - if (modifiedSince) { - modifiedSince = new Date(modifiedSince); - lastModified = new Date(lastModified); - notModified = lastModified <= modifiedSince; - } - - return !! (etagMatches && notModified); -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/package.json deleted file mode 100644 index c1035e6e2b4..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/fresh/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "fresh", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "HTTP response freshness testing", - "version": "0.1.0", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "readme": "\n# node-fresh\n\n HTTP response freshness testing\n\n## fresh(req, res)\n\n Check freshness of `req` and `res` headers.\n\n When the cache is \"fresh\" __true__ is returned,\n otherwise __false__ is returned to indicate that\n the cache is now stale.\n\n## Example:\n\n```js\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'luna' };\nfresh(req, res);\n// => false\n\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'tobi' };\nfresh(req, res);\n// => true\n```\n\n## Installation\n\n```\n$ npm install fresh\n```", - "readmeFilename": "Readme.md", - "_id": "fresh@0.1.0", - "dist": { - "shasum": "0c6ecc369d58d45f1f14894e3c667213a7c78189" - }, - "_from": "fresh@0.1.0", - "_resolved": "https://registry.npmjs.org/fresh/-/fresh-0.1.0.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.gitmodules b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.gitmodules deleted file mode 100644 index 49e31dac7d7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "support/expresso"] - path = support/expresso - url = git://github.com/visionmedia/expresso.git -[submodule "support/should"] - path = support/should - url = git://github.com/visionmedia/should.js.git diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.npmignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.travis.yml deleted file mode 100644 index 2c0a8f63f4f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.4 \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/History.md deleted file mode 100644 index 3eaf7dfdc75..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/History.md +++ /dev/null @@ -1,73 +0,0 @@ - -0.4.2 / 2012-02-08 -================== - - * Fixed: ensure objects are created when appropriate not arrays [aheckmann] - -0.4.1 / 2012-01-26 -================== - - * Fixed stringify()ing numbers. Closes #23 - -0.4.0 / 2011-11-21 -================== - - * Allow parsing of an existing object (for `bodyParser()`) [jackyz] - * Replaced expresso with mocha - -0.3.2 / 2011-11-08 -================== - - * Fixed global variable leak - -0.3.1 / 2011-08-17 -================== - - * Added `try/catch` around malformed uri components - * Add test coverage for Array native method bleed-though - -0.3.0 / 2011-07-19 -================== - - * Allow `array[index]` and `object[property]` syntaxes [Aria Stewart] - -0.2.0 / 2011-06-29 -================== - - * Added `qs.stringify()` [Cory Forsyth] - -0.1.0 / 2011-04-13 -================== - - * Added jQuery-ish array support - -0.0.7 / 2011-03-13 -================== - - * Fixed; handle empty string and `== null` in `qs.parse()` [dmit] - allows for convenient `qs.parse(url.parse(str).query)` - -0.0.6 / 2011-02-14 -================== - - * Fixed; support for implicit arrays - -0.0.4 / 2011-02-09 -================== - - * Fixed `+` as a space - -0.0.3 / 2011-02-08 -================== - - * Fixed case when right-hand value contains "]" - -0.0.2 / 2011-02-07 -================== - - * Fixed "=" presence in key - -0.0.1 / 2011-02-07 -================== - - * Initial release \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Makefile deleted file mode 100644 index e4df8370490..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - -test: - @./node_modules/.bin/mocha - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Readme.md deleted file mode 100644 index db0d14548af..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/Readme.md +++ /dev/null @@ -1,54 +0,0 @@ -# node-querystring - - query string parser for node supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. - -## Installation - - $ npm install qs - -## Examples - -```js -var qs = require('qs'); - -qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); -// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } - -qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) -// => user[name]=Tobi&user[email]=tobi%40learnboost.com -``` - -## Testing - -Install dev dependencies: - - $ npm install -d - -and execute: - - $ make test - -## License - -(The MIT License) - -Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/benchmark.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/benchmark.js deleted file mode 100644 index 97e2c93ed0f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/benchmark.js +++ /dev/null @@ -1,17 +0,0 @@ - -var qs = require('./'); - -var times = 100000 - , start = new Date - , n = times; - -console.log('times: %d', times); - -while (n--) qs.parse('foo=bar'); -console.log('simple: %dms', new Date - start); - -var start = new Date - , n = times; - -while (n--) qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); -console.log('nested: %dms', new Date - start); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/examples.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/examples.js deleted file mode 100644 index 27617b75f0d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/examples.js +++ /dev/null @@ -1,51 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('./'); - -var obj = qs.parse('foo'); -console.log(obj) - -var obj = qs.parse('foo=bar=baz'); -console.log(obj) - -var obj = qs.parse('users[]'); -console.log(obj) - -var obj = qs.parse('name=tj&email=tj@vision-media.ca'); -console.log(obj) - -var obj = qs.parse('users[]=tj&users[]=tobi&users[]=jane'); -console.log(obj) - -var obj = qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); -console.log(obj) - -var obj = qs.parse('users[][name][first]=tj&users[][name][last]=holowaychuk'); -console.log(obj) - -var obj = qs.parse('a=a&a=b&a=c'); -console.log(obj) - -var obj = qs.parse('user[tj]=tj&user[tj]=TJ'); -console.log(obj) - -var obj = qs.parse('user[names]=tj&user[names]=TJ&user[names]=Tyler'); -console.log(obj) - -var obj = qs.parse('user[name][first]=tj&user[name][first]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[1]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[foo]=TJ'); -console.log(obj) - -var str = qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}); -console.log(str); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/index.js deleted file mode 100644 index d177d209b7b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/querystring'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/lib/querystring.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/lib/querystring.js deleted file mode 100644 index 6c727120a72..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/lib/querystring.js +++ /dev/null @@ -1,264 +0,0 @@ - -/*! - * querystring - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Library version. - */ - -exports.version = '0.4.2'; - -/** - * Object#toString() ref for stringify(). - */ - -var toString = Object.prototype.toString; - -/** - * Cache non-integer test regexp. - */ - -var isint = /^[0-9]+$/; - -function promote(parent, key) { - if (parent[key].length == 0) return parent[key] = {}; - var t = {}; - for (var i in parent[key]) t[i] = parent[key][i]; - parent[key] = t; - return t; -} - -function parse(parts, parent, key, val) { - var part = parts.shift(); - // end - if (!part) { - if (Array.isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } - // array - } else { - var obj = parent[key] = parent[key] || []; - if (']' == part) { - if (Array.isArray(obj)) { - if ('' != val) obj.push(val); - } else if ('object' == typeof obj) { - obj[Object.keys(obj).length] = val; - } else { - obj = parent[key] = [parent[key], val]; - } - // prop - } else if (~part.indexOf(']')) { - part = part.substr(0, part.length - 1); - if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - // key - } else { - if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - } - } -} - -/** - * Merge parent key/val pair. - */ - -function merge(parent, key, val){ - if (~key.indexOf(']')) { - var parts = key.split('[') - , len = parts.length - , last = len - 1; - parse(parts, parent, 'base', val); - // optimize - } else { - if (!isint.test(key) && Array.isArray(parent.base)) { - var t = {}; - for (var k in parent.base) t[k] = parent.base[k]; - parent.base = t; - } - set(parent.base, key, val); - } - - return parent; -} - -/** - * Parse the given obj. - */ - -function parseObject(obj){ - var ret = { base: {} }; - Object.keys(obj).forEach(function(name){ - merge(ret, name, obj[name]); - }); - return ret.base; -} - -/** - * Parse the given str. - */ - -function parseString(str){ - return String(str) - .split('&') - .reduce(function(ret, pair){ - try{ - pair = decodeURIComponent(pair.replace(/\+/g, ' ')); - } catch(e) { - // ignore - } - - var eql = pair.indexOf('=') - , brace = lastBraceInKey(pair) - , key = pair.substr(0, brace || eql) - , val = pair.substr(brace || eql, pair.length) - , val = val.substr(val.indexOf('=') + 1, val.length); - - // ?foo - if ('' == key) key = pair, val = ''; - - return merge(ret, key, val); - }, { base: {} }).base; -} - -/** - * Parse the given query `str` or `obj`, returning an object. - * - * @param {String} str | {Object} obj - * @return {Object} - * @api public - */ - -exports.parse = function(str){ - if (null == str || '' == str) return {}; - return 'object' == typeof str - ? parseObject(str) - : parseString(str); -}; - -/** - * Turn the given `obj` into a query string - * - * @param {Object} obj - * @return {String} - * @api public - */ - -var stringify = exports.stringify = function(obj, prefix) { - if (Array.isArray(obj)) { - return stringifyArray(obj, prefix); - } else if ('[object Object]' == toString.call(obj)) { - return stringifyObject(obj, prefix); - } else if ('string' == typeof obj) { - return stringifyString(obj, prefix); - } else { - return prefix + '=' + obj; - } -}; - -/** - * Stringify the given `str`. - * - * @param {String} str - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyString(str, prefix) { - if (!prefix) throw new TypeError('stringify expects an object'); - return prefix + '=' + encodeURIComponent(str); -} - -/** - * Stringify the given `arr`. - * - * @param {Array} arr - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyArray(arr, prefix) { - var ret = []; - if (!prefix) throw new TypeError('stringify expects an object'); - for (var i = 0; i < arr.length; i++) { - ret.push(stringify(arr[i], prefix + '[]')); - } - return ret.join('&'); -} - -/** - * Stringify the given `obj`. - * - * @param {Object} obj - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyObject(obj, prefix) { - var ret = [] - , keys = Object.keys(obj) - , key; - - for (var i = 0, len = keys.length; i < len; ++i) { - key = keys[i]; - ret.push(stringify(obj[key], prefix - ? prefix + '[' + encodeURIComponent(key) + ']' - : encodeURIComponent(key))); - } - - return ret.join('&'); -} - -/** - * Set `obj`'s `key` to `val` respecting - * the weird and wonderful syntax of a qs, - * where "foo=bar&foo=baz" becomes an array. - * - * @param {Object} obj - * @param {String} key - * @param {String} val - * @api private - */ - -function set(obj, key, val) { - var v = obj[key]; - if (undefined === v) { - obj[key] = val; - } else if (Array.isArray(v)) { - v.push(val); - } else { - obj[key] = [v, val]; - } -} - -/** - * Locate last brace in `str` within the key. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function lastBraceInKey(str) { - var len = str.length - , brace - , c; - for (var i = 0; i < len; ++i) { - c = str[i]; - if (']' == c) brace = false; - if ('[' == c) brace = true; - if ('=' == c && !brace) return i; - } -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/package.json deleted file mode 100644 index a4da7d189a6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "qs", - "description": "querystring parser", - "version": "0.4.2", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/node-querystring.git" - }, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "main": "index", - "engines": { - "node": "*" - }, - "readme": "# node-querystring\n\n query string parser for node supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others.\n\n## Installation\n\n $ npm install qs\n\n## Examples\n\n```js\nvar qs = require('qs');\n\nqs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com');\n// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } }\n\nqs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }})\n// => user[name]=Tobi&user[email]=tobi%40learnboost.com\n```\n\n## Testing\n\nInstall dev dependencies:\n\n $ npm install -d\n\nand execute:\n\n $ make test\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/node-querystring/issues" - }, - "_id": "qs@0.4.2", - "dist": { - "shasum": "2d0e20c8184dbf0232ed6861b729c86cbe596fcd" - }, - "_from": "qs@0.4.2", - "_resolved": "https://registry.npmjs.org/qs/-/qs-0.4.2.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/mocha.opts b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/mocha.opts deleted file mode 100644 index 521cbb23543..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/mocha.opts +++ /dev/null @@ -1,2 +0,0 @@ ---require should ---ui exports diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/parse.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/parse.js deleted file mode 100644 index f219e27a276..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/parse.js +++ /dev/null @@ -1,167 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('../'); - -module.exports = { - 'test basics': function(){ - qs.parse('0=foo').should.eql({ '0': 'foo' }); - - qs.parse('foo=c++') - .should.eql({ foo: 'c ' }); - - qs.parse('a[>=]=23') - .should.eql({ a: { '>=': '23' }}); - - qs.parse('a[<=>]==23') - .should.eql({ a: { '<=>': '=23' }}); - - qs.parse('a[==]=23') - .should.eql({ a: { '==': '23' }}); - - qs.parse('foo') - .should.eql({ foo: '' }); - - qs.parse('foo=bar') - .should.eql({ foo: 'bar' }); - - qs.parse('foo%3Dbar=baz') - .should.eql({ foo: 'bar=baz' }); - - qs.parse(' foo = bar = baz ') - .should.eql({ ' foo ': ' bar = baz ' }); - - qs.parse('foo=bar=baz') - .should.eql({ foo: 'bar=baz' }); - - qs.parse('foo=bar&bar=baz') - .should.eql({ foo: 'bar', bar: 'baz' }); - - qs.parse('foo=bar&baz') - .should.eql({ foo: 'bar', baz: '' }); - - qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World') - .should.eql({ - cht: 'p3' - , chd: 't:60,40' - , chs: '250x100' - , chl: 'Hello|World' - }); - }, - - 'test nesting': function(){ - qs.parse('ops[>=]=25') - .should.eql({ ops: { '>=': '25' }}); - - qs.parse('user[name]=tj') - .should.eql({ user: { name: 'tj' }}); - - qs.parse('user[name][first]=tj&user[name][last]=holowaychuk') - .should.eql({ user: { name: { first: 'tj', last: 'holowaychuk' }}}); - }, - - 'test escaping': function(){ - qs.parse('foo=foo%20bar') - .should.eql({ foo: 'foo bar' }); - }, - - 'test arrays': function(){ - qs.parse('images[]') - .should.eql({ images: [] }); - - qs.parse('user[]=tj') - .should.eql({ user: ['tj'] }); - - qs.parse('user[]=tj&user[]=tobi&user[]=jane') - .should.eql({ user: ['tj', 'tobi', 'jane'] }); - - qs.parse('user[names][]=tj&user[names][]=tyler') - .should.eql({ user: { names: ['tj', 'tyler'] }}); - - qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca') - .should.eql({ user: { names: ['tj', 'tyler'], email: 'tj@vision-media.ca' }}); - - qs.parse('items=a&items=b') - .should.eql({ items: ['a', 'b'] }); - - qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ') - .should.eql({ user: { names: ['tj', 'holowaychuk', 'TJ'] }}); - - qs.parse('user[name][first]=tj&user[name][first]=TJ') - .should.eql({ user: { name: { first: ['tj', 'TJ'] }}}); - - var o = qs.parse('existing[fcbaebfecc][name][last]=tj') - o.should.eql({ existing: { 'fcbaebfecc': { name: { last: 'tj' }}}}) - Array.isArray(o.existing).should.be.false; - }, - - 'test right-hand brackets': function(){ - qs.parse('pets=["tobi"]') - .should.eql({ pets: '["tobi"]' }); - - qs.parse('operators=[">=", "<="]') - .should.eql({ operators: '[">=", "<="]' }); - - qs.parse('op[>=]=[1,2,3]') - .should.eql({ op: { '>=': '[1,2,3]' }}); - - qs.parse('op[>=]=[1,2,3]&op[=]=[[[[1]]]]') - .should.eql({ op: { '>=': '[1,2,3]', '=': '[[[[1]]]]' }}); - }, - - 'test duplicates': function(){ - qs.parse('items=bar&items=baz&items=raz') - .should.eql({ items: ['bar', 'baz', 'raz'] }); - }, - - 'test empty': function(){ - qs.parse('').should.eql({}); - qs.parse(undefined).should.eql({}); - qs.parse(null).should.eql({}); - }, - - 'test arrays with indexes': function(){ - qs.parse('foo[0]=bar&foo[1]=baz').should.eql({ foo: ['bar', 'baz'] }); - qs.parse('foo[1]=bar&foo[0]=baz').should.eql({ foo: ['baz', 'bar'] }); - qs.parse('foo[base64]=RAWR').should.eql({ foo: { base64: 'RAWR' }}); - qs.parse('foo[64base]=RAWR').should.eql({ foo: { '64base': 'RAWR' }}); - }, - - 'test arrays becoming objects': function(){ - qs.parse('foo[0]=bar&foo[bad]=baz').should.eql({ foo: { 0: "bar", bad: "baz" }}); - qs.parse('foo[bad]=baz&foo[0]=bar').should.eql({ foo: { 0: "bar", bad: "baz" }}); - }, - - 'test bleed-through of Array native properties/methods': function(){ - Array.prototype.protoProperty = true; - Array.prototype.protoFunction = function () {}; - qs.parse('foo=bar').should.eql({ foo: 'bar' }); - }, - - 'test malformed uri': function(){ - qs.parse('{%:%}').should.eql({ '{%:%}': '' }); - qs.parse('foo=%:%}').should.eql({ 'foo': '%:%}' }); - }, - - 'test semi-parsed': function(){ - qs.parse({ 'user[name]': 'tobi' }) - .should.eql({ user: { name: 'tobi' }}); - - qs.parse({ 'user[name]': 'tobi', 'user[email][main]': 'tobi@lb.com' }) - .should.eql({ user: { name: 'tobi', email: { main: 'tobi@lb.com' } }}); - } - - // 'test complex': function(){ - // qs.parse('users[][name][first]=tj&users[foo]=bar') - // .should.eql({ - // users: [ { name: 'tj' }, { name: 'tobi' }, { foo: 'bar' }] - // }); - // - // qs.parse('users[][name][first]=tj&users[][name][first]=tobi') - // .should.eql({ - // users: [ { name: 'tj' }, { name: 'tobi' }] - // }); - // } -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/stringify.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/stringify.js deleted file mode 100644 index c2195cbca07..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/qs/test/stringify.js +++ /dev/null @@ -1,103 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('../') - , should = require('should') - , str_identities = { - 'basics': [ - { str: 'foo=bar', obj: {'foo' : 'bar'}}, - { str: 'foo=%22bar%22', obj: {'foo' : '\"bar\"'}}, - { str: 'foo=', obj: {'foo': ''}}, - { str: 'foo=1&bar=2', obj: {'foo' : '1', 'bar' : '2'}}, - { str: 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F', obj: {'my weird field': "q1!2\"'w$5&7/z8)?"}}, - { str: 'foo%3Dbaz=bar', obj: {'foo=baz': 'bar'}}, - { str: 'foo=bar&bar=baz', obj: {foo: 'bar', bar: 'baz'}} - ], - 'escaping': [ - { str: 'foo=foo%20bar', obj: {foo: 'foo bar'}}, - { str: 'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld', obj: { - cht: 'p3' - , chd: 't:60,40' - , chs: '250x100' - , chl: 'Hello|World' - }} - ], - 'nested': [ - { str: 'foo[]=bar&foo[]=quux', obj: {'foo' : ['bar', 'quux']}}, - { str: 'foo[]=bar', obj: {foo: ['bar']}}, - { str: 'foo[]=1&foo[]=2', obj: {'foo' : ['1', '2']}}, - { str: 'foo=bar&baz[]=1&baz[]=2&baz[]=3', obj: {'foo' : 'bar', 'baz' : ['1', '2', '3']}}, - { str: 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3', obj: {'foo' : ['bar'], 'baz' : ['1', '2', '3']}}, - { str: 'x[y][z]=1', obj: {'x' : {'y' : {'z' : '1'}}}}, - { str: 'x[y][z][]=1', obj: {'x' : {'y' : {'z' : ['1']}}}}, - { str: 'x[y][z]=2', obj: {'x' : {'y' : {'z' : '2'}}}}, - { str: 'x[y][z][]=1&x[y][z][]=2', obj: {'x' : {'y' : {'z' : ['1', '2']}}}}, - { str: 'x[y][][z]=1', obj: {'x' : {'y' : [{'z' : '1'}]}}}, - { str: 'x[y][][z][]=1', obj: {'x' : {'y' : [{'z' : ['1']}]}}}, - { str: 'x[y][][z]=1&x[y][][w]=2', obj: {'x' : {'y' : [{'z' : '1', 'w' : '2'}]}}}, - { str: 'x[y][][v][w]=1', obj: {'x' : {'y' : [{'v' : {'w' : '1'}}]}}}, - { str: 'x[y][][z]=1&x[y][][v][w]=2', obj: {'x' : {'y' : [{'z' : '1', 'v' : {'w' : '2'}}]}}}, - { str: 'x[y][][z]=1&x[y][][z]=2', obj: {'x' : {'y' : [{'z' : '1'}, {'z' : '2'}]}}}, - { str: 'x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3', obj: {'x' : {'y' : [{'z' : '1', 'w' : 'a'}, {'z' : '2', 'w' : '3'}]}}}, - { str: 'user[name][first]=tj&user[name][last]=holowaychuk', obj: { user: { name: { first: 'tj', last: 'holowaychuk' }}}} - ], - 'errors': [ - { obj: 'foo=bar', message: 'stringify expects an object' }, - { obj: ['foo', 'bar'], message: 'stringify expects an object' } - ], - 'numbers': [ - { str: 'limit[]=1&limit[]=2&limit[]=3', obj: { limit: [1, 2, '3'] }}, - { str: 'limit=1', obj: { limit: 1 }} - ] - }; - - -// Assert error -function err(fn, msg){ - var err; - try { - fn(); - } catch (e) { - should.equal(e.message, msg); - return; - } - throw new Error('no exception thrown, expected "' + msg + '"'); -} - -function test(type) { - var str, obj; - for (var i = 0; i < str_identities[type].length; i++) { - str = str_identities[type][i].str; - obj = str_identities[type][i].obj; - qs.stringify(obj).should.eql(str); - } -} - -module.exports = { - 'test basics': function() { - test('basics'); - }, - - 'test escaping': function() { - test('escaping'); - }, - - 'test nested': function() { - test('nested'); - }, - - 'test numbers': function(){ - test('numbers'); - }, - - 'test errors': function() { - var obj, message; - for (var i = 0; i < str_identities['errors'].length; i++) { - message = str_identities['errors'][i].message; - obj = str_identities['errors'][i].obj; - err(function(){ qs.stringify(obj) }, message); - } - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/History.md deleted file mode 100644 index 4110075a934..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/History.md +++ /dev/null @@ -1,15 +0,0 @@ - -0.0.3 / 2012-07-16 -================== - - * fix normalization of the root directory. Closes #3 - -0.0.2 / 2012-07-09 -================== - - * add passing of req explicitly for now (YUCK) - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Makefile deleted file mode 100644 index a9dcfd50dbd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec \ - --bail - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Readme.md deleted file mode 100644 index 85171a91039..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/Readme.md +++ /dev/null @@ -1,123 +0,0 @@ - -# send - - Send is Connect's `static()` extracted for generalized use, a streaming static file - server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework. - -## Installation - - $ npm install send - -## Examples - - Small: - -```js -var http = require('http'); -var send = require('send'); - -var app = http.createServer(function(req, res){ - send(req, req.url).pipe(res); -}); -``` - - Serving from a root directory with custom error-handling: - -```js -var http = require('http'); -var send = require('send'); - -var app = http.createServer(function(req, res){ - // your custom error-handling logic: - function error(err) { - res.statusCode = err.status || 500; - res.end(err.message); - } - - // your custom directory handling logic: - function redirect() { - res.statusCode = 301; - res.setHeader('Location', req.url + '/'); - res.end('Redirecting to ' + req.url + '/'); - } - - // transfer arbitrary files from within - // /www/example.com/public/* - send(req, url.parse(req.url).pathname) - .root('/www/example.com/public') - .on('error', error) - .on('directory', redirect) - .pipe(res); -}); -``` - -## API - -### Events - - - `error` an error occurred `(err)` - - `directory` a directory was requested - - `stream` file streaming has started `(stream)` - - `end` streaming has completed - -### .root(dir) - - Serve files relative to `path`. Aliased as `.from(dir)`. - -### .index(path) - - By default send supports "index.html" files, to disable this - invoke `.index(false)` or to supply a new index pass a string. - -### .maxage(ms) - - Provide a max-age in milliseconds for http caching, defaults to 0. - -## Error-handling - - By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc. - -## Caching - - It does _not_ perform internal caching, you should use a reverse proxy cache such - as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;). - -## Debugging - - To enable `debug()` instrumentation output export __DEBUG__: - -``` -$ DEBUG=send node app -``` - -## Running tests - -``` -$ npm install -$ make test -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/index.js deleted file mode 100644 index f17158d853e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/send'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/send.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/send.js deleted file mode 100644 index ff6adf9270b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/send.js +++ /dev/null @@ -1,462 +0,0 @@ - -/** - * Module dependencies. - */ - -var debug = require('debug')('send') - , parseRange = require('range-parser') - , Stream = require('stream') - , mime = require('mime') - , fresh = require('fresh') - , path = require('path') - , http = require('http') - , fs = require('fs') - , basename = path.basename - , normalize = path.normalize - , join = path.join - , utils = require('./utils'); - -/** - * Expose `send`. - */ - -exports = module.exports = send; - -/** - * Expose mime module. - */ - -exports.mime = mime; - -/** - * Return a `SendStream` for `req` and `path`. - * - * @param {Request} req - * @param {String} path - * @return {SendStream} - * @api public - */ - -function send(req, path) { - return new SendStream(req, path); -} - -/** - * Initialize a `SendStream` with the given `path`. - * - * Events: - * - * - `error` an error occurred - * - `stream` file streaming has started - * - `end` streaming has completed - * - `directory` a directory was requested - * - * @param {Request} req - * @param {String} path - * @api private - */ - -function SendStream(req, path) { - var self = this; - this.req = req; - this.path = path; - this.maxage(0); - this.hidden(false); - this.index('index.html'); -} - -/** - * Inherits from `Stream.prototype`. - */ - -SendStream.prototype.__proto__ = Stream.prototype; - -/** - * Enable or disable "hidden" (dot) files. - * - * @param {Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.hidden = function(val){ - debug('hidden %s', val); - this._hidden = val; - return this; -}; - -/** - * Set index `path`, set to a falsy - * value to disable index support. - * - * @param {String|Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.index = function(path){ - debug('index %s', path); - this._index = path; - return this; -}; - -/** - * Set root `path`. - * - * @param {String} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.root = -SendStream.prototype.from = function(path){ - this._root = normalize(path); - return this; -}; - -/** - * Set max-age to `ms`. - * - * @param {Number} ms - * @return {SendStream} - * @api public - */ - -SendStream.prototype.maxage = function(ms){ - if (Infinity == ms) ms = 60 * 60 * 24 * 365 * 1000; - debug('max-age %d', ms); - this._maxage = ms; - return this; -}; - -/** - * Emit error with `status`. - * - * @param {Number} status - * @api private - */ - -SendStream.prototype.error = function(status, err){ - var res = this.res; - var msg = http.STATUS_CODES[status]; - err = err || new Error(msg); - err.status = status; - if (this.listeners('error').length) return this.emit('error', err); - res.statusCode = err.status; - res.end(msg); -}; - -/** - * Check if the pathname is potentially malicious. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isMalicious = function(){ - return !this._root && ~this.path.indexOf('..'); -}; - -/** - * Check if the pathname ends with "/". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasTrailingSlash = function(){ - return '/' == this.path[this.path.length - 1]; -}; - -/** - * Check if the basename leads with ".". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasLeadingDot = function(){ - return '.' == basename(this.path)[0]; -}; - -/** - * Check if this is a conditional GET request. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isConditionalGET = function(){ - return this.req.headers['if-none-match'] - || this.req.headers['if-modified-since']; -}; - -/** - * Strip content-* header fields. - * - * @api private - */ - -SendStream.prototype.removeContentHeaderFields = function(){ - var res = this.res; - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); - } - }); -}; - -/** - * Respond with 304 not modified. - * - * @api private - */ - -SendStream.prototype.notModified = function(){ - var res = this.res; - debug('not modified'); - this.removeContentHeaderFields(); - res.statusCode = 304; - res.end(); -}; - -/** - * Check if the request is cacheable, aka - * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isCachable = function(){ - var res = this.res; - return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode; -}; - -/** - * Handle stat() error. - * - * @param {Error} err - * @api private - */ - -SendStream.prototype.onStatError = function(err){ - var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; - if (~notfound.indexOf(err.code)) return this.error(404, err); - this.error(500, err); -}; - -/** - * Check if the cache is fresh. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isFresh = function(){ - return fresh(this.req.headers, this.res._headers); -}; - -/** - * Redirect to `path`. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.redirect = function(path){ - if (this.listeners('directory').length) return this.emit('directory'); - var res = this.res; - path += '/'; - res.statusCode = 301; - res.setHeader('Location', path); - res.end('Redirecting to ' + utils.escape(path)); -}; - -/** - * Pipe to `res. - * - * @param {Stream} res - * @return {Stream} res - * @api public - */ - -SendStream.prototype.pipe = function(res){ - var self = this - , args = arguments - , path = this.path - , root = this._root; - - // references - this.res = res; - - // invalid request uri - path = utils.decode(path); - if (-1 == path) return this.error(400); - - // null byte(s) - if (~path.indexOf('\0')) return this.error(400); - - // join / normalize from optional root dir - if (root) path = normalize(join(this._root, path)); - - // ".." is malicious without "root" - if (this.isMalicious()) return this.error(403); - - // malicious path - if (root && 0 != path.indexOf(root)) return this.error(403); - - // hidden file support - if (!this._hidden && this.hasLeadingDot()) return this.error(404); - - // index file support - if (this._index && this.hasTrailingSlash()) path += this._index; - - debug('stat "%s"', path); - fs.stat(path, function(err, stat){ - if (err) return self.onStatError(err); - if (stat.isDirectory()) return self.redirect(self.path); - self.send(path, stat); - }); - - return res; -}; - -/** - * Transfer `path`. - * - * @param {String} path - * @api public - */ - -SendStream.prototype.send = function(path, stat){ - var options = {}; - var len = stat.size; - var res = this.res; - var req = this.req; - var ranges = req.headers.range; - - // set header fields - this.setHeader(stat); - - // set content-type - this.type(path); - - // conditional GET support - if (this.isConditionalGET() - && this.isCachable() - && this.isFresh()) { - return this.notModified(); - } - - // Range support - if (ranges) { - ranges = parseRange(len, ranges); - - // unsatisfiable - if (-1 == ranges) { - res.setHeader('Content-Range', 'bytes */' + stat.size); - return this.error(416); - } - - // valid (syntactically invalid ranges are treated as a regular response) - if (-2 != ranges) { - options.start = ranges[0].start; - options.end = ranges[0].end; - - // Content-Range - len = options.end - options.start + 1; - res.statusCode = 206; - res.setHeader('Content-Range', 'bytes ' - + options.start - + '-' - + options.end - + '/' - + stat.size); - } - } - - // content-length - res.setHeader('Content-Length', len); - - // HEAD support - if ('HEAD' == req.method) return res.end(); - - this.stream(path, options); -}; - -/** - * Stream `path` to the response. - * - * @param {String} path - * @param {Object} options - * @api private - */ - -SendStream.prototype.stream = function(path, options){ - // TODO: this is all lame, refactor meeee - var self = this; - var res = this.res; - var req = this.req; - - // pipe - var stream = fs.createReadStream(path, options); - this.emit('stream', stream); - stream.pipe(res); - - // socket closed, done with the fd - req.on('close', stream.destroy.bind(stream)); - - // error handling code-smell - stream.on('error', function(err){ - // no hope in responding - if (res._header) { - console.error(err.stack); - req.destroy(); - return; - } - - // 500 - err.status = 500; - self.emit('error', err); - }); - - // end - stream.on('end', function(){ - self.emit('end'); - }); -}; - -/** - * Set content-type based on `path` - * if it hasn't been explicitly set. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.type = function(path){ - var res = this.res; - if (res.getHeader('Content-Type')) return; - var type = mime.lookup(path); - var charset = mime.charsets.lookup(type); - debug('content-type %s', type); - res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); -}; - -/** - * Set reaponse header fields, most - * fields may be pre-defined. - * - * @param {Object} stat - * @api private - */ - -SendStream.prototype.setHeader = function(stat){ - var res = this.res; - res.setHeader('Accept-Ranges', 'bytes'); - if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat)); - if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); - if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (this._maxage / 1000)); - if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString()); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/utils.js deleted file mode 100644 index 950e5a2c13d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/lib/utils.js +++ /dev/null @@ -1,47 +0,0 @@ - -/** - * Return an ETag in the form of `"-"` - * from the given `stat`. - * - * @param {Object} stat - * @return {String} - * @api private - */ - -exports.etag = function(stat) { - return '"' + stat.size + '-' + Number(stat.mtime) + '"'; -}; - -/** - * decodeURIComponent. - * - * Allows V8 to only deoptimize this fn instead of all - * of send(). - * - * @param {String} path - * @api private - */ - -exports.decode = function(path){ - try { - return decodeURIComponent(path); - } catch (err) { - return -1; - } -}; - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/LICENSE b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/LICENSE deleted file mode 100644 index 451fc4550c2..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Benjamin Thomas, Robert Kieffer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/README.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/README.md deleted file mode 100644 index d8b66a86aa6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# mime - -Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community. - -## Install - -Install with [npm](http://github.com/isaacs/npm): - - npm install mime - -## API - Queries - -### mime.lookup(path) -Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. - - var mime = require('mime'); - - mime.lookup('/path/to/file.txt'); // => 'text/plain' - mime.lookup('file.txt'); // => 'text/plain' - mime.lookup('.TXT'); // => 'text/plain' - mime.lookup('htm'); // => 'text/html' - -### mime.extension(type) -Get the default extension for `type` - - mime.extension('text/html'); // => 'html' - mime.extension('application/octet-stream'); // => 'bin' - -### mime.charsets.lookup() - -Map mime-type to charset - - mime.charsets.lookup('text/plain'); // => 'UTF-8' - -(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) - -## API - Defining Custom Types - -The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types). - -### mime.define() - -Add custom mime/extension mappings - - mime.define({ - 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], - 'application/x-my-type': ['x-mt', 'x-mtt'], - // etc ... - }); - - mime.lookup('x-sft'); // => 'text/x-some-format' - -The first entry in the extensions array is returned by `mime.extension()`. E.g. - - mime.extension('text/x-some-format'); // => 'x-sf' - -### mime.load(filepath) - -Load mappings from an Apache ".types" format file - - mime.load('./my_project.types'); - -The .types file format is simple - See the `types` dir for examples. diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/mime.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/mime.js deleted file mode 100644 index 1e00585d300..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/mime.js +++ /dev/null @@ -1,104 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -function Mime() { - // Map of extension -> mime type - this.types = Object.create(null); - - // Map of mime type -> extension - this.extensions = Object.create(null); -} - -/** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * @param map (Object) type definitions - */ -Mime.prototype.define = function (map) { - for (var type in map) { - var exts = map[type]; - - for (var i = 0; i < exts.length; i++) { - this.types[exts[i]] = type; - } - - // Default extension is the first one we encounter - if (!this.extensions[type]) { - this.extensions[type] = exts[0]; - } - } -}; - -/** - * Load an Apache2-style ".types" file - * - * This may be called multiple times (it's expected). Where files declare - * overlapping types/extensions, the last file wins. - * - * @param file (String) path of file to load. - */ -Mime.prototype.load = function(file) { - // Read file and split into lines - var map = {}, - content = fs.readFileSync(file, 'ascii'), - lines = content.split(/[\r\n]+/); - - lines.forEach(function(line) { - // Clean up whitespace/comments, and split into fields - var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); - map[fields.shift()] = fields; - }); - - this.define(map); -}; - -/** - * Lookup a mime type based on extension - */ -Mime.prototype.lookup = function(path, fallback) { - var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); - - return this.types[ext] || fallback || this.default_type; -}; - -/** - * Return file extension associated with a mime type - */ -Mime.prototype.extension = function(mimeType) { - return this.extensions[mimeType]; -}; - -// Default instance -var mime = new Mime(); - -// Load local copy of -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -mime.load(path.join(__dirname, 'types/mime.types')); - -// Load additional types from node.js community -mime.load(path.join(__dirname, 'types/node.types')); - -// Default type -mime.default_type = mime.lookup('bin'); - -// -// Additional API specific to the default instance -// - -mime.Mime = Mime; - -/** - * Lookup a charset based on mime type. - */ -mime.charsets = { - lookup: function(mimeType, fallback) { - // Assume text types are utf8 - return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; - } -} - -module.exports = mime; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/package.json deleted file mode 100644 index 2c13f5efded..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "dependencies": {}, - "description": "A comprehensive library for mime-type mapping", - "devDependencies": {}, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "https://github.com/broofa/node-mime", - "type": "git" - }, - "version": "1.2.6", - "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-mime/issues" - }, - "_id": "mime@1.2.6", - "dist": { - "shasum": "ce180807e42e0051cec41a48e21f06e0ffa37fdd" - }, - "_from": "mime@1.2.6", - "_resolved": "https://registry.npmjs.org/mime/-/mime-1.2.6.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/test.js deleted file mode 100644 index cbad034a18f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/test.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Usage: node test.js - */ - -var mime = require('./mime'); -var assert = require('assert'); - -function eq(a, b) { - console.log('Test: ' + a + ' === ' + b); - assert.strictEqual.apply(null, arguments); -} - -console.log(Object.keys(mime.extensions).length + ' types'); -console.log(Object.keys(mime.types).length + ' extensions\n'); - -// -// Test mime lookups -// - -eq('text/plain', mime.lookup('text.txt')); -eq('text/plain', mime.lookup('.text.txt')); -eq('text/plain', mime.lookup('.txt')); -eq('text/plain', mime.lookup('txt')); -eq('application/octet-stream', mime.lookup('text.nope')); -eq('fallback', mime.lookup('text.fallback', 'fallback')); -eq('application/octet-stream', mime.lookup('constructor')); -eq('text/plain', mime.lookup('TEXT.TXT')); -eq('text/event-stream', mime.lookup('text/event-stream')); -eq('application/x-web-app-manifest+json', mime.lookup('text.webapp')); - -// -// Test extensions -// - -eq('txt', mime.extension(mime.types.text)); -eq('html', mime.extension(mime.types.htm)); -eq('bin', mime.extension('application/octet-stream')); -eq(undefined, mime.extension('constructor')); - -// -// Test node types -// - -eq('application/octet-stream', mime.lookup('file.buffer')); -eq('audio/mp4', mime.lookup('file.m4a')); - -// -// Test charsets -// - -eq('UTF-8', mime.charsets.lookup('text/plain')); -eq(undefined, mime.charsets.lookup(mime.types.js)); -eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); - -console.log('\nOK'); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types deleted file mode 100644 index b3cae2ed810..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types +++ /dev/null @@ -1,1510 +0,0 @@ -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/calendar+xml -# application/cals-1840 -# application/ccmp+xml -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -application/inkml+xml ink inkml -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/onenote onetoc onetoc2 onetmp onepkg -application/oxps oxps -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rpki-ghostbusters gbr -application/rpki-manifest mft -application/rpki-roa roa -# application/rpki-updown -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vcard+xml -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.astraea-software.iota iota -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.collection+json -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -# application/vnd.curl -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.dece.zip uvz uvvz -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -# application/vnd.eprints.data+xml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -# application/vnd.hal+json -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -application/vnd.hzn-3d-crossword x3d -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.packageitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -application/vnd.mynfc taglet -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oftn.l10n+json -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-feature-handler+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.cab-user-prefs+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.pal+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.route66.link66+xml link66 -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.package smzip -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tcpdump.pcap pcap cap dmp -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.through-ngn -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cdlink vcd -application/x-chat chat -application/x-chess-pgn pgn -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff -# application/x-font-vfont -application/x-futuresplash spl -application/x-gnumeric gnumeric -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-stuffit sit -application/x-stuffitx sitx -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xpinstall xpi -# application/x400-bp -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dv -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/fwdred -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/ip-mr_v2.5 -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -audio/ogg oga ogg spx -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.dvb.file dvb -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -audio/x-wav wav -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -# text/fwdred -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -text/vcard vcard -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -text/vnd.dvb.subtitle sub -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-pascal p pas -text/x-java-source java -text/x-setext etx -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.dvb.file dvb -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-ms-asf asf asx -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/node.types b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/node.types deleted file mode 100644 index b7fe8c0d316..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/mime/types/node.types +++ /dev/null @@ -1,65 +0,0 @@ -# What: Google Chrome Extension -# Why: To allow apps to (work) be served with the right content type header. -# http://codereview.chromium.org/2830017 -# Added by: niftylettuce -application/x-chrome-extension crx - -# What: OTF Message Silencer -# Why: To silence the "Resource interpreted as font but transferred with MIME -# type font/otf" message that occurs in Google Chrome -# Added by: niftylettuce -font/opentype otf - -# What: HTC support -# Why: To properly render .htc files such as CSS3PIE -# Added by: niftylettuce -text/x-component htc - -# What: HTML5 application cache manifest -# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps -# per https://developer.mozilla.org/en/offline_resources_in_firefox -# Added by: louisremi -text/cache-manifest appcache manifest - -# What: node binary buffer format -# Why: semi-standard extension w/in the node community -# Added by: tootallnate -application/octet-stream buffer - -# What: The "protected" MP-4 formats used by iTunes. -# Why: Required for streaming music to browsers (?) -# Added by: broofa -application/mp4 m4p -audio/mp4 m4a - -# What: Music playlist format (http://en.wikipedia.org/wiki/M3U) -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -application/x-mpegURL m3u8 - -# What: Video format, Part of RFC1890 -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -video/MP2T ts - -# What: The FLAC lossless codec format -# Why: Streaming and serving FLAC audio -# Added by: jacobrask -audio/flac flac - -# What: EventSource mime type -# Why: mime type of Server-Sent Events stream -# http://www.w3.org/TR/eventsource/#text-event-stream -# Added by: francois2metz -text/event-stream event-stream - -# What: Mozilla App manifest mime type -# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests -# Added by: ednapiranha -application/x-web-app-manifest+json webapp - -# What: Matroska Mime Types -# Why: http://en.wikipedia.org/wiki/Matroska -# Added by: aduncan88 -video/x-matroska mkv -audio/x-matroska mka diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/History.md deleted file mode 100644 index 82df7b1e41e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/History.md +++ /dev/null @@ -1,15 +0,0 @@ - -0.0.4 / 2012-06-17 -================== - - * changed: ret -1 for unsatisfiable and -2 when invalid - -0.0.3 / 2012-06-17 -================== - - * fix last-byte-pos default to len - 1 - -0.0.2 / 2012-06-14 -================== - - * add `.type` diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Readme.md deleted file mode 100644 index b2a67fe834d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/Readme.md +++ /dev/null @@ -1,28 +0,0 @@ - -# node-range-parser - - Range header field parser. - -## Example: - -```js -assert(-1 == parse(200, 'bytes=500-20')); -assert(-2 == parse(200, 'bytes=malformed')); -parse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }])); -parse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }])); -parse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }])); -parse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }])); -parse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }])); -parse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }])); -parse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }])); -parse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }])); -parse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }])); -parse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }])); -parse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }])); -``` - -## Installation - -``` -$ npm install range-parser -``` \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/index.js deleted file mode 100644 index 9b0f7a8ec11..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/index.js +++ /dev/null @@ -1,49 +0,0 @@ - -/** - * Parse "Range" header `str` relative to the given file `size`. - * - * @param {Number} size - * @param {String} str - * @return {Array} - * @api public - */ - -module.exports = function(size, str){ - var valid = true; - var i = str.indexOf('='); - - if (-1 == i) return -2; - - var arr = str.slice(i + 1).split(',').map(function(range){ - var range = range.split('-') - , start = parseInt(range[0], 10) - , end = parseInt(range[1], 10); - - // -nnn - if (isNaN(start)) { - start = size - end; - end = size - 1; - // nnn- - } else if (isNaN(end)) { - end = size - 1; - } - - // limit last-byte-pos to current length - if (end > size - 1) end = size - 1; - - // invalid - if (isNaN(start) - || isNaN(end) - || start > end - || start < 0) valid = false; - - return { - start: start, - end: end - }; - }); - - arr.type = str.slice(0, i); - - return valid ? arr : -1; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/package.json deleted file mode 100644 index d6aa3748167..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/node_modules/range-parser/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "range-parser", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "Range header field string parser", - "version": "0.0.4", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "readme": "\n# node-range-parser\n\n Range header field parser.\n\n## Example:\n\n```js\nassert(-1 == parse(200, 'bytes=500-20'));\nassert(-2 == parse(200, 'bytes=malformed'));\nparse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));\nparse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));\nparse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));\nparse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));\nparse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));\nparse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));\nparse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));\nparse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));\nparse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));\n```\n\n## Installation\n\n```\n$ npm install range-parser\n```", - "readmeFilename": "Readme.md", - "_id": "range-parser@0.0.4", - "dist": { - "shasum": "4b1193f74cfd08bc5b305791c5a00c20a9e5e2b6" - }, - "_from": "range-parser@0.0.4", - "_resolved": "https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/package.json deleted file mode 100644 index 97bf3856aa7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/node_modules/send/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "send", - "version": "0.0.3", - "description": "Better streaming static file server with Range and conditional-GET support", - "keywords": [ - "static", - "file", - "server" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": { - "debug": "*", - "mime": "1.2.6", - "fresh": "0.1.0", - "range-parser": "0.0.4" - }, - "devDependencies": { - "mocha": "*", - "should": "*", - "supertest": "0.0.1", - "connect": "2.x" - }, - "scripts": { - "test": "make test" - }, - "main": "index", - "readme": "\n# send\n\n Send is Connect's `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n $ npm install send\n\n## Examples\n\n Small:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n});\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader('Location', req.url + '/');\n res.end('Redirecting to ' + req.url + '/');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname)\n .root('/www/example.com/public')\n .on('error', error)\n .on('directory', redirect)\n .pipe(res);\n});\n```\n\n## API\n\n### Events\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .root(dir)\n\n Serve files relative to `path`. Aliased as `.from(dir)`.\n\n### .index(path)\n\n By default send supports \"index.html\" files, to disable this\n invoke `.index(false)` or to supply a new index pass a string.\n\n### .maxage(ms)\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ make test\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "_id": "send@0.0.3", - "dist": { - "shasum": "f728cf184038749414b5f641b84f29822258990a" - }, - "_from": "send@0.0.3", - "_resolved": "https://registry.npmjs.org/send/-/send-0.0.3.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/package.json deleted file mode 100644 index 58fe0219bd5..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "connect", - "version": "2.3.9", - "description": "High performance middleware framework", - "keywords": [ - "framework", - "web", - "middleware", - "connect", - "rack" - ], - "repository": { - "type": "git", - "url": "git://github.com/senchalabs/connect.git" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "dependencies": { - "qs": "0.4.2", - "formidable": "1.0.11", - "crc": "0.2.0", - "cookie": "0.0.4", - "bytes": "0.1.0", - "send": "0.0.3", - "fresh": "0.1.0", - "debug": "*" - }, - "devDependencies": { - "should": "*", - "mocha": "*", - "jade": "*", - "dox": "*" - }, - "main": "index", - "engines": { - "node": ">= 0.5.0" - }, - "bugs": { - "url": "https://github.com/senchalabs/connect/issues" - }, - "readme": "ERROR: No README data found!", - "_id": "connect@2.3.9", - "dist": { - "shasum": "5c0043defb1de54960edbc4496dcd964a64d1a94" - }, - "_from": "connect@2.3.9", - "_resolved": "https://registry.npmjs.org/connect/-/connect-2.3.9.tgz" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/connect/test.js deleted file mode 100644 index 822c2bb7d83..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/connect/test.js +++ /dev/null @@ -1,8 +0,0 @@ -var connect = require('./') - , http = require('http'); - -var app = connect() -.use(connect.staticCache()) -.use(connect.static(__dirname)); - -http.createServer(app).listen(3000); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.jshintrc b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.jshintrc deleted file mode 100644 index bbe0a3e8a05..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.jshintrc +++ /dev/null @@ -1,43 +0,0 @@ -{ - "predef": [ - "phantom", - "module", - "require", - "__dirname", - "process", - "console", - "it", - "describe", - "before", - "beforeEach", - "after", - "should", - "rewire", - "$" - ], - - "browser": true, - "node" : true, - "es5": true, - "bitwise": true, - "curly": true, - "eqeqeq": true, - "forin": false, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonew": true, - "plusplus": false, - "undef": true, - "strict": true, - "trailing": false, - "globalstrict": true, - "nonstandard": true, - "white": false, - "indent": 2, - "expr": true, - "multistr": true, - "onevar": false -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.npmignore b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.npmignore deleted file mode 100644 index cbd931a5c04..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -data/ -deps/ -coverage.html -lib-cov -test/ -test_results.md diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.travis.yml deleted file mode 100644 index f0afa7e8376..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 -services: - - mongodb diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/AUTHORS b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/AUTHORS deleted file mode 100644 index 99e04c19eb9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/AUTHORS +++ /dev/null @@ -1,16 +0,0 @@ -# Total 12 contributors. -# Ordered by date of first contribution. -# Auto-generated (http://github.com/dtrejo/node-authors) on Tue Aug 14 2012 02:58:57 GMT+0800 (CST). - -Gui Lin (https://github.com/guileen) -François de Metz (https://github.com/francois2metz) -fengmk2 (http://fengmk2.github.com) -Quang Van (https://github.com/quangv) -Matt Perpick (https://github.com/clutchski) -humanchimp (https://github.com/humanchimp) -Joe Faber (https://github.com/jlfaber) -Harvey McQueen (https://github.com/hmcqueen) -Paul Gebheim (https://github.com/paulirish) -Aneil Mallavarapu (https://github.com/amallavarapu) -wmertens (https://github.com/wmertens) -Rakshit Menpara (https://github.com/deltasquare4) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/History.md b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/History.md deleted file mode 100644 index 25af581994a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/History.md +++ /dev/null @@ -1,61 +0,0 @@ - -0.5.0 / 2012-12-29 -================== - - * fixed unsafe mode warnning log - * Merge pull request #84 from kingpearl/master - * MongoDB 1.2.x support - * Merge pull request #73 from jockster/master - * Merge pull request #75 from voke/patch-1 - * Fix typo - * fixed bind() test cases; - * Minor error in readme. Now updated - * Updated readme according to issue #72 - -0.3.4 / 2011-03-24 - * fix global leaks - -0.3.3 / 2011-03-15 -================== - * Add rootCollection option to SkinGridStore.exist - -0.3.2 / 2011-03-01 -================== - * exports all classes of node-mongodb-native - -0.3.1 / 2011-02-26 -================== - * bug fix #33 - -0.3.0 / 2011-01-19 -================== - * add ReplSet support - * bug fix - -0.2.3 / 2011-01-03 -================== - * add db.toObjectID - * fix #25 for node-mongodb-native update - -0.2.2 / 2011-12-02 -================== - * add bind support for embeded collections, e.g. db.bind('system.js') - * add method `toId` to SkinDB - * add property `ObjectID`, `bson_serializer` to SkinDB. - * SkinCollection.prototype.id is now deprecated. - -0.2.1 / 2011-11-18 -================== - * add ObjectId support for XXXXById - -0.2.0 / 2011-11-06 -================== - * add SkinDB.gridfs - -0.1.3 / 2011-05-24 -================== - * add SkinCollection.removeById - -0.1.2 / 2011-04-30 -================== - * add mongoskin.router diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/LICENSE b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/LICENSE deleted file mode 100644 index e91ac035ea1..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Makefile deleted file mode 100644 index 94d697ebfc6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -TESTS = test/ -TESTTIMEOUT = 60000 -REPORTER = spec -MOCHA_OPTS = -PROJECT_DIR = $(shell pwd) -MONGOSKIN_REPLICASET = false -JSCOVERAGE = ./node_modules/jscover/bin/jscover -SUPPORT_VERSIONS := \ - 1.0.0 1.0.1 1.0.2 \ - 1.1.0-beta 1.1.1 1.1.2 1.1.3 1.1.4 - -test: - @npm install - @if ! test -d deps/mongodb; then \ - git clone git://github.com/mongodb/node-mongodb-native.git deps/mongodb; \ - fi - @cd deps/mongodb && npm install && git pull && cd ../.. - @NODE_ENV=test MONGOSKIN_REPLICASET=$(MONGOSKIN_REPLICASET) \ - ./node_modules/mocha/bin/mocha --recursive \ - --reporter $(REPORTER) --timeout $(TESTTIMEOUT) \ - $(MOCHA_OPTS) $(TESTS) - -test-debug: - @$(MAKE) test MOCHA_OPTS="--debug-brk" - -test-replicaset: - @$(MAKE) test MONGOSKIN_REPLICASET=true - -lib-cov: - @rm -rf $@ - @$(JSCOVERAGE) lib $@ - -test-cov: lib-cov - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=dot - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html - @$(MAKE) test REPORTER=markdown > test_results.md - -test-version: - @for version in $(SUPPORT_VERSIONS); do \ - echo "test with mongodb@$$version"; \ - npm install mongodb@$$version --loglevel=warn; \ - $(MAKE) test REPORTER=dot; \ - done - -.PHONY: test-replicaset test-version test-cov test lib-cov diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Readme.md deleted file mode 100644 index ba39ce97b91..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/Readme.md +++ /dev/null @@ -1,724 +0,0 @@ -# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin) - -![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png) - -This project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native). -The api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first. - -## Test - -* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md) -* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html) - -## Test pass [mongodb] versions - -* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` - when connection open error. -* 1.0.x -* 1.1.x -* 1.2.x - -```bash -$ make test -``` - - - -# Mongoskin document - -* [Nodejs mongodb drivers comparation](#comparation) -* [Install](#install) -* [Quick Start](#quickstart) - * [Connect easier](#quickstart-1) - * [Server options and BSON options](#quickstart-2) - * [Similar API with node-mongodb-native](#quickstart-3) - * [Cursor easier](#quickstart-4) - * [MVC helper](#quickstart-5) -* [Documentation](#documentation) - * [Module](#module) - * [SkinServer](#skinserver) - * [SkinDb](#skindb) - * [SkinCollection](#skincollection) - * [Additional methods](#additional-collection-op) - * [Collection operation](#inherit-collection-op) - * [Indexes](#inherit-indexes) - * [Querying](#inherit-query) - * [Aggregation](#inherit-aggregation) - * [Inserting](#inherit-inserting) - * [Updating](#inherit-updating) - * [Removing](#inherit-removing) - * [SkinCursor](#skincursor) - - - -Nodejs Mongodb Driver Comparison -======== - -node-mongodb-native --------- - -One of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build -on top of it, including mongoskin. Unfortunately, it has an awkward interface with too many -callbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model. - -See [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs) - -mongoose --------- - -Mongoose provides an ORM way to hold Collection instance as Model, - you should define schema first. But why mongodb need schema? - Some guys like me, want to write code from application layer but not database layer, - and we can use any fields without define it before. - - Mongoose provide a DAL that you can do validation, and write your middlewares. - But some guys like me would like to validate manually, I think it is the tao of mongodb. - - If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice. - -mongoskin --------- - -Mongoskin is an easy to use driver of mongodb for nodejs, - it is similar with mongo shell, powerful like node-mongodb-native, - and support additional javascript method binding, which make it can act as a Model(in document way). - -It will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native), - and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29). - -If you need validation, you can use [node-iform](https://github.com/guileen/node-iform). - -[Back to index](#index) - - - -Install -======== - -```bash -$ npm install mongoskin -``` - -[Back to index](#index) - - - - -Quick Start -======== - - **Is mongoskin synchronized?** - -Nope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29). -**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native) - - - -Connect easier --------- -You can connect to mongodb easier now. - -```js -var mongo = require('mongoskin'); -mongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) { - console.dir(items); -}) -``` - - - -Server options and BSON options --------- -You can also set `auto_reconnect` options querystring. -And native_parser options will automatically set if native_parser is available. - -```js -var mongo = require('mongoskin'); -var db = mongo.db('localhost:27017/test?auto_reconnect'); -``` - - - -Similar API with node-mongodb-native --------- -You can do everything that node-mongodb-native can do. - -```js -db.createCollection(...); -db.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {}); -db.collection('posts').hint = 'slug'; -db.collection('posts').findOne({slug: 'whats-up'}, function (err, post) { - // do something -}); -``` - - - -Cursor easier --------- - -```js -db.collection('posts').find().toArray(function (err, posts) { - // do something -}); -``` - - - -MVC helper --------- - -You can bind **additional methods** for collection. -It is very useful if you want to use MVC patterns with nodejs and mongodb. -You can also invoke collection by properties after bind, -it could simplfy your `require`. - -To keep your code in line with DRY principles, it's possible to create your own -data layer by for example, setting up your own validators and/or default values -inside the MVC methods as shown below in the config example - -```js -db.bind('posts', { - findTop10 : function (fn) { - this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn); - }, - removeTagWith : function (tag, fn) { - this.remove({tags:tag},fn); - } - } -}); - -db.bind('settings', { - - getAll: function(user, fn) { - - this.find({user: user}).toArray(function(err, settings) { - - // We want to set a default currency from within our app instead of storing it - // for every user - settings.currency = (typeof settings.currency !== "undefined") ? settings.currency : 'USD'; - - fn(err, settings); - - }); - } -}); - - -db.bind('comments'); - -db.collection('posts').removeTagWith('delete', function (err, replies) { - //do something -}); - -db.posts.findTop10(function (err, topPosts) { - //do something -}); - -db.comments.find().toArray(function (err, comments) { - //do something -}); -``` - -[Back to index](#index) - - - - -Documentation -======== - -for more information, see the source. - -[Back to index](#index) - - - - -Module --------- - -### MongoSkin Url format - -``` -[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]` -``` - -e.g. - -``` -localhost/blog -mongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect -127.0.0.1?auto_reconnect=false -``` - -### db(serverURL[s], dbOptions, replicasetOptions) - -Get or create instance of [SkinDb](#skindb). - -```js -var db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5'); -``` - -for ReplSet server - -```js -var db = mongoskin.db([ - '192.168.0.1:27017/?auto_reconnect=true', - '192.168.0.2:27017/?auto_reconnect=true', - '192.168.0.3:27017/?auto_reconnect=true' -], { - database: 'testdb', - safe: true -}, { - connectArbiter: false, - socketOptions: { - timeout: 2000 - } -}); -``` - -### router(select) - -select is `function(collectionName)` returns a database instance, means router collectionName to that database. - -```js -var db = mongo.router(function (coll_name) { - switch(coll_name) { - case 'user': - case 'message': - return mongo.db('192.168.1.3/auth_db'); - default: - return mongo.db('192.168.1.2/app_db'); - } -}); -db.bind('user', require('./shared-user-methods')); -var users = db.user; //auth_db.user -var messages = db.collection('message'); // auth_db.message -var products = db.collection('product'); //app_db.product -``` - -### classes extends frome node-mongodb-native - -* BSONPure -* BSONNative -* BinaryParser -* Binary -* Code -* DBRef -* Double -* MaxKey -* MinKey -* ObjectID -* Symbol -* Timestamp -* Long -* BaseCommand -* DbCommand -* DeleteCommand -* GetMoreCommand -* InsertCommand -* KillCursorCommand -* QueryCommand -* UpdateCommand -* MongoReply -* Admin -* Collection -* Connection -* Server -* ReplSetServers -* Cursor -* Db -* connect -* Grid -* Chunk -* GridStore -* native -* pure - - -[Back to index](#index) - - - -SkinServer --------- - -### SkinServer(server) - -Construct SkinServer from native Server instance. - -### db(dbname, username=null, password=null) - -Construct [SkinDb](#skindb) from SkinServer. - -[Back to index](#index) - - - -SkinDb --------- - -### SkinDb(db, username=null, password=null) - -Construct SkinDb. - -### open(callback) - -Connect to database, retrieval native -[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) -instance, callback is function(err, db). - -### collection(collectionName) - -Retrieval [SkinCollection](#skincollection) instance of specified collection name. - - - -### bind(collectionName) - -### bind(collectionName, SkinCollection) - -### bind(collectionName, extendObject1, extendObject2 ...) - -Bind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name). -You can also bind additional methods to the SkinCollection, it is useful when -you want to reuse a complex operation. This will also affect -db.collection(name) method. - -e.g. - -```js -db.bind('book', { - firstBook: function (fn) { - this.findOne(fn); - } -}); -db.book.firstBook(function (err, book) {}); -``` - -### all the methods from Db.prototype - -See [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information. - -[Back to index](#index) - - - -SkinCollection --------- - -See [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information. - - -### open(callback) - -Retrieval native -[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) -instance, callback is function(err, collection). - -### id(hex) - -Equivalent to - -```js -db.bson_serializer.ObjectID.createFromHexString(hex); -``` - -See [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548) - - - - -### Collection operation - -```js -checkCollectionName(collectionName) -options(callback) -rename(collectionName, callback) -drop(callback) -``` - - - -### Indexes - -```js -createIndex(fieldOrSpec, unique, callback) -ensureIndex(fieldOrSpec, unique, callback) -indexInformation(callback) -dropIndex(indexName, callback) -dropIndexes(callback) -``` - -See [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md) - - - -### Queries - -See [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md) - -#### findItems(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.toArray(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findEach(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.each(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findById(id, ..., callback) - -Equivalent to - -```js -collection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417) - -#### find(...) - -If the last parameter is function, it is equivalent to native -[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) -method, else it will return a future [SkinCursor](#skincursor). - -e.g. - -```js -// callback -db.book.find({}, function (err, cursor) {/* do something */}); -// future SkinCursor -db.book.find().toArray(function (err, books) {/* do something */}); -``` - -#### normalizeHintField(hint) - -#### find - -```js -/** - * Various argument possibilities - * 1 callback - * 2 selector, callback, - * 2 callback, options // really?! - * 3 selector, fields, callback - * 3 selector, options, callback - * 4,selector, fields, options, callback - * 5 selector, fields, skip, limit, callback - * 6 selector, fields, skip, limit, timeout, callback - * - * Available options: - * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize - */ -``` - -#### findAndModify(query, sort, update, options, callback) - -```js -/** - Fetch and update a collection - query: a filter for the query - sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate - update: an object describing the modifications to the documents selected by the query - options: - remove: set to a true to remove the object before returning - new: set to true if you want to return the modified object rather than the original. Ignored for remove. - upsert: true/false (perform upsert operation) -**/ -``` - -#### findOne(queryObject, options, callback) - - - -### Aggregation - -#### mapReduce(map, reduce, options, callback) - -e.g. - -```js -var map = function () { - emit(test(this.timestamp.getYear()), 1); -} - -var reduce = function (k, v){ - count = 0; - for (i = 0; i < v.length; i++) { - count += v[i]; - } - return count; -} -var options = {scope: {test: new client.bson_serializer.Code(t.toString())}}; -collection.mapReduce(map, reduce, options, function (err, collection) { - collection.find(function (err, cursor) { - cursor.toArray(function (err, results) { - test.equal(2, results[0].value) - finished_test({test_map_reduce_functions_scope:'ok'}); - }) -}) -``` - -#### group(keys, condition, initial, reduce, command, callback) - -e.g. - -```js -collection.group([], {}, {"count":0}, "function (obj, prev) { prev.count++; }", true, function(err, results) {}); -``` - -#### count(query, callback) -#### distinct(key, query, callback) - - - -### Inserting - -#### insert(docs, options, callback) - - - -### Updating - -#### save(doc, options, callback) - -```js -/** - Update a single document in this collection. - spec - a associcated array containing the fields that need to be present in - the document for the update to succeed - - document - an associated array with the fields to be updated or in the case of - a upsert operation the fields to be inserted. - - Options: - upsert - true/false (perform upsert operation) - multi - true/false (update all documents matching spec) - strict - true/false (perform check if the operation failed, required extra call to db) - Deprecated Options: - safe - true/false (perform check if the operation failed, required extra call to db) -**/ -``` - -#### update(spec, document, options, callback) - -#### updateById(_id, ..., callback) - -Equivalent to - -```js -collection.update({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md) - - - -### Removing - -#### remove(selector, options, callback) - -#### removeById(_id, options, callback) - -[Back to index](#index) - - - -SkinCursor ---------- - -See [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1) -of node-mongodb-native for more information. - -All these methods will return the SkinCursor itself. - -```js -sort(keyOrList, [direction], [callback]) -limit(limit, [callback]) -skip(skip, [callback]) -batchSize(skip, [callback]) - -toArray(callback) -each(callback) -count(callback) -nextObject(callback) -getMore(callback) -explain(callback) -``` - -[Back to index](#index) - -## How to validate input? - -I wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) -base on [node-validator](https://github.com/chriso/node-validator) - -## Authors - -Below is the output from `git-summary`. - -``` - project: node-mongoskin - commits: 112 - active : 54 days - files : 39 - authors: - 49 Lin Gui 43.8% - 34 guilin 桂林 30.4% - 9 fengmk2 8.0% - 5 guilin 4.5% - 2 François de Metz 1.8% - 2 Paul Gebheim 1.8% - 2 Gui Lin 1.8% - 1 humanchimp 0.9% - 1 Aneil Mallavarapu 0.9% - 1 wmertens 0.9% - 1 Harvey McQueen 0.9% - 1 Joe Faber 0.9% - 1 Matt Perpick 0.9% - 1 Quang Van 0.9% - 1 Rakshit Menpara 0.9% - 1 Wout Mertens 0.9% -``` - -## License - -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/admin.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/admin.js deleted file mode 100644 index f32eee53546..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/admin.js +++ /dev/null @@ -1,9 +0,0 @@ -var db = require('./config').db; - -db.admin.listDatabases(function(err, result){ - if(err) { - console.traceError(err); - } - console.log(result); - db.close(); -}) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/close.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/close.js deleted file mode 100644 index 73fafaa1381..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/close.js +++ /dev/null @@ -1,15 +0,0 @@ -var db = require('./config').db; - -db.collection('test').findOne({}, function(err, data) { - if(!err) { - console.log('db has open'); - console.log(data); - } -}); - -process.on('SIGINT', function() { - console.log('Recieve SIGINT'); - db.close(function(){ - console.log('database has closed'); - }) -}) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/config.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/config.js deleted file mode 100644 index 80c9184a9d7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/config.js +++ /dev/null @@ -1,5 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -exports.db = mongoskin.db('localhost/test'); - -mongoskin.db('localhost', { database: 'test' }); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/generateId.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/generateId.js deleted file mode 100644 index 6acb4bfe4df..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/generateId.js +++ /dev/null @@ -1,31 +0,0 @@ -var redis = require('redis').createClient() - , shorten = require('shorten')(redis) - , async = require('async') - , db = require('./config').db - ; - -db.bind('user'); - -function log(err) { - if(err) { - console.log(err.stack); - } -} - -function createUser(user, callback) { - - async.waterfall([ - function(fn) { - shorten.nextId('user', fn); - } - , function(uid, fn) { - user.uid = uid; - db.user.save(user, fn); - } - ], callback); - -} - -for(var i = 0; i<10; i++) { - createUser({name: 'user' + i}, log); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/gridfs.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/gridfs.js deleted file mode 100644 index ce476a3bba0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/gridfs.js +++ /dev/null @@ -1,13 +0,0 @@ -var db = require('./config').db; - -db.gridfs().open('test.txt', 'w', function(err, gs) { - gs.write('blablabla', function(err, reply) { - gs.close(function(err, reply){ - db.gridfs().open('test.txt', 'r' ,function(err, gs) { - gs.read(function(err, reply){ - console.log(reply.toString()); - }); - }); - }); - }); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/insert.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/insert.js deleted file mode 100644 index bba4c58007f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/insert.js +++ /dev/null @@ -1,8 +0,0 @@ -var db = require('./config').db; - -db.collection('test').insert({foo: 'bar'}, function(err, result) { - console.log(result); - db.collection('test').drop(); - db.close(); - -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replSetBenchmark.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replSetBenchmark.js deleted file mode 100644 index bacd59eb3d0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replSetBenchmark.js +++ /dev/null @@ -1,45 +0,0 @@ - -var mongo = require('../'); - -var conf = { - hosts: [ - '127.0.0.1:27110/?auto_reconnect', - '127.0.0.1:27111/?auto_reconnect' - ], - dataDB: 'test' -}; - -var db = exports.db = mongo.db(conf.hosts, { - database: conf.dataDB -}); - -var noop = function() {}; - -db.bind('user'); -// db.user.ensureIndex({ name: 1 }, { unique: true }, noop); -// db.user.ensureIndex({ enable: 1 }, noop); -// db.user.ensureIndex({ created_at: 1, enable: 1 }, noop); - -var counter = 0; -setInterval(function () { - db.user.findItems({ name: 'name_' + counter }, function (err, items) { - if (err) { - console.error('findItems user error', err); - } - if (items) { - console.log('total: %d users', items.length); - } - }); - db.user.insert({ - name: 'name_' + counter, - createtime: new Date() - }, function(err, user) { - if (err) { - console.error('insert user error', err); - } - if (user && user[0]) { - console.log('new: %d %s', counter, user[0]._id); - } - }); - counter++; -}, 10); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replset.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replset.js deleted file mode 100644 index 4e3dc616ccf..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/replset.js +++ /dev/null @@ -1,10 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -var db = mongoskin.db(['127.0.0.1:27017'], { - database: 'test' -}); - -db.open(function(err, data) { - console.log(err && err.stack); - console.log(data); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/update.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/update.js deleted file mode 100644 index 080d84e3807..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/examples/update.js +++ /dev/null @@ -1,19 +0,0 @@ -var db = require('./config').db; -var articles = db.collection('articles'); -articles.insert({foo: 'bar', val: 'val1'}, function(err, result) { - - console.log(result); - articles.update({foo:'bar'}, {foo: 'bar', val:'val2'}, {strict: true}, function(err, result) { - - console.log(result); - articles.find({foo: 'bar'}).toArray(function(err, docs){ - - console.log(docs); - articles.drop(); - db.close(); - - }); - - }) - -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/index.js deleted file mode 100644 index dd996affa95..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = process.env.MONGOSKIN_COV ? require('./lib-cov/mongoskin') : require('./lib/mongoskin'); \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/integration_tests.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/integration_tests.js deleted file mode 100644 index 7a34db70fa1..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/integration_tests.js +++ /dev/null @@ -1,203 +0,0 @@ -GLOBAL.DEBUG = true; - -var assert = require('assert'), - mongo = require('../lib/mongoskin'); - -console.log('======== test MongoSkin.db ========'); -(function(){ - var username = 'testuser', - password = 'password'; - - db = mongo.db('localhost/test'); - db.open(function(err, db) { - assert.ok(!err); - assert.ok(db, err && err.stack); - db.addUser(username, password, function(err, result){ - var authdb = mongo.db(username + ':' + password +'@localhost/test'); - authdb.open(function(err, db){ - assert.ok(!err, err && err.stack); - }); - var faildb = mongo.db(username + ':wrongpassword@localhost/test'); - faildb.open(function(err, db){ - assert.ok(err, 'should not auth'); - assert.ok(!db, 'should not return db'); - }); - }); - }); -})(); - -(function(){ - db = mongo.db('db://admin:admin@localhost:27017/test?auto_reconnect'); - db.open(function(err, db){ - assert.ok(err instanceof Error); - }) -})(); - -var bindToBlog = { - first: function(fn) { - this.findOne(fn); - } -}; - -console.log('======== test MongoSkin.router ========'); -var testdb1 = mongo.db('localhost/test1'); -var testdb2 = mongo.db('localhost/test2'); -var router = mongo.router(function(name){ - switch(name){ - case 'user': - case 'message': - return testdb1; - default: - return testdb2; - } -}); -assert.equal(router.collection('user'), testdb1.collection('user'), 'user should router to testdb1'); -assert.equal(router.collection('message'), testdb1.collection('message'), 'message should router to testdb1'); -assert.equal(router.collection('others'), testdb2.collection('others'), 'others should router to testdb2'); -router.bind('user'); -router.bind('others'); -assert.equal(router.user, testdb1.user, 'user property should router to testdb1'); -assert.equal(router.others, testdb2.others, 'user property should router to testdb1'); - -console.log('======== test MongoSkin.bind ========'); -var db = mongo.db('localhost/test_mongoskin'); -db.bind('blog', bindToBlog); -db.bind('users'); -assert.equal(db.blog.first, bindToBlog.first); -assert.ok(db.users); - -console.log('======== test SkinDb bson ========'); -assert.ok(db.ObjectID.createFromHexString('a7b79d4dca9d730000000000')); - -console.log('======== test SkinDb.bind ========'); -db.bind('blog2', bindToBlog); -db.bind('user2'); -assert.equal(db.blog2.first, bindToBlog.first); -assert.ok(db.user2); - -console.log('======== test SkinDb.open ========'); -(function(){ - var db1, db2; - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db1 = db; - assert.equal(db1.state, 'connected'); - if (db2) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db2 = db; - assert.equal(db2.state, 'connected'); - if (db1) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - -})() - -console.log('======== test normal method of SkinDb ========'); -db.createCollection('test_createCollection', function(err, collection) { - assert.equal(db.db.state, 'connected'); - assert.ok(collection, err && err.stack); -}); - - -console.log('======== test SkinDb.collection ========'); -assert.equal(db.blog, db.collection('blog')); - -console.log('======== test SkinCollection.open ========'); -var coll1, coll2; -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll1 = coll; - if (coll2) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll2 = coll; - if (coll1) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -console.log('======== test normal method of SkinCollection ========'); -db.collection('test_normal').ensureIndex([['a',1]], function(err, replies){ - assert.ok(replies, err && err.stack); -}); - -console.log('======== test SkinCollection.drop ========'); -db.collection('test_find').drop(function(err, replies){ - assert.ok(!err, err && err.stack); -}); - -console.log('======== test SkinCollection.find ========'); -collection = db.collection('test_find'); -collection.insert([{a:1},{a:2},{a:3},{a:4}], function(err, replies){ - assert.ok(replies, err && err.stack); - console.log('======== test SkinCollection.findById ========'); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.equal(item.a, 1); - console.log('======== test SkinCollection.removeById ========'); - collection.removeById(replies[0]._id.toString(), function(err, reply){ - assert.ok(!err, err && err.stack); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.ok(!err); - assert.ok(!item); - }); - }); - }); -}); - - - collection.findItems(function(err, items){ - assert.ok(items, err && err.stack); - console.log('found '+ items.length + ' items'); - }); - collection.findEach(function(err, item){ - assert.ok(!err, err && err.stack); - }); - collection.find(function(err, cursor){ - assert.ok(cursor, err && err.stack); - }); - - console.log('======== test SkinCursor ========'); - collection.find().toArray(function(err, items){ - console.log('======== test find cursor toArray========'); - assert.ok(items, err && err.stack); - }); - collection.find().each(function(err, item){ - console.log('======== test find cursor each========'); - assert.ok(!err, err && err.stack); - }); - collection.find().sort({a:-1}).limit(2).skip(1).toArray(function(err, items){ - console.log('======== test cursor sort() limit() skip() ========'); - assert.ok(!err, err && err.stack); - console.dir(items); - }); - -console.log('======== deep future test ========'); -(function(){ - var db2 = mongo.db('localhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(!err, err && err.stack); - }) -})(); - -(function(){ - var db2 = mongo.db('unknownhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(err); - }) -})(); -/* -console.log('======== test SkinDb.close ========'); -db.close(); -assert.equal(db.db.state, 'notConnected'); -*/ - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/longlive.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/longlive.js deleted file mode 100644 index 828f71a1bdb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/integration/longlive.js +++ /dev/null @@ -1,28 +0,0 @@ -var mongo = require('../'); -var db = mongo.db('192.168.0.103/test'); -// var db = mongo.db('127.0.0.1/test'); -var myconsole = require('myconsole'); - -var foo = db.collection('foo'); - -setInterval(function() { - foo.insert({foo:'foo'}, function(err, result){ - if(err) return myconsole.error(err); - foo.count(function(err, count){ - if(err) return myconsole.error(err); - myconsole.log('count: %d', count); - foo.find().limit(10).toArray(function(err, arr) { - if(err) return myconsole.error(err); - myconsole.log('arr: %d', arr.length); - }) - }) - }) -}, 500); - -process.on('SIGINT', function(){ - myconsole.log('SIGINT') - foo.drop(function(err){ - if(err) myconsole.error(err); - process.exit(); - }) -}) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/admin.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/admin.js deleted file mode 100644 index 035e2087d7b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/admin.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - admin.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var Admin = require('mongodb').Admin; -var utils = require('./utils'); -var constant = require('./constant'); - -/** - * SkinAdmin - * - * @param {SkinDb} skinDb - * @constructor - * @api public - */ -var SkinAdmin = exports.SkinAdmin = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; - this.admin = null; -}; - -utils.inherits(SkinAdmin, utils.SkinObject); - -/** - * Retrieve mongodb.Admin instance. - * - * @param {Function(err, admin)} callback - * @return {SkinAdmin} this - * @api public - */ -SkinAdmin.prototype.open = function (callback) { - if (this.state === constant.STATE_OPEN) { - callback(null, this.admin); - return this; - } - this.emitter.once('open', callback); - if (this.state === constant.STATE_OPENNING) { - return this; - } - this.state = constant.STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.admin = null; - this.state = constant.STATE_CLOSE; - } else { - this.admin = new Admin(db); - this.state = constant.STATE_OPEN; - } - this.emitter.emit('open', err, this.admin); - }.bind(this)); - return this; -}; - -for (var key in Admin.prototype) { - var method = Admin.prototype[key]; - utils.bindSkin('SkinAdmin', SkinAdmin, 'admin', key, method); -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/collection.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/collection.js deleted file mode 100644 index 20302026747..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/collection.js +++ /dev/null @@ -1,300 +0,0 @@ -/*! - * mongoskin - collection.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - bind these methods from Collection.prototype to Provider - - methods: - insert - checkCollectionName - remove - rename - save - update - distinct - count - drop - findAndModify - find - normalizeHintField - findOne - createIndex - ensureIndex - indexInformation - dropIndex - dropIndexes - mapReduce - group - options -*/ -var __slice = Array.prototype.slice; -var events = require('events'); -var Collection = require('mongodb').Collection; -var SkinCursor = require('./cursor').SkinCursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * Construct SkinCollection from SkinDb and collectionName - * use skinDb.collection('name') usually - * - * @param {SkinDb} skinDb - * @param {String} collectionName - * @param {Object} [options] collection options - * @constructor - * @api public - */ -var SkinCollection = exports.SkinCollection = function (skinDb, collectionName, options) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(50); - - this.options = options; - this.skinDb = skinDb; - this.ObjectID = this.skinDb.ObjectID; - this.collectionName = collectionName; - this.collection = null; - this.internalHint = null; - this.__defineGetter__('hint', function () { - return this.internalHint; - }); - this.__defineSetter__('hint', function (value) { - this.internalHint = value; - this.open(function (err, collection) { - collection.hint = value; - this.internalHint = collection.hint; - }.bind(this)); - }); -}; - -utils.inherits(SkinCollection, utils.SkinObject); - -for (var _name in Collection.prototype) { - var method = Collection.prototype[_name]; - utils.bindSkin('SkinCollection', SkinCollection, 'collection', _name, method); -} - -/* - * find is a special method, because it could return a SkinCursor instance - */ -SkinCollection.prototype._find = SkinCollection.prototype.find; - -/** - * Retrieve mongodb.Collection - * - * @param {Function(err, collection)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.collection); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.state = STATE_CLOSE; - return this.emitter.emit('open', err, null); - } - db.collection(this.collectionName, this.options, function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - } else { - this.state = STATE_OPEN; - this.collection = collection; - if (this.hint) { - this.collection.hint = this.hit; - } - } - this.emitter.emit('open', err, collection); - }.bind(this)); - }.bind(this)); - break; - } - return this; -}; - -/** - * Close current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.close = function (callback) { - this.collection = null; - this.state = STATE_CLOSE; - return this; -}; - -/** - * Drop current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.drop = function (callback) { - this.skinDb.dropCollection(this.collectionName, callback); - this.close(); - return this; -}; - -/** - * same args as find, but use Array as callback result but not use Cursor - * - * findItems(args, function (err, items) {}); - * - * same as - * - * find(args).toArray(function (err, items) {}); - * - * or using `mongodb.collection.find()` - * - * find(args, function (err, cursor) { - * cursor.toArray(function (err, items) { - * }); - * }); - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, docs)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findItems = function (query, options, callback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.toArray(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * find and cursor.each(fn). - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, item)} eachCallback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findEach = function (query, options, eachCallback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.each(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * @deprecated use `SkinDb.toId` instead - * - * @param {String} hex - * @return {ObjectID|String} - * @api public - */ -SkinCollection.prototype.id = function (hex) { - return this.skinDb.toId(hex); -}; - -/** - * Operate by object.`_id` - * - * @param {String} methodName - * @param {String|ObjectID|Number} id - * @param {Arguments|Array} args - * @return {SkinCollection} this - * @api private - */ -SkinCollection.prototype._operateById = function (methodName, id, args) { - args = __slice.call(args); - args[0] = {_id: this.skinDb.toId(id)}; - this[methodName].apply(this, args); - return this; -}; - -/** - * Find one object by _id. - * - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err, doc)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findById = function (id, callback) { - return this._operateById('findOne', id, arguments); -}; - -/** - * Update doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Object} doc - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.updateById = function (id, doc, callback) { - return this._operateById('update', id, arguments); -}; - -/** - * Remove doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.removeById = function (id, callback) { - return this._operateById('remove', id, arguments); -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB. - * - * @param {Object} query - * @param {Object} options - * @param {Function(err, docs)} callback - * @return {SkinCursor|SkinCollection} if last argument is not a function, then returns a SkinCursor, - * otherise return this - * @api public - */ -SkinCollection.prototype.find = function (query, options, callback) { - var args = __slice.call(arguments); - if (args.length > 0 && typeof args[args.length - 1] === 'function') { - this._find.apply(this, args); - return this; - } else { - return new SkinCursor(null, this, args); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/constant.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/constant.js deleted file mode 100644 index b9fb90704ac..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/constant.js +++ /dev/null @@ -1,15 +0,0 @@ -/*! - * mongoskin - constant.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -exports.DEFAULT_PORT = 27017; - -exports.STATE_CLOSE = 0; -exports.STATE_OPENNING = 1; -exports.STATE_OPEN = 2; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/cursor.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/cursor.js deleted file mode 100644 index a879d80a473..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/cursor.js +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * mongoskin - cursor.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter; -var Cursor = require('mongodb').Cursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -var SkinCursor = exports.SkinCursor = function (cursor, skinCollection, args) { - utils.SkinObject.call(this); - - this.cursor = cursor; - this.skinCollection = skinCollection; - this.args = args || []; - this.emitter = new EventEmitter(); - if (cursor) { - this.state = STATE_OPEN; - } -}; - -utils.inherits(SkinCursor, utils.SkinObject); - -/** - * Retrieve mongodb.Cursor instance. - * - * @param {Function(err, cursor)} callback - * @return {SkinCursor} this - * @api public - */ -SkinCursor.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.cursor); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinCollection.open(function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - this.emitter.emit('open', err); - return; - } - // copy args - var args = this.args.slice(); - args.push(function (err, cursor) { - if (cursor) { - this.state = STATE_OPEN; - this.cursor = cursor; - } - this.emitter.emit('open', err, cursor); - }.bind(this)); - collection.find.apply(collection, args); - }.bind(this)); - break; - } - return this; -}; - -[ - // callbacks - 'toArray', 'each', 'count', 'nextObject', 'getMore', 'explain', - // self return - 'sort', 'limit', 'skip', 'batchSize', - // unsupported - //'rewind', 'close' ,... -].forEach(function (name) { - var method = Cursor.prototype[name]; - utils.bindSkin('SkinCursor', SkinCursor, 'cursor', name, method); -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/db.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/db.js deleted file mode 100644 index f954a52ff5b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/db.js +++ /dev/null @@ -1,254 +0,0 @@ -/*! - * mongoskin - db.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var mongodb = require('mongodb'); -var utils = require('./utils'); -var SkinAdmin = require('./admin').SkinAdmin; -var SkinCollection = require('./collection').SkinCollection; -var SkinGridStore = require('./gridfs').SkinGridStore; -var Db = mongodb.Db; -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * SkinDb - * - * @param {Db} dbconn, mongodb.Db instance - * @param {String} [username] - * @param {String} [password] - * @constructor - * @api public - */ -var SkinDb = exports.SkinDb = function (dbconn, username, password) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(100); - - this._dbconn = dbconn; - this.db = null; - this.username = username; - this.password = password; - this.admin = new SkinAdmin(this); - this._collections = {}; - this.bson_serializer = dbconn.bson_serializer; - this.ObjectID = mongodb.ObjectID /* 0.9.7-3-2 */ || dbconn.bson_serializer.ObjectID /* <= 0.9.7 */; -}; - -utils.inherits(SkinDb, utils.SkinObject); - -/** - * Convert to ObjectID. - * - * @param {String} hex - * @return {ObjectID} - */ -SkinDb.prototype.toObjectID = SkinDb.prototype.toId = function (hex) { - if (hex instanceof this.ObjectID) { - return hex; - } - if (!hex || hex.length !== 24) { - return hex; - } - return this.ObjectID.createFromHexString(hex); -}; - - -/** - * Open the database connection. - * - * @param {Function(err, nativeDb)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback && callback(null, this.db); - break; - case STATE_OPENNING: - // if call 'open' method multi times before opened - callback && this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - var onDbOpen = function (err, db) { - if (!err && db) { - this.db = db; - this.state = STATE_OPEN; - } else { - db && db.close(); - // close the openning connection. - this._dbconn.close(); - this.db = null; - this.state = STATE_CLOSE; - } - this.emitter.emit('open', err, this.db); - }.bind(this); - callback && this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this._dbconn.open(function (err, db) { - if (db && this.username) { - // do authenticate - db.authenticate(this.username, this.password, function (err) { - onDbOpen(err, db); - }); - } else { - onDbOpen(err, db); - } - }.bind(this)); - break; - } - return this; -}; - -/** - * Close the database connection. - * - * @param {Function(err)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.close = function (callback) { - if (this.state === STATE_CLOSE) { - callback && callback(); - } else if (this.state === STATE_OPEN) { - this.state = STATE_CLOSE; - this.db.close(callback); - } else if (this.state === STATE_OPENNING) { - var that = this; - this.emitter.once('open', function (err, db) { - that.state = STATE_CLOSE; - db ? db.close(callback) : callback && callback(err); - }); - } - return this; -}; - -/** - * Create or retrieval skin collection - * - * @param {String} name, the collection name. - * @param {Object} [options] collection options. - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.collection = function (name, options) { - var collection = this._collections[name]; - if (!collection) { - this._collections[name] = collection = new SkinCollection(this, name, options); - } - return collection; -}; - -/** - * gridfs - * - * @return {SkinGridStore} - * @api public - */ -SkinDb.prototype.gridfs = function () { - return this.skinGridStore || (this.skinGridStore = new SkinGridStore(this)); -}; - -/** - * bind additional method to SkinCollection - * - * 1. collectionName - * 2. collectionName, extends1, extends2,... extendsn - * 3. collectionName, SkinCollection - * - * @param {String} collectionName - * @param {Object|SkinCollection} [options] - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.bind = function (collectionName, options) { - var args = __slice.call(arguments); - var name = args[0]; - - if (typeof name !== 'string' || !name.trim()) { - throw new Error('Must provide collection name to bind.'); - } - if (args.length === 1) { - return this.bind(name, this.collection(name)); - } - if (args.length === 2 && args[1].constructor === SkinCollection) { - this._collections[name] = args[1]; - Object.defineProperty(this, name, { - value: args[1], - writable: false, - enumerable: true - }); - // support bind for system.js - var names = name.split('.'); - if (names.length > 1){ - var prev = this, next; - for (var i = 0; i < names.length - 1; i++) { - next = prev[names[i]]; - if (!next) { - next = {}; - Object.defineProperty(prev, names[i], { - value: next, - writable: false, - enumerable : true - }); - } - prev = next; - } - Object.defineProperty(prev, names[names.length - 1], { - value: args[1], - writable: false, - enumerable : true - }); - } - return args[1]; - } - - var isOptions = false; - var argsIndex = 1; - if (options && typeof options === 'object') { - isOptions = true; - argsIndex = 2; - for (var k in options) { - if (typeof options[k] === 'function') { - isOptions = false; - argsIndex = 1; - break; - } - } - } - var collection = this.collection(name, isOptions ? options : null); - for (var len = args.length; argsIndex < len; argsIndex++) { - var extend = args[argsIndex]; - if (typeof extend !== 'object') { - throw new Error('the args[' + argsIndex + '] should be object, but is `' + extend + '`'); - } - utils.extend(collection, extend); - } - return this.bind(name, collection); -}; - -var IGNORE_NAMES = [ - 'bind', 'open', 'close', 'collection', 'admin', 'state' -]; -// bind method of mongodb.Db to SkinDb -for (var key in Db.prototype) { - if (!key || key[0] === '_' || IGNORE_NAMES.indexOf(key) >= 0) { - continue; - } - var method = Db.prototype[key]; - utils.bindSkin('SkinDb', SkinDb, 'db', key, method); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/gridfs.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/gridfs.js deleted file mode 100644 index 603e9e9a67c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/gridfs.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - gridfs.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var GridStore = require('mongodb').GridStore; -var utils = require('./utils'); - -/** - * @param filename: filename or ObjectId - */ -var SkinGridStore = exports.SkinGridStore = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; -}; - -utils.inherits(SkinGridStore, utils.SkinObject); - -/** - * @param id - * @param filename - * @param mode - * @param options - * @param callback - * callback(err, gridStoreObject) - */ -SkinGridStore.prototype.open = function (id, filename, mode, options, callback) { - var args = Array.prototype.slice.call(arguments); - callback = args.pop(); - this.skinDb.open(function (err, db) { - var gs = new GridStore(db, args[0], args[1], args[2], args[3]); - var props = { - length: gs.length, - contentType: gs.contentType, - uploadDate: gs.uploadDate, - metadata: gs.metadata, - chunkSize: gs.chunkSize - }; - - gs.open(function (error, reply) { - callback(error, reply, props); - }); - }); -}; - -/** - * @param filename: filename or ObjectId - */ -SkinGridStore.prototype.unlink = SkinGridStore.prototype.remove = function (filename, callback) { - this.skinDb.open(function (err, db) { - GridStore.unlink(db, filename, callback); - }); -}; - -SkinGridStore.prototype.exist = function (filename, rootCollection, callback) { - this.skinDb.open(function (err, db) { - GridStore.exist(db, filename, rootCollection, callback); - }); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/index.js deleted file mode 100644 index db051fc3115..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/index.js +++ /dev/null @@ -1,200 +0,0 @@ -/*! - * mongoskin - index.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var url = require('url'); -var Router = require('./router').Router; -var mongo = require('mongodb'); -var SkinServer = require('./server').SkinServer; -var SkinDb =require('./db').SkinDb; -var Db = mongo.Db; -var Server = mongo.Server; -var ReplSetServers = mongo.ReplSetServers; -var BSONNative = mongo.BSONNative; -var constant = require('./constant'); -var DEFAULT_PORT = constant.DEFAULT_PORT; - -function toBool(value) { - return value !== undefined && value !== 'false' && value !== 'no' && value !== 'off'; -} - -/** - * parse the database url to config - * - * [*://]username:password@host[:port]/database?options - * - * @param {String} serverUrl - * @return {Object} config - * - {String} host - * - {Number} port, default is `DEFAULT_PORT`. - * - {String} [database], no database by default. - * - {Object} options - * - {Bool} auto_reconnect, default is `false`. - * - {Number} poolSize, default is `1`. - * - {String} [username], no username by default. - * - {String} [password], no password by default. - * @api private - */ -var parseUrl = function (serverUrl) { - serverUrl = /\w+:\/\//.test(serverUrl) ? serverUrl : 'db://' + serverUrl; - var uri = url.parse(serverUrl, true); - var config = {}; - var serverOptions = uri.query; - - config.host = uri.hostname; - config.port = parseInt(uri.port, 10) || DEFAULT_PORT; - if (uri.pathname) { - config.database = uri.pathname.replace(/\//g, ''); - } - config.options = {}; - config.options.auto_reconnect = toBool(serverOptions.auto_reconnect); - config.options.poolSize = parseInt(serverOptions.poolSize || 1, 10); - if (uri && uri.auth) { - var auth = uri.auth; - var separator = auth.indexOf(':'); - config.username = auth.substr(0, separator); - config.password = auth.substr(separator + 1); - } - return config; -}; - -/** - * constructor Server from url - * - * @param {String} serverUrl - * @return {Server} - * @api private - */ -var parseServer = function (serverUrl) { - var config = parseUrl(serverUrl); - return new Server(config.host, config.port, config.options); -}; - -/* - * exports mongo classes ObjectID Long Code DbRef ... to mongoskin - */ -for (var key in mongo) { - exports[key] = mongo[key]; -} - -/** - * constructor SkinDb from serverURL[s] - * - * ReplicaSet: mongoskin.db(serverURLs, dbOptions, replicasetOptions) - * - * ```js - * mongoskin.db([ - * '192.168.0.1:27017/', - * '192.168.0.2/?auto_reconnect', - * '192.168.0.3' - * ], {database: 'mydb'}, {connectArbiter: false, socketOptions: {timeout: 2000}}); - * ``` - * - * Single Server: mongoskin.db(dbURL, options) - * - * ```js - * mongoskin.db('192.168.0.1:27017/mydb'); - * // or - * mongoskin.db('192.168.0.1:27017', {database: 'mydb'}); - * // set the connection timeout to `2000ms` - * mongoskin.db('192.168.0.1:27017', {database: 'mydb', socketOptions: {timeout: 2000}}); - * ``` - * - * @param {String|Array} serverUrl or server urls. - * @param {Object} [dbOptions] - * - {Object} socketOptions: @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#socket-options - * - the other, @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#db-options - * @param {Object} [replicasetOptions], options for replicaset. - * The detail of this options, please - * @see https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/connection/repl_set.js#L27. - * @return {SkinDb} - * @api public - */ -exports.db = function (serverUrl, dbOptions, replicasetOptions) { - dbOptions = dbOptions || {}; - - var server, database, config; - - if (Array.isArray(serverUrl)) { - if (!dbOptions.database) { - throw new Error('Please provide a database in `dbOptions` to connect.'); - } - database = dbOptions.database; - - var len = serverUrl.length; - var servers = []; - for (var i = 0; i < len; i++) { - config = parseUrl(serverUrl[i]); - if (config.database || config.username) { - console.log('MONGOSKIN:WARN: database or username found in RepliSet server URL, ' + serverUrl[i]); - } - servers.push(new Server(config.host, config.port, config.options)); - } - server = new ReplSetServers(servers, replicasetOptions); - } else { - config = parseUrl(serverUrl); - database = dbOptions.database || config.database; - if (!database) { - throw new Error('Please provide a database to connect to.'); - } - var socketOptions = dbOptions.socketOptions; - if (socketOptions) { - delete dbOptions.socketOptions; - config.options.socketOptions = socketOptions; - } - server = new Server(config.host, config.port, config.options); - - if (dbOptions.username === undefined) { - dbOptions.username = config.username; - dbOptions.password = config.password; - } - } - - var skinServer = new SkinServer(server); - return skinServer.db(database, dbOptions); -}; - -/** - * select different db by collection name - * - * @param select `function(name)` returns SkinDb - * - * ```js - * var router = mongoskin.router(function (name) { - * swhich (name) { - * case 'user': - * case 'group': - * return authDb; - * default: - * return appDb; - * } - * }); - * router.collection('user') - * ``` - * - * @param {Function(name)} select - * @return {Router} - * @api public - */ -exports.router = function (select) { - return new Router(select); -}; - -/* - * export Skin classes from ./db ./collection ./cursor ./admin - */ -['server', 'db', 'collection', 'cursor', 'admin'].forEach(function (path) { - var module = require('./' + path); - for (var name in module) { - exports[name] = module[name]; - } -}); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/router.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/router.js deleted file mode 100644 index 1e7bf301d98..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/router.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * mongoskin - router.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - * Router - * - * @param {Function(name)} select - * @constructor - * @api public - */ -var Router = exports.Router = function (select) { - this._select = select; - this._collections = {}; -}; - -/** - * Bind custom methods - * - * @param {String} name, collection name. - * @param {Object} [options] - * @return {Router} this - * @api public - */ -Router.prototype.bind = function (name, options) { - var args = Array.prototype.slice.call(arguments); - var database = this._select(name); - var collection = database.bind.apply(database, args); - this._collections[name] = collection; - Object.defineProperty(this, name, { - value: collection, - writable: false, - enumerable: true - }); - return this; -}; - -Router.prototype.collection = function (name) { - return this._collections[name] || (this._collections[name] = this._select(name).collection(name)); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/server.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/server.js deleted file mode 100644 index 54baaf44dfd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/server.js +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * mongoskin - server.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var mongodb = require('mongodb'); -var Db = mongodb.Db; -var Server = mongodb.Server; -var SkinDb = require('./db').SkinDb; - -/** - * Construct SkinServer with native Server - * - * @param {Server} server - * @constructor - * @api public - */ -var SkinServer = exports.SkinServer = function (server) { - this.server = server; - this._cache_ = {}; -}; - -/** - * Create SkinDb from a SkinServer - * - * @param {String} name database name - * @param {Object} [options] - * @return {SkinDb} - * @api public - */ -SkinServer.prototype.db = function (name, options) { - options = options || {}; - var username = options.username || ''; - var key = username + '@' + name; - var skinDb = this._cache_[key]; - if (!skinDb || skinDb.fail) { - var password = options.password; - if (!options.native_parser) { - options.native_parser = !! mongodb.BSONNative; - } - var db = new Db(name, this.server, options); - skinDb = new SkinDb(db, username, password); - this._cache_[key] = skinDb; - } - return skinDb; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/utils.js deleted file mode 100644 index 9b98231e607..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/lib/mongoskin/utils.js +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * mongoskin - utils.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var EventEmitter = require('events').EventEmitter; -var constant = require('./constant'); -var STATE_OPEN = constant.STATE_OPEN; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_CLOSE = constant.STATE_CLOSE; - -exports.inherits = require('util').inherits; - -exports.error = function (err, args, name) { - var cb = args.pop(); - if (cb && typeof cb === 'function') { - cb(err); - } else { - console.error("Error occured with no callback to handle it while calling " + name, err); - } -}; - -/** - * SkinObject - * - * @constructor - * @api public - */ -exports.SkinObject = function () { - this.emitter = new EventEmitter(); - this.state = STATE_CLOSE; -}; - -/** - * Skin method binding. - * - * @param {String} objName - * @param {Function} obj - * @param {String} nativeObjName - * @param {String} methodName - * @param {Function} method - * @return {Function} - */ -exports.bindSkin = function (objName, obj, nativeObjName, methodName, method) { - if (typeof method !== 'function') { - return; - } - return obj.prototype[methodName] = function () { - var args = __slice.call(arguments); - if (this.state === STATE_OPEN) { - method.apply(this[nativeObjName], args); - return this; - } - this.open(function (err, nativeObj) { - if (err) { - exports.error(err, args, objName + '.' + methodName); - } else { - return method.apply(nativeObj, args); - } - }); - return this; - }; -}; - -exports.extend = function (destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; -}; - -exports.noop = function () {}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/logo.png b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/logo.png deleted file mode 100644 index c8de074af05..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/logo.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md deleted file mode 100644 index 2a1c52e2abd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -## Contributing to the driver - -### Bugfixes - -- Before starting to write code, look for existing [tickets](https://github.com/mongodb/node-mongodb-native/issues) or [create one](https://github.com/mongodb/node-mongodb-native/issues/new) for your specific issue. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch. -- Fork the [repo](https://github.com/mongodb/node-mongodb-native) _or_ for small documentation changes, navigate to the source on github and click the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. -- Follow the general coding style of the rest of the project: - - 2 space tabs - - no trailing whitespace - - comma last - - inline documentation for new methods, class members, etc - - 0 space between conditionals/functions, and their parenthesis and curly braces - - `if(..) {` - - `for(..) {` - - `while(..) {` - - `function(err) {` -- Write tests and make sure they pass (execute `make test` from the cmd line to run the test suite). - -### Documentation - -To contribute to the [API documentation](http://mongodb.github.com/node-mongodb-native/) just make your changes to the inline documentation of the appropriate [source code](https://github.com/mongodb/node-mongodb-native/tree/master/docs) in the master branch and submit a [pull request](https://help.github.com/articles/using-pull-requests/). You might also use the github [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. - -If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make generate_docs`. Make sure you have the python documentation framework sphinx installed `easy_install sphinx`. The docs are generated under `docs/build'. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes. \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Makefile deleted file mode 100644 index ac55626c767..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit -DOX = node_modules/dox/bin/dox -name = all - -total: build_native - -test-coverage: - rm -rf lib-cov/ - jscoverage lib/ lib-cov/ - @TEST_COVERAGE=true nodeunit test/ test/gridstore test/connection - -build_native: - -test: build_native - @echo "\n == Run All tests minus replicaset tests==" - $(NODE) dev/tools/test_all.js --noreplicaset --boot - -test_pure: build_native - @echo "\n == Run All tests minus replicaset tests==" - $(NODE) dev/tools/test_all.js --noreplicaset --boot --nonative - -test_junit: build_native - @echo "\n == Run All tests minus replicaset tests==" - $(NODE) dev/tools/test_all.js --junit --noreplicaset --nokill - -jenkins: build_native - @echo "\n == Run All tests minus replicaset tests==" - $(NODE) dev/tools/test_all.js --junit --noreplicaset --nokill - -test_nodeunit_pure: - @echo "\n == Execute Test Suite using Pure JS BSON Parser == " - @$(NODEUNIT) test/ test/gridstore test/bson - -test_nodeunit_replicaset_pure: - @echo "\n == Execute Test Suite using Pure JS BSON Parser == " - @$(NODEUNIT) test/replicaset - -test_nodeunit_native: - @echo "\n == Execute Test Suite using Native BSON Parser == " - @TEST_NATIVE=TRUE $(NODEUNIT) test/ test/gridstore test/bson - -test_nodeunit_replicaset_native: - @echo "\n == Execute Test Suite using Native BSON Parser == " - @TEST_NATIVE=TRUE $(NODEUNIT) test/replicaset - -test_all: build_native - @echo "\n == Run All tests ==" - $(NODE) dev/tools/test_all.js --boot - -test_all_junit: build_native - @echo "\n == Run All tests ==" - $(NODE) dev/tools/test_all.js --junit --boot - -clean: - rm ./external-libs/bson/bson.node - rm -r ./external-libs/bson/build - -generate_docs: - $(NODE) dev/tools/build-docs.js - make --directory=./docs/sphinx-docs --file=Makefile html - -.PHONY: total diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Readme.md b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Readme.md deleted file mode 100644 index b81e719bfe4..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/Readme.md +++ /dev/null @@ -1,442 +0,0 @@ -Up to date documentation -======================== - -[Documentation](http://mongodb.github.com/node-mongodb-native/) - -Install -======= - -To install the most recent release from npm, run: - - npm install mongodb - -That may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version) - -To install the latest from the repository, run:: - - npm install path/to/node-mongodb-native - -Community -========= -Check out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver. - -Try it live -============ - - -Introduction -============ - -This is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/. - -A simple example of inserting a document. - -```javascript - var client = new Db('test', new Server("127.0.0.1", 27017, {}), {w: 1}), - test = function (err, collection) { - collection.insert({a:2}, function(err, docs) { - - collection.count(function(err, count) { - test.assertEquals(1, count); - }); - - // Locate all the entries using find - collection.find().toArray(function(err, results) { - test.assertEquals(1, results.length); - test.assertTrue(results[0].a === 2); - - // Let's close the db - client.close(); - }); - }); - }; - - client.open(function(err, p_client) { - client.collection('test_insert', test); - }); -``` - -Data types -========== - -To store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code). - -In particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example: - -```javascript - // Get the objectID type - var ObjectID = require('mongodb').ObjectID; - - var idString = '4e4e1638c85e808431000003'; - collection.findOne({_id: new ObjectID(idString)}, console.log) // ok - collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined -``` - -Here are the constructors the non-Javascript BSON primitive types: - -```javascript - // Fetch the library - var mongo = require('mongodb'); - // Create new instances of BSON types - new mongo.Long(numberString) - new mongo.ObjectID(hexString) - new mongo.Timestamp() // the actual unique number is generated on insert. - new mongo.DBRef(collectionName, id, dbName) - new mongo.Binary(buffer) // takes a string or Buffer - new mongo.Code(code, [context]) - new mongo.Symbol(string) - new mongo.MinKey() - new mongo.MaxKey() - new mongo.Double(number) // Force double storage -``` - -The C/C++ bson parser/serializer --------------------------------- - -If you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below - -```javascript - // using native_parser: - var client = new Db('integration_tests_20', - new Server("127.0.0.1", 27017), - {native_parser:true}); -``` - -The C++ parser uses the js objects both for serialization and deserialization. - -GitHub information -================== - -The source code is available at http://github.com/mongodb/node-mongodb-native. -You can either clone the repository or download a tarball of the latest release. - -Once you have the source you can test the driver by running - - $ make test - -in the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass. - -Examples -======== - -For examples look in the examples/ directory. You can execute the examples using node. - - $ cd examples - $ node queries.js - -GridStore -========= - -The GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition. - -For more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) - -Replicasets -=========== -For more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md) - -Primary Key Factories ---------------------- - -Defining your own primary key factory allows you to generate your own series of id's -(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long "string". - -Simple example below - -```javascript - // Custom factory (need to provide a 12 byte array); - CustomPKFactory = function() {} - CustomPKFactory.prototype = new Object(); - CustomPKFactory.createPk = function() { - return new ObjectID("aaaaaaaaaaaa"); - } - - var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory}); - p_client.open(function(err, p_client) { - p_client.dropDatabase(function(err, done) { - p_client.createCollection('test_custom_key', function(err, collection) { - collection.insert({'a':1}, function(err, docs) { - collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) { - cursor.toArray(function(err, items) { - test.assertEquals(1, items.length); - - // Let's close the db - p_client.close(); - }); - }); - }); - }); - }); - }); -``` - -Strict mode ------------ - -Each database has an optional strict mode. If it is set then asking for a collection -that does not exist will return an Error object in the callback. Similarly if you -attempt to create a collection that already exists. Strict is provided for convenience. - -```javascript - var error_client = new Db('integration_tests_', new Server("127.0.0.1", 27017, {auto_reconnect: false}), {strict:true}); - test.assertEquals(true, error_client.strict); - - error_client.open(function(err, error_client) { - error_client.collection('does-not-exist', function(err, collection) { - test.assertTrue(err instanceof Error); - test.assertEquals("Collection does-not-exist does not exist. Currently in strict mode.", err.message); - }); - - error_client.createCollection('test_strict_access_collection', function(err, collection) { - error_client.collection('test_strict_access_collection', function(err, collection) { - test.assertTrue(collection instanceof Collection); - // Let's close the db - error_client.close(); - }); - }); - }); -``` - -Documentation -============= - -If this document doesn't answer your questions, see the source of -[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js) -or [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js), -or the documentation at MongoDB for query and update formats. - -Find ----- - -The find method is actually a factory method to create -Cursor objects. A Cursor lazily uses the connection the first time -you call `nextObject`, `each`, or `toArray`. - -The basic operation on a cursor is the `nextObject` method -that fetches the next matching document from the database. The convenience -methods `each` and `toArray` call `nextObject` until the cursor is exhausted. - -Signatures: - -```javascript - var cursor = collection.find(query, [fields], options); - cursor.sort(fields).limit(n).skip(m). - - cursor.nextObject(function(err, doc) {}); - cursor.each(function(err, doc) {}); - cursor.toArray(function(err, docs) {}); - - cursor.rewind() // reset the cursor to its initial state. -``` - -Useful chainable methods of cursor. These can optionally be options of `find` instead of method calls: - -* `.limit(n).skip(m)` to control paging. -* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes: - * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2. - * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above - * `.sort([['field1', 'desc'], 'field2'])` same as above - * `.sort('field1')` ascending by field1 - -Other options of `find`: - -* `fields` the fields to fetch (to avoid transferring the entire document) -* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors). -* `batchSize` The number of the subset of results to request the database -to return for every request. This should initially be greater than 1 otherwise -the database will automatically close the cursor. The batch size can be set to 1 -with `batchSize(n, function(err){})` after performing the initial query to the database. -* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint). -* `explain` turns this into an explain query. You can also call -`explain()` on any cursor to fetch the explanation. -* `snapshot` prevents documents that are updated while the query is active -from being returned multiple times. See more -[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database). -* `timeout` if false, asks MongoDb not to time out this cursor after an -inactivity period. - - -For information on how to create queries, see the -[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.find({}, {limit:10}).toArray(function(err, docs) { - console.dir(docs); - }); - }); -``` - -Insert ------- - -Signature: - -```javascript - collection.insert(docs, options, [callback]); -``` - -where `docs` can be a single document or an array of documents. - -Useful options: - -* `safe:true` Should always set if you have a callback. - -See also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.insert({hello: 'world'}, {safe:true}, - function(err, objects) { - if (err) console.warn(err.message); - if (err && err.message.indexOf('E11000 ') !== -1) { - // this _id was already inserted in the database - } - }); - }); -``` - -Note that there's no reason to pass a callback to the insert or update commands -unless you use the `safe:true` option. If you don't specify `safe:true`, then -your callback will be called immediately. - -Update; update and insert (upsert) ----------------------------------- - -The update operation will update the first document that matches your query -(or all documents that match if you use `multi:true`). -If `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated. - -See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for -the modifier (`$inc`, `$set`, `$push`, etc.) formats. - -Signature: - -```javascript - collection.update(criteria, objNew, options, [callback]); -``` - -Useful options: - -* `safe:true` Should always set if you have a callback. -* `multi:true` If set, all matching documents are updated, not just the first. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `update`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true}, - function(err) { - if (err) console.warn(err.message); - else console.log('successfully updated'); - }); - }); -``` - -Find and modify ---------------- - -`findAndModify` is like `update`, but it also gives the updated document to -your callback. But there are a few key differences between findAndModify and -update: - - 1. The signatures differ. - 2. You can only findAndModify a single item, not multiple items. - -Signature: - -```javascript - collection.findAndModify(query, sort, update, options, callback) -``` - -The sort parameter is used to specify which object to operate on, if more than -one document matches. It takes the same format as the cursor sort (see -Connection.find above). - -See the -[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) -for more details. - -Useful options: - -* `remove:true` set to a true to remove the object before returning -* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `findAndModify`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {}, - function(err, object) { - if (err) console.warn(err.message); - else console.dir(object); // undefined if no matching object exists. - }); - }); -``` - -Save ----- - -The `save` method is a shorthand for upsert if the document contains an -`_id`, or an insert if there is no `_id`. - -Sponsors -======== -Just as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB. - -If your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details. - -And I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing. - -Release Notes -============= - -See HISTORY - -Credits -======= - -1. [10gen](http://github.com/mongodb/mongo-ruby-driver/) -2. [Google Closure Library](http://code.google.com/closure/library/) -3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser) - -Contributors -============ - -Aaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy - -License -======= - - Copyright 2009 - 2012 Christian Amor Kvalheim. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/index.js deleted file mode 100755 index 4f59e9d9262..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/mongodb'); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/install.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/install.js deleted file mode 100644 index f9f2a5778eb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/install.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false'; -build_native = build_native == 'true' ? true : false; -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total']); - } else { - make = spawn('gmake', ['total']); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js deleted file mode 100644 index 6e9cd306cb4..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js +++ /dev/null @@ -1,339 +0,0 @@ -/*! - * Module dependencies. - */ -var Collection = require('./collection').Collection, - Cursor = require('./cursor').Cursor, - DbCommand = require('./commands/db_command').DbCommand, - utils = require('./utils'); - -/** - * Allows the user to access the admin functionality of MongoDB - * - * @class Represents the Admin methods of MongoDB. - * @param {Object} db Current db instance we wish to perform Admin operations on. - * @return {Function} Constructor for Admin type. - */ -function Admin(db) { - if(!(this instanceof Admin)) return new Admin(db); - this.db = db; -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.buildInfo = function(callback) { - this.serverInfo(callback); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured. - * @return {null} Returns no result - * @api private - */ -Admin.prototype.serverInfo = function(callback) { - this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Retrieve this db's server status. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.serverStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) { - callback(null, doc.documents[0]); - } else { - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - } - }); -}; - -/** - * Retrieve the current profiling Level for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingLevel = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({profile:-1}, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) { - var was = doc.was; - if(was == 0) return callback(null, "off"); - if(was == 1) return callback(null, "slow_only"); - if(was == 2) return callback(null, "all"); - return callback(new Error("Error: illegal profiling level value " + was), null); - } else { - err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - } - }); -}; - -/** - * Ping the MongoDB server and retrieve results - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.ping = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - - this.db.executeDbAdminCommand({ping: 1}, callback); -} - -/** - * Authenticate against MongoDB - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.authenticate = function(username, password, callback) { - this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Logout current authenticated user - * - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.logout = function(callback) { - this.db.logout({authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Add a user to the MongoDB server, if the user exists it will - * overwrite the current password - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.addUser = function(username, password, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - options.dbName = 'admin'; - // Add user - this.db.addUser(username, password, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Remove a user from the MongoDB server - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options.dbName = 'admin'; - - this.db.removeUser(username, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Set the current profiling level of MongoDB - * - * @param {String} level The new profiling level (off, slow_only, all) - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.setProfilingLevel = function(level, callback) { - var self = this; - var command = {}; - var profile = 0; - - if(level == "off") { - profile = 0; - } else if(level == "slow_only") { - profile = 1; - } else if(level == "all") { - profile = 2; - } else { - return callback(new Error("Error: illegal profiling level value " + level)); - } - - // Set up the profile number - command['profile'] = profile; - - this.db.executeDbAdminCommand(command, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) - return callback(null, level); - return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - }); -}; - -/** - * Retrive the current profiling information for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingInfo = function(callback) { - try { - new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) { - return callback(err, items); - }); - } catch (err) { - return callback(err, null); - } -}; - -/** - * Execute a db command against the Admin database - * - * @param {Object} command A command object `{ping:1}`. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.command = function(command, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Execute a command - this.db.executeDbAdminCommand(command, options, function(err, doc) { - // Ensure change before event loop executes - return callback != null ? callback(err, doc) : null; - }); -} - -/** - * Validate an existing collection - * - * @param {String} collectionName The name of the collection to validate. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.validateCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - var self = this; - var command = {validate: collectionName}; - var keys = Object.keys(options); - - // Decorate command with extra options - for(var i = 0; i < keys.length; i++) { - if(options.hasOwnProperty(keys[i])) { - command[keys[i]] = options[keys[i]]; - } - } - - this.db.executeDbCommand(command, function(err, doc) { - if(err != null) return callback(err, null); - doc = doc.documents[0]; - - if(doc.ok === 0) - return callback(new Error("Error with validate command"), null); - if(doc.result != null && doc.result.constructor != String) - return callback(new Error("Error with validation data"), null); - if(doc.result != null && doc.result.match(/exception|corrupt/) != null) - return callback(new Error("Error: invalid collection " + collectionName), null); - if(doc.valid != null && !doc.valid) - return callback(new Error("Error: invalid collection " + collectionName), null); - - return callback(null, doc); - }); -}; - -/** - * List the available databases - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.listDatabases = function(callback) { - // Execute the listAllDatabases command - this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Get ReplicaSet status - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.replSetGetStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) - return callback(null, doc.documents[0]); - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - }); -}; - -/** - * @ignore - */ -exports.Admin = Admin; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js deleted file mode 100644 index 3775660e685..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js +++ /dev/null @@ -1,1743 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var InsertCommand = require('./commands/insert_command').InsertCommand - , QueryCommand = require('./commands/query_command').QueryCommand - , DeleteCommand = require('./commands/delete_command').DeleteCommand - , UpdateCommand = require('./commands/update_command').UpdateCommand - , DbCommand = require('./commands/db_command').DbCommand - , ObjectID = require('bson').ObjectID - , Code = require('bson').Code - , Cursor = require('./cursor').Cursor - , utils = require('./utils'); - -/** - * Precompiled regexes - * @ignore -**/ -const eErrorMessages = /No matching object found/; - -/** - * toString helper. - * @ignore - */ -var toString = Object.prototype.toString; - -/** - * Create a new Collection instance - * - * Options - * - **slaveOk** {Boolean, default:false}, Allow reads from secondaries. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - * @class Represents a Collection - * @param {Object} db db instance. - * @param {String} collectionName collection name. - * @param {Object} [pkFactory] alternative primary key factory. - * @param {Object} [options] additional options for the collection. - * @return {Object} a collection instance. - */ -function Collection (db, collectionName, pkFactory, options) { - if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options); - - checkCollectionName(collectionName); - - this.db = db; - this.collectionName = collectionName; - this.internalHint = null; - this.opts = options != null && ('object' === typeof options) ? options : {}; - this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk; - this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions; - this.raw = options == null || options.raw == null ? db.raw : options.raw; - - this.readPreference = options == null || options.readPreference == null ? db.serverConfig.readPreference : options.readPreference; - this.readPreference = this.readPreference == null ? 'primary' : this.readPreference; - - this.pkFactory = pkFactory == null - ? ObjectID - : pkFactory; - - var self = this; -} - -/** - * Inserts a single document or a an array of documents into MongoDB. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Array|Object} docs - * @param {Object} [options] optional options for insert command - * @param {Function} [callback] optional callback for the function, must be provided when using a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.insert = function insert (docs, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - insertAll(self, Array.isArray(docs) ? docs : [docs], options, callback); - return this; -}; - -/** - * @ignore - */ -var checkCollectionName = function checkCollectionName (collectionName) { - if ('string' !== typeof collectionName) { - throw Error("collection name must be a String"); - } - - if (!collectionName || collectionName.indexOf('..') != -1) { - throw Error("collection names cannot be empty"); - } - - if (collectionName.indexOf('$') != -1 && - collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) { - throw Error("collection names must not contain '$'"); - } - - if (collectionName.match(/^\.|\.$/) != null) { - throw Error("collection names must not start or end with '.'"); - } -}; - -/** - * Removes documents specified by `selector` from the db. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **single** {Boolean, default:false}, removes the first document found. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [selector] optional select, no selector is equivalent to removing all documents. - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a remove with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.remove = function remove(selector, options, callback) { - if ('function' === typeof selector) { - callback = selector; - selector = options = {}; - } else if ('function' === typeof options) { - callback = options; - options = {}; - } - - // Ensure options - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Ensure we have at least an empty selector - selector = selector == null ? {} : selector; - // Set up flags for the command, if we have a single document remove - var flags = 0 | (options.single ? 1 : 0); - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Create a delete command - var deleteCommand = new DeleteCommand( - this.db - , dbName + "." + this.collectionName - , selector - , flags); - - var self = this; - var errorOptions = _getWriteConcern(self, options, callback); - // Execute the command, do not add a callback as it's async - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = true; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeRemoveCommand(deleteCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, error[0].n); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - var result = this.db._executeRemoveCommand(deleteCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * Renames the collection. - * - * @param {String} newName the new name of the collection. - * @param {Function} callback the callback accepting the result - * @return {null} - * @api public - */ -Collection.prototype.rename = function rename (newName, callback) { - var self = this; - // Ensure the new name is valid - checkCollectionName(newName); - // Execute the command, return the new renamed collection if successful - self.db._executeQueryCommand(DbCommand.createRenameCollectionCommand(self.db, self.collectionName, newName), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - if(callback != null) { - // Set current object to point to the new name - self.collectionName = newName; - // Return the current collection - callback(null, self); - } - } else if(result.documents[0].errmsg != null) { - if(null != callback) { - if (null == err) { - err = utils.toError(result.documents[0]); - } - callback(err, null); - } - } - }); -}; - -/** - * @ignore - */ -var insertAll = function insertAll (self, docs, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Insert options (flags for insert) - var insertFlags = {}; - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['keepGoing'] != null) { - insertFlags['keepGoing'] = options['keepGoing']; - } - - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['continueOnError'] != null) { - insertFlags['continueOnError'] = options['continueOnError']; - } - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = self.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - insertFlags['serializeFunctions'] = options['serializeFunctions']; - } else { - insertFlags['serializeFunctions'] = self.serializeFunctions; - } - - // Pass in options - var insertCommand = new InsertCommand( - self.db - , dbName + "." + self.collectionName, true, insertFlags); - - // Add the documents and decorate them with id's if they have none - for(var index = 0, len = docs.length; index < len; ++index) { - var doc = docs[index]; - - // Add id to each document if it's not already defined - if (!(Buffer.isBuffer(doc)) && doc['_id'] == null && self.db.forceServerObjectId != true) { - doc['_id'] = self.pkFactory.createPk(); - } - - insertCommand.add(doc); - } - - // Collect errorOptions - var errorOptions = _getWriteConcern(self, options, callback); - // Default command options - var commandOptions = {}; - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - self.db._executeInsertCommand(insertCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if (err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, docs); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute the call without a write concern - var result = self.db._executeInsertCommand(insertCommand, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, docs); - } -}; - -/** - * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic - * operators and update instead for more efficient operations. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [doc] the document to save - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a safe save - * @return {null} - * @api public - */ -Collection.prototype.save = function save(doc, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Extract the id, if we have one we need to do a update command - var id = doc['_id']; - var commandOptions = _getWriteConcern(this, options, callback); - - if(id) { - commandOptions.upsert = true; - this.update({ _id: id }, doc, commandOptions, callback); - } else { - this.insert(doc, commandOptions, callback && function (err, docs) { - if (err) return callback(err, null); - - if (Array.isArray(docs)) { - callback(err, docs[0]); - } else { - callback(err, docs); - } - }); - } -}; - -/** - * Updates documents. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **multi** {Boolean, default:false}, update all documents matching the selector. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} selector the query to select the document/documents to be updated - * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted. - * @param {Object} [options] additional options during update. - * @param {Function} [callback] must be provided if you performing an update with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.update = function update(selector, document, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - var updateCommand = new UpdateCommand( - this.db - , dbName + "." + this.collectionName - , selector - , document - , options); - - var self = this; - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeUpdateCommand(updateCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - // Perform the callback - callback(null, error[0].n, error[0]); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute update - var result = this.db._executeUpdateCommand(updateCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * The distinct command returns returns a list of distinct values for the given key across a collection. - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} key key to run distinct against. - * @param {Object} [query] option query to narrow the returned objects. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from distinct or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.distinct = function distinct(key, query, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - - var mapCommandHash = { - 'distinct': this.collectionName - , 'query': query - , 'key': key - }; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // Create the command - var cmd = DbCommand.createDbSlaveOkCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err) - return callback(err); - if(result.documents[0].ok != 1) - return callback(new Error(result.documents[0].errmsg)); - callback(null, result.documents[0].values); - }); -}; - -/** - * Count number of matching documents in the db to a query. - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object} [query] query to filter by before performing count. - * @param {Object} [options] additional options during count. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the count method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.count = function count (query, options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - - // Final query - var final_query = { - 'count': this.collectionName - , 'query': query - , 'fields': null - }; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Set up query options - var queryOptions = QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - if (this.slaveOk || this.db.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - var queryCommand = new QueryCommand( - this.db - , this.db.databaseName + ".$cmd" - , queryOptions - , 0 - , -1 - , final_query - , null - ); - - var self = this; - this.db._executeQueryCommand(queryCommand, {read:readPreference}, function (err, result) { - result = result && result.documents; - if(!callback) return; - - if(err) return callback(err); - if (result[0].ok != 1 || result[0].errmsg) { - return callback(utils.toError(result[0])); - } - callback(null, result[0].n); - }); -}; - - -/** - * Drop the collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the drop method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.drop = function drop(callback) { - this.db.dropCollection(this.collectionName, callback); -}; - -/** - * Find and update a document. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **remove** {Boolean, default:false}, set to true to remove the object before returning. - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} doc - the fields/vals to be updated - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndModify method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndModify = function findAndModify (query, sort, doc, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - doc = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - var self = this; - - var queryObject = { - 'findandmodify': this.collectionName - , 'query': query - , 'sort': utils.formattedOrderClause(sort) - }; - - queryObject.new = options.new ? 1 : 0; - queryObject.remove = options.remove ? 1 : 0; - queryObject.upsert = options.upsert ? 1 : 0; - - if (options.fields) { - queryObject.fields = options.fields; - } - - if (doc && !options.remove) { - queryObject.update = doc; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - - // If we have j, w or something else do the getLast Error path - if(errorOptions != null && typeof errorOptions == 'object') { - // Commands to send - var commands = []; - // Add the find and modify command - commands.push(DbCommand.createDbCommand(this.db, queryObject, options)); - // If we have safe defined we need to return both call results - var chainedCommands = errorOptions != null ? true : false; - // Add error command if we have one - if(chainedCommands) { - commands.push(DbCommand.createGetLastErrorCommand(errorOptions, this.db)); - } - - // Fire commands and - this.db._executeQueryCommand(commands, {read:false}, function(err, result) { - if(err != null) return callback(err); - result = result && result.documents; - - if(result[0].err != null) { - return callback(utils.toError(result[0]), null); - } - - // Workaround due to 1.8.X returning an error on no matching object - // while 2.0.X does not not, making 2.0.X behaviour standard - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - return callback(null, result[0].value, result[0]); - }); - } else { - // Only run command and rely on getLastError command - var command = DbCommand.createDbCommand(this.db, queryObject, options) - // Execute command - this.db._executeQueryCommand(command, {read:false}, function(err, result) { - if(err != null) return callback(err); - - result = result && result.documents; - - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - // If we have an error return it - if(result[0].lastErrorObject && result[0].lastErrorObject.err != null) { - return callback(utils.toError(result[0].lastErrorObject), null); - } - - return callback(null, result[0].value, result[0]); - }); - } -} - -/** - * Find and remove a document - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndRemove method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndRemove = function(query, sort, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - options = args.length ? args.shift() : {}; - // Add the remove option - options['remove'] = true; - // Execute the callback - this.findAndModify(query, sort, null, options, callback); -} - -var testForFields = { - limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1 - , numberOfRetries: 1, awaitdata: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1 - , comment: 1, raw: 1, readPreference: 1, numberOfRetries: 1, partial: 1, read: 1, dbName: 1 -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **tailableRetryInterval** {Number, default:100}, specify the miliseconds between getMores on tailable cursor. - * - **numberOfRetries** {Number, default:5}, specify the number of times to retry the tailable cursor. - * - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor. - * - **exhaust** {Boolean, default:false} have the server send all the documents at once as getMore packets, not recommended. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **numberOfRetries** {Number, default:5}, if using awaidata specifies the number of times to retry on timeout. - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the find method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.find = function find () { - var options - , args = Array.prototype.slice.call(arguments, 0) - , has_callback = typeof args[args.length - 1] === 'function' - , has_weird_callback = typeof args[0] === 'function' - , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null) - , len = args.length - , selector = len >= 1 ? args[0] : {} - , fields = len >= 2 ? args[1] : undefined; - - if(len === 1 && has_weird_callback) { - // backwards compat for callback?, options case - selector = {}; - options = args[0]; - } - - if(len === 2 && !Array.isArray(fields)) { - var fieldKeys = Object.getOwnPropertyNames(fields); - var is_option = false; - - for(var i = 0; i < fieldKeys.length; i++) { - if(testForFields[fieldKeys[i]] != null) { - is_option = true; - break; - } - } - - if(is_option) { - options = fields; - fields = undefined; - } else { - options = {}; - } - } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) { - var newFields = {}; - // Rewrite the array - for(var i = 0; i < fields.length; i++) { - newFields[fields[i]] = 1; - } - // Set the fields - fields = newFields; - } - - if(3 === len) { - options = args[2]; - } - - // Ensure selector is not null - selector = selector == null ? {} : selector; - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Validate correctness of the field selector - var object = fields; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Check special case where we are using an objectId - if(selector instanceof ObjectID) { - selector = {_id:selector}; - } - - // If it's a serialized fields field we need to just let it through - // user be warned it better be good - if(options && options.fields && !(Buffer.isBuffer(options.fields))) { - fields = {}; - - if(Array.isArray(options.fields)) { - if(!options.fields.length) { - fields['_id'] = 1; - } else { - for (var i = 0, l = options.fields.length; i < l; i++) { - fields[options.fields[i]] = 1; - } - } - } else { - fields = options.fields; - } - } - - if (!options) options = {}; - options.skip = len > 3 ? args[2] : options.skip ? options.skip : 0; - options.limit = len > 3 ? args[3] : options.limit ? options.limit : 0; - options.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw; - options.hint = options.hint != null ? normalizeHintField(options.hint) : this.internalHint; - options.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout; - // If we have overridden slaveOk otherwise use the default db setting - options.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk; - - // Set option - var o = options; - // Support read/readPreference - if(o["read"] != null) o["readPreference"] = o["read"]; - // Set the read preference - o.read = o["readPreference"] ? o.readPreference : this.readPreference; - // Adjust slave ok if read preference is secondary or secondary only - if(o.read == "secondary" || o.read == "secondaryOnly") options.slaveOk = true; - - // callback for backward compatibility - if(callback) { - // TODO refactor Cursor args - callback(null, new Cursor(this.db, this, selector, fields, o)); - } else { - return new Cursor(this.db, this, selector, fields, o); - } -}; - -/** - * Normalizes a `hint` argument. - * - * @param {String|Object|Array} hint - * @return {Object} - * @api private - */ -var normalizeHintField = function normalizeHintField(hint) { - var finalHint = null; - - if (null != hint) { - switch (hint.constructor) { - case String: - finalHint = {}; - finalHint[hint] = 1; - break; - case Object: - finalHint = {}; - for (var name in hint) { - finalHint[name] = hint[name]; - } - break; - case Array: - finalHint = {}; - hint.forEach(function(param) { - finalHint[param] = 1; - }); - break; - } - } - - return finalHint; -}; - -/** - * Finds a single document based on the query - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findOne method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.findOne = function findOne () { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - var callback = args.pop(); - var cursor = this.find.apply(this, args).limit(-1).batchSize(1); - // Return the item - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the createIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.createIndex = function createIndex (fieldOrSpec, options, callback) { - // Clean up call - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Collect errorOptions - var errorOptions = _getWriteConcern(this, options, callback); - // Execute create index - this.db.createIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the ensureIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.ensureIndex = function ensureIndex (fieldOrSpec, options, callback) { - // Clean up call - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Execute create index - this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexInformation method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexInformation = function indexInformation (options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // Call the index information - this.db.indexInformation(this.collectionName, options, callback); -}; - -/** - * Drops an index from this collection. - * - * @param {String} name - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropIndex = function dropIndex (name, callback) { - this.db.dropIndex(this.collectionName, name, callback); -}; - -/** - * Drops all indexes from this collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropAllIndexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropAllIndexes = function dropIndexes (callback) { - this.db.dropIndex(this.collectionName, '*', function (err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Drops all indexes from this collection. - * - * @deprecated - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndexes method or null if an error occured. - * @return {null} - * @api private - */ -Collection.prototype.dropIndexes = Collection.prototype.dropAllIndexes; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the reIndex method or null if an error occured. - * @return {null} - * @api public -**/ -Collection.prototype.reIndex = function(callback) { - this.db.reIndex(this.collectionName, callback); -} - -/** - * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection. - * - * Options - * - **out** {Object, default:*{inline:1}*}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}* - * - **query** {Object}, query filter object. - * - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces. - * - **limit** {Number}, number of objects to return from collection. - * - **keeptemp** {Boolean, default:false}, keep temporary data. - * - **finalize** {Function | String}, finalize function. - * - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize. - * - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X. - * - **verbose** {Boolean, default:false}, provide statistics on job execution time. - * - **readPreference** {String, only for inline results}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Function|String} map the mapping function. - * @param {Function|String} reduce the reduce function. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the mapReduce method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.mapReduce = function mapReduce (map, reduce, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers) - if(null == options.out) { - throw new Error("the out option parameter must be defined, see mongodb docs for possible values"); - } - - if ('function' === typeof map) { - map = map.toString(); - } - - if ('function' === typeof reduce) { - reduce = reduce.toString(); - } - - if ('function' === typeof options.finalize) { - options.finalize = options.finalize.toString(); - } - - var mapCommandHash = { - mapreduce: this.collectionName - , map: map - , reduce: reduce - }; - - // Add any other options passed in - for (var name in options) { - if ('scope' == name) { - mapCommandHash[name] = processScope(options[name]); - } else { - mapCommandHash[name] = options[name]; - } - } - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // If we have a read preference and inline is not set as output fail hard - if(readPreference != false && options['out'] != 'inline') { - throw new Error("a readPreference can only be provided when performing an inline mapReduce"); - } - - // self - var self = this; - var cmd = DbCommand.createDbCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if (err) { - return callback(err); - } - - // - if (1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) { - return callback(utils.toError(result.documents[0])); - } - - // Create statistics value - var stats = {}; - if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis; - if(result.documents[0].counts) stats['counts'] = result.documents[0].counts; - if(result.documents[0].timing) stats['timing'] = result.documents[0].timing; - - // invoked with inline? - if(result.documents[0].results) { - return callback(null, result.documents[0].results, stats); - } - - // The returned collection - var collection = null; - - // If we have an object it's a different db - if(result.documents[0].result != null && typeof result.documents[0].result == 'object') { - var doc = result.documents[0].result; - collection = self.db.db(doc.db).collection(doc.collection); - } else { - // Create a collection object that wraps the result collection - collection = self.db.collection(result.documents[0].result) - } - - // If we wish for no verbosity - if(options['verbose'] == null || !options['verbose']) { - return callback(err, collection); - } - - // Return stats as third set of values - callback(err, collection, stats); - }); -}; - -/** - * Functions that are passed as scope args must - * be converted to Code instances. - * @ignore - */ -function processScope (scope) { - if (!utils.isObject(scope)) { - return scope; - } - - var keys = Object.keys(scope); - var i = keys.length; - var key; - - while (i--) { - key = keys[i]; - if ('function' == typeof scope[key]) { - scope[key] = new Code(String(scope[key])); - } - } - - return scope; -} - -/** - * Group function helper - * @ignore - */ -var groupFunction = function () { - var c = db[ns].find(condition); - var map = new Map(); - var reduce_function = reduce; - - while (c.hasNext()) { - var obj = c.next(); - var key = {}; - - for (var i = 0, len = keys.length; i < len; ++i) { - var k = keys[i]; - key[k] = obj[k]; - } - - var aggObj = map.get(key); - - if (aggObj == null) { - var newObj = Object.extend({}, key); - aggObj = Object.extend(newObj, initial); - map.put(key, aggObj); - } - - reduce_function(obj, aggObj); - } - - return { "result": map.values() }; -}.toString(); - -/** - * Run a group command across a collection - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by. - * @param {Object} condition an optional condition that must be true for a row to be considered. - * @param {Object} initial initial value of the aggregation counter object. - * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated - * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned. - * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the group method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.group = function group(keys, condition, initial, reduce, finalize, command, options, callback) { - var args = Array.prototype.slice.call(arguments, 3); - callback = args.pop(); - // Fetch all commands - reduce = args.length ? args.shift() : null; - finalize = args.length ? args.shift() : null; - command = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Make sure we are backward compatible - if(!(typeof finalize == 'function')) { - command = finalize; - finalize = null; - } - - if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) { - keys = Object.keys(keys); - } - - if(typeof reduce === 'function') { - reduce = reduce.toString(); - } - - if(typeof finalize === 'function') { - finalize = finalize.toString(); - } - - // Set up the command as default - command = command == null ? true : command; - - // Execute using the command - if(command) { - var reduceFunction = reduce instanceof Code - ? reduce - : new Code(reduce); - - var selector = { - group: { - 'ns': this.collectionName - , '$reduce': reduceFunction - , 'cond': condition - , 'initial': initial - , 'out': "inline" - } - }; - - // if finalize is defined - if(finalize != null) selector.group['finalize'] = finalize; - // Set up group selector - if ('function' === typeof keys || keys instanceof Code) { - selector.group.$keyf = keys instanceof Code - ? keys - : new Code(keys); - } else { - var hash = {}; - keys.forEach(function (key) { - hash[key] = 1; - }); - selector.group.key = hash; - } - - var cmd = DbCommand.createDbSlaveOkCommand(this.db, selector); - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err != null) return callback(err); - - var document = result.documents[0]; - if (null == document.retval) { - return callback(new Error("group command failed: " + document.errmsg)); - } - - callback(null, document.retval); - }); - - } else { - // Create execution scope - var scope = reduce != null && reduce instanceof Code - ? reduce.scope - : {}; - - scope.ns = this.collectionName; - scope.keys = keys; - scope.condition = condition; - scope.initial = initial; - - // Pass in the function text to execute within mongodb. - var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';'); - - this.db.eval(new Code(groupfn, scope), function (err, results) { - if (err) return callback(err, null); - callback(null, results.result || results); - }); - } -}; - -/** - * Returns the options of the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the options method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.options = function options(callback) { - this.db.collectionsInfo(this.collectionName, function (err, cursor) { - if (err) return callback(err); - cursor.nextObject(function (err, document) { - callback(err, document && document.options || null); - }); - }); -}; - -/** - * Returns if the collection is a capped collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the isCapped method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.isCapped = function isCapped(callback) { - this.options(function(err, document) { - if(err != null) { - callback(err); - } else { - callback(null, document && document.capped); - } - }); -}; - -/** - * Checks if one or more indexes exist on the collection - * - * @param {String|Array} indexNames check if one or more indexes exist on the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexExists method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexExists = function indexExists(indexes, callback) { - this.indexInformation(function(err, indexInformation) { - // If we have an error return - if(err != null) return callback(err, null); - // Let's check for the index names - if(Array.isArray(indexes)) { - for(var i = 0; i < indexes.length; i++) { - if(indexInformation[indexes[i]] == null) { - return callback(null, false); - } - } - - // All keys found return true - return callback(null, true); - } else { - return callback(null, indexInformation[indexes] != null); - } - }); -} - -/** - * Execute the geoNear command to search for items in the collection - * - * Options - * - **num** {Number}, max number of results to return. - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions. - * - **query** {Object}, filter the results by a query. - * - **spherical** {Boolean, default:false}, perform query using a spherical model. - * - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X. - * - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoNear method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoNear = function geoNear(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoNear:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['num'] != null) commandObject['num'] = options['num']; - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['distanceMultiplier'] != null) commandObject['distanceMultiplier'] = options['distanceMultiplier']; - if(options['query'] != null) commandObject['query'] = options['query']; - if(options['spherical'] != null) commandObject['spherical'] = options['spherical']; - if(options['uniqueDocs'] != null) commandObject['uniqueDocs'] = options['uniqueDocs']; - if(options['includeLocs'] != null) commandObject['includeLocs'] = options['includeLocs']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Execute a geo search using a geo haystack index on a collection. - * - * Options - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **search** {Object}, filter the results by a query. - * - **limit** {Number}, max number of results to return. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoHaystackSearch method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoSearch:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['query'] != null) commandObject['search'] = options['query']; - if(options['search'] != null) commandObject['search'] = options['search']; - if(options['limit'] != null) commandObject['limit'] = options['limit']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Retrieve all the indexes on the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexes = function indexes(callback) { - // Return all the index information - this.db.indexInformation(this.collectionName, {full:true}, callback); -} - -/** - * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.1 - * - * Options - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Array} array containing all the aggregation framework commands for the execution. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the aggregate method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.aggregate = function(pipeline, options, callback) { - // * - **explain** {Boolean}, return the query plan for the aggregation pipeline instead of the results. 2.3, 2.4 - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - var self = this; - - // If we have any of the supported options in the options object - var opts = args[args.length - 1]; - options = opts.readPreference || opts.explain ? args.pop() : {} - - // Convert operations to an array - if(!Array.isArray(args[0])) { - pipeline = []; - // Push all the operations to the pipeline - for(var i = 0; i < args.length; i++) pipeline.push(args[i]); - } - - // Build the command - var command = { aggregate : this.collectionName, pipeline : pipeline}; - // Add all options - var keys = Object.keys(options); - // Add all options - for(var i = 0; i < keys.length; i++) { - command[keys[i]] = options[keys[i]]; - } - - // Execute the command - this.db.command(command, options, function(err, result) { - if(err) { - callback(err); - } else if(result['err'] || result['errmsg']) { - callback(utils.toError(result)); - } else if(typeof result == 'object' && result['serverPipeline']) { - callback(null, result); - } else { - callback(null, result.result); - } - }); -} - -/** - * Get all the collection statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the stats method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - collStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * @ignore - */ -Object.defineProperty(Collection.prototype, "hint", { - enumerable: true - , get: function () { - return this.internalHint; - } - , set: function (v) { - this.internalHint = normalizeHintField(v); - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(self.opts.w != null || typeof self.opts.j == 'boolean' || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.opts); - } else if(typeof self.opts.safe == "boolean") { - finalOptions = {w: (self.opts.safe ? 1 : 0)}; - } else if(self.db.safe.w != null || typeof self.db.safe.j == 'boolean' || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.safe); - } else if(self.db.options.w != null || typeof self.db.options.j == 'boolean' || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.options); - } else if(typeof self.db.safe == "boolean") { - finalOptions = {w: (self.db.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Expose. - */ -exports.Collection = Collection; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js deleted file mode 100644 index 955858283ce..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - Base object used for common functionality -**/ -var BaseCommand = exports.BaseCommand = function BaseCommand() { -}; - -var id = 1; -BaseCommand.prototype.getRequestId = function getRequestId() { - if (!this.requestId) this.requestId = id++; - return this.requestId; -}; - -BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {} - -BaseCommand.prototype.updateRequestId = function() { - this.requestId = id++; - return this.requestId; -}; - -// OpCodes -BaseCommand.OP_REPLY = 1; -BaseCommand.OP_MSG = 1000; -BaseCommand.OP_UPDATE = 2001; -BaseCommand.OP_INSERT = 2002; -BaseCommand.OP_GET_BY_OID = 2003; -BaseCommand.OP_QUERY = 2004; -BaseCommand.OP_GET_MORE = 2005; -BaseCommand.OP_DELETE = 2006; -BaseCommand.OP_KILL_CURSORS = 2007; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js deleted file mode 100644 index b1a798de861..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js +++ /dev/null @@ -1,240 +0,0 @@ -var QueryCommand = require('./query_command').QueryCommand, - InsertCommand = require('./insert_command').InsertCommand, - inherits = require('util').inherits, - utils = require('../utils'), - crypto = require('crypto'); - -/** - Db Command -**/ -var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - QueryCommand.call(this); - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = dbInstance; - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(DbCommand, QueryCommand); - -// Constants -DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"; -DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes"; -DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile"; -DbCommand.SYSTEM_USER_COLLECTION = "system.users"; -DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd"; -DbCommand.SYSTEM_JS_COLLECTION = "system.js"; - -// New commands -DbCommand.NcreateIsMasterCommand = function(db, databaseName) { - return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -// Provide constructors for different db commands -DbCommand.createIsMasterCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -DbCommand.createCollectionInfoCommand = function(db, selector) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null); -}; - -DbCommand.createGetNonceCommand = function(db, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null); -}; - -DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) { - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var hash_password = md5.digest('hex'); - // Final key - md5 = crypto.createHash('md5'); - md5.update(nonce + username + hash_password); - var key = md5.digest('hex'); - // Creat selector - var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key}; - // Create db command - return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null); -}; - -DbCommand.createLogoutCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null); -}; - -DbCommand.createCreateCollectionCommand = function(db, collectionName, options) { - var selector = {'create':collectionName}; - // Modify the options to ensure correct behaviour - for(var name in options) { - if(options[name] != null && options[name].constructor != Function) selector[name] = options[name]; - } - // Execute the command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null); -}; - -DbCommand.createDropCollectionCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null); -}; - -DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName) { - var renameCollection = db.databaseName + "." + fromCollectionName; - var toCollection = db.databaseName + "." + toCollectionName; - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection}, null); -}; - -DbCommand.createGetLastErrorCommand = function(options, db) { - - if (typeof db === 'undefined') { - db = options; - options = {}; - } - // Final command - var command = {'getlasterror':1}; - // If we have an options Object let's merge in the fields (fsync/wtimeout/w) - if('object' === typeof options) { - for(var name in options) { - command[name] = options[name] - } - } - - // Special case for w == 1, remove the w - if(1 == command.w) { - delete command.w; - } - - // Execute command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null); -}; - -DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand; - -DbCommand.createGetPreviousErrorsCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null); -}; - -DbCommand.createResetErrorHistoryCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null); -}; - -DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) { - var fieldHash = {}; - var indexes = []; - var keys; - - // Get all the fields accordingly - if('string' == typeof fieldOrSpec) { - // 'type' - indexes.push(fieldOrSpec + '_' + 1); - fieldHash[fieldOrSpec] = 1; - - } else if(utils.isArray(fieldOrSpec)) { - - fieldOrSpec.forEach(function(f) { - if('string' == typeof f) { - // [{location:'2d'}, 'type'] - indexes.push(f + '_' + 1); - fieldHash[f] = 1; - } else if(utils.isArray(f)) { - // [['location', '2d'],['type', 1]] - indexes.push(f[0] + '_' + (f[1] || 1)); - fieldHash[f[0]] = f[1] || 1; - } else if(utils.isObject(f)) { - // [{location:'2d'}, {type:1}] - keys = Object.keys(f); - keys.forEach(function(k) { - indexes.push(k + '_' + f[k]); - fieldHash[k] = f[k]; - }); - } else { - // undefined (ignore) - } - }); - - } else if(utils.isObject(fieldOrSpec)) { - // {location:'2d', type:1} - keys = Object.keys(fieldOrSpec); - keys.forEach(function(key) { - indexes.push(key + '_' + fieldOrSpec[key]); - fieldHash[key] = fieldOrSpec[key]; - }); - } - - // Generate the index name - var indexName = typeof options.name == 'string' - ? options.name - : indexes.join("_"); - - var selector = { - 'ns': db.databaseName + "." + collectionName, - 'key': fieldHash, - 'name': indexName - } - - // Ensure we have a correct finalUnique - var finalUnique = options == null || 'object' === typeof options - ? false - : options; - - // Set up options - options = options == null || typeof options == 'boolean' - ? {} - : options; - - // Add all the options - var keys = Object.keys(options); - for(var i = 0; i < keys.length; i++) { - selector[keys[i]] = options[keys[i]]; - } - - if(selector['unique'] == null) - selector['unique'] = finalUnique; - - var name = db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION; - var cmd = new InsertCommand(db, name, false); - return cmd.add(selector); -}; - -DbCommand.logoutCommand = function(db, command_hash, options) { - var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName; - // Create logout command - return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -} - -DbCommand.createDropIndexCommand = function(db, collectionName, indexName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null); -}; - -DbCommand.createReIndexCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null); -}; - -DbCommand.createDropDatabaseCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null); -}; - -DbCommand.createDbCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options); -}; - -DbCommand.createAdminDbCommand = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -}; - -DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null); -}; - -DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options); -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js deleted file mode 100644 index e6ae20ab6e6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js +++ /dev/null @@ -1,114 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.flags = flags; - this.collectionName = collectionName; - this.selector = selector; - this.db = db; -}; - -inherits(DeleteCommand, BaseCommand); - -DeleteCommand.OP_DELETE = 2006; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 ZERO; // 0 - reserved for future use - mongo.BSON selector; // query object. See below for details. -} -*/ -DeleteCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff; - _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff; - _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff; - _command[_index] = DeleteCommand.OP_DELETE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(this.selector)) { - documentLength = this.selector.length; - // Copy the data into the current buffer - this.selector.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js deleted file mode 100644 index d3aac02ef81..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js +++ /dev/null @@ -1,83 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Get More Document Command -**/ -var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.numberToReturn = numberToReturn; - this.cursorId = cursorId; - this.db = db; -}; - -inherits(GetMoreCommand, BaseCommand); - -GetMoreCommand.OP_GET_MORE = 2005; - -GetMoreCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index++] = totalLengthOfCommand & 0xff; - _command[_index++] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 24) & 0xff; - - // Write the request ID - _command[_index++] = this.requestId & 0xff; - _command[_index++] = (this.requestId >> 8) & 0xff; - _command[_index++] = (this.requestId >> 16) & 0xff; - _command[_index++] = (this.requestId >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the op_code for the command - _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Number of documents to return - _command[_index++] = this.numberToReturn & 0xff; - _command[_index++] = (this.numberToReturn >> 8) & 0xff; - _command[_index++] = (this.numberToReturn >> 16) & 0xff; - _command[_index++] = (this.numberToReturn >> 24) & 0xff; - - // Encode the cursor id - var low_bits = this.cursorId.getLowBits(); - // Encode low bits - _command[_index++] = low_bits & 0xff; - _command[_index++] = (low_bits >> 8) & 0xff; - _command[_index++] = (low_bits >> 16) & 0xff; - _command[_index++] = (low_bits >> 24) & 0xff; - - var high_bits = this.cursorId.getHighBits(); - // Encode high bits - _command[_index++] = high_bits & 0xff; - _command[_index++] = (high_bits >> 8) & 0xff; - _command[_index++] = (high_bits >> 16) & 0xff; - _command[_index++] = (high_bits >> 24) & 0xff; - // Return command - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js deleted file mode 100644 index d6a210017a5..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js +++ /dev/null @@ -1,147 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.documents = []; - this.checkKeys = checkKeys == null ? true : checkKeys; - this.db = db; - this.flags = 0; - this.serializeFunctions = false; - - // Ensure valid options hash - options = options == null ? {} : options; - - // Check if we have keepGoing set -> set flag if it's the case - if(options['keepGoing'] != null && options['keepGoing']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Check if we have keepGoing set -> set flag if it's the case - if(options['continueOnError'] != null && options['continueOnError']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(InsertCommand, BaseCommand); - -// OpCodes -InsertCommand.OP_INSERT = 2002; - -InsertCommand.prototype.add = function(document) { - if(Buffer.isBuffer(document)) { - var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24; - if(object_size != document.length) { - var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.documents.push(document); - return this; -}; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - BSON[] documents; // one or more documents to insert into the collection -} -*/ -InsertCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4); - // var docLength = 0 - for(var i = 0; i < this.documents.length; i++) { - if(Buffer.isBuffer(this.documents[i])) { - totalLengthOfCommand += this.documents[i].length; - } else { - // Calculate size of document - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true); - } - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff; - _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff; - _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff; - _command[_index] = InsertCommand.OP_INSERT & 0xff; - // Adjust index - _index = _index + 4; - // Write flags if any - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write all the bson documents to the buffer at the index offset - for(var i = 0; i < this.documents.length; i++) { - // Document binary length - var documentLength = 0 - var object = this.documents[i]; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - return _command; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js deleted file mode 100644 index d8ccb0c3a64..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js +++ /dev/null @@ -1,98 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Insert Document Command -**/ -var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) { - BaseCommand.call(this); - - this.cursorIds = cursorIds; - this.db = db; -}; - -inherits(KillCursorCommand, BaseCommand); - -KillCursorCommand.OP_KILL_CURSORS = 2007; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - int32 numberOfCursorIDs; // number of cursorIDs in message - int64[] cursorIDs; // array of cursorIDs to close -} -*/ -KillCursorCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff; - _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff; - _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff; - _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Number of cursors to kill - var numberOfCursors = this.cursorIds.length; - _command[_index + 3] = (numberOfCursors >> 24) & 0xff; - _command[_index + 2] = (numberOfCursors >> 16) & 0xff; - _command[_index + 1] = (numberOfCursors >> 8) & 0xff; - _command[_index] = numberOfCursors & 0xff; - // Adjust index - _index = _index + 4; - - // Encode all the cursors - for(var i = 0; i < this.cursorIds.length; i++) { - // Encode the cursor id - var low_bits = this.cursorIds[i].getLowBits(); - // Encode low bits - _command[_index + 3] = (low_bits >> 24) & 0xff; - _command[_index + 2] = (low_bits >> 16) & 0xff; - _command[_index + 1] = (low_bits >> 8) & 0xff; - _command[_index] = low_bits & 0xff; - // Adjust index - _index = _index + 4; - - var high_bits = this.cursorIds[i].getHighBits(); - // Encode high bits - _command[_index + 3] = (high_bits >> 24) & 0xff; - _command[_index + 2] = (high_bits >> 16) & 0xff; - _command[_index + 1] = (high_bits >> 8) & 0xff; - _command[_index] = high_bits & 0xff; - // Adjust index - _index = _index + 4; - } - - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js deleted file mode 100644 index 76829d9991f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js +++ /dev/null @@ -1,261 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = query, - object_size; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - object = returnFieldSelector; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Set up options - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - - // Ensure we have no null query - query = query == null ? {} : query; - // Wrap query in the $query parameter so we can add read preferences for mongos - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = db; - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(QueryCommand, BaseCommand); - -QueryCommand.OP_QUERY = 2004; - -/* - * Adds the read prefrence to the current command - */ -QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) { - // If we have readPreference set to true set to secondary prefered - if(readPreference == true) { - readPreference = 'secondaryPreferred'; - } else if(readPreference == 'false') { - readPreference = 'primary'; - } - - // Force the slave ok flag to be set if we are not using primary read preference - if(readPreference != false && readPreference != 'primary') { - this.queryOptions |= QueryCommand.OPTS_SLAVE; - } - - // Backward compatibility, ensure $query only set on read preference so 1.8.X works - if((readPreference != null || tags != null) && this.query['$query'] == null) { - this.query = {'$query': this.query}; - } - - // If we have no readPreference set and no tags, check if the slaveOk bit is set - if(readPreference == null && tags == null) { - // If we have a slaveOk bit set the read preference for MongoS - if(this.queryOptions & QueryCommand.OPTS_SLAVE) { - this.query['$readPreference'] = {mode: 'secondary'} - } else { - this.query['$readPreference'] = {mode: 'primary'} - } - } - - // Build read preference object - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - this.query['$readPreference'] = readPreference.toObject(); - } else if(readPreference != null) { - // Add the read preference - this.query['$readPreference'] = {mode: readPreference}; - - // If we have tags let's add them - if(tags != null) { - this.query['$readPreference']['tags'] = tags; - } - } -} - -/* -struct { - MsgHeader header; // standard message header - int32 opts; // query options. See below for details. - cstring fullCollectionName; // "dbname.collectionname" - int32 numberToSkip; // number of documents to skip when returning results - int32 numberToReturn; // number of documents to return in the first OP_REPLY - BSON query ; // query object. See below for details. - [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details. -} -*/ -QueryCommand.prototype.toBinary = function() { - // Total length of the command - var totalLengthOfCommand = 0; - // Calculate total length of the document - if(Buffer.isBuffer(this.query)) { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4); - } else { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4); - } - - // Calculate extra fields size - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true); - } - } else if(Buffer.isBuffer(this.returnFieldSelector)) { - totalLengthOfCommand += this.returnFieldSelector.length; - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff; - _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff; - _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff; - _command[_index] = QueryCommand.OP_QUERY & 0xff; - // Adjust index - _index = _index + 4; - - // Write the query options - _command[_index + 3] = (this.queryOptions >> 24) & 0xff; - _command[_index + 2] = (this.queryOptions >> 16) & 0xff; - _command[_index + 1] = (this.queryOptions >> 8) & 0xff; - _command[_index] = this.queryOptions & 0xff; - // Adjust index - _index = _index + 4; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the number of documents to skip - _command[_index + 3] = (this.numberToSkip >> 24) & 0xff; - _command[_index + 2] = (this.numberToSkip >> 16) & 0xff; - _command[_index + 1] = (this.numberToSkip >> 8) & 0xff; - _command[_index] = this.numberToSkip & 0xff; - // Adjust index - _index = _index + 4; - - // Write the number of documents to return - _command[_index + 3] = (this.numberToReturn >> 24) & 0xff; - _command[_index + 2] = (this.numberToReturn >> 16) & 0xff; - _command[_index + 1] = (this.numberToReturn >> 8) & 0xff; - _command[_index] = this.numberToReturn & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.query; - - // Serialize the selector - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Push field selector if available - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) { - // Document binary length - var documentLength = 0 - var object = this.returnFieldSelector; - - // Serialize the selector - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - // Return finished command - return _command; -}; - -// Constants -QueryCommand.OPTS_NONE = 0; -QueryCommand.OPTS_TAILABLE_CURSOR = 2; -QueryCommand.OPTS_SLAVE = 4; -QueryCommand.OPTS_OPLOG_REPLY = 8; -QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16; -QueryCommand.OPTS_AWAIT_DATA = 32; -QueryCommand.OPTS_EXHAUST = 64; -QueryCommand.OPTS_PARTIAL = 128; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js deleted file mode 100644 index 9829dea453d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js +++ /dev/null @@ -1,174 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Update Document Command -**/ -var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) { - BaseCommand.call(this); - - var object = spec; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - var object = document; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.collectionName = collectionName; - this.spec = spec; - this.document = document; - this.db = db; - this.serializeFunctions = false; - - // Generate correct flags - var db_upsert = 0; - var db_multi_update = 0; - db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert; - db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update; - - // Flags - this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2); - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(UpdateCommand, BaseCommand); - -UpdateCommand.OP_UPDATE = 2001; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 flags; // bit vector. see below - BSON spec; // the query to select the document - BSON document; // the document data to update with or insert -} -*/ -UpdateCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) + - this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4); - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff; - _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff; - _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff; - _command[_index] = UpdateCommand.OP_UPDATE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the update flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.spec; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Document binary length - var documentLength = 0 - var object = this.document; - - // Serialize the document - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - return _command; -}; - -// Constants -UpdateCommand.DB_UPSERT = 0; -UpdateCommand.DB_MULTI_UPDATE = 1; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js deleted file mode 100644 index e93463c305f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js +++ /dev/null @@ -1,169 +0,0 @@ -var EventEmitter = require('events').EventEmitter - , inherits = require('util').inherits; - -/** - * Internal class for callback storage - * @ignore - */ -var CallbackStore = function() { - // Make class an event emitter - EventEmitter.call(this); - // Add a info about call variable - this._notReplied = {}; -} - -/** - * @ignore - */ -inherits(CallbackStore, EventEmitter); - -var Base = function Base() { - EventEmitter.call(this); - - // Callback store is part of connection specification - if(Base._callBackStore == null) { - Base._callBackStore = new CallbackStore(); - } - - // this._callBackStore = Base._callBackStore; - this._callBackStore = new CallbackStore(); -} - -/** - * @ignore - */ -inherits(Base, EventEmitter); - -/** - * Fire all the errors - * @ignore - */ -Base.prototype.__executeAllCallbacksWithError = function(err) { - // Check all callbacks - var keys = Object.keys(this._callBackStore._notReplied); - // For each key check if it's a callback that needs to be returned - for(var j = 0; j < keys.length; j++) { - var info = this._callBackStore._notReplied[keys[j]]; - // Check if we have a chained command (findAndModify) - if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) { - var chained = info['chained']; - // Only callback once and the last one is the right one - var finalCallback = chained.pop(); - // Emit only the last event - this._callBackStore.emit(finalCallback, err, null); - - // Put back the final callback to ensure we don't call all commands in the chain - chained.push(finalCallback); - - // Remove all chained callbacks - for(var i = 0; i < chained.length; i++) { - delete this._callBackStore._notReplied[chained[i]]; - } - } else { - this._callBackStore.emit(keys[j], err, null); - } - } -} - -/** - * Register a handler - * @ignore - * @api private - */ -Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) { - // If we have an array of commands, chain them - var chained = Array.isArray(db_command); - - // Check if we have exhausted - if(typeof exhaust == 'function') { - callback = exhaust; - exhaust = false; - } - - // If they are chained we need to add a special handler situation - if(chained) { - // List off chained id's - var chainedIds = []; - // Add all id's - for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString()); - // Register all the commands together - for(var i = 0; i < db_command.length; i++) { - var command = db_command[i]; - // Add the callback to the store - this._callBackStore.once(command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection, exhaust:false}; - } - } else { - // Add the callback to the list of handlers - this._callBackStore.once(db_command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust}; - } -} - -/** - * Re-Register a handler, on the cursor id f.ex - * @ignore - * @api private - */ -Base.prototype._reRegisterHandler = function(newId, object, callback) { - // Add the callback to the list of handlers - this._callBackStore.once(newId, object.callback.listener); - // Add the information about the reply - this._callBackStore._notReplied[newId] = object.info; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._callHandler = function(id, document, err) { - // If there is a callback peform it - if(this._callBackStore.listeners(id).length >= 1) { - // Get info object - var info = this._callBackStore._notReplied[id]; - // Delete the current object - delete this._callBackStore._notReplied[id]; - // Emit to the callback of the object - this._callBackStore.emit(id, err, document, info.connection); - } -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._hasHandler = function(id) { - // If there is a callback peform it - return this._callBackStore.listeners(id).length >= 1; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._removeHandler = function(id) { - // Remove the information - if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id]; - // Remove the callback if it's registered - this._callBackStore.removeAllListeners(id); - // Force cleanup _events, node.js seems to set it as a null value - if(this._callBackStore._events != null) delete this._callBackStore._events[id]; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._findHandler = function(id) { - var info = this._callBackStore._notReplied[id]; - // Return the callback - return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null} -} - -exports.Base = Base; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js deleted file mode 100644 index 14cbeeee222..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js +++ /dev/null @@ -1,494 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - binaryutils = require('../utils'), - tls = require('tls'); - -var Connection = exports.Connection = function(id, socketOptions) { - // Set up event emitter - EventEmitter.call(this); - // Store all socket options - this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false}; - // Set keep alive default if not overriden - if(this.socketOptions.keepAlive == null && (process.platform !== "sunos" || process.platform !== "win32")) this.socketOptions.keepAlive = 100; - // Id for the connection - this.id = id; - // State of the connection - this.connected = false; - // Set if this is a domain socket - this.domainSocket = this.socketOptions.domainSocket; - - // - // Connection parsing state - // - this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE; - // Contains the current message bytes - this.buffer = null; - // Contains the current message size - this.sizeOfMessage = 0; - // Contains the readIndex for the messaage - this.bytesRead = 0; - // Contains spill over bytes from additional messages - this.stubBuffer = 0; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]}; - - // Just keeps list of events we allow - resetHandlers(this, false); -} - -// Set max bson size -Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4; - -// Inherit event emitter so we can emit stuff wohoo -inherits(Connection, EventEmitter); - -Connection.prototype.start = function() { - var self = this; - - // If we have a normal connection - if(this.socketOptions.ssl) { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Check if the driver should validate the certificate - var validate_certificates = this.socketOptions.sslValidate == true ? true : false; - - // Create options for the tls connection - var tls_options = { - socket: this.connection - , rejectUnauthorized: false - } - - // If we wish to validate the certificate we have provided a ca store - if(validate_certificates) { - tls_options.ca = this.socketOptions.sslCA; - } - - // If we have a certificate to present - if(this.socketOptions.sslCert) { - tls_options.cert = this.socketOptions.sslCert; - tls_options.key = this.socketOptions.sslKey; - // Allow for a combined cert/key pem file being passed in as cert parameter - // if(tls_options.key == null) { - // tls_options.key = this.socketOptions.ssl_cert; - // } - } - - // If the driver has been provided a private key password - if(this.socketOptions.sslPass) { - tls_options.passphrase = this.socketOptions.sslPass; - } - - // Contains the cleartext stream - var cleartext = null; - // Attempt to establish a TLS connection to the server - try { - cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() { - // If we have a ssl certificate validation error return an error - if(cleartext.authorizationError && validate_certificates) { - // Emit an error - return self.emit("error", cleartext.authorizationError, self, {ssl:true}); - } - - // Connect to the server - connectHandler(self)(); - }) - } catch(err) { - return self.emit("error", "SSL connection failed", self, {ssl:true}); - } - - // Save the output stream - this.writeSteam = cleartext; - - // Set up data handler for the clear stream - cleartext.on("data", createDataHandler(this)); - // Do any handling of end event of the stream - cleartext.on("end", endHandler(this)); - cleartext.on("error", errorHandler(this)); - - // Handle any errors - this.connection.on("error", errorHandler(this)); - // Handle timeout - this.connection.on("timeout", timeoutHandler(this)); - // Handle drain event - this.connection.on("drain", drainHandler(this)); - // Handle the close event - this.connection.on("close", closeHandler(this)); - } else { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Set up write stream - this.writeSteam = this.connection; - // Add handlers - this.connection.on("error", errorHandler(this)); - // Add all handlers to the socket to manage it - this.connection.on("connect", connectHandler(this)); - // this.connection.on("end", endHandler(this)); - this.connection.on("data", createDataHandler(this)); - this.connection.on("timeout", timeoutHandler(this)); - this.connection.on("drain", drainHandler(this)); - this.connection.on("close", closeHandler(this)); - } -} - -// Check if the sockets are live -Connection.prototype.isConnected = function() { - return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable; -} - -// Write the data out to the socket -Connection.prototype.write = function(command, callback) { - try { - // If we have a list off commands to be executed on the same socket - if(Array.isArray(command)) { - for(var i = 0; i < command.length; i++) { - var binaryCommand = command[i].toBinary() - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximal allowed bson size of " + this.maxBsonSize + " bytes")); - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]}); - - var r = this.writeSteam.write(binaryCommand); - } - } else { - var binaryCommand = command.toBinary() - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximal allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command}); - - var r = this.writeSteam.write(binaryCommand); - } - } catch (err) { - if(typeof callback === 'function') callback(err); - } -} - -// Force the closure of the connection -Connection.prototype.close = function() { - // clear out all the listeners - resetHandlers(this, true); - // Add a dummy error listener to catch any weird last moment errors (and ignore them) - this.connection.on("error", function() {}) - // destroy connection - this.connection.destroy(); - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("closed connection", this.connection); - } -} - -// Reset all handlers -var resetHandlers = function(self, clearListeners) { - self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]}; - - // If we want to clear all the listeners - if(clearListeners && self.connection != null) { - var keys = Object.keys(self.eventHandlers); - // Remove all listeners - for(var i = 0; i < keys.length; i++) { - self.connection.removeAllListeners(keys[i]); - } - } -} - -// -// Handlers -// - -// Connect handler -var connectHandler = function(self) { - return function(data) { - // Set connected - self.connected = true; - // Now that we are connected set the socket timeout - self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout); - // Emit the connect event with no error - self.emit("connect", null, self); - } -} - -var createDataHandler = exports.Connection.createDataHandler = function(self) { - // We need to handle the parsing of the data - // and emit the messages when there is a complete one - return function(data) { - // Parse until we are done with the data - while(data.length > 0) { - // If we still have bytes to read on the current message - if(self.bytesRead > 0 && self.sizeOfMessage > 0) { - // Calculate the amount of remaining bytes - var remainingBytesToRead = self.sizeOfMessage - self.bytesRead; - // Check if the current chunk contains the rest of the message - if(remainingBytesToRead > data.length) { - // Copy the new data into the exiting buffer (should have been allocated when we know the message size) - data.copy(self.buffer, self.bytesRead); - // Adjust the number of bytes read so it point to the correct index in the buffer - self.bytesRead = self.bytesRead + data.length; - - // Reset state of buffer - data = new Buffer(0); - } else { - // Copy the missing part of the data into our current buffer - data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead); - // Slice the overflow into a new buffer that we will then re-parse - data = data.slice(remainingBytesToRead); - - // Emit current complete message - try { - var emitBuffer = self.buffer; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Emit the buffer - self.emit("message", emitBuffer, self); - } catch(err) { - var errorObject = {err:"socketHandler", trace:err, bin:buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } - } else { - // Stub buffer is kept in case we don't get enough bytes to determine the - // size of the message (< 4 bytes) - if(self.stubBuffer != null && self.stubBuffer.length > 0) { - - // If we have enough bytes to determine the message size let's do it - if(self.stubBuffer.length + data.length > 4) { - // Prepad the data - var newData = new Buffer(self.stubBuffer.length + data.length); - self.stubBuffer.copy(newData, 0); - data.copy(newData, self.stubBuffer.length); - // Reassign for parsing - data = newData; - - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - - } else { - - // Add the the bytes to the stub buffer - var newStubBuffer = new Buffer(self.stubBuffer.length + data.length); - // Copy existing stub buffer - self.stubBuffer.copy(newStubBuffer, 0); - // Copy missing part of the data - data.copy(newStubBuffer, self.stubBuffer.length); - // Exit parsing loop - data = new Buffer(0); - } - } else { - if(data.length > 4) { - // Retrieve the message size - var sizeOfMessage = binaryutils.decodeUInt32(data, 0); - // If we have a negative sizeOfMessage emit error and return - if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{ - sizeOfMessage: sizeOfMessage, - bytesRead: self.bytesRead, - stubBuffer: self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - return; - } - - // Ensure that the size of message is larger than 0 and less than the max allowed - if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) { - self.buffer = new Buffer(sizeOfMessage); - // Copy all the data into the buffer - data.copy(self.buffer, 0); - // Update bytes read - self.bytesRead = data.length; - // Update sizeOfMessage - self.sizeOfMessage = sizeOfMessage; - // Ensure stub buffer is null - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) { - try { - var emitBuffer = data; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:0, - buffer:null, - stubBuffer:null}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - - // Clear out the state of the parser - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else { - try { - var emitBuffer = data.slice(0, sizeOfMessage); - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Copy rest of message - data = data.slice(sizeOfMessage); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - - } - } else { - // Create a buffer that contains the space for the non-complete message - self.stubBuffer = new Buffer(data.length) - // Copy the data to the stub buffer - data.copy(self.stubBuffer, 0); - // Exit parsing loop - data = new Buffer(0); - } - } - } - } - } -} - -var endHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit end event - self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var timeoutHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit timeout event - self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self); - } -} - -var drainHandler = function(self) { - return function() { - } -} - -var errorHandler = function(self) { - return function(err) { - // Set connected to false - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var closeHandler = function(self) { - return function(hadError) { - // If we have an error during the connection phase - if(hadError && !self.connected) { - // Set disconnected - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } else { - // Set disconnected - self.connected = false; - // Emit close - self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } - } -} - -// Some basic defaults -Connection.DEFAULT_PORT = 27017; - - - - - - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js deleted file mode 100644 index 8e6f3eed4dc..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js +++ /dev/null @@ -1,278 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - MongoReply = require("../responses/mongo_reply").MongoReply, - Connection = require("./connection").Connection; - -var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) { - if(typeof host !== 'string') { - throw new Error("host must be specified [" + host + "]"); - } - - // Set up event emitter - EventEmitter.call(this); - - // Keep all options for the socket in a specific collection allowing the user to specify the - // Wished upon socket connection parameters - this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {}; - this.socketOptions.host = host; - this.socketOptions.port = port; - this.socketOptions.domainSocket = false; - this.bson = bson; - // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc) - this.poolSize = poolSize; - this.minPoolSize = Math.floor(this.poolSize / 2) + 1; - - // Check if the host is a socket - if(host.match(/^\//)) { - this.socketOptions.domainSocket = true; - } else if(typeof port === 'string') { - try { - port = parseInt(port, 10); - } catch(err) { - new Error("port must be specified or valid integer[" + port + "]"); - } - } else if(typeof port !== 'number') { - throw new Error("port must be specified [" + port + "]"); - } - - // Set default settings for the socket options - utils.setIntegerParameter(this.socketOptions, 'timeout', 0); - // Delay before writing out the data to the server - utils.setBooleanParameter(this.socketOptions, 'noDelay', true); - // Delay before writing out the data to the server - utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0); - // Set the encoding of the data read, default is binary == null - utils.setStringParameter(this.socketOptions, 'encoding', null); - // Allows you to set a throttling bufferSize if you need to stop overflows - utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0); - - // Internal structures - this.openConnections = []; - // Assign connection id's - this.connectionId = 0; - - // Current index for selection of pool connection - this.currentConnectionIndex = 0; - // The pool state - this._poolState = 'disconnected'; - // timeout control - this._timeout = false; - // Time to wait between connections for the pool - this._timeToWait = 10; -} - -inherits(ConnectionPool, EventEmitter); - -ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) { - if(maxBsonSize == null){ - maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxBsonSize = maxBsonSize; - } -} - -// Start a function -var _connect = function(_self) { - // return new function() { - // Create a new connection instance - var connection = new Connection(_self.connectionId++, _self.socketOptions); - // Set logger on pool - connection.logger = _self.logger; - // Connect handler - connection.on("connect", function(err, connection) { - // Add connection to list of open connections - _self.openConnections.push(connection); - // If the number of open connections is equal to the poolSize signal ready pool - if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') { - // Set connected - _self._poolState = 'connected'; - // Emit pool ready - _self.emit("poolReady"); - } else if(_self.openConnections.length < _self.poolSize) { - // Wait a little bit of time to let the close event happen if the server closes the connection - // so we don't leave hanging connections around - if(typeof _self._timeToWait == 'number') { - setTimeout(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }, _self._timeToWait); - } else { - process.nextTick(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }); - } - } - }); - - var numberOfErrors = 0 - - // Error handler - connection.on("error", function(err, connection, error_options) { - numberOfErrors++; - // If we are already disconnected ignore the event - if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) { - _self.emit("error", err, connection, error_options); - } - - // Close the connection - connection.close(); - // Set pool as disconnected - _self._poolState = 'disconnected'; - // Stop the pool - _self.stop(); - }); - - // Close handler - connection.on("close", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) { - _self.emit("close"); - } - - // Set disconnected - _self._poolState = 'disconnected'; - // Stop - _self.stop(); - }); - - // Timeout handler - connection.on("timeout", function(err, connection) { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) { - _self.emit("timeout", err); - } - - // Close the connection - connection.close(); - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - // Parse error, needs a complete shutdown of the pool - connection.on("parseError", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) { - _self.emit("parseError", new Error("parseError occured")); - } - - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - connection.on("message", function(message) { - _self.emit("message", message); - }); - - // Start connection in the next tick - connection.start(); - // }(); -} - - -// Start method, will throw error if no listeners are available -// Pass in an instance of the listener that contains the api for -// finding callbacks for a given message etc. -ConnectionPool.prototype.start = function() { - var markerDate = new Date().getTime(); - var self = this; - - if(this.listeners("poolReady").length == 0) { - throw "pool must have at least one listener ready that responds to the [poolReady] event"; - } - - // Set pool state to connecting - this._poolState = 'connecting'; - this._timeout = false; - - _connect(self); -} - -// Restart a connection pool (on a close the pool might be in a wrong state) -ConnectionPool.prototype.restart = function() { - // Close all connections - this.stop(false); - // Now restart the pool - this.start(); -} - -// Stop the connections in the pool -ConnectionPool.prototype.stop = function(removeListeners) { - removeListeners = removeListeners == null ? true : removeListeners; - // Set disconnected - this._poolState = 'disconnected'; - - // Clear all listeners if specified - if(removeListeners) { - this.removeAllEventListeners(); - } - - // Close all connections - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].close(); - } - - // Clean up - this.openConnections = []; -} - -// Check the status of the connection -ConnectionPool.prototype.isConnected = function() { - return this._poolState === 'connected'; -} - -// Checkout a connection from the pool for usage, or grab a specific pool instance -ConnectionPool.prototype.checkoutConnection = function(id) { - var index = (this.currentConnectionIndex++ % (this.openConnections.length)); - var connection = this.openConnections[index]; - return connection; -} - -ConnectionPool.prototype.getAllConnections = function() { - return this.openConnections; -} - -// Remove all non-needed event listeners -ConnectionPool.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("connect"); - this.removeAllListeners("end"); - this.removeAllListeners("parseError"); - this.removeAllListeners("message"); - this.removeAllListeners("poolReady"); -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js deleted file mode 100644 index 591092495a8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.setIntegerParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) { - throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setBooleanParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "boolean") { - throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setStringParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "string") { - throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js deleted file mode 100644 index ffcb1aa5c5b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js +++ /dev/null @@ -1,334 +0,0 @@ -var ReadPreference = require('./read_preference').ReadPreference - , Base = require('./base').Base - , inherits = require('util').inherits; - -/** - * Mongos constructor provides a connection to a mongos proxy including failover to additional servers - * - * Options - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - * @class Represents a Mongos connection with failover to backup proxies - * @param {Array} list of mongos server objects - * @param {Object} [options] additional options for the mongos connection - */ -var Mongos = function Mongos(servers, options) { - // Set up basic - if(!(this instanceof Mongos)) - return new Mongos(servers, options); - - // Set up event emitter - Base.call(this); - - // Throw error on wrong setup - if(servers == null || !Array.isArray(servers) || servers.length == 0) - throw new Error("At least one mongos proxy must be in the array"); - - // Ensure we have at least an empty options object - this.options = options == null ? {} : options; - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - // How often are we checking for new servers in the replicaset - this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 2000 : this.options['haInterval']; - // Save all the server connections - this.servers = servers; - // Servers we need to attempt reconnect with - this.downServers = []; - // Just contains the current lowest ping time and server - this.lowestPingTimeServer = null; - this.lowestPingTime = 0; - - // Add options to servers - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - server._callBackStore = this._callBackStore; - // Default empty socket options object - var socketOptions = {host: server.host, port: server.port}; - // If a socket option object exists clone it - if(this.socketOptions != null) { - var keys = Object.keys(this.socketOptions); - for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]]; - } - // Set socket options - server.socketOptions = socketOptions; - } -} - -/** - * @ignore - */ -inherits(Mongos, Base); - -/** - * @ignore - */ -Mongos.prototype.isMongos = function() { - return true; -} - -/** - * @ignore - */ -Mongos.prototype.connect = function(db, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - - // Keep reference to parent - this.db = db; - // Set server state to connecting - this._serverState = 'connecting'; - // Number of total servers that need to initialized (known servers) - this._numberOfServersLeftToInitialize = this.servers.length; - // Default to the first proxy server as the first one to use - this._currentMongos = this.servers[0]; - - // Connect handler - var connectHandler = function(_server) { - return function(err, result) { - self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1; - - if(self._numberOfServersLeftToInitialize == 0) { - // Start ha function if it exists - if(self.haEnabled) { - // Setup the ha process - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - - // Set the mongos to connected - self._serverState = "connected"; - // Emit the open event - self.db.emit("open", null, self.db); - // Callback - callback(null, self.db); - } - } - }; - - // Error handler - var errorOrCloseHandler = function(_server) { - return function(err, result) { - // Create current mongos comparision - var currentUrl = self._currentMongos.host + ":" + self._currentMongos.port; - var serverUrl = this.host + ":" + this.port; - // We need to check if the server that closed is the actual current proxy we are using, otherwise - // just ignore - if(currentUrl == serverUrl) { - // Remove the server from the list - if(self.servers.indexOf(_server) != -1) { - self.servers.splice(self.servers.indexOf(_server), 1); - } - - // Pick the next one on the list if there is one - for(var i = 0; i < self.servers.length; i++) { - // Grab the server out of the array (making sure there is no servers in the list if none available) - var server = self.servers[i]; - // Generate url for comparision - var serverUrl = server.host + ":" + server.port; - // It's not the current one and connected set it as the current db - if(currentUrl != serverUrl && server.isConnected()) { - self._currentMongos = server; - break; - } - } - } - - // Ensure we don't store the _server twice - if(self.downServers.indexOf(_server) == -1) { - // Add the server instances - self.downServers.push(_server); - } - } - } - - // Mongo function - this.mongosCheckFunction = function() { - // If we have down servers let's attempt a reconnect - if(self.downServers.length > 0) { - var numberOfServersLeft = self.downServers.length; - // Attempt to reconnect - for(var i = 0; i < self.downServers.length; i++) { - var downServer = self.downServers.pop(); - // Attemp to reconnect - downServer.connect(self.db, {returnIsMasterResults: true}, function(_server) { - // Return a function to check for the values - return function(err, result) { - // Adjust the number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - - if(err != null) { - self.downServers.push(_server); - } else { - // Add server event handlers - _server.on("close", errorOrCloseHandler(_server)); - _server.on("error", errorOrCloseHandler(_server)); - // Add to list of servers - self.servers.push(_server); - } - - if(numberOfServersLeft <= 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - }(downServer)); - } - } else if(self.servers.length > 0) { - var numberOfServersLeft = self.servers.length; - var _s = new Date().getTime() - - // Else let's perform a ping command - for(var i = 0; i < self.servers.length; i++) { - var executePing = function(_server) { - // Get a read connection - var _connection = _server.checkoutReader(); - // Execute ping command - self.db.command({ping:1}, {connection:_connection}, function(err, result) { - var pingTime = new Date().getTime() - _s; - // If no server set set the first one, otherwise check - // the lowest ping time and assign the server if it's got a lower ping time - if(self.lowestPingTimeServer == null) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } else if(self.lowestPingTime > pingTime - && (_server.host != self.lowestPingTimeServer.host || _server.port != self.lowestPingTimeServer.port)) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } - - // Number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - // All active mongos's pinged - if(numberOfServersLeft == 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - }) - } - // Execute the function - executePing(self.servers[i]); - } - } else { - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - - // Connect all the server instances - for(var i = 0; i < this.servers.length; i++) { - // Get the connection - var server = this.servers[i]; - server.mongosInstance = this; - // Add server event handlers - server.on("close", errorOrCloseHandler(server)); - server.on("timeout", errorOrCloseHandler(server)); - server.on("error", errorOrCloseHandler(server)); - // Connect the instance - server.connect(self.db, {returnIsMasterResults: true}, connectHandler(server)); - } -} - -/** - * @ignore - * Just return the currently picked active connection - */ -Mongos.prototype.allServerInstances = function() { - return this.servers; -} - -/** - * Always ourselves - * @ignore - */ -Mongos.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Mongos.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - // Add all connections - for(var i = 0; i < this.servers.length; i++) { - allConnections = allConnections.concat(this.servers[i].allRawConnections()); - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -Mongos.prototype.isConnected = function() { - return this._serverState == "connected"; -} - -/** - * @ignore - */ -Mongos.prototype.checkoutWriter = function() { - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutWriter(); - } - return this._currentMongos.checkoutWriter(); -} - -/** - * @ignore - */ -Mongos.prototype.checkoutReader = function(read) { - // If we have a read preference object unpack it - if(typeof read == 'object' && read['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode); - } else if(!ReadPreference.isValid(read)) { - throw new Error("Illegal readPreference mode specified, " + read); - } - - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutReader(); - } - return this._currentMongos.checkoutReader(); -} - -/** - * @ignore - */ -Mongos.prototype.close = function(callback) { - var self = this; - // Set server status as disconnected - this._serverState = 'disconnected'; - // Number of connections to close - var numberOfConnectionsToClose = self.servers.length; - // If we have a ha process running kill it - if(self._replicasetTimeoutId != null) clearTimeout(self._replicasetTimeoutId); - // Close all proxy connections - for(var i = 0; i < self.servers.length; i++) { - self.servers[i].close(function(err, result) { - numberOfConnectionsToClose = numberOfConnectionsToClose - 1; - // Callback if we have one defined - if(numberOfConnectionsToClose == 0 && typeof callback == 'function') { - callback(null); - } - }); - } -} - -/** - * @ignore - * Return the used state - */ -Mongos.prototype._isUsed = function() { - return this._used; -} - -exports.Mongos = Mongos; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js deleted file mode 100644 index 4cba58792b1..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * A class representation of the Read Preference. - * - * Read Preferences - * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.). - * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary. - * - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error. - * - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary. - * - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection. - * - * @class Represents a Read Preference. - * @param {String} the read preference type - * @param {Object} tags - * @return {ReadPreference} - */ -var ReadPreference = function(mode, tags) { - if(!(this instanceof ReadPreference)) - return new ReadPreference(mode, tags); - this._type = 'ReadPreference'; - this.mode = mode; - this.tags = tags; -} - -/** - * @ignore - */ -ReadPreference.isValid = function(_mode) { - return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED - || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED - || _mode == ReadPreference.NEAREST); -} - -/** - * @ignore - */ -ReadPreference.prototype.isValid = function(mode) { - var _mode = typeof mode == 'string' ? mode : this.mode; - return ReadPreference.isValid(_mode); -} - -/** - * @ignore - */ -ReadPreference.prototype.toObject = function() { - var object = {mode:this.mode}; - - if(this.tags != null) { - object['tags'] = this.tags; - } - - return object; -} - -/** - * @ignore - */ -ReadPreference.PRIMARY = 'primary'; -ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred'; -ReadPreference.SECONDARY = 'secondary'; -ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred'; -ReadPreference.NEAREST = 'nearest' - -/** - * @ignore - */ -exports.ReadPreference = ReadPreference; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js deleted file mode 100644 index 4bb5ac76ac9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js +++ /dev/null @@ -1,1391 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - debug = require('util').debug, - inherits = require('util').inherits, - inspect = require('util').inspect, - Server = require('./server').Server, - PingStrategy = require('./strategies/ping_strategy').PingStrategy, - StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy, - Base = require('./base').Base; - -const STATE_STARTING_PHASE_1 = 0; -const STATE_PRIMARY = 1; -const STATE_SECONDARY = 2; -const STATE_RECOVERING = 3; -const STATE_FATAL_ERROR = 4; -const STATE_STARTING_PHASE_2 = 5; -const STATE_UNKNOWN = 6; -const STATE_ARBITER = 7; -const STATE_DOWN = 8; -const STATE_ROLLBACK = 9; - -/** - * ReplSet constructor provides replicaset functionality - * - * Options - * - **ha** {Boolean, default:true}, turn on high availability. - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect. - * - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect. - * - **rs_name** {String}, the name of the replicaset to connect to. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strategy** {String, default:null}, selection strategy for reads choose between (ping and statistical, default is round-robin) - * - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms) - * - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - * @class Represents a Replicaset Configuration - * @param {Array} list of server objects participating in the replicaset. - * @param {Object} [options] additional options for the replicaset connection. - */ -var ReplSet = exports.ReplSet = function(servers, options) { - this.count = 0; - - // Set up basic - if(!(this instanceof ReplSet)) - return new ReplSet(servers, options); - - // Set up event emitter - Base.call(this); - - // Ensure no Mongos's - for(var i = 0; i < servers.length; i++) { - if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server"); - } - - // Just reference for simplicity - var self = this; - // Contains the master server entry - this.options = options == null ? {} : options; - this.reconnectWait = this.options["reconnectWait"] != null ? this.options["reconnectWait"] : 1000; - this.retries = this.options["retries"] != null ? this.options["retries"] : 30; - this.replicaSet = this.options["rs_name"]; - - // Are we allowing reads from secondaries ? - this.readSecondary = this.options["read_secondary"]; - this.slaveOk = true; - this.closedConnectionCount = 0; - this._used = false; - - // Connect arbiters ? - this.connectArbiter = this.options.connectArbiter == null ? false : this.options.connectArbiter; - - // Default poolSize for new server instances - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this._currentServerChoice = 0; - - // Set up ssl connections - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // Read preference - this._readPreference = null; - // Number of initalized severs - this._numberOfServersLeftToInitialize = 0; - // Do we record server stats or not - this.recordQueryStats = false; - // Update health try server - this.updateHealthServerTry = 0; - - // Get the readPreference - var readPreference = this.options['readPreference']; - - // Validate correctness of Read preferences - if(readPreference != null) { - if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED - && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED - && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("Illegal readPreference mode specified, " + readPreference); - } - - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Ensure read_secondary is set correctly - if(!this.readSecondary) - this.readSecondary = this._readPreference == ReadPreference.PRIMARY - || this._readPreference == false - || this._readPreference == null ? false : true; - - // Strategy for picking a secondary - this.secondaryAcceptableLatencyMS = this.options['secondaryAcceptableLatencyMS'] == null ? 15 : this.options['secondaryAcceptableLatencyMS']; - this.strategy = this.options['strategy']; - // Make sure strategy is one of the two allowed - if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical')) throw new Error("Only ping or statistical strategies allowed"); - // Let's set up our strategy object for picking secodaries - if(this.strategy == 'ping') { - // Create a new instance - this.strategyInstance = new PingStrategy(this, this.secondaryAcceptableLatencyMS); - } else if(this.strategy == 'statistical') { - // Set strategy as statistical - this.strategyInstance = new StatisticsStrategy(this); - // Add enable query information - this.enableRecordQueryStats(true); - } - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.debug == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Ensure all the instances are of type server and auto_reconnect is false - if(!Array.isArray(servers) || servers.length == 0) { - throw Error("The parameter must be an array of servers and contain at least one server"); - } else if(Array.isArray(servers) || servers.length > 0) { - var count = 0; - servers.forEach(function(server) { - if(server instanceof Server) count = count + 1; - // Ensure no server has reconnect on - server.options.auto_reconnect = false; - // Set up ssl options - server.ssl = self.ssl; - server.sslValidate = self.sslValidate; - server.sslCA = self.sslCA; - server.sslCert = self.sslCert; - server.sslKey = self.sslKey; - server.sslPass = self.sslPass; - server.poolSize = self.poolSize; - // Set callback store - server._callBackStore = self._callBackStore; - }); - - if(count < servers.length) { - throw Error("All server entries must be of type Server"); - } else { - this.servers = servers; - } - } - - // var deduplicate list - var uniqueServers = {}; - // De-duplicate any servers in the seed list - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - // If server does not exist set it - if(uniqueServers[server.host + ":" + server.port] == null) { - uniqueServers[server.host + ":" + server.port] = server; - } - } - - // Let's set the deduplicated list of servers - this.servers = []; - // Add the servers - for(var key in uniqueServers) { - this.servers.push(uniqueServers[key]); - } - - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - this._haServer = null; - // How often are we checking for new servers in the replicaset - this.replicasetStatusCheckInterval = this.options['haInterval'] == null ? 5000 : this.options['haInterval']; - this._replicasetTimeoutId = null; - - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - - // Current list of servers to test - this.pingCandidateServers = []; - - // Last replicaset check time - this.lastReplicaSetTime = new Date().getTime(); -}; - -/** - * @ignore - */ -inherits(ReplSet, Base); - -/** - * @ignore - */ -// Allow setting the read preference at the replicaset level -ReplSet.prototype.setReadPreference = function(preference) { - // Set read preference - this._readPreference = preference; - // Ensure slaveOk is correct for secodnaries read preference and tags - if((this._readPreference == ReadPreference.SECONDARY_PREFERRED || this._readPreference == ReadPreference.SECONDARY) - || (this._readPreference != null && typeof this._readPreference == 'object')) { - this.slaveOk = true; - } -} - -/** - * @ignore - */ -ReplSet.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -ReplSet.prototype.isMongos = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isConnected = function(read) { - if(read == null || read == ReadPreference.PRIMARY || read == false) - return this.primary != null && this._state.master != null && this._state.master.isConnected(); - - if((read == ReadPreference.PRIMARY_PREFERRED || read == ReadPreference.SECONDARY_PREFERRED || read == ReadPreference.NEAREST) - && ((this.primary != null && this._state.master != null && this._state.master.isConnected()) - || (this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0))) { - return true; - } else if(read == ReadPreference.SECONDARY) { - return this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0; - } - - // No valid connection return false - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isSetMember = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isPrimary = function(config) { - return this.readSecondary && Object.keys(this._state.secondaries).length > 0 ? false : true; -} - -/** - * @ignore - */ -ReplSet.prototype.isReadPrimary = ReplSet.prototype.isPrimary; - -/** - * @ignore - */ -ReplSet.prototype.allServerInstances = function() { - var self = this; - // If no state yet return empty - if(!self._state) return []; - // Close all the servers (concatenate entire list of servers first for ease) - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // Arbiter keys - var keys = Object.keys(self._state.arbiters); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.arbiters[keys[i]]); - } - - // Passive keys - var keys = Object.keys(self._state.passives); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.passives[keys[i]]); - } - - // Return complete list of all servers - return allServers; -} - -/** - * Enables high availability pings. - * - * @ignore - */ -ReplSet.prototype._enableHA = function () { - var self = this; - return check(); - - function ping () { - if("disconnected" == self._serverState) return; - // Create a list of all servers we can send the ismaster command to - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // If no servers quit as are probably connecting - if(allServers.length == 0) return; - // Pick one of the servers - self.updateHealthServerTry = self.updateHealthServerTry++ % allServers.length; - var selectedServer = allServers[self.updateHealthServerTry]; - - // If we have an active db instance - if(self.dbInstances.length > 0) { - var db = self.dbInstances[0]; - - // We have an instance already - if(self._haServer == null) { - // Create a new master connection - self._haServer = new Server(selectedServer.host, selectedServer.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - ssl: self.ssl, - sslValidate: self.sslValidate, - sslCA: self.sslCA, - sslCert: self.sslCert, - sslKey: self.sslKey, - sslPass: self.sslPass - }); - - self._haServer._callBackStore = self._callBackStore; - // Add close handler - self.on("close", function() { - self._haServer = null; - }); - - // Connect using the new _server connection to not impact the driver - // behavior on any errors we could possibly run into - self._haServer.connect(db, function(err, result, _server) { - if(err) { - if(_server.close) _server.close(); - return check(); - } - - executeMasterCommand(db, _server); - }); - } else { - executeMasterCommand(db, self._haServer); - } - } - } - - function executeMasterCommand(db, _server) { - try { - // Create is master command - var cmd = DbCommand.createIsMasterCommand(db); - // Execute is master command - db._executeQueryCommand(cmd, {failFast:true, connection: _server.checkoutReader()}, function(err, res) { - // If error let's set perform another check - if(err) return check(); - // Validate the replicaset - self._validateReplicaset(res, db.auths, function() { - check(); - }); - }); - } catch(err) { - self._haServer = null; - check(); - } - } - - function check() { - self._haTimer = setTimeout(ping, self.replicasetStatusCheckInterval); - } -} - -/** - * @ignore - */ -ReplSet.prototype._validateReplicaset = function(result, auths, cb) { - var self = this; - var res = result.documents[0]; - - // manage master node changes - if(res.primary && self._state.master && self._state.master.name != res.primary) { - // Delete master record so we can rediscover it - delete self._state.addresses[self._state.master.name]; - - // TODO existing issue? this seems to only work if - // we already have a connection to the new primary. - - // Update information on new primary - // add as master, remove from secondary - var newMaster = self._state.addresses[res.primary]; - newMaster.isMasterDoc.ismaster = true; - newMaster.isMasterDoc.secondary = false; - self._state.master = newMaster; - delete self._state.secondaries[res.primary]; - } - - // discover new hosts - var hosts = []; - - for(var i = 0; i < res.hosts.length; ++i) { - var host = res.hosts[i]; - if (host == res.me) continue; - if (!(self._state.addresses[host] || ~hosts.indexOf(host))) { - // we dont already have a connection to this host and aren't - // already planning on connecting. - hosts.push(host); - } - } - - connectTo(hosts, auths, self, cb); -} - -/** - * Create connections to all `hosts` firing `cb` after - * connections are attempted for all `hosts`. - * - * @param {Array} hosts - * @param {Array} [auths] - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectTo (hosts, auths, replset, cb) { - var pending = hosts.length; - if (!pending) return cb(); - - for(var i = 0; i < hosts.length; ++i) { - connectToHost(hosts[i], auths, replset, handle); - } - - function handle () { - --pending; - if (0 === pending) cb(); - } -} - -/** - * Attempts connection to `host` and authenticates with optional `auth` - * for the given `replset` firing `cb` when finished. - * - * @param {String} host - * @param {Array} auths - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectToHost (host, auths, replset, cb) { - var server = createServer(host, replset); - - var options = { - returnIsMasterResults: true, - eventReceiver: server - } - - server.connect(replset.db, options, function(err, result) { - var doc = result && result.documents && result.documents[0]; - - if (err || !doc) { - server.close(); - return cb(err, result, server); - } - - if(!(doc.ismaster || doc.secondary || doc.arbiterOnly)) { - server.close(); - return cb(null, result, server); - } - - // if host is an arbiter, disconnect if not configured for it - if(doc.arbiterOnly && !replset.connectArbiter) { - server.close(); - return cb(null, result, server); - } - - // create handler for successful connections - var handleConnect = _connectHandler(replset, null, server); - function complete () { - handleConnect(err, result); - cb(); - } - - // authenticate if necessary - if(!(Array.isArray(auths) && auths.length > 0)) { - return complete(); - } - - var pending = auths.length; - - var connections = server.allRawConnections(); - var pendingAuthConn = connections.length; - for(var x = 0; x 0) { - self.db.emit(event, err); - } - - // If it's the primary close all connections - if(self._state.master - && self._state.master.host == server.host - && self._state.master.port == server.port) { - // return self.close(); - self._state.master = null; - } - } -} - -var _connectHandler = function(self, candidateServers, instanceServer) { - return function(err, result) { - // If we have an ssl error store the error - if(err && err.ssl) { - self._sslError = err; - } - - // We are disconnected stop attempting reconnect or connect - if(self._serverState == 'disconnected') return instanceServer.close(); - - // If no error handle isMaster - if(err == null && result.documents[0].hosts != null) { - // Fetch the isMaster command result - var document = result.documents[0]; - // Break out the results - var setName = document.setName; - var isMaster = document.ismaster; - var secondary = document.secondary; - var passive = document.passive; - var arbiterOnly = document.arbiterOnly; - var hosts = Array.isArray(document.hosts) ? document.hosts : []; - var arbiters = Array.isArray(document.arbiters) ? document.arbiters : []; - var passives = Array.isArray(document.passives) ? document.passives : []; - var tags = document.tags ? document.tags : {}; - var primary = document.primary; - // Find the current server name and fallback if none - var userProvidedServerString = instanceServer.host + ":" + instanceServer.port; - var me = document.me || userProvidedServerString; - - // Verify if the set name is the same otherwise shut down and return an error - if(self.replicaSet == null) { - self.replicaSet = setName; - } else if(self.replicaSet != setName) { - // Stop the set - self.close(); - // Emit a connection error - return self.emit("connectionError", - new Error("configured mongodb replicaset does not match provided replicaset [" + setName + "] != [" + self.replicaSet + "]")) - } - - // Make sure we have the right reference - var oldServer = self._state.addresses[userProvidedServerString] - if (oldServer && oldServer !== instanceServer) oldServer.close(); - delete self._state.addresses[userProvidedServerString]; - - if (self._state.addresses[me] && self._state.addresses[me] !== instanceServer) { - self._state.addresses[me].close(); - } - - self._state.addresses[me] = instanceServer; - - // Let's add the server to our list of server types - if(secondary == true && (passive == false || passive == null)) { - self._state.secondaries[me] = instanceServer; - } else if(arbiterOnly == true) { - self._state.arbiters[me] = instanceServer; - } else if(secondary == true && passive == true) { - self._state.passives[me] = instanceServer; - } else if(isMaster == true) { - self._state.master = instanceServer; - } else if(isMaster == false && primary != null && self._state.addresses[primary]) { - self._state.master = self._state.addresses[primary]; - } - - // Set the name - instanceServer.name = me; - // Add tag info - instanceServer.tags = tags; - - // Add the handlers to the instance - instanceServer.on("close", _handler("close", self)); - instanceServer.on("error", _handler("error", self)); - instanceServer.on("timeout", _handler("timeout", self)); - - // Possible hosts - var possibleHosts = Array.isArray(hosts) ? hosts.slice() : []; - possibleHosts = Array.isArray(passives) ? possibleHosts.concat(passives) : possibleHosts; - - if(self.connectArbiter == true) { - possibleHosts = Array.isArray(arbiters) ? possibleHosts.concat(arbiters) : possibleHosts; - } - - if(Array.isArray(candidateServers)) { - // Add any new candidate servers for connection - for(var j = 0; j < possibleHosts.length; j++) { - if(self._state.addresses[possibleHosts[j]] == null && possibleHosts[j] != null) { - var parts = possibleHosts[j].split(/:/); - if(parts.length == 1) { - parts = [parts[0], Connection.DEFAULT_PORT]; - } - - // New candidate server - var candidateServer = new Server(parts[0], parseInt(parts[1])); - candidateServer._callBackStore = self._callBackStore; - candidateServer.name = possibleHosts[j]; - candidateServer.ssl = self.ssl; - candidateServer.sslValidate = self.sslValidate; - candidateServer.sslCA = self.sslCA; - candidateServer.sslCert = self.sslCert; - candidateServer.sslKey = self.sslKey; - candidateServer.sslPass = self.sslPass; - - // Set the candidate server - self._state.addresses[possibleHosts[j]] = candidateServer; - // Add the new server to the list of candidate servers - candidateServers.push(candidateServer); - } - } - } - } else if(err != null || self._serverState == 'disconnected'){ - delete self._state.addresses[instanceServer.host + ":" + instanceServer.port]; - // Remove it from the set - instanceServer.close(); - } - - // Attempt to connect to the next server - if(Array.isArray(candidateServers) && candidateServers.length > 0) { - var server = candidateServers.pop(); - - // Get server addresses - var addresses = self._state.addresses; - - // Default empty socket options object - var socketOptions = {}; - - // Set fast connect timeout - socketOptions['connectTimeoutMS'] = self._connectTimeoutMS; - - // If a socket option object exists clone it - if(self.socketOptions != null && typeof self.socketOptions === 'object') { - var keys = Object.keys(self.socketOptions); - for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = self.socketOptions[keys[j]]; - } - - // If ssl is specified - if(self.ssl) server.ssl = true; - - // Add host information to socket options - socketOptions['host'] = server.host; - socketOptions['port'] = server.port; - server.socketOptions = socketOptions; - server.replicasetInstance = self; - server.enableRecordQueryStats(self.recordQueryStats); - - // Set the server - if (addresses[server.host + ":" + server.port] != server) { - if (addresses[server.host + ":" + server.port]) { - // Close the connection before deleting - addresses[server.host + ":" + server.port].close(); - } - delete addresses[server.host + ":" + server.port]; - } - addresses[server.host + ":" + server.port] = server; - // Connect - server.connect(self.db, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(self, candidateServers, server)); - } else if(Array.isArray(candidateServers)) { - // If we have no primary emit error - if(self._state.master == null) { - // Stop the set - self.close(); - - // If we have an ssl error send the message instead of no primary found - if(self._sslError) { - return self.emit("connectionError", self._sslError); - } - - // Emit a connection error - return self.emit("connectionError", - new Error("no primary server found in set")) - } else{ - if (self.strategyInstance) { - self.strategyInstance.start(); - } - - for(var i = 0; i < self.dbInstances.length; i++) self.dbInstances[i]._state = 'connected'; - self.emit("fullsetup", null, self.db, self); - self.emit("open", null, self.db, self); - } - } - } -} - -/** - * Interval state object constructor - * - * @ignore - */ -ReplSet.State = function ReplSetState () { - this.errorMessages = []; - this.secondaries = {}; - this.addresses = {}; - this.arbiters = {}; - this.passives = {}; - this.members = []; - this.errors = {}; - this.setName = null; - this.master = null; -} - -/** - * @ignore - */ -ReplSet.prototype.connect = function(parent, options, callback) { - var self = this; - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Ensure it's all closed - self.close(); - - // Set connecting status - this.db = parent; - this._serverState = 'connecting'; - this._callbackList = []; - - this._state = new ReplSet.State(); - - // Ensure parent can do a slave query if it's set - parent.slaveOk = this.slaveOk - ? this.slaveOk - : parent.slaveOk; - - // Remove any listeners - this.removeAllListeners("fullsetup"); - this.removeAllListeners("connectionError"); - - // Add primary found event handler - this.once("fullsetup", function() { - self._handleOnFullSetup(parent); - - // Callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(null, parent, self); - } - }); - - this.once("connectionError", function(err) { - self._serverState = 'disconnected'; - // Ensure it's all closed - self.close(); - // Perform the callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(err, parent, self); - } - }); - - // Get server addresses - var addresses = this._state.addresses; - - // De-duplicate any servers - var server, key; - for(var i = 0; i < this.servers.length; i++) { - server = this.servers[i]; - key = server.host + ":" + server.port; - if(null == addresses[key]) { - addresses[key] = server; - } - } - - // Get the list of servers that is deduplicated and start connecting - var candidateServers = []; - var keys = Object.keys(addresses); - for(var i = 0; i < keys.length; i++) { - server = addresses[keys[i]]; - server.assignReplicaSet(this); - candidateServers.push(server); - } - - // Let's connect to the first one on the list - server = candidateServers.pop(); - var opts = { - returnIsMasterResults: true, - eventReceiver: server - } - server.connect(parent, opts, _connectHandler(this, candidateServers, server)); -} - -/** - * Handles the first `fullsetup` event of this ReplSet. - * - * @param {Db} parent - * @ignore - */ -ReplSet.prototype._handleOnFullSetup = function (parent) { - this._serverState = 'connected'; - for(var i = 0; i < this.dbInstances.length; i++) this.dbInstances[i]._state = 'connected'; - if(parent._state) parent._state = 'connected'; - // Emit the fullsetup and open event - parent.emit("open", null, this.db, this); - parent.emit("fullsetup", null, this.db, this); - - if(!this.haEnabled) return; - this._enableHA(); -} - -/** - * Disables high availability pings. - * - * @ignore - */ -ReplSet.prototype._disableHA = function () { - clearTimeout(this._haTimer); - this._haTimer = undefined; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutWriter = function() { - // Establish connection - var connection = this._state.master != null ? this._state.master.checkoutWriter() : null; - // Return the connection - return connection; -} - -/** - * @ignore - */ -var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) { - var keys = Object.keys(self._state.secondaries); - var connection; - - // Find first available reader if any - for(var i = 0; i < keys.length; i++) { - connection = self._state.secondaries[keys[i]].checkoutReader(); - if(connection) return connection; - } - - // If we still have a null, read from primary if it's not secondary only - if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) { - connection = self._state.master.checkoutReader(); - if(connection) return connection; - } - - var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED - ? 'secondary' - : self._readPreference; - - return new Error("No replica set member available for query with ReadPreference " - + preferenceName + " and tags " + JSON.stringify(tags)); -} - -/** - * @ignore - */ -var _pickFromTags = function(self, tags) { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Match all the servers that match the provdided tags - var keys = Object.keys(self._state.secondaries); - var candidateServers = []; - - for(var i = 0; i < keys.length; i++) { - var server = self._state.secondaries[keys[i]]; - // If we have tags match - if(server.tags != null) { - var matching = true; - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - candidateServers.push(server); - } - } - } - - // If we have a candidate server return - if(candidateServers.length > 0) { - if(this.strategyInstance) return this.strategyInstance.checkoutSecondary(tags, candidateServers); - // Set instance to return - return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader(); - } - } - - // No connection found - return null; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutReader = function(readPreference, tags) { - var connection = null; - - // If we have a read preference object unpack it - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + readPreference.mode); - // Set the tag - tags = readPreference.tags; - readPreference = readPreference.mode; - } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("read preferences must be either a string or an instance of ReadPreference"); - } - - // Set up our read Preference, allowing us to override the readPreference - var finalReadPreference = readPreference != null ? readPreference : this._readPreference; - finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference; - finalReadPreference = finalReadPreference == null ? ReadPreference.PRIMARY : finalReadPreference; - - // If we are reading from a primary - if(finalReadPreference == 'primary') { - // If we provide a tags set send an error - if(typeof tags == 'object' && tags != null) { - return new Error("PRIMARY cannot be combined with tags"); - } - - // If we provide a tags set send an error - if(this._state.master == null) { - return new Error("No replica set primary available for query with ReadPreference PRIMARY"); - } - - // Checkout a writer - return this.checkoutWriter(); - } - - // If we have specified to read from a secondary server grab a random one and read - // from it, otherwise just pass the primary connection - if((this.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) { - // Check if there is a primary available and return that if possible - connection = this.checkoutWriter(); - // If no connection available checkout a secondary - if(connection == null) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } - } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED && tags == null && Object.keys(this._state.secondaries).length == 0) { - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } - } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } - } else if(this.strategyInstance != null) { - connection = this.strategyInstance.checkoutReader(tags); - } - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) { - connection = this.strategyInstance.checkoutSecondary(tags); - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) { - return new Error("A strategy for calculating nearness must be enabled such as ping or statistical"); - } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) { - if(tags != null && typeof tags == 'object') { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } else { - connection = new Error("No replica set secondary available for query with ReadPreference SECONDARY"); - } - } else { - connection = this.checkoutWriter(); - } - - // Return the connection - return connection; -} - -/** - * Pick a secondary using round robin - * - * @ignore - */ -function _roundRobin (replset, tags) { - var keys = Object.keys(replset._state.secondaries); - var key = keys[replset._currentServerChoice++ % keys.length]; - - var conn = null != replset._state.secondaries[key] - ? replset._state.secondaries[key].checkoutReader() - : null; - - // If connection is null fallback to first available secondary - if (null == conn) { - conn = pickFirstConnectedSecondary(replset, tags); - } - - return conn; -} - -/** - * @ignore - */ -ReplSet.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - if(this._state.master == null) return []; - // Get connection object - var allMasterConnections = this._state.master.connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(allMasterConnections); - // If we have read secondary let's add all secondary servers - if(Object.keys(this._state.secondaries).length > 0) { - // Get all the keys - var keys = Object.keys(this._state.secondaries); - // For each of the secondaries grab the connections - for(var i = 0; i < keys.length; i++) { - // Get connection object - var secondaryPoolConnections = this._state.secondaries[keys[i]].connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(secondaryPoolConnections); - } - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -ReplSet.prototype.enableRecordQueryStats = function(enable) { - // Set the global enable record query stats - this.recordQueryStats = enable; - // Ensure all existing servers already have the flag set, even if the - // connections are up already or we have not connected yet - if(this._state != null && this._state.addresses != null) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances and set the enableRecordQueryStats flag - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].enableRecordQueryStats(enable); - } - } else if(Array.isArray(this.servers)) { - for(var i = 0; i < this.servers.length; i++) { - this.servers[i].enableRecordQueryStats(enable); - } - } -} - -/** - * @ignore - */ -ReplSet.prototype.disconnect = function(callback) { - this.close(callback); -} - -/** - * @ignore - */ -ReplSet.prototype.close = function(callback) { - var self = this; - // Disconnect - this._serverState = 'disconnected'; - // Close all servers - if(this._state && this._state.addresses) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].close(); - } - } - - // If we have a strategy stop it - if(this.strategyInstance) this.strategyInstance.stop(); - - // If it's a callback - if(typeof callback == 'function') callback(null, null); -} - -/** - * Auto Reconnect property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "autoReconnect", { enumerable: true - , get: function () { - return true; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return ReadPreference.SECONDARY_PREFERRED; - } else if(this._readPreference == null && !this.readSecondary) { - return ReadPreference.PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * Db Instances - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "dbInstances", {enumerable:true - , get: function() { - var servers = this.allServerInstances(); - return servers.length > 0 ? servers[0].dbInstances : []; - } -}) - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "host", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.host; - } -}); - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "port", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.port; - } -}); - -/** - * Get status of read - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "read", { enumerable: true - , get: function () { - return this.secondaries.length > 0 ? this.secondaries[0] : null; - } -}); - -/** - * Get list of secondaries - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.secondaries); - var array = new Array(keys.length); - // Convert secondaries to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.secondaries[keys[i]]; - } - return array; - } -}); - -/** - * Get list of all secondaries including passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "allSecondaries", {enumerable: true - , get: function() { - return this.secondaries.concat(this.passives); - } -}); - -/** - * Get list of arbiters - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.arbiters); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.arbiters[keys[i]]; - } - return array; - } -}); - -/** - * Get list of passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "passives", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.passives); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.passives[keys[i]]; - } - return array; - } -}); - -/** - * Master connection property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "primary", { enumerable: true - , get: function () { - return this._state != null ? this._state.master : null; - } -}); - -/** - * @ignore - */ -// Backward compatibility -exports.ReplSetServers = ReplSet; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js deleted file mode 100644 index c4ae952cbb2..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js +++ /dev/null @@ -1,900 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - ConnectionPool = require('./connection_pool').ConnectionPool, - EventEmitter = require('events').EventEmitter, - Base = require('./base').Base, - utils = require('../utils'), - inherits = require('util').inherits; - -/** - * Class representing a single MongoDB Server connection - * - * Options - * - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST) - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - **slaveOk** {Boolean, default:false}, legacy option allowing reads from secondary, use **readPrefrence** instead. - * - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **auto_reconnect** {Boolean, default:false}, reconnect on error. - * - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big - * - * @class Represents a Server connection. - * @param {String} host the server host - * @param {Number} port the server port - * @param {Object} [options] optional options for insert command - */ -function Server(host, port, options) { - // Set up Server instance - if(!(this instanceof Server)) return new Server(host, port, options); - - // Set up event emitter - Base.call(this); - - // Ensure correct values - if(port != null && typeof port == 'object') { - options = port; - port = Connection.DEFAULT_PORT; - } - - var self = this; - this.host = host; - this.port = port; - this.options = options == null ? {} : options; - this.internalConnection; - this.internalMaster = false; - this.connected = false; - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false; - this.slaveOk = this.options["slave_ok"] ? this.options["slave_ok"] : this.options["slaveOk"]; - this._used = false; - this.replicasetInstance = null; - - // Set ssl as connection method - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Get the readPreference - var readPreference = this.options['readPreference']; - // If readPreference is an object get the mode string - var validateReadPreference = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - // Read preference setting - if(validateReadPreference != null) { - if(validateReadPreference != ReadPreference.PRIMARY && validateReadPreference != ReadPreference.SECONDARY && validateReadPreference != ReadPreference.NEAREST - && validateReadPreference != ReadPreference.SECONDARY_PREFERRED && validateReadPreference != ReadPreference.PRIMARY_PREFERRED) { - throw new Error("Illegal readPreference mode specified, " + validateReadPreference); - } - - // Set read Preference - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Contains the isMaster information returned from the server - this.isMasterDoc; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck; - - // Set ssl up if it's defined - if(this.ssl) { - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // this._timeout = false; - // Contains state information about server connection - this._state = {'runtimeStats': {'queryStats':new RunningStats()}}; - // Do we record server stats or not - this.recordQueryStats = false; -}; - -/** - * @ignore - */ -inherits(Server, Base); - -// -// Deprecated, USE ReadPreferences class -// -Server.READ_PRIMARY = ReadPreference.PRIMARY; -Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED; -Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY; - -/** - * Always ourselves - * @ignore - */ -Server.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Server.prototype.isMongos = function() { - return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false; -} - -/** - * @ignore - */ -Server.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -Server.prototype.close = function(callback) { - // Remove all local listeners - this.removeAllListeners(); - - if(this.connectionPool != null) { - // Remove all the listeners on the pool so it does not fire messages all over the place - this.connectionPool.removeAllEventListeners(); - // Close the connection if it's open - this.connectionPool.stop(true); - } - - // Set server status as disconnected - this._serverState = 'disconnected'; - // Peform callback if present - if(typeof callback === 'function') callback(null); -}; - -/** - * @ignore - */ -Server.prototype.isConnected = function() { - return this._serverState == 'connected'; -} - -/** - * @ignore - */ -Server.prototype.allServerInstances = function() { - return [this]; -} - -/** - * @ignore - */ -Server.prototype.isSetMember = function() { - return this.replicasetInstance != null || this.mongosInstance != null; -} - -/** - * Assigns a replica set to this `server`. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.assignReplicaSet = function (replset) { - this.replicasetInstance = replset; - this.inheritReplSetOptionsFrom(replset); - this.enableRecordQueryStats(replset.recordQueryStats); -} - -/** - * Takes needed options from `replset` and overwrites - * our own options. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.inheritReplSetOptionsFrom = function (replset) { - this.socketOptions = {}; - this.socketOptions.connectTimeoutMS = replset._connectTimeoutMS; - - if(replset.ssl) { - // Set ssl on - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = replset.sslValidate == null ? false : replset.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(replset.sslCA) ? replset.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = replset.sslCert; - // Set certificate to present - this.socketOptions.sslKey = replset.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = replset.sslPass; - } - - // If a socket option object exists clone it - if(utils.isObject(replset.socketOptions)) { - var keys = Object.keys(replset.socketOptions); - for(var i = 0; i < keys.length; i++) - this.socketOptions[keys[i]] = replset.socketOptions[keys[i]]; - } -} - -/** - * Opens this server connection. - * - * @ignore - */ -Server.prototype.connect = function(dbInstance, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Currently needed to work around problems with multiple connections in a pool with ssl - // TODO fix if possible - if(this.ssl == true) { - // Set up socket options for ssl - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Let's connect - var server = this; - // Let's us override the main receiver of events - var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this; - // Save reference to dbInstance - this.db = dbInstance; // `db` property matches ReplSet and Mongos - this.dbInstances = [dbInstance]; - - // Force connection pool if there is one - if(server.connectionPool) server.connectionPool.stop(); - - // Set server state to connecting - this._serverState = 'connecting'; - // Ensure dbInstance can do a slave query if it's set - dbInstance.slaveOk = this.slaveOk ? this.slaveOk : dbInstance.slaveOk; - // Create connection Pool instance with the current BSON serializer - var connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions); - // If ssl is not enabled don't wait between the pool connections - if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null; - // Set logger on pool - connectionPool.logger = this.logger; - - // Set up a new pool using default settings - server.connectionPool = connectionPool; - - // Set basic parameters passed in - var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults; - - // Create a default connect handler, overriden when using replicasets - var connectCallback = function(err, reply) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // If something close down the connection and removed the callback before - // proxy killed connection etc, ignore the erorr as close event was isssued - if(err != null && internalCallback == null) return; - // Internal callback - if(err != null) return internalCallback(err, null, server); - server.master = reply.documents[0].ismaster == 1 ? true : false; - server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize); - // Set server as connected - server.connected = true; - // Save document returned so we can query it - server.isMasterDoc = reply.documents[0]; - - // Emit open event - _emitAcrossAllDbInstances(server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null); - - // If we have it set to returnIsMasterResults - if(returnIsMasterResults) { - internalCallback(null, reply, server); - } else { - internalCallback(null, dbInstance, server); - } - }; - - // Let's us override the main connect callback - var connectHandler = options.connectHandler == null ? connectCallback : options.connectHandler; - - // Set up on connect method - connectionPool.on("poolReady", function() { - // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks) - var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName); - // Check out a reader from the pool - var connection = connectionPool.checkoutConnection(); - // Set server state to connEcted - server._serverState = 'connected'; - - // Register handler for messages - server._registerHandler(db_command, false, connection, connectHandler); - - // Write the command out - connection.write(db_command); - }) - - // Set up item connection - connectionPool.on("message", function(message) { - // Attempt to parse the message - try { - // Create a new mongo reply - var mongoReply = new MongoReply() - // Parse the header - mongoReply.parseHeader(message, connectionPool.bson) - - // If message size is not the same as the buffer size - // something went terribly wrong somewhere - if(mongoReply.messageLength != message.length) { - // Emit the error - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server); - // Remove all listeners - server.removeAllListeners(); - } else { - var startDate = new Date().getTime(); - - // Callback instance - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - - // The command executed another request, log the handler again under that request id - if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0" - && callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) { - server._reRegisterHandler(mongoReply.requestId, callbackInfo); - } - - // Only execute callback if we have a caller - // chained is for findAndModify as it does not respect write concerns - if(callbackInfo && callbackInfo.callback && callbackInfo.info && Array.isArray(callbackInfo.info.chained)) { - // Check if callback has already been fired (missing chain command) - var chained = callbackInfo.info.chained; - var numberOfFoundCallbacks = 0; - for(var i = 0; i < chained.length; i++) { - if(server._hasHandler(chained[i])) numberOfFoundCallbacks++; - } - - // If we have already fired then clean up rest of chain and move on - if(numberOfFoundCallbacks != chained.length) { - for(var i = 0; i < chained.length; i++) { - server._removeHandler(chained[i]); - } - - // Just return from function - return; - } - - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Fetch the callback - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - // If we have an error let's execute the callback and clean up all other - // chained commands - var firstResult = mongoReply && mongoReply.documents; - - // Check for an error, if we have one let's trigger the callback and clean up - // The chained callbacks - if(firstResult[0].err != null || firstResult[0].errmsg != null) { - // Trigger the callback for the error - server._callHandler(mongoReply.responseTo, mongoReply, null); - } else { - var chainedIds = callbackInfo.info.chained; - - if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) { - // Cleanup all other chained calls - chainedIds.pop(); - // Remove listeners - for(var i = 0; i < chainedIds.length; i++) server._removeHandler(chainedIds[i]); - // Call the handler - server._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null); - } else{ - // Add the results to all the results - for(var i = 0; i < chainedIds.length; i++) { - var handler = server._findHandler(chainedIds[i]); - // Check if we have an object, if it's the case take the current object commands and - // and add this one - if(handler.info != null) { - handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : []; - handler.info.results.push(mongoReply); - } - } - } - } - }); - } else if(callbackInfo && callbackInfo.callback && callbackInfo.info) { - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Let's record the stats info if it's enabled - if(server.recordQueryStats == true && server._state['runtimeStats'] != null - && server._state.runtimeStats['queryStats'] instanceof RunningStats) { - // Add data point to the running statistics object - server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start); - } - - server._callHandler(mongoReply.responseTo, mongoReply, null); - }); - } - } - } catch (err) { - // Throw error in next tick - process.nextTick(function() { - throw err; - }) - } - }); - - // Handle timeout - connectionPool.on("timeout", function(err) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(err, null, server); - } else if(server.isSetMember()) { - if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server); - } else { - if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(err); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true); - } - }); - - // Handle errors - connectionPool.on("error", function(message, connection, error_options) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Error message - var error_message = new Error(message && message.err ? message.err : message); - // Error message coming from ssl - if(error_options && error_options.ssl) error_message.ssl = true; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(error_message, null, server); - } else if(server.isSetMember()) { - if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server); - } else { - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(error_message); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true); - } - }); - - // Handle close events - connectionPool.on("close", function() { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback == 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server); - } else { - if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true); - } - }); - - // If we have a parser error we are in an unknown state, close everything and emit - // error - connectionPool.on("parseError", function(message) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - }); - - // Boot up connection poole, pass in a locator of callbacks - connectionPool.start(); -} - -/** - * @ignore - */ -var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) { - // Emit close event across all db instances sharing the sockets - var allServerInstances = server.allServerInstances(); - // Fetch the first server instance - var serverInstance = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(serverInstance.dbInstances) && serverInstance.dbInstances.length >= 1) { - for(var i = 0; i < serverInstance.dbInstances.length; i++) { - var dbInstance = serverInstance.dbInstances[i]; - // Set the parent - if(resetConnection && typeof dbInstance.openCalled != 'undefined') - dbInstance.openCalled = false; - // Check if it's our current db instance and skip if it is - if(filterDb == null || filterDb.databaseName !== dbInstance.databaseName || filterDb.tag !== dbInstance.tag) { - // Only emit if there is a listener - if(dbInstance.listeners(event).length > 0) - dbInstance.emit(event, message, object); - } - } - } -} - -/** - * @ignore - */ -Server.prototype.allRawConnections = function() { - return this.connectionPool.getAllConnections(); -} - -/** - * Check if a writer can be provided - * @ignore - */ -var canCheckoutWriter = function(self, read) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } if(self.isMasterDoc['secondary'] == true) { - return new Error("Cannot write to a secondary"); - } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutWriter = function(read) { - if(read == true) return this.connectionPool.checkoutConnection(); - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutWriter(this, read); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * Check if a reader can be provided - * @ignore - */ -var canCheckoutReader = function(self) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } else if(self._readPreference != null) { - // If the read preference is Primary and the instance is not a master return an error - if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) { - return new Error("Read preference is Server.PRIMARY and server is not master"); - } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutReader = function() { - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutReader(this); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * @ignore - */ -Server.prototype.enableRecordQueryStats = function(enable) { - this.recordQueryStats = enable; -} - -/** - * Internal statistics object used for calculating average and standard devitation on - * running queries - * @ignore - */ -var RunningStats = function() { - var self = this; - this.m_n = 0; - this.m_oldM = 0.0; - this.m_oldS = 0.0; - this.m_newM = 0.0; - this.m_newS = 0.0; - - // Define getters - Object.defineProperty(this, "numDataValues", { enumerable: true - , get: function () { return this.m_n; } - }); - - Object.defineProperty(this, "mean", { enumerable: true - , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; } - }); - - Object.defineProperty(this, "variance", { enumerable: true - , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); } - }); - - Object.defineProperty(this, "standardDeviation", { enumerable: true - , get: function () { return Math.sqrt(this.variance); } - }); - - Object.defineProperty(this, "sScore", { enumerable: true - , get: function () { - var bottom = this.mean + this.standardDeviation; - if(bottom == 0) return 0; - return ((2 * this.mean * this.standardDeviation)/(bottom)); - } - }); -} - -/** - * @ignore - */ -RunningStats.prototype.push = function(x) { - // Update the number of samples - this.m_n = this.m_n + 1; - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if(this.m_n == 1) { - this.m_oldM = this.m_newM = x; - this.m_oldS = 0.0; - } else { - this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n; - this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM); - - // set up for next iteration - this.m_oldM = this.m_newM; - this.m_oldS = this.m_newS; - } -} - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true - , get: function () { - return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect']; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "connection", { enumerable: true - , get: function () { - return this.internalConnection; - } - , set: function(connection) { - this.internalConnection = connection; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "master", { enumerable: true - , get: function () { - return this.internalMaster; - } - , set: function(value) { - this.internalMaster = value; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "primary", { enumerable: true - , get: function () { - return this; - } -}); - -/** - * Getter for query Stats - * @ignore - */ -Object.defineProperty(Server.prototype, "queryStats", { enumerable: true - , get: function () { - return this._state.runtimeStats.queryStats; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true - , get: function () { - return this._state.runtimeStats; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(Server.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return Server.READ_SECONDARY; - } else if(this._readPreference == null && !this.readSecondary) { - return Server.READ_PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * @ignore - */ -exports.Server = Server; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js deleted file mode 100644 index 0d7817f0ceb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js +++ /dev/null @@ -1,252 +0,0 @@ -var Server = require("../server").Server; - -// The ping strategy uses pings each server and records the -// elapsed time for the server so it can pick a server based on lowest -// return time for the db command {ping:true} -var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) { - this.replicaset = replicaset; - this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS; - this.state = 'disconnected'; - this.pingInterval = 5000; - // Class instance - this.Db = require("../../db").Db; - // Active db connections - this.dbs = {}; -} - -// Starts any needed code -PingStrategy.prototype.start = function(callback) { - // already running? - if ('connected' == this.state) return; - - this.state = 'connected'; - - // Start ping server - this._pingServer(callback); -} - -// Stops and kills any processes running -PingStrategy.prototype.stop = function(callback) { - // Stop the ping process - this.state = 'disconnected'; - - // optional callback - callback && callback(null, null); -} - -PingStrategy.prototype.checkoutSecondary = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // Sort by ping time - finalCandidates.sort(function(a, b) { - return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs']; - }); - - if(0 === finalCandidates.length) - return new Error("No replica set members available for query"); - - // handle undefined pingMs - var lowestPing = finalCandidates[0].runtimeStats['pingMs'] | 0; - - // determine acceptable latency - var acceptable = lowestPing + this.secondaryAcceptableLatencyMS; - - // remove any server responding slower than acceptable - var len = finalCandidates.length; - while(len--) { - if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) { - finalCandidates.splice(len, 1); - } - } - - // If no candidates available return an error - if(finalCandidates.length == 0) - return new Error("No replica set members available for query"); - - // Pick a random acceptable server - return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); -} - -PingStrategy.prototype._pingServer = function(callback) { - var self = this; - - // Ping server function - var pingFunction = function() { - if(self.state == 'disconnected') return; - - // Create a list of all servers we can send the ismaster command to - var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : []; - - // Secondary keys - var keys = Object.keys(self.replicaset._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self.replicaset._state.secondaries[keys[i]]); - } - - // Number of server entries - var numberOfEntries = allServers.length; - - // We got keys - for(var i = 0; i < allServers.length; i++) { - - // We got a server instance - var server = allServers[i]; - - // Create a new server object, avoid using internal connections as they might - // be in an illegal state - new function(serverInstance) { - var _db = self.dbs[serverInstance.host + ":" + serverInstance.port]; - // If we have a db - if(_db != null) { - // Startup time of the command - var startTime = Date.now(); - - // Execute ping command in own scope - var _ping = function(__db, __serverInstance) { - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }; - // Ping - _ping(_db, serverInstance); - } else { - // Create a new master connection - var _server = new Server(serverInstance.host, serverInstance.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self.replicaset._connectTimeoutMS }, - ssl: self.replicaset.ssl, - sslValidate: self.replicaset.sslValidate, - sslCA: self.replicaset.sslCA, - sslCert: self.replicaset.sslCert, - sslKey: self.replicaset.sslKey, - sslPass: self.replicaset.sslPass - }); - - // Create Db instance - var _db = new self.Db(self.replicaset.db.databaseName, _server, { safe: true }); - _db.on("close", function() { - delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port]; - }) - - var _ping = function(__db, __serverInstance) { - __db.open(function(err, db) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - // Save instance - self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db; - - // Startup time of the command - var startTime = Date.now(); - - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }); - }; - - _ping(_db, serverInstance); - } - - function done() { - // Adjust the number of checks - numberOfEntries--; - - // If we are done with all results coming back trigger ping again - if(0 === numberOfEntries && 'connected' == self.state) { - setTimeout(pingFunction, self.pingInterval); - } - } - }(server); - } - } - - // Start pingFunction - // setTimeout(pingFunction, 1000); - pingFunction(); - - callback && callback(null); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js deleted file mode 100644 index 2e87dbd66d0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js +++ /dev/null @@ -1,78 +0,0 @@ -// The Statistics strategy uses the measure of each end-start time for each -// query executed against the db to calculate the mean, variance and standard deviation -// and pick the server which the lowest mean and deviation -var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) { - this.replicaset = replicaset; -} - -// Starts any needed code -StatisticsStrategy.prototype.start = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.stop = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.checkoutSecondary = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // If no candidates available return an error - if(finalCandidates.length == 0) return new Error("No replica set members available for query"); - // Pick a random server - return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js deleted file mode 100644 index d31e8a0b62f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js +++ /dev/null @@ -1,223 +0,0 @@ -var fs = require('fs'), - ReadPreference = require('./read_preference').ReadPreference; - -exports.parse = function(url, options) { - // Ensure we have a default options object if none set - options = options || {}; - // Variables - var connection_part = ''; - var auth_part = ''; - var query_string_part = ''; - var dbName = 'admin'; - - // Must start with mongodb - if(url.indexOf("mongodb://") != 0) - throw Error("URL must be in the format mongodb://user:pass@host:port/dbname"); - // If we have a ? mark cut the query elements off - if(url.indexOf("?") != -1) { - query_string_part = url.substr(url.indexOf("?") + 1); - connection_part = url.substring("mongodb://".length, url.indexOf("?")) - } else { - connection_part = url.substring("mongodb://".length); - } - - // Check if we have auth params - if(connection_part.indexOf("@") != -1) { - auth_part = connection_part.split("@")[0]; - connection_part = connection_part.split("@")[1]; - } - - // Check if the connection string has a db - if(connection_part.indexOf(".sock") != -1) { - if(connection_part.indexOf(".sock/") != -1) { - dbName = connection_part.split(".sock/")[1]; - connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length); - } - } else if(connection_part.indexOf("/") != -1) { - dbName = connection_part.split("/")[1]; - connection_part = connection_part.split("/")[0]; - } - - // Result object - var object = {}; - - // Pick apart the authentication part of the string - var authPart = auth_part || ''; - var auth = authPart.split(':', 2); - if(options['uri_decode_auth']){ - auth[0] = decodeURIComponent(auth[0]); - if(auth[1]){ - auth[1] = decodeURIComponent(auth[1]); - } - } - - // Add auth to final object if we have 2 elements - if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]}; - - // Variables used for temporary storage - var hostPart; - var urlOptions; - var servers; - var serverOptions = {socketOptions: {}}; - var dbOptions = {read_preference_tags: []}; - var replSetServersOptions = {socketOptions: {}}; - // Add server options to final object - object.server_options = serverOptions; - object.db_options = dbOptions; - object.rs_options = replSetServersOptions; - object.mongos_options = {}; - - // Let's check if we are using a domain socket - if(url.match(/\.sock/)) { - // Split out the socket part - var domainSocket = url.substring( - url.indexOf("mongodb://") + "mongodb://".length - , url.lastIndexOf(".sock") + ".sock".length); - // Clean out any auth stuff if any - if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1]; - servers = [{domain_socket: domainSocket}]; - } else { - // Split up the db - hostPart = connection_part; - // Parse all server results - servers = hostPart.split(',').map(function(h) { - var hostPort = h.split(':', 2); - var _host = hostPort[0] || 'localhost'; - var _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017; - // Check for localhost?safe=true style case - if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0]; - - // Return the mapped object - return {host: _host, port: _port}; - }); - } - - // Get the db name - object.dbName = dbName || 'admin'; - // Split up all the options - urlOptions = (query_string_part || '').split(/[&;]/); - // Ugh, we have to figure out which options go to which constructor manually. - urlOptions.forEach(function(opt) { - if(!opt) return; - var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1]; - // Options implementations - switch(name) { - case 'slaveOk': - case 'slave_ok': - serverOptions.slave_ok = (value == 'true'); - break; - case 'maxPoolSize': - case 'poolSize': - serverOptions.poolSize = parseInt(value, 10); - replSetServersOptions.poolSize = parseInt(value, 10); - break; - case 'autoReconnect': - case 'auto_reconnect': - serverOptions.auto_reconnect = (value == 'true'); - break; - case 'minPoolSize': - throw new Error("minPoolSize not supported"); - case 'maxIdleTimeMS': - throw new Error("maxIdleTimeMS not supported"); - case 'waitQueueMultiple': - throw new Error("waitQueueMultiple not supported"); - case 'waitQueueTimeoutMS': - throw new Error("waitQueueTimeoutMS not supported"); - case 'uuidRepresentation': - throw new Error("uuidRepresentation not supported"); - case 'ssl': - if(value == 'prefer') { - serverOptions.ssl = value; - replSetServersOptions.ssl = value; - break; - } - serverOptions.ssl = (value == 'true'); - replSetServersOptions.ssl = (value == 'true'); - break; - case 'replicaSet': - case 'rs_name': - replSetServersOptions.rs_name = value; - break; - case 'reconnectWait': - replSetServersOptions.reconnectWait = parseInt(value, 10); - break; - case 'retries': - replSetServersOptions.retries = parseInt(value, 10); - break; - case 'readSecondary': - case 'read_secondary': - replSetServersOptions.read_secondary = (value == 'true'); - break; - case 'fsync': - dbOptions.fsync = (value == 'true'); - break; - case 'journal': - dbOptions.journal = (value == 'true'); - break; - case 'safe': - dbOptions.safe = (value == 'true'); - break; - case 'nativeParser': - case 'native_parser': - dbOptions.native_parser = (value == 'true'); - break; - case 'connectTimeoutMS': - serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - break; - case 'socketTimeoutMS': - serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - break; - case 'w': - dbOptions.w = parseInt(value, 10); - break; - case 'wtimeoutMS': - dbOptions.wtimeoutMS = parseInt(value, 10); - break; - case 'readPreference': - if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest"); - dbOptions.read_preference = value; - break; - case 'readPreferenceTags': - // Contains the tag object - var tagObject = {}; - if(value == null || value == '') { - dbOptions.read_preference_tags.push(tagObject); - break; - } - - // Split up the tags - var tags = value.split(/\,/); - for(var i = 0; i < tags.length; i++) { - var parts = tags[i].trim().split(/\:/); - tagObject[parts[0]] = parts[1]; - } - - // Set the preferences tags - dbOptions.read_preference_tags.push(tagObject); - break; - default: - break; - } - }); - - // No tags: should be null (not []) - if(dbOptions.read_preference_tags.length === 0) { - dbOptions.read_preference_tags = null; - } - - // Validate if there are an invalid write concern combinations - if((dbOptions.w == -1 || dbOptions.w == 0) && ( - dbOptions.journal == true - || dbOptions.fsync == true - || dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync") - - // If no read preference set it to primary - if(!dbOptions.read_preference) dbOptions.read_preference = 'primary'; - - // Add servers to result - object.servers = servers; - // Returned parsed object - return object; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js deleted file mode 100644 index 5bf462c45eb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js +++ /dev/null @@ -1,996 +0,0 @@ -var QueryCommand = require('./commands/query_command').QueryCommand, - GetMoreCommand = require('./commands/get_more_command').GetMoreCommand, - KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand, - Long = require('bson').Long, - ReadPreference = require('./connection/read_preference').ReadPreference, - CursorStream = require('./cursorstream'), - utils = require('./utils'); - -/** - * Constructor for a cursor object that handles all the operations on query result - * using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly, - * but use find to acquire a cursor. - * - * Options - * - **skip** {Number} skip number of documents to skip. - * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **hint** {Object}, hint force the query to use a specific index. - * - **explain** {Boolean}, explain return the explaination of the query. - * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned. - * - **timeout** {Boolean}, timeout allow the query to timeout. - * - **tailable** {Boolean}, tailable allow the cursor to be tailable. - * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor. - * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database. - * - **raw** {Boolean}, raw return all query documents as raw buffers (default false). - * - **read** {Boolean}, read specify override of read from source (primary/secondary). - * - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries. - * - **returnKey** {Boolean}, returnKey only return the index key. - * - **maxScan** {Number}, maxScan limit the number of items to scan. - * - **min** {Number}, min set index bounds. - * - **max** {Number}, max set index bounds. - * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results. - * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler. - * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout. - * - **dbName** {String}, dbName override the default dbName. - * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor. - * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets. - * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos. - * - * @class Represents a Cursor. - * @param {Db} db the database object to work with. - * @param {Collection} collection the collection to query. - * @param {Object} selector the query selector. - * @param {Object} fields an object containing what fields to include or exclude from objects returned. - * @param {Object} [options] additional options for the collection. -*/ -function Cursor(db, collection, selector, fields, options) { - this.db = db; - this.collection = collection; - this.selector = selector; - this.fields = fields; - options = !options ? {} : options; - - this.skipValue = options.skip == null ? 0 : options.skip; - this.limitValue = options.limit == null ? 0 : options.limit; - this.sortValue = options.sort; - this.hint = options.hint; - this.explainValue = options.explain; - this.snapshot = options.snapshot; - this.timeout = options.timeout == null ? true : options.timeout; - this.tailable = options.tailable; - this.awaitdata = options.awaitdata; - this.numberOfRetries = options.numberOfRetries == null ? 5 : options.numberOfRetries; - this.currentNumberOfRetries = this.numberOfRetries; - this.batchSizeValue = options.batchSize == null ? 0 : options.batchSize; - this.slaveOk = options.slaveOk == null ? collection.slaveOk : options.slaveOk; - this.raw = options.raw == null ? false : options.raw; - this.read = options.read == null ? ReadPreference.PRIMARY : options.read; - this.returnKey = options.returnKey; - this.maxScan = options.maxScan; - this.min = options.min; - this.max = options.max; - this.showDiskLoc = options.showDiskLoc; - this.comment = options.comment; - this.tailableRetryInterval = options.tailableRetryInterval || 100; - this.exhaust = options.exhaust || false; - this.partial = options.partial || false; - - this.totalNumberOfRecords = 0; - this.items = []; - this.cursorId = Long.fromInt(0); - - // This name - this.dbName = options.dbName; - - // State variables for the cursor - this.state = Cursor.INIT; - // Keep track of the current query run - this.queryRun = false; - this.getMoreTimer = false; - - // If we are using a specific db execute against it - if(this.dbName != null) { - this.collectionName = this.dbName + "." + this.collection.collectionName; - } else { - this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName; - } -}; - -/** - * Resets this cursor to its initial state. All settings like the query string, - * tailable, batchSizeValue, skipValue and limits are preserved. - * - * @return {Cursor} returns itself with rewind applied. - * @api public - */ -Cursor.prototype.rewind = function() { - var self = this; - - if (self.state != Cursor.INIT) { - if (self.state != Cursor.CLOSED) { - self.close(function() {}); - } - - self.numberOfReturned = 0; - self.totalNumberOfRecords = 0; - self.items = []; - self.cursorId = Long.fromInt(0); - self.state = Cursor.INIT; - self.queryRun = false; - } - - return self; -}; - - -/** - * Returns an array of documents. The caller is responsible for making sure that there - * is enough memory to store the results. Note that the array only contain partial - * results when this cursor had been previouly accessed. In that case, - * cursor.rewind() can be used to reset the cursor. - * - * @param {Function} callback This will be called after executing this method successfully. The first parameter will contain the Error object if an error occured, or null otherwise. The second parameter will contain an array of BSON deserialized objects as a result of the query. - * @return {null} - * @api public - */ -Cursor.prototype.toArray = function(callback) { - var self = this; - - if(!callback) { - throw new Error('callback is mandatory'); - } - - if(this.tailable) { - callback(new Error("Tailable cursor cannot be converted to array"), null); - } else if(this.state != Cursor.CLOSED) { - // return toArrayExhaust(self, callback); - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return toArrayExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - self.nextObject({noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err), null); - if(self.cursorId.toString() == "0") { - self.state = Cursor.CLOSED; - return callback(null, self.items); - } - - // Let's issue getMores until we have no more records waiting - getAllByGetMore(self, function(err, done) { - self.state = Cursor.CLOSED; - if(err) return callback(utils.toError(err), null); - callback(null, self.items); - }); - }) - - } else { - callback(new Error("Cursor is closed"), null); - } -} - -var toArrayExhaust = function(self, callback) { - var items = []; - - self.each(function(err, item) { - if(err != null) { - return callback(utils.toError(err), null); - } - - if(item != null && Array.isArray(items)) { - items.push(item); - } else { - var resultItems = items; - items = null; - self.items = []; - callback(null, resultItems); - } - }); -} - -var getAllByGetMore = function(self, callback) { - getMore(self, {noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err)); - if(result == null) return callback(null, null); - if(self.cursorId.toString() == "0") return callback(null, null); - getAllByGetMore(self, callback); - }) -} - -/** - * Iterates over all the documents for this cursor. As with **{cursor.toArray}**, - * not all of the elements will be iterated if this cursor had been previouly accessed. - * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike - * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements - * at any given time if batch size is specified. Otherwise, the caller is responsible - * for making sure that the entire result can fit the memory. - * - * @param {Function} callback this will be called for while iterating every document of the query result. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the document. - * @return {null} - * @api public - */ -Cursor.prototype.each = function(callback) { - var self = this; - var fn; - - if (!callback) { - throw new Error('callback is mandatory'); - } - - if(this.state != Cursor.CLOSED) { - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return eachExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - if(this.items.length > 0) { - // Trampoline all the entries - while(fn = loop(self, callback)) fn(self, callback); - // Call each again - self.each(callback); - } else { - self.nextObject(function(err, item) { - - if(err) { - self.state = Cursor.CLOSED; - return callback(utils.toError(err), item); - } - - if(item == null) return callback(null, null); - callback(null, item); - self.each(callback); - }) - } - } else { - callback(new Error("Cursor is closed"), null); - } -} - -// Special for exhaust command as we don't initiate the actual result sets -// the server just sends them as they arrive meaning we need to get the IO event -// loop happen so we can receive more data from the socket or we return to early -// after the first fetch and loose all the incoming getMore's automatically issued -// from the server. -var eachExhaust = function(self, callback) { - //FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2) - process.nextTick(function(){ - // Fetch the next object until there is no more objects - self.nextObject(function(err, item) { - if(err != null) return callback(err, null); - if(item != null) { - callback(null, item); - eachExhaust(self, callback); - } else { - // Close the cursor if done - self.state = Cursor.CLOSED; - callback(err, null); - } - }); - }); -} - -// Trampoline emptying the number of retrieved items -// without incurring a nextTick operation -var loop = function(self, callback) { - // No more items we are done - if(self.items.length == 0) return; - // Get the next document - var doc = self.items.shift(); - // Callback - callback(null, doc); - // Loop - return loop; -} - -/** - * Determines how many result the query for this cursor will return - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the number of results or null if an error occured. - * @return {null} - * @api public - */ -Cursor.prototype.count = function(callback) { - this.collection.count(this.selector, callback); -}; - -/** - * Sets the sort parameter of this cursor to the given value. - * - * This method has the following method signatures: - * (keyOrList, callback) - * (keyOrList, direction, callback) - * - * @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction]. - * @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive. - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.sort = function(keyOrList, direction, callback) { - callback = callback || function(){}; - if(typeof direction === "function") { callback = direction; direction = null; } - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support sorting"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - var order = keyOrList; - - if(direction != null) { - order = [[keyOrList, direction]]; - } - - this.sortValue = order; - callback(null, this); - } - return this; -}; - -/** - * Sets the limit parameter of this cursor to the given value. - * - * @param {Number} limit the new limit. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.limit = function(limit, callback) { - if(this.tailable) { - if(callback) { - callback(new Error("Tailable cursor doesn't support limit"), null); - } else { - throw new Error("Tailable cursor doesn't support limit"); - } - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback) { - callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else { - if(limit != null && limit.constructor != Number) { - if(callback) { - callback(new Error("limit requires an integer"), null); - } else { - throw new Error("limit requires an integer"); - } - } else { - this.limitValue = limit; - if(callback) return callback(null, this); - } - } - - return this; -}; - -/** - * Sets the read preference for the cursor - * - * @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.setReadPreference = function(readPreference, tags, callback) { - if(typeof tags == 'function') callback = tags; - - var _mode = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - - if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback == null) throw new Error("Cannot change read preference on executed query or closed cursor"); - callback(new Error("Cannot change read preference on executed query or closed cursor")); - } else if(_mode != null && _mode != 'primary' - && _mode != 'secondaryOnly' && _mode != 'secondary' - && _mode != 'nearest' && _mode != 'primaryPreferred' && _mode != 'secondaryPreferred') { - if(callback == null) throw new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported"); - callback(new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported")); - } else { - this.read = readPreference; - if(callback != null) callback(null, this); - } - - return this; -} - -/** - * Sets the skip parameter of this cursor to the given value. - * - * @param {Number} skip the new skip value. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.skip = function(skip, callback) { - callback = callback || function(){}; - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support skip"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - if(skip != null && skip.constructor != Number) { - callback(new Error("skip requires an integer"), null); - } else { - this.skipValue = skip; - callback(null, this); - } - } - - return this; -}; - -/** - * Sets the batch size parameter of this cursor to the given value. - * - * @param {Number} batchSize the new batch size. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.batchSize = function(batchSize, callback) { - if(this.state == Cursor.CLOSED) { - if(callback != null) { - return callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else if(batchSize != null && batchSize.constructor != Number) { - if(callback != null) { - return callback(new Error("batchSize requires an integer"), null); - } else { - throw new Error("batchSize requires an integer"); - } - } else { - this.batchSizeValue = batchSize; - if(callback != null) return callback(null, this); - } - - return this; -}; - -/** - * The limit used for the getMore command - * - * @return {Number} The number of records to request per batch. - * @ignore - * @api private - */ -var limitRequest = function(self) { - var requestedLimit = self.limitValue; - var absLimitValue = Math.abs(self.limitValue); - var absBatchValue = Math.abs(self.batchSizeValue); - - if(absLimitValue > 0) { - if (absBatchValue > 0) { - requestedLimit = Math.min(absLimitValue, absBatchValue); - } - } else { - requestedLimit = self.batchSizeValue; - } - - return requestedLimit; -}; - - -/** - * Generates a QueryCommand object using the parameters of this cursor. - * - * @return {QueryCommand} The command object - * @ignore - * @api private - */ -var generateQueryCommand = function(self) { - // Unpack the options - var queryOptions = QueryCommand.OPTS_NONE; - if(!self.timeout) { - queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - } - - if(self.tailable != null) { - queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR; - self.skipValue = self.limitValue = 0; - - // if awaitdata is set - if(self.awaitdata != null) { - queryOptions |= QueryCommand.OPTS_AWAIT_DATA; - } - } - - if(self.exhaust) { - queryOptions |= QueryCommand.OPTS_EXHAUST; - } - - if(self.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - if(self.partial) { - queryOptions |= QueryCommand.OPTS_PARTIAL; - } - - // limitValue of -1 is a special case used by Db#eval - var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self); - - // Check if we need a special selector - if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null - || self.returnKey != null || self.maxScan != null || self.min != null || self.max != null - || self.showDiskLoc != null || self.comment != null) { - - // Build special selector - var specialSelector = {'$query':self.selector}; - if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue); - if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint; - if(self.snapshot != null) specialSelector['$snapshot'] = true; - if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey; - if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan; - if(self.min != null) specialSelector['$min'] = self.min; - if(self.max != null) specialSelector['$max'] = self.max; - if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc; - if(self.comment != null) specialSelector['$comment'] = self.comment; - // If we have explain set only return a single document with automatic cursor close - if(self.explainValue != null) { - numberToReturn = (-1)*Math.abs(numberToReturn); - specialSelector['$explain'] = true; - } - - // Return the query - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields); - } else { - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields); - } -}; - -/** - * @return {Object} Returns an object containing the sort value of this cursor with - * the proper formatting that can be used internally in this cursor. - * @ignore - * @api private - */ -Cursor.prototype.formattedOrderClause = function() { - return utils.formattedOrderClause(this.sortValue); -}; - -/** - * Converts the value of the sort direction into its equivalent numerical value. - * - * @param sortDirection {String|number} Range of acceptable values: - * 'ascending', 'descending', 'asc', 'desc', 1, -1 - * - * @return {number} The equivalent numerical value - * @throws Error if the given sortDirection is invalid - * @ignore - * @api private - */ -Cursor.prototype.formatSortValue = function(sortDirection) { - return utils.formatSortValue(sortDirection); -}; - -/** - * Gets the next document from the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @api public - */ -Cursor.prototype.nextObject = function(options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.INIT) { - var cmd; - try { - cmd = generateQueryCommand(self); - } catch (err) { - return callback(err, null); - } - - // Execute command - var commandHandler = function(err, result) { - self.state = Cursor.OPEN; - if(err != null && result == null) return callback(err, null); - - if(!err && result.documents[0] && result.documents[0]['$err']) { - return self.close(function() {callback(result.documents[0]['$err'], null);}); - } - - self.queryRun = true; - self.state = Cursor.OPEN; // Adjust the state of the cursor - self.cursorId = result.cursorId; - self.totalNumberOfRecords = result.numberReturned; - - // Add the new documents to the list of items, using forloop to avoid - // new array allocations and copying - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // If we have noReturn set just return (not modifying the internal item list) - // used for toArray - if(options.noReturn) { - return callback(null, true); - } - - // Ignore callbacks until the cursor is dead for exhausted - if(self.exhaust && result.cursorId.toString() == "0") { - self.nextObject(callback); - } else if(self.exhaust == false || self.exhaust == null) { - self.nextObject(callback); - } - }; - - // If we have no connection set on this cursor check one out - if(self.connection == null) { - try { - self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read); - } catch(err) { - return callback(err, null); - } - } - - // Execute the command - self.db._executeQueryCommand(cmd, {exhaust: self.exhaust, raw:self.raw, read:self.read, connection:self.connection}, commandHandler); - // Set the command handler to null - commandHandler = null; - } else if(self.items.length) { - callback(null, self.items.shift()); - } else if(self.cursorId.greaterThan(Long.fromInt(0))) { - getMore(self, callback); - } else { - // Force cursor to stay open - return self.close(function() {callback(null, null);}); - } -} - -/** - * Gets more results from the database if any. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @ignore - * @api private - */ -var getMore = function(self, options, callback) { - var limit = 0; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.GET_MORE) return callback(null, null); - - // Set get more in progress - self.state = Cursor.GET_MORE; - - // Set options - if (!self.tailable && self.limitValue > 0) { - limit = self.limitValue - self.totalNumberOfRecords; - if (limit < 1) { - self.close(function() {callback(null, null);}); - return; - } - } - - try { - var getMoreCommand = new GetMoreCommand( - self.db - , self.collectionName - , limitRequest(self) - , self.cursorId - ); - - // Set up options - var command_options = {read: self.read, raw: self.raw, connection:self.connection }; - - // Execute the command - self.db._executeQueryCommand(getMoreCommand, command_options, function(err, result) { - // Get more done - self.state = Cursor.OPEN; - - try { - if(err != null) { - return callback(err, null); - } - - var isDead = 1 === result.responseFlag && result.cursorId.isZero(); - - self.cursorId = result.cursorId; - self.totalNumberOfRecords += result.numberReturned; - - // Determine if there's more documents to fetch - if(result.numberReturned > 0) { - if (self.limitValue > 0) { - var excessResult = self.totalNumberOfRecords - self.limitValue; - - if (excessResult > 0) { - result.documents.splice(-1 * excessResult, excessResult); - } - } - - // Reset the tries for awaitdata if we are using it - self.currentNumberOfRetries = self.numberOfRetries; - // Get the documents - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // Don's shift a document out as we need it for toArray - if(options.noReturn) { - return callback(null, true); - callback(null, true); - } else { - callback(null, self.items.shift()); - } - } else if(self.tailable && !isDead && self.awaitdata) { - // Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used - self.currentNumberOfRetries = self.currentNumberOfRetries - 1; - if(self.currentNumberOfRetries == 0) { - self.close(function() { - callback(new Error("tailable cursor timed out"), null); - }); - } else { - getMore(self, callback); - } - } else if(self.tailable && !isDead) { - self.getMoreTimer = setTimeout(function() { getMore(self, callback); }, self.tailableRetryInterval); - } else { - self.close(function() {callback(null, null); }); - } - - result = null; - } catch(err) { - callback(err, null); - } - }); - - getMoreCommand = null; - } catch(err) { - // Get more done - self.state = Cursor.OPEN; - - var handleClose = function() { - callback(err, null); - }; - - self.close(handleClose); - handleClose = null; - } -} - -/** - * Gets a detailed information about how the query is performed on this cursor and how - * long it took the database to process it. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details. - * @api public - */ -Cursor.prototype.explain = function(callback) { - var limit = (-1)*Math.abs(this.limitValue); - - // * - **skip** {Number} skip number of documents to skip. - // * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1. - // * - **hint** {Object}, hint force the query to use a specific index. - // * - **explain** {Boolean}, explain return the explaination of the query. - // * - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries. - // * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned. - // * - **timeout** {Boolean}, timeout allow the query to timeout. - // * - **tailable** {Boolean}, tailable allow the cursor to be tailable. - // * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor. - // * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database. - // * - **raw** {Boolean}, raw return all query documents as raw buffers (default false). - // * - **read** {Boolean}, read specify override of read from source (primary/secondary). - // * - **returnKey** {Boolean}, returnKey only return the index key. - // * - **maxScan** {Number}, maxScan limit the number of items to scan. - // * - **min** {Number}, min set index bounds. - // * - **max** {Number}, max set index bounds. - // * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results. - // * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler. - // * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout. - // * - **dbName** {String}, dbName override the default dbName. - // * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor. - // * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets. - // * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos. - - // * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - -// function Cursor(db, collection, selector, fields, skip, limit -// - , sort, hint, explain, snapshot, timeout, tailable, batchSize, slaveOk, raw, read -// - , returnKey, maxScan, min, max, showDiskLoc, comment, awaitdata, numberOfRetries, dbName, tailableRetry - - // Create a new cursor and fetch the plan - var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, { - skip: this.skipValue - , limit:limit - , sort: this.sortValue - , hint: this.hint - , explain: true - , snapshot: this.snapshot - , timeout: this.timeout - , tailable: this.tailable - , batchSize: this.batchSizeValue - , slaveOk: this.slaveOk - , raw: this.raw - , read: this.read - , returnKey: this.returnKey - , maxScan: this.maxScan - , min: this.min - , max: this.max - , showDiskLoc: this.showDiskLoc - , comment: this.comment - , awaitdata: this.awaitdata - , numberOfRetries: this.numberOfRetries - , dbName: this.dbName - }); - - // Fetch the explaination document - cursor.nextObject(function(err, item) { - if(err != null) return callback(err, null); - // close the cursor - cursor.close(function(err, result) { - if(err != null) return callback(err, null); - callback(null, item); - }); - }); -}; - -/** - * @ignore - */ -Cursor.prototype.streamRecords = function(options) { - console.log("[WARNING] streamRecords method is deprecated, please use stream method which is much faster"); - var args = Array.prototype.slice.call(arguments, 0); - options = args.length ? args.shift() : {}; - - var - self = this, - stream = new process.EventEmitter(), - recordLimitValue = this.limitValue || 0, - emittedRecordCount = 0, - queryCommand = generateQueryCommand(self); - - // see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol - queryCommand.numberToReturn = options.fetchSize ? options.fetchSize : 500; - // Execute the query - execute(queryCommand); - - function execute(command) { - self.db._executeQueryCommand(command, {exhaust: self.exhaust, read:self.read, raw:self.raw, connection:self.connection}, function(err,result) { - if(err) { - stream.emit('error', err); - self.close(function(){}); - return; - } - - if (!self.queryRun && result) { - self.queryRun = true; - self.cursorId = result.cursorId; - self.state = Cursor.OPEN; - self.getMoreCommand = new GetMoreCommand(self.db, self.collectionName, queryCommand.numberToReturn, result.cursorId); - } - - var resflagsMap = { - CursorNotFound:1<<0, - QueryFailure:1<<1, - ShardConfigStale:1<<2, - AwaitCapable:1<<3 - }; - - if(result.documents && result.documents.length && !(result.responseFlag & resflagsMap.QueryFailure)) { - try { - result.documents.forEach(function(doc){ - if(recordLimitValue && emittedRecordCount>=recordLimitValue) { - throw("done"); - } - emittedRecordCount++; - stream.emit('data', doc); - }); - } catch(err) { - if (err != "done") { throw err; } - else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - self.close(function(){}); - return; - } - } - // rinse & repeat - execute(self.getMoreCommand); - } else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - } - }); - } - - return stream; -}; - -/** - * Returns a Node ReadStream interface for this cursor. - * - * @return {CursorStream} returns a stream object. - * @api public - */ -Cursor.prototype.stream = function stream () { - return new CursorStream(this); -} - -/** - * Close the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor. - * @return {null} - * @api public - */ -Cursor.prototype.close = function(callback) { - var self = this - this.getMoreTimer && clearTimeout(this.getMoreTimer); - // Close the cursor if not needed - if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) { - try { - var command = new KillCursorCommand(this.db, [this.cursorId]); - // Added an empty callback to ensure we don't throw any null exceptions - this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function() {}); - } catch(err) {} - } - - // Null out the connection - self.connection = null; - // Reset cursor id - this.cursorId = Long.fromInt(0); - // Set to closed status - this.state = Cursor.CLOSED; - - if(callback) { - callback(null, self); - self.items = []; - } - - return this; -}; - -/** - * Check if the cursor is closed or open. - * - * @return {Boolean} returns the state of the cursor. - * @api public - */ -Cursor.prototype.isClosed = function() { - return this.state == Cursor.CLOSED ? true : false; -}; - -/** - * Init state - * - * @classconstant INIT - **/ -Cursor.INIT = 0; - -/** - * Cursor open - * - * @classconstant OPEN - **/ -Cursor.OPEN = 1; - -/** - * Cursor closed - * - * @classconstant CLOSED - **/ -Cursor.CLOSED = 2; - -/** - * Cursor performing a get more - * - * @classconstant OPEN - **/ -Cursor.GET_MORE = 3; - -/** - * @ignore - * @api private - */ -exports.Cursor = Cursor; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js deleted file mode 100644 index ee0cd80700b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Module dependecies. - */ -var Stream = require('stream').Stream; - -/** - * CursorStream - * - * Returns a stream interface for the **cursor**. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - **close** {function() {}} the end event triggers when there is no more documents available. - * - * @class Represents a CursorStream. - * @param {Cursor} cursor a cursor object that the stream wraps. - * @return {Stream} - */ -function CursorStream(cursor) { - if(!(this instanceof CursorStream)) return new CursorStream(cursor); - - Stream.call(this); - - this.readable = true; - this.paused = false; - this._cursor = cursor; - this._destroyed = null; - - // give time to hook up events - var self = this; - process.nextTick(function () { - self._init(); - }); -} - -/** - * Inherit from Stream - * @ignore - * @api private - */ -CursorStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -CursorStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -CursorStream.prototype.paused; - -/** - * Initialize the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._init = function () { - if (this._destroyed) return; - this._next(); -} - -/** - * Pull the next document from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._next = function () { - if (this.paused || this._destroyed) return; - - var self = this; - // Get the next object - process.nextTick(function() { - self._cursor.nextObject(function (err, doc) { - self._onNextObject(err, doc); - }); - }); -} - -/** - * Handle each document as its returned from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._onNextObject = function (err, doc) { - if(err) return this.destroy(err); - - // when doc is null we hit the end of the cursor - if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) { - this.emit('end') - return this.destroy(); - } else if(doc) { - this.emit('data', doc); - this._next(); - } -} - -/** - * Pauses the stream. - * - * @api public - */ -CursorStream.prototype.pause = function () { - this.paused = true; -} - -/** - * Resumes the stream. - * - * @api public - */ -CursorStream.prototype.resume = function () { - var self = this; - - // Don't do anything if we are not paused - if(!this.paused) return; - if(!this._cursor.state == 3) return; - - process.nextTick(function() { - self.paused = false; - // Only trigger more fetching if the cursor is open - self._next(); - }) -} - -/** - * Destroys the stream, closing the underlying - * cursor. No more events will be emitted. - * - * @api public - */ -CursorStream.prototype.destroy = function (err) { - if (this._destroyed) return; - this._destroyed = true; - this.readable = false; - - this._cursor.close(); - - if (err) { - this.emit('error', err); - } - - this.emit('close'); -} - -// TODO - maybe implement the raw option to pass binary? -//CursorStream.prototype.setEncoding = function () { -//} - -module.exports = exports = CursorStream; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js deleted file mode 100644 index c888cf40bbb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js +++ /dev/null @@ -1,2106 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var QueryCommand = require('./commands/query_command').QueryCommand, - DbCommand = require('./commands/db_command').DbCommand, - MongoReply = require('./responses/mongo_reply').MongoReply, - Admin = require('./admin').Admin, - Collection = require('./collection').Collection, - Server = require('./connection/server').Server, - ReplSet = require('./connection/repl_set').ReplSet, - ReadPreference = require('./connection/read_preference').ReadPreference, - Mongos = require('./connection/mongos').Mongos, - Cursor = require('./cursor').Cursor, - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - crypto = require('crypto'), - utils = require('./utils'), - parse = require('./connection/url_parser').parse; - -/** - * Create a new Db instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a Db - * @param {String} databaseName name of the database. - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function Db(databaseName, serverConfig, options) { - if(!(this instanceof Db)) return new Db(databaseName, serverConfig, options); - - EventEmitter.call(this); - this.databaseName = databaseName; - this.serverConfig = serverConfig; - this.options = options == null ? {} : options; - // State to check against if the user force closed db - this._applicationClosed = false; - // Fetch the override flag if any - var overrideUsedFlag = this.options['override_used_flag'] == null ? false : this.options['override_used_flag']; - - // Verify that nobody is using this config - if(!overrideUsedFlag && this.serverConfig != null && typeof this.serverConfig == 'object' && this.serverConfig._isUsed && this.serverConfig._isUsed()) { - throw new Error("A Server or ReplSet instance cannot be shared across multiple Db instances"); - } else if(!overrideUsedFlag && typeof this.serverConfig == 'object'){ - // Set being used - this.serverConfig._used = true; - } - - // Ensure we have a valid db name - validateDatabaseName(databaseName); - - // Contains all the connections for the db - try { - this.native_parser = this.options.native_parser; - // The bson lib - var bsonLib = this.bsonLib = this.options.native_parser ? require('bson').BSONNative : require('bson').BSONPure; - // Fetch the serializer object - var BSON = bsonLib.BSON; - // Create a new instance - this.bson = new BSON([bsonLib.Long, bsonLib.ObjectID, bsonLib.Binary, bsonLib.Code, bsonLib.DBRef, bsonLib.Symbol, bsonLib.Double, bsonLib.Timestamp, bsonLib.MaxKey, bsonLib.MinKey]); - // Backward compatibility to access types - this.bson_deserializer = bsonLib; - this.bson_serializer = bsonLib; - } catch (err) { - // If we tried to instantiate the native driver - var msg = "Native bson parser not compiled, please compile " - + "or avoid using native_parser=true"; - throw Error(msg); - } - - // Internal state of the server - this._state = 'disconnected'; - - this.pkFactory = this.options.pk == null ? bsonLib.ObjectID : this.options.pk; - this.forceServerObjectId = this.options.forceServerObjectId != null ? this.options.forceServerObjectId : false; - - // Added safe - this.safe = this.options.safe == null ? false : this.options.safe; - - // If we have not specified a "safe mode" we just print a warning to the console - if(this.options.safe == null && this.options.w == null && this.options.journal == null && this.options.fsync == null) { - console.log("========================================================================================"); - console.log("= Please ensure that you set the default write concern for the database by setting ="); - console.log("= one of the options ="); - console.log("= ="); - console.log("= w: (value of > -1 or the string 'majority'), where < 1 means ="); - console.log("= no write acknowlegement ="); - console.log("= journal: true/false, wait for flush to journal before acknowlegement ="); - console.log("= fsync: true/false, wait for flush to file system before acknowlegement ="); - console.log("= ="); - console.log("= For backward compatibility safe is still supported and ="); - console.log("= allows values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}] ="); - console.log("= the default value is false which means the driver receives does not ="); - console.log("= return the information of the success/error of the insert/update/remove ="); - console.log("= ="); - console.log("= ex: new Db(new Server('localhost', 27017), {safe:false}) ="); - console.log("= ="); - console.log("= http://www.mongodb.org/display/DOCS/getLastError+Command ="); - console.log("= ="); - console.log("= The default of no acknowlegement will change in the very near future ="); - console.log("= ="); - console.log("= This message will disappear when the default safe is set on the driver Db ="); - console.log("========================================================================================"); - } - - // Internal states variables - this.notReplied ={}; - this.isInitializing = true; - this.auths = []; - this.openCalled = false; - - // Command queue, keeps a list of incoming commands that need to be executed once the connection is up - this.commands = []; - - // Set up logger - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - // Allow slaveOk - this.slaveOk = this.options["slave_ok"] == null ? false : this.options["slave_ok"]; - - var self = this; - // Associate the logger with the server config - this.serverConfig.logger = this.logger; - this.tag = new Date().getTime(); - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[]}; - - // Controls serialization options - this.serializeFunctions = this.options.serializeFunctions != null ? this.options.serializeFunctions : false; - - // Raw mode - this.raw = this.options.raw != null ? this.options.raw : false; - - // Record query stats - this.recordQueryStats = this.options.recordQueryStats != null ? this.options.recordQueryStats : false; - - // If we have server stats let's make sure the driver objects have it enabled - if(this.recordQueryStats == true) { - this.serverConfig.enableRecordQueryStats(true); - } - - // Retry information - this.retryMiliSeconds = this.options.retryMiliSeconds != null ? this.options.retryMiliSeconds : 1000; - this.numberOfRetries = this.options.numberOfRetries != null ? this.options.numberOfRetries : 60; - - // Set default read preference if any - this.readPreference = this.options.readPreference; -}; - -/** - * @ignore - */ -function validateDatabaseName(databaseName) { - if(typeof databaseName !== 'string') throw new Error("database name must be a string"); - if(databaseName.length === 0) throw new Error("database name cannot be the empty string"); - - var invalidChars = [" ", ".", "$", "/", "\\"]; - for(var i = 0; i < invalidChars.length; i++) { - if(databaseName.indexOf(invalidChars[i]) != -1) throw new Error("database names cannot contain the character '" + invalidChars[i] + "'"); - } -} - -/** - * @ignore - */ -inherits(Db, EventEmitter); - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the index information or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.open = function(callback) { - var self = this; - - // Check that the user has not called this twice - if(this.openCalled) { - // Close db - this.close(); - // Throw error - throw new Error("db object already connecting, open cannot be called multiple times"); - } - - // If we have a specified read preference - if(this.readPreference != null) this.serverConfig.setReadPreference(this.readPreference); - - // Set that db has been opened - this.openCalled = true; - - // Set the status of the server - self._state = 'connecting'; - // Set up connections - if(self.serverConfig instanceof Server || self.serverConfig instanceof ReplSet || self.serverConfig instanceof Mongos) { - self.serverConfig.connect(self, {firstCall: true}, function(err, result) { - if(err != null) { - // Set that db has been closed - self.openCalled = false; - // Return error from connection - return callback(err, null); - } - // Set the status of the server - self._state = 'connected'; - // If we have queued up commands execute a command to trigger replays - if(self.commands.length > 0) _execute_queued_command(self); - // Callback - return callback(null, self); - }); - } else { - return callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null); - } -}; - -// Execute any baked up commands -var _execute_queued_command = function(self) { - // Execute any backed up commands - process.nextTick(function() { - // Execute any backed up commands - while(self.commands.length > 0) { - // Fetch the command - var command = self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(self, command['db_command'], command['options'], command['callback']); - } - } - }); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -Db.prototype.db = function(dbName) { - // Copy the options and add out internal override of the not shared flag - var options = {}; - for(var key in this.options) { - options[key] = this.options[key]; - } - - // Add override flag - options['override_used_flag'] = true; - // Create a new db instance - var newDbInstance = new Db(dbName, this.serverConfig, options); - //copy over any auths, we may need them for reconnecting - if (this.serverConfig.db) { - newDbInstance.auths = this.serverConfig.db.auths; - } - // Add the instance to the list of approved db instances - var allServerInstances = this.serverConfig.allServerInstances(); - // Add ourselves to all server callback instances - for(var i = 0; i < allServerInstances.length; i++) { - var server = allServerInstances[i]; - server.dbInstances.push(newDbInstance); - } - // Return new db object - return newDbInstance; -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Boolean} [forceClose] connection can never be reused. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.close = function(forceClose, callback) { - var self = this; - // Ensure we force close all connections - this._applicationClosed = false; - - if(typeof forceClose == 'function') { - callback = forceClose; - } else if(typeof forceClose == 'boolean') { - this._applicationClosed = forceClose; - } - - // Remove all listeners and close the connection - this.serverConfig.close(function(err, result) { - // Emit the close event - if(typeof callback !== 'function') self.emit("close"); - - // Emit close event across all db instances sharing the sockets - var allServerInstances = self.serverConfig.allServerInstances(); - // Fetch the first server instance - if(Array.isArray(allServerInstances) && allServerInstances.length > 0) { - var server = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(server.dbInstances) && server.dbInstances.length > 1) { - for(var i = 0; i < server.dbInstances.length; i++) { - var dbInstance = server.dbInstances[i]; - // Check if it's our current db instance and skip if it is - if(dbInstance.databaseName !== self.databaseName && dbInstance.tag !== self.tag) { - server.dbInstances[i].emit("close"); - } - } - } - } - - // Remove all listeners - self.removeAllEventListeners(); - // You can reuse the db as everything is shut down - self.openCalled = false; - // If we have a callback call it - if(callback) callback(err, result); - }); -}; - -/** - * Access the Admin database - * - * @param {Function} [callback] returns the results. - * @return {Admin} the admin db object. - * @api public - */ -Db.prototype.admin = function(callback) { - if(callback == null) return new Admin(this); - callback(null, new Admin(this)); -}; - -/** - * Returns a cursor to all the collection information. - * - * @param {String} [collectionName] the collection name we wish to retrieve the information from. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the options or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionsInfo = function(collectionName, callback) { - if(callback == null && typeof collectionName == 'function') { callback = collectionName; collectionName = null; } - // Create selector - var selector = {}; - // If we are limiting the access to a specific collection name - if(collectionName != null) selector.name = this.databaseName + "." + collectionName; - - // Return Cursor - // callback for backward compatibility - if(callback) { - callback(null, new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector)); - } else { - return new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector); - } -}; - -/** - * Get the list of all collection names for the specified db - * - * Options - * - **namesOnly** {String, default:false}, Return only the full collection namespace. - * - * @param {String} [collectionName] the collection name we wish to filter by. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection names or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionNames = function(collectionName, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - collectionName = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure no breaking behavior - if(collectionName != null && typeof collectionName == 'object') { - options = collectionName; - collectionName = null; - } - - // Let's make our own callback to reuse the existing collections info method - self.collectionsInfo(collectionName, function(err, cursor) { - if(err != null) return callback(err, null); - - cursor.toArray(function(err, documents) { - if(err != null) return callback(err, null); - - // List of result documents that have been filtered - var filtered_documents = documents.filter(function(document) { - return !(document.name.indexOf(self.databaseName) == -1 || document.name.indexOf('$') != -1); - }); - - // If we are returning only the names - if(options.namesOnly) { - filtered_documents = filtered_documents.map(function(document) { return document.name }); - } - - // Return filtered items - callback(null, filtered_documents); - }); - }); -}; - -/** - * Fetch a specific collection (containing the actual collection information) - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if collection already exists - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collection = function(collectionName, options, callback) { - var self = this; - if(typeof options === "function") { callback = options; options = {}; } - // Execute safe - - if(options && (options.strict)) { - self.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - if(collections.length == 0) { - return callback(new Error("Collection " + collectionName + " does not exist. Currently in safe mode."), null); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - }); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - if(callback == null) { - throw err; - } else { - return callback(err, null); - } - } - - // If we have no callback return collection object - return callback == null ? collection : callback(null, collection); - } -}; - -/** - * Fetch all collections for the current db. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collections or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collections = function(callback) { - var self = this; - // Let's get the collection names - self.collectionNames(function(err, documents) { - if(err != null) return callback(err, null); - var collections = []; - documents.forEach(function(document) { - collections.push(new Collection(self, document.name.replace(self.databaseName + ".", ''), self.pkFactory)); - }); - // Return the collection objects - callback(null, collections); - }); -}; - -/** - * Evaluate javascript on the server - * - * Options - * - **nolock** {Boolean, default:false}, Tell MongoDB not to block on the evaulation of the javascript. - * - * @param {Code} code javascript to execute on server. - * @param {Object|Array} [parameters] the parameters for the call. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from eval or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.eval = function(code, parameters, options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - parameters = args.length ? args.shift() : parameters; - options = args.length ? args.shift() : {}; - - var finalCode = code; - var finalParameters = []; - // If not a code object translate to one - if(!(finalCode instanceof this.bsonLib.Code)) { - finalCode = new this.bsonLib.Code(finalCode); - } - - // Ensure the parameters are correct - if(parameters != null && parameters.constructor != Array && typeof parameters !== 'function') { - finalParameters = [parameters]; - } else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') { - finalParameters = parameters; - } - - // Create execution selector - var selector = {'$eval':finalCode, 'args':finalParameters}; - // Check if the nolock parameter is passed in - if(options['nolock']) { - selector['nolock'] = options['nolock']; - } - - // Set primary read preference - options.readPreference = ReadPreference.PRIMARY; - - // Execute the eval - this.collection(DbCommand.SYSTEM_COMMAND_COLLECTION).findOne(selector, options, function(err, result) { - if(err) return callback(err); - - if(result && result.ok == 1) { - callback(null, result.retval); - } else if(result) { - callback(new Error("eval failed: " + result.errmsg), null); return; - } else { - callback(err, result); - } - }); -}; - -/** - * Dereference a dbref, against a db - * - * @param {DBRef} dbRef db reference object we wish to resolve. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dereference or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dereference = function(dbRef, callback) { - var db = this; - // If we have a db reference then let's get the db first - if(dbRef.db != null) db = this.db(dbRef.db); - // Fetch the collection and find the reference - var collection = db.collection(dbRef.namespace); - collection.findOne({'_id':dbRef.oid}, function(err, result) { - callback(err, result); - }); -}; - -/** - * Logout user from server, fire off on all connections and remove all auth info - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.logout = function(options, callback) { - var self = this; - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Number of connections we need to logout from - var numberOfConnections = this.serverConfig.allRawConnections().length; - - // Let's generate the logout command object - var logoutCommand = DbCommand.logoutCommand(self, {logout:1}, options); - self._executeQueryCommand(logoutCommand, {onAll:true}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - // Reset auth - self.auths = []; - // Handle any errors - if(err == null && result.documents[0].ok == 1) { - internalCallback(null, true); - } else { - err != null ? internalCallback(err, false) : internalCallback(new Error(result.documents[0].errmsg), false); - } - } - }); -} - -/** - * Authenticate a user against the server. - * - * Options - * - **authdb** {String}, The database that the credentials are for, - * different from the name of the current DB, for example admin - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authentication or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.authenticate = function(username, password, options, callback) { - var self = this; - - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - // the default db to authenticate against is 'this' - // if authententicate is called from a retry context, it may be another one, like admin - var authdb = options.authdb ? options.authdb : self.databaseName; - // Push the new auth if we have no previous record - - var numberOfConnections = 0; - var errorObject = null; - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = this.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - // Execute all four - this._executeQueryCommand(DbCommand.createGetNonceCommand(self), options, function(err, result, connection) { - // Execute on all the connections - if(err == null) { - // Nonce used to make authentication request with md5 hash - var nonce = result.documents[0].nonce; - // Execute command - self._executeQueryCommand(DbCommand.createAuthenticationCommand(self, username, password, nonce, authdb), {connection:connection}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Ensure we save any error - if(err) { - errorObject = err; - } else if(result.documents[0].err != null || result.documents[0].errmsg != null){ - errorObject = utils.toError(result.documents[0]); - } - - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - - if(errorObject == null && result.documents[0].ok == 1) { - // We authenticated correctly save the credentials - self.auths = [{'username':username, 'password':password, 'authdb': authdb}]; - // Return callback - internalCallback(errorObject, true); - } else { - internalCallback(errorObject, false); - } - } - }); - } - }); -}; - -/** - * Add a user to the database. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.addUser = function(username, password, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - errorOptions.w = errorOptions.w == null ? 1 : errorOptions.w; - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var userPassword = md5.digest('hex'); - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - // Check if we are inserting the first user - collection.count({}, function(err, count) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Check if the user exists and update i - collection.find({user: username}, {dbName: options['dbName']}).toArray(function(err, documents) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Add command keys - var commandOptions = errorOptions; - commandOptions.dbName = options['dbName']; - commandOptions.upsert = true; - - // We have a user, let's update the password or upsert if not - collection.update({user: username},{$set: {user: username, pwd: userPassword}}, commandOptions, function(err, results) { - if(count == 0 && err) { - callback(null, [{user:username, pwd:userPassword}]); - } else if(err) { - callback(err, null) - } else { - callback(null, [{user:username, pwd:userPassword}]); - } - }); - }); - }); -}; - -/** - * Remove a user from a database - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - collection.findOne({user: username}, {dbName: options['dbName']}, function(err, user) { - if(user != null) { - // Add command keys - var commandOptions = safe; - commandOptions.dbName = options['dbName']; - - collection.remove({user: username}, commandOptions, function(err, result) { - callback(err, true); - }); - } else { - callback(err, false); - } - }); -}; - -/** - * Creates a collection on a server pre-allocating space, need to create f.ex capped collections. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **capped** {Boolean, default:false}, create a capped collection. - * - **size** {Number}, the size of the capped collection in bytes. - * - **max** {Number}, the maximum number of documents in the capped collection. - * - **autoIndexId** {Boolean, default:true}, create an index on the _id field of the document, True by default on MongoDB 2.2 or higher off for version < 2.2. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if collection already exists - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : null; - var self = this; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Check if we have the name - this.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - var found = false; - collections.forEach(function(collection) { - if(collection.name == self.databaseName + "." + collectionName) found = true; - }); - - // If the collection exists either throw an exception (if db in safe mode) or return the existing collection - if(found && options && options.strict) { - return callback(new Error("Collection " + collectionName + " already exists. Currently in safe mode."), null); - } else if(found){ - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - - // Create a new collection and return it - self._executeQueryCommand(DbCommand.createCreateCollectionCommand(self, collectionName, options), {read:false, safe:safe}, function(err, result) { - var document = result.documents[0]; - // If we have no error let's return the collection - if(err == null && document.ok == 1) { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } else { - if (null == err) err = utils.toError(document); - callback(err, null); - } - }); - }); -}; - -/** - * Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server. - * - * @param {Object} selector the command hash to send to the server, ex: {ping:1}. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} - * @api public - */ -Db.prototype.command = function(selector, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Set up the options - var cursor = new Cursor(this - , new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, { - limit: -1, timeout: QueryCommand.OPTS_NO_CURSOR_TIMEOUT, dbName: options['dbName'] - }); - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Ensure only commands who support read Prefrences are exeuted otherwise override and use Primary - if(readPreference != false) { - if(selector['group'] || selector['aggregate'] || selector['collStats'] || selector['dbStats'] - || selector['count'] || selector['distinct'] || selector['geoNear'] || selector['geoSearch'] || selector['geoWalk'] - || (selector['mapreduce'] && selector.out == 'inline')) { - // Set the read preference - cursor.setReadPreference(readPreference); - } else { - cursor.setReadPreference(ReadPreference.PRIMARY); - } - } - - // Return the next object - cursor.nextObject(callback); -}; - -/** - * Drop a collection from the database, removing it permanently. New accesses will create a new collection. - * - * @param {String} collectionName the name of the collection we wish to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropCollection = function(collectionName, callback) { - var self = this; - callback || (callback = function(){}); - - // Drop the collection - this._executeQueryCommand(DbCommand.createDropCollectionCommand(this, collectionName), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, true); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Rename a collection. - * - * @param {String} fromCollection the name of the current collection we wish to rename. - * @param {String} toCollection the new name of the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from renameCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.renameCollection = function(fromCollection, toCollection, callback) { - var self = this; - callback || (callback = function(){}); - - // Execute the command, return the new renamed collection if successful - this._executeQueryCommand(DbCommand.createRenameCollectionCommand(this, fromCollection, toCollection), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, new Collection(self, toCollection, self.pkFactory)); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Return last error message for the given connection, note options can be combined. - * - * Options - * - **fsync** {Boolean, default:false}, option forces the database to fsync all files before returning. - * - **j** {Boolean, default:false}, awaits the journal commit before returning, > MongoDB 2.0. - * - **w** {Number}, until a write operation has been replicated to N servers. - * - **wtimeout** {Number}, number of miliseconds to wait before timing out. - * - * Connection Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Object} [connectionOptions] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from lastError or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.lastError = function(options, connectionOptions, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - connectionOptions = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetLastErrorCommand(options, this), connectionOptions, function(err, error) { - callback(err, error && error.documents); - }); -}; - -/** - * Legacy method calls. - * - * @ignore - * @api private - */ -Db.prototype.error = Db.prototype.lastError; -Db.prototype.lastStatus = Db.prototype.lastError; - -/** - * Return all errors up to the last time db reset_error_history was called. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from previousErrors or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.previousErrors = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetPreviousErrorsCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Runs a command on the database. - * @ignore - * @api private - */ -Db.prototype.executeDbCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, command_hash, options), options, callback); -}; - -/** - * Runs a command on the database as admin. - * @ignore - * @api private - */ -Db.prototype.executeDbAdminCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createAdminDbCommand(this, command_hash), options, callback); -}; - -/** - * Resets the error history of the mongo instance. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from resetErrorHistory or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.resetErrorHistory = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createResetErrorHistoryCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - // Default command options - var commandOptions = {}; - - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute insert command - this._executeInsertCommand(command, commandOptions, function(err, result) { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute insert command - var result = this._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, null); - } -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ensureIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Make sure we don't try to do a write concern without a callback - if(_hasWriteConcern(errorOptions) && callback == null) - throw new Error("Cannot use a writeConcern without a provided callback"); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - var index_name = command.documents[0].name; - - // Default command options - var commandOptions = {}; - // Check if the index allready exists - this.indexInformation(collectionName, function(err, collectionInfo) { - if(err != null) return callback(err, null); - - if(!collectionInfo[index_name]) { - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - if(typeof callback === 'function' - && commandOptions.w < 1 && !commandOptions.fsync && !commandOptions.journal) { - commandOptions.w = 1; - } - - self._executeInsertCommand(command, commandOptions, function(err, result) { - // Only callback if we have one specified - if(typeof callback === 'function') { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - } - }); - } else { - // Execute insert command - var result = self._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, index_name); - } - } else { - if(typeof callback === 'function') return callback(null, index_name); - } - }); -}; - -/** - * Returns the information available on allocated cursors. - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from cursorInfo or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.cursorInfo = function(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, {'cursorInfo':1}), options, function(err, result) { - callback(err, result.documents[0]); - }); -}; - -/** - * Drop an index on a collection. - * - * @param {String} collectionName the name of the collection where the command will drop an index. - * @param {String} indexName name of the index to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropIndex = function(collectionName, indexName, callback) { - this._executeQueryCommand(DbCommand.createDropIndexCommand(this, collectionName, indexName), callback); -}; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {String} collectionName the name of the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from reIndex or null if an error occured. - * @api public -**/ -Db.prototype.reIndex = function(collectionName, callback) { - this._executeQueryCommand(DbCommand.createReIndexCommand(this, collectionName), function(err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} collectionName the name of the collection. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from indexInformation or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.indexInformation = function(collectionName, options, callback) { - if(typeof callback === 'undefined') { - if(typeof options === 'undefined') { - callback = collectionName; - collectionName = null; - } else { - callback = options; - } - options = {}; - } - - // If we specified full information - var full = options['full'] == null ? false : options['full']; - // Build selector for the indexes - var selector = collectionName != null ? {ns: (this.databaseName + "." + collectionName)} : {}; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : ReadPreference.PRIMARY; - - // Iterate through all the fields of the index - this.collection(DbCommand.SYSTEM_INDEX_COLLECTION, function(err, collection) { - // Perform the find for the collection - collection.find(selector).setReadPreference(readPreference).toArray(function(err, indexes) { - if(err != null) return callback(err, null); - // Contains all the information - var info = {}; - - // if full defined just return all the indexes directly - if(full) return callback(null, indexes); - - // Process all the indexes - for(var i = 0; i < indexes.length; i++) { - var index = indexes[i]; - // Let's unpack the object - info[index.name] = []; - for(var name in index.key) { - info[index.name].push([name, index.key[name]]); - } - } - - // Return all the indexes - callback(null, info); - }); - }); -}; - -/** - * Drop a database. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropDatabase or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropDatabase = function(callback) { - var self = this; - - this._executeQueryCommand(DbCommand.createDropDatabaseCommand(this), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - callback(null, true); - } else { - if(err) { - callback(err, false); - } else { - callback(utils.toError(result.documents[0]), false); - } - } - }); -}; - -/** - * Get all the db statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from stats or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - dbStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.command(commandObject, options, callback); -} - -/** - * @ignore - */ -var __executeQueryCommand = function(self, db_command, options, callback) { - // Options unpacking - var read = options['read'] != null ? options['read'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var onAll = options['onAll'] != null ? options['onAll'] : false; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - - // Correct read preference to default primary if set to false, null or primary - if(!(typeof read == 'object') && read._type == 'ReadPreference') { - read = (read == null || read == 'primary' || read == false) ? ReadPreference.PRIMARY : read; - if(!ReadPreference.isValid(read)) return callback(new Error("Illegal readPreference mode specified, " + read)); - } else if(typeof read == 'object' && read._type == 'ReadPreference') { - if(!read.isValid()) return callback(new Error("Illegal readPreference mode specified, " + read.mode)); - } - - // If we have a read preference set and we are a mongos pass the read preference on to the mongos instance, - if(self.serverConfig.isMongos() && read != null && read != false) { - db_command.setMongosReadPreference(read); - } - - // If we got a callback object - if(typeof callback === 'function' && !onAll) { - // Override connection if we passed in a specific connection - var connection = specifiedConnection != null ? specifiedConnection : null; - - if(connection instanceof Error) return callback(connection, null); - - // Fetch either a reader or writer dependent on the specified read option if no connection - // was passed in - if(connection == null) { - connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - } - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error || connection['message'] != null) { - return callback(connection); - } - - // Exhaust Option - var exhaust = options.exhaust || false; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, exhaust, callback); - // Write the message out and handle any errors if there are any - connection.write(db_command, function(err) { - if(err != null) { - // Call the handler with an error - self.serverConfig._callHandler(db_command.getRequestId(), null, err); - } - }); - } else if(typeof callback === 'function' && onAll) { - var connections = self.serverConfig.allRawConnections(); - var numberOfEntries = connections.length; - // Go through all the connections - for(var i = 0; i < connections.length; i++) { - // Fetch a connection - var connection = connections[i]; - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, callback); - // Write the message out - connection.write(db_command, function(err) { - // Adjust the number of entries we need to process - numberOfEntries = numberOfEntries - 1; - // Remove listener - if(err != null) { - // Clean up listener and return error - self.serverConfig._removeHandler(db_command.getRequestId()); - } - - // No more entries to process callback with the error - if(numberOfEntries <= 0) { - callback(err); - } - }); - - // Update the db_command request id - db_command.updateRequestId(); - } - } else { - // Fetch either a reader or writer dependent on the specified read option - var connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - // Ensure we have a valid connection - if(connection == null || connection instanceof Error || connection['message'] != null) return null; - // Write the message out - connection.write(db_command, function(err) { - if(err != null) { - // Emit the error - self.emit("error", err); - } - }); - } -} - -/** - * @ignore - */ -var __retryCommandOnFailure = function(self, retryInMilliseconds, numberOfTimes, command, db_command, options, callback) { - if(this._state == 'connected' || this._state == 'disconnected') this._state = 'connecting'; - // Number of retries done - var numberOfRetriesDone = numberOfTimes; - // Retry function, execute once - var retryFunction = function(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback) { - _self.serverConfig.connect(_self, {}, function(err, result, _serverConfig) { - if(_options) delete _options['connection']; - - // Adjust the number of retries left - _numberOfRetriesDone = _numberOfRetriesDone - 1; - // Definitively restart - if(err != null && _numberOfRetriesDone > 0) { - _self._state = 'connecting'; - // Close the server config - _serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } else if(err != null && _numberOfRetriesDone <= 0) { - _self._state = 'disconnected'; - // Force close the current connections - _serverConfig.close(function(_err) { - // Force close the current connections - if(typeof _callback == 'function') _callback(err, null); - }); - } else if(err == null && _self.serverConfig.isConnected() == true && Array.isArray(_self.auths) && _self.auths.length > 0) { - _self._state = 'connected'; - // Get number of auths we need to execute - var numberOfAuths = _self.auths.length; - // Apply all auths - for(var i = 0; i < _self.auths.length; i++) { - _self.authenticate(_self.auths[i].username, _self.auths[i].password, {'authdb':_self.auths[i].authdb}, function(err, authenticated) { - numberOfAuths = numberOfAuths - 1; - - // If we have no more authentications to replay - if(numberOfAuths == 0) { - if(err != null || !authenticated) { - if(typeof _callback == 'function') _callback(err, null); - return; - } else { - // Execute command - command(_self, _db_command, _options, _callback); - // Execute all the commands - if(_self.commands.length > 0) _execute_queued_command(_self); - } - } - }); - } - } else if(err == null && _self.serverConfig.isConnected() == true) { - _self._state = 'connected'; - - // Execute command - command(_self, _db_command, _options, _callback); - - process.nextTick(function() { - // Execute any backed up commands - while(_self.commands.length > 0) { - // Fetch the command - var command = _self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(_self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(_self, command['db_command'], command['options'], command['callback']); - } - } - }); - } else { - _self._state = 'connecting'; - // Force close the current connections - _serverConfig.close(function(err) { - // _self.serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } - }); - }; - - // Execute function first time - retryFunction(self, numberOfRetriesDone, retryInMilliseconds, numberOfTimes, command, db_command, options, callback); -} - -/** - * Execute db query command (not safe) - * @ignore - * @api private - */ -Db.prototype._executeQueryCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - - // fast fail option used for HA, no retry - var failFast = options['failFast'] != null - ? options['failFast'] - : false; - - // Check if the user force closed the command - if(this._applicationClosed) { - var err = new Error("db closed by application"); - if('function' == typeof callback) { - return callback(err, null); - } else { - throw err; - } - } - - var config = this.serverConfig; - // If the pool is not connected, attemp to reconnect to send the message - if(this._state == 'connecting' && config.autoReconnect && !failFast) { - return process.nextTick(function() { - self.commands.push({ - type: 'query', - db_command: db_command, - options: options, - callback: callback - }); - }) - } - - if(!failFast && !config.isConnected(options.read) && config.autoReconnect - && (options.read == null - || options.read == false - || options.read == ReadPreference.PRIMARY - || config.checkoutReader() == null)) { - this._state = 'connecting'; - return __retryCommandOnFailure(this, - this.retryMiliSeconds, - this.numberOfRetries, - __executeQueryCommand, - db_command, - options, - callback); - } - - if(!config.isConnected(options.read) && !config.autoReconnect && callback) { - // Fire an error to the callback if we are not connected - // and don't reconnect. - return callback(new Error("no open connections"), null); - } - - __executeQueryCommand(self, db_command, options, function (err, result, conn) { - callback(err, result, conn); - }); - -}; - -/** - * @ignore - */ -var __executeInsertCommand = function(self, db_command, options, callback) { - // Always checkout a writer for this kind of operations - var connection = self.serverConfig.checkoutWriter(); - // Get safe mode - var safe = options['safe'] != null ? options['safe'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - - // Ensure we have a valid connection - if(typeof callback === 'function') { - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - var errorOptions = _getWriteConcern(self, options, callback); - if(errorOptions.w > 0 || errorOptions.w == 'majority' || errorOptions.j || errorOptions.journal || errorOptions.fsync) { - // db command is now an array of commands (original command + lastError) - db_command = [db_command, DbCommand.createGetLastErrorCommand(safe, self)]; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command[1], raw, connection, callback); - } - } - - // If we have no callback and there is no connection - if(connection == null) return null; - if(connection instanceof Error && typeof callback == 'function') return callback(connection, null); - if(connection instanceof Error) return null; - if(connection == null && typeof callback == 'function') return callback(new Error("no primary server found"), null); - - // Write the message out - connection.write(db_command, function(err) { - // Return the callback if it's not a safe operation and the callback is defined - if(typeof callback === 'function' && (safe == null || safe == false)) { - // Perform the callback - callback(err, null); - } else if(typeof callback === 'function') { - // Call the handler with an error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, err); - } else if(typeof callback == 'function' && safe && safe.w == -1) { - // Call the handler with no error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, null); - } else if(!safe || safe.w == -1) { - self.emit("error", err); - } - }); -} - -/** - * Execute an insert Command - * @ignore - * @api private - */ -Db.prototype._executeInsertCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if(callback == null && typeof options === 'function') { - callback = options; - options = {}; - } - - // Ensure options are not null - options = options == null ? {} : options; - - // Check if the user force closed the command - if(this._applicationClosed) { - if(typeof callback == 'function') { - return callback(new Error("db closed by application"), null); - } else { - throw new Error("db closed by application"); - } - } - - // If the pool is not connected, attemp to reconnect to send the message - if(self._state == 'connecting' && this.serverConfig.autoReconnect) { - process.nextTick(function() { - self.commands.push({type:'insert', 'db_command':db_command, 'options':options, 'callback':callback}); - }) - } else if(!this.serverConfig.isConnected() && this.serverConfig.autoReconnect) { - this._state = 'connecting'; - // Retry command - __retryCommandOnFailure(this, this.retryMiliSeconds, this.numberOfRetries, __executeInsertCommand, db_command, options, callback); - } else if(!this.serverConfig.isConnected() && !this.serverConfig.autoReconnect && callback) { - // Fire an error to the callback if we are not connected and don't do reconnect - if(callback) callback(new Error("no open connections"), null); - } else { - __executeInsertCommand(self, db_command, options, callback); - } -} - -/** - * Update command is the same - * @ignore - * @api private - */ -Db.prototype._executeUpdateCommand = Db.prototype._executeInsertCommand; -/** - * Remove command is the same - * @ignore - * @api private - */ -Db.prototype._executeRemoveCommand = Db.prototype._executeInsertCommand; - -/** - * Wrap a Mongo error document into an Error instance. - * Deprecated. Use utils.toError instead. - * - * @ignore - * @api private - * @deprecated - */ -Db.prototype.wrap = utils.toError; - -/** - * Default URL - * - * @classconstant DEFAULT_URL - **/ -Db.DEFAULT_URL = 'mongodb://localhost:27017/default'; - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the db instance or null if an error occured. - * @return {null} - * @api public - */ -Db.connect = function(url, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = typeof args[args.length - 1] == 'function' ? args.pop() : null; - options = args.length ? args.shift() : null; - options = options || {}; - var serverOptions = options.server || {}; - var mongosOptions = options.mongos || {}; - var replSetServersOptions = options.replSet || options.replSetServers || {}; - var dbOptions = options.db || {}; - - // If callback is null throw an exception - if(callback == null) throw new Error("no callback function provided"); - - // Parse the string - var object = parse(url); - // Merge in any options for db in options object - if(dbOptions) { - for(var name in dbOptions) object.db_options[name] = dbOptions[name]; - } - - // Merge in any options for server in options object - if(serverOptions) { - for(var name in serverOptions) object.server_options[name] = serverOptions[name]; - } - - // Merge in any replicaset server options - if(replSetServersOptions) { - for(var name in replSetServersOptions) object.rs_options[name] = replSetServersOptions[name]; - } - - // Merge in any replicaset server options - if(mongosOptions) { - for(var name in mongosOptions) object.mongos_options[name] = mongosOptions[name]; - } - - // We need to ensure that the list of servers are only either direct members or mongos - // they cannot be a mix of monogs and mongod's - var totalNumberOfServers = object.servers.length; - var totalNumberOfMongosServers = 0; - var totalNumberOfMongodServers = 0; - var serverConfig = null; - - // Failure modes - if(object.servers.length == 0) throw new Error("connection string must contain at least one seed host"); - - // If we have no db setting for the native parser try to set the c++ one first - object.db_options.native_parser = _setNativeParser(object.db_options); - // If no auto_reconnect is set, set it to true as default for single servers - if(typeof object.server_options.auto_reconnect != 'boolean') { - object.server_options.auto_reconnect = true; - } - - // If we have more than a server, it could be replicaset or mongos list - // need to verify that it's one or the other and fail if it's a mix - // Connect to all servers and run ismaster - for(var i = 0; i < object.servers.length; i++) { - // Set up socket options - var _server_options = {poolSize:1, socketOptions:{connectTimeoutMS:1000}, auto_reconnect:false}; - - // Ensure we have ssl setup for the servers - if(object.rs_options.ssl) { - _server_options.ssl = object.rs_options.ssl; - _server_options.sslValidate = object.rs_options.sslValidate; - _server_options.sslCA = object.rs_options.sslCA; - _server_options.sslCert = object.rs_options.sslCert; - _server_options.sslKey = object.rs_options.sslKey; - _server_options.sslPass = object.rs_options.sslPass; - } else if(object.server_options.ssl) { - _server_options.ssl = object.server_options.ssl; - _server_options.sslValidate = object.server_options.sslValidate; - _server_options.sslCA = object.server_options.sslCA; - _server_options.sslCert = object.server_options.sslCert; - _server_options.sslKey = object.server_options.sslKey; - _server_options.sslPass = object.server_options.sslPass; - } - - // Set up the Server object - var _server = object.servers[i].domain_socket - ? new Server(object.servers[i].domain_socket, _server_options) - : new Server(object.servers[i].host, object.servers[i].port, _server_options); - - // Attempt connect - new Db(object.dbName, _server, {safe:false, native_parser:false}).open(function(err, db) { - // Update number of servers - totalNumberOfServers = totalNumberOfServers - 1; - // If no error do the correct checks - if(!err) { - // Close the connection - db.close(true); - var isMasterDoc = db.serverConfig.isMasterDoc; - // Check what type of server we have - if(isMasterDoc.setName) totalNumberOfMongodServers++; - if(isMasterDoc.msg && isMasterDoc.msg == "isdbgrid") totalNumberOfMongosServers++; - } - - if(totalNumberOfServers == 0) { - // If we have a mix of mongod and mongos, throw an error - if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) - return callback(new Error("cannot combine a list of replicaset seeds and mongos seeds")); - - if(totalNumberOfMongodServers == 0 && object.servers.length == 1) { - var obj = object.servers[0]; - serverConfig = obj.domain_socket ? - new Server(obj.domain_socket, object.server_options) - : new Server(obj.host, obj.port, object.server_options); - } else if(totalNumberOfMongodServers > 0) { - serverConfig = new ReplSet(object.servers.map(function(serverObj) { - return new Server(serverObj.host, serverObj.port, object.server_options); - }), object.rs_options); - } else if(totalNumberOfMongosServers > 0) { - serverConfig = new Mongos(object.servers.map(function(serverObj) { - return new Server(serverObj.host, serverObj.port, object.server_options); - }), object.mongos_options); - } - - if(serverConfig == null) return callback(new Error("Could not locate any valid servers in initial seed list")); - // Set up all options etc and connect to the database - _finishConnecting(serverConfig, object, options, callback) - } - }); - } -} - -var _setNativeParser = function(db_options) { - if(typeof db_options.native_parser == 'boolean') return db_options.native_parser; - - try { - require('bson').BSONNative.BSON; - return true; - } catch(err) { - return false; - } -} - -var _finishConnecting = function(serverConfig, object, options, callback) { - // Safe settings - var safe = {}; - // Build the safe parameter if needed - if(object.db_options.journal) safe.j = object.db_options.journal; - if(object.db_options.w) safe.w = object.db_options.w; - if(object.db_options.fsync) safe.fsync = object.db_options.fsync; - if(object.db_options.wtimeoutMS) safe.wtimeout = object.db_options.wtimeoutMS; - - // If we have a read Preference set - if(object.db_options.read_preference) { - var readPreference = new ReadPreference(object.db_options.read_preference); - // If we have the tags set up - if(object.db_options.read_preference_tags) - readPreference = new ReadPreference(object.db_options.read_preference, object.db_options.read_preference_tags); - // Add the read preference - object.db_options.readPreference = readPreference; - } - - // No safe mode if no keys - if(Object.keys(safe).length == 0) safe = false; - - // Add the safe object - object.db_options.safe = safe; - - // Set up the db options - var db = new Db(object.dbName, serverConfig, object.db_options); - - // Open the db - db.open(function(err, db){ - if(err == null && object.auth){ - db.authenticate(object.auth.user, object.auth.password, function(err, success){ - if(success){ - callback(null, db); - } else { - callback(err ? err : new Error('Could not authenticate user ' + auth[0]), db); - } - }); - } else { - callback(err, db); - } - }); -} - -/** - * State of the db connection - * @ignore - */ -Object.defineProperty(Db.prototype, "state", { enumerable: true - , get: function () { - return this.serverConfig._serverState; - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(self.options.w != null || typeof self.options.j == 'boolean' || typeof self.options.journal == 'boolean' || typeof self.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.options); - } else if(self.safe.w != null || typeof self.safe.j == 'boolean' || typeof self.safe.journal == 'boolean' || typeof self.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.safe); - } else if(typeof self.safe == "boolean") { - finalOptions = {w: (self.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Legacy support - * - * @ignore - * @api private - */ -exports.connect = Db.connect; -exports.Db = Db; - -/** - * Remove all listeners to the db instance. - * @ignore - * @api private - */ -Db.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("parseError"); - this.removeAllListeners("poolReady"); - this.removeAllListeners("message"); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js deleted file mode 100644 index 572d144653c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js +++ /dev/null @@ -1,213 +0,0 @@ -var Binary = require('bson').Binary, - ObjectID = require('bson').ObjectID; - -/** - * Class for representing a single chunk in GridFS. - * - * @class - * - * @param file {GridStore} The {@link GridStore} object holding this chunk. - * @param mongoObject {object} The mongo object representation of this chunk. - * - * @throws Error when the type of data field for {@link mongoObject} is not - * supported. Currently supported types for data field are instances of - * {@link String}, {@link Array}, {@link Binary} and {@link Binary} - * from the bson module - * - * @see Chunk#buildMongoObject - */ -var Chunk = exports.Chunk = function(file, mongoObject) { - if(!(this instanceof Chunk)) return new Chunk(file, mongoObject); - - this.file = file; - var self = this; - var mongoObjectFinal = mongoObject == null ? {} : mongoObject; - - this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id; - this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n; - this.data = new Binary(); - - if(mongoObjectFinal.data == null) { - } else if(typeof mongoObjectFinal.data == "string") { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data, 'binary', 0); - this.data = new Binary(buffer); - } else if(Array.isArray(mongoObjectFinal.data)) { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data.join(''), 'binary', 0); - this.data = new Binary(buffer); - } else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") { - this.data = mongoObjectFinal.data; - } else if(Buffer.isBuffer(mongoObjectFinal.data)) { - } else { - throw Error("Illegal chunk format"); - } - // Update position - this.internalPosition = 0; -}; - -/** - * Writes a data to this object and advance the read/write head. - * - * @param data {string} the data to write - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.write = function(data, callback) { - this.data.write(data, this.internalPosition); - this.internalPosition = this.data.length(); - if(callback != null) return callback(null, this); - return this; -}; - -/** - * Reads data and advances the read/write head. - * - * @param length {number} The length of data to read. - * - * @return {string} The data read if the given length will not exceed the end of - * the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.read = function(length) { - // Default to full read if no index defined - length = length == null || length == 0 ? this.length() : length; - - if(this.length() - this.internalPosition + 1 >= length) { - var data = this.data.read(this.internalPosition, length); - this.internalPosition = this.internalPosition + length; - return data; - } else { - return ''; - } -}; - -Chunk.prototype.readSlice = function(length) { - if ((this.length() - this.internalPosition) >= length) { - var data = null; - if (this.data.buffer != null) { //Pure BSON - data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length); - } else { //Native BSON - data = new Buffer(length); - length = this.data.readInto(data, this.internalPosition); - } - this.internalPosition = this.internalPosition + length; - return data; - } else { - return null; - } -}; - -/** - * Checks if the read/write head is at the end. - * - * @return {boolean} Whether the read/write head has reached the end of this - * chunk. - */ -Chunk.prototype.eof = function() { - return this.internalPosition == this.length() ? true : false; -}; - -/** - * Reads one character from the data of this chunk and advances the read/write - * head. - * - * @return {string} a single character data read if the the read/write head is - * not at the end of the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.getc = function() { - return this.read(1); -}; - -/** - * Clears the contents of the data in this chunk and resets the read/write head - * to the initial position. - */ -Chunk.prototype.rewind = function() { - this.internalPosition = 0; - this.data = new Binary(); -}; - -/** - * Saves this chunk to the database. Also overwrites existing entries having the - * same id as this chunk. - * - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.save = function(callback) { - var self = this; - - self.file.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) { - if(err) return callback(err); - - if(self.data.length() > 0) { - self.buildMongoObject(function(mongoObject) { - collection.insert(mongoObject, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - } else { - callback(null, self); - } - }); - }); -}; - -/** - * Creates a mongoDB object representation of this chunk. - * - * @param callback {function(Object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this chunk
    - *          'files_id' : , // {number} foreign key to the file collection
    - *          'n' : , // {number} chunk number
    - *          'data' : , // {bson#Binary} the chunk data itself
    - *        }
    - *        
    - * - * @see MongoDB GridFS Chunk Object Structure - */ -Chunk.prototype.buildMongoObject = function(callback) { - var mongoObject = {'_id': this.objectId, - 'files_id': this.file.fileId, - 'n': this.chunkNumber, - 'data': this.data}; - callback(mongoObject); -}; - -/** - * @return {number} the length of the data - */ -Chunk.prototype.length = function() { - return this.data.length(); -}; - -/** - * The position of the read/write head - * @name position - * @lends Chunk# - * @field - */ -Object.defineProperty(Chunk.prototype, "position", { enumerable: true - , get: function () { - return this.internalPosition; - } - , set: function(value) { - this.internalPosition = value; - } -}); - -/** - * The default chunk size - * @constant - */ -Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js deleted file mode 100644 index aa695b723cd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js +++ /dev/null @@ -1,103 +0,0 @@ -var GridStore = require('./gridstore').GridStore, - ObjectID = require('bson').ObjectID; - -/** - * A class representation of a simple Grid interface. - * - * @class Represents the Grid. - * @param {Db} db A database instance to interact with. - * @param {String} [fsName] optional different root collection for GridFS. - * @return {Grid} - */ -function Grid(db, fsName) { - - if(!(this instanceof Grid)) return new Grid(db, fsName); - - this.db = db; - this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName; -} - -/** - * Puts binary data to the grid - * - * Options - * - **_id** {Any}, unique id for this file - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @param {Buffer} data buffer with Binary Data. - * @param {Object} [options] the options for the files. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.put = function(data, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // If root is not defined add our default one - options['root'] = options['root'] == null ? this.fsName : options['root']; - - // Return if we don't have a buffer object as data - if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null); - // Get filename if we are using it - var filename = options['filename'] || null; - // Get id if we are using it - var id = options['_id'] || null; - // Create gridstore - var gridStore = new GridStore(this.db, id, filename, "w", options); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - gridStore.write(data, function(err, result) { - if(err) return callback(err, null); - - gridStore.close(function(err, result) { - if(err) return callback(err, null); - callback(null, result); - }) - }) - }) -} - -/** - * Get binary data to the grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.get = function(id, callback) { - // Create gridstore - var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName}); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - // Return the data - gridStore.read(function(err, data) { - return callback(err, data) - }); - }) -} - -/** - * Delete file from grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.delete = function(id, callback) { - // Create gridstore - GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) { - if(err) return callback(err, false); - return callback(null, true); - }); -} - -exports.Grid = Grid; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js deleted file mode 100644 index e9ddb9727fc..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js +++ /dev/null @@ -1,1466 +0,0 @@ -/** - * @fileOverview GridFS is a tool for MongoDB to store files to the database. - * Because of the restrictions of the object size the database can hold, a - * facility to split a file into several chunks is needed. The {@link GridStore} - * class offers a simplified api to interact with files while managing the - * chunks of split files behind the scenes. More information about GridFS can be - * found here. - */ -var Chunk = require('./chunk').Chunk, - DbCommand = require('../commands/db_command').DbCommand, - ObjectID = require('bson').ObjectID, - Buffer = require('buffer').Buffer, - fs = require('fs'), - util = require('util'), - inherits = util.inherits, - ReadStream = require('./readstream').ReadStream, - Stream = require('stream'); - -var REFERENCE_BY_FILENAME = 0, - REFERENCE_BY_ID = 1; - -/** - * A class representation of a file stored in GridFS. - * - * Modes - * - **"r"** - read only. This is the default mode. - * - **"w"** - write in truncate mode. Existing data will be overwriten. - * - **w+"** - write in edit mode. - * - * Options - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @class Represents the GridStore. - * @param {Db} db A database instance to interact with. - * @param {Any} [id] optional unique id for this file - * @param {String} [filename] optional filename for this file, no unique constrain on the field - * @param {String} mode set the mode for this file. - * @param {Object} options optional properties to specify. - * @return {GridStore} - */ -var GridStore = function GridStore(db, id, filename, mode, options) { - if(!(this instanceof GridStore)) return new GridStore(db, id, filename, mode, options); - - var self = this; - this.db = db; - - // Call stream constructor - if(typeof Stream == 'function') { - Stream.call(this); - } else { - // 0.4.X backward compatibility fix - Stream.Stream.call(this); - } - - // Handle options - if(typeof options === 'undefined') options = {}; - // Handle mode - if(typeof mode === 'undefined') { - mode = filename; - filename = undefined; - } else if(typeof mode == 'object') { - options = mode; - mode = filename; - filename = undefined; - } - - if(id instanceof ObjectID) { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } else if(typeof filename == 'undefined') { - this.referenceBy = REFERENCE_BY_FILENAME; - this.filename = id; - if (mode.indexOf('w') != null) { - this.fileId = new ObjectID(); - } - } else { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } - - // Set up the rest - this.mode = mode == null ? "r" : mode; - this.options = options == null ? {} : options; - this.root = this.options['root'] == null ? exports.GridStore.DEFAULT_ROOT_COLLECTION : this.options['root']; - this.position = 0; - // Set default chunk size - this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize']; -} - -/** - * Code for the streaming capabilities of the gridstore object - * Most code from Aaron heckmanns project https://github.com/aheckmann/gridfs-stream - * Modified to work on the gridstore object itself - * @ignore - */ -if(typeof Stream == 'function') { - GridStore.prototype = { __proto__: Stream.prototype } -} else { - // Node 0.4.X compatibility code - GridStore.prototype = { __proto__: Stream.Stream.prototype } -} - -// Move pipe to _pipe -GridStore.prototype._pipe = GridStore.prototype.pipe; - -/** - * Opens the file from the database and initialize this object. Also creates a - * new one if file does not exist. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an **{Error}** object and the second parameter will be null if an error occured. Otherwise, the first parameter will be null and the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.open = function(callback) { - if( this.mode != "w" && this.mode != "w+" && this.mode != "r"){ - callback(new Error("Illegal mode " + this.mode), null); - return; - } - - var self = this; - - if((self.mode == "w" || self.mode == "w+") && self.db.serverConfig.primary != null) { - // Get files collection - self.collection(function(err, collection) { - if(err) return callback(err); - - // Put index on filename - collection.ensureIndex([['filename', 1]], function(err, index) { - if(err) return callback(err); - - // Get chunk collection - self.chunkCollection(function(err, chunkCollection) { - if(err) return callback(err); - - // Ensure index on chunk collection - chunkCollection.ensureIndex([['files_id', 1], ['n', 1]], function(err, index) { - if(err) return callback(err); - _open(self, callback); - }); - }); - }); - }); - } else { - // Open the gridstore - _open(self, callback); - } -}; - -/** - * Hidding the _open function - * @ignore - * @api private - */ -var _open = function(self, callback) { - self.collection(function(err, collection) { - if(err!==null) { - callback(new Error("at collection: "+err), null); - return; - } - - // Create the query - var query = self.referenceBy == REFERENCE_BY_ID ? {_id:self.fileId} : {filename:self.filename}; - query = null == self.fileId && this.filename == null ? null : query; - - // Fetch the chunks - if(query != null) { - collection.find(query, function(err, cursor) { - if(err) return error(err); - - // Fetch the file - cursor.nextObject(function(err, doc) { - if(err) return error(err); - - // Check if the collection for the files exists otherwise prepare the new one - if(doc != null) { - self.fileId = doc._id; - self.filename = doc.filename; - self.contentType = doc.contentType; - self.internalChunkSize = doc.chunkSize; - self.uploadDate = doc.uploadDate; - self.aliases = doc.aliases; - self.length = doc.length; - self.metadata = doc.metadata; - self.internalMd5 = doc.md5; - } else if (self.mode != 'r') { - self.fileId = self.fileId == null ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - } else { - self.length = 0; - var txtId = self.fileId instanceof ObjectID ? self.fileId.toHexString() : self.fileId; - return error(new Error((self.referenceBy == REFERENCE_BY_ID ? txtId : self.filename) + " does not exist", self)); - } - - // Process the mode of the object - if(self.mode == "r") { - nthChunk(self, 0, function(err, chunk) { - if(err) return error(err); - self.currentChunk = chunk; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - }); - } else { - // Write only mode - self.fileId = null == self.fileId ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - - self.chunkCollection(function(err, collection2) { - if(err) return error(err); - - // No file exists set up write mode - if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - } - }); - - // only pass error to callback once - function error (err) { - if(error.err) return; - callback(error.err = err); - } -}; - -/** - * Stores a file from the file system to the GridFS database. - * - * @param {String|Buffer|FileHandle} file the file to store. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.writeFile = function (file, callback) { - var self = this; - if (typeof file === 'string') { - fs.open(file, 'r', 0666, function (err, fd) { - if(err) return callback(err); - self.writeFile(fd, callback); - }); - return; - } - - self.open(function (err, self) { - if(err) return callback(err); - - fs.fstat(file, function (err, stats) { - if(err) return callback(err); - - var offset = 0; - var index = 0; - var numberOfChunksLeft = Math.min(stats.size / self.chunkSize); - - // Write a chunk - var writeChunk = function() { - fs.read(file, self.chunkSize, offset, 'binary', function(err, data, bytesRead) { - if(err) return callback(err); - - offset = offset + bytesRead; - - // Create a new chunk for the data - var chunk = new Chunk(self, {n:index++}); - chunk.write(data, function(err, chunk) { - if(err) return callback(err); - - chunk.save(function(err, result) { - if(err) return callback(err); - - self.position = self.position + data.length; - - // Point to current chunk - self.currentChunk = chunk; - - if(offset >= stats.size) { - fs.close(file); - self.close(callback); - } else { - return process.nextTick(writeChunk); - } - }); - }); - }); - } - - // Process the first write - process.nextTick(writeChunk); - }); - }); -}; - -/** - * Writes some data. This method will work properly only if initialized with mode - * "w" or "w+". - * - * @param string {string} The data to write. - * @param close {boolean=false} opt_argument Closes this file after writing if - * true. - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - * - * @ignore - * @api private - */ -var writeBuffer = function(self, buffer, close, callback) { - if(typeof close === "function") { callback = close; close = null; } - var finalClose = (close == null) ? false : close; - - if(self.mode[0] != "w") { - callback(new Error((self.referenceBy == REFERENCE_BY_ID ? self.toHexString() : self.filename) + " not opened for writing"), null); - } else { - if(self.currentChunk.position + buffer.length >= self.chunkSize) { - // Write out the current Chunk and then keep writing until we have less data left than a chunkSize left - // to a new chunk (recursively) - var previousChunkNumber = self.currentChunk.chunkNumber; - var leftOverDataSize = self.chunkSize - self.currentChunk.position; - var firstChunkData = buffer.slice(0, leftOverDataSize); - var leftOverData = buffer.slice(leftOverDataSize); - // A list of chunks to write out - var chunksToWrite = [self.currentChunk.write(firstChunkData)]; - // If we have more data left than the chunk size let's keep writing new chunks - while(leftOverData.length >= self.chunkSize) { - // Create a new chunk and write to it - var newChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - var firstChunkData = leftOverData.slice(0, self.chunkSize); - leftOverData = leftOverData.slice(self.chunkSize); - // Update chunk number - previousChunkNumber = previousChunkNumber + 1; - // Write data - newChunk.write(firstChunkData); - // Push chunk to save list - chunksToWrite.push(newChunk); - } - - // Set current chunk with remaining data - self.currentChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - // If we have left over data write it - if(leftOverData.length > 0) self.currentChunk.write(leftOverData); - - // Update the position for the gridstore - self.position = self.position + buffer.length; - // Total number of chunks to write - var numberOfChunksToWrite = chunksToWrite.length; - // Write out all the chunks and then return - for(var i = 0; i < chunksToWrite.length; i++) { - var chunk = chunksToWrite[i]; - chunk.save(function(err, result) { - if(err) return callback(err); - - numberOfChunksToWrite = numberOfChunksToWrite - 1; - - if(numberOfChunksToWrite <= 0) { - return callback(null, self); - } - }) - } - } else { - // Update the position for the gridstore - self.position = self.position + buffer.length; - // We have less data than the chunk size just write it and callback - self.currentChunk.write(buffer); - callback(null, self); - } - } -}; - -/** - * Creates a mongoDB object representation of this object. - * - * @param callback {function(object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this file
    - *          'filename' : , // {string} name for this file
    - *          'contentType' : , // {string} mime type for this file
    - *          'length' : , // {number} size of this file?
    - *          'chunksize' : , // {number} chunk size used by this file
    - *          'uploadDate' : , // {Date}
    - *          'aliases' : , // {array of string}
    - *          'metadata' : , // {string}
    - *        }
    - *        
    - * - * @ignore - * @api private - */ -var buildMongoObject = function(self, callback) { - // // Keeps the final chunk number - // var chunkNumber = 0; - // var previousChunkSize = 0; - // // Get the correct chunk Number, if we have an empty chunk return the previous chunk number - // if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) { - // chunkNumber = self.currentChunk.chunkNumber - 1; - // } else { - // chunkNumber = self.currentChunk.chunkNumber; - // previousChunkSize = self.currentChunk.position; - // } - - // // Calcuate the length - // var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0; - var mongoObject = { - '_id': self.fileId, - 'filename': self.filename, - 'contentType': self.contentType, - 'length': self.position ? self.position : 0, - 'chunkSize': self.chunkSize, - 'uploadDate': self.uploadDate, - 'aliases': self.aliases, - 'metadata': self.metadata - }; - - var md5Command = {filemd5:self.fileId, root:self.root}; - self.db.command(md5Command, function(err, results) { - mongoObject.md5 = results.md5; - callback(mongoObject); - }); -}; - -/** - * Saves this file to the database. This will overwrite the old entry if it - * already exists. This will work properly only if mode was initialized to - * "w" or "w+". - * - * @param {Function} callback this will be called after executing this method. Passes an **{Error}** object to the first parameter and null to the second if an error occured. Otherwise, passes null to the first and a reference to this object to the second. - * @return {null} - * @api public - */ -GridStore.prototype.close = function(callback) { - var self = this; - - if(self.mode[0] == "w") { - if(self.currentChunk != null && self.currentChunk.position > 0) { - self.currentChunk.save(function(err, chunk) { - if(err) return callback(err); - - self.collection(function(err, files) { - if(err) return callback(err); - - // Build the mongo object - if(self.uploadDate != null) { - files.remove({'_id':self.fileId}, {safe:true}, function(err, collection) { - if(err) return callback(err); - - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } else { - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - } - }); - }); - } else { - self.collection(function(err, files) { - if(err) return callback(err); - - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } - } else if(self.mode[0] == "r") { - callback(null, null); - } else { - callback(new Error("Illegal mode " + self.mode), null); - } -}; - -/** - * Gets the nth chunk of this file. - * - * @param chunkNumber {number} The nth chunk to retrieve. - * @param callback {function(*, Chunk|object)} This will be called after - * executing this method. null will be passed to the first parameter while - * a new {@link Chunk} instance will be passed to the second parameter if - * the chunk was found or an empty object {} if not. - * - * @ignore - * @api private - */ -var nthChunk = function(self, chunkNumber, callback) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.find({'files_id':self.fileId, 'n':chunkNumber}, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, chunk) { - if(err) return callback(err); - - var finalChunk = chunk == null ? {} : chunk; - callback(null, new Chunk(self, finalChunk)); - }); - }); - }); -}; - -/** - * - * @ignore - * @api private - */ -GridStore.prototype._nthChunk = function(chunkNumber, callback) { - nthChunk(this, chunkNumber, callback); -} - -/** - * @return {Number} The last chunk number of this file. - * - * @ignore - * @api private - */ -var lastChunkNumber = function(self) { - return Math.floor(self.length/self.chunkSize); -}; - -/** - * Retrieve this file's chunks collection. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.chunkCollection = function(callback) { - this.db.collection((this.root + ".chunks"), callback); -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param callback {function(*, boolean)} This will be called after this method - * executes. Passes null to the first and true to the second argument. - * - * @ignore - * @api private - */ -var deleteChunks = function(self, callback) { - if(self.fileId != null) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err, false); - collection.remove({'files_id':self.fileId}, {safe:true}, function(err, result) { - if(err) return callback(err, false); - callback(null, true); - }); - }); - } else { - callback(null, true); - } -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param {Function} callback this will be called after this method executes. Passes null to the first and true to the second argument. - * @return {null} - * @api public - */ -GridStore.prototype.unlink = function(callback) { - var self = this; - deleteChunks(this, function(err) { - if(err!==null) { - err.message = "at deleteChunks: " + err.message; - return callback(err); - } - - self.collection(function(err, collection) { - if(err!==null) { - err.message = "at collection: " + err.message; - return callback(err); - } - - collection.remove({'_id':self.fileId}, {safe:true}, function(err) { - callback(err, self); - }); - }); - }); -}; - -/** - * Retrieves the file collection associated with this object. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.collection = function(callback) { - this.db.collection(this.root + ".files", callback); -}; - -/** - * Reads the data of this file. - * - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Function} callback This will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.prototype.readlines = function(separator, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - separator = args.length ? args.shift() : "\n"; - - this.read(function(err, data) { - if(err) return callback(err); - - var items = data.toString().split(separator); - items = items.length > 0 ? items.splice(0, items.length - 1) : []; - for(var i = 0; i < items.length; i++) { - items[i] = items[i] + separator; - } - - callback(null, items); - }); -}; - -/** - * Deletes all the chunks of this file in the database if mode was set to "w" or - * "w+" and resets the read/write head to the initial position. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.rewind = function(callback) { - var self = this; - - if(this.currentChunk.chunkNumber != 0) { - if(this.mode[0] == "w") { - deleteChunks(self, function(err, gridStore) { - if(err) return callback(err); - self.currentChunk = new Chunk(self, {'n': 0}); - self.position = 0; - callback(null, self); - }); - } else { - self.currentChunk(0, function(err, chunk) { - if(err) return callback(err); - self.currentChunk = chunk; - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - }); - } - } else { - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - } -}; - -/** - * Retrieves the contents of this file and advances the read/write head. Works with Buffers only. - * - * There are 3 signatures for this method: - * - * (callback) - * (length, callback) - * (length, buffer, callback) - * - * @param {Number} [length] the number of characters to read. Reads all the characters from the read/write head to the EOF if not specified. - * @param {String|Buffer} [buffer] a string to hold temporary data. This is used for storing the string data read so far when recursively calling this method. - * @param {Function} callback this will be called after this method is executed. null will be passed to the first parameter and a string containing the contents of the buffer concatenated with the contents read from this file will be passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.read = function(length, buffer, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - length = args.length ? args.shift() : null; - buffer = args.length ? args.shift() : null; - - // The data is a c-terminated string and thus the length - 1 - var finalLength = length == null ? self.length - self.position : length; - var finalBuffer = buffer == null ? new Buffer(finalLength) : buffer; - // Add a index to buffer to keep track of writing position or apply current index - finalBuffer._index = buffer != null && buffer._index != null ? buffer._index : 0; - - if((self.currentChunk.length() - self.currentChunk.position + finalBuffer._index) >= finalLength) { - var slice = self.currentChunk.readSlice(finalLength - finalBuffer._index); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update internal position - self.position = finalBuffer.length; - // Check if we don't have a file at all - if(finalLength == 0 && finalBuffer.length == 0) return callback(new Error("File does not exist"), null); - // Else return data - callback(null, finalBuffer); - } else { - var slice = self.currentChunk.readSlice(self.currentChunk.length() - self.currentChunk.position); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update index position - finalBuffer._index += slice.length; - - // Load next chunk and read more - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) return callback(err); - - if(chunk.length() > 0) { - self.currentChunk = chunk; - self.read(length, finalBuffer, callback); - } else { - if (finalBuffer._index > 0) { - callback(null, finalBuffer) - } else { - callback(new Error("no chunks found for file, possibly corrupt"), null); - } - } - }); - } -} - -/** - * Retrieves the position of the read/write head of this file. - * - * @param {Function} callback This gets called after this method terminates. null is passed to the first parameter and the position is passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.tell = function(callback) { - callback(null, this.position); -}; - -/** - * Moves the read/write head to a new location. - * - * There are 3 signatures for this method - * - * Seek Location Modes - * - **GridStore.IO_SEEK_SET**, **(default)** set the position from the start of the file. - * - **GridStore.IO_SEEK_CUR**, set the position from the current position in the file. - * - **GridStore.IO_SEEK_END**, set the position from the end of the file. - * - * @param {Number} [position] the position to seek to - * @param {Number} [seekLocation] seek mode. Use one of the Seek Location modes. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.seek = function(position, seekLocation, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - seekLocation = args.length ? args.shift() : null; - - var seekLocationFinal = seekLocation == null ? exports.GridStore.IO_SEEK_SET : seekLocation; - var finalPosition = position; - var targetPosition = 0; - if(seekLocationFinal == exports.GridStore.IO_SEEK_CUR) { - targetPosition = self.position + finalPosition; - } else if(seekLocationFinal == exports.GridStore.IO_SEEK_END) { - targetPosition = self.length + finalPosition; - } else { - targetPosition = finalPosition; - } - - var newChunkNumber = Math.floor(targetPosition/self.chunkSize); - if(newChunkNumber != self.currentChunk.chunkNumber) { - var seekChunk = function() { - nthChunk(self, newChunkNumber, function(err, chunk) { - self.currentChunk = chunk; - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(err, self); - }); - }; - - if(self.mode[0] == 'w') { - self.currentChunk.save(function(err) { - if(err) return callback(err); - seekChunk(); - }); - } else { - seekChunk(); - } - } else { - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(null, self); - } -}; - -/** - * Verify if the file is at EOF. - * - * @return {Boolean} true if the read/write head is at the end of this file. - * @api public - */ -GridStore.prototype.eof = function() { - return this.position == this.length ? true : false; -}; - -/** - * Retrieves a single character from this file. - * - * @param {Function} callback this gets called after this method is executed. Passes null to the first parameter and the character read to the second or null to the second if the read/write head is at the end of the file. - * @return {null} - * @api public - */ -GridStore.prototype.getc = function(callback) { - var self = this; - - if(self.eof()) { - callback(null, null); - } else if(self.currentChunk.eof()) { - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - self.currentChunk = chunk; - self.position = self.position + 1; - callback(err, self.currentChunk.getc()); - }); - } else { - self.position = self.position + 1; - callback(null, self.currentChunk.getc()); - } -}; - -/** - * Writes a string to the file with a newline character appended at the end if - * the given string does not have one. - * - * @param {String} string the string to write. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.puts = function(string, callback) { - var finalString = string.match(/\n$/) == null ? string + "\n" : string; - this.write(finalString, callback); -}; - -/** - * Returns read stream based on this GridStore file - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @param {Boolean} autoclose if true current GridStore will be closed when EOF and 'close' event will be fired - * @return {null} - * @api public - */ -GridStore.prototype.stream = function(autoclose) { - return new ReadStream(autoclose, this); -}; - -/** -* The collection to be used for holding the files and chunks collection. -* -* @classconstant DEFAULT_ROOT_COLLECTION -**/ -GridStore.DEFAULT_ROOT_COLLECTION = 'fs'; - -/** -* Default file mime type -* -* @classconstant DEFAULT_CONTENT_TYPE -**/ -GridStore.DEFAULT_CONTENT_TYPE = 'binary/octet-stream'; - -/** -* Seek mode where the given length is absolute. -* -* @classconstant IO_SEEK_SET -**/ -GridStore.IO_SEEK_SET = 0; - -/** -* Seek mode where the given length is an offset to the current read/write head. -* -* @classconstant IO_SEEK_CUR -**/ -GridStore.IO_SEEK_CUR = 1; - -/** -* Seek mode where the given length is an offset to the end of the file. -* -* @classconstant IO_SEEK_END -**/ -GridStore.IO_SEEK_END = 2; - -/** - * Checks if a file exists in the database. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file to look for. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes true to the second if the file exists and false otherwise. - * @return {null} - * @api public - */ -GridStore.exist = function(db, fileIdObject, rootCollection, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - - // Fetch collection - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - db.collection(rootCollectionFinal + ".files", function(err, collection) { - if(err) return callback(err); - - // Build query - var query = (typeof fileIdObject == 'string' || Object.prototype.toString.call(fileIdObject) == '[object RegExp]' ) - ? {'filename':fileIdObject} - : {'_id':fileIdObject}; // Attempt to locate file - - collection.find(query, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, item) { - if(err) return callback(err); - callback(null, item == null ? false : true); - }); - }); - }); -}; - -/** - * Gets the list of files stored in the GridFS. - * - * @param {Db} db the database to query. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes an array of strings containing the names of the files. - * @return {null} - * @api public - */ -GridStore.list = function(db, rootCollection, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure we have correct values - if(rootCollection != null && typeof rootCollection == 'object') { - options = rootCollection; - rootCollection = null; - } - - // Check if we are returning by id not filename - var byId = options['id'] != null ? options['id'] : false; - // Fetch item - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - var items = []; - db.collection((rootCollectionFinal + ".files"), function(err, collection) { - if(err) return callback(err); - - collection.find(function(err, cursor) { - if(err) return callback(err); - - cursor.each(function(err, item) { - if(item != null) { - items.push(byId ? item._id : item.filename); - } else { - callback(err, items); - } - }); - }); - }); -}; - -/** - * Reads the contents of a file. - * - * This method has the following signatures - * - * (db, name, callback) - * (db, name, length, callback) - * (db, name, length, offset, callback) - * (db, name, length, offset, options, callback) - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {Number} [length] the size of data to read. - * @param {Number} [offset] the offset from the head of the file of which to start reading from. - * @param {Object} [options] the options for the file. - * @param {Function} callback this will be called after this method executes. A string with an error message will be passed to the first parameter when the length and offset combination exceeds the length of the file while an Error object will be passed if other forms of error occured, otherwise, a string is passed. The second parameter will contain the data read if successful or null if an error occured. - * @return {null} - * @api public - */ -GridStore.read = function(db, name, length, offset, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - length = args.length ? args.shift() : null; - offset = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - // Make sure we are not reading out of bounds - if(offset && offset >= gridStore.length) return callback("offset larger than size of file", null); - if(length && length > gridStore.length) return callback("length is larger than the size of the file", null); - if(offset && length && (offset + length) > gridStore.length) return callback("offset and length is larger than the size of the file", null); - - if(offset != null) { - gridStore.seek(offset, function(err, gridStore) { - if(err) return callback(err); - gridStore.read(length, callback); - }); - } else { - gridStore.read(length, callback); - } - }); -}; - -/** - * Reads the data of this file. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Object} [options] file options. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.readlines = function(db, name, separator, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - separator = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - var finalSeperator = separator == null ? "\n" : separator; - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - gridStore.readlines(finalSeperator, callback); - }); -}; - -/** - * Deletes the chunks and metadata information of a file from GridFS. - * - * @param {Db} db the database to interact with. - * @param {String|Array} names the name/names of the files to delete. - * @param {Object} [options] the options for the files. - * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.unlink = function(db, names, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : null; - - if(names.constructor == Array) { - var tc = 0; - for(var i = 0; i < names.length; i++) { - ++tc; - self.unlink(db, names[i], function(result) { - if(--tc == 0) { - callback(null, self); - } - }); - } - } else { - new GridStore(db, names, "w", options).open(function(err, gridStore) { - if(err) return callback(err); - deleteChunks(gridStore, function(err, result) { - if(err) return callback(err); - gridStore.collection(function(err, collection) { - if(err) return callback(err); - collection.remove({'_id':gridStore.fileId}, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - }); - }); - } -}; - -/** - * Returns the current chunksize of the file. - * - * @field chunkSize - * @type {Number} - * @getter - * @setter - * @property return number of bytes in the current chunkSize. - */ -Object.defineProperty(GridStore.prototype, "chunkSize", { enumerable: true - , get: function () { - return this.internalChunkSize; - } - , set: function(value) { - if(!(this.mode[0] == "w" && this.position == 0 && this.uploadDate == null)) { - this.internalChunkSize = this.internalChunkSize; - } else { - this.internalChunkSize = value; - } - } -}); - -/** - * The md5 checksum for this file. - * - * @field md5 - * @type {Number} - * @getter - * @setter - * @property return this files md5 checksum. - */ -Object.defineProperty(GridStore.prototype, "md5", { enumerable: true - , get: function () { - return this.internalMd5; - } -}); - -/** - * GridStore Streaming methods - * Handles the correct return of the writeable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "writable", { enumerable: true - , get: function () { - if(this._writeable == null) { - this._writeable = this.mode != null && this.mode.indexOf("w") != -1; - } - // Return the _writeable - return this._writeable; - } - , set: function(value) { - this._writeable = value; - } -}); - -/** - * Handles the correct return of the readable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "readable", { enumerable: true - , get: function () { - if(this._readable == null) { - this._readable = this.mode != null && this.mode.indexOf("r") != -1; - } - return this._readable; - } - , set: function(value) { - this._readable = value; - } -}); - -GridStore.prototype.paused; - -/** - * Handles the correct setting of encoding for the stream - * @ignore - */ -GridStore.prototype.setEncoding = fs.ReadStream.prototype.setEncoding; - -/** - * Handles the end events - * @ignore - */ -GridStore.prototype.end = function end(data) { - var self = this; - // allow queued data to write before closing - if(!this.writable) return; - this.writable = false; - - if(data) { - this._q.push(data); - } - - this.on('drain', function () { - self.close(function (err) { - if (err) return _error(self, err); - self.emit('close'); - }); - }); - - _flush(self); -} - -/** - * Handles the normal writes to gridstore - * @ignore - */ -var _writeNormal = function(self, data, close, callback) { - // If we have a buffer write it using the writeBuffer method - if(Buffer.isBuffer(data)) { - return writeBuffer(self, data, close, callback); - } else { - // Wrap the string in a buffer and write - return writeBuffer(self, new Buffer(data, 'binary'), close, callback); - } -} - -/** - * Writes some data. This method will work properly only if initialized with mode "w" or "w+". - * - * @param {String|Buffer} data the data to write. - * @param {Boolean} [close] closes this file after writing if set to true. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.write = function write(data, close, callback) { - // If it's a normal write delegate the call - if(typeof close == 'function' || typeof callback == 'function') { - return _writeNormal(this, data, close, callback); - } - - // Otherwise it's a stream write - var self = this; - if (!this.writable) { - throw new Error('GridWriteStream is not writable'); - } - - // queue data until we open. - if (!this._opened) { - // Set up a queue to save data until gridstore object is ready - this._q = []; - _openStream(self); - this._q.push(data); - return false; - } - - // Push data to queue - this._q.push(data); - _flush(this); - // Return write successful - return true; -} - -/** - * Handles the destroy part of a stream - * @ignore - */ -GridStore.prototype.destroy = function destroy() { - // close and do not emit any more events. queued data is not sent. - if(!this.writable) return; - this.readable = false; - if(this.writable) { - this.writable = false; - this._q.length = 0; - this.emit('close'); - } -} - -/** - * Handles the destroySoon part of a stream - * @ignore - */ -GridStore.prototype.destroySoon = function destroySoon() { - // as soon as write queue is drained, destroy. - // may call destroy immediately if no data is queued. - if(!this._q.length) { - return this.destroy(); - } - this._destroying = true; -} - -/** - * Handles the pipe part of the stream - * @ignore - */ -GridStore.prototype.pipe = function(destination, options) { - var self = this; - // Open the gridstore - this.open(function(err, result) { - if(err) _errorRead(self, err); - if(!self.readable) return; - // Set up the pipe - self._pipe(destination, options); - // Emit the stream is open - self.emit('open'); - // Read from the stream - _read(self); - }) -} - -/** - * Internal module methods - * @ignore - */ -var _read = function _read(self) { - if (!self.readable || self.paused || self.reading) { - return; - } - - self.reading = true; - var stream = self._stream = self.stream(); - stream.paused = self.paused; - - stream.on('data', function (data) { - if (self._decoder) { - var str = self._decoder.write(data); - if (str.length) self.emit('data', str); - } else { - self.emit('data', data); - } - }); - - stream.on('end', function (data) { - self.emit('end', data); - }); - - stream.on('error', function (data) { - _errorRead(self, data); - }); - - stream.on('close', function (data) { - self.emit('close', data); - }); - - self.pause = function () { - // native doesn't always pause. - // bypass its pause() method to hack it - self.paused = stream.paused = true; - } - - self.resume = function () { - if(!self.paused) return; - - self.paused = false; - stream.resume(); - self.readable = stream.readable; - } - - self.destroy = function () { - self.readable = false; - stream.destroy(); - } -} - -/** - * pause - * @ignore - */ -GridStore.prototype.pause = function pause () { - // Overridden when the GridStore opens. - this.paused = true; -} - -/** - * resume - * @ignore - */ -GridStore.prototype.resume = function resume () { - // Overridden when the GridStore opens. - this.paused = false; -} - -/** - * Internal module methods - * @ignore - */ -var _flush = function _flush(self, _force) { - if (!self._opened) return; - if (!_force && self._flushing) return; - self._flushing = true; - - // write the entire q to gridfs - if (!self._q.length) { - self._flushing = false; - self.emit('drain'); - - if(self._destroying) { - self.destroy(); - } - return; - } - - self.write(self._q.shift(), function (err, store) { - if (err) return _error(self, err); - self.emit('progress', store.position); - _flush(self, true); - }); -} - -var _openStream = function _openStream (self) { - if(self._opening == true) return; - self._opening = true; - - // Open the store - self.open(function (err, gridstore) { - if (err) return _error(self, err); - self._opened = true; - self.emit('open'); - _flush(self); - }); -} - -var _error = function _error(self, err) { - self.destroy(); - self.emit('error', err); -} - -var _errorRead = function _errorRead (self, err) { - self.readable = false; - self.emit('error', err); -} - -/** - * @ignore - * @api private - */ -exports.GridStore = GridStore; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js deleted file mode 100644 index ebb09bd8c8a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js +++ /dev/null @@ -1,188 +0,0 @@ -var Stream = require('stream').Stream, - util = require('util'); - -/** - * ReadStream - * - * Returns a stream interface for the **file**. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @class Represents a GridFS File Stream. - * @param {Boolean} autoclose automatically close file when the stream reaches the end. - * @param {GridStore} cursor a cursor object that the stream wraps. - * @return {ReadStream} - */ -function ReadStream(autoclose, gstore) { - if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore); - Stream.call(this); - - this.autoclose = !!autoclose; - this.gstore = gstore; - - this.finalLength = gstore.length - gstore.position; - this.completedLength = 0; - this.currentChunkNumber = gstore.currentChunk.chunkNumber; - - this.paused = false; - this.readable = true; - this.pendingChunk = null; - this.executing = false; - - // Calculate the number of chunks - this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize); - - // This seek start position inside the current chunk - this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize); - - var self = this; - process.nextTick(function() { - self._execute(); - }); -}; - -/** - * Inherit from Stream - * @ignore - * @api private - */ -ReadStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -ReadStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -ReadStream.prototype.paused; - -/** - * @ignore - * @api private - */ -ReadStream.prototype._execute = function() { - if(this.paused === true || this.readable === false) { - return; - } - - var gstore = this.gstore; - var self = this; - // Set that we are executing - this.executing = true; - - var last = false; - var toRead = 0; - - if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) { - self.executing = false; - last = true; - } - - // Data setup - var data = null; - - // Read a slice (with seek set if none) - if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition); - this.seekStartPosition = 0; - } else { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length()); - } - - // Return the data - if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) { - self.currentChunkNumber = self.currentChunkNumber + 1; - self.completedLength += data.length; - self.pendingChunk = null; - self.emit("data", data); - } - - if(last === true) { - self.readable = false; - self.emit("end"); - - if(self.autoclose === true) { - if(gstore.mode[0] == "w") { - gstore.close(function(err, doc) { - if (err) { - self.emit("error", err); - return; - } - self.readable = false; - self.emit("close", doc); - }); - } else { - self.readable = false; - self.emit("close"); - } - } - } else { - gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) { - self.readable = false; - self.emit("error", err); - self.executing = false; - return; - } - - self.pendingChunk = chunk; - if(self.paused === true) { - self.executing = false; - return; - } - - gstore.currentChunk = self.pendingChunk; - self._execute(); - }); - } -}; - -/** - * Pauses this stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.pause = function() { - if(!this.executing) { - this.paused = true; - } -}; - -/** - * Destroys the stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.destroy = function() { - this.readable = false; - // Emit close event - this.emit("close"); -}; - -/** - * Resumes this stream. - * - * @ignore - * @api public - */ -ReadStream.prototype.resume = function() { - if(this.paused === false || !this.readable) { - return; - } - - this.paused = false; - var self = this; - process.nextTick(function() { - self._execute(); - }); -}; - -exports.ReadStream = ReadStream; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js deleted file mode 100644 index 6a2b72759dc..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js +++ /dev/null @@ -1,69 +0,0 @@ -try { - exports.BSONPure = require('bson').BSONPure; - exports.BSONNative = require('bson').BSONNative; -} catch(err) { - // do nothing -} - -[ 'commands/base_command' - , 'admin' - , 'collection' - , 'connection/read_preference' - , 'connection/connection' - , 'connection/server' - , 'connection/mongos' - , 'connection/repl_set' - , 'mongo_client' - , 'cursor' - , 'db' - , 'mongo_client' - , 'gridfs/grid' - , 'gridfs/chunk' - , 'gridfs/gridstore'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } - - // backwards compat - exports.ReplSetServers = exports.ReplSet; - - // Add BSON Classes - exports.Binary = require('bson').Binary; - exports.Code = require('bson').Code; - exports.DBRef = require('bson').DBRef; - exports.Double = require('bson').Double; - exports.Long = require('bson').Long; - exports.MinKey = require('bson').MinKey; - exports.MaxKey = require('bson').MaxKey; - exports.ObjectID = require('bson').ObjectID; - exports.Symbol = require('bson').Symbol; - exports.Timestamp = require('bson').Timestamp; - - // Add BSON Parser - exports.BSON = require('bson').BSONPure.BSON; - -}); - -// Get the Db object -var Db = require('./db').Db; -// Set up the connect function -var connect = Db.connect; -var obj = connect; -// Map all values to the exports value -for(var name in exports) { - obj[name] = exports[name]; -} - -// Add the pure and native backward compatible functions -exports.pure = exports.native = function() { - return obj; -} - -// Map all values to the exports value -for(var name in exports) { - connect[name] = exports[name]; -} - -// Set our exports to be the connect function -module.exports = connect; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js deleted file mode 100644 index f1f3a8da62b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js +++ /dev/null @@ -1,116 +0,0 @@ -var Db = require('./db').Db; - -/** - * Create a new MongoClient instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a MongoClient - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function MongoClient(serverConfig, options) { - options = options == null ? {} : options; - // If no write concern is set set the default to w:1 - if(options != null && !options.journal && !options.w && !options.fsync) { - options.w = 1; - } - - // The internal db instance we are wrapping - this._db = new Db('test', serverConfig, options); -} - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the connected mongoclient or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.open = function(callback) { - // Self reference - var self = this; - - this._db.open(function(err, db) { - if(err) return callback(err, null); - callback(null, self); - }) -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the close method or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.close = function(callback) { - this._db.close(callback); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -MongoClient.prototype.db = function(dbName) { - return this._db.db(dbName); -} - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.connect = function(url, options, callback) { - if(typeof options == 'function') { - callback = options; - options = {}; - } - - Db.connect(url, options, function(err, db) { - if(err) return callback(err, null); - - if(db.options !== null && !db.options.safe && !db.options.journal - && !db.options.w && !db.options.fsync && typeof db.options.w != 'number' - && (db.options.safe == false && url.indexOf("safe=") == -1)) { - db.options.w = 1; - } - - // Return the db - callback(null, db); - }); -} - -exports.MongoClient = MongoClient; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js deleted file mode 100644 index b129dc65e28..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js +++ /dev/null @@ -1,140 +0,0 @@ -var Long = require('bson').Long; - -/** - Reply message from mongo db -**/ -var MongoReply = exports.MongoReply = function() { - this.documents = []; - this.index = 0; -}; - -MongoReply.prototype.parseHeader = function(binary_reply, bson) { - // Unpack the standard header first - this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the request id for this reply - this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the id of the request that triggered the response - this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // Skip op-code field - this.index = this.index + 4 + 4; - // Unpack the reply message - this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the cursor id (a 64 bit long integer) - var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - this.cursorId = new Long(low_bits, high_bits); - // Unpack the starting from - this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the number of objects returned - this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; -} - -MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) { - raw = raw == null ? false : raw; - // Just set a doc limit for deserializing - var docLimitSize = 1024*20; - - // If our message length is very long, let's switch to process.nextTick for messages - if(this.messageLength > docLimitSize) { - var batchSize = this.numberReturned; - this.documents = new Array(this.numberReturned); - - // Just walk down until we get a positive number >= 1 - for(var i = 50; i > 0; i--) { - if((this.numberReturned/i) >= 1) { - batchSize = i; - break; - } - } - - // Actual main creator of the processFunction setting internal state to control the flow - var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) { - var object_index = 0; - // Internal loop process that will use nextTick to ensure we yield some time - var processFunction = function() { - // Adjust batchSize if we have less results left than batchsize - if((_numberReturned - object_index) < _batchSize) { - _batchSize = _numberReturned - object_index; - } - - // If raw just process the entries - if(raw) { - // Iterate over the batch - for(var i = 0; i < _batchSize; i++) { - // Are we done ? - if(object_index <= _numberReturned) { - // Read the size of the bson object - var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - _self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize); - // Adjust binary index to point to next block of binary bson data - _self.index = _self.index + bsonObjectSize; - // Update number of docs parsed - object_index = object_index + 1; - } - } - } else { - try { - // Parse documents - _self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index); - // Adjust index - object_index = object_index + _batchSize; - } catch (err) { - return callback(err); - } - } - - // If we hav more documents process NextTick - if(object_index < _numberReturned) { - process.nextTick(processFunction); - } else { - callback(null); - } - } - - // Return the process function - return processFunction; - }(this, binary_reply, batchSize, this.numberReturned)(); - } else { - try { - // Let's unpack all the bson documents, deserialize them and store them - for(var object_index = 0; object_index < this.numberReturned; object_index++) { - // Read the size of the bson object - var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - if(raw) { - // Deserialize the object and add to the documents array - this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize)); - } else { - // Deserialize the object and add to the documents array - this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize))); - } - // Adjust binary index to point to next block of binary bson data - this.index = this.index + bsonObjectSize; - } - } catch(err) { - return callback(err); - } - - // No error return - callback(null); - } -} - -MongoReply.prototype.is_error = function(){ - if(this.documents.length == 1) { - return this.documents[0].ok == 1 ? false : true; - } - return false; -}; - -MongoReply.prototype.error_message = function() { - return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js deleted file mode 100644 index a67aca5172f..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Sort functions, Normalize and prepare sort parameters - */ -var formatSortValue = exports.formatSortValue = function(sortDirection) { - var value = ("" + sortDirection).toLowerCase(); - - switch (value) { - case 'ascending': - case 'asc': - case '1': - return 1; - case 'descending': - case 'desc': - case '-1': - return -1; - default: - throw new Error("Illegal sort clause, must be of the form " - + "[['field1', '(ascending|descending)'], " - + "['field2', '(ascending|descending)']]"); - } -}; - -var formattedOrderClause = exports.formattedOrderClause = function(sortValue) { - var orderBy = {}; - - if (Array.isArray(sortValue)) { - for(var i = 0; i < sortValue.length; i++) { - if(sortValue[i].constructor == String) { - orderBy[sortValue[i]] = 1; - } else { - orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]); - } - } - } else if(Object.prototype.toString.call(sortValue) === '[object Object]') { - orderBy = sortValue; - } else if (sortValue.constructor == String) { - orderBy[sortValue] = 1; - } else { - throw new Error("Illegal sort clause, must be of the form " + - "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"); - } - - return orderBy; -}; - -exports.encodeInt = function(value) { - var buffer = new Buffer(4); - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = value & 0xff; - return buffer; -} - -exports.encodeIntInPlace = function(value, buffer, index) { - buffer[index + 3] = (value >> 24) & 0xff; - buffer[index + 2] = (value >> 16) & 0xff; - buffer[index + 1] = (value >> 8) & 0xff; - buffer[index] = value & 0xff; -} - -exports.encodeCString = function(string) { - var buf = new Buffer(string, 'utf8'); - return [buf, new Buffer([0])]; -} - -exports.decodeUInt32 = function(array, index) { - return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24; -} - -// Decode the int -exports.decodeUInt8 = function(array, index) { - return array[index]; -} - -/** - * Context insensitive type checks - */ - -var toString = Object.prototype.toString; - -exports.isObject = function (arg) { - return '[object Object]' == toString.call(arg) -} - -exports.isArray = function (arg) { - return Array.isArray(arg) || - 'object' == typeof arg && '[object Array]' == toString.call(arg) -} - -exports.isDate = function (arg) { - return 'object' == typeof arg && '[object Date]' == toString.call(arg) -} - -exports.isRegExp = function (arg) { - return 'object' == typeof arg && '[object RegExp]' == toString.call(arg) -} - -/** - * Wrap a Mongo error document in an Error instance - * @ignore - * @api private - */ -exports.toError = function(error) { - if (error instanceof Error) return error; - - var msg = error.err || error.errmsg || error; - var e = new Error(msg); - e.name = 'MongoError'; - - // Get all object keys - var keys = typeof error == 'object' - ? Object.keys(error) - : []; - - for(var i = 0; i < keys.length; i++) { - e[keys[i]] = error[keys[i]]; - } - - return e; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile deleted file mode 100644 index 2ca559209c3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit - -all: clean node_gyp - -test: clean node_gyp - npm test - -node_gyp: clean - node-gyp configure build - -clean: - node-gyp clean - -.PHONY: all diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md deleted file mode 100644 index 73892e2d19a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md +++ /dev/null @@ -1 +0,0 @@ -A JS/C++ Bson parser for node, used in the MongoDB Native driver \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js deleted file mode 100644 index 45a11115484..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js +++ /dev/null @@ -1,130 +0,0 @@ -// var BSON = require('../../lib/mongodb').BSONNative.BSON, -// ObjectID = require('../../lib/mongodb').BSONNative.ObjectID, -// Code = require('../../lib/mongodb').BSONNative.Code, -// Long = require('../../lib/mongodb').BSONNative.Long, -// Binary = require('../../lib/mongodb').BSONNative.Binary, -// debug = require('util').debug, -// inspect = require('util').inspect, -// -// Long = require('../../lib/mongodb').Long, -// ObjectID = require('../../lib/mongodb').ObjectID, -// Binary = require('../../lib/mongodb').Binary, -// Code = require('../../lib/mongodb').Code, -// DBRef = require('../../lib/mongodb').DBRef, -// Symbol = require('../../lib/mongodb').Symbol, -// Double = require('../../lib/mongodb').Double, -// MaxKey = require('../../lib/mongodb').MaxKey, -// MinKey = require('../../lib/mongodb').MinKey, -// Timestamp = require('../../lib/mongodb').Timestamp; - - -// var BSON = require('../../lib/mongodb').BSONPure.BSON, -// ObjectID = require('../../lib/mongodb').BSONPure.ObjectID, -// Code = require('../../lib/mongodb').BSONPure.Code, -// Long = require('../../lib/mongodb').BSONPure.Long, -// Binary = require('../../lib/mongodb').BSONPure.Binary; - -var BSON = require('../lib/bson').BSONNative.BSON, - Long = require('../lib/bson').Long, - ObjectID = require('../lib/bson').ObjectID, - Binary = require('../lib/bson').Binary, - Code = require('../lib/bson').Code, - DBRef = require('../lib/bson').DBRef, - Symbol = require('../lib/bson').Symbol, - Double = require('../lib/bson').Double, - MaxKey = require('../lib/bson').MaxKey, - MinKey = require('../lib/bson').MinKey, - Timestamp = require('../lib/bson').Timestamp; - - // console.dir(require('../lib/bson')) - -var COUNT = 1000; -var COUNT = 100; - -var object = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - date: new Date(), - double: new Double(1.4), - id: new ObjectID(), - min: new MinKey(), - max: new MaxKey(), - symbol: new Symbol('hello'), - long: Long.fromNumber(100), - bin: new Binary(new Buffer(100)), - - subObject: { - moreText: "Bacon ipsum dolor sit amet cow pork belly rump ribeye pastrami andouille. Tail hamburger pork belly, drumstick flank salami t-bone sirloin pork chop ribeye ham chuck pork loin shankle. Ham fatback pork swine, sirloin shankle short loin andouille shank sausage meatloaf drumstick. Pig chicken cow bresaola, pork loin jerky meatball tenderloin brisket strip steak jowl spare ribs. Biltong sirloin pork belly boudin, bacon pastrami rump chicken. Jowl rump fatback, biltong bacon t-bone turkey. Turkey pork loin boudin, tenderloin jerky beef ribs pastrami spare ribs biltong pork chop beef.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly boudin shoulder ribeye pork chop brisket biltong short ribs. Salami beef pork belly, t-bone sirloin meatloaf tail jowl spare ribs. Sirloin biltong bresaola cow turkey. Biltong fatback meatball, bresaola tail shankle turkey pancetta ham ribeye flank bacon jerky pork chop. Boudin sirloin shoulder, salami swine flank jerky t-bone pork chop pork beef tongue. Bresaola ribeye jerky andouille. Ribeye ground round sausage biltong beef ribs chuck, shank hamburger chicken short ribs spare ribs tenderloin meatloaf pork loin." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string", - code: new Code("function() {}", {i:1}) -} - -// Number of objects -var numberOfObjects = 10000; -var bson = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -console.log("---------------------- 1") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - objectBSON = bson.serialize(object, null, true) -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -console.log("---------------------- 2") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - bson.deserialize(objectBSON); -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -// // Buffer With copies of the objectBSON -// var data = new Buffer(objectBSON.length * numberOfObjects); -// var index = 0; -// -// // Copy the buffer 1000 times to create a strea m of objects -// for(var i = 0; i < numberOfObjects; i++) { -// // Copy data -// objectBSON.copy(data, index); -// // Adjust index -// index = index + objectBSON.length; -// } -// -// // console.log("-----------------------------------------------------------------------------------") -// // console.dir(objectBSON) -// -// var x, start, end, j -// var objectBSON, objectJSON -// -// // Allocate the return array (avoid concatinating everything) -// var results = new Array(numberOfObjects); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// // var objects = BSON.deserializeStream(data, 0, numberOfObjects); -// // console.log("----------------------------------------------------------------------------------- 0") -// // var objects = BSON.deserialize(data); -// // console.log("----------------------------------------------------------------------------------- 1") -// // console.dir(objects) -// -// for (j=COUNT; --j>=0; ) { -// var nextIndex = BSON.deserializeStream(data, 0, numberOfObjects, results, 0); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectBSON.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectBSON.length)/1024)); -// -// // console.dir(nextIndex) -// // console.dir(results) - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp deleted file mode 100644 index 42445d325d7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp +++ /dev/null @@ -1,17 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'bson', - 'sources': [ 'ext/bson.cc' ], - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile deleted file mode 100644 index f035c632ab3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile +++ /dev/null @@ -1,359 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= ./gyp-mac-tool flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) -ARFLAGS.target ?= crs - -# N.B.: the logic of which commands to run should match the computation done -# in gyp's make.py where ARFLAGS.host etc. is computed. -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar -ARFLAGS.host := crs - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_objc = CXX($(TOOLSET)) $@ -cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< - -quiet_cmd_objcxx = CXX($(TOOLSET)) $@ -cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< - -# Commands for precompiled header files. -quiet_cmd_pch_c = CXX($(TOOLSET)) $@ -cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< -quiet_cmd_pch_cc = CXX($(TOOLSET)) $@ -cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< -quiet_cmd_pch_m = CXX($(TOOLSET)) $@ -cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< -quiet_cmd_pch_mm = CXX($(TOOLSET)) $@ -cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< - -# gyp-mac-tool is written next to the root Makefile by gyp. -# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd -# already. -quiet_cmd_mac_tool = MACTOOL $(4) $< -cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" - -quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ -cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) - -quiet_cmd_infoplist = INFOPLIST $@ -cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@") - -quiet_cmd_alink = LIBTOOL-STATIC $@ -cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool -static -o $@ $(filter %.o,$^) - -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) - -# TODO(thakis): Find out and document the difference between shared_library and -# loadable_module on mac. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) - -# TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass -# -bundle -single_module here (for osmesa.so). -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 2,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.m FORCE_DO_CMD - @$(call do_cmd,objc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.mm FORCE_DO_CMD - @$(call do_cmd,objcxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bson.target.mk)))),) - include bson.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /Users/oroce/.node-gyp/0.8.16/tools/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/Users/oroce/developing/nodejs/countly-server/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi -I/usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/oroce/.node-gyp/0.8.16/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/oroce/.node-gyp/0.8.16" "-Dmodule_root_dir=/Users/oroce/developing/nodejs/countly-server/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../../../../.node-gyp/0.8.16/common.gypi $(srcdir)/../../../../../../../../../../../../../../../usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d deleted file mode 100644 index 8c45ea16ee3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bson.node := ./gyp-mac-tool flock ./Release/linker.lock g++ -shared -Wl,-search_paths_first -mmacosx-version-min=10.5 -arch x86_64 -L./Release -install_name @loader_path/bson.node -o Release/bson.node Release/obj.target/bson/ext/bson.o -undefined dynamic_lookup diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d deleted file mode 100644 index 390e1cc423d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d +++ /dev/null @@ -1,38 +0,0 @@ -cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_DARWIN_USE_64_BIT_INODE=1' '-DBUILDING_NODE_EXTENSION' -I/Users/oroce/.node-gyp/0.8.16/src -I/Users/oroce/.node-gyp/0.8.16/deps/uv/include -I/Users/oroce/.node-gyp/0.8.16/deps/v8/include -Os -gdwarf-2 -mmacosx-version-min=10.5 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-rtti -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc -Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \ - /Users/oroce/.node-gyp/0.8.16/deps/v8/include/v8.h \ - /Users/oroce/.node-gyp/0.8.16/deps/v8/include/v8stdint.h \ - /Users/oroce/.node-gyp/0.8.16/src/node.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/ares.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/ares_version.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/uv-unix.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/ngx-queue.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/ev.h \ - /Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/eio.h \ - /Users/oroce/.node-gyp/0.8.16/src/node_object_wrap.h \ - /Users/oroce/.node-gyp/0.8.16/src/node.h \ - /Users/oroce/.node-gyp/0.8.16/src/ev-emul.h \ - /Users/oroce/.node-gyp/0.8.16/src/eio-emul.h \ - /Users/oroce/.node-gyp/0.8.16/src/node_version.h \ - /Users/oroce/.node-gyp/0.8.16/src/node_buffer.h ../ext/bson.h \ - /Users/oroce/.node-gyp/0.8.16/src/node_object_wrap.h -../ext/bson.cc: -/Users/oroce/.node-gyp/0.8.16/deps/v8/include/v8.h: -/Users/oroce/.node-gyp/0.8.16/deps/v8/include/v8stdint.h: -/Users/oroce/.node-gyp/0.8.16/src/node.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/ares.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/ares_version.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/uv-unix.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/ngx-queue.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/ev.h: -/Users/oroce/.node-gyp/0.8.16/deps/uv/include/uv-private/eio.h: -/Users/oroce/.node-gyp/0.8.16/src/node_object_wrap.h: -/Users/oroce/.node-gyp/0.8.16/src/node.h: -/Users/oroce/.node-gyp/0.8.16/src/ev-emul.h: -/Users/oroce/.node-gyp/0.8.16/src/eio-emul.h: -/Users/oroce/.node-gyp/0.8.16/src/node_version.h: -/Users/oroce/.node-gyp/0.8.16/src/node_buffer.h: -../ext/bson.h: -/Users/oroce/.node-gyp/0.8.16/src/node_object_wrap.h: diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node deleted file mode 100755 index 5a54b7f005d..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o deleted file mode 100644 index 0b03634d8c4..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile deleted file mode 100644 index 90bf8247b39..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) bson diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk deleted file mode 100644 index ab6ae513a65..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk +++ /dev/null @@ -1,147 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bson -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-D_DARWIN_USE_64_BIT_INODE=1' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -Os \ - -gdwarf-2 \ - -mmacosx-version-min=10.5 \ - -arch x86_64 \ - -Wall \ - -Wendif-labels \ - -W \ - -Wno-unused-parameter - -# Flags passed to only C files. -CFLAGS_C_Debug := \ - -fno-strict-aliasing - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti \ - -fno-threadsafe-statics \ - -fno-strict-aliasing - -# Flags passed to only ObjC files. -CFLAGS_OBJC_Debug := - -# Flags passed to only ObjC++ files. -CFLAGS_OBJCC_Debug := - -INCS_Debug := \ - -I/Users/oroce/.node-gyp/0.8.16/src \ - -I/Users/oroce/.node-gyp/0.8.16/deps/uv/include \ - -I/Users/oroce/.node-gyp/0.8.16/deps/v8/include - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-D_DARWIN_USE_64_BIT_INODE=1' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Os \ - -gdwarf-2 \ - -mmacosx-version-min=10.5 \ - -arch x86_64 \ - -Wall \ - -Wendif-labels \ - -W \ - -Wno-unused-parameter - -# Flags passed to only C files. -CFLAGS_C_Release := \ - -fno-strict-aliasing - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti \ - -fno-threadsafe-statics \ - -fno-strict-aliasing - -# Flags passed to only ObjC files. -CFLAGS_OBJC_Release := - -# Flags passed to only ObjC++ files. -CFLAGS_OBJCC_Release := - -INCS_Release := \ - -I/Users/oroce/.node-gyp/0.8.16/src \ - -I/Users/oroce/.node-gyp/0.8.16/deps/uv/include \ - -I/Users/oroce/.node-gyp/0.8.16/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/ext/bson.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) -$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE)) -$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -Wl,-search_paths_first \ - -mmacosx-version-min=10.5 \ - -arch x86_64 \ - -L$(builddir) \ - -install_name @loader_path/bson.node - -LDFLAGS_Release := \ - -Wl,-search_paths_first \ - -mmacosx-version-min=10.5 \ - -arch x86_64 \ - -L$(builddir) \ - -install_name @loader_path/bson.node - -LIBS := \ - -undefined dynamic_lookup - -$(builddir)/bson.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(builddir)/bson.node: LIBS := $(LIBS) -$(builddir)/bson.node: TOOLSET := $(TOOLSET) -$(builddir)/bson.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(builddir)/bson.node -# Add target alias -.PHONY: bson -bson: $(builddir)/bson.node - -# Short alias for building this executable. -.PHONY: bson.node -bson.node: $(builddir)/bson.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bson.node - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi deleted file mode 100644 index c8c4c25d3bd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi +++ /dev/null @@ -1,105 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 42, - "host_arch": "x64", - "node_install_npm": "true", - "node_install_waf": "true", - "node_prefix": "/usr/local/n/versions/0.8.16", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "target_arch": "x64", - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "true", - "nodedir": "/Users/oroce/.node-gyp/0.8.16", - "copy_dev_lib": "true", - "save_dev": "", - "viewer": "man", - "browser": "", - "rollback": "true", - "usage": "", - "globalignorefile": "/usr/local/etc/npmignore", - "shell": "/bin/bash", - "init_author_url": "", - "parseable": "", - "email": "robert@oroszi.net", - "userignorefile": "/Users/oroce/.npmignore", - "init_author_email": "", - "sign_git_tag": "", - "cache_max": "null", - "long": "", - "ignore": "", - "npat": "", - "fetch_retries": "2", - "registry": "https://registry.npmjs.org/", - "message": "%s", - "versions": "", - "globalconfig": "/usr/local/etc/npmrc", - "always_auth": "", - "cache_lock_retries": "10", - "proprietary_attribs": "true", - "fetch_retry_mintimeout": "10000", - "json": "", - "coverage": "", - "pre": "", - "engine_strict": "", - "description": "true", - "https_proxy": "", - "userconfig": "/Users/oroce/.npmrc", - "init_module": "/Users/oroce/.npm-init.js", - "npaturl": "http://npat.npmjs.org/", - "user": "", - "node_version": "v0.8.16", - "save": "", - "editor": "vi", - "tag": "latest", - "global": "", - "username": "oroce", - "optional": "true", - "force": "", - "searchopts": "", - "depth": "null", - "searchsort": "name", - "rebuild_bundle": "true", - "unicode": "true", - "yes": "", - "fetch_retry_maxtimeout": "60000", - "strict_ssl": "true", - "dev": "", - "group": "20", - "fetch_retry_factor": "10", - "cache_lock_stale": "60000", - "version": "", - "cache_min": "", - "cache": "/Users/oroce/.npm", - "searchexclude": "", - "color": "true", - "save_optional": "", - "user_agent": "node/v0.8.16", - "cache_lock_wait": "10000", - "production": "", - "save_bundle": "", - "umask": "18", - "init_version": "0.0.0", - "git": "git", - "init_author_name": "", - "onload_script": "", - "tmp": "/var/folders/y8/_xyy9vt143sgmjdt6xkh9qhm0000gn/T/", - "unsafe_perm": "true", - "link": "", - "prefix": "/usr/local" - } -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/gyp-mac-tool b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/gyp-mac-tool deleted file mode 100755 index 22f8331585a..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/gyp-mac-tool +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python -# Generated by gyp. Do not edit. -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Utility functions to perform Xcode-style build steps. - -These functions are executed via gyp-mac-tool when using the Makefile generator. -""" - -import fcntl -import os -import plistlib -import re -import shutil -import string -import subprocess -import sys - - -def main(args): - executor = MacTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: - sys.exit(exit_code) - - -class MacTool(object): - """This class performs all the Mac tooling steps. The methods can either be - executed directly, or dispatched from an argument list.""" - - def Dispatch(self, args): - """Dispatches a string command to a method.""" - if len(args) < 1: - raise Exception("Not enough arguments") - - method = "Exec%s" % self._CommandifyName(args[0]) - return getattr(self, method)(*args[1:]) - - def _CommandifyName(self, name_string): - """Transforms a tool name like copy-info-plist to CopyInfoPlist""" - return name_string.title().replace('-', '') - - def ExecCopyBundleResource(self, source, dest): - """Copies a resource file to the bundle/Resources directory, performing any - necessary compilation on each resource.""" - extension = os.path.splitext(source)[1].lower() - if os.path.isdir(source): - # Copy tree. - if os.path.exists(dest): - shutil.rmtree(dest) - shutil.copytree(source, dest) - elif extension == '.xib': - return self._CopyXIBFile(source, dest) - elif extension == '.strings': - self._CopyStringsFile(source, dest) - else: - shutil.copyfile(source, dest) - - def _CopyXIBFile(self, source, dest): - """Compiles a XIB file with ibtool into a binary plist in the bundle.""" - tools_dir = os.environ.get('DEVELOPER_BIN_DIR', '/usr/bin') - args = [os.path.join(tools_dir, 'ibtool'), '--errors', '--warnings', - '--notices', '--output-format', 'human-readable-text', '--compile', - dest, source] - ibtool_section_re = re.compile(r'/\*.*\*/') - ibtool_re = re.compile(r'.*note:.*is clipping its content') - ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) - current_section_header = None - for line in ibtoolout.stdout: - if ibtool_section_re.match(line): - current_section_header = line - elif not ibtool_re.match(line): - if current_section_header: - sys.stdout.write(current_section_header) - current_section_header = None - sys.stdout.write(line) - return ibtoolout.returncode - - def _CopyStringsFile(self, source, dest): - """Copies a .strings file using iconv to reconvert the input into UTF-16.""" - input_code = self._DetectInputEncoding(source) or "UTF-8" - fp = open(dest, 'w') - args = ['/usr/bin/iconv', '--from-code', input_code, '--to-code', - 'UTF-16', source] - subprocess.call(args, stdout=fp) - fp.close() - - def _DetectInputEncoding(self, file_name): - """Reads the first few bytes from file_name and tries to guess the text - encoding. Returns None as a guess if it can't detect it.""" - fp = open(file_name, 'rb') - try: - header = fp.read(3) - except e: - fp.close() - return None - fp.close() - if header.startswith("\xFE\xFF"): - return "UTF-16BE" - elif header.startswith("\xFF\xFE"): - return "UTF-16LE" - elif header.startswith("\xEF\xBB\xBF"): - return "UTF-8" - else: - return None - - def ExecCopyInfoPlist(self, source, dest): - """Copies the |source| Info.plist to the destination directory |dest|.""" - # Read the source Info.plist into memory. - fd = open(source, 'r') - lines = fd.read() - fd.close() - - # Go through all the environment variables and replace them as variables in - # the file. - for key in os.environ: - if key.startswith('_'): - continue - evar = '${%s}' % key - lines = string.replace(lines, evar, os.environ[key]) - - # Write out the file with variables replaced. - fd = open(dest, 'w') - fd.write(lines) - fd.close() - - # Now write out PkgInfo file now that the Info.plist file has been - # "compiled". - self._WritePkgInfo(dest) - - def _WritePkgInfo(self, info_plist): - """This writes the PkgInfo file from the data stored in Info.plist.""" - plist = plistlib.readPlist(info_plist) - if not plist: - return - - # Only create PkgInfo for executable types. - package_type = plist['CFBundlePackageType'] - if package_type != 'APPL': - return - - # The format of PkgInfo is eight characters, representing the bundle type - # and bundle signature, each four characters. If that is missing, four - # '?' characters are used instead. - signature_code = plist.get('CFBundleSignature', '????') - if len(signature_code) != 4: # Wrong length resets everything, too. - signature_code = '?' * 4 - - dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') - fp = open(dest, 'w') - fp.write('%s%s' % (package_type, signature_code)) - fp.close() - - def ExecFlock(self, lockfile, *cmd_list): - """Emulates the most basic behavior of Linux's flock(1).""" - # Rely on exception handling to report errors. - fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666) - fcntl.flock(fd, fcntl.LOCK_EX) - return subprocess.call(cmd_list) - - def ExecFilterLibtool(self, *cmd_list): - """Calls libtool and filters out 'libtool: file: foo.o has no symbols'.""" - libtool_re = re.compile(r'^libtool: file: .* has no symbols$') - libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE) - for line in libtoolout.stderr: - if not libtool_re.match(line): - sys.stderr.write(line) - return libtoolout.returncode - - def ExecPackageFramework(self, framework, version): - """Takes a path to Something.framework and the Current version of that and - sets up all the symlinks.""" - # Find the name of the binary based on the part before the ".framework". - binary = os.path.basename(framework).split('.')[0] - - CURRENT = 'Current' - RESOURCES = 'Resources' - VERSIONS = 'Versions' - - if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)): - # Binary-less frameworks don't seem to contain symlinks (see e.g. - # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle). - return - - # Move into the framework directory to set the symlinks correctly. - pwd = os.getcwd() - os.chdir(framework) - - # Set up the Current version. - self._Relink(version, os.path.join(VERSIONS, CURRENT)) - - # Set up the root symlinks. - self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary) - self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES) - - # Back to where we were before! - os.chdir(pwd) - - def _Relink(self, dest, link): - """Creates a symlink to |dest| named |link|. If |link| already exists, - it is overwritten.""" - if os.path.lexists(link): - os.remove(link) - os.symlink(dest, link) - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile deleted file mode 100644 index 435999ee960..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc deleted file mode 100644 index b910d792066..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc +++ /dev/null @@ -1,1006 +0,0 @@ -//=========================================================================== - -#include -#include -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -// this and the above block must be around the v8.h header otherwise -// v8 is not happy -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __sun - #include -#endif - -#include "bson.h" - -using namespace v8; -using namespace node; - -//=========================================================================== - -void DataStream::WriteObjectId(const Handle& object, const Handle& key) -{ - uint16_t buffer[12]; - object->Get(key)->ToString()->Write(buffer, 0, 12); - for(uint32_t i = 0; i < 12; ++i) - { - *p++ = (char) buffer[i]; - } -} - -void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...) -{ - va_list args; - va_start(args, format); - char* string = (char*) malloc(allocationSize); - vsprintf(string, format, args); - va_end(args); - - throw string; -} - -void DataStream::CheckKey(const Local& keyName) -{ - size_t keyLength = keyName->Utf8Length(); - if(keyLength == 0) return; - - char* keyStringBuffer = (char*) alloca(keyLength+1); - keyName->WriteUtf8(keyStringBuffer); - - if(keyStringBuffer[0] == '$') - { - ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer); - } - - if(strchr(keyStringBuffer, '.') != NULL) - { - ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer); - } -} - -template void BSONSerializer::SerializeDocument(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - Local object = bson->GetSerializeObject(value); - - // Get the object property names - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local propertyNames = object->GetPropertyNames(); - #else - Local propertyNames = object->GetOwnPropertyNames(); - #endif - - // Length of the property - int propertyLength = propertyNames->Length(); - for(int i = 0; i < propertyLength; ++i) - { - const Local& propertyName = propertyNames->Get(i)->ToString(); - if(checkKeys) this->CheckKey(propertyName); - - const Local& propertyValue = object->Get(propertyName); - - if(serializeFunctions || !propertyValue->IsFunction()) - { - void* typeLocation = this->BeginWriteType(); - this->WriteString(propertyName); - SerializeValue(typeLocation, propertyValue); - } - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -template void BSONSerializer::SerializeArray(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - - Local array = Local::Cast(value->ToObject()); - uint32_t arrayLength = array->Length(); - - for(uint32_t i = 0; i < arrayLength; ++i) - { - void* typeLocation = this->BeginWriteType(); - this->WriteUInt32String(i); - SerializeValue(typeLocation, array->Get(i)); - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes. -// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths) -// and ensures that there is always consistency between bytes counted and bytes written by design. -template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value) -{ - if(value->IsNumber()) - { - double doubleValue = value->NumberValue(); - int intValue = (int) doubleValue; - if(intValue == doubleValue) - { - this->CommitType(typeLocation, BSON_TYPE_INT); - this->WriteInt32(intValue); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(doubleValue); - } - } - else if(value->IsString()) - { - this->CommitType(typeLocation, BSON_TYPE_STRING); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsBoolean()) - { - this->CommitType(typeLocation, BSON_TYPE_BOOLEAN); - this->WriteBool(value); - } - else if(value->IsArray()) - { - this->CommitType(typeLocation, BSON_TYPE_ARRAY); - SerializeArray(value); - } - else if(value->IsDate()) - { - this->CommitType(typeLocation, BSON_TYPE_DATE); - this->WriteInt64(value); - } - else if(value->IsRegExp()) - { - this->CommitType(typeLocation, BSON_TYPE_REGEXP); - const Handle& regExp = Handle::Cast(value); - - this->WriteString(regExp->GetSource()); - - int flags = regExp->GetFlags(); - if(flags & RegExp::kGlobal) this->WriteByte('s'); - if(flags & RegExp::kIgnoreCase) this->WriteByte('i'); - if(flags & RegExp::kMultiline) this->WriteByte('m'); - this->WriteByte(0); - } - else if(value->IsFunction()) - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsObject()) - { - const Local& object = value->ToObject(); - if(object->Has(bson->_bsontypeString)) - { - const Local& constructorString = object->GetConstructorName(); - if(bson->longString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_LONG); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->timestampString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->objectIDString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OID); - this->WriteObjectId(object, bson->_objectIDidString); - } - else if(bson->binaryString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value(); - Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject(); - - this->WriteInt32(length); - this->WriteByte(object, bson->_binarySubTypeString); // write subtype - // If type 0x02 write the array length aswell - if(object->Get(bson->_binarySubTypeString)->Int32Value() == 0x02) { - this->WriteInt32(length); - } - // Write the actual data - this->WriteData(Buffer::Data(bufferObj), length); - } - else if(bson->doubleString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(object, bson->_doubleValueString); - } - else if(bson->symbolString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_SYMBOL); - this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString()); - } - else if(bson->codeString->StrictEquals(constructorString)) - { - const Local& function = object->Get(bson->_codeCodeString)->ToString(); - const Local& scope = object->Get(bson->_codeScopeString)->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - if(propertyNameLength > 0) - { - this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE); - void* codeWidthScopeSize = this->BeginWriteSize(); - this->WriteLengthPrefixedString(function->ToString()); - SerializeDocument(scope); - this->CommitSize(codeWidthScopeSize); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(function->ToString()); - } - } - else if(bson->dbrefString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - - void* dbRefSize = this->BeginWriteSize(); - - void* refType = this->BeginWriteType(); - this->WriteData("$ref", 5); - SerializeValue(refType, object->Get(bson->_dbRefNamespaceString)); - - void* idType = this->BeginWriteType(); - this->WriteData("$id", 4); - SerializeValue(idType, object->Get(bson->_dbRefOidString)); - - const Local& refDbValue = object->Get(bson->_dbRefDbString); - if(!refDbValue->IsUndefined()) - { - void* dbType = this->BeginWriteType(); - this->WriteData("$db", 4); - SerializeValue(dbType, refDbValue); - } - - this->WriteByte(0); - this->CommitSize(dbRefSize); - } - else if(bson->minKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MIN_KEY); - } - else if(bson->maxKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MAX_KEY); - } - } - else if(Buffer::HasInstance(value)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(value->ToObject()); - uint32_t length = object->length(); - #else - uint32_t length = Buffer::Length(value->ToObject()); - #endif - - this->WriteInt32(length); - this->WriteByte(0); - this->WriteData(Buffer::Data(value->ToObject()), length); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - SerializeDocument(value); - } - } - else if(value->IsNull() || value->IsUndefined()) - { - this->CommitType(typeLocation, BSON_TYPE_NULL); - } -} - -// Data points to start of element list, length is length of entire document including '\0' but excluding initial size -BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length) -: bson(aBson), - pStart(data), - p(data), - pEnd(data + length - 1) -{ - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length) -: bson(parentSerializer.bson), - pStart(parentSerializer.p), - p(parentSerializer.p), - pEnd(parentSerializer.p + length - 1) -{ - parentSerializer.p += length; - if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds"); - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -Local BSONDeserializer::ReadCString() -{ - char* start = p; - while(*p++) { } - return String::New(start, (int32_t) (p-start-1) ); -} - -int32_t BSONDeserializer::ReadRegexOptions() -{ - int32_t options = 0; - for(;;) - { - switch(*p++) - { - case '\0': return options; - case 's': options |= RegExp::kGlobal; break; - case 'i': options |= RegExp::kIgnoreCase; break; - case 'm': options |= RegExp::kMultiline; break; - } - } -} - -uint32_t BSONDeserializer::ReadIntegerString() -{ - uint32_t value = 0; - while(*p) - { - if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array"); - value = value * 10 + *p++ - '0'; - } - ++p; - return value; -} - -Local BSONDeserializer::ReadString() -{ - uint32_t length = ReadUInt32(); - char* start = p; - p += length; - return String::New(start, length-1); -} - -Local BSONDeserializer::ReadObjectId() -{ - uint16_t objectId[12]; - for(size_t i = 0; i < 12; ++i) - { - objectId[i] = *reinterpret_cast(p++); - } - return String::New(objectId, 12); -} - -Handle BSONDeserializer::DeserializeDocument() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeDocumentInternal(); -} - -Handle BSONDeserializer::DeserializeDocumentInternal() -{ - Local returnObject = Object::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - const Local& name = ReadCString(); - const Handle& value = DeserializeValue(type); - returnObject->ForceSet(name, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes"); - - // From JavaScript: - // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - if(returnObject->Has(bson->_dbRefIdRefString)) - { - Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) }; - return bson->dbrefConstructor->NewInstance(3, argv); - } - else - { - return returnObject; - } -} - -Handle BSONDeserializer::DeserializeArray() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeArrayInternal(); -} - -Handle BSONDeserializer::DeserializeArrayInternal() -{ - Local returnArray = Array::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - uint32_t index = ReadIntegerString(); - const Handle& value = DeserializeValue(type); - returnArray->Set(index, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes"); - - return returnArray; -} - -Handle BSONDeserializer::DeserializeValue(BsonType type) -{ - switch(type) - { - case BSON_TYPE_STRING: - return ReadString(); - - case BSON_TYPE_INT: - return Integer::New(ReadInt32()); - - case BSON_TYPE_NUMBER: - return Number::New(ReadDouble()); - - case BSON_TYPE_NULL: - return Null(); - - case BSON_TYPE_UNDEFINED: - return Undefined(); - - case BSON_TYPE_TIMESTAMP: - { - int32_t lowBits = ReadInt32(); - int32_t highBits = ReadInt32(); - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->timestampConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_BOOLEAN: - return (ReadByte() != 0) ? True() : False(); - - case BSON_TYPE_REGEXP: - { - const Local& regex = ReadCString(); - int32_t options = ReadRegexOptions(); - return RegExp::New(regex, (RegExp::Flags) options); - } - - case BSON_TYPE_CODE: - { - const Local& code = ReadString(); - const Local& scope = Object::New(); - Local argv[] = { code, scope }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_CODE_W_SCOPE: - { - ReadUInt32(); - const Local& code = ReadString(); - const Handle& scope = DeserializeDocument(); - Local argv[] = { code, scope->ToObject() }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_OID: - { - Local argv[] = { ReadObjectId() }; - return bson->objectIDConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_BINARY: - { - uint32_t length = ReadUInt32(); - uint32_t subType = ReadByte(); - if(subType == 0x02) { - length = ReadInt32(); - } - - Buffer* buffer = Buffer::New(p, length); - p += length; - - Handle argv[] = { buffer->handle_, Uint32::New(subType) }; - return bson->binaryConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_LONG: - { - // Read 32 bit integers - int32_t lowBits = (int32_t) ReadInt32(); - int32_t highBits = (int32_t) ReadInt32(); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - // Adjust the pointer and read as 64 bit value - p -= 8; - // Read the 64 bit value - int64_t finalValue = (int64_t) ReadInt64(); - return Number::New(finalValue); - } - - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->longConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_DATE: - return Date::New((double) ReadInt64()); - - case BSON_TYPE_ARRAY: - return DeserializeArray(); - - case BSON_TYPE_OBJECT: - return DeserializeDocument(); - - case BSON_TYPE_SYMBOL: - { - const Local& string = ReadString(); - Local argv[] = { string }; - return bson->symbolConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_MIN_KEY: - return bson->minKeyConstructor->NewInstance(); - - case BSON_TYPE_MAX_KEY: - return bson->maxKeyConstructor->NewInstance(); - - default: - ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type); - } - - return v8::Null(); -} - - -static Handle VException(const char *msg) -{ - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Persistent BSON::constructor_template; - -BSON::BSON() : ObjectWrap() -{ - // Setup pre-allocated comparision objects - _bsontypeString = Persistent::New(String::New("_bsontype")); - _longLowString = Persistent::New(String::New("low_")); - _longHighString = Persistent::New(String::New("high_")); - _objectIDidString = Persistent::New(String::New("id")); - _binaryPositionString = Persistent::New(String::New("position")); - _binarySubTypeString = Persistent::New(String::New("sub_type")); - _binaryBufferString = Persistent::New(String::New("buffer")); - _doubleValueString = Persistent::New(String::New("value")); - _symbolValueString = Persistent::New(String::New("value")); - _dbRefRefString = Persistent::New(String::New("$ref")); - _dbRefIdRefString = Persistent::New(String::New("$id")); - _dbRefDbRefString = Persistent::New(String::New("$db")); - _dbRefNamespaceString = Persistent::New(String::New("namespace")); - _dbRefDbString = Persistent::New(String::New("db")); - _dbRefOidString = Persistent::New(String::New("oid")); - _codeCodeString = Persistent::New(String::New("code")); - _codeScopeString = Persistent::New(String::New("scope")); - _toBSONString = Persistent::New(String::New("toBSON")); - - longString = Persistent::New(String::New("Long")); - objectIDString = Persistent::New(String::New("ObjectID")); - binaryString = Persistent::New(String::New("Binary")); - codeString = Persistent::New(String::New("Code")); - dbrefString = Persistent::New(String::New("DBRef")); - symbolString = Persistent::New(String::New("Symbol")); - doubleString = Persistent::New(String::New("Double")); - timestampString = Persistent::New(String::New("Timestamp")); - minKeyString = Persistent::New(String::New("MinKey")); - maxKeyString = Persistent::New(String::New("MaxKey")); -} - -void BSON::Initialize(v8::Handle target) -{ - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and passing it the existing context -Handle BSON::New(const Arguments &args) -{ - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) - { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) - { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - uint32_t foundClassesMask = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(bson->longString)) { - bson->longConstructor = Persistent::New(func); - foundClassesMask |= 1; - } else if(functionName->StrictEquals(bson->objectIDString)) { - bson->objectIDConstructor = Persistent::New(func); - foundClassesMask |= 2; - } else if(functionName->StrictEquals(bson->binaryString)) { - bson->binaryConstructor = Persistent::New(func); - foundClassesMask |= 4; - } else if(functionName->StrictEquals(bson->codeString)) { - bson->codeConstructor = Persistent::New(func); - foundClassesMask |= 8; - } else if(functionName->StrictEquals(bson->dbrefString)) { - bson->dbrefConstructor = Persistent::New(func); - foundClassesMask |= 0x10; - } else if(functionName->StrictEquals(bson->symbolString)) { - bson->symbolConstructor = Persistent::New(func); - foundClassesMask |= 0x20; - } else if(functionName->StrictEquals(bson->doubleString)) { - bson->doubleConstructor = Persistent::New(func); - foundClassesMask |= 0x40; - } else if(functionName->StrictEquals(bson->timestampString)) { - bson->timestampConstructor = Persistent::New(func); - foundClassesMask |= 0x80; - } else if(functionName->StrictEquals(bson->minKeyString)) { - bson->minKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x100; - } else if(functionName->StrictEquals(bson->maxKeyString)) { - bson->maxKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x200; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(foundClassesMask != 0x3ff) { - delete bson; - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } - else - { - return VException("No types passed in"); - } - } - else - { - return VException("Argument passed in must be an array of types"); - } -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ - -Handle BSON::BSONDeserialize(const Arguments &args) -{ - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) - { -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Validate that we have at least 5 bytes - if(length < 5) return VException("corrupt bson message < 5 bytes long"); - - try - { - BSONDeserializer deserializer(bson, data, length); - return deserializer.DeserializeDocument(); - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - } - else - { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) return VException("corrupt bson message < 5 bytes long"); - - // Let's define the buffer size - char* data = (char *)malloc(len); - DecodeWrite(data, len, args[0], BINARY); - - try - { - BSONDeserializer deserializer(bson, data, len); - Handle result = deserializer.DeserializeDocument(); - free(data); - return result; - - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - free(data); - return error; - } - } -} - -Local BSON::GetSerializeObject(const Handle& argValue) -{ - Local object = argValue->ToObject(); - if(object->Has(_toBSONString)) - { - const Local& toBSON = object->Get(_toBSONString); - if(!toBSON->IsFunction()) ThrowAllocatedStringException(64, "toBSON is not a function"); - - Local result = Local::Cast(toBSON)->Call(object, 0, NULL); - if(!result->IsObject()) ThrowAllocatedStringException(64, "toBSON function did not return an object"); - return result->ToObject(); - } - else - { - return object; - } -} - -Handle BSON::BSONSerialize(const Arguments &args) -{ - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - bool serializeFunctions = (args.Length() >= 4) && args[3]->BooleanValue(); - - char *serialized_object = NULL; - size_t object_size; - try - { - Local object = bson->GetSerializeObject(args[0]); - - BSONSerializer counter(bson, false, serializeFunctions); - counter.SerializeDocument(object); - object_size = counter.GetSerializeSize(); - - // Allocate the memory needed for the serialization - serialized_object = (char *)malloc(object_size); - - // Check if we have a boolean value - bool checkKeys = args.Length() >= 3 && args[1]->IsBoolean() && args[1]->BooleanValue(); - BSONSerializer data(bson, checkKeys, serializeFunctions, serialized_object); - data.SerializeDocument(object); - } - catch(char *err_msg) - { - free(serialized_object); - Handle error = VException(err_msg); - free(err_msg); - return error; - } - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) - { - Buffer *buffer = Buffer::New(serialized_object, object_size); - free(serialized_object); - return scope.Close(buffer->handle_); - } - else - { - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - free(serialized_object); - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) -{ - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - bool serializeFunctions = (args.Length() >= 2) && args[1]->BooleanValue(); - BSONSerializer countSerializer(bson, false, serializeFunctions); - countSerializer.SerializeDocument(args[0]); - - // Return the object size - return scope.Close(Uint32::New((uint32_t) countSerializer.GetSerializeSize())); -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) -{ - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, ->, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - uint32_t index; - size_t object_size; - - try - { - BSON *bson = ObjectWrap::Unwrap(args.This()); - - Local obj = args[2]->ToObject(); - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); - - index = args[3]->Uint32Value(); - bool checkKeys = args.Length() >= 4 && args[1]->IsBoolean() && args[1]->BooleanValue(); - bool serializeFunctions = (args.Length() == 5) && args[4]->BooleanValue(); - - BSONSerializer dataSerializer(bson, checkKeys, serializeFunctions, data+index); - dataSerializer.SerializeDocument(bson->GetSerializeObject(args[0])); - object_size = dataSerializer.GetSerializeSize(); - - if(object_size + index > length) return VException("Serious error - overflowed buffer!!"); - } - catch(char *exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - return scope.Close(Uint32::New((uint32_t) (index + object_size - 1))); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) -{ - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) return VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) - { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->Uint32Value(); - uint32_t index = args[1]->Uint32Value(); - uint32_t resultIndex = args[4]->Uint32Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - BSONDeserializer deserializer(bson, data+index, length-index); - for(uint32_t i = 0; i < numberOfDocuments; i++) - { - try - { - documents->Set(i + resultIndex, deserializer.DeserializeDocument()); - } - catch (char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - } - - // Return new index of parsing - return scope.Close(Uint32::New((uint32_t) (index + deserializer.GetSerializeSize()))); -} - -// Exporting function -extern "C" void init(Handle target) -{ - HandleScope scope; - BSON::Initialize(target); -} - -NODE_MODULE(bson, BSON::Initialize); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h deleted file mode 100644 index 580abd4de2b..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h +++ /dev/null @@ -1,273 +0,0 @@ -//=========================================================================== - -#ifndef BSON_H_ -#define BSON_H_ - -//=========================================================================== - -#define USE_MISALIGNED_MEMORY_ACCESS 1 - -#include -#include -#include - -using namespace v8; -using namespace node; - -//=========================================================================== - -enum BsonType -{ - BSON_TYPE_NUMBER = 1, - BSON_TYPE_STRING = 2, - BSON_TYPE_OBJECT = 3, - BSON_TYPE_ARRAY = 4, - BSON_TYPE_BINARY = 5, - BSON_TYPE_UNDEFINED = 6, - BSON_TYPE_OID = 7, - BSON_TYPE_BOOLEAN = 8, - BSON_TYPE_DATE = 9, - BSON_TYPE_NULL = 10, - BSON_TYPE_REGEXP = 11, - BSON_TYPE_CODE = 13, - BSON_TYPE_SYMBOL = 14, - BSON_TYPE_CODE_W_SCOPE = 15, - BSON_TYPE_INT = 16, - BSON_TYPE_TIMESTAMP = 17, - BSON_TYPE_LONG = 18, - BSON_TYPE_MAX_KEY = 0x7f, - BSON_TYPE_MIN_KEY = 0xff -}; - -//=========================================================================== - -template class BSONSerializer; - -class BSON : public ObjectWrap { -public: - BSON(); - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - -private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparison objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - Persistent _codeCodeString; - Persistent _codeScopeString; - Persistent _toBSONString; - - Local GetSerializeObject(const Handle& object); - - template friend class BSONSerializer; - friend class BSONDeserializer; -}; - -//=========================================================================== - -class CountStream -{ -public: - CountStream() : count(0) { } - - void WriteByte(int value) { ++count; } - void WriteByte(const Handle&, const Handle&) { ++count; } - void WriteBool(const Handle& value) { ++count; } - void WriteInt32(int32_t value) { count += 4; } - void WriteInt32(const Handle& value) { count += 4; } - void WriteInt32(const Handle& object, const Handle& key) { count += 4; } - void WriteInt64(int64_t value) { count += 8; } - void WriteInt64(const Handle& value) { count += 8; } - void WriteDouble(double value) { count += 8; } - void WriteDouble(const Handle& value) { count += 8; } - void WriteDouble(const Handle&, const Handle&) { count += 8; } - void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { count += value->Utf8Length()+5; } - void WriteObjectId(const Handle& object, const Handle& key) { count += 12; } - void WriteString(const Local& value) { count += value->Utf8Length() + 1; } // This returns the number of bytes exclusive of the NULL terminator - void WriteData(const char* data, size_t length) { count += length; } - - void* BeginWriteType() { ++count; return NULL; } - void CommitType(void*, BsonType) { } - void* BeginWriteSize() { count += 4; return NULL; } - void CommitSize(void*) { } - - size_t GetSerializeSize() const { return count; } - - // Do nothing. CheckKey is implemented for DataStream - void CheckKey(const Local&) { } - -private: - size_t count; -}; - -class DataStream -{ -public: - DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { } - - void WriteByte(int value) { *p++ = value; } - void WriteByte(const Handle& object, const Handle& key) { *p++ = object->Get(key)->Int32Value(); } -#if USE_MISALIGNED_MEMORY_ACCESS - void WriteInt32(int32_t value) { *reinterpret_cast(p) = value; p += 4; } - void WriteInt64(int64_t value) { *reinterpret_cast(p) = value; p += 8; } - void WriteDouble(double value) { *reinterpret_cast(p) = value; p += 8; } -#else - void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; } - void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; } - void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; } -#endif - void WriteBool(const Handle& value) { WriteByte(value->BooleanValue() ? 1 : 0); } - void WriteInt32(const Handle& value) { WriteInt32(value->Int32Value()); } - void WriteInt32(const Handle& object, const Handle& key) { WriteInt32(object->Get(key)); } - void WriteInt64(const Handle& value) { WriteInt64(value->IntegerValue()); } - void WriteDouble(const Handle& value) { WriteDouble(value->NumberValue()); } - void WriteDouble(const Handle& object, const Handle& key) { WriteDouble(object->Get(key)); } - void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); } - void WriteObjectId(const Handle& object, const Handle& key); - void WriteString(const Local& value) { p += value->WriteUtf8(p); } // This returns the number of bytes inclusive of the NULL terminator. - void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; } - - void* BeginWriteType() { void* returnValue = p; p++; return returnValue; } - void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast(beginPoint) = value; } - void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; } - -#if USE_MISALIGNED_MEMORY_ACCESS - void CommitSize(void* beginPoint) { *reinterpret_cast(beginPoint) = (int32_t) (p - (char*) beginPoint); } -#else - void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); } -#endif - - size_t GetSerializeSize() const { return p - destinationBuffer; } - - void CheckKey(const Local& keyName); - -protected: - char *const destinationBuffer; // base, never changes - char* p; // cursor into buffer -}; - -template class BSONSerializer : public T -{ -private: - typedef T Inherited; - -public: - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - - void SerializeDocument(const Handle& value); - void SerializeArray(const Handle& value); - void SerializeValue(void* typeLocation, const Handle& value); - -private: - bool checkKeys; - bool serializeFunctions; - BSON* bson; -}; - -//=========================================================================== - -class BSONDeserializer -{ -public: - BSONDeserializer(BSON* aBson, char* data, size_t length); - BSONDeserializer(BSONDeserializer& parentSerializer, size_t length); - - Handle DeserializeDocument(); - - bool HasMoreData() const { return p < pEnd; } - Local ReadCString(); - uint32_t ReadIntegerString(); - int32_t ReadRegexOptions(); - Local ReadString(); - Local ReadObjectId(); - - unsigned char ReadByte() { return *reinterpret_cast(p++); } -#if USE_MISALIGNED_MEMORY_ACCESS - int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast(p); p += 8; return returnValue; } - double ReadDouble() { double returnValue = *reinterpret_cast(p); p += 8; return returnValue; } -#else - int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } - double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } -#endif - - size_t GetSerializeSize() const { return p - pStart; } - -private: - Handle DeserializeArray(); - Handle DeserializeValue(BsonType type); - Handle DeserializeDocumentInternal(); - Handle DeserializeArrayInternal(); - - BSON* bson; - char* const pStart; - char* p; - char* const pEnd; -}; - -//=========================================================================== - -#endif // BSON_H_ - -//=========================================================================== diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js deleted file mode 100644 index 85e243cc2e1..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js +++ /dev/null @@ -1,30 +0,0 @@ -var bson = null; - -// Load the precompiled win32 binary -if(process.platform == "win32" && process.arch == "x64") { - bson = require('./win32/x64/bson'); -} else if(process.platform == "win32" && process.arch == "ia32") { - bson = require('./win32/ia32/bson'); -} else { - bson = require('../build/Release/bson'); -} - -exports.BSON = bson.BSON; -exports.Long = require('../lib/bson/long').Long; -exports.ObjectID = require('../lib/bson/objectid').ObjectID; -exports.DBRef = require('../lib/bson/db_ref').DBRef; -exports.Code = require('../lib/bson/code').Code; -exports.Timestamp = require('../lib/bson/timestamp').Timestamp; -exports.Binary = require('../lib/bson/binary').Binary; -exports.Double = require('../lib/bson/double').Double; -exports.MaxKey = require('../lib/bson/max_key').MaxKey; -exports.MinKey = require('../lib/bson/min_key').MinKey; -exports.Symbol = require('../lib/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node deleted file mode 100644 index b27819bb1a8..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node deleted file mode 100644 index a544c8ed638..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js deleted file mode 100644 index fc13b28ff3d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/install.js +++ /dev/null @@ -1,56 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= Attempting to build bson c++ extension =\n"); -process.stdout.write("= Windows: no build will be attempted as binaries are prepackaged =\n"); -process.stdout.write("= Unix: on failure the package will still install without the C++ extension =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_package_config_mongodb_native'] != null ? process.env['npm_package_config_mongodb_native'] : 'false'; -if(process.env['npm_config_mongodb_debug']) { - console.log("== process.env['npm_package_config_mongodb_native'] :: " + process.env['npm_package_config_mongodb_native']); - console.log("== build_native :: " + build_native); -} - -build_native = process.env['npm_config_mongodb_native'] != null ? process.env['npm_config_mongodb_native'] : build_native; -if(process.env['npm_config_mongodb_debug']) { - console.log("== process.env['npm_config_mongodb_native'] :: " + process.env['npm_config_mongodb_native']); - console.log("== build_native :: " + build_native); -} - -build_native = build_native == 'true' ? true : false; -if(process.env['npm_config_mongodb_debug']) { - console.log("== build_native :: " + build_native); -} - -// If we are building the native bson extension ensure we use gmake if available -if(process.platform != "win32" && process.platform != "win64") { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['node_gyp'], {cwd:process.env['PWD']}); - } else { - make = spawn('gmake', ['node_gyp'], {cwd:process.env['PWD']}); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js deleted file mode 100644 index afbe6b183b9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js +++ /dev/null @@ -1,331 +0,0 @@ -/** - * Module dependencies. - */ -var Buffer = require('buffer').Buffer; // TODO just use global Buffer - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 3; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 4; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js deleted file mode 100644 index d2fc811f416..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js deleted file mode 100644 index 57fdd7958b8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js +++ /dev/null @@ -1,1519 +0,0 @@ -var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js deleted file mode 100644 index 69b56a3ff51..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js deleted file mode 100644 index 56b651029bd..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js deleted file mode 100644 index ae5146378f0..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js deleted file mode 100644 index 6fca3924f6c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js deleted file mode 100644 index 950fcad343d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js +++ /dev/null @@ -1,74 +0,0 @@ -try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js deleted file mode 100644 index f8f37a6b865..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js +++ /dev/null @@ -1,854 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js deleted file mode 100644 index 0825408d0c9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js deleted file mode 100644 index 230c2e64a1d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js deleted file mode 100644 index 1ff9a8326a8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js deleted file mode 100644 index 8e2838d1783..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js deleted file mode 100644 index c650d1536c8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json deleted file mode 100644 index bdc83f610bb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "bson", - "description": "A bson parser for node.js and the browser", - "keywords": [ - "mongodb", - "bson", - "parser" - ], - "version": "0.1.6", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [], - "repository": { - "type": "git", - "url": "git://github.com/mongodb/js-bson.git" - }, - "bugs": { - "mail": "node-mongodb-native@googlegroups.com", - "url": "https://github.com/mongodb/js-bson/issues" - }, - "devDependencies": { - "nodeunit": "0.7.3", - "gleak": "0.2.3" - }, - "config": { - "native": false - }, - "main": "./lib/bson/index", - "directories": { - "lib": "./lib/bson" - }, - "engines": { - "node": ">=0.6.0" - }, - "scripts": { - "install": "node install.js || (exit 0)", - "test": "nodeunit ./test/node && TEST_NATIVE=TRUE nodeunit ./test/node" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "A JS/C++ Bson parser for node, used in the MongoDB Native driver", - "readmeFilename": "README.md", - "_id": "bson@0.1.6", - "dist": { - "shasum": "1ce91b2d66f300878af63b63f8c1e4a692161e49" - }, - "_from": "bson@0.1.6" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js deleted file mode 100644 index 84d8ffc78a9..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js +++ /dev/null @@ -1,260 +0,0 @@ -this.bson_test = { - 'Full document serialization and deserialization': function (test) { - var motherOfAllDocuments = { - 'string': "客家è¯", - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary('hello world'), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSON.serialize(motherOfAllDocuments, true, true, false); - // Deserialize the object - var object = BSON.deserialize(data); - - // Asserts - test.equal(Utf8.decode(motherOfAllDocuments.string), object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - test.ok(assertArrayEqual(motherOfAllDocuments.binary.value(true), object.binary.value(true))); - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); - }, - - 'exercise all the binary object constructor methods': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - test.done(); - }, - - 'exercise the put binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); - }, - - 'exercise the write binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); - }, - - 'exercise the read binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(assertArrayEqual(stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(assertArrayEqual(stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(assertArrayEqual(stringToArrayBuffer('world'), data)); - test.done(); - }, - - 'Should correctly handle toBson function for an object': function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = BSON.serialize(doc, false, true); - var deserialized_doc = BSON.deserialize(serialized_data); - test.equal(1, deserialized_doc.b); - test.done(); - } -}; - -var assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -var stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -var stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -var Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js deleted file mode 100644 index af7fd0b5867..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js +++ /dev/null @@ -1,2034 +0,0 @@ -/*! - * Nodeunit - * https://github.com/caolan/nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * json2.js - * http://www.JSON.org/json2.js - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -nodeunit = (function(){ -/* - http://www.JSON.org/json2.js - 2010-11-17 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, strict: false, regexp: false */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -var JSON = {}; - -(function () { - "use strict"; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) ? - this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? - '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : - '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : - gap ? '[\n' + gap + - partial.join(',\n' + gap) + '\n' + - mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : - gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + - mind + '}' : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ -.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') -.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') -.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); -var assert = this.assert = {}; -var types = {}; -var core = {}; -var nodeunit = {}; -var reporter = {}; -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - var _indexOf = function (arr, item) { - if (arr.indexOf) { - return arr.indexOf(item); - } - for (var i = 0; i < arr.length; i += 1) { - if (arr[i] === item) { - return i; - } - } - return -1; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var completed = []; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners, function (fn) { - fn(); - }); - }; - - addListener(function () { - if (completed.length === keys.length) { - callback(null); - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - completed.push(k); - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && _indexOf(completed, x) !== -1); - }, true); - }; - if (ready()) { - task[task.length - 1](taskCallback); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - if (!tasks.length) { - return callback(); - } - callback = callback || function () {}; - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var tasks = []; - var q = { - concurrency: concurrency, - push: function (data, callback) { - tasks.push({data: data, callback: callback}); - async.nextTick(q.process); - }, - process: function () { - if (workers < q.concurrency && tasks.length) { - var task = tasks.splice(0, 1)[0]; - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - q.process(); - }); - } - }, - length: function () { - return tasks.length; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - hasher = hasher || function (x) { - return x; - }; - return function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else { - fn.apply(null, args.concat([function () { - memo[key] = arguments; - callback.apply(null, arguments); - }])); - } - }; - }; - -}()); -(function(exports){ -/** - * This file is based on the node.js assert module, but with some small - * changes for browser-compatibility - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - */ - - -/** - * Added for browser compatibility - */ - -var _keys = function(obj){ - if(Object.keys) return Object.keys(obj); - if (typeof obj != 'object' && typeof obj != 'function') { - throw new TypeError('-'); - } - var keys = []; - for(var k in obj){ - if(obj.hasOwnProperty(k)) keys.push(k); - } - return keys; -}; - - - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({message: message, actual: actual, expected: expected}) - -assert.AssertionError = function AssertionError (options) { - this.name = "AssertionError"; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// code from util.inherits in node -assert.AssertionError.super_ = Error; - - -// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call -// TODO: test what effect this may have -var ctor = function () { this.constructor = assert.AssertionError; }; -ctor.prototype = Error.prototype; -assert.AssertionError.prototype = new ctor(); - - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name+":", this.message].join(' '); - } else { - return [ this.name+":" - , JSON.stringify(this.expected ) - , this.operator - , JSON.stringify(this.actual) - ].join(" "); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, "==", assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, "==", assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, "!=", assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, "deepEqual", assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == "object", - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical "prototype" property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull (value) { - return value === null || value === undefined; -} - -function isArguments (object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv (a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical "prototype" property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try{ - var ka = _keys(a), - kb = _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; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, "===", assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, "!==", assert.notStrictEqual); - } -}; - -function _throws (shouldThrow, block, err, message) { - var exception = null, - threw = false, - typematters = true; - - message = message || ""; - - //handle optional arguments - if (arguments.length == 3) { - if (typeof(err) == "string") { - message = err; - typematters = false; - } - } else if (arguments.length == 2) { - typematters = false; - } - - try { - block(); - } catch (e) { - threw = true; - exception = e; - } - - if (shouldThrow && !threw) { - fail( "Missing expected exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if (!shouldThrow && threw && typematters && exception instanceof err) { - fail( "Got unwanted exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if ((shouldThrow && threw && typematters && !(exception instanceof err)) || - (!shouldThrow && threw)) { - throw exception; - } -}; - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function (err) { if (err) {throw err;}}; -})(assert); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var assert = require('./assert'), //@REMOVE_LINE_FOR_BROWSER -// async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Creates assertion objects representing the result of an assert call. - * Accepts an object or AssertionError as its argument. - * - * @param {object} obj - * @api public - */ - -exports.assertion = function (obj) { - return { - method: obj.method || '', - message: obj.message || (obj.error && obj.error.message) || '', - error: obj.error, - passed: function () { - return !this.error; - }, - failed: function () { - return Boolean(this.error); - } - }; -}; - -/** - * Creates an assertion list object representing a group of assertions. - * Accepts an array of assertion objects. - * - * @param {Array} arr - * @param {Number} duration - * @api public - */ - -exports.assertionList = function (arr, duration) { - var that = arr || []; - that.failures = function () { - var failures = 0; - for (var i = 0; i < this.length; i += 1) { - if (this[i].failed()) { - failures += 1; - } - } - return failures; - }; - that.passes = function () { - return that.length - that.failures(); - }; - that.duration = duration || 0; - return that; -}; - -/** - * Create a wrapper function for assert module methods. Executes a callback - * after the it's complete with an assertion object representing the result. - * - * @param {Function} callback - * @api private - */ - -var assertWrapper = function (callback) { - return function (new_method, assert_method, arity) { - return function () { - var message = arguments[arity - 1]; - var a = exports.assertion({method: new_method, message: message}); - try { - assert[assert_method].apply(null, arguments); - } - catch (e) { - a.error = e; - } - callback(a); - }; - }; -}; - -/** - * Creates the 'test' object that gets passed to every test function. - * Accepts the name of the test function as its first argument, followed by - * the start time in ms, the options object and a callback function. - * - * @param {String} name - * @param {Number} start - * @param {Object} options - * @param {Function} callback - * @api public - */ - -exports.test = function (name, start, options, callback) { - var expecting; - var a_list = []; - - var wrapAssert = assertWrapper(function (a) { - a_list.push(a); - if (options.log) { - async.nextTick(function () { - options.log(a); - }); - } - }); - - var test = { - done: function (err) { - if (expecting !== undefined && expecting !== a_list.length) { - var e = new Error( - 'Expected ' + expecting + ' assertions, ' + - a_list.length + ' ran' - ); - var a1 = exports.assertion({method: 'expect', error: e}); - a_list.push(a1); - if (options.log) { - async.nextTick(function () { - options.log(a1); - }); - } - } - if (err) { - var a2 = exports.assertion({error: err}); - a_list.push(a2); - if (options.log) { - async.nextTick(function () { - options.log(a2); - }); - } - } - var end = new Date().getTime(); - async.nextTick(function () { - var assertion_list = exports.assertionList(a_list, end - start); - options.testDone(name, assertion_list); - callback(null, a_list); - }); - }, - ok: wrapAssert('ok', 'ok', 2), - same: wrapAssert('same', 'deepEqual', 3), - equals: wrapAssert('equals', 'equal', 3), - expect: function (num) { - expecting = num; - }, - _assertion_list: a_list - }; - // add all functions from the assert module - for (var k in assert) { - if (assert.hasOwnProperty(k)) { - test[k] = wrapAssert(k, k, assert[k].length); - } - } - return test; -}; - -/** - * Ensures an options object has all callbacks, adding empty callback functions - * if any are missing. - * - * @param {Object} opt - * @return {Object} - * @api public - */ - -exports.options = function (opt) { - var optionalCallback = function (name) { - opt[name] = opt[name] || function () {}; - }; - - optionalCallback('moduleStart'); - optionalCallback('moduleDone'); - optionalCallback('testStart'); - optionalCallback('testDone'); - //optionalCallback('log'); - - // 'done' callback is not optional. - - return opt; -}; -})(types); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER -// types = require('./types'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Added for browser compatibility - */ - -var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; -}; - - -var _copy = function (obj) { - var nobj = {}; - var keys = _keys(obj); - for (var i = 0; i < keys.length; i += 1) { - nobj[keys[i]] = obj[keys[i]]; - } - return nobj; -}; - - -/** - * Runs a test function (fn) from a loaded module. After the test function - * calls test.done(), the callback is executed with an assertionList as its - * second argument. - * - * @param {String} name - * @param {Function} fn - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runTest = function (name, fn, opt, callback) { - var options = types.options(opt); - - options.testStart(name); - var start = new Date().getTime(); - var test = types.test(name, start, options, callback); - - try { - fn(test); - } - catch (e) { - test.done(e); - } -}; - -/** - * Takes an object containing test functions or other test suites as properties - * and runs each in series. After all tests have completed, the callback is - * called with a list of all assertions as the second argument. - * - * If a name is passed to this function it is prepended to all test and suite - * names that run within it. - * - * @param {String} name - * @param {Object} suite - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runSuite = function (name, suite, opt, callback) { - var keys = _keys(suite); - - async.concatSeries(keys, function (k, cb) { - var prop = suite[k], _name; - - _name = name ? [].concat(name, k) : [k]; - - _name.toString = function () { - // fallback for old one - return this.join(' - '); - }; - - if (typeof prop === 'function') { - var in_name = false; - for (var i = 0; i < _name.length; i += 1) { - if (_name[i] === opt.testspec) { - in_name = true; - } - } - if (!opt.testspec || in_name) { - if (opt.moduleStart) { - opt.moduleStart(); - } - exports.runTest(_name, suite[k], opt, cb); - } - else { - return cb(); - } - } - else { - exports.runSuite(_name, suite[k], opt, cb); - } - }, callback); -}; - -/** - * Run each exported test function or test suite from a loaded module. - * - * @param {String} name - * @param {Object} mod - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runModule = function (name, mod, opt, callback) { - var options = _copy(types.options(opt)); - - var _run = false; - var _moduleStart = options.moduleStart; - function run_once() { - if (!_run) { - _run = true; - _moduleStart(name); - } - } - options.moduleStart = run_once; - - var start = new Date().getTime(); - - exports.runSuite(null, mod, options, function (err, a_list) { - var end = new Date().getTime(); - var assertion_list = types.assertionList(a_list, end - start); - options.moduleDone(name, assertion_list); - callback(null, a_list); - }); -}; - -/** - * Treats an object literal as a list of modules keyed by name. Runs each - * module and finished with calling 'done'. You can think of this as a browser - * safe alternative to runFiles in the nodeunit module. - * - * @param {Object} modules - * @param {Object} opt - * @api public - */ - -// TODO: add proper unit tests for this function -exports.runModules = function (modules, opt) { - var all_assertions = []; - var options = types.options(opt); - var start = new Date().getTime(); - - async.concatSeries(_keys(modules), function (k, cb) { - exports.runModule(k, modules[k], options, cb); - }, - function (err, all_assertions) { - var end = new Date().getTime(); - options.done(types.assertionList(all_assertions, end - start)); - }); -}; - - -/** - * Wraps a test function with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Function} fn - * @api private - */ - -var wrapTest = function (setUp, tearDown, fn) { - return function (test) { - var context = {}; - if (tearDown) { - var done = test.done; - test.done = function (err) { - try { - tearDown.call(context, function (err2) { - if (err && err2) { - test._assertion_list.push( - types.assertion({error: err}) - ); - return done(err2); - } - done(err || err2); - }); - } - catch (e) { - done(e); - } - }; - } - if (setUp) { - setUp.call(context, function (err) { - if (err) { - return test.done(err); - } - fn.call(context, test); - }); - } - else { - fn.call(context, test); - } - }; -}; - - -/** - * Wraps a group of tests with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Object} group - * @api private - */ - -var wrapGroup = function (setUp, tearDown, group) { - var tests = {}; - var keys = _keys(group); - for (var i = 0; i < keys.length; i += 1) { - var k = keys[i]; - if (typeof group[k] === 'function') { - tests[k] = wrapTest(setUp, tearDown, group[k]); - } - else if (typeof group[k] === 'object') { - tests[k] = wrapGroup(setUp, tearDown, group[k]); - } - } - return tests; -}; - - -/** - * Utility for wrapping a suite of test functions with setUp and tearDown - * functions. - * - * @param {Object} suite - * @return {Object} - * @api public - */ - -exports.testCase = function (suite) { - var setUp = suite.setUp; - var tearDown = suite.tearDown; - delete suite.setUp; - delete suite.tearDown; - return wrapGroup(setUp, tearDown, suite); -}; -})(core); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - - -/** - * NOTE: this test runner is not listed in index.js because it cannot be - * used with the command-line tool, only inside the browser. - */ - - -/** - * Reporter info string - */ - -exports.info = "Browser-based test reporter"; - - -/** - * Run all tests within each module, reporting the results - * - * @param {Array} files - * @api public - */ - -exports.run = function (modules, options) { - var start = new Date().getTime(); - - function setText(el, txt) { - if ('innerText' in el) { - el.innerText = txt; - } - else if ('textContent' in el){ - el.textContent = txt; - } - } - - function getOrCreate(tag, id) { - var el = document.getElementById(id); - if (!el) { - el = document.createElement(tag); - el.id = id; - document.body.appendChild(el); - } - return el; - }; - - var header = getOrCreate('h1', 'nodeunit-header'); - var banner = getOrCreate('h2', 'nodeunit-banner'); - var userAgent = getOrCreate('h2', 'nodeunit-userAgent'); - var tests = getOrCreate('ol', 'nodeunit-tests'); - var result = getOrCreate('p', 'nodeunit-testresult'); - - setText(userAgent, navigator.userAgent); - - nodeunit.runModules(modules, { - moduleStart: function (name) { - /*var mheading = document.createElement('h2'); - mheading.innerText = name; - results.appendChild(mheading); - module = document.createElement('ol'); - results.appendChild(module);*/ - }, - testDone: function (name, assertions) { - var test = document.createElement('li'); - var strong = document.createElement('strong'); - strong.innerHTML = name + ' (' + - '' + assertions.failures() + ', ' + - '' + assertions.passes() + ', ' + - assertions.length + - ')'; - test.className = assertions.failures() ? 'fail': 'pass'; - test.appendChild(strong); - - var aList = document.createElement('ol'); - aList.style.display = 'none'; - test.onclick = function () { - var d = aList.style.display; - aList.style.display = (d == 'none') ? 'block': 'none'; - }; - for (var i=0; i' + (a.error.stack || a.error) + ''; - li.className = 'fail'; - } - else { - li.innerHTML = a.message || a.method || 'no message'; - li.className = 'pass'; - } - aList.appendChild(li); - } - test.appendChild(aList); - tests.appendChild(test); - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - - var failures = assertions.failures(); - banner.className = failures ? 'fail': 'pass'; - - result.innerHTML = 'Tests completed in ' + duration + - ' milliseconds.
    ' + - assertions.passes() + ' assertions of ' + - '' + assertions.length + ' passed, ' + - assertions.failures() + ' failed.'; - } - }); -}; -})(reporter); -nodeunit = core; -nodeunit.assert = assert; -nodeunit.reporter = reporter; -nodeunit.run = reporter.run; -return nodeunit; })(); diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js deleted file mode 100644 index c7288e8d875..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js +++ /dev/null @@ -1,13 +0,0 @@ -this.suite2 = { - 'another test': function (test) { - setTimeout(function () { - // lots of assertions - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.done(); - }, 10); - } -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js deleted file mode 100644 index 89297419bf1..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js +++ /dev/null @@ -1,7 +0,0 @@ -this.suite3 = { - 'test for ie6,7,8': function (test) { - test.deepEqual(["test"], ["test"]); - test.notDeepEqual(["a"], ["b"]); - test.done(); - } -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html deleted file mode 100644 index 56d4d9643b6..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Example tests - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js deleted file mode 100644 index 5304bef45c8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js +++ /dev/null @@ -1,240 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -var _Uint8Array = null; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - _Uint8Array = global.Uint8Array; - delete global['Uint8Array']; - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - global['Uint8Array'] = _Uint8Array; - callback(); -} - -// /** -// * @ignore -// */ -// exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { -// var motherOfAllDocuments = { -// 'string': '客家è¯', -// 'array': [1,2,3], -// 'hash': {'a':1, 'b':2}, -// 'date': new Date(), -// 'oid': new ObjectID(), -// 'binary': new Binary(new Buffer("hello")), -// 'int': 42, -// 'float': 33.3333, -// 'regexp': /regexp/, -// 'boolean': true, -// 'long': Long.fromNumber(100), -// 'where': new Code('this.a > i', {i:1}), -// 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), -// 'minkey': new MinKey(), -// 'maxkey': new MaxKey() -// } -// -// // Let's serialize it -// var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); -// // Build a typed array -// var arr = new Uint8Array(new ArrayBuffer(data.length)); -// // Iterate over all the fields and copy -// for(var i = 0; i < data.length; i++) { -// arr[i] = data[i] -// } -// -// // Deserialize the object -// var object = BSONDE.BSON.deserialize(arr); -// // Asserts -// test.equal(motherOfAllDocuments.string, object.string); -// test.deepEqual(motherOfAllDocuments.array, object.array); -// test.deepEqual(motherOfAllDocuments.date, object.date); -// test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); -// // Assert the values of the binary -// for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { -// test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); -// } -// test.deepEqual(motherOfAllDocuments.int, object.int); -// test.deepEqual(motherOfAllDocuments.float, object.float); -// test.deepEqual(motherOfAllDocuments.regexp, object.regexp); -// test.deepEqual(motherOfAllDocuments.boolean, object.boolean); -// test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); -// test.deepEqual(motherOfAllDocuments.where, object.where); -// test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); -// test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); -// test.deepEqual(motherOfAllDocuments.minkey, object.minkey); -// test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); -// test.done(); -// } - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js deleted file mode 100644 index 74815402ffb..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js +++ /dev/null @@ -1,493 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple edge value'] = function(test) { - // Simple serialization and deserialization of edge value - var doc = {doc:0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly execute toJSON'] = function(test) { - var a = Long.fromNumber(10); - assert.equal(10, a); - - var a = Long.fromNumber(9223372036854775807); - assert.equal(9223372036854775807, a); - - // Simple serialization and deserialization test for a Single String value - var doc = {doc:'Serialize'}; - var simple_string_serialized = bsonC.serialize(doc, true, false); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize nested document'] = function(test) { - // Nested doc - var doc = {a:{b:{c:1}}}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple integer serialization/deserialization test, including testing boundary conditions'] = function(test) { - var doc = {doc:-1}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization test for a Long value'] = function(test) { - var doc = {doc:Long.fromNumber(9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:Long.fromNumber(-9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Float value'] = function(test) { - var doc = {doc:2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a null value'] = function(test) { - var doc = {doc:null}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:true}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a date value'] = function(test) { - var date = new Date(); - var doc = {doc:date}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:/abcd/mi}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - - var doc = {doc:/abcd/}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a objectId value'] = function(test) { - var doc = {doc:new ObjectID()}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value'] = function(test) { - var binary = new Binary(); - var string = 'binstring' - for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value of type 2'] = function(test) { - var binary = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Code value'] = function(test) { - var code = new Code('this.a > i', {'i': 1}); - var simple_string_serialized_2 = bsonJS.serialize({doc:code}, false, true); - var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for an Object'] = function(test) { - var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - - // Simple serialization and deserialization for an Array - var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a DBRef'] = function(test) { - var oid = new ObjectID() - var oid2 = new ObjectID.createFromHexString(oid.toHexString()) - var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - // Ensure we have the same values for the dbref - var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object_c = bsonC.deserialize(simple_string_serialized); - - assert.equal(object_js.doc.namespace, object_c.doc.namespace); - assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); - assert.equal(object_js.doc.db, object_c.doc.db); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize bytes array'] = function(test) { - // Serialized document - var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal('Patty', object.name) - assert.equal(34, object.age) - assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize utf8'] = function(test) { - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.equal(doc.name, object.name) - assert.equal(doc.name1, object.name1) - assert.equal(doc.name2, object.name2) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize object with array'] = function(test) { - var doc = {b:[1, 2, 3]}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc, object) - test.done(); -} - -/** - * @ignore - */ -exports['Test equality of an object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id_2 = new ObjectID(); - assert.ok(object_id.equals(object_id)); - assert.ok(!(object_id.equals(object_id_2))) - test.done(); -} - -/** - * @ignore - */ -exports['Test same serialization for Object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id2 = ObjectID.createFromHexString(object_id.toString()) - var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - - assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object2 = bsonC.deserialize(simple_string_serialized); - assert.equal(object.doc.id, object2.doc.id) - test.done(); -} - -/** - * @ignore - */ -exports['Complex object serialization'] = function(test) { - // JS Object - var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; - var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - - // C++ Object - var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; - var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) - }; - - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - - for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); - } - - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc._id.id, doc1._id.id) - assert.equal(doc._id.id, doc2._id.id) - assert.equal(doc1._id.id, doc2._id.id) - - var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize function'] = function(test) { - var doc = { - _id: 'testid', - key1: function() {} - } - - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Deserialize the string - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize document with special operators'] = function(test) { - var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Should serialize to the same value - assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) - var doc1 = bsonJS.deserialize(simple_string_serialized_2); - var doc2 = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc1, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Create ObjectID from hex string'] = function(test) { - // Hex Id - var hexId = new ObjectID().toString(); - var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docJSBin = bsonJS.serialize(docJS, false, true, true); - var docCBin = bsonC.serialize(docC, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize big complex document'] = function(test) { - // Complex document serialization - var doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} - var docJSBin = bsonJS.serialize(doc, false, true, true); - var docCBin = bsonC.serialize(doc, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Should error out due to 24 characters but not valid hexstring for ObjectID'] = function(test) { - try { - var oid = new ObjectID("tttttttttttttttttttttttt"); - test.ok(false); - } catch(err) {} - - test.done(); -} - - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js deleted file mode 100644 index 9eb5756e193..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js +++ /dev/null @@ -1,1694 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - ObjectId = mongoO.ObjectId, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - vm = require('vm'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly create ObjectID and do deep equals'] = function(test) { - var test_string = {hello: new ObjectID()}; - test_string.hello.toHexString(); - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly get BSON types from require'] = function(test) { - var _mongodb = require('../../lib/bson'); - test.ok(_mongodb.ObjectID === ObjectID); - test.ok(_mongodb.Binary === Binary); - test.ok(_mongodb.Long === Long); - test.ok(_mongodb.Timestamp === Timestamp); - test.ok(_mongodb.Code === Code); - test.ok(_mongodb.DBRef === DBRef); - test.ok(_mongodb.Symbol === Symbol); - test.ok(_mongodb.MinKey === MinKey); - test.ok(_mongodb.MaxKey === MaxKey); - test.ok(_mongodb.Double === Double); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary')); - test.equal("a_1", object.name); - test.equal(false, object.unique); - test.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary'));//, false, true); - // Perform tests - test.equal("hello", object.string); - test.deepEqual([1,2,3], object.array); - test.equal(1, object.hash.a); - test.equal(2, object.hash.b); - test.ok(object.date != null); - test.ok(object.oid != null); - test.ok(object.binary != null); - test.equal(42, object.int); - test.equal(33.3333, object.float); - test.ok(object.regexp != null); - test.equal(true, object.boolean); - test.ok(object.where != null); - test.ok(object.dbref != null); - test.ok(object[null] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize Empty String'] = function(test) { - var test_string = {hello: ''}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data2)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_null, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_null)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_null, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(null, object.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -5600}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: 2147483647}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -2147483648}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.age, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.age); - test.deepEqual(doc.doc.name, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.name); - test.deepEqual(doc.doc.shoe_size, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.shoe_size); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - Array.prototype.toXml = function() {}; - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize a nested object'] = function(test) { - var doc = {doc: {doc:1}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date(); - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date from another VM'] = function(test) { - var script = "date1 = new Date();", - ctx = vm.createContext({ - date1 : null - }); - vm.runInContext(script, ctx, 'myfile.vm'); - - var date = ctx.date1; - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize nested doc'] = function(test) { - var doc = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - - subObject: { - moreText: "Bacon ipsum dolor.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string" - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()}; - var doc2 = {doc: ObjectID.createFromHexString(doc.doc.toHexString())}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var decoded_hash = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc; - var keys = []; - - for(var name in decoded_hash) keys.push(name); - test.deepEqual(['b', 'a', 'c', 'd'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - // Serialize the regular expression - var doc = {doc: /foobar/mi}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.toString(), doc2.doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary(); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Type 2 Binary object'] = function(test) { - var bin = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary(); - bin.write(data); - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports["Should Correctly Serialize and Deserialize DBRef"] = function(test) { - var oid = new ObjectID(); - var doc = {dbref: new DBRef('namespace', oid, null)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal("namespace", doc2.dbref.namespace); - test.deepEqual(doc2.dbref.oid.toHexString(), oid.toHexString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize partial DBRef'] = function(test) { - var id = new ObjectID(); - var doc = {'name':'something', 'user':{'$ref':'username', '$id': id}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal('something', doc2.name); - test.equal('username', doc2.user.namespace); - test.equal(id.toString(), doc2.user.oid.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple Int'] = function(test) { - var doc = {doc:2147483648}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, doc2.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer'] = function(test) { - var doc = {doc: Long.fromNumber(9223372036854775807)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775809)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Deserialize Large Integers as Number not Long'] = function(test) { - function roundTrip(val) { - var doc = {doc: val}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - }; - - roundTrip(Math.pow(2,52)); - roundTrip(Math.pow(2,53) - 1); - roundTrip(Math.pow(2,53)); - roundTrip(-Math.pow(2,52)); - roundTrip(-Math.pow(2,53) + 1); - roundTrip(-Math.pow(2,53)); - roundTrip(Math.pow(2,65)); // Too big for Long. - roundTrip(-Math.pow(2,65)); - roundTrip(9223372036854775807); - roundTrip(1234567890123456800); // Bigger than 2^53, stays a double. - roundTrip(-1234567890123456800); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer and Timestamp as different types'] = function(test) { - var long = Long.fromNumber(9223372036854775807); - var timestamp = Timestamp.fromNumber(9223372036854775807); - test.ok(long instanceof Long); - test.ok(!(long instanceof Timestamp)); - test.ok(timestamp instanceof Timestamp); - test.ok(!(timestamp instanceof Long)); - - var test_int = {doc: long, doc2: timestamp}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(test_int.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Always put the id as the first item in a hash'] = function(test) { - var hash = {doc: {not_id:1, '_id':2}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(hash, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(hash)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(hash, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - var keys = []; - - for(var name in deserialized_data.doc) { - keys.push(name); - } - - test.deepEqual(['not_id', '_id'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a User defined Binary object'] = function(test) { - var bin = new Binary(); - bin.sub_type = BSON.BSON_BINARY_SUBTYPE_USER_DEFINED; - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(deserialized_data.doc.sub_type, BSON.BSON_BINARY_SUBTYPE_USER_DEFINED); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correclty Serialize and Deserialize a Code object'] = function(test) { - var doc = {'doc': {'doc2': new Code('this.a > i', {i:1})}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.doc2.code, deserialized_data.doc.doc2.code); - test.deepEqual(doc.doc.doc2.scope.i, deserialized_data.doc.doc2.scope.i); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly serialize and deserialize and embedded array'] = function(test) { - var doc = {'a':0, - 'b':['tmp1', 'tmp2', 'tmp3', 'tmp4', 'tmp5', 'tmp6', 'tmp7', 'tmp8', 'tmp9', 'tmp10', 'tmp11', 'tmp12', 'tmp13', 'tmp14', 'tmp15', 'tmp16'] - }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.a, deserialized_data.a); - test.deepEqual(doc.b, deserialized_data.b); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize UTF8'] = function(test) { - // Serialize utf8 - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize query object'] = function(test) { - var doc = { count: 'remove_with_no_callback_bug_test', query: {}, fields: null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize empty query object'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize array based doc'] = function(test) { - var doc = { b: [ 1, 2, 3 ], _id: new ObjectID() }; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Symbol'] = function(test) { - if(Symbol != null) { - var doc = { b: [ new Symbol('test') ]}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.ok(deserialized_data.b[0] instanceof Symbol); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should handle Deeply nested document'] = function(test) { - var doc = {a:{b:{c:{d:2}}}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should handle complicated all typed object'] = function(test) { - // First doc - var date = new Date(); - var oid = new ObjectID(); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - // Second doc - var oid = new ObjectID.createFromHexString(oid.toHexString()); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc2 = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize Complex Nested Object'] = function(test) { - var doc = { email: 'email@email.com', - encrypted_password: 'password', - friends: [ '4db96b973d01205364000006', - '4dc77b24c5ba38be14000002' ], - location: [ 72.4930088, 23.0431957 ], - name: 'Amit Kumar', - password_salt: 'salty', - profile_fields: [], - username: 'amit', - _id: new ObjectID() } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = doc; - doc2._id = ObjectID.createFromHexString(doc2._id.toHexString()); - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly massive doc'] = function(test) { - var oid1 = new ObjectID(); - var oid2 = new ObjectID(); - - // JS doc - var doc = { dbref2: new DBRef('namespace', oid1, 'integration_tests_'), - _id: oid2 }; - - var doc2 = { dbref2: new DBRef('namespace', ObjectID.createFromHexString(oid1.toHexString()), 'integration_tests_'), - _id: new ObjectID.createFromHexString(oid2.toHexString()) }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize regexp object'] = function(test) { - var doc = {'b':/foobaré/}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize complicated object'] = function(test) { - var doc = {a:{b:{c:[new ObjectID(), new ObjectID()]}}, d:{f:1332.3323}}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object'] = function(test) { - var doc = { "_id" : { "date" : new Date(), "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object with even more nesting'] = function(test) { - var doc = { "_id" : { "date" : {a:1, b:2, c:new Date()}, "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize empty name object'] = function(test) { - var doc = {'':'test', - 'bbbb':1}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc2[''], 'test'); - test.equal(doc2['bbbb'], 1); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly handle Forced Doubles to ensure we allocate enough space for cap collections'] = function(test) { - if(Double != null) { - var doubleValue = new Double(100); - var doc = {value:doubleValue}; - - // Serialize - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({value:100}, doc2); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should deserialize correctly'] = function(test) { - var doc = { - "_id" : new ObjectID("4e886e687ff7ef5e00000162"), - "str" : "foreign", - "type" : 2, - "timestamp" : ISODate("2011-10-02T14:00:08.383Z"), - "links" : [ - "http://www.reddit.com/r/worldnews/comments/kybm0/uk_home_secretary_calls_for_the_scrapping_of_the/" - ] - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize and deserialize MinKey and MaxKey values'] = function(test) { - var doc = { - _id : new ObjectID("4e886e687ff7ef5e00000162"), - minKey : new MinKey(), - maxKey : new MaxKey() - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.ok(doc2.minKey instanceof MinKey); - test.ok(doc2.maxKey instanceof MaxKey); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize Double value'] = function(test) { - var doc = { - value : new Double(34343.2222) - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.ok(doc.value.valueOf(), doc2.value); - test.ok(doc.value.value, doc2.value); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly create objects'] = function(test) { - try { - var object1 = ObjectID.createFromHexString('000000000000000000000001') - var object2 = ObjectID.createFromHexString('00000000000000000000001') - test.ok(false); - } catch(err) { - test.ok(err != null); - } - - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly retrieve timestamp'] = function(test) { - var testDate = new Date(); - var object1 = new ObjectID(); - test.equal(Math.floor(testDate.getTime()/1000), Math.floor(object1.getTimestamp().getTime()/1000)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly throw error on bsonparser errors'] = function(test) { - var data = new Buffer(3); - var parser = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - - // Catch to small buffer error - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - data = new Buffer(5); - data[0] = 0xff; - data[1] = 0xff; - // Catch illegal size - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - // Finish up - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function BSON.calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the object without serializing the function - var size = BSON.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = BSON.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object using instance method'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the object without serializing the function - var size = bson.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = bson.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function BSON.serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object using a BSON instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function BSON.serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = BSON.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object using a bson instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = bson.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function BSON.deserialize - * @ignore - */ - exports['Should correctly deserialize a buffer using the BSON class level parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = BSON.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = BSON.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function deserialize - * @ignore - */ -exports['Should correctly deserialize a buffer using the BSON instance parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = bson.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = bson.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function BSON.deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should have a correct cached representation of the hexString'] = function (test) { - ObjectID.cacheHexString = true; - var a = new ObjectID; - var __id = a.__id; - test.equal(__id, a.toHexString()); - - // hexString - a = new ObjectID(__id); - test.equal(__id, a.toHexString()); - - // fromHexString - a = ObjectID.createFromHexString(__id); - test.equal(a.__id, a.toHexString()); - test.equal(__id, a.toHexString()); - - // number - var genTime = a.generationTime; - a = new ObjectID(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - - // generationTime - delete a.__id; - a.generationTime = genTime; - test.equal(__id, a.toHexString()); - - // createFromTime - a = ObjectId.createFromTime(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - ObjectId.cacheHexString = false; - - test.done(); -} - -/** - * @ignore - */ -// 'Should Correctly Function' = function(test) { -// var doc = {b:1, func:function() { -// this.b = 2; -// }}; -// -// var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); -// -// debug("----------------------------------------------------------------------") -// debug(inspect(serialized_data)) -// -// // var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); -// // new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); -// // assertBuffersEqual(test, serialized_data, serialized_data2, 0); -// var COUNT = 100000; -// -// // var b = null; -// // eval("b = function(x) { return x+x; }"); -// // var b = new Function("x", "return x+x;"); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// for (i=COUNT; --i>=0; ) { -// var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// } -// -// end = new Date -// console.log("time = ", end - start, "ms -", COUNT * 1000 / (end - start), " ops/sec") -// -// // debug(inspect(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).functionCache)) -// // -// // var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // // test.deepEqual(doc, doc2) -// // // -// // debug(inspect(doc2)) -// // doc2.func() -// // debug(inspect(doc2)) -// // -// // var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); -// // var doc3 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // -// // debug("-----------------------------------------------") -// // debug(inspect(doc3)) -// -// // var key = "0" -// // for(var i = 1; i < 10000; i++) { -// // key = key + " " + i -// // } -// -// test.done(); -// -// -// // var car = { -// // model : "Volvo", -// // country : "Sweden", -// // -// // isSwedish : function() { -// // return this.country == "Sweden"; -// // } -// // } -// -// }, - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js deleted file mode 100644 index cde83f8fd03..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js +++ /dev/null @@ -1,392 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': '客家è¯', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); - // Build a typed array - var arr = new Uint8Array(new ArrayBuffer(data.length)); - // Iterate over all the fields and copy - for(var i = 0; i < data.length; i++) { - arr[i] = data[i] - } - - // Deserialize the object - var object = BSONDE.BSON.deserialize(arr); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports['exercise all the binary object constructor methods'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(utils.stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - test.done(); -}; - -/** - * @ignore - */ -exports['exercise the put binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(utils.assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(utils.assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the write binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the read binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('world'), data)); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js deleted file mode 100644 index 7a78347ec7e..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js +++ /dev/null @@ -1,315 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonC.deserialize(serialized_data); - assert.equal("a_1", object.name); - assert.equal(false, object.unique); - assert.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal("hello", object.string); - assert.deepEqual([1, 2, 3], object.array); - assert.equal(1, object.hash.a); - assert.equal(2, object.hash.b); - assert.ok(object.date != null); - assert.ok(object.oid != null); - assert.ok(object.binary != null); - assert.equal(42, object.int); - assert.equal(33.3333, object.float); - assert.ok(object.regexp != null); - assert.equal(true, object.boolean); - assert.ok(object.where != null); - assert.ok(object.dbref != null); - assert.ok(object['null'] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'} - var serialized_data = bsonC.serialize(test_string) - assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null} - var serialized_data = bsonC.serialize(test_null) - var object = bsonC.deserialize(serialized_data); - assert.deepEqual(test_null, object); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize undefined value'] = function(test) { - var test_undefined = {doc:undefined} - var serialized_data = bsonC.serialize(test_undefined) - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal(null, object.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42} - var serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -5600} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: 2147483647} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -2147483648} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date() - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12) - date.setUTCFullYear(2009) - date.setUTCMonth(11 - 1) - date.setUTCHours(12) - date.setUTCMinutes(0) - date.setUTCSeconds(30) - var doc = {doc: date} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Buffer'] = function(test) { - var doc = {doc: new Buffer("123451234512345")} - var serialized_data = bsonC.serialize(doc) - - assert.equal("123451234512345", bsonC.deserialize(serialized_data).doc.buffer.toString('ascii')); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var test_code = {} - var serialized_data = bsonC.serialize(test_code) - assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}} - var serialized_data = bsonC.serialize(doc) - var decoded_hash = bsonC.deserialize(serialized_data).doc - var keys = [] - for(var name in decoded_hash) keys.push(name) - assert.deepEqual(['b', 'a', 'c', 'd'], keys) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - var doc = {doc: /foobar/mi} - var serialized_data = bsonC.serialize(doc) - var doc2 = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.toString(), doc2.doc.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary() - var string = 'binstring' - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary() - bin.write(data) - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js deleted file mode 100644 index e9282e54908..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js +++ /dev/null @@ -1,109 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser; - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should correctly handle toBson function for an object'] = function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var deserialized_doc = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({b:1}, deserialized_doc); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js deleted file mode 100644 index 9d7cbe7c6ea..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js +++ /dev/null @@ -1,80 +0,0 @@ -exports.assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -exports.stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -exports.stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -exports.Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js deleted file mode 100644 index c707cfcb56c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js +++ /dev/null @@ -1,21 +0,0 @@ - -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE deleted file mode 100644 index 7c435baaec8..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js deleted file mode 100644 index 73834010f60..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js +++ /dev/null @@ -1,190 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css deleted file mode 100644 index 6583fe7c66d..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js deleted file mode 100644 index c3d2dc7d2d3..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png deleted file mode 100644 index 218f3b43713..00000000000 Binary files a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png and /dev/null differ diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/package.json deleted file mode 100755 index cd3b746d4de..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/package.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "name": "mongodb", - "description": "A node.js driver for MongoDB", - "keywords": [ - "mongodb", - "mongo", - "driver", - "db" - ], - "version": "1.2.11", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [ - { - "name": "Aaron Heckmann" - }, - { - "name": "Christoph Pojer" - }, - { - "name": "Pau Ramon Revilla" - }, - { - "name": "Nathan White" - }, - { - "name": "Emmerman" - }, - { - "name": "Seth LaForge" - }, - { - "name": "Boris Filipov" - }, - { - "name": "Stefan Schärmeli" - }, - { - "name": "Tedde Lundgren" - }, - { - "name": "renctan" - }, - { - "name": "Sergey Ukustov" - }, - { - "name": "Ciaran Jessup" - }, - { - "name": "kuno" - }, - { - "name": "srimonti" - }, - { - "name": "Erik Abele" - }, - { - "name": "Pratik Daga" - }, - { - "name": "Slobodan Utvic" - }, - { - "name": "Kristina Chodorow" - }, - { - "name": "Yonathan Randolph" - }, - { - "name": "Brian Noguchi" - }, - { - "name": "Sam Epstein" - }, - { - "name": "James Harrison Fisher" - }, - { - "name": "Vladimir Dronnikov" - }, - { - "name": "Ben Hockey" - }, - { - "name": "Henrik Johansson" - }, - { - "name": "Simon Weare" - }, - { - "name": "Alex Gorbatchev" - }, - { - "name": "Shimon Doodkin" - }, - { - "name": "Kyle Mueller" - }, - { - "name": "Eran Hammer-Lahav" - }, - { - "name": "Marcin Ciszak" - }, - { - "name": "François de Metz" - }, - { - "name": "Vinay Pulim" - }, - { - "name": "nstielau" - }, - { - "name": "Adam Wiggins" - }, - { - "name": "entrinzikyl" - }, - { - "name": "Jeremy Selier" - }, - { - "name": "Ian Millington" - }, - { - "name": "Public Keating" - }, - { - "name": "andrewjstone" - }, - { - "name": "Christopher Stott" - }, - { - "name": "Corey Jewett" - }, - { - "name": "brettkiefer" - }, - { - "name": "Rob Holland" - }, - { - "name": "Senmiao Liu" - }, - { - "name": "heroic" - }, - { - "name": "gitfy" - }, - { - "name": "Andrew Stone" - }, - { - "name": "John Le Drew" - }, - { - "name": "Lucasfilm Singapore" - }, - { - "name": "Roman Shtylman" - }, - { - "name": "Matt Self" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/mongodb/node-mongodb-native.git" - }, - "bugs": { - "mail": "node-mongodb-native@googlegroups.com", - "url": "http://github.com/mongodb/node-mongodb-native/issues" - }, - "dependencies": { - "bson": "0.1.6" - }, - "devDependencies": { - "dox": "0.2.0", - "uglify-js": "1.2.5", - "ejs": "0.6.1", - "nodeunit": "0.7.4", - "github3": ">=0.3.0", - "markdown": "0.3.1", - "gleak": "0.2.3", - "step": "0.0.5", - "async": "0.1.22" - }, - "config": { - "native": false - }, - "main": "./lib/mongodb/index", - "homepage": "http://mongodb.github.com/node-mongodb-native/", - "directories": { - "lib": "./lib/mongodb" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "test": "make test_pure" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Up to date documentation\n========================\n\n[Documentation](http://mongodb.github.com/node-mongodb-native/)\n\nInstall\n=======\n\nTo install the most recent release from npm, run:\n\n npm install mongodb\n\nThat may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version)\n\nTo install the latest from the repository, run::\n\n npm install path/to/node-mongodb-native\n\nCommunity\n=========\nCheck out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver.\n\nTry it live\n============\n\n\nIntroduction\n============\n\nThis is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/.\n\nA simple example of inserting a document.\n\n```javascript\n var client = new Db('test', new Server(\"127.0.0.1\", 27017, {}), {w: 1}),\n test = function (err, collection) {\n collection.insert({a:2}, function(err, docs) {\n\n collection.count(function(err, count) {\n test.assertEquals(1, count);\n });\n\n // Locate all the entries using find\n collection.find().toArray(function(err, results) {\n test.assertEquals(1, results.length);\n test.assertTrue(results[0].a === 2);\n\n // Let's close the db\n client.close();\n });\n });\n };\n\n client.open(function(err, p_client) {\n client.collection('test_insert', test);\n });\n```\n\nData types\n==========\n\nTo store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code).\n\nIn particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example:\n\n```javascript\n // Get the objectID type\n var ObjectID = require('mongodb').ObjectID;\n\n var idString = '4e4e1638c85e808431000003';\n collection.findOne({_id: new ObjectID(idString)}, console.log) // ok\n collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined\n```\n\nHere are the constructors the non-Javascript BSON primitive types:\n\n```javascript\n // Fetch the library\n var mongo = require('mongodb');\n // Create new instances of BSON types\n new mongo.Long(numberString)\n new mongo.ObjectID(hexString)\n new mongo.Timestamp() // the actual unique number is generated on insert.\n new mongo.DBRef(collectionName, id, dbName)\n new mongo.Binary(buffer) // takes a string or Buffer\n new mongo.Code(code, [context])\n new mongo.Symbol(string)\n new mongo.MinKey()\n new mongo.MaxKey()\n new mongo.Double(number)\t// Force double storage\n```\n\nThe C/C++ bson parser/serializer\n--------------------------------\n\nIf you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below\n\n```javascript\n // using native_parser:\n var client = new Db('integration_tests_20',\n new Server(\"127.0.0.1\", 27017),\n {native_parser:true});\n```\n\nThe C++ parser uses the js objects both for serialization and deserialization.\n\nGitHub information\n==================\n\nThe source code is available at http://github.com/mongodb/node-mongodb-native.\nYou can either clone the repository or download a tarball of the latest release.\n\nOnce you have the source you can test the driver by running\n\n $ make test\n\nin the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass.\n\nExamples\n========\n\nFor examples look in the examples/ directory. You can execute the examples using node.\n\n $ cd examples\n $ node queries.js\n\nGridStore\n=========\n\nThe GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition.\n\nFor more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)\n\nReplicasets\n===========\nFor more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md)\n\nPrimary Key Factories\n---------------------\n\nDefining your own primary key factory allows you to generate your own series of id's\n(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long \"string\".\n\nSimple example below\n\n```javascript\n // Custom factory (need to provide a 12 byte array);\n CustomPKFactory = function() {}\n CustomPKFactory.prototype = new Object();\n CustomPKFactory.createPk = function() {\n return new ObjectID(\"aaaaaaaaaaaa\");\n }\n\n var p_client = new Db('integration_tests_20', new Server(\"127.0.0.1\", 27017, {}), {'pk':CustomPKFactory});\n p_client.open(function(err, p_client) {\n p_client.dropDatabase(function(err, done) {\n p_client.createCollection('test_custom_key', function(err, collection) {\n collection.insert({'a':1}, function(err, docs) {\n collection.find({'_id':new ObjectID(\"aaaaaaaaaaaa\")}, function(err, cursor) {\n cursor.toArray(function(err, items) {\n test.assertEquals(1, items.length);\n\n // Let's close the db\n p_client.close();\n });\n });\n });\n });\n });\n });\n```\n\nStrict mode\n-----------\n\nEach database has an optional strict mode. If it is set then asking for a collection\nthat does not exist will return an Error object in the callback. Similarly if you\nattempt to create a collection that already exists. Strict is provided for convenience.\n\n```javascript\n var error_client = new Db('integration_tests_', new Server(\"127.0.0.1\", 27017, {auto_reconnect: false}), {strict:true});\n test.assertEquals(true, error_client.strict);\n\n error_client.open(function(err, error_client) {\n error_client.collection('does-not-exist', function(err, collection) {\n test.assertTrue(err instanceof Error);\n test.assertEquals(\"Collection does-not-exist does not exist. Currently in strict mode.\", err.message);\n });\n\n error_client.createCollection('test_strict_access_collection', function(err, collection) {\n error_client.collection('test_strict_access_collection', function(err, collection) {\n test.assertTrue(collection instanceof Collection);\n // Let's close the db\n error_client.close();\n });\n });\n });\n```\n\nDocumentation\n=============\n\nIf this document doesn't answer your questions, see the source of\n[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js)\nor [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js),\nor the documentation at MongoDB for query and update formats.\n\nFind\n----\n\nThe find method is actually a factory method to create\nCursor objects. A Cursor lazily uses the connection the first time\nyou call `nextObject`, `each`, or `toArray`.\n\nThe basic operation on a cursor is the `nextObject` method\nthat fetches the next matching document from the database. The convenience\nmethods `each` and `toArray` call `nextObject` until the cursor is exhausted.\n\nSignatures:\n\n```javascript\n var cursor = collection.find(query, [fields], options);\n cursor.sort(fields).limit(n).skip(m).\n\n cursor.nextObject(function(err, doc) {});\n cursor.each(function(err, doc) {});\n cursor.toArray(function(err, docs) {});\n\n cursor.rewind() // reset the cursor to its initial state.\n```\n\nUseful chainable methods of cursor. These can optionally be options of `find` instead of method calls:\n\n* `.limit(n).skip(m)` to control paging.\n* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes:\n * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2.\n * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above\n * `.sort([['field1', 'desc'], 'field2'])` same as above\n * `.sort('field1')` ascending by field1\n\nOther options of `find`:\n\n* `fields` the fields to fetch (to avoid transferring the entire document)\n* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors).\n* `batchSize` The number of the subset of results to request the database\nto return for every request. This should initially be greater than 1 otherwise\nthe database will automatically close the cursor. The batch size can be set to 1\nwith `batchSize(n, function(err){})` after performing the initial query to the database.\n* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint).\n* `explain` turns this into an explain query. You can also call\n`explain()` on any cursor to fetch the explanation.\n* `snapshot` prevents documents that are updated while the query is active\nfrom being returned multiple times. See more\n[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database).\n* `timeout` if false, asks MongoDb not to time out this cursor after an\ninactivity period.\n\n\nFor information on how to create queries, see the\n[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.find({}, {limit:10}).toArray(function(err, docs) {\n console.dir(docs);\n });\n });\n```\n\nInsert\n------\n\nSignature:\n\n```javascript\n collection.insert(docs, options, [callback]);\n```\n\nwhere `docs` can be a single document or an array of documents.\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n\nSee also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.insert({hello: 'world'}, {safe:true},\n function(err, objects) {\n if (err) console.warn(err.message);\n if (err && err.message.indexOf('E11000 ') !== -1) {\n // this _id was already inserted in the database\n }\n });\n });\n```\n\nNote that there's no reason to pass a callback to the insert or update commands\nunless you use the `safe:true` option. If you don't specify `safe:true`, then\nyour callback will be called immediately.\n\nUpdate; update and insert (upsert)\n----------------------------------\n\nThe update operation will update the first document that matches your query\n(or all documents that match if you use `multi:true`).\nIf `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated.\n\nSee the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for\nthe modifier (`$inc`, `$set`, `$push`, etc.) formats.\n\nSignature:\n\n```javascript\n collection.update(criteria, objNew, options, [callback]);\n```\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n* `multi:true` If set, all matching documents are updated, not just the first.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `update`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true},\n function(err) {\n if (err) console.warn(err.message);\n else console.log('successfully updated');\n });\n });\n```\n\nFind and modify\n---------------\n\n`findAndModify` is like `update`, but it also gives the updated document to\nyour callback. But there are a few key differences between findAndModify and\nupdate:\n\n 1. The signatures differ.\n 2. You can only findAndModify a single item, not multiple items.\n\nSignature:\n\n```javascript\n collection.findAndModify(query, sort, update, options, callback)\n```\n\nThe sort parameter is used to specify which object to operate on, if more than\none document matches. It takes the same format as the cursor sort (see\nConnection.find above).\n\nSee the\n[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command)\nfor more details.\n\nUseful options:\n\n* `remove:true` set to a true to remove the object before returning\n* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `findAndModify`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {},\n function(err, object) {\n if (err) console.warn(err.message);\n else console.dir(object); // undefined if no matching object exists.\n });\n });\n```\n\nSave\n----\n\nThe `save` method is a shorthand for upsert if the document contains an\n`_id`, or an insert if there is no `_id`.\n\nSponsors\n========\nJust as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB.\n\nIf your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details.\n\nAnd I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing.\n\nRelease Notes\n=============\n\nSee HISTORY\n\nCredits\n=======\n\n1. [10gen](http://github.com/mongodb/mongo-ruby-driver/)\n2. [Google Closure Library](http://code.google.com/closure/library/)\n3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser)\n\nContributors\n============\n\nAaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy\n\nLicense\n=======\n\n Copyright 2009 - 2012 Christian Amor Kvalheim.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n", - "readmeFilename": "Readme.md", - "_id": "mongodb@1.2.11", - "dist": { - "shasum": "510158d5dfd945735a9a78aaf3a0814dee527a4f" - }, - "_from": "mongodb@1.2.x" -} diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/upload.py b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/upload.py deleted file mode 100644 index 6296fdeddd2..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/node_modules/mongodb/upload.py +++ /dev/null @@ -1,2347 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 -# -# Copyright 2007 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tool for uploading diffs from a version control system to the codereview app. - -Usage summary: upload.py [options] [-- diff_options] [path...] - -Diff options are passed to the diff command of the underlying system. - -Supported version control systems: - Git - Mercurial - Subversion - Perforce - CVS - -It is important for Git/Mercurial users to specify a tree/node/branch to diff -against by using the '--rev' option. -""" -# This code is derived from appcfg.py in the App Engine SDK (open source), -# and from ASPN recipe #146306. - -import ConfigParser -import cookielib -import errno -import fnmatch -import getpass -import logging -import marshal -import mimetypes -import optparse -import os -import re -import socket -import subprocess -import sys -import urllib -import urllib2 -import urlparse - -# The md5 module was deprecated in Python 2.5. -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - -try: - import readline -except ImportError: - pass - -try: - import keyring -except ImportError: - keyring = None - -# The logging verbosity: -# 0: Errors only. -# 1: Status messages. -# 2: Info logs. -# 3: Debug logs. -verbosity = 1 - -# The account type used for authentication. -# This line could be changed by the review server (see handler for -# upload.py). -AUTH_ACCOUNT_TYPE = "HOSTED" - -# URL of the default review server. As for AUTH_ACCOUNT_TYPE, this line could be -# changed by the review server (see handler for upload.py). -DEFAULT_REVIEW_SERVER = "codereview.10gen.com" - -# Max size of patch or base file. -MAX_UPLOAD_SIZE = 900 * 1024 - -# Constants for version control names. Used by GuessVCSName. -VCS_GIT = "Git" -VCS_MERCURIAL = "Mercurial" -VCS_SUBVERSION = "Subversion" -VCS_PERFORCE = "Perforce" -VCS_CVS = "CVS" -VCS_UNKNOWN = "Unknown" - -VCS_ABBREVIATIONS = { - VCS_MERCURIAL.lower(): VCS_MERCURIAL, - "hg": VCS_MERCURIAL, - VCS_SUBVERSION.lower(): VCS_SUBVERSION, - "svn": VCS_SUBVERSION, - VCS_PERFORCE.lower(): VCS_PERFORCE, - "p4": VCS_PERFORCE, - VCS_GIT.lower(): VCS_GIT, - VCS_CVS.lower(): VCS_CVS, -} - -# The result of parsing Subversion's [auto-props] setting. -svn_auto_props_map = None - -def GetEmail(prompt): - """Prompts the user for their email address and returns it. - - The last used email address is saved to a file and offered up as a suggestion - to the user. If the user presses enter without typing in anything the last - used email address is used. If the user enters a new address, it is saved - for next time we prompt. - - """ - last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") - last_email = "" - if os.path.exists(last_email_file_name): - try: - last_email_file = open(last_email_file_name, "r") - last_email = last_email_file.readline().strip("\n") - last_email_file.close() - prompt += " [%s]" % last_email - except IOError, e: - pass - email = raw_input(prompt + ": ").strip() - if email: - try: - last_email_file = open(last_email_file_name, "w") - last_email_file.write(email) - last_email_file.close() - except IOError, e: - pass - else: - email = last_email - return email - - -def StatusUpdate(msg): - """Print a status message to stdout. - - If 'verbosity' is greater than 0, print the message. - - Args: - msg: The string to print. - """ - if verbosity > 0: - print msg - - -def ErrorExit(msg): - """Print an error message to stderr and exit.""" - print >>sys.stderr, msg - sys.exit(1) - - -class ClientLoginError(urllib2.HTTPError): - """Raised to indicate there was an error authenticating with ClientLogin.""" - - def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) - self.args = args - self.reason = args["Error"] - self.info = args.get("Info", None) - - -class AbstractRpcServer(object): - """Provides a common interface for a simple RPC server.""" - - def __init__(self, host, auth_function, host_override=None, extra_headers={}, - save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): - """Creates a new HttpRpcServer. - - Args: - host: The host to send requests to. - auth_function: A function that takes no arguments and returns an - (email, password) tuple when called. Will be called if authentication - is required. - host_override: The host header to send to the server (defaults to host). - extra_headers: A dict of extra headers to append to every request. - save_cookies: If True, save the authentication cookies to local disk. - If False, use an in-memory cookiejar instead. Subclasses must - implement this functionality. Defaults to False. - account_type: Account type used for authentication. Defaults to - AUTH_ACCOUNT_TYPE. - """ - self.host = host - if (not self.host.startswith("http://") and - not self.host.startswith("https://")): - self.host = "http://" + self.host - self.host_override = host_override - self.auth_function = auth_function - self.authenticated = False - self.extra_headers = extra_headers - self.save_cookies = save_cookies - self.account_type = account_type - self.opener = self._GetOpener() - if self.host_override: - logging.info("Server: %s; Host: %s", self.host, self.host_override) - else: - logging.info("Server: %s", self.host) - - def _GetOpener(self): - """Returns an OpenerDirector for making HTTP requests. - - Returns: - A urllib2.OpenerDirector object. - """ - raise NotImplementedError() - - def _CreateRequest(self, url, data=None): - """Creates a new urllib request.""" - logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data, headers={"Accept": "text/plain"}) - if self.host_override: - req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): - req.add_header(key, value) - return req - - def _GetAuthToken(self, email, password): - """Uses ClientLogin to authenticate the user, returning an auth token. - - Args: - email: The user's email address - password: The user's password - - Raises: - ClientLoginError: If there was an error authenticating with ClientLogin. - HTTPError: If there was some other form of HTTP error. - - Returns: - The authentication token returned by ClientLogin. - """ - account_type = self.account_type - if self.host.endswith(".google.com"): - # Needed for use inside Google. - account_type = "HOSTED" - req = self._CreateRequest( - url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ - "Email": email, - "Passwd": password, - "service": "ah", - "source": "rietveld-codereview-upload", - "accountType": account_type, - }), - ) - try: - response = self.opener.open(req) - response_body = response.read() - response_dict = dict(x.split("=") - for x in response_body.split("\n") if x) - return response_dict["Auth"] - except urllib2.HTTPError, e: - if e.code == 403: - body = e.read() - response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) - raise ClientLoginError(req.get_full_url(), e.code, e.msg, - e.headers, response_dict) - else: - raise - - def _GetAuthCookie(self, auth_token): - """Fetches authentication cookies for an authentication token. - - Args: - auth_token: The authentication token returned by ClientLogin. - - Raises: - HTTPError: If there was an error fetching the authentication cookies. - """ - # This is a dummy value to allow us to identify when we're successful. - continue_location = "http://localhost/" - args = {"continue": continue_location, "auth": auth_token} - req = self._CreateRequest("%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) - try: - response = self.opener.open(req) - except urllib2.HTTPError, e: - response = e - if (response.code != 302 or - response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) - self.authenticated = True - - def _Authenticate(self): - """Authenticates the user. - - The authentication process works as follows: - 1) We get a username and password from the user - 2) We use ClientLogin to obtain an AUTH token for the user - (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). - 3) We pass the auth token to /_ah/login on the server to obtain an - authentication cookie. If login was successful, it tries to redirect - us to the URL we provided. - - If we attempt to access the upload API without first obtaining an - authentication cookie, it returns a 401 response (or a 302) and - directs us to authenticate ourselves with ClientLogin. - """ - for i in range(3): - credentials = self.auth_function() - try: - auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: - print >>sys.stderr, '' - if e.reason == "BadAuthentication": - if e.info == "InvalidSecondFactor": - print >>sys.stderr, ( - "Use an application-specific password instead " - "of your regular account password.\n" - "See http://www.google.com/" - "support/accounts/bin/answer.py?answer=185833") - else: - print >>sys.stderr, "Invalid username or password." - elif e.reason == "CaptchaRequired": - print >>sys.stderr, ( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.\n" - "If you are using a Google Apps account the URL is:\n" - "https://www.google.com/a/yourdomain.com/UnlockCaptcha") - elif e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." - elif e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." - elif e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." - elif e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." - break - elif e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") - elif e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." - else: - # Unknown error. - raise - print >>sys.stderr, '' - continue - self._GetAuthCookie(auth_token) - return - - def Send(self, request_path, payload=None, - content_type="application/octet-stream", - timeout=None, - extra_headers=None, - **kwargs): - """Sends an RPC and returns the response. - - Args: - request_path: The path to send the request to, eg /api/appversion/create. - payload: The body of the request, or None to send an empty request. - content_type: The Content-Type header to use. - timeout: timeout in seconds; default None i.e. no timeout. - (Note: for large requests on OS X, the timeout doesn't work right.) - extra_headers: Dict containing additional HTTP headers that should be - included in the request (string header names mapped to their values), - or None to not include any additional headers. - kwargs: Any keyword arguments are converted into query string parameters. - - Returns: - The response body, as a string. - """ - # TODO: Don't require authentication. Let the server say - # whether it is necessary. - if not self.authenticated: - self._Authenticate() - - old_timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) - try: - tries = 0 - while True: - tries += 1 - args = dict(kwargs) - url = "%s%s" % (self.host, request_path) - if args: - url += "?" + urllib.urlencode(args) - req = self._CreateRequest(url=url, data=payload) - req.add_header("Content-Type", content_type) - if extra_headers: - for header, value in extra_headers.items(): - req.add_header(header, value) - try: - f = self.opener.open(req) - response = f.read() - f.close() - return response - except urllib2.HTTPError, e: - if tries > 3: - raise - elif e.code == 401 or e.code == 302: - self._Authenticate() - elif e.code == 301: - # Handle permanent redirect manually. - url = e.info()["location"] - url_loc = urlparse.urlparse(url) - self.host = '%s://%s' % (url_loc[0], url_loc[1]) - elif e.code >= 500: - ErrorExit(e.read()) - else: - raise - finally: - socket.setdefaulttimeout(old_timeout) - - -class HttpRpcServer(AbstractRpcServer): - """Provides a simplified RPC-style interface for HTTP requests.""" - - def _Authenticate(self): - """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() - if self.save_cookies: - StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) - self.cookie_jar.save() - - def _GetOpener(self): - """Returns an OpenerDirector that supports cookies and ignores redirects. - - Returns: - A urllib2.OpenerDirector object. - """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) - if self.save_cookies: - self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) - if os.path.exists(self.cookie_file): - try: - self.cookie_jar.load() - self.authenticated = True - StatusUpdate("Loaded authentication cookies from %s" % - self.cookie_file) - except (cookielib.LoadError, IOError): - # Failed to load cookies - just ignore them. - pass - else: - # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) - os.close(fd) - # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) - else: - # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) - return opener - - -class CondensedHelpFormatter(optparse.IndentedHelpFormatter): - """Frees more horizontal space by removing indentation from group - options and collapsing arguments between short and long, e.g. - '-o ARG, --opt=ARG' to -o --opt ARG""" - - def format_heading(self, heading): - return "%s:\n" % heading - - def format_option(self, option): - self.dedent() - res = optparse.HelpFormatter.format_option(self, option) - self.indent() - return res - - def format_option_strings(self, option): - self.set_long_opt_delimiter(" ") - optstr = optparse.HelpFormatter.format_option_strings(self, option) - optlist = optstr.split(", ") - if len(optlist) > 1: - if option.takes_value(): - # strip METAVAR from all but the last option - optlist = [x.split()[0] for x in optlist[:-1]] + optlist[-1:] - optstr = " ".join(optlist) - return optstr - - -parser = optparse.OptionParser( - usage="%prog [options] [-- diff_options] [path...]", - add_help_option=False, - formatter=CondensedHelpFormatter() -) -parser.add_option("-h", "--help", action="store_true", - help="Show this help message and exit.") -parser.add_option("-y", "--assume_yes", action="store_true", - dest="assume_yes", default=False, - help="Assume that the answer to yes/no questions is 'yes'.") -# Logging -group = parser.add_option_group("Logging options") -group.add_option("-q", "--quiet", action="store_const", const=0, - dest="verbose", help="Print errors only.") -group.add_option("-v", "--verbose", action="store_const", const=2, - dest="verbose", default=1, - help="Print info level logs.") -group.add_option("--noisy", action="store_const", const=3, - dest="verbose", help="Print all logs.") -group.add_option("--print_diffs", dest="print_diffs", action="store_true", - help="Print full diffs.") -# Review server -group = parser.add_option_group("Review server options") -group.add_option("-s", "--server", action="store", dest="server", - default=DEFAULT_REVIEW_SERVER, - metavar="SERVER", - help=("The server to upload to. The format is host[:port]. " - "Defaults to '%default'.")) -group.add_option("-e", "--email", action="store", dest="email", - metavar="EMAIL", default=None, - help="The username to use. Will prompt if omitted.") -group.add_option("-H", "--host", action="store", dest="host", - metavar="HOST", default=None, - help="Overrides the Host header sent with all RPCs.") -group.add_option("--no_cookies", action="store_false", - dest="save_cookies", default=True, - help="Do not save authentication cookies to local disk.") -group.add_option("--account_type", action="store", dest="account_type", - metavar="TYPE", default=AUTH_ACCOUNT_TYPE, - choices=["GOOGLE", "HOSTED"], - help=("Override the default account type " - "(defaults to '%default', " - "valid choices are 'GOOGLE' and 'HOSTED').")) -# Issue -group = parser.add_option_group("Issue options") -group.add_option("-t", "--title", action="store", dest="title", - help="New issue subject or new patch set title") -group.add_option("-m", "--message", action="store", dest="message", - default=None, - help="New issue description or new patch set message") -group.add_option("-F", "--file", action="store", dest="file", - default=None, help="Read the message above from file.") -group.add_option("-r", "--reviewers", action="store", dest="reviewers", - metavar="REVIEWERS", default=None, - help="Add reviewers (comma separated email addresses).") -group.add_option("--cc", action="store", dest="cc", - metavar="CC", default=None, - help="Add CC (comma separated email addresses).") -group.add_option("--private", action="store_true", dest="private", - default=False, - help="Make the issue restricted to reviewers and those CCed") -# Upload options -group = parser.add_option_group("Patch options") -group.add_option("-i", "--issue", type="int", action="store", - metavar="ISSUE", default=None, - help="Issue number to which to add. Defaults to new issue.") -group.add_option("--base_url", action="store", dest="base_url", default=None, - help="Base URL path for files (listed as \"Base URL\" when " - "viewing issue). If omitted, will be guessed automatically " - "for SVN repos and left blank for others.") -group.add_option("--download_base", action="store_true", - dest="download_base", default=False, - help="Base files will be downloaded by the server " - "(side-by-side diffs may not work on files with CRs).") -group.add_option("--rev", action="store", dest="revision", - metavar="REV", default=None, - help="Base revision/branch/tree to diff against. Use " - "rev1:rev2 range to review already committed changeset.") -group.add_option("--send_mail", action="store_true", - dest="send_mail", default=False, - help="Send notification email to reviewers.") -group.add_option("-p", "--send_patch", action="store_true", - dest="send_patch", default=False, - help="Same as --send_mail, but include diff as an " - "attachment, and prepend email subject with 'PATCH:'.") -group.add_option("--vcs", action="store", dest="vcs", - metavar="VCS", default=None, - help=("Version control system (optional, usually upload.py " - "already guesses the right VCS).")) -group.add_option("--emulate_svn_auto_props", action="store_true", - dest="emulate_svn_auto_props", default=False, - help=("Emulate Subversion's auto properties feature.")) -# Perforce-specific -group = parser.add_option_group("Perforce-specific options " - "(overrides P4 environment variables)") -group.add_option("--p4_port", action="store", dest="p4_port", - metavar="P4_PORT", default=None, - help=("Perforce server and port (optional)")) -group.add_option("--p4_changelist", action="store", dest="p4_changelist", - metavar="P4_CHANGELIST", default=None, - help=("Perforce changelist id")) -group.add_option("--p4_client", action="store", dest="p4_client", - metavar="P4_CLIENT", default=None, - help=("Perforce client/workspace")) -group.add_option("--p4_user", action="store", dest="p4_user", - metavar="P4_USER", default=None, - help=("Perforce user")) - -def GetRpcServer(server, email=None, host_override=None, save_cookies=True, - account_type=AUTH_ACCOUNT_TYPE): - """Returns an instance of an AbstractRpcServer. - - Args: - server: String containing the review server URL. - email: String containing user's email address. - host_override: If not None, string containing an alternate hostname to use - in the host header. - save_cookies: Whether authentication cookies should be saved to disk. - account_type: Account type for authentication, either 'GOOGLE' - or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. - - Returns: - A new AbstractRpcServer, on which RPC calls can be made. - """ - - rpc_server_class = HttpRpcServer - - # If this is the dev_appserver, use fake authentication. - host = (host_override or server).lower() - if re.match(r'(http://)?localhost([:/]|$)', host): - if email is None: - email = "test@example.com" - logging.info("Using debug user %s. Override with --email" % email) - server = rpc_server_class( - server, - lambda: (email, "password"), - host_override=host_override, - extra_headers={"Cookie": - 'dev_appserver_login="%s:False"' % email}, - save_cookies=save_cookies, - account_type=account_type) - # Don't try to talk to ClientLogin. - server.authenticated = True - return server - - def GetUserCredentials(): - """Prompts the user for a username and password.""" - # Create a local alias to the email variable to avoid Python's crazy - # scoping rules. - global keyring - local_email = email - if local_email is None: - local_email = GetEmail("Email (login for uploading to %s)" % server) - password = None - if keyring: - try: - password = keyring.get_password(host, local_email) - except: - # Sadly, we have to trap all errors here as - # gnomekeyring.IOError inherits from object. :/ - print "Failed to get password from keyring" - keyring = None - if password is not None: - print "Using password from system keyring." - else: - password = getpass.getpass("Password for %s: " % local_email) - if keyring: - answer = raw_input("Store password in system keyring?(y/N) ").strip() - if answer == "y": - keyring.set_password(host, local_email, password) - return (local_email, password) - - return rpc_server_class(server, - GetUserCredentials, - host_override=host_override, - save_cookies=save_cookies) - - -def EncodeMultipartFormData(fields, files): - """Encode form fields for multipart/form-data. - - Args: - fields: A sequence of (name, value) elements for regular form fields. - files: A sequence of (name, filename, value) elements for data to be - uploaded as files. - Returns: - (content_type, body) ready for httplib.HTTP instance. - - Source: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 - """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - for (key, value) in fields: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - for (key, filename, value) in files: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - lines.append('Content-Type: %s' % GetContentType(filename)) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - -def GetContentType(filename): - """Helper to guess the content-type from the filename.""" - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - -# Use a shell for subcommands on Windows to get a PATH search. -use_shell = sys.platform.startswith("win") - -def RunShellWithReturnCodeAndStderr(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout, stderr and the return code. - - Args: - command: Command to execute. - print_output: If True, the output is printed to stdout. - If False, both stdout and stderr are ignored. - universal_newlines: Use universal_newlines flag (default: True). - - Returns: - Tuple (stdout, stderr, return code) - """ - logging.info("Running %s", command) - env = env.copy() - env['LC_MESSAGES'] = 'C' - p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=use_shell, universal_newlines=universal_newlines, - env=env) - if print_output: - output_array = [] - while True: - line = p.stdout.readline() - if not line: - break - print line.strip("\n") - output_array.append(line) - output = "".join(output_array) - else: - output = p.stdout.read() - p.wait() - errout = p.stderr.read() - if print_output and errout: - print >>sys.stderr, errout - p.stdout.close() - p.stderr.close() - return output, errout, p.returncode - -def RunShellWithReturnCode(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout and the return code.""" - out, err, retcode = RunShellWithReturnCodeAndStderr(command, print_output, - universal_newlines, env) - return out, retcode - -def RunShell(command, silent_ok=False, universal_newlines=True, - print_output=False, env=os.environ): - data, retcode = RunShellWithReturnCode(command, print_output, - universal_newlines, env) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) - if not silent_ok and not data: - ErrorExit("No output from %s" % command) - return data - - -class VersionControlSystem(object): - """Abstract base class providing an interface to the VCS.""" - - def __init__(self, options): - """Constructor. - - Args: - options: Command line options. - """ - self.options = options - - def GetGUID(self): - """Return string to distinguish the repository from others, for example to - query all opened review issues for it""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def PostProcessDiff(self, diff): - """Return the diff with any special post processing this VCS needs, e.g. - to include an svn-style "Index:".""" - return diff - - def GenerateDiff(self, args): - """Return the current diff as a string. - - Args: - args: Extra arguments to pass to the diff command. - """ - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def CheckForUnknownFiles(self): - """Show an "are you sure?" prompt if there are unknown files.""" - unknown_files = self.GetUnknownFiles() - if unknown_files: - print "The following files are not added to version control:" - for line in unknown_files: - print line - prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() - if answer != "y": - ErrorExit("User aborted") - - def GetBaseFile(self, filename): - """Get the content of the upstream version of a file. - - Returns: - A tuple (base_content, new_content, is_binary, status) - base_content: The contents of the base file. - new_content: For text files, this is empty. For binary files, this is - the contents of the new file, since the diff output won't contain - information to reconstruct the current file. - is_binary: True iff the file is binary. - status: The status of the file. - """ - - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - - def GetBaseFiles(self, diff): - """Helper that calls GetBase file for each file in the patch. - - Returns: - A dictionary that maps from filename to GetBaseFile's tuple. Filenames - are retrieved based on lines that start with "Index:" or - "Property changes on:". - """ - files = {} - for line in diff.splitlines(True): - if line.startswith('Index:') or line.startswith('Property changes on:'): - unused, filename = line.split(':', 1) - # On Windows if a file has property changes its filename uses '\' - # instead of '/'. - filename = filename.strip().replace('\\', '/') - files[filename] = self.GetBaseFile(filename) - return files - - - def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, - files): - """Uploads the base files (and if necessary, the current ones as well).""" - - def UploadFile(filename, file_id, content, is_binary, status, is_base): - """Uploads a file to the server.""" - file_too_large = False - if is_base: - type = "base" - else: - type = "current" - if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % - (type, filename)) - file_too_large = True - content = "" - checksum = md5(content).hexdigest() - if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) - url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) - form_fields = [("filename", filename), - ("status", status), - ("checksum", checksum), - ("is_binary", str(is_binary)), - ("is_current", str(not is_base)), - ] - if file_too_large: - form_fields.append(("file_too_large", "1")) - if options.email: - form_fields.append(("user", options.email)) - ctype, body = EncodeMultipartFormData(form_fields, - [("data", filename, content)]) - response_body = rpc_server.Send(url, body, - content_type=ctype) - if not response_body.startswith("OK"): - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - - patches = dict() - [patches.setdefault(v, k) for k, v in patch_list] - for filename in patches.keys(): - base_content, new_content, is_binary, status = files[filename] - file_id_str = patches.get(filename) - if file_id_str.find("nobase") != -1: - base_content = None - file_id_str = file_id_str[file_id_str.rfind("_") + 1:] - file_id = int(file_id_str) - if base_content != None: - UploadFile(filename, file_id, base_content, is_binary, status, True) - if new_content != None: - UploadFile(filename, file_id, new_content, is_binary, status, False) - - def IsImage(self, filename): - """Returns true if the filename has an image extension.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False - return mimetype.startswith("image/") - - def IsBinaryData(self, data): - """Returns true if data contains a null byte.""" - # Derived from how Mercurial's heuristic, see - # http://selenic.com/hg/file/848a6658069e/mercurial/util.py#l229 - return bool(data and "\0" in data) - - -class SubversionVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Subversion.""" - - def __init__(self, options): - super(SubversionVCS, self).__init__(options) - if self.options.revision: - match = re.match(r"(\d+)(:(\d+))?", self.options.revision) - if not match: - ErrorExit("Invalid Subversion revision %s." % self.options.revision) - self.rev_start = match.group(1) - self.rev_end = match.group(3) - else: - self.rev_start = self.rev_end = None - # Cache output from "svn list -r REVNO dirname". - # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). - self.svnls_cache = {} - # Base URL is required to fetch files deleted in an older revision. - # Result is cached to not guess it over and over again in GetBaseFile(). - required = self.options.download_base or self.options.revision is not None - self.svn_base = self._GuessBase(required) - - def GetGUID(self): - return self._GetInfo("Repository UUID") - - def GuessBase(self, required): - """Wrapper for _GuessBase.""" - return self.svn_base - - def _GuessBase(self, required): - """Returns base URL for current diff. - - Args: - required: If true, exits if the url can't be guessed, otherwise None is - returned. - """ - url = self._GetInfo("URL") - if url: - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - guess = "" - # TODO(anatoli) - repository specific hacks should be handled by server - if netloc == "svn.python.org" and scheme == "svn+ssh": - path = "projects" + path - scheme = "http" - guess = "Python " - elif netloc.endswith(".googlecode.com"): - scheme = "http" - guess = "Google Code " - path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - logging.info("Guessed %sbase = %s", guess, base) - return base - if required: - ErrorExit("Can't find URL in output from svn info") - return None - - def _GetInfo(self, key): - """Parses 'svn info' for current dir. Returns value for key or None""" - for line in RunShell(["svn", "info"]).splitlines(): - if line.startswith(key + ": "): - return line.split(":", 1)[1].strip() - - def _EscapeFilename(self, filename): - """Escapes filename for SVN commands.""" - if "@" in filename and not filename.endswith("@"): - filename = "%s@" % filename - return filename - - def GenerateDiff(self, args): - cmd = ["svn", "diff"] - if self.options.revision: - cmd += ["-r", self.options.revision] - cmd.extend(args) - data = RunShell(cmd) - count = 0 - for line in data.splitlines(): - if line.startswith("Index:") or line.startswith("Property changes on:"): - count += 1 - logging.info(line) - if not count: - ErrorExit("No valid patches found in output from svn diff") - return data - - def _CollapseKeywords(self, content, keyword_str): - """Collapses SVN keywords.""" - # svn cat translates keywords but svn diff doesn't. As a result of this - # behavior patching.PatchChunks() fails with a chunk mismatch error. - # This part was originally written by the Review Board development team - # who had the same problem (http://reviews.review-board.org/r/276/). - # Mapping of keywords to known aliases - svn_keywords = { - # Standard keywords - 'Date': ['Date', 'LastChangedDate'], - 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], - 'Author': ['Author', 'LastChangedBy'], - 'HeadURL': ['HeadURL', 'URL'], - 'Id': ['Id'], - - # Aliases - 'LastChangedDate': ['LastChangedDate', 'Date'], - 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], - 'LastChangedBy': ['LastChangedBy', 'Author'], - 'URL': ['URL', 'HeadURL'], - } - - def repl(m): - if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) - return "$%s$" % m.group(1) - keywords = [keyword - for name in keyword_str.split(" ") - for keyword in svn_keywords.get(name, [])] - return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) - - def GetUnknownFiles(self): - status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) - unknown_files = [] - for line in status.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - - def ReadFile(self, filename): - """Returns the contents of a file.""" - file = open(filename, 'rb') - result = "" - try: - result = file.read() - finally: - file.close() - return result - - def GetStatus(self, filename): - """Returns the status of a file.""" - if not self.options.revision: - status = RunShell(["svn", "status", "--ignore-externals", - self._EscapeFilename(filename)]) - if not status: - ErrorExit("svn status returned no output for %s" % filename) - status_lines = status.splitlines() - # If file is in a cl, the output will begin with - # "\n--- Changelist 'cl_name':\n". See - # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt - if (len(status_lines) == 3 and - not status_lines[0] and - status_lines[1].startswith("--- Changelist")): - status = status_lines[2] - else: - status = status_lines[0] - # If we have a revision to diff against we need to run "svn list" - # for the old and the new revision and compare the results to get - # the correct status for a file. - else: - dirname, relfilename = os.path.split(filename) - if dirname not in self.svnls_cache: - cmd = ["svn", "list", "-r", self.rev_start, - self._EscapeFilename(dirname) or "."] - out, err, returncode = RunShellWithReturnCodeAndStderr(cmd) - if returncode: - # Directory might not yet exist at start revison - # svn: Unable to find repository location for 'abc' in revision nnn - if re.match('^svn: Unable to find repository location for .+ in revision \d+', err): - old_files = () - else: - ErrorExit("Failed to get status for %s:\n%s" % (filename, err)) - else: - old_files = out.splitlines() - args = ["svn", "list"] - if self.rev_end: - args += ["-r", self.rev_end] - cmd = args + [self._EscapeFilename(dirname) or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to run command %s" % cmd) - self.svnls_cache[dirname] = (old_files, out.splitlines()) - old_files, new_files = self.svnls_cache[dirname] - if relfilename in old_files and relfilename not in new_files: - status = "D " - elif relfilename in old_files and relfilename in new_files: - status = "M " - else: - status = "A " - return status - - def GetBaseFile(self, filename): - status = self.GetStatus(filename) - base_content = None - new_content = None - - # If a file is copied its status will be "A +", which signifies - # "addition-with-history". See "svn st" for more information. We need to - # upload the original file or else diff parsing will fail if the file was - # edited. - if status[0] == "A" and status[3] != "+": - # We'll need to upload the new content if we're adding a binary file - # since diff's output won't contain it. - mimetype = RunShell(["svn", "propget", "svn:mime-type", - self._EscapeFilename(filename)], silent_ok=True) - base_content = "" - is_binary = bool(mimetype) and not mimetype.startswith("text/") - if is_binary and self.IsImage(filename): - new_content = self.ReadFile(filename) - elif (status[0] in ("M", "D", "R") or - (status[0] == "A" and status[3] == "+") or # Copied file. - (status[0] == " " and status[1] == "M")): # Property change. - args = [] - if self.options.revision: - # filename must not be escaped. We already add an ampersand here. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - # Don't change filename, it's needed later. - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:mime-type", url] - mimetype, returncode = RunShellWithReturnCode(cmd) - if returncode: - # File does not exist in the requested revision. - # Reset mimetype, it contains an error message. - mimetype = "" - else: - mimetype = mimetype.strip() - get_base = False - # this test for binary is exactly the test prescribed by the - # official SVN docs at - # http://subversion.apache.org/faq.html#binary-files - is_binary = (bool(mimetype) and - not mimetype.startswith("text/") and - mimetype not in ("image/x-xbitmap", "image/x-xpixmap")) - if status[0] == " ": - # Empty base content just to force an upload. - base_content = "" - elif is_binary: - if self.IsImage(filename): - get_base = True - if status[0] == "M": - if not self.rev_end: - new_content = self.ReadFile(filename) - else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) - new_content = RunShell(["svn", "cat", url], - universal_newlines=True, silent_ok=True) - else: - base_content = "" - else: - get_base = True - - if get_base: - if is_binary: - universal_newlines = False - else: - universal_newlines = True - if self.rev_start: - # "svn cat -r REV delete_file.txt" doesn't work. cat requires - # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - else: - base_content, ret_code = RunShellWithReturnCode( - ["svn", "cat", self._EscapeFilename(filename)], - universal_newlines=universal_newlines) - if ret_code and status[0] == "R": - # It's a replaced file without local history (see issue208). - # The base file needs to be fetched from the server. - url = "%s/%s" % (self.svn_base, filename) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - elif ret_code: - ErrorExit("Got error status from 'svn cat %s'" % filename) - if not is_binary: - args = [] - if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:keywords", url] - keywords, returncode = RunShellWithReturnCode(cmd) - if keywords and not returncode: - base_content = self._CollapseKeywords(base_content, keywords) - else: - StatusUpdate("svn status returned unexpected output: %s" % status) - sys.exit(1) - return base_content, new_content, is_binary, status[0:5] - - -class GitVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Git.""" - - def __init__(self, options): - super(GitVCS, self).__init__(options) - # Map of filename -> (hash before, hash after) of base file. - # Hashes for "no such file" are represented as None. - self.hashes = {} - # Map of new filename -> old filename for renames. - self.renames = {} - - def GetGUID(self): - revlist = RunShell("git rev-list --parents HEAD".split()).splitlines() - # M-A: Return the 1st root hash, there could be multiple when a - # subtree is merged. In that case, more analysis would need to - # be done to figure out which HEAD is the 'most representative'. - for r in revlist: - if ' ' not in r: - return r - - def PostProcessDiff(self, gitdiff): - """Converts the diff output to include an svn-style "Index:" line as well - as record the hashes of the files, so we can upload them along with our - diff.""" - # Special used by git to indicate "no such content". - NULL_HASH = "0"*40 - - def IsFileNew(filename): - return filename in self.hashes and self.hashes[filename][0] is None - - def AddSubversionPropertyChange(filename): - """Add svn's property change information into the patch if given file is - new file. - - We use Subversion's auto-props setting to retrieve its property. - See http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2 for - Subversion's [auto-props] setting. - """ - if self.options.emulate_svn_auto_props and IsFileNew(filename): - svnprops = GetSubversionPropertyChanges(filename) - if svnprops: - svndiff.append("\n" + svnprops + "\n") - - svndiff = [] - filecount = 0 - filename = None - for line in gitdiff.splitlines(): - match = re.match(r"diff --git a/(.*) b/(.*)$", line) - if match: - # Add auto property here for previously seen file. - if filename is not None: - AddSubversionPropertyChange(filename) - filecount += 1 - # Intentionally use the "after" filename so we can show renames. - filename = match.group(2) - svndiff.append("Index: %s\n" % filename) - if match.group(1) != match.group(2): - self.renames[match.group(2)] = match.group(1) - else: - # The "index" line in a git diff looks like this (long hashes elided): - # index 82c0d44..b2cee3f 100755 - # We want to save the left hash, as that identifies the base file. - match = re.match(r"index (\w+)\.\.(\w+)", line) - if match: - before, after = (match.group(1), match.group(2)) - if before == NULL_HASH: - before = None - if after == NULL_HASH: - after = None - self.hashes[filename] = (before, after) - svndiff.append(line + "\n") - if not filecount: - ErrorExit("No valid patches found in output from git diff") - # Add auto property for the last seen file. - assert filename is not None - AddSubversionPropertyChange(filename) - return "".join(svndiff) - - def GenerateDiff(self, extra_args): - extra_args = extra_args[:] - if self.options.revision: - if ":" in self.options.revision: - extra_args = self.options.revision.split(":", 1) + extra_args - else: - extra_args = [self.options.revision] + extra_args - - # --no-ext-diff is broken in some versions of Git, so try to work around - # this by overriding the environment (but there is still a problem if the - # git config key "diff.external" is used). - env = os.environ.copy() - if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] - return RunShell( - [ "git", "diff", "--no-color", "--no-ext-diff", "--full-index", - "--ignore-submodules", "-M"] + extra_args, - env=env) - - def GetUnknownFiles(self): - status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], - silent_ok=True) - return status.splitlines() - - def GetFileContent(self, file_hash, is_binary): - """Returns the content of a file identified by its git hash.""" - data, retcode = RunShellWithReturnCode(["git", "show", file_hash], - universal_newlines=not is_binary) - if retcode: - ErrorExit("Got error status from 'git show %s'" % file_hash) - return data - - def GetBaseFile(self, filename): - hash_before, hash_after = self.hashes.get(filename, (None,None)) - base_content = None - new_content = None - status = None - - if filename in self.renames: - status = "A +" # Match svn attribute name for renames. - if filename not in self.hashes: - # If a rename doesn't change the content, we never get a hash. - base_content = RunShell( - ["git", "show", "HEAD:" + filename], silent_ok=True) - elif not hash_before: - status = "A" - base_content = "" - elif not hash_after: - status = "D" - else: - status = "M" - - is_binary = self.IsBinaryData(base_content) - is_image = self.IsImage(filename) - - # Grab the before/after content if we need it. - # We should include file contents if it's text or it's an image. - if not is_binary or is_image: - # Grab the base content if we don't have it already. - if base_content is None and hash_before: - base_content = self.GetFileContent(hash_before, is_binary) - # Only include the "after" file if it's an image; otherwise it - # it is reconstructed from the diff. - if is_image and hash_after: - new_content = self.GetFileContent(hash_after, is_binary) - - return (base_content, new_content, is_binary, status) - - -class CVSVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for CVS.""" - - def __init__(self, options): - super(CVSVCS, self).__init__(options) - - def GetGUID(self): - """For now we don't know how to get repository ID for CVS""" - return - - def GetOriginalContent_(self, filename): - RunShell(["cvs", "up", filename], silent_ok=True) - # TODO need detect file content encoding - content = open(filename).read() - return content.replace("\r\n", "\n") - - def GetBaseFile(self, filename): - base_content = None - new_content = None - status = "A" - - output, retcode = RunShellWithReturnCode(["cvs", "status", filename]) - if retcode: - ErrorExit("Got error status from 'cvs status %s'" % filename) - - if output.find("Status: Locally Modified") != -1: - status = "M" - temp_filename = "%s.tmp123" % filename - os.rename(filename, temp_filename) - base_content = self.GetOriginalContent_(filename) - os.rename(temp_filename, filename) - elif output.find("Status: Locally Added"): - status = "A" - base_content = "" - elif output.find("Status: Needs Checkout"): - status = "D" - base_content = self.GetOriginalContent_(filename) - - return (base_content, new_content, self.IsBinaryData(base_content), status) - - def GenerateDiff(self, extra_args): - cmd = ["cvs", "diff", "-u", "-N"] - if self.options.revision: - cmd += ["-r", self.options.revision] - - cmd.extend(extra_args) - data, retcode = RunShellWithReturnCode(cmd) - count = 0 - if retcode in [0, 1]: - for line in data.splitlines(): - if line.startswith("Index:"): - count += 1 - logging.info(line) - - if not count: - ErrorExit("No valid patches found in output from cvs diff") - - return data - - def GetUnknownFiles(self): - data, retcode = RunShellWithReturnCode(["cvs", "diff"]) - if retcode not in [0, 1]: - ErrorExit("Got error status from 'cvs diff':\n%s" % (data,)) - unknown_files = [] - for line in data.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - -class MercurialVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Mercurial.""" - - def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) - # Absolute path to repository (we can be in a subdir) - self.repo_dir = os.path.normpath(repo_dir) - # Compute the subdir - cwd = os.path.normpath(os.getcwd()) - assert cwd.startswith(self.repo_dir) - self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") - if self.options.revision: - self.base_rev = self.options.revision - else: - self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() - - def GetGUID(self): - # See chapter "Uniquely identifying a repository" - # http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html - info = RunShell("hg log -r0 --template {node}".split()) - return info.strip() - - def _GetRelPath(self, filename): - """Get relative path of a file according to the current directory, - given its logical path in the repo.""" - absname = os.path.join(self.repo_dir, filename) - return os.path.relpath(absname) - - def GenerateDiff(self, extra_args): - cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args - data = RunShell(cmd, silent_ok=True) - svndiff = [] - filecount = 0 - for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) - if m: - # Modify line to make it look like as it comes from svn diff. - # With this modification no changes on the server side are required - # to make upload.py work with Mercurial repos. - # NOTE: for proper handling of moved/copied files, we have to use - # the second filename. - filename = m.group(2) - svndiff.append("Index: %s" % filename) - svndiff.append("=" * 67) - filecount += 1 - logging.info(line) - else: - svndiff.append(line) - if not filecount: - ErrorExit("No valid patches found in output from hg diff") - return "\n".join(svndiff) + "\n" - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - args = [] - status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], - silent_ok=True) - unknown_files = [] - for line in status.splitlines(): - st, fn = line.split(" ", 1) - if st == "?": - unknown_files.append(fn) - return unknown_files - - def GetBaseFile(self, filename): - # "hg status" and "hg cat" both take a path relative to the current subdir, - # but "hg diff" has given us the path relative to the repo root. - base_content = "" - new_content = None - is_binary = False - oldrelpath = relpath = self._GetRelPath(filename) - # "hg status -C" returns two lines for moved/copied files, one otherwise - out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) - out = out.splitlines() - # HACK: strip error message about missing file/directory if it isn't in - # the working copy - if out[0].startswith('%s: ' % relpath): - out = out[1:] - status, _ = out[0].split(' ', 1) - if len(out) > 1 and status == "A": - # Moved/copied => considered as modified, use old filename to - # retrieve base contents - oldrelpath = out[1].strip() - status = "M" - if ":" in self.base_rev: - base_rev = self.base_rev.split(":", 1)[0] - else: - base_rev = self.base_rev - if status != "A": - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True) - is_binary = self.IsBinaryData(base_content) - if status != "R": - new_content = open(relpath, "rb").read() - is_binary = is_binary or self.IsBinaryData(new_content) - if is_binary and base_content: - # Fetch again without converting newlines - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True, universal_newlines=False) - if not is_binary or not self.IsImage(relpath): - new_content = None - return base_content, new_content, is_binary, status - - -class PerforceVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Perforce.""" - - def __init__(self, options): - - def ConfirmLogin(): - # Make sure we have a valid perforce session - while True: - data, retcode = self.RunPerforceCommandWithReturnCode( - ["login", "-s"], marshal_output=True) - if not data: - ErrorExit("Error checking perforce login") - if not retcode and (not "code" in data or data["code"] != "error"): - break - print "Enter perforce password: " - self.RunPerforceCommandWithReturnCode(["login"]) - - super(PerforceVCS, self).__init__(options) - - self.p4_changelist = options.p4_changelist - if not self.p4_changelist: - ErrorExit("A changelist id is required") - if (options.revision): - ErrorExit("--rev is not supported for perforce") - - self.p4_port = options.p4_port - self.p4_client = options.p4_client - self.p4_user = options.p4_user - - ConfirmLogin() - - if not options.title: - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - if description and "desc" in description: - # Rietveld doesn't support multi-line descriptions - raw_title = description["desc"].strip() - lines = raw_title.splitlines() - if len(lines): - options.title = lines[0] - - def GetGUID(self): - """For now we don't know how to get repository ID for Perforce""" - return - - def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False, - universal_newlines=True): - args = ["p4"] - if marshal_output: - # -G makes perforce format its output as marshalled python objects - args.extend(["-G"]) - if self.p4_port: - args.extend(["-p", self.p4_port]) - if self.p4_client: - args.extend(["-c", self.p4_client]) - if self.p4_user: - args.extend(["-u", self.p4_user]) - args.extend(extra_args) - - data, retcode = RunShellWithReturnCode( - args, print_output=False, universal_newlines=universal_newlines) - if marshal_output and data: - data = marshal.loads(data) - return data, retcode - - def RunPerforceCommand(self, extra_args, marshal_output=False, - universal_newlines=True): - # This might be a good place to cache call results, since things like - # describe or fstat might get called repeatedly. - data, retcode = self.RunPerforceCommandWithReturnCode( - extra_args, marshal_output, universal_newlines) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (extra_args, data)) - return data - - def GetFileProperties(self, property_key_prefix = "", command = "describe"): - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - - changed_files = {} - file_index = 0 - # Try depotFile0, depotFile1, ... until we don't find a match - while True: - file_key = "depotFile%d" % file_index - if file_key in description: - filename = description[file_key] - change_type = description[property_key_prefix + str(file_index)] - changed_files[filename] = change_type - file_index += 1 - else: - break - return changed_files - - def GetChangedFiles(self): - return self.GetFileProperties("action") - - def GetUnknownFiles(self): - # Perforce doesn't detect new files, they have to be explicitly added - return [] - - def IsBaseBinary(self, filename): - base_filename = self.GetBaseFilename(filename) - return self.IsBinaryHelper(base_filename, "files") - - def IsPendingBinary(self, filename): - return self.IsBinaryHelper(filename, "describe") - - def IsBinaryHelper(self, filename, command): - file_types = self.GetFileProperties("type", command) - if not filename in file_types: - ErrorExit("Trying to check binary status of unknown file %s." % filename) - # This treats symlinks, macintosh resource files, temporary objects, and - # unicode as binary. See the Perforce docs for more details: - # http://www.perforce.com/perforce/doc.current/manuals/cmdref/o.ftypes.html - return not file_types[filename].endswith("text") - - def GetFileContent(self, filename, revision, is_binary): - file_arg = filename - if revision: - file_arg += "#" + revision - # -q suppresses the initial line that displays the filename and revision - return self.RunPerforceCommand(["print", "-q", file_arg], - universal_newlines=not is_binary) - - def GetBaseFilename(self, filename): - actionsWithDifferentBases = [ - "move/add", # p4 move - "branch", # p4 integrate (to a new file), similar to hg "add" - "add", # p4 integrate (to a new file), after modifying the new file - ] - - # We only see a different base for "add" if this is a downgraded branch - # after a file was branched (integrated), then edited. - if self.GetAction(filename) in actionsWithDifferentBases: - # -Or shows information about pending integrations/moves - fstat_result = self.RunPerforceCommand(["fstat", "-Or", filename], - marshal_output=True) - - baseFileKey = "resolveFromFile0" # I think it's safe to use only file0 - if baseFileKey in fstat_result: - return fstat_result[baseFileKey] - - return filename - - def GetBaseRevision(self, filename): - base_filename = self.GetBaseFilename(filename) - - have_result = self.RunPerforceCommand(["have", base_filename], - marshal_output=True) - if "haveRev" in have_result: - return have_result["haveRev"] - - def GetLocalFilename(self, filename): - where = self.RunPerforceCommand(["where", filename], marshal_output=True) - if "path" in where: - return where["path"] - - def GenerateDiff(self, args): - class DiffData: - def __init__(self, perforceVCS, filename, action): - self.perforceVCS = perforceVCS - self.filename = filename - self.action = action - self.base_filename = perforceVCS.GetBaseFilename(filename) - - self.file_body = None - self.base_rev = None - self.prefix = None - self.working_copy = True - self.change_summary = None - - def GenerateDiffHeader(diffData): - header = [] - header.append("Index: %s" % diffData.filename) - header.append("=" * 67) - - if diffData.base_filename != diffData.filename: - if diffData.action.startswith("move"): - verb = "rename" - else: - verb = "copy" - header.append("%s from %s" % (verb, diffData.base_filename)) - header.append("%s to %s" % (verb, diffData.filename)) - - suffix = "\t(revision %s)" % diffData.base_rev - header.append("--- " + diffData.base_filename + suffix) - if diffData.working_copy: - suffix = "\t(working copy)" - header.append("+++ " + diffData.filename + suffix) - if diffData.change_summary: - header.append(diffData.change_summary) - return header - - def GenerateMergeDiff(diffData, args): - # -du generates a unified diff, which is nearly svn format - diffData.file_body = self.RunPerforceCommand( - ["diff", "-du", diffData.filename] + args) - diffData.base_rev = self.GetBaseRevision(diffData.filename) - diffData.prefix = "" - - # We have to replace p4's file status output (the lines starting - # with +++ or ---) to match svn's diff format - lines = diffData.file_body.splitlines() - first_good_line = 0 - while (first_good_line < len(lines) and - not lines[first_good_line].startswith("@@")): - first_good_line += 1 - diffData.file_body = "\n".join(lines[first_good_line:]) - return diffData - - def GenerateAddDiff(diffData): - fstat = self.RunPerforceCommand(["fstat", diffData.filename], - marshal_output=True) - if "headRev" in fstat: - diffData.base_rev = fstat["headRev"] # Re-adding a deleted file - else: - diffData.base_rev = "0" # Brand new file - diffData.working_copy = False - rel_path = self.GetLocalFilename(diffData.filename) - diffData.file_body = open(rel_path, 'r').read() - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -0,0 +1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " @@" - diffData.prefix = "+" - return diffData - - def GenerateDeleteDiff(diffData): - diffData.base_rev = self.GetBaseRevision(diffData.filename) - is_base_binary = self.IsBaseBinary(diffData.filename) - # For deletes, base_filename == filename - diffData.file_body = self.GetFileContent(diffData.base_filename, - None, - is_base_binary) - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " +0,0 @@" - diffData.prefix = "-" - return diffData - - changed_files = self.GetChangedFiles() - - svndiff = [] - filecount = 0 - for (filename, action) in changed_files.items(): - svn_status = self.PerforceActionToSvnStatus(action) - if svn_status == "SKIP": - continue - - diffData = DiffData(self, filename, action) - # Is it possible to diff a branched file? Stackoverflow says no: - # http://stackoverflow.com/questions/1771314/in-perforce-command-line-how-to-diff-a-file-reopened-for-add - if svn_status == "M": - diffData = GenerateMergeDiff(diffData, args) - elif svn_status == "A": - diffData = GenerateAddDiff(diffData) - elif svn_status == "D": - diffData = GenerateDeleteDiff(diffData) - else: - ErrorExit("Unknown file action %s (svn action %s)." % \ - (action, svn_status)) - - svndiff += GenerateDiffHeader(diffData) - - for line in diffData.file_body.splitlines(): - svndiff.append(diffData.prefix + line) - filecount += 1 - if not filecount: - ErrorExit("No valid patches found in output from p4 diff") - return "\n".join(svndiff) + "\n" - - def PerforceActionToSvnStatus(self, status): - # Mirroring the list at http://permalink.gmane.org/gmane.comp.version-control.mercurial.devel/28717 - # Is there something more official? - return { - "add" : "A", - "branch" : "A", - "delete" : "D", - "edit" : "M", # Also includes changing file types. - "integrate" : "M", - "move/add" : "M", - "move/delete": "SKIP", - "purge" : "D", # How does a file's status become "purge"? - }[status] - - def GetAction(self, filename): - changed_files = self.GetChangedFiles() - if not filename in changed_files: - ErrorExit("Trying to get base version of unknown file %s." % filename) - - return changed_files[filename] - - def GetBaseFile(self, filename): - base_filename = self.GetBaseFilename(filename) - base_content = "" - new_content = None - - status = self.PerforceActionToSvnStatus(self.GetAction(filename)) - - if status != "A": - revision = self.GetBaseRevision(base_filename) - if not revision: - ErrorExit("Couldn't find base revision for file %s" % filename) - is_base_binary = self.IsBaseBinary(base_filename) - base_content = self.GetFileContent(base_filename, - revision, - is_base_binary) - - is_binary = self.IsPendingBinary(filename) - if status != "D" and status != "SKIP": - relpath = self.GetLocalFilename(filename) - if is_binary and self.IsImage(relpath): - new_content = open(relpath, "rb").read() - - return base_content, new_content, is_binary, status - -# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. -def SplitPatch(data): - """Splits a patch into separate pieces for each file. - - Args: - data: A string containing the output of svn diff. - - Returns: - A list of 2-tuple (filename, text) where text is the svn diff output - pertaining to filename. - """ - patches = [] - filename = None - diff = [] - for line in data.splitlines(True): - new_filename = None - if line.startswith('Index:'): - unused, new_filename = line.split(':', 1) - new_filename = new_filename.strip() - elif line.startswith('Property changes on:'): - unused, temp_filename = line.split(':', 1) - # When a file is modified, paths use '/' between directories, however - # when a property is modified '\' is used on Windows. Make them the same - # otherwise the file shows up twice. - temp_filename = temp_filename.strip().replace('\\', '/') - if temp_filename != filename: - # File has property changes but no modifications, create a new diff. - new_filename = temp_filename - if new_filename: - if filename and diff: - patches.append((filename, ''.join(diff))) - filename = new_filename - diff = [line] - continue - if diff is not None: - diff.append(line) - if filename and diff: - patches.append((filename, ''.join(diff))) - return patches - - -def UploadSeparatePatches(issue, rpc_server, patchset, data, options): - """Uploads a separate patch for each file in the diff output. - - Returns a list of [patch_key, filename] for each file. - """ - patches = SplitPatch(data) - rv = [] - for patch in patches: - if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + - " because the file is too large.") - continue - form_fields = [("filename", patch[0])] - if not options.download_base: - form_fields.append(("content_upload", "1")) - files = [("data", "data.diff", patch[1])] - ctype, body = EncodeMultipartFormData(form_fields, files) - url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] - response_body = rpc_server.Send(url, body, content_type=ctype) - lines = response_body.splitlines() - if not lines or lines[0] != "OK": - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - rv.append([lines[1], patch[0]]) - return rv - - -def GuessVCSName(options): - """Helper to guess the version control system. - - This examines the current directory, guesses which VersionControlSystem - we're using, and returns an string indicating which VCS is detected. - - Returns: - A pair (vcs, output). vcs is a string indicating which VCS was detected - and is one of VCS_GIT, VCS_MERCURIAL, VCS_SUBVERSION, VCS_PERFORCE, - VCS_CVS, or VCS_UNKNOWN. - Since local perforce repositories can't be easily detected, this method - will only guess VCS_PERFORCE if any perforce options have been specified. - output is a string containing any interesting output from the vcs - detection routine, or None if there is nothing interesting. - """ - for attribute, value in options.__dict__.iteritems(): - if attribute.startswith("p4") and value != None: - return (VCS_PERFORCE, None) - - def RunDetectCommand(vcs_type, command): - """Helper to detect VCS by executing command. - - Returns: - A pair (vcs, output) or None. Throws exception on error. - """ - try: - out, returncode = RunShellWithReturnCode(command) - if returncode == 0: - return (vcs_type, out.strip()) - except OSError, (errcode, message): - if errcode != errno.ENOENT: # command not found code - raise - - # Mercurial has a command to get the base directory of a repository - # Try running it, but don't die if we don't have hg installed. - # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. - res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) - if res != None: - return res - - # Subversion from 1.7 has a single centralized .svn folder - # ( see http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng ) - # That's why we use 'svn info' instead of checking for .svn dir - res = RunDetectCommand(VCS_SUBVERSION, ["svn", "info"]) - if res != None: - return res - - # Git has a command to test if you're in a git tree. - # Try running it, but don't die if we don't have git installed. - res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", - "--is-inside-work-tree"]) - if res != None: - return res - - # detect CVS repos use `cvs status && $? == 0` rules - res = RunDetectCommand(VCS_CVS, ["cvs", "status"]) - if res != None: - return res - - return (VCS_UNKNOWN, None) - - -def GuessVCS(options): - """Helper to guess the version control system. - - This verifies any user-specified VersionControlSystem (by command line - or environment variable). If the user didn't specify one, this examines - the current directory, guesses which VersionControlSystem we're using, - and returns an instance of the appropriate class. Exit with an error - if we can't figure it out. - - Returns: - A VersionControlSystem instance. Exits if the VCS can't be guessed. - """ - vcs = options.vcs - if not vcs: - vcs = os.environ.get("CODEREVIEW_VCS") - if vcs: - v = VCS_ABBREVIATIONS.get(vcs.lower()) - if v is None: - ErrorExit("Unknown version control system %r specified." % vcs) - (vcs, extra_output) = (v, None) - else: - (vcs, extra_output) = GuessVCSName(options) - - if vcs == VCS_MERCURIAL: - if extra_output is None: - extra_output = RunShell(["hg", "root"]).strip() - return MercurialVCS(options, extra_output) - elif vcs == VCS_SUBVERSION: - return SubversionVCS(options) - elif vcs == VCS_PERFORCE: - return PerforceVCS(options) - elif vcs == VCS_GIT: - return GitVCS(options) - elif vcs == VCS_CVS: - return CVSVCS(options) - - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) - - -def CheckReviewer(reviewer): - """Validate a reviewer -- either a nickname or an email addres. - - Args: - reviewer: A nickname or an email address. - - Calls ErrorExit() if it is an invalid email address. - """ - if "@" not in reviewer: - return # Assume nickname - parts = reviewer.split("@") - if len(parts) > 2: - ErrorExit("Invalid email address: %r" % reviewer) - assert len(parts) == 2 - if "." not in parts[1]: - ErrorExit("Invalid email address: %r" % reviewer) - - -def LoadSubversionAutoProperties(): - """Returns the content of [auto-props] section of Subversion's config file as - a dictionary. - - Returns: - A dictionary whose key-value pair corresponds the [auto-props] section's - key-value pair. - In following cases, returns empty dictionary: - - config file doesn't exist, or - - 'enable-auto-props' is not set to 'true-like-value' in [miscellany]. - """ - if os.name == 'nt': - subversion_config = os.environ.get("APPDATA") + "\\Subversion\\config" - else: - subversion_config = os.path.expanduser("~/.subversion/config") - if not os.path.exists(subversion_config): - return {} - config = ConfigParser.ConfigParser() - config.read(subversion_config) - if (config.has_section("miscellany") and - config.has_option("miscellany", "enable-auto-props") and - config.getboolean("miscellany", "enable-auto-props") and - config.has_section("auto-props")): - props = {} - for file_pattern in config.options("auto-props"): - props[file_pattern] = ParseSubversionPropertyValues( - config.get("auto-props", file_pattern)) - return props - else: - return {} - -def ParseSubversionPropertyValues(props): - """Parse the given property value which comes from [auto-props] section and - returns a list whose element is a (svn_prop_key, svn_prop_value) pair. - - See the following doctest for example. - - >>> ParseSubversionPropertyValues('svn:eol-style=LF') - [('svn:eol-style', 'LF')] - >>> ParseSubversionPropertyValues('svn:mime-type=image/jpeg') - [('svn:mime-type', 'image/jpeg')] - >>> ParseSubversionPropertyValues('svn:eol-style=LF;svn:executable') - [('svn:eol-style', 'LF'), ('svn:executable', '*')] - """ - key_value_pairs = [] - for prop in props.split(";"): - key_value = prop.split("=") - assert len(key_value) <= 2 - if len(key_value) == 1: - # If value is not given, use '*' as a Subversion's convention. - key_value_pairs.append((key_value[0], "*")) - else: - key_value_pairs.append((key_value[0], key_value[1])) - return key_value_pairs - - -def GetSubversionPropertyChanges(filename): - """Return a Subversion's 'Property changes on ...' string, which is used in - the patch file. - - Args: - filename: filename whose property might be set by [auto-props] config. - - Returns: - A string like 'Property changes on |filename| ...' if given |filename| - matches any entries in [auto-props] section. None, otherwise. - """ - global svn_auto_props_map - if svn_auto_props_map is None: - svn_auto_props_map = LoadSubversionAutoProperties() - - all_props = [] - for file_pattern, props in svn_auto_props_map.items(): - if fnmatch.fnmatch(filename, file_pattern): - all_props.extend(props) - if all_props: - return FormatSubversionPropertyChanges(filename, all_props) - return None - - -def FormatSubversionPropertyChanges(filename, props): - """Returns Subversion's 'Property changes on ...' strings using given filename - and properties. - - Args: - filename: filename - props: A list whose element is a (svn_prop_key, svn_prop_value) pair. - - Returns: - A string which can be used in the patch file for Subversion. - - See the following doctest for example. - - >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) - Property changes on: foo.cc - ___________________________________________________________________ - Added: svn:eol-style - + LF - - """ - prop_changes_lines = [ - "Property changes on: %s" % filename, - "___________________________________________________________________"] - for key, value in props: - prop_changes_lines.append("Added: " + key) - prop_changes_lines.append(" + " + value) - return "\n".join(prop_changes_lines) + "\n" - - -def RealMain(argv, data=None): - """The real main function. - - Args: - argv: Command line arguments. - data: Diff contents. If None (default) the diff is generated by - the VersionControlSystem implementation returned by GuessVCS(). - - Returns: - A 2-tuple (issue id, patchset id). - The patchset id is None if the base files are not uploaded by this - script (applies only to SVN checkouts). - """ - options, args = parser.parse_args(argv[1:]) - if options.help: - if options.verbose < 2: - # hide Perforce options - parser.epilog = "Use '--help -v' to show additional Perforce options." - parser.option_groups.remove(parser.get_option_group('--p4_port')) - parser.print_help() - sys.exit(0) - - global verbosity - verbosity = options.verbose - if verbosity >= 3: - logging.getLogger().setLevel(logging.DEBUG) - elif verbosity >= 2: - logging.getLogger().setLevel(logging.INFO) - - vcs = GuessVCS(options) - - base = options.base_url - if isinstance(vcs, SubversionVCS): - # Guessing the base field is only supported for Subversion. - # Note: Fetching base files may become deprecated in future releases. - guessed_base = vcs.GuessBase(options.download_base) - if base: - if guessed_base and base != guessed_base: - print "Using base URL \"%s\" from --base_url instead of \"%s\"" % \ - (base, guessed_base) - else: - base = guessed_base - - if not base and options.download_base: - options.download_base = True - logging.info("Enabled upload of base file") - if not options.assume_yes: - vcs.CheckForUnknownFiles() - if data is None: - data = vcs.GenerateDiff(args) - data = vcs.PostProcessDiff(data) - if options.print_diffs: - print "Rietveld diff start:*****" - print data - print "Rietveld diff end:*****" - files = vcs.GetBaseFiles(data) - if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" - rpc_server = GetRpcServer(options.server, - options.email, - options.host, - options.save_cookies, - options.account_type) - form_fields = [] - - repo_guid = vcs.GetGUID() - if repo_guid: - form_fields.append(("repo_guid", repo_guid)) - if base: - b = urlparse.urlparse(base) - username, netloc = urllib.splituser(b.netloc) - if username: - logging.info("Removed username from base URL") - base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params, - b.query, b.fragment)) - form_fields.append(("base", base)) - if options.issue: - form_fields.append(("issue", str(options.issue))) - if options.email: - form_fields.append(("user", options.email)) - if options.reviewers: - for reviewer in options.reviewers.split(','): - CheckReviewer(reviewer) - form_fields.append(("reviewers", options.reviewers)) - if options.cc: - for cc in options.cc.split(','): - CheckReviewer(cc) - form_fields.append(("cc", options.cc)) - - # Process --message, --title and --file. - message = options.message or "" - title = options.title or "" - if options.file: - if options.message: - ErrorExit("Can't specify both message and message file options") - file = open(options.file, 'r') - message = file.read() - file.close() - if options.issue: - prompt = "Title describing this patch set: " - else: - prompt = "New issue subject: " - title = ( - title or message.split('\n', 1)[0].strip() or raw_input(prompt).strip()) - if not title and not options.issue: - ErrorExit("A non-empty title is required for a new issue") - # For existing issues, it's fine to give a patchset an empty name. Rietveld - # doesn't accept that so use a whitespace. - title = title or " " - if len(title) > 100: - title = title[:99] + '…' - if title and not options.issue: - message = message or title - - form_fields.append(("subject", title)) - # If it's a new issue send message as description. Otherwise a new - # message is created below on upload_complete. - if message and not options.issue: - form_fields.append(("description", message)) - - # Send a hash of all the base file so the server can determine if a copy - # already exists in an earlier patchset. - base_hashes = "" - for file, info in files.iteritems(): - if not info[0] is None: - checksum = md5(info[0]).hexdigest() - if base_hashes: - base_hashes += "|" - base_hashes += checksum + ":" + file - form_fields.append(("base_hashes", base_hashes)) - if options.private: - if options.issue: - print "Warning: Private flag ignored when updating an existing issue." - else: - form_fields.append(("private", "1")) - if options.send_patch: - options.send_mail = True - if not options.download_base: - form_fields.append(("content_upload", "1")) - if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." - uploaded_diff_file = [] - form_fields.append(("separate_patches", "1")) - else: - uploaded_diff_file = [("data", "data.diff", data)] - ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) - response_body = rpc_server.Send("/upload", body, content_type=ctype) - patchset = None - if not options.download_base or not uploaded_diff_file: - lines = response_body.splitlines() - if len(lines) >= 2: - msg = lines[0] - patchset = lines[1].strip() - patches = [x.split(" ", 1) for x in lines[2:]] - else: - msg = response_body - else: - msg = response_body - StatusUpdate(msg) - if not response_body.startswith("Issue created.") and \ - not response_body.startswith("Issue updated."): - sys.exit(0) - issue = msg[msg.rfind("/")+1:] - - if not uploaded_diff_file: - result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) - if not options.download_base: - patches = result - - if not options.download_base: - vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) - - payload = {} # payload for final request - if options.send_mail: - payload["send_mail"] = "yes" - if options.send_patch: - payload["attach_patch"] = "yes" - if options.issue and message: - payload["message"] = message - payload = urllib.urlencode(payload) - rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""), - payload=payload) - return issue, patchset - - -def main(): - try: - logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" - "%(lineno)s %(message)s ")) - os.environ['LC_ALL'] = 'C' - RealMain(sys.argv) - except KeyboardInterrupt: - print - StatusUpdate("Interrupted.") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/package.json b/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/package.json deleted file mode 100644 index 044e12e41d7..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/node_modules/mongoskin/package.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "name": "mongoskin", - "description": "The future layer above node-mongodb-native", - "version": "0.5.0", - "author": { - "name": "Gui Lin", - "email": "guileen@gmail.com" - }, - "homepage": "https://github.com/kissjs/node-mongoskin", - "repository": { - "type": "git", - "url": "git://github.com/guileen/node-mongoskin.git" - }, - "bugs": { - "url": "https://github.com/kissjs/node-mongoskin/issues" - }, - "main": "./index.js", - "keywords": [ - "mongodb", - "database", - "nosql" - ], - "engines": { - "node": ">= 0.4.0" - }, - "dependencies": { - "mongodb": "1.2.x" - }, - "devDependencies": { - "mocha": "*", - "jscover": "*", - "should": "*" - }, - "scripts": { - "test": "make test" - }, - "directories": { - "example": "./examples", - "lib": "./lib/mongoskin" - }, - "license": "MIT", - "contributors": [ - { - "name": "Gui Lin", - "email": "guileen@gmail.com", - "url": "https://github.com/guileen" - }, - { - "name": "François de Metz", - "email": "francois@2metz.fr", - "url": "https://github.com/francois2metz" - }, - { - "name": "fengmk2", - "email": "fengmk2@gmail.com", - "url": "http://fengmk2.github.com" - }, - { - "name": "Quang Van", - "email": "quangvvv@gmail.com", - "url": "https://github.com/quangv" - }, - { - "name": "Matt Perpick", - "email": "clutchski@gmail.com", - "url": "https://github.com/clutchski" - }, - { - "name": "humanchimp", - "email": "morphcham@gmail.com", - "url": "https://github.com/humanchimp" - }, - { - "name": "Joe Faber", - "email": "joe.faber@mandiant.com", - "url": "https://github.com/jlfaber" - }, - { - "name": "Harvey McQueen", - "email": "hmcqueen@gmail.com", - "url": "https://github.com/hmcqueen" - }, - { - "name": "Paul Gebheim", - "email": "pgebheim@monkeyinferno.com", - "url": "https://github.com/paulirish" - }, - { - "name": "Aneil Mallavarapu", - "email": "aneil@blipboard.com", - "url": "https://github.com/amallavarapu" - }, - { - "name": "wmertens", - "email": "Wout.Mertens@gmail.com", - "url": "https://github.com/wmertens" - }, - { - "name": "Rakshit Menpara", - "email": "deltasquare4@gmail.com", - "url": "https://github.com/deltasquare4" - } - ], - "readme": "# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin)\n\n![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png)\n\nThis project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native).\nThe api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first.\n\n## Test\n\n* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md)\n* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html)\n\n## Test pass [mongodb] versions\n\n* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` \n when connection open error.\n* 1.0.x\n* 1.1.x\n* 1.2.x\n\n```bash\n$ make test\n```\n\n\n\n# Mongoskin document\n\n* [Nodejs mongodb drivers comparation](#comparation)\n* [Install](#install)\n* [Quick Start](#quickstart)\n * [Connect easier](#quickstart-1)\n * [Server options and BSON options](#quickstart-2)\n * [Similar API with node-mongodb-native](#quickstart-3)\n * [Cursor easier](#quickstart-4)\n * [MVC helper](#quickstart-5)\n* [Documentation](#documentation)\n * [Module](#module)\n * [SkinServer](#skinserver)\n * [SkinDb](#skindb)\n * [SkinCollection](#skincollection)\n * [Additional methods](#additional-collection-op)\n * [Collection operation](#inherit-collection-op)\n * [Indexes](#inherit-indexes)\n * [Querying](#inherit-query)\n * [Aggregation](#inherit-aggregation)\n * [Inserting](#inherit-inserting)\n * [Updating](#inherit-updating)\n * [Removing](#inherit-removing)\n * [SkinCursor](#skincursor)\n\n\n\nNodejs Mongodb Driver Comparison\n========\n\nnode-mongodb-native\n--------\n\nOne of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build\non top of it, including mongoskin. Unfortunately, it has an awkward interface with too many \ncallbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model.\n \nSee [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs)\n\nmongoose\n--------\n\nMongoose provides an ORM way to hold Collection instance as Model,\n you should define schema first. But why mongodb need schema?\n Some guys like me, want to write code from application layer but not database layer,\n and we can use any fields without define it before.\n\n Mongoose provide a DAL that you can do validation, and write your middlewares.\n But some guys like me would like to validate manually, I think it is the tao of mongodb.\n\n If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice.\n\nmongoskin\n--------\n\nMongoskin is an easy to use driver of mongodb for nodejs,\n it is similar with mongo shell, powerful like node-mongodb-native,\n and support additional javascript method binding, which make it can act as a Model(in document way).\n\nIt will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native),\n and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29).\n\nIf you need validation, you can use [node-iform](https://github.com/guileen/node-iform).\n\n[Back to index](#index)\n\n\n\nInstall\n========\n\n```bash\n$ npm install mongoskin\n```\n\n[Back to index](#index)\n\n\n\n\nQuick Start\n========\n\n **Is mongoskin synchronized?**\n\nNope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29).\n**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native)\n\n\n\nConnect easier\n--------\nYou can connect to mongodb easier now.\n\n```js\nvar mongo = require('mongoskin');\nmongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) {\n console.dir(items);\n})\n```\n\n\n\nServer options and BSON options\n--------\nYou can also set `auto_reconnect` options querystring.\nAnd native_parser options will automatically set if native_parser is available.\n\n```js\nvar mongo = require('mongoskin');\nvar db = mongo.db('localhost:27017/test?auto_reconnect');\n```\n\n\n\nSimilar API with node-mongodb-native\n--------\nYou can do everything that node-mongodb-native can do.\n\n```js\ndb.createCollection(...);\ndb.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {});\ndb.collection('posts').hint = 'slug';\ndb.collection('posts').findOne({slug: 'whats-up'}, function (err, post) {\n // do something\n});\n```\n\n\n\nCursor easier\n--------\n\n```js\ndb.collection('posts').find().toArray(function (err, posts) {\n // do something\n});\n```\n\n\n\nMVC helper\n--------\n\nYou can bind **additional methods** for collection.\nIt is very useful if you want to use MVC patterns with nodejs and mongodb.\nYou can also invoke collection by properties after bind,\nit could simplfy your `require`.\n\nTo keep your code in line with DRY principles, it's possible to create your own\ndata layer by for example, setting up your own validators and/or default values\ninside the MVC methods as shown below in the config example\n\n```js\ndb.bind('posts', {\n findTop10 : function (fn) {\n this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn);\n },\n removeTagWith : function (tag, fn) {\n this.remove({tags:tag},fn);\n }\n } \n});\n\ndb.bind('settings', {\n\n getAll: function(user, fn) {\n \n \tthis.find({user: user}).toArray(function(err, settings) {\n \t\n \t // We want to set a default currency from within our app instead of storing it\n \t // for every user\n \t settings.currency = (typeof settings.currency !== \"undefined\") ? settings.currency : 'USD';\n \t\t\n \t fn(err, settings);\n \t\n \t});\n }\n});\n\n \ndb.bind('comments');\n\ndb.collection('posts').removeTagWith('delete', function (err, replies) {\n //do something\n});\n\ndb.posts.findTop10(function (err, topPosts) {\n //do something\n});\n\ndb.comments.find().toArray(function (err, comments) {\n //do something\n});\n```\n\n[Back to index](#index)\n\n\n\n\nDocumentation\n========\n\nfor more information, see the source.\n\n[Back to index](#index)\n\n\n\n\nModule\n--------\n\n### MongoSkin Url format\n\n```\n[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]`\n```\n\ne.g.\n\n```\nlocalhost/blog\nmongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect\n127.0.0.1?auto_reconnect=false\n```\n\n### db(serverURL[s], dbOptions, replicasetOptions)\n\nGet or create instance of [SkinDb](#skindb).\n\n```js\nvar db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5');\n```\n\nfor ReplSet server\n\n```js\nvar db = mongoskin.db([\n '192.168.0.1:27017/?auto_reconnect=true',\n '192.168.0.2:27017/?auto_reconnect=true',\n '192.168.0.3:27017/?auto_reconnect=true'\n], {\n database: 'testdb',\n safe: true\n}, {\n connectArbiter: false,\n socketOptions: {\n timeout: 2000\n }\n});\n```\n\n### router(select)\n\nselect is `function(collectionName)` returns a database instance, means router collectionName to that database.\n\n```js\nvar db = mongo.router(function (coll_name) {\n switch(coll_name) {\n case 'user':\n case 'message':\n return mongo.db('192.168.1.3/auth_db');\n default:\n return mongo.db('192.168.1.2/app_db');\n }\n});\ndb.bind('user', require('./shared-user-methods'));\nvar users = db.user; //auth_db.user\nvar messages = db.collection('message'); // auth_db.message\nvar products = db.collection('product'); //app_db.product\n```\n\n### classes extends frome node-mongodb-native\n\n* BSONPure\n* BSONNative\n* BinaryParser\n* Binary\n* Code\n* DBRef\n* Double\n* MaxKey\n* MinKey\n* ObjectID\n* Symbol\n* Timestamp\n* Long\n* BaseCommand\n* DbCommand\n* DeleteCommand\n* GetMoreCommand\n* InsertCommand\n* KillCursorCommand\n* QueryCommand\n* UpdateCommand\n* MongoReply\n* Admin\n* Collection\n* Connection\n* Server\n* ReplSetServers\n* Cursor\n* Db\n* connect\n* Grid\n* Chunk\n* GridStore\n* native\n* pure\n\n\n[Back to index](#index)\n\n\n\nSkinServer\n--------\n\n### SkinServer(server)\n\nConstruct SkinServer from native Server instance.\n\n### db(dbname, username=null, password=null)\n\nConstruct [SkinDb](#skindb) from SkinServer.\n\n[Back to index](#index)\n\n\n\nSkinDb\n--------\n\n### SkinDb(db, username=null, password=null)\n\nConstruct SkinDb.\n\n### open(callback)\n\nConnect to database, retrieval native\n[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17)\ninstance, callback is function(err, db).\n\n### collection(collectionName)\n\nRetrieval [SkinCollection](#skincollection) instance of specified collection name.\n\n\n\n### bind(collectionName)\n\n### bind(collectionName, SkinCollection)\n\n### bind(collectionName, extendObject1, extendObject2 ...)\n\nBind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name).\nYou can also bind additional methods to the SkinCollection, it is useful when\nyou want to reuse a complex operation. This will also affect\ndb.collection(name) method.\n\ne.g.\n\n```js\ndb.bind('book', {\n firstBook: function (fn) {\n this.findOne(fn);\n }\n});\ndb.book.firstBook(function (err, book) {});\n```\n\n### all the methods from Db.prototype\n\nSee [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information.\n\n[Back to index](#index)\n\n\n\nSkinCollection\n--------\n\nSee [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information.\n\n\n### open(callback)\n\nRetrieval native\n[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45)\ninstance, callback is function(err, collection).\n\n### id(hex)\n\nEquivalent to\n\n```js\ndb.bson_serializer.ObjectID.createFromHexString(hex);\n```\n\nSee [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548)\n\n\n\n\n### Collection operation\n\n```js\ncheckCollectionName(collectionName)\noptions(callback)\nrename(collectionName, callback)\ndrop(callback)\n```\n\n\n\n### Indexes\n\n```js\ncreateIndex(fieldOrSpec, unique, callback)\nensureIndex(fieldOrSpec, unique, callback)\nindexInformation(callback)\ndropIndex(indexName, callback)\ndropIndexes(callback)\n```\n \nSee [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md)\n\n\n\n### Queries\n\nSee [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md)\n\n#### findItems(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.toArray(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findEach(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.each(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findById(id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417)\n\n#### find(...)\n\nIf the last parameter is function, it is equivalent to native\n[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\nmethod, else it will return a future [SkinCursor](#skincursor).\n\ne.g.\n\n```js\n// callback\ndb.book.find({}, function (err, cursor) {/* do something */});\n// future SkinCursor\ndb.book.find().toArray(function (err, books) {/* do something */});\n```\n\n#### normalizeHintField(hint)\n\n#### find\n\n```js\n/**\n * Various argument possibilities\n * 1 callback\n * 2 selector, callback,\n * 2 callback, options // really?!\n * 3 selector, fields, callback\n * 3 selector, options, callback\n * 4,selector, fields, options, callback\n * 5 selector, fields, skip, limit, callback\n * 6 selector, fields, skip, limit, timeout, callback\n *\n * Available options:\n * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize\n */\n```\n\n#### findAndModify(query, sort, update, options, callback) \n\n```js\n/**\n Fetch and update a collection\n query: a filter for the query\n sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate\n update: an object describing the modifications to the documents selected by the query\n options:\n remove: set to a true to remove the object before returning\n new: set to true if you want to return the modified object rather than the original. Ignored for remove.\n upsert: true/false (perform upsert operation)\n**/\n```\n\n#### findOne(queryObject, options, callback)\n\n\n\n### Aggregation\n\n#### mapReduce(map, reduce, options, callback)\n\ne.g.\n\n```js\nvar map = function () {\n emit(test(this.timestamp.getYear()), 1);\n}\n\nvar reduce = function (k, v){\n count = 0;\n for (i = 0; i < v.length; i++) {\n count += v[i];\n }\n return count;\n}\nvar options = {scope: {test: new client.bson_serializer.Code(t.toString())}};\ncollection.mapReduce(map, reduce, options, function (err, collection) {\n collection.find(function (err, cursor) {\n cursor.toArray(function (err, results) {\n test.equal(2, results[0].value)\n finished_test({test_map_reduce_functions_scope:'ok'}); \n })\n})\n```\n\n#### group(keys, condition, initial, reduce, command, callback)\n\ne.g. \n\n```js\ncollection.group([], {}, {\"count\":0}, \"function (obj, prev) { prev.count++; }\", true, function(err, results) {});\n```\n\n#### count(query, callback)\n#### distinct(key, query, callback)\n\n\n\n### Inserting\n\n#### insert(docs, options, callback)\n\n\n\n### Updating\n\n#### save(doc, options, callback)\n\n```js\n/**\n Update a single document in this collection.\n spec - a associcated array containing the fields that need to be present in\n the document for the update to succeed\n\n document - an associated array with the fields to be updated or in the case of\n a upsert operation the fields to be inserted.\n\n Options:\n upsert - true/false (perform upsert operation)\n multi - true/false (update all documents matching spec)\n strict - true/false (perform check if the operation failed, required extra call to db)\n Deprecated Options:\n safe - true/false (perform check if the operation failed, required extra call to db)\n**/\n```\n\n#### update(spec, document, options, callback)\n\n#### updateById(_id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.update({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md)\n\n\n\n### Removing\n\n#### remove(selector, options, callback)\n\n#### removeById(_id, options, callback)\n\n[Back to index](#index)\n\n\n\nSkinCursor\n---------\n\nSee [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1)\nof node-mongodb-native for more information.\n\nAll these methods will return the SkinCursor itself.\n\n```js\nsort(keyOrList, [direction], [callback])\nlimit(limit, [callback])\nskip(skip, [callback])\nbatchSize(skip, [callback])\n\ntoArray(callback)\neach(callback)\ncount(callback)\nnextObject(callback)\ngetMore(callback)\nexplain(callback)\n```\n\n[Back to index](#index)\n\n## How to validate input?\n\nI wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) \nbase on [node-validator](https://github.com/chriso/node-validator)\n\n## Authors\n\nBelow is the output from `git-summary`.\n\n```\n project: node-mongoskin\n commits: 112\n active : 54 days\n files : 39\n authors: \n 49 Lin Gui 43.8%\n 34 guilin æ¡‚æž— 30.4%\n 9 fengmk2 8.0%\n 5 guilin 4.5%\n 2 François de Metz 1.8%\n 2 Paul Gebheim 1.8%\n 2 Gui Lin 1.8%\n 1 humanchimp 0.9%\n 1 Aneil Mallavarapu 0.9%\n 1 wmertens 0.9%\n 1 Harvey McQueen 0.9%\n 1 Joe Faber 0.9%\n 1 Matt Perpick 0.9%\n 1 Quang Van 0.9%\n 1 Rakshit Menpara 0.9%\n 1 Wout Mertens 0.9%\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 - 2012 kissjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "_id": "mongoskin@0.5.0", - "dist": { - "shasum": "e1ea3b581744ef5ee101fddfa8ae03eac65d9f6e" - }, - "_from": "mongoskin@0.5.0" -} diff --git a/frontend/express/node_modules/connect-mongoskin/package.json b/frontend/express/node_modules/connect-mongoskin/package.json deleted file mode 100644 index 7f3ccf6030c..00000000000 --- a/frontend/express/node_modules/connect-mongoskin/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "connect-mongoskin", - "version": "0.1.1", - "description": "Connect's durable sessions middleware backed by MongoSkin", - "keywords": [ - "connect", - "session", - "mongoskin", - "mongodb", - "rack" - ], - "repository": { - "type": "git", - "url": "git://github.com/johnnyhalife/connect-mongoskin.git" - }, - "dependencies": { - "connect": "2.3.9", - "mongoskin": "0.5.0" - }, - "engines": { - "node": ">=0.6.0", - "npm": ">=1.0.0" - }, - "readme": "# MongoSkin Session Store\n\nSimple Session Store for [Connect() Framework][1] session Middleware that leverages an existing connection from [MongoSkin][3]\n\n### Motivation\n\nWe were using a `connect-mongodb` which was working great, however we want to keep our connection pool centralized, \nhave the benefits that an abstraction layer like [mongoskin][3] provides and avoid going twice through the pain \nof getting our ReplSetCluster configuration in place.\n\n## Installation\n\nUse `git clone` to download the source and make it available in your project wirh `npm link`.\n\nor \n\n```bash\nnpm install connect-mongoskin\n```\n\n## Usage\n\nThis session store is build to work with [Connect() Framework][1] / [ExpressJS() Framework][2] / [RailwayJS() Framework][3]\nUse it like any other middleware.\n\n### Abstract example\n\nThe lib reuses an existing client, so pass in the SkinDb and options if needed.\n\n var SkinStore = new SkinStore(`db`, `options`[, callback]);\n\n### Connect() / ExpressJS() Example\n\n var express = require('express'),\n db = require('mongoskin').db(`your_connection_here`),\n SkinStore = require('connect-mongoskin');\n\n var app = express.createServer();\n app.use(express.cookieParser());\n app.use(express.session({cookie: { secure: false, maxAge:86400000 }, store: new SkinStore(`db`)})); \n\n[1]: https://github.com/senchalabs/connect\n[2]: https://github.com/visionmedia/express\n[3]: https://github.com/kissjs/node-mongoskin\n\n\n### Meta\n\nOriginally written by [@johnnyhalife](http://twitter.com/johnnyhalife) (johnny at mural.ly)", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/johnnyhalife/connect-mongoskin/issues" - }, - "_id": "connect-mongoskin@0.1.1", - "dist": { - "shasum": "812ec2fe585e68f50837a97f72e101315bb8b402" - }, - "_from": "connect-mongoskin@", - "_resolved": "https://registry.npmjs.org/connect-mongoskin/-/connect-mongoskin-0.1.1.tgz" -} diff --git a/frontend/express/node_modules/ejs/.npmignore b/frontend/express/node_modules/ejs/.npmignore deleted file mode 100644 index 020ddac2ced..00000000000 --- a/frontend/express/node_modules/ejs/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -# ignore any vim files: -*.sw[a-z] -vim/.netrwhist -node_modules diff --git a/frontend/express/node_modules/ejs/.travis.yml b/frontend/express/node_modules/ejs/.travis.yml deleted file mode 100644 index 1ccd29932a6..00000000000 --- a/frontend/express/node_modules/ejs/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -node_js: - - 0.11 - - 0.10 - - 0.9 - - 0.6 - - 0.8 diff --git a/frontend/express/node_modules/ejs/History.md b/frontend/express/node_modules/ejs/History.md deleted file mode 100644 index c26f168c05d..00000000000 --- a/frontend/express/node_modules/ejs/History.md +++ /dev/null @@ -1,131 +0,0 @@ - -0.8.4 / 2013-05-08 -================== - - * fix support for colons in filter arguments - * fix double callback when the callback throws - * rename escape option - -0.8.3 / 2012-09-13 -================== - - * allow pre-compiling into a standalone function [seanmonstar] - -0.8.2 / 2012-08-16 -================== - - * fix include "open" / "close" options. Closes #64 - -0.8.1 / 2012-08-11 -================== - - * fix comments. Closes #62 [Nate Silva] - -0.8.0 / 2012-07-25 -================== - - * add `<% include file %>` support - * fix wrapping of custom require in build step. Closes #57 - -0.7.3 / 2012-04-25 -================== - - * Added repository to package.json [isaacs] - -0.7.1 / 2012-03-26 -================== - - * Fixed exception when using express in production caused by typo. [slaskis] - -0.7.0 / 2012-03-24 -================== - - * Added newline consumption support (`-%>`) [whoatemydomain] - -0.6.1 / 2011-12-09 -================== - - * Fixed `ejs.renderFile()` - -0.6.0 / 2011-12-09 -================== - - * Changed: you no longer need `{ locals: {} }` - -0.5.0 / 2011-11-20 -================== - - * Added express 3.x support - * Added ejs.renderFile() - * Added 'json' filter - * Fixed tests for 0.5.x - -0.4.3 / 2011-06-20 -================== - - * Fixed stacktraces line number when used multiline js expressions [Octave] - -0.4.2 / 2011-05-11 -================== - - * Added client side support - -0.4.1 / 2011-04-21 -================== - - * Fixed error context - -0.4.0 / 2011-04-21 -================== - - * Added; ported jade's error reporting to ejs. [slaskis] - -0.3.1 / 2011-02-23 -================== - - * Fixed optional `compile()` options - -0.3.0 / 2011-02-14 -================== - - * Added 'json' filter [Yuriy Bogdanov] - * Use exported version of parse function to allow monkey-patching [Anatoliy Chakkaev] - -0.2.1 / 2010-10-07 -================== - - * Added filter support - * Fixed _cache_ option. ~4x performance increase - -0.2.0 / 2010-08-05 -================== - - * Added support for global tag config - * Added custom tag support. Closes #5 - * Fixed whitespace bug. Closes #4 - -0.1.0 / 2010-08-04 -================== - - * Faster implementation [ashleydev] - -0.0.4 / 2010-08-02 -================== - - * Fixed single quotes for content outside of template tags. [aniero] - * Changed; `exports.compile()` now expects only "locals" - -0.0.3 / 2010-07-15 -================== - - * Fixed single quotes - -0.0.2 / 2010-07-09 -================== - - * Fixed newline preservation - -0.0.1 / 2010-07-09 -================== - - * Initial release diff --git a/frontend/express/node_modules/ejs/Makefile b/frontend/express/node_modules/ejs/Makefile deleted file mode 100644 index a687a0a52d0..00000000000 --- a/frontend/express/node_modules/ejs/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -SRC = $(shell find lib -name "*.js" -type f) -UGLIFY_FLAGS = --no-mangle - -all: ejs.min.js - -test: - @./node_modules/.bin/mocha \ - --reporter spec - -ejs.js: $(SRC) - @node support/compile.js $^ - -ejs.min.js: ejs.js - @uglifyjs $(UGLIFY_FLAGS) $< > $@ \ - && du ejs.min.js \ - && du ejs.js - -clean: - rm -f ejs.js - rm -f ejs.min.js - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/Readme.md b/frontend/express/node_modules/ejs/Readme.md deleted file mode 100644 index ab0a3dd14b0..00000000000 --- a/frontend/express/node_modules/ejs/Readme.md +++ /dev/null @@ -1,188 +0,0 @@ -# EJS - -Embedded JavaScript templates. - -[![Build Status](https://travis-ci.org/visionmedia/ejs.png)](https://travis-ci.org/visionmedia/ejs) - -## Installation - - $ npm install ejs - -## Features - - * Complies with the [Express](http://expressjs.com) view system - * Static caching of intermediate JavaScript - * Unbuffered code for conditionals etc `<% code %>` - * Escapes html by default with `<%= code %>` - * Unescaped buffering with `<%- code %>` - * Supports tag customization - * Filter support for designer-friendly templates - * Includes - * Client-side support - * Newline slurping with `<% code -%>` or `<% -%>` or `<%= code -%>` or `<%- code -%>` - -## Example - - <% if (user) { %> -

    <%= user.name %>

    - <% } %> - -## Try out a live example now - -
    - -## Usage - - ejs.compile(str, options); - // => Function - - ejs.render(str, options); - // => str - -## Options - - - `cache` Compiled functions are cached, requires `filename` - - `filename` Used by `cache` to key caches - - `scope` Function execution context - - `debug` Output generated function body - - `compileDebug` When `false` no debug instrumentation is compiled - - `client` Returns standalone compiled function - - `open` Open tag, defaulting to "<%" - - `close` Closing tag, defaulting to "%>" - - * All others are template-local variables - -## Includes - - Includes are relative to the template with the `include` statement, - for example if you have "./views/users.ejs" and "./views/user/show.ejs" - you would use `<% include user/show %>`. The included file(s) are literally - included into the template, _no_ IO is performed after compilation, thus - local variables are available to these included templates. - -``` -
      - <% users.forEach(function(user){ %> - <% include user/show %> - <% }) %> -
    -``` - -## Custom delimiters - -Custom delimiters can also be applied globally: - - var ejs = require('ejs'); - ejs.open = '{{'; - ejs.close = '}}'; - -Which would make the following a valid template: - -

    {{= title }}

    - -## Filters - -EJS conditionally supports the concept of "filters". A "filter chain" -is a designer friendly api for manipulating data, without writing JavaScript. - -Filters can be applied by supplying the _:_ modifier, so for example if we wish to take the array `[{ name: 'tj' }, { name: 'mape' }, { name: 'guillermo' }]` and output a list of names we can do this simply with filters: - -Template: - -

    <%=: users | map:'name' | join %>

    - -Output: - -

    Tj, Mape, Guillermo

    - -Render call: - - ejs.render(str, { - users: [ - { name: 'tj' }, - { name: 'mape' }, - { name: 'guillermo' } - ] - }); - -Or perhaps capitalize the first user's name for display: - -

    <%=: users | first | capitalize %>

    - -## Filter list - -Currently these filters are available: - - - first - - last - - capitalize - - downcase - - upcase - - sort - - sort_by:'prop' - - size - - length - - plus:n - - minus:n - - times:n - - divided_by:n - - join:'val' - - truncate:n - - truncate_words:n - - replace:pattern,substitution - - prepend:val - - append:val - - map:'prop' - - reverse - - get:'prop' - -## Adding filters - - To add a filter simply add a method to the `.filters` object: - -```js -ejs.filters.last = function(obj) { - return obj[obj.length - 1]; -}; -``` - -## Layouts - - Currently EJS has no notion of blocks, only compile-time `include`s, - however you may still utilize this feature to implement "layouts" by - simply including a header and footer like so: - -```html -<% include head %> -

    Title

    -

    My page

    -<% include foot %> -``` - -## client-side support - - include `./ejs.js` or `./ejs.min.js` and `require("ejs").compile(str)`. - -## License - -(The MIT License) - -Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/ejs/benchmark.js b/frontend/express/node_modules/ejs/benchmark.js deleted file mode 100644 index 7b267e1603f..00000000000 --- a/frontend/express/node_modules/ejs/benchmark.js +++ /dev/null @@ -1,14 +0,0 @@ - - -var ejs = require('./lib/ejs'), - str = '<% if (foo) { %>

    <%= foo %>

    <% } %>', - times = 50000; - -console.log('rendering ' + times + ' times'); - -var start = new Date; -while (times--) { - ejs.render(str, { cache: true, filename: 'test', locals: { foo: 'bar' }}); -} - -console.log('took ' + (new Date - start) + 'ms'); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/ejs.js b/frontend/express/node_modules/ejs/ejs.js deleted file mode 100644 index d910f117c7f..00000000000 --- a/frontend/express/node_modules/ejs/ejs.js +++ /dev/null @@ -1,581 +0,0 @@ -ejs = (function(){ - -// CommonJS require() - -function require(p){ - if ('fs' == p) return {}; - var path = require.resolve(p) - , mod = require.modules[path]; - if (!mod) throw new Error('failed to require "' + p + '"'); - if (!mod.exports) { - mod.exports = {}; - mod.call(mod.exports, mod, mod.exports, require.relative(path)); - } - return mod.exports; - } - -require.modules = {}; - -require.resolve = function (path){ - var orig = path - , reg = path + '.js' - , index = path + '/index.js'; - return require.modules[reg] && reg - || require.modules[index] && index - || orig; - }; - -require.register = function (path, fn){ - require.modules[path] = fn; - }; - -require.relative = function (parent) { - return function(p){ - if ('.' != p.substr(0, 1)) return require(p); - - var path = parent.split('/') - , segs = p.split('/'); - path.pop(); - - for (var i = 0; i < segs.length; i++) { - var seg = segs[i]; - if ('..' == seg) path.pop(); - else if ('.' != seg) path.push(seg); - } - - return require(path.join('/')); - }; - }; - - -require.register("ejs.js", function(module, exports, require){ - -/*! - * EJS - * Copyright(c) 2012 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./utils') - , fs = require('fs'); - -/** - * Library version. - */ - -exports.version = '0.7.2'; - -/** - * Filters. - * - * @type Object - */ - -var filters = exports.filters = require('./filters'); - -/** - * Intermediate js cache. - * - * @type Object - */ - -var cache = {}; - -/** - * Clear intermediate js cache. - * - * @api public - */ - -exports.clearCache = function(){ - cache = {}; -}; - -/** - * Translate filtered code into function calls. - * - * @param {String} js - * @return {String} - * @api private - */ - -function filtered(js) { - return js.substr(1).split('|').reduce(function(js, filter){ - var parts = filter.split(':') - , name = parts.shift() - , args = parts.shift() || ''; - if (args) args = ', ' + args; - return 'filters.' + name + '(' + js + args + ')'; - }); -}; - -/** - * Re-throw the given `err` in context to the - * `str` of ejs, `filename`, and `lineno`. - * - * @param {Error} err - * @param {String} str - * @param {String} filename - * @param {String} lineno - * @api private - */ - -function rethrow(err, str, filename, lineno){ - var lines = str.split('\n') - , start = Math.max(lineno - 3, 0) - , end = Math.min(lines.length, lineno + 3); - - // Error context - var context = lines.slice(start, end).map(function(line, i){ - var curr = i + start + 1; - return (curr == lineno ? ' >> ' : ' ') - + curr - + '| ' - + line; - }).join('\n'); - - // Alter exception message - err.path = filename; - err.message = (filename || 'ejs') + ':' - + lineno + '\n' - + context + '\n\n' - + err.message; - - throw err; -} - -/** - * Parse the given `str` of ejs, returning the function body. - * - * @param {String} str - * @return {String} - * @api public - */ - -var parse = exports.parse = function(str, options){ - var options = options || {} - , open = options.open || exports.open || '<%' - , close = options.close || exports.close || '%>'; - - var buf = [ - "var buf = [];" - , "\nwith (locals) {" - , "\n buf.push('" - ]; - - var lineno = 1; - - var consumeEOL = false; - for (var i = 0, len = str.length; i < len; ++i) { - if (str.slice(i, open.length + i) == open) { - i += open.length - - var prefix, postfix, line = '__stack.lineno=' + lineno; - switch (str.substr(i, 1)) { - case '=': - prefix = "', escape((" + line + ', '; - postfix = ")), '"; - ++i; - break; - case '-': - prefix = "', (" + line + ', '; - postfix = "), '"; - ++i; - break; - default: - prefix = "');" + line + ';'; - postfix = "; buf.push('"; - } - - var end = str.indexOf(close, i) - , js = str.substring(i, end) - , start = i - , n = 0; - - if ('-' == js[js.length-1]){ - js = js.substring(0, js.length - 2); - consumeEOL = true; - } - - while (~(n = js.indexOf("\n", n))) n++, lineno++; - if (js.substr(0, 1) == ':') js = filtered(js); - buf.push(prefix, js, postfix); - i += end - start + close.length - 1; - - } else if (str.substr(i, 1) == "\\") { - buf.push("\\\\"); - } else if (str.substr(i, 1) == "'") { - buf.push("\\'"); - } else if (str.substr(i, 1) == "\r") { - buf.push(" "); - } else if (str.substr(i, 1) == "\n") { - if (consumeEOL) { - consumeEOL = false; - } else { - buf.push("\\n"); - lineno++; - } - } else { - buf.push(str.substr(i, 1)); - } - } - - buf.push("');\n}\nreturn buf.join('');"); - return buf.join(''); -}; - -/** - * Compile the given `str` of ejs into a `Function`. - * - * @param {String} str - * @param {Object} options - * @return {Function} - * @api public - */ - -var compile = exports.compile = function(str, options){ - options = options || {}; - - var input = JSON.stringify(str) - , filename = options.filename - ? JSON.stringify(options.filename) - : 'undefined'; - - // Adds the fancy stack trace meta info - str = [ - 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };', - rethrow.toString(), - 'try {', - exports.parse(str, options), - '} catch (err) {', - ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);', - '}' - ].join("\n"); - - if (options.debug) console.log(str); - var fn = new Function('locals, filters, escape', str); - return function(locals){ - return fn.call(this, locals, filters, utils.escape); - } -}; - -/** - * Render the given `str` of ejs. - * - * Options: - * - * - `locals` Local variables object - * - `cache` Compiled functions are cached, requires `filename` - * - `filename` Used by `cache` to key caches - * - `scope` Function execution context - * - `debug` Output generated function body - * - `open` Open tag, defaulting to "<%" - * - `close` Closing tag, defaulting to "%>" - * - * @param {String} str - * @param {Object} options - * @return {String} - * @api public - */ - -exports.render = function(str, options){ - var fn - , options = options || {}; - - if (options.cache) { - if (options.filename) { - fn = cache[options.filename] || (cache[options.filename] = compile(str, options)); - } else { - throw new Error('"cache" option requires "filename".'); - } - } else { - fn = compile(str, options); - } - - options.__proto__ = options.locals; - return fn.call(options.scope, options); -}; - -/** - * Render an EJS file at the given `path` and callback `fn(err, str)`. - * - * @param {String} path - * @param {Object|Function} options or callback - * @param {Function} fn - * @api public - */ - -exports.renderFile = function(path, options, fn){ - var key = path + ':string'; - - if ('function' == typeof options) { - fn = options, options = {}; - } - - options.filename = path; - - try { - var str = options.cache - ? cache[key] || (cache[key] = fs.readFileSync(path, 'utf8')) - : fs.readFileSync(path, 'utf8'); - - fn(null, exports.render(str, options)); - } catch (err) { - fn(err); - } -}; - -// express support - -exports.__express = exports.renderFile; - -/** - * Expose to require(). - */ - -if (require.extensions) { - require.extensions['.ejs'] = function(module, filename) { - source = require('fs').readFileSync(filename, 'utf-8'); - module._compile(compile(source, {}), filename); - }; -} else if (require.registerExtension) { - require.registerExtension('.ejs', function(src) { - return compile(src, {}); - }); -} - -}); // module: ejs.js - -require.register("filters.js", function(module, exports, require){ - -/*! - * EJS - Filters - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * First element of the target `obj`. - */ - -exports.first = function(obj) { - return obj[0]; -}; - -/** - * Last element of the target `obj`. - */ - -exports.last = function(obj) { - return obj[obj.length - 1]; -}; - -/** - * Capitalize the first letter of the target `str`. - */ - -exports.capitalize = function(str){ - str = String(str); - return str[0].toUpperCase() + str.substr(1, str.length); -}; - -/** - * Downcase the target `str`. - */ - -exports.downcase = function(str){ - return String(str).toLowerCase(); -}; - -/** - * Uppercase the target `str`. - */ - -exports.upcase = function(str){ - return String(str).toUpperCase(); -}; - -/** - * Sort the target `obj`. - */ - -exports.sort = function(obj){ - return Object.create(obj).sort(); -}; - -/** - * Sort the target `obj` by the given `prop` ascending. - */ - -exports.sort_by = function(obj, prop){ - return Object.create(obj).sort(function(a, b){ - a = a[prop], b = b[prop]; - if (a > b) return 1; - if (a < b) return -1; - return 0; - }); -}; - -/** - * Size or length of the target `obj`. - */ - -exports.size = exports.length = function(obj) { - return obj.length; -}; - -/** - * Add `a` and `b`. - */ - -exports.plus = function(a, b){ - return Number(a) + Number(b); -}; - -/** - * Subtract `b` from `a`. - */ - -exports.minus = function(a, b){ - return Number(a) - Number(b); -}; - -/** - * Multiply `a` by `b`. - */ - -exports.times = function(a, b){ - return Number(a) * Number(b); -}; - -/** - * Divide `a` by `b`. - */ - -exports.divided_by = function(a, b){ - return Number(a) / Number(b); -}; - -/** - * Join `obj` with the given `str`. - */ - -exports.join = function(obj, str){ - return obj.join(str || ', '); -}; - -/** - * Truncate `str` to `len`. - */ - -exports.truncate = function(str, len){ - str = String(str); - return str.substr(0, len); -}; - -/** - * Truncate `str` to `n` words. - */ - -exports.truncate_words = function(str, n){ - var str = String(str) - , words = str.split(/ +/); - return words.slice(0, n).join(' '); -}; - -/** - * Replace `pattern` with `substitution` in `str`. - */ - -exports.replace = function(str, pattern, substitution){ - return String(str).replace(pattern, substitution || ''); -}; - -/** - * Prepend `val` to `obj`. - */ - -exports.prepend = function(obj, val){ - return Array.isArray(obj) - ? [val].concat(obj) - : val + obj; -}; - -/** - * Append `val` to `obj`. - */ - -exports.append = function(obj, val){ - return Array.isArray(obj) - ? obj.concat(val) - : obj + val; -}; - -/** - * Map the given `prop`. - */ - -exports.map = function(arr, prop){ - return arr.map(function(obj){ - return obj[prop]; - }); -}; - -/** - * Reverse the given `obj`. - */ - -exports.reverse = function(obj){ - return Array.isArray(obj) - ? obj.reverse() - : String(obj).split('').reverse().join(''); -}; - -/** - * Get `prop` of the given `obj`. - */ - -exports.get = function(obj, prop){ - return obj[prop]; -}; - -/** - * Packs the given `obj` into json string - */ -exports.json = function(obj){ - return JSON.stringify(obj); -}; -}); // module: filters.js - -require.register("utils.js", function(module, exports, require){ - -/*! - * EJS - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; - -}); // module: utils.js - - return require("ejs"); -})(); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/ejs.min.js b/frontend/express/node_modules/ejs/ejs.min.js deleted file mode 100644 index 611ee4254b5..00000000000 --- a/frontend/express/node_modules/ejs/ejs.min.js +++ /dev/null @@ -1 +0,0 @@ -ejs=function(){function require(p){if("fs"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}return require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p.substr(0,1))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i> ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message,err}var parse=exports.parse=function(str,options){var options=options||{},open=options.open||exports.open||"<%",close=options.close||exports.close||"%>",buf=["var buf = [];","\nwith (locals) {","\n buf.push('"],lineno=1,consumeEOL=!1;for(var i=0,len=str.length;ib?1:a/g,">").replace(/"/g,""")}}),require("ejs")}(); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/examples/client.html b/frontend/express/node_modules/ejs/examples/client.html deleted file mode 100644 index 30dfea9f242..00000000000 --- a/frontend/express/node_modules/ejs/examples/client.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/examples/functions.ejs b/frontend/express/node_modules/ejs/examples/functions.ejs deleted file mode 100644 index bd5610e2dca..00000000000 --- a/frontend/express/node_modules/ejs/examples/functions.ejs +++ /dev/null @@ -1,9 +0,0 @@ -

    Users

    - -<% function user(user) { %> -
  • <%= user.name %> is a <%= user.age %> year old <%= user.species %>.
  • -<% } %> - -
      - <% users.map(user) %> -
    \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/examples/functions.js b/frontend/express/node_modules/ejs/examples/functions.js deleted file mode 100644 index 607833f8d60..00000000000 --- a/frontend/express/node_modules/ejs/examples/functions.js +++ /dev/null @@ -1,22 +0,0 @@ - -/** - * Module dependencies. - */ - -var ejs = require('../') - , fs = require('fs') - , path = __dirname + '/functions.ejs' - , str = fs.readFileSync(path, 'utf8'); - -var users = []; - -users.push({ name: 'Tobi', age: 2, species: 'ferret' }) -users.push({ name: 'Loki', age: 2, species: 'ferret' }) -users.push({ name: 'Jane', age: 6, species: 'ferret' }) - -var ret = ejs.render(str, { - users: users, - filename: path -}); - -console.log(ret); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/examples/list.ejs b/frontend/express/node_modules/ejs/examples/list.ejs deleted file mode 100644 index d571330aeea..00000000000 --- a/frontend/express/node_modules/ejs/examples/list.ejs +++ /dev/null @@ -1,7 +0,0 @@ -<% if (names.length) { %> -
      - <% names.forEach(function(name){ %> -
    • <%= name %>
    • - <% }) %> -
    -<% } %> \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/examples/list.js b/frontend/express/node_modules/ejs/examples/list.js deleted file mode 100644 index ec614ed6240..00000000000 --- a/frontend/express/node_modules/ejs/examples/list.js +++ /dev/null @@ -1,14 +0,0 @@ - -/** - * Module dependencies. - */ - -var ejs = require('../') - , fs = require('fs') - , str = fs.readFileSync(__dirname + '/list.ejs', 'utf8'); - -var ret = ejs.render(str, { - names: ['foo', 'bar', 'baz'] -}); - -console.log(ret); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/index.js b/frontend/express/node_modules/ejs/index.js deleted file mode 100644 index 20bf71a3fc1..00000000000 --- a/frontend/express/node_modules/ejs/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/ejs'); \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/lib/ejs.js b/frontend/express/node_modules/ejs/lib/ejs.js deleted file mode 100644 index 8601b10ab4e..00000000000 --- a/frontend/express/node_modules/ejs/lib/ejs.js +++ /dev/null @@ -1,353 +0,0 @@ - -/*! - * EJS - * Copyright(c) 2012 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./utils') - , path = require('path') - , basename = path.basename - , dirname = path.dirname - , extname = path.extname - , join = path.join - , fs = require('fs') - , read = fs.readFileSync; - -/** - * Filters. - * - * @type Object - */ - -var filters = exports.filters = require('./filters'); - -/** - * Intermediate js cache. - * - * @type Object - */ - -var cache = {}; - -/** - * Clear intermediate js cache. - * - * @api public - */ - -exports.clearCache = function(){ - cache = {}; -}; - -/** - * Translate filtered code into function calls. - * - * @param {String} js - * @return {String} - * @api private - */ - -function filtered(js) { - return js.substr(1).split('|').reduce(function(js, filter){ - var parts = filter.split(':') - , name = parts.shift() - , args = parts.join(':') || ''; - if (args) args = ', ' + args; - return 'filters.' + name + '(' + js + args + ')'; - }); -}; - -/** - * Re-throw the given `err` in context to the - * `str` of ejs, `filename`, and `lineno`. - * - * @param {Error} err - * @param {String} str - * @param {String} filename - * @param {String} lineno - * @api private - */ - -function rethrow(err, str, filename, lineno){ - var lines = str.split('\n') - , start = Math.max(lineno - 3, 0) - , end = Math.min(lines.length, lineno + 3); - - // Error context - var context = lines.slice(start, end).map(function(line, i){ - var curr = i + start + 1; - return (curr == lineno ? ' >> ' : ' ') - + curr - + '| ' - + line; - }).join('\n'); - - // Alter exception message - err.path = filename; - err.message = (filename || 'ejs') + ':' - + lineno + '\n' - + context + '\n\n' - + err.message; - - throw err; -} - -/** - * Parse the given `str` of ejs, returning the function body. - * - * @param {String} str - * @return {String} - * @api public - */ - -var parse = exports.parse = function(str, options){ - var options = options || {} - , open = options.open || exports.open || '<%' - , close = options.close || exports.close || '%>' - , filename = options.filename - , compileDebug = options.compileDebug !== false - , buf = []; - - buf.push('var buf = [];'); - if (false !== options._with) buf.push('\nwith (locals || {}) { (function(){ '); - buf.push('\n buf.push(\''); - - var lineno = 1; - - var consumeEOL = false; - for (var i = 0, len = str.length; i < len; ++i) { - if (str.slice(i, open.length + i) == open) { - i += open.length - - var prefix, postfix, line = (compileDebug ? '__stack.lineno=' : '') + lineno; - switch (str.substr(i, 1)) { - case '=': - prefix = "', escape((" + line + ', '; - postfix = ")), '"; - ++i; - break; - case '-': - prefix = "', (" + line + ', '; - postfix = "), '"; - ++i; - break; - default: - prefix = "');" + line + ';'; - postfix = "; buf.push('"; - } - - var end = str.indexOf(close, i) - , js = str.substring(i, end) - , start = i - , include = null - , n = 0; - - if ('-' == js[js.length-1]){ - js = js.substring(0, js.length - 2); - consumeEOL = true; - } - - if (0 == js.trim().indexOf('include')) { - var name = js.trim().slice(7).trim(); - if (!filename) throw new Error('filename option is required for includes'); - var path = resolveInclude(name, filename); - include = read(path, 'utf8'); - include = exports.parse(include, { filename: path, _with: false, open: open, close: close, compileDebug: compileDebug }); - buf.push("' + (function(){" + include + "})() + '"); - js = ''; - } - - while (~(n = js.indexOf("\n", n))) n++, lineno++; - if (js.substr(0, 1) == ':') js = filtered(js); - if (js) { - if (js.lastIndexOf('//') > js.lastIndexOf('\n')) js += '\n'; - buf.push(prefix, js, postfix); - } - i += end - start + close.length - 1; - - } else if (str.substr(i, 1) == "\\") { - buf.push("\\\\"); - } else if (str.substr(i, 1) == "'") { - buf.push("\\'"); - } else if (str.substr(i, 1) == "\r") { - // ignore - } else if (str.substr(i, 1) == "\n") { - if (consumeEOL) { - consumeEOL = false; - } else { - buf.push("\\n"); - lineno++; - } - } else { - buf.push(str.substr(i, 1)); - } - } - - if (false !== options._with) buf.push("'); })();\n} \nreturn buf.join('');") - else buf.push("');\nreturn buf.join('');"); - - return buf.join(''); -}; - -/** - * Compile the given `str` of ejs into a `Function`. - * - * @param {String} str - * @param {Object} options - * @return {Function} - * @api public - */ - -var compile = exports.compile = function(str, options){ - options = options || {}; - var escape = options.escape || utils.escape; - - var input = JSON.stringify(str) - , compileDebug = options.compileDebug !== false - , client = options.client - , filename = options.filename - ? JSON.stringify(options.filename) - : 'undefined'; - - if (compileDebug) { - // Adds the fancy stack trace meta info - str = [ - 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };', - rethrow.toString(), - 'try {', - exports.parse(str, options), - '} catch (err) {', - ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);', - '}' - ].join("\n"); - } else { - str = exports.parse(str, options); - } - - if (options.debug) console.log(str); - if (client) str = 'escape = escape || ' + escape.toString() + ';\n' + str; - - try { - var fn = new Function('locals, filters, escape', str); - } catch (err) { - if ('SyntaxError' == err.name) { - err.message += options.filename - ? ' in ' + filename - : ' while compiling ejs'; - } - throw err; - } - - if (client) return fn; - - return function(locals){ - return fn.call(this, locals, filters, escape); - } -}; - -/** - * Render the given `str` of ejs. - * - * Options: - * - * - `locals` Local variables object - * - `cache` Compiled functions are cached, requires `filename` - * - `filename` Used by `cache` to key caches - * - `scope` Function execution context - * - `debug` Output generated function body - * - `open` Open tag, defaulting to "<%" - * - `close` Closing tag, defaulting to "%>" - * - * @param {String} str - * @param {Object} options - * @return {String} - * @api public - */ - -exports.render = function(str, options){ - var fn - , options = options || {}; - - if (options.cache) { - if (options.filename) { - fn = cache[options.filename] || (cache[options.filename] = compile(str, options)); - } else { - throw new Error('"cache" option requires "filename".'); - } - } else { - fn = compile(str, options); - } - - options.__proto__ = options.locals; - return fn.call(options.scope, options); -}; - -/** - * Render an EJS file at the given `path` and callback `fn(err, str)`. - * - * @param {String} path - * @param {Object|Function} options or callback - * @param {Function} fn - * @api public - */ - -exports.renderFile = function(path, options, fn){ - var key = path + ':string'; - - if ('function' == typeof options) { - fn = options, options = {}; - } - - options.filename = path; - - var str; - try { - str = options.cache - ? cache[key] || (cache[key] = read(path, 'utf8')) - : read(path, 'utf8'); - } catch (err) { - fn(err); - return; - } - fn(null, exports.render(str, options)); -}; - -/** - * Resolve include `name` relative to `filename`. - * - * @param {String} name - * @param {String} filename - * @return {String} - * @api private - */ - -function resolveInclude(name, filename) { - var path = join(dirname(filename), name); - var ext = extname(name); - if (!ext) path += '.ejs'; - return path; -} - -// express support - -exports.__express = exports.renderFile; - -/** - * Expose to require(). - */ - -if (require.extensions) { - require.extensions['.ejs'] = function(module, filename) { - source = require('fs').readFileSync(filename, 'utf-8'); - module._compile(compile(source, {}), filename); - }; -} else if (require.registerExtension) { - require.registerExtension('.ejs', function(src) { - return compile(src, {}); - }); -} diff --git a/frontend/express/node_modules/ejs/lib/filters.js b/frontend/express/node_modules/ejs/lib/filters.js deleted file mode 100644 index d425c8d89e1..00000000000 --- a/frontend/express/node_modules/ejs/lib/filters.js +++ /dev/null @@ -1,198 +0,0 @@ - -/*! - * EJS - Filters - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * First element of the target `obj`. - */ - -exports.first = function(obj) { - return obj[0]; -}; - -/** - * Last element of the target `obj`. - */ - -exports.last = function(obj) { - return obj[obj.length - 1]; -}; - -/** - * Capitalize the first letter of the target `str`. - */ - -exports.capitalize = function(str){ - str = String(str); - return str[0].toUpperCase() + str.substr(1, str.length); -}; - -/** - * Downcase the target `str`. - */ - -exports.downcase = function(str){ - return String(str).toLowerCase(); -}; - -/** - * Uppercase the target `str`. - */ - -exports.upcase = function(str){ - return String(str).toUpperCase(); -}; - -/** - * Sort the target `obj`. - */ - -exports.sort = function(obj){ - return Object.create(obj).sort(); -}; - -/** - * Sort the target `obj` by the given `prop` ascending. - */ - -exports.sort_by = function(obj, prop){ - return Object.create(obj).sort(function(a, b){ - a = a[prop], b = b[prop]; - if (a > b) return 1; - if (a < b) return -1; - return 0; - }); -}; - -/** - * Size or length of the target `obj`. - */ - -exports.size = exports.length = function(obj) { - return obj.length; -}; - -/** - * Add `a` and `b`. - */ - -exports.plus = function(a, b){ - return Number(a) + Number(b); -}; - -/** - * Subtract `b` from `a`. - */ - -exports.minus = function(a, b){ - return Number(a) - Number(b); -}; - -/** - * Multiply `a` by `b`. - */ - -exports.times = function(a, b){ - return Number(a) * Number(b); -}; - -/** - * Divide `a` by `b`. - */ - -exports.divided_by = function(a, b){ - return Number(a) / Number(b); -}; - -/** - * Join `obj` with the given `str`. - */ - -exports.join = function(obj, str){ - return obj.join(str || ', '); -}; - -/** - * Truncate `str` to `len`. - */ - -exports.truncate = function(str, len){ - str = String(str); - return str.substr(0, len); -}; - -/** - * Truncate `str` to `n` words. - */ - -exports.truncate_words = function(str, n){ - var str = String(str) - , words = str.split(/ +/); - return words.slice(0, n).join(' '); -}; - -/** - * Replace `pattern` with `substitution` in `str`. - */ - -exports.replace = function(str, pattern, substitution){ - return String(str).replace(pattern, substitution || ''); -}; - -/** - * Prepend `val` to `obj`. - */ - -exports.prepend = function(obj, val){ - return Array.isArray(obj) - ? [val].concat(obj) - : val + obj; -}; - -/** - * Append `val` to `obj`. - */ - -exports.append = function(obj, val){ - return Array.isArray(obj) - ? obj.concat(val) - : obj + val; -}; - -/** - * Map the given `prop`. - */ - -exports.map = function(arr, prop){ - return arr.map(function(obj){ - return obj[prop]; - }); -}; - -/** - * Reverse the given `obj`. - */ - -exports.reverse = function(obj){ - return Array.isArray(obj) - ? obj.reverse() - : String(obj).split('').reverse().join(''); -}; - -/** - * Get `prop` of the given `obj`. - */ - -exports.get = function(obj, prop){ - return obj[prop]; -}; - -/** - * Packs the given `obj` into json string - */ -exports.json = function(obj){ - return JSON.stringify(obj); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/lib/utils.js b/frontend/express/node_modules/ejs/lib/utils.js deleted file mode 100644 index 8d569d6f23f..00000000000 --- a/frontend/express/node_modules/ejs/lib/utils.js +++ /dev/null @@ -1,23 +0,0 @@ - -/*! - * EJS - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; - \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/package.json b/frontend/express/node_modules/ejs/package.json deleted file mode 100644 index d0f9da33696..00000000000 --- a/frontend/express/node_modules/ejs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "ejs", - "description": "Embedded JavaScript templates", - "version": "0.8.4", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "keywords": [ - "template", - "engine", - "ejs" - ], - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "main": "./lib/ejs.js", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/ejs.git" - }, - "scripts": { - "test": "mocha --require should --reporter spec" - }, - "readme": "# EJS\n\nEmbedded JavaScript templates.\n\n[![Build Status](https://travis-ci.org/visionmedia/ejs.png)](https://travis-ci.org/visionmedia/ejs)\n\n## Installation\n\n $ npm install ejs\n\n## Features\n\n * Complies with the [Express](http://expressjs.com) view system\n * Static caching of intermediate JavaScript\n * Unbuffered code for conditionals etc `<% code %>`\n * Escapes html by default with `<%= code %>`\n * Unescaped buffering with `<%- code %>`\n * Supports tag customization\n * Filter support for designer-friendly templates\n * Includes\n * Client-side support\n * Newline slurping with `<% code -%>` or `<% -%>` or `<%= code -%>` or `<%- code -%>`\n\n## Example\n\n <% if (user) { %>\n\t

    <%= user.name %>

    \n <% } %>\n \n## Try out a live example now\n\n\n\n## Usage\n\n ejs.compile(str, options);\n // => Function\n\n ejs.render(str, options);\n // => str\n\n## Options\n\n - `cache` Compiled functions are cached, requires `filename`\n - `filename` Used by `cache` to key caches\n - `scope` Function execution context\n - `debug` Output generated function body\n - `compileDebug` When `false` no debug instrumentation is compiled\n - `client` Returns standalone compiled function\n - `open` Open tag, defaulting to \"<%\"\n - `close` Closing tag, defaulting to \"%>\"\n - * All others are template-local variables\n\n## Includes\n\n Includes are relative to the template with the `include` statement,\n for example if you have \"./views/users.ejs\" and \"./views/user/show.ejs\"\n you would use `<% include user/show %>`. The included file(s) are literally\n included into the template, _no_ IO is performed after compilation, thus\n local variables are available to these included templates.\n\n```\n
      \n <% users.forEach(function(user){ %>\n <% include user/show %>\n <% }) %>\n
    \n```\n\n## Custom delimiters\n\nCustom delimiters can also be applied globally:\n\n var ejs = require('ejs');\n ejs.open = '{{';\n ejs.close = '}}';\n\nWhich would make the following a valid template:\n\n

    {{= title }}

    \n\n## Filters\n\nEJS conditionally supports the concept of \"filters\". A \"filter chain\"\nis a designer friendly api for manipulating data, without writing JavaScript.\n\nFilters can be applied by supplying the _:_ modifier, so for example if we wish to take the array `[{ name: 'tj' }, { name: 'mape' }, { name: 'guillermo' }]` and output a list of names we can do this simply with filters:\n\nTemplate:\n\n

    <%=: users | map:'name' | join %>

    \n\nOutput:\n\n

    Tj, Mape, Guillermo

    \n\nRender call:\n\n ejs.render(str, {\n users: [\n { name: 'tj' },\n { name: 'mape' },\n { name: 'guillermo' }\n ]\n });\n\nOr perhaps capitalize the first user's name for display:\n\n

    <%=: users | first | capitalize %>

    \n\n## Filter list\n\nCurrently these filters are available:\n\n - first\n - last\n - capitalize\n - downcase\n - upcase\n - sort\n - sort_by:'prop'\n - size\n - length\n - plus:n\n - minus:n\n - times:n\n - divided_by:n\n - join:'val'\n - truncate:n\n - truncate_words:n\n - replace:pattern,substitution\n - prepend:val\n - append:val\n - map:'prop'\n - reverse\n - get:'prop'\n\n## Adding filters\n\n To add a filter simply add a method to the `.filters` object:\n \n```js\nejs.filters.last = function(obj) {\n return obj[obj.length - 1];\n};\n```\n\n## Layouts\n\n Currently EJS has no notion of blocks, only compile-time `include`s,\n however you may still utilize this feature to implement \"layouts\" by\n simply including a header and footer like so:\n\n```html\n<% include head %>\n

    Title

    \n

    My page

    \n<% include foot %>\n```\n\n## client-side support\n\n include `./ejs.js` or `./ejs.min.js` and `require(\"ejs\").compile(str)`.\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/ejs/issues" - }, - "_id": "ejs@0.8.4", - "_from": "ejs@0.8.4", - "dist": { - "shasum": "0ebc89264679c6ceea48b58e9c6f01f3184affb4" - }, - "_resolved": "https://registry.npmjs.org/ejs/-/ejs-0.8.4.tgz" -} diff --git a/frontend/express/node_modules/ejs/support/compile.js b/frontend/express/node_modules/ejs/support/compile.js deleted file mode 100644 index 497a1bb4e78..00000000000 --- a/frontend/express/node_modules/ejs/support/compile.js +++ /dev/null @@ -1,176 +0,0 @@ - -/** - * Module dependencies. - */ - -var fs = require('fs'); - -/** - * Arguments. - */ - -var args = process.argv.slice(2) - , pending = args.length - , files = {}; - -console.log(''); - -// parse arguments - -args.forEach(function(file){ - var mod = file.replace('lib/', ''); - fs.readFile(file, 'utf8', function(err, js){ - if (err) throw err; - console.log(' \033[90mcompile : \033[0m\033[36m%s\033[0m', file); - files[file] = parse(js); - --pending || compile(); - }); -}); - -/** - * Parse the given `js`. - */ - -function parse(js) { - return parseInheritance(parseConditionals(js)); -} - -/** - * Parse __proto__. - */ - -function parseInheritance(js) { - return js - .replace(/^ *(\w+)\.prototype\.__proto__ * = *(\w+)\.prototype *;?/gm, function(_, child, parent){ - return child + '.prototype = new ' + parent + ';\n' - + child + '.prototype.constructor = '+ child + ';\n'; - }); -} - -/** - * Parse the given `js`, currently supporting: - * - * 'if' ['node' | 'browser'] - * 'end' - * - */ - -function parseConditionals(js) { - var lines = js.split('\n') - , len = lines.length - , buffer = true - , browser = false - , buf = [] - , line - , cond; - - for (var i = 0; i < len; ++i) { - line = lines[i]; - if (/^ *\/\/ *if *(node|browser)/gm.exec(line)) { - cond = RegExp.$1; - buffer = browser = 'browser' == cond; - } else if (/^ *\/\/ *end/.test(line)) { - buffer = true; - browser = false; - } else if (browser) { - buf.push(line.replace(/^( *)\/\//, '$1')); - } else if (buffer) { - buf.push(line); - } - } - - return buf.join('\n'); -} - -/** - * Compile the files. - */ - -function compile() { - var buf = ''; - buf += 'ejs = (function(){\n'; - buf += '\n// CommonJS require()\n\n'; - buf += browser.require + '\n\n'; - buf += 'require.modules = {};\n\n'; - buf += 'require.resolve = ' + browser.resolve + ';\n\n'; - buf += 'require.register = ' + browser.register + ';\n\n'; - buf += 'require.relative = ' + browser.relative + ';\n\n'; - args.forEach(function(file){ - var js = files[file]; - file = file.replace('lib/', ''); - buf += '\nrequire.register("' + file + '", function(module, exports, require){\n'; - buf += js; - buf += '\n}); // module: ' + file + '\n'; - }); - buf += '\n return require("ejs");\n})();'; - fs.writeFile('ejs.js', buf, function(err){ - if (err) throw err; - console.log(' \033[90m create : \033[0m\033[36m%s\033[0m', 'ejs.js'); - console.log(); - }); -} - -// refactored version of weepy's -// https://github.com/weepy/brequire/blob/master/browser/brequire.js - -var browser = { - - /** - * Require a module. - */ - - require: function require(p){ - if ('fs' == p) return {}; - var path = require.resolve(p) - , mod = require.modules[path]; - if (!mod) throw new Error('failed to require "' + p + '"'); - if (!mod.exports) { - mod.exports = {}; - mod.call(mod.exports, mod, mod.exports, require.relative(path)); - } - return mod.exports; - }, - - /** - * Resolve module path. - */ - - resolve: function(path){ - var orig = path - , reg = path + '.js' - , index = path + '/index.js'; - return require.modules[reg] && reg - || require.modules[index] && index - || orig; - }, - - /** - * Return relative require(). - */ - - relative: function(parent) { - return function(p){ - if ('.' != p.substr(0, 1)) return require(p); - - var path = parent.split('/') - , segs = p.split('/'); - path.pop(); - - for (var i = 0; i < segs.length; i++) { - var seg = segs[i]; - if ('..' == seg) path.pop(); - else if ('.' != seg) path.push(seg); - } - - return require(path.join('/')); - }; - }, - - /** - * Register a module. - */ - - register: function(path, fn){ - require.modules[path] = fn; - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/ejs/test/ejs.js b/frontend/express/node_modules/ejs/test/ejs.js deleted file mode 100644 index 1c58c1c7208..00000000000 --- a/frontend/express/node_modules/ejs/test/ejs.js +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Module dependencies. - */ - -var ejs = require('..') - , fs = require('fs') - , read = fs.readFileSync - , assert = require('should'); - -/** - * Load fixture `name`. - */ - -function fixture(name) { - return read('test/fixtures/' + name, 'utf8').replace(/\r/g, ''); -} - -/** - * User fixtures. - */ - -var users = []; -users.push({ name: 'tobi' }); -users.push({ name: 'loki' }); -users.push({ name: 'jane' }); - -describe('ejs.compile(str, options)', function(){ - it('should compile to a function', function(){ - var fn = ejs.compile('

    yay

    '); - fn().should.equal('

    yay

    '); - }) - - it('should throw if there are syntax errors', function(){ - try { - ejs.compile(fixture('fail.ejs')); - } catch (err) { - err.message.should.include('compiling ejs'); - - try { - ejs.compile(fixture('fail.ejs'), { filename: 'fail.ejs' }); - } catch (err) { - err.message.should.include('fail.ejs'); - return; - } - } - - assert(false, 'compiling a file with invalid syntax should throw an exception'); - }) - - it('should allow customizing delimiters', function(){ - var fn = ejs.compile('

    {= name }

    ', { open: '{', close: '}' }); - fn({ name: 'tobi' }).should.equal('

    tobi

    '); - - var fn = ejs.compile('

    ::= name ::

    ', { open: '::', close: '::' }); - fn({ name: 'tobi' }).should.equal('

    tobi

    '); - - var fn = ejs.compile('

    (= name )

    ', { open: '(', close: ')' }); - fn({ name: 'tobi' }).should.equal('

    tobi

    '); - }) - - it('should default to using ejs.open and ejs.close', function(){ - ejs.open = '{'; - ejs.close = '}'; - var fn = ejs.compile('

    {= name }

    '); - fn({ name: 'tobi' }).should.equal('

    tobi

    '); - - var fn = ejs.compile('

    |= name |

    ', { open: '|', close: '|' }); - fn({ name: 'tobi' }).should.equal('

    tobi

    '); - delete ejs.open; - delete ejs.close; - }) - - it('should have a working client option', function(){ - var fn = ejs.compile('

    <%= foo %>

    ', { client: true }); - var str = fn.toString(); - eval('var preFn = ' + str); - preFn({ foo: 'bar' }).should.equal('

    bar

    '); - }) -}) - -describe('ejs.render(str, options)', function(){ - it('should render the template', function(){ - ejs.render('

    yay

    ') - .should.equal('

    yay

    '); - }) - - it('should accept locals', function(){ - ejs.render('

    <%= name %>

    ', { name: 'tobi' }) - .should.equal('

    tobi

    '); - }) -}) - -describe('ejs.renderFile(path, options, fn)', function(){ - it('should render a file', function(done){ - ejs.renderFile('test/fixtures/para.ejs', function(err, html){ - if (err) return done(err); - html.should.equal('

    hey

    '); - done(); - }); - }) - - it('should accept locals', function(done){ - var options = { name: 'tj', open: '{', close: '}' }; - ejs.renderFile('test/fixtures/user.ejs', options, function(err, html){ - if (err) return done(err); - html.should.equal('

    tj

    '); - done(); - }); - }) - - it('should not catch err threw by callback', function(done){ - var options = { name: 'tj', open: '{', close: '}' }; - var counter = 0; - try { - ejs.renderFile('test/fixtures/user.ejs', options, function(err, html){ - counter++; - if (err) { - err.message.should.not.equal('Exception in callback'); - return done(err); - } - throw new Error('Exception in callback'); - }); - } catch (err) { - counter.should.equal(1); - err.message.should.equal('Exception in callback'); - done(); - } - }) -}) - -describe('<%=', function(){ - it('should escape', function(){ - ejs.render('<%= name %>', { name: ' - -### Raw JavaScript - - It is also possible to expose "raw" javascript strings. - - app.expose('var some = "variable";'); - - Optionally passing the destination buffer, providing us with the "head" local variable, instead of the default of "javascript". - - app.expose('var some = "variable";', 'head'); - -### Exposing Functions - - Exposing a named function is easy too, simply pass it in with an optional buffer name for placement within a template much like above. - - app.expose(function someFunction(){ - return 'yay'; - }, 'foot'); - -### Self-Calling Functions - - Another alternative is passing an anonymous function, which executes itself, creating a "wrapper" function. - - app.expose(function(){ - function notify() { - alert('this will execute right away :D'); - } - notify(); - }); - -### Request-Level Exposure - - Finally we can apply all of the above at the request-level as well, below we expose "app.current.user" as `{ name: 'tj' }`, for the specific request only. - - app.get('/', function(req, res){ - var user = { name: 'tj' }; - res.expose(user, 'app.current.user'); - res.render('index', { layout: false }); - }); - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express-expose/index.js b/frontend/express/node_modules/express-expose/index.js deleted file mode 100644 index 8374594f09d..00000000000 --- a/frontend/express/node_modules/express-expose/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/express-expose'); \ No newline at end of file diff --git a/frontend/express/node_modules/express-expose/lib/express-expose.js b/frontend/express/node_modules/express-expose/lib/express-expose.js deleted file mode 100644 index 7c2cb1035b8..00000000000 --- a/frontend/express/node_modules/express-expose/lib/express-expose.js +++ /dev/null @@ -1,189 +0,0 @@ - -/*! - * express-expose - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var express = require('express') - , basename = require('path').basename - , extname = require('path').extname - , http = require('http') - , app = express.application - , res = express.response - , fs = require('fs'); - -/** - * Default namespace. - */ - -exports.namespace = 'app'; - -/** - * Default local variable name. - */ - -exports.name = 'javascript'; - -/** - * Expose the given `obj` to the client-side, with - * an optional `namespace` defaulting to "express". - * - * @param {Object|String|Function} obj - * @param {String} namespace - * @param {String} name - * @return {HTTPServer} for chaining - * @api public - */ - -res.expose = -app.expose = function(obj, namespace, name){ - var app = this.app || this; - var req = this.req; - - app._exposed = app._exposed || {}; - - // support second arg as name - // when a string or function is given - if ('string' == typeof obj || 'function' == typeof obj) { - name = namespace || exports.name; - } else { - name = name || exports.name; - namespace = namespace || exports.namespace; - } - - // buffer string - if ('string' == typeof obj) { - this.js = this.js || {}; - var buf = this.js[name] = this.js[name] || []; - buf.push(obj); - // buffer function - } else if ('function' == typeof obj && obj.name) { - this.expose(obj.toString(), name); - // buffer self-calling function - } else if ('function' == typeof obj) { - this.expose(';(' + obj + ')();', name); - // buffer object - } else { - this.expose(renderNamespace(namespace), name); - this.expose(renderObject(obj, namespace), name); - this.expose('\n'); - } - - // locals - function locals(req, res) { - var appjs = app.exposed(name) - , resjs = res.exposed(name) - , js = ''; - - if (appjs || resjs) { - js += '// app: \n' + appjs; - js += '// res: \n' + resjs; - } - - res.locals[name] = js; - } - - // app level locals - if (!req && !app._exposed[name]) { - app._exposed[name] = true; - app.use(function(req, res, next){ - locals(req, res); - next(); - }); - // request level locals - } else if (req) { - locals(req, this); - } - - return this; -}; - -/** - * Render the exposed javascript. - * - * @return {String} - * @api private - */ - -res.exposed = -app.exposed = function(name){ - name = name || exports.name; - this.js = this.js || {}; - return this.js[name] - ? this.js[name].join('\n') - : ''; -}; - -/** - * Render a namespace from the given `str`. - * - * Examples: - * - * renderNamespace('foo.bar.baz'); - * - * var foo = foo || {}; - * foo.bar = foo.bar || {}; - * foo.bar.baz = foo.bar.baz || {}; - * - * @param {String} str - * @return {String} - * @api private - */ - -function renderNamespace(str){ - var parts = [] - , split = str.split('.') - , len = split.length; - - return str.split('.').map(function(part, i){ - parts.push(part); - part = parts.join('.'); - return (i ? '' : 'window.') + part + ' = window.' + part + ' || {};'; - }).join('\n'); -} - -/** - * Render `obj` with the given `namespace`. - * - * @param {Object} obj - * @param {String} namespace - * @return {String} - * @api private - */ - -function renderObject(obj, namespace) { - return Object.keys(obj).map(function(key){ - var val = obj[key]; - return namespace + '["' + key + '"] = ' + string(val) + ';'; - }).join('\n'); -} - -/** - * Return a string representation of `obj`. - * - * @param {Mixed} obj - * @return {String} - * @api private - */ - -function string(obj) { - if ('function' == typeof obj) { - return obj.toString(); - } else if (obj instanceof Date) { - return 'new Date("' + obj + '")'; - } else if (Array.isArray(obj)) { - return '[' + obj.map(string).join(', ') + ']'; - } else if ('[object Object]' == Object.prototype.toString.call(obj)) { - return '{' + Object.keys(obj).map(function(key){ - return '"' + key + '":' + string(obj[key]); - }).join(', ') + '}'; - } else { - return JSON.stringify(obj); - } -} - diff --git a/frontend/express/node_modules/express-expose/lib/require.js b/frontend/express/node_modules/express-expose/lib/require.js deleted file mode 100644 index aa4a8d85d10..00000000000 --- a/frontend/express/node_modules/express-expose/lib/require.js +++ /dev/null @@ -1,43 +0,0 @@ -function require(p){ - var path = require.resolve(p) - , mod = require.modules[path]; - if (!mod) throw new Error('failed to require "' + p + '"'); - if (!mod.exports) { - mod.exports = {}; - mod.call(mod.exports, mod, mod.exports, require.relative(path)); - } - return mod.exports; -} - -require.modules = {}; - -require.resolve = function (path){ - var orig = path - , reg = path + '.js' - , index = path + '/index.js'; - return require.modules[reg] && reg - || require.modules[index] && index - || orig; -}; - -require.register = function (path, fn){ - require.modules[path] = fn; -}; - -require.relative = function (parent) { - return function(p){ - if ('.' != p[0]) return require(p); - - var path = parent.split('/') - , segs = p.split('/'); - path.pop(); - - for (var i = 0; i < segs.length; i++) { - var seg = segs[i]; - if ('..' == seg) path.pop(); - else if ('.' != seg) path.push(seg); - } - - return require(path.join('/')); - }; -}; diff --git a/frontend/express/node_modules/express-expose/package.json b/frontend/express/node_modules/express-expose/package.json deleted file mode 100644 index a0dd3cbfed9..00000000000 --- a/frontend/express/node_modules/express-expose/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "express-expose", - "version": "0.3.3", - "description": "Expose helpers and local variables to the client-side", - "keywords": [ - "express" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "devDependencies": { - "express": "3.x", - "mocha": "*", - "should": "*", - "jade": "*", - "supertest": "*" - }, - "main": "index", - "readme": "\n# express-expose\n\n Expose helpers and local variables to the client-side.\n\n## Installation\n\n $ npm install express-expose\n\n## Usage\n\n var express = require('express')\n , expose = require('express-expose');\n\n app.expose(...);\n\n## Versions\n\n Versions `0.3.0` and above are designed for Express 3.x, below for 2.x.\n\n## Examples\n\n### Exposing Objects\n\n A common use-case for exposing objects to the client-side would be exposing some properties, perhaps the express configuration. The call to `app.expose(obj)` below defaults to exposing the properties to `app.*`, so for example `app.views`, `app.title`, etc.\n\n app.set('views', __dirname + '/views');\n app.set('view engine', 'jade');\n app.set('title', 'Example');\n app.set('default language', 'en');\n\n app.expose(app.settings);\n\n Another use-case would be exposing helper methods, perhaps the same ones as you are currently exposing to templates. Below we expose the `math` object as utilities to our templates, as well as the client-side. Within a template we would call `add(1,2)`, and on the CS we would call `utils.add(1,2)`, since we have passed the namespace \"utils\".\n\n var math = { add: function(a,b){ return a + b; } };\n app.expose(math, 'utils').helpers(math);\n \n Sometimes you might want to output to a different area, so for this we can pass an additional param \"languages\" which tells express which buffer to write to, which ends up providing us with the local variable \"languages\" in our template, where the default is \"javascript\". The \"app\" string here is the namespace.\n\n app.expose({ en: 'English', fr: 'French' }, 'app', 'languages');\n\n You'll then want to output the default buffer (or others) to your template, in Jade this would look something like:\n \n script!= javascript\n\n And in EJS:\n \n \n\n### Raw JavaScript\n\n It is also possible to expose \"raw\" javascript strings.\n\n app.expose('var some = \"variable\";');\n\n Optionally passing the destination buffer, providing us with the \"head\" local variable, instead of the default of \"javascript\".\n \n app.expose('var some = \"variable\";', 'head');\n\n### Exposing Functions\n\n Exposing a named function is easy too, simply pass it in with an optional buffer name for placement within a template much like above.\n\n app.expose(function someFunction(){\n return 'yay';\n }, 'foot');\n\n### Self-Calling Functions\n\n Another alternative is passing an anonymous function, which executes itself, creating a \"wrapper\" function.\n\n app.expose(function(){\n function notify() {\n alert('this will execute right away :D');\n }\n notify();\n });\n\n### Request-Level Exposure\n\n Finally we can apply all of the above at the request-level as well, below we expose \"app.current.user\" as `{ name: 'tj' }`, for the specific request only.\n\n app.get('/', function(req, res){\n var user = { name: 'tj' };\n res.expose(user, 'app.current.user');\n res.render('index', { layout: false });\n });\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "_id": "express-expose@0.3.3", - "_from": "express-expose" -} diff --git a/frontend/express/node_modules/express/.npmignore b/frontend/express/node_modules/express/.npmignore deleted file mode 100644 index caf574de4de..00000000000 --- a/frontend/express/node_modules/express/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -.git* -docs/ -examples/ -support/ -test/ -testing.js -.DS_Store -coverage.html -lib-cov diff --git a/frontend/express/node_modules/express/.travis.yml b/frontend/express/node_modules/express/.travis.yml deleted file mode 100644 index cc4dba29d95..00000000000 --- a/frontend/express/node_modules/express/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" diff --git a/frontend/express/node_modules/express/History.md b/frontend/express/node_modules/express/History.md deleted file mode 100644 index 1f92c8b6cba..00000000000 --- a/frontend/express/node_modules/express/History.md +++ /dev/null @@ -1,1152 +0,0 @@ - -3.2.6 / 2013-06-02 -================== - - * update connect - -3.2.5 / 2013-05-21 -================== - - * update connect - * update node-cookie - * add: throw a meaningful error when there is no default engine - * change generation of ETags with res.send() to GET requests only. Closes #1619 - -3.2.4 / 2013-05-09 -================== - - * fix `req.subdomains` when no Host is present - * fix `req.host` when no Host is present, return undefined - -3.2.3 / 2013-05-07 -================== - - * update connect / qs - -3.2.2 / 2013-05-03 -================== - - * update qs - -3.2.1 / 2013-04-29 -================== - - * add app.VERB() paths array deprecation warning - * update connect - * update qs and remove all ~ semver crap - * fix: accept number as value of Signed Cookie - -3.2.0 / 2013-04-15 -================== - - * add "view" constructor setting to override view behaviour - * add req.acceptsEncoding(name) - * add req.acceptedEncodings - * revert cookie signature change causing session race conditions - * fix sorting of Accept values of the same quality - -3.1.2 / 2013-04-12 -================== - - * add support for custom Accept parameters - * update cookie-signature - -3.1.1 / 2013-04-01 -================== - - * add X-Forwarded-Host support to `req.host` - * fix relative redirects - * update mkdirp - * update buffer-crc32 - * remove legacy app.configure() method from app template. - -3.1.0 / 2013-01-25 -================== - - * add support for leading "." in "view engine" setting - * add array support to `res.set()` - * add node 0.8.x to travis.yml - * add "subdomain offset" setting for tweaking `req.subdomains` - * add `res.location(url)` implementing `res.redirect()`-like setting of Location - * use app.get() for x-powered-by setting for inheritance - * fix colons in passwords for `req.auth` - -3.0.6 / 2013-01-04 -================== - - * add http verb methods to Router - * update connect - * fix mangling of the `res.cookie()` options object - * fix jsonp whitespace escape. Closes #1132 - -3.0.5 / 2012-12-19 -================== - - * add throwing when a non-function is passed to a route - * fix: explicitly remove Transfer-Encoding header from 204 and 304 responses - * revert "add 'etag' option" - -3.0.4 / 2012-12-05 -================== - - * add 'etag' option to disable `res.send()` Etags - * add escaping of urls in text/plain in `res.redirect()` - for old browsers interpreting as html - * change crc32 module for a more liberal license - * update connect - -3.0.3 / 2012-11-13 -================== - - * update connect - * update cookie module - * fix cookie max-age - -3.0.2 / 2012-11-08 -================== - - * add OPTIONS to cors example. Closes #1398 - * fix route chaining regression. Closes #1397 - -3.0.1 / 2012-11-01 -================== - - * update connect - -3.0.0 / 2012-10-23 -================== - - * add `make clean` - * add "Basic" check to req.auth - * add `req.auth` test coverage - * add cb && cb(payload) to `res.jsonp()`. Closes #1374 - * add backwards compat for `res.redirect()` status. Closes #1336 - * add support for `res.json()` to retain previously defined Content-Types. Closes #1349 - * update connect - * change `res.redirect()` to utilize a pathname-relative Location again. Closes #1382 - * remove non-primitive string support for `res.send()` - * fix view-locals example. Closes #1370 - * fix route-separation example - -3.0.0rc5 / 2012-09-18 -================== - - * update connect - * add redis search example - * add static-files example - * add "x-powered-by" setting (`app.disable('x-powered-by')`) - * add "application/octet-stream" redirect Accept test case. Closes #1317 - -3.0.0rc4 / 2012-08-30 -================== - - * add `res.jsonp()`. Closes #1307 - * add "verbose errors" option to error-pages example - * add another route example to express(1) so people are not so confused - * add redis online user activity tracking example - * update connect dep - * fix etag quoting. Closes #1310 - * fix error-pages 404 status - * fix jsonp callback char restrictions - * remove old OPTIONS default response - -3.0.0rc3 / 2012-08-13 -================== - - * update connect dep - * fix signed cookies to work with `connect.cookieParser()` ("s:" prefix was missing) [tnydwrds] - * fix `res.render()` clobbering of "locals" - -3.0.0rc2 / 2012-08-03 -================== - - * add CORS example - * update connect dep - * deprecate `.createServer()` & remove old stale examples - * fix: escape `res.redirect()` link - * fix vhost example - -3.0.0rc1 / 2012-07-24 -================== - - * add more examples to view-locals - * add scheme-relative redirects (`res.redirect("//foo.com")`) support - * update cookie dep - * update connect dep - * update send dep - * fix `express(1)` -h flag, use -H for hogan. Closes #1245 - * fix `res.sendfile()` socket error handling regression - -3.0.0beta7 / 2012-07-16 -================== - - * update connect dep for `send()` root normalization regression - -3.0.0beta6 / 2012-07-13 -================== - - * add `err.view` property for view errors. Closes #1226 - * add "jsonp callback name" setting - * add support for "/foo/:bar*" non-greedy matches - * change `res.sendfile()` to use `send()` module - * change `res.send` to use "response-send" module - * remove `app.locals.use` and `res.locals.use`, use regular middleware - -3.0.0beta5 / 2012-07-03 -================== - - * add "make check" support - * add route-map example - * add `res.json(obj, status)` support back for BC - * add "methods" dep, remove internal methods module - * update connect dep - * update auth example to utilize cores pbkdf2 - * updated tests to use "supertest" - -3.0.0beta4 / 2012-06-25 -================== - - * Added `req.auth` - * Added `req.range(size)` - * Added `res.links(obj)` - * Added `res.send(body, status)` support back for backwards compat - * Added `.default()` support to `res.format()` - * Added 2xx / 304 check to `req.fresh` - * Revert "Added + support to the router" - * Fixed `res.send()` freshness check, respect res.statusCode - -3.0.0beta3 / 2012-06-15 -================== - - * Added hogan `--hjs` to express(1) [nullfirm] - * Added another example to content-negotiation - * Added `fresh` dep - * Changed: `res.send()` always checks freshness - * Fixed: expose connects mime module. Cloases #1165 - -3.0.0beta2 / 2012-06-06 -================== - - * Added `+` support to the router - * Added `req.host` - * Changed `req.param()` to check route first - * Update connect dep - -3.0.0beta1 / 2012-06-01 -================== - - * Added `res.format()` callback to override default 406 behaviour - * Fixed `res.redirect()` 406. Closes #1154 - -3.0.0alpha5 / 2012-05-30 -================== - - * Added `req.ip` - * Added `{ signed: true }` option to `res.cookie()` - * Removed `res.signedCookie()` - * Changed: dont reverse `req.ips` - * Fixed "trust proxy" setting check for `req.ips` - -3.0.0alpha4 / 2012-05-09 -================== - - * Added: allow `[]` in jsonp callback. Closes #1128 - * Added `PORT` env var support in generated template. Closes #1118 [benatkin] - * Updated: connect 2.2.2 - -3.0.0alpha3 / 2012-05-04 -================== - - * Added public `app.routes`. Closes #887 - * Added _view-locals_ example - * Added _mvc_ example - * Added `res.locals.use()`. Closes #1120 - * Added conditional-GET support to `res.send()` - * Added: coerce `res.set()` values to strings - * Changed: moved `static()` in generated apps below router - * Changed: `res.send()` only set ETag when not previously set - * Changed connect 2.2.1 dep - * Changed: `make test` now runs unit / acceptance tests - * Fixed req/res proto inheritance - -3.0.0alpha2 / 2012-04-26 -================== - - * Added `make benchmark` back - * Added `res.send()` support for `String` objects - * Added client-side data exposing example - * Added `res.header()` and `req.header()` aliases for BC - * Added `express.createServer()` for BC - * Perf: memoize parsed urls - * Perf: connect 2.2.0 dep - * Changed: make `expressInit()` middleware self-aware - * Fixed: use app.get() for all core settings - * Fixed redis session example - * Fixed session example. Closes #1105 - * Fixed generated express dep. Closes #1078 - -3.0.0alpha1 / 2012-04-15 -================== - - * Added `app.locals.use(callback)` - * Added `app.locals` object - * Added `app.locals(obj)` - * Added `res.locals` object - * Added `res.locals(obj)` - * Added `res.format()` for content-negotiation - * Added `app.engine()` - * Added `res.cookie()` JSON cookie support - * Added "trust proxy" setting - * Added `req.subdomains` - * Added `req.protocol` - * Added `req.secure` - * Added `req.path` - * Added `req.ips` - * Added `req.fresh` - * Added `req.stale` - * Added comma-delmited / array support for `req.accepts()` - * Added debug instrumentation - * Added `res.set(obj)` - * Added `res.set(field, value)` - * Added `res.get(field)` - * Added `app.get(setting)`. Closes #842 - * Added `req.acceptsLanguage()` - * Added `req.acceptsCharset()` - * Added `req.accepted` - * Added `req.acceptedLanguages` - * Added `req.acceptedCharsets` - * Added "json replacer" setting - * Added "json spaces" setting - * Added X-Forwarded-Proto support to `res.redirect()`. Closes #92 - * Added `--less` support to express(1) - * Added `express.response` prototype - * Added `express.request` prototype - * Added `express.application` prototype - * Added `app.path()` - * Added `app.render()` - * Added `res.type()` to replace `res.contentType()` - * Changed: `res.redirect()` to add relative support - * Changed: enable "jsonp callback" by default - * Changed: renamed "case sensitive routes" to "case sensitive routing" - * Rewrite of all tests with mocha - * Removed "root" setting - * Removed `res.redirect('home')` support - * Removed `req.notify()` - * Removed `app.register()` - * Removed `app.redirect()` - * Removed `app.is()` - * Removed `app.helpers()` - * Removed `app.dynamicHelpers()` - * Fixed `res.sendfile()` with non-GET. Closes #723 - * Fixed express(1) public dir for windows. Closes #866 - -2.5.9/ 2012-04-02 -================== - - * Added support for PURGE request method [pbuyle] - * Fixed `express(1)` generated app `app.address()` before `listening` [mmalecki] - -2.5.8 / 2012-02-08 -================== - - * Update mkdirp dep. Closes #991 - -2.5.7 / 2012-02-06 -================== - - * Fixed `app.all` duplicate DELETE requests [mscdex] - -2.5.6 / 2012-01-13 -================== - - * Updated hamljs dev dep. Closes #953 - -2.5.5 / 2012-01-08 -================== - - * Fixed: set `filename` on cached templates [matthewleon] - -2.5.4 / 2012-01-02 -================== - - * Fixed `express(1)` eol on 0.4.x. Closes #947 - -2.5.3 / 2011-12-30 -================== - - * Fixed `req.is()` when a charset is present - -2.5.2 / 2011-12-10 -================== - - * Fixed: express(1) LF -> CRLF for windows - -2.5.1 / 2011-11-17 -================== - - * Changed: updated connect to 1.8.x - * Removed sass.js support from express(1) - -2.5.0 / 2011-10-24 -================== - - * Added ./routes dir for generated app by default - * Added npm install reminder to express(1) app gen - * Added 0.5.x support - * Removed `make test-cov` since it wont work with node 0.5.x - * Fixed express(1) public dir for windows. Closes #866 - -2.4.7 / 2011-10-05 -================== - - * Added mkdirp to express(1). Closes #795 - * Added simple _json-config_ example - * Added shorthand for the parsed request's pathname via `req.path` - * Changed connect dep to 1.7.x to fix npm issue... - * Fixed `res.redirect()` __HEAD__ support. [reported by xerox] - * Fixed `req.flash()`, only escape args - * Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie] - -2.4.6 / 2011-08-22 -================== - - * Fixed multiple param callback regression. Closes #824 [reported by TroyGoode] - -2.4.5 / 2011-08-19 -================== - - * Added support for routes to handle errors. Closes #809 - * Added `app.routes.all()`. Closes #803 - * Added "basepath" setting to work in conjunction with reverse proxies etc. - * Refactored `Route` to use a single array of callbacks - * Added support for multiple callbacks for `app.param()`. Closes #801 -Closes #805 - * Changed: removed .call(self) for route callbacks - * Dependency: `qs >= 0.3.1` - * Fixed `res.redirect()` on windows due to `join()` usage. Closes #808 - -2.4.4 / 2011-08-05 -================== - - * Fixed `res.header()` intention of a set, even when `undefined` - * Fixed `*`, value no longer required - * Fixed `res.send(204)` support. Closes #771 - -2.4.3 / 2011-07-14 -================== - - * Added docs for `status` option special-case. Closes #739 - * Fixed `options.filename`, exposing the view path to template engines - -2.4.2. / 2011-07-06 -================== - - * Revert "removed jsonp stripping" for XSS - -2.4.1 / 2011-07-06 -================== - - * Added `res.json()` JSONP support. Closes #737 - * Added _extending-templates_ example. Closes #730 - * Added "strict routing" setting for trailing slashes - * Added support for multiple envs in `app.configure()` calls. Closes #735 - * Changed: `res.send()` using `res.json()` - * Changed: when cookie `path === null` don't default it - * Changed; default cookie path to "home" setting. Closes #731 - * Removed _pids/logs_ creation from express(1) - -2.4.0 / 2011-06-28 -================== - - * Added chainable `res.status(code)` - * Added `res.json()`, an explicit version of `res.send(obj)` - * Added simple web-service example - -2.3.12 / 2011-06-22 -================== - - * \#express is now on freenode! come join! - * Added `req.get(field, param)` - * Added links to Japanese documentation, thanks @hideyukisaito! - * Added; the `express(1)` generated app outputs the env - * Added `content-negotiation` example - * Dependency: connect >= 1.5.1 < 2.0.0 - * Fixed view layout bug. Closes #720 - * Fixed; ignore body on 304. Closes #701 - -2.3.11 / 2011-06-04 -================== - - * Added `npm test` - * Removed generation of dummy test file from `express(1)` - * Fixed; `express(1)` adds express as a dep - * Fixed; prune on `prepublish` - -2.3.10 / 2011-05-27 -================== - - * Added `req.route`, exposing the current route - * Added _package.json_ generation support to `express(1)` - * Fixed call to `app.param()` function for optional params. Closes #682 - -2.3.9 / 2011-05-25 -================== - - * Fixed bug-ish with `../' in `res.partial()` calls - -2.3.8 / 2011-05-24 -================== - - * Fixed `app.options()` - -2.3.7 / 2011-05-23 -================== - - * Added route `Collection`, ex: `app.get('/user/:id').remove();` - * Added support for `app.param(fn)` to define param logic - * Removed `app.param()` support for callback with return value - * Removed module.parent check from express(1) generated app. Closes #670 - * Refactored router. Closes #639 - -2.3.6 / 2011-05-20 -================== - - * Changed; using devDependencies instead of git submodules - * Fixed redis session example - * Fixed markdown example - * Fixed view caching, should not be enabled in development - -2.3.5 / 2011-05-20 -================== - - * Added export `.view` as alias for `.View` - -2.3.4 / 2011-05-08 -================== - - * Added `./examples/say` - * Fixed `res.sendfile()` bug preventing the transfer of files with spaces - -2.3.3 / 2011-05-03 -================== - - * Added "case sensitive routes" option. - * Changed; split methods supported per rfc [slaskis] - * Fixed route-specific middleware when using the same callback function several times - -2.3.2 / 2011-04-27 -================== - - * Fixed view hints - -2.3.1 / 2011-04-26 -================== - - * Added `app.match()` as `app.match.all()` - * Added `app.lookup()` as `app.lookup.all()` - * Added `app.remove()` for `app.remove.all()` - * Added `app.remove.VERB()` - * Fixed template caching collision issue. Closes #644 - * Moved router over from connect and started refactor - -2.3.0 / 2011-04-25 -================== - - * Added options support to `res.clearCookie()` - * Added `res.helpers()` as alias of `res.locals()` - * Added; json defaults to UTF-8 with `res.send()`. Closes #632. [Daniel * Dependency `connect >= 1.4.0` - * Changed; auto set Content-Type in res.attachement [Aaron Heckmann] - * Renamed "cache views" to "view cache". Closes #628 - * Fixed caching of views when using several apps. Closes #637 - * Fixed gotcha invoking `app.param()` callbacks once per route middleware. -Closes #638 - * Fixed partial lookup precedence. Closes #631 -Shaw] - -2.2.2 / 2011-04-12 -================== - - * Added second callback support for `res.download()` connection errors - * Fixed `filename` option passing to template engine - -2.2.1 / 2011-04-04 -================== - - * Added `layout(path)` helper to change the layout within a view. Closes #610 - * Fixed `partial()` collection object support. - Previously only anything with `.length` would work. - When `.length` is present one must still be aware of holes, - however now `{ collection: {foo: 'bar'}}` is valid, exposes - `keyInCollection` and `keysInCollection`. - - * Performance improved with better view caching - * Removed `request` and `response` locals - * Changed; errorHandler page title is now `Express` instead of `Connect` - -2.2.0 / 2011-03-30 -================== - - * Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606 - * Added `app.match.VERB()`, ex `app.match.put('/user/12')`. Closes #606 - * Added `app.VERB(path)` as alias of `app.lookup.VERB()`. - * Dependency `connect >= 1.2.0` - -2.1.1 / 2011-03-29 -================== - - * Added; expose `err.view` object when failing to locate a view - * Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann] - * Fixed; `res.send(undefined)` responds with 204 [aheckmann] - -2.1.0 / 2011-03-24 -================== - - * Added `/_?` partial lookup support. Closes #447 - * Added `request`, `response`, and `app` local variables - * Added `settings` local variable, containing the app's settings - * Added `req.flash()` exception if `req.session` is not available - * Added `res.send(bool)` support (json response) - * Fixed stylus example for latest version - * Fixed; wrap try/catch around `res.render()` - -2.0.0 / 2011-03-17 -================== - - * Fixed up index view path alternative. - * Changed; `res.locals()` without object returns the locals - -2.0.0rc3 / 2011-03-17 -================== - - * Added `res.locals(obj)` to compliment `res.local(key, val)` - * Added `res.partial()` callback support - * Fixed recursive error reporting issue in `res.render()` - -2.0.0rc2 / 2011-03-17 -================== - - * Changed; `partial()` "locals" are now optional - * Fixed `SlowBuffer` support. Closes #584 [reported by tyrda01] - * Fixed .filename view engine option [reported by drudge] - * Fixed blog example - * Fixed `{req,res}.app` reference when mounting [Ben Weaver] - -2.0.0rc / 2011-03-14 -================== - - * Fixed; expose `HTTPSServer` constructor - * Fixed express(1) default test charset. Closes #579 [reported by secoif] - * Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP] - -2.0.0beta3 / 2011-03-09 -================== - - * Added support for `res.contentType()` literal - The original `res.contentType('.json')`, - `res.contentType('application/json')`, and `res.contentType('json')` - will work now. - * Added `res.render()` status option support back - * Added charset option for `res.render()` - * Added `.charset` support (via connect 1.0.4) - * Added view resolution hints when in development and a lookup fails - * Added layout lookup support relative to the page view. - For example while rendering `./views/user/index.jade` if you create - `./views/user/layout.jade` it will be used in favour of the root layout. - * Fixed `res.redirect()`. RFC states absolute url [reported by unlink] - * Fixed; default `res.send()` string charset to utf8 - * Removed `Partial` constructor (not currently used) - -2.0.0beta2 / 2011-03-07 -================== - - * Added res.render() `.locals` support back to aid in migration process - * Fixed flash example - -2.0.0beta / 2011-03-03 -================== - - * Added HTTPS support - * Added `res.cookie()` maxAge support - * Added `req.header()` _Referrer_ / _Referer_ special-case, either works - * Added mount support for `res.redirect()`, now respects the mount-point - * Added `union()` util, taking place of `merge(clone())` combo - * Added stylus support to express(1) generated app - * Added secret to session middleware used in examples and generated app - * Added `res.local(name, val)` for progressive view locals - * Added default param support to `req.param(name, default)` - * Added `app.disabled()` and `app.enabled()` - * Added `app.register()` support for omitting leading ".", either works - * Added `res.partial()`, using the same interface as `partial()` within a view. Closes #539 - * Added `app.param()` to map route params to async/sync logic - * Added; aliased `app.helpers()` as `app.locals()`. Closes #481 - * Added extname with no leading "." support to `res.contentType()` - * Added `cache views` setting, defaulting to enabled in "production" env - * Added index file partial resolution, eg: partial('user') may try _views/user/index.jade_. - * Added `req.accepts()` support for extensions - * Changed; `res.download()` and `res.sendfile()` now utilize Connect's - static file server `connect.static.send()`. - * Changed; replaced `connect.utils.mime()` with npm _mime_ module - * Changed; allow `req.query` to be pre-defined (via middleware or other parent - * Changed view partial resolution, now relative to parent view - * Changed view engine signature. no longer `engine.render(str, options, callback)`, now `engine.compile(str, options) -> Function`, the returned function accepts `fn(locals)`. - * Fixed `req.param()` bug returning Array.prototype methods. Closes #552 - * Fixed; using `Stream#pipe()` instead of `sys.pump()` in `res.sendfile()` - * Fixed; using _qs_ module instead of _querystring_ - * Fixed; strip unsafe chars from jsonp callbacks - * Removed "stream threshold" setting - -1.0.8 / 2011-03-01 -================== - - * Allow `req.query` to be pre-defined (via middleware or other parent app) - * "connect": ">= 0.5.0 < 1.0.0". Closes #547 - * Removed the long deprecated __EXPRESS_ENV__ support - -1.0.7 / 2011-02-07 -================== - - * Fixed `render()` setting inheritance. - Mounted apps would not inherit "view engine" - -1.0.6 / 2011-02-07 -================== - - * Fixed `view engine` setting bug when period is in dirname - -1.0.5 / 2011-02-05 -================== - - * Added secret to generated app `session()` call - -1.0.4 / 2011-02-05 -================== - - * Added `qs` dependency to _package.json_ - * Fixed namespaced `require()`s for latest connect support - -1.0.3 / 2011-01-13 -================== - - * Remove unsafe characters from JSONP callback names [Ryan Grove] - -1.0.2 / 2011-01-10 -================== - - * Removed nested require, using `connect.router` - -1.0.1 / 2010-12-29 -================== - - * Fixed for middleware stacked via `createServer()` - previously the `foo` middleware passed to `createServer(foo)` - would not have access to Express methods such as `res.send()` - or props like `req.query` etc. - -1.0.0 / 2010-11-16 -================== - - * Added; deduce partial object names from the last segment. - For example by default `partial('forum/post', postObject)` will - give you the _post_ object, providing a meaningful default. - * Added http status code string representation to `res.redirect()` body - * Added; `res.redirect()` supporting _text/plain_ and _text/html_ via __Accept__. - * Added `req.is()` to aid in content negotiation - * Added partial local inheritance [suggested by masylum]. Closes #102 - providing access to parent template locals. - * Added _-s, --session[s]_ flag to express(1) to add session related middleware - * Added _--template_ flag to express(1) to specify the - template engine to use. - * Added _--css_ flag to express(1) to specify the - stylesheet engine to use (or just plain css by default). - * Added `app.all()` support [thanks aheckmann] - * Added partial direct object support. - You may now `partial('user', user)` providing the "user" local, - vs previously `partial('user', { object: user })`. - * Added _route-separation_ example since many people question ways - to do this with CommonJS modules. Also view the _blog_ example for - an alternative. - * Performance; caching view path derived partial object names - * Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454 - * Fixed jsonp support; _text/javascript_ as per mailinglist discussion - -1.0.0rc4 / 2010-10-14 -================== - - * Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0 - * Added route-middleware support (very helpful, see the [docs](http://expressjs.com/guide.html#Route-Middleware)) - * Added _jsonp callback_ setting to enable/disable jsonp autowrapping [Dav Glass] - * Added callback query check on response.send to autowrap JSON objects for simple webservice implementations [Dav Glass] - * Added `partial()` support for array-like collections. Closes #434 - * Added support for swappable querystring parsers - * Added session usage docs. Closes #443 - * Added dynamic helper caching. Closes #439 [suggested by maritz] - * Added authentication example - * Added basic Range support to `res.sendfile()` (and `res.download()` etc) - * Changed; `express(1)` generated app using 2 spaces instead of 4 - * Default env to "development" again [aheckmann] - * Removed _context_ option is no more, use "scope" - * Fixed; exposing _./support_ libs to examples so they can run without installs - * Fixed mvc example - -1.0.0rc3 / 2010-09-20 -================== - - * Added confirmation for `express(1)` app generation. Closes #391 - * Added extending of flash formatters via `app.flashFormatters` - * Added flash formatter support. Closes #411 - * Added streaming support to `res.sendfile()` using `sys.pump()` when >= "stream threshold" - * Added _stream threshold_ setting for `res.sendfile()` - * Added `res.send()` __HEAD__ support - * Added `res.clearCookie()` - * Added `res.cookie()` - * Added `res.render()` headers option - * Added `res.redirect()` response bodies - * Added `res.render()` status option support. Closes #425 [thanks aheckmann] - * Fixed `res.sendfile()` responding with 403 on malicious path - * Fixed `res.download()` bug; when an error occurs remove _Content-Disposition_ - * Fixed; mounted apps settings now inherit from parent app [aheckmann] - * Fixed; stripping Content-Length / Content-Type when 204 - * Fixed `res.send()` 204. Closes #419 - * Fixed multiple _Set-Cookie_ headers via `res.header()`. Closes #402 - * Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo] - - -1.0.0rc2 / 2010-08-17 -================== - - * Added `app.register()` for template engine mapping. Closes #390 - * Added `res.render()` callback support as second argument (no options) - * Added callback support to `res.download()` - * Added callback support for `res.sendfile()` - * Added support for middleware access via `express.middlewareName()` vs `connect.middlewareName()` - * Added "partials" setting to docs - * Added default expresso tests to `express(1)` generated app. Closes #384 - * Fixed `res.sendfile()` error handling, defer via `next()` - * Fixed `res.render()` callback when a layout is used [thanks guillermo] - * Fixed; `make install` creating ~/.node_libraries when not present - * Fixed issue preventing error handlers from being defined anywhere. Closes #387 - -1.0.0rc / 2010-07-28 -================== - - * Added mounted hook. Closes #369 - * Added connect dependency to _package.json_ - - * Removed "reload views" setting and support code - development env never caches, production always caches. - - * Removed _param_ in route callbacks, signature is now - simply (req, res, next), previously (req, res, params, next). - Use _req.params_ for path captures, _req.query_ for GET params. - - * Fixed "home" setting - * Fixed middleware/router precedence issue. Closes #366 - * Fixed; _configure()_ callbacks called immediately. Closes #368 - -1.0.0beta2 / 2010-07-23 -================== - - * Added more examples - * Added; exporting `Server` constructor - * Added `Server#helpers()` for view locals - * Added `Server#dynamicHelpers()` for dynamic view locals. Closes #349 - * Added support for absolute view paths - * Added; _home_ setting defaults to `Server#route` for mounted apps. Closes #363 - * Added Guillermo Rauch to the contributor list - * Added support for "as" for non-collection partials. Closes #341 - * Fixed _install.sh_, ensuring _~/.node_libraries_ exists. Closes #362 [thanks jf] - * Fixed `res.render()` exceptions, now passed to `next()` when no callback is given [thanks guillermo] - * Fixed instanceof `Array` checks, now `Array.isArray()` - * Fixed express(1) expansion of public dirs. Closes #348 - * Fixed middleware precedence. Closes #345 - * Fixed view watcher, now async [thanks aheckmann] - -1.0.0beta / 2010-07-15 -================== - - * Re-write - - much faster - - much lighter - - Check [ExpressJS.com](http://expressjs.com) for migration guide and updated docs - -0.14.0 / 2010-06-15 -================== - - * Utilize relative requires - * Added Static bufferSize option [aheckmann] - * Fixed caching of view and partial subdirectories [aheckmann] - * Fixed mime.type() comments now that ".ext" is not supported - * Updated haml submodule - * Updated class submodule - * Removed bin/express - -0.13.0 / 2010-06-01 -================== - - * Added node v0.1.97 compatibility - * Added support for deleting cookies via Request#cookie('key', null) - * Updated haml submodule - * Fixed not-found page, now using using charset utf-8 - * Fixed show-exceptions page, now using using charset utf-8 - * Fixed view support due to fs.readFile Buffers - * Changed; mime.type() no longer accepts ".type" due to node extname() changes - -0.12.0 / 2010-05-22 -================== - - * Added node v0.1.96 compatibility - * Added view `helpers` export which act as additional local variables - * Updated haml submodule - * Changed ETag; removed inode, modified time only - * Fixed LF to CRLF for setting multiple cookies - * Fixed cookie complation; values are now urlencoded - * Fixed cookies parsing; accepts quoted values and url escaped cookies - -0.11.0 / 2010-05-06 -================== - - * Added support for layouts using different engines - - this.render('page.html.haml', { layout: 'super-cool-layout.html.ejs' }) - - this.render('page.html.haml', { layout: 'foo' }) // assumes 'foo.html.haml' - - this.render('page.html.haml', { layout: false }) // no layout - * Updated ext submodule - * Updated haml submodule - * Fixed EJS partial support by passing along the context. Issue #307 - -0.10.1 / 2010-05-03 -================== - - * Fixed binary uploads. - -0.10.0 / 2010-04-30 -================== - - * Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s - encoding is set to 'utf8' or 'utf-8'. - * Added "encoding" option to Request#render(). Closes #299 - * Added "dump exceptions" setting, which is enabled by default. - * Added simple ejs template engine support - * Added error reponse support for text/plain, application/json. Closes #297 - * Added callback function param to Request#error() - * Added Request#sendHead() - * Added Request#stream() - * Added support for Request#respond(304, null) for empty response bodies - * Added ETag support to Request#sendfile() - * Added options to Request#sendfile(), passed to fs.createReadStream() - * Added filename arg to Request#download() - * Performance enhanced due to pre-reversing plugins so that plugins.reverse() is not called on each request - * Performance enhanced by preventing several calls to toLowerCase() in Router#match() - * Changed; Request#sendfile() now streams - * Changed; Renamed Request#halt() to Request#respond(). Closes #289 - * Changed; Using sys.inspect() instead of JSON.encode() for error output - * Changed; run() returns the http.Server instance. Closes #298 - * Changed; Defaulting Server#host to null (INADDR_ANY) - * Changed; Logger "common" format scale of 0.4f - * Removed Logger "request" format - * Fixed; Catching ENOENT in view caching, preventing error when "views/partials" is not found - * Fixed several issues with http client - * Fixed Logger Content-Length output - * Fixed bug preventing Opera from retaining the generated session id. Closes #292 - -0.9.0 / 2010-04-14 -================== - - * Added DSL level error() route support - * Added DSL level notFound() route support - * Added Request#error() - * Added Request#notFound() - * Added Request#render() callback function. Closes #258 - * Added "max upload size" setting - * Added "magic" variables to collection partials (\_\_index\_\_, \_\_length\_\_, \_\_isFirst\_\_, \_\_isLast\_\_). Closes #254 - * Added [haml.js](http://github.com/visionmedia/haml.js) submodule; removed haml-js - * Added callback function support to Request#halt() as 3rd/4th arg - * Added preprocessing of route param wildcards using param(). Closes #251 - * Added view partial support (with collections etc) - * Fixed bug preventing falsey params (such as ?page=0). Closes #286 - * Fixed setting of multiple cookies. Closes #199 - * Changed; view naming convention is now NAME.TYPE.ENGINE (for example page.html.haml) - * Changed; session cookie is now httpOnly - * Changed; Request is no longer global - * Changed; Event is no longer global - * Changed; "sys" module is no longer global - * Changed; moved Request#download to Static plugin where it belongs - * Changed; Request instance created before body parsing. Closes #262 - * Changed; Pre-caching views in memory when "cache view contents" is enabled. Closes #253 - * Changed; Pre-caching view partials in memory when "cache view partials" is enabled - * Updated support to node --version 0.1.90 - * Updated dependencies - * Removed set("session cookie") in favour of use(Session, { cookie: { ... }}) - * Removed utils.mixin(); use Object#mergeDeep() - -0.8.0 / 2010-03-19 -================== - - * Added coffeescript example app. Closes #242 - * Changed; cache api now async friendly. Closes #240 - * Removed deprecated 'express/static' support. Use 'express/plugins/static' - -0.7.6 / 2010-03-19 -================== - - * Added Request#isXHR. Closes #229 - * Added `make install` (for the executable) - * Added `express` executable for setting up simple app templates - * Added "GET /public/*" to Static plugin, defaulting to /public - * Added Static plugin - * Fixed; Request#render() only calls cache.get() once - * Fixed; Namespacing View caches with "view:" - * Fixed; Namespacing Static caches with "static:" - * Fixed; Both example apps now use the Static plugin - * Fixed set("views"). Closes #239 - * Fixed missing space for combined log format - * Deprecated Request#sendfile() and 'express/static' - * Removed Server#running - -0.7.5 / 2010-03-16 -================== - - * Added Request#flash() support without args, now returns all flashes - * Updated ext submodule - -0.7.4 / 2010-03-16 -================== - - * Fixed session reaper - * Changed; class.js replacing js-oo Class implementation (quite a bit faster, no browser cruft) - -0.7.3 / 2010-03-16 -================== - - * Added package.json - * Fixed requiring of haml / sass due to kiwi removal - -0.7.2 / 2010-03-16 -================== - - * Fixed GIT submodules (HAH!) - -0.7.1 / 2010-03-16 -================== - - * Changed; Express now using submodules again until a PM is adopted - * Changed; chat example using millisecond conversions from ext - -0.7.0 / 2010-03-15 -================== - - * Added Request#pass() support (finds the next matching route, or the given path) - * Added Logger plugin (default "common" format replaces CommonLogger) - * Removed Profiler plugin - * Removed CommonLogger plugin - -0.6.0 / 2010-03-11 -================== - - * Added seed.yml for kiwi package management support - * Added HTTP client query string support when method is GET. Closes #205 - - * Added support for arbitrary view engines. - For example "foo.engine.html" will now require('engine'), - the exports from this module are cached after the first require(). - - * Added async plugin support - - * Removed usage of RESTful route funcs as http client - get() etc, use http.get() and friends - - * Removed custom exceptions - -0.5.0 / 2010-03-10 -================== - - * Added ext dependency (library of js extensions) - * Removed extname() / basename() utils. Use path module - * Removed toArray() util. Use arguments.values - * Removed escapeRegexp() util. Use RegExp.escape() - * Removed process.mixin() dependency. Use utils.mixin() - * Removed Collection - * Removed ElementCollection - * Shameless self promotion of ebook "Advanced JavaScript" (http://dev-mag.com) ;) - -0.4.0 / 2010-02-11 -================== - - * Added flash() example to sample upload app - * Added high level restful http client module (express/http) - * Changed; RESTful route functions double as HTTP clients. Closes #69 - * Changed; throwing error when routes are added at runtime - * Changed; defaulting render() context to the current Request. Closes #197 - * Updated haml submodule - -0.3.0 / 2010-02-11 -================== - - * Updated haml / sass submodules. Closes #200 - * Added flash message support. Closes #64 - * Added accepts() now allows multiple args. fixes #117 - * Added support for plugins to halt. Closes #189 - * Added alternate layout support. Closes #119 - * Removed Route#run(). Closes #188 - * Fixed broken specs due to use(Cookie) missing - -0.2.1 / 2010-02-05 -================== - - * Added "plot" format option for Profiler (for gnuplot processing) - * Added request number to Profiler plugin - * Fixed binary encoding for multi-part file uploads, was previously defaulting to UTF8 - * Fixed issue with routes not firing when not files are present. Closes #184 - * Fixed process.Promise -> events.Promise - -0.2.0 / 2010-02-03 -================== - - * Added parseParam() support for name[] etc. (allows for file inputs with "multiple" attr) Closes #180 - * Added Both Cache and Session option "reapInterval" may be "reapEvery". Closes #174 - * Added expiration support to cache api with reaper. Closes #133 - * Added cache Store.Memory#reap() - * Added Cache; cache api now uses first class Cache instances - * Added abstract session Store. Closes #172 - * Changed; cache Memory.Store#get() utilizing Collection - * Renamed MemoryStore -> Store.Memory - * Fixed use() of the same plugin several time will always use latest options. Closes #176 - -0.1.0 / 2010-02-03 -================== - - * Changed; Hooks (before / after) pass request as arg as well as evaluated in their context - * Updated node support to 0.1.27 Closes #169 - * Updated dirname(__filename) -> __dirname - * Updated libxmljs support to v0.2.0 - * Added session support with memory store / reaping - * Added quick uid() helper - * Added multi-part upload support - * Added Sass.js support / submodule - * Added production env caching view contents and static files - * Added static file caching. Closes #136 - * Added cache plugin with memory stores - * Added support to StaticFile so that it works with non-textual files. - * Removed dirname() helper - * Removed several globals (now their modules must be required) - -0.0.2 / 2010-01-10 -================== - - * Added view benchmarks; currently haml vs ejs - * Added Request#attachment() specs. Closes #116 - * Added use of node's parseQuery() util. Closes #123 - * Added `make init` for submodules - * Updated Haml - * Updated sample chat app to show messages on load - * Updated libxmljs parseString -> parseHtmlString - * Fixed `make init` to work with older versions of git - * Fixed specs can now run independant specs for those who cant build deps. Closes #127 - * Fixed issues introduced by the node url module changes. Closes 126. - * Fixed two assertions failing due to Collection#keys() returning strings - * Fixed faulty Collection#toArray() spec due to keys() returning strings - * Fixed `make test` now builds libxmljs.node before testing - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/LICENSE b/frontend/express/node_modules/express/LICENSE deleted file mode 100644 index 36075a3b7fa..00000000000 --- a/frontend/express/node_modules/express/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2009-2011 TJ Holowaychuk - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/Makefile b/frontend/express/node_modules/express/Makefile deleted file mode 100644 index 228f299a9e7..00000000000 --- a/frontend/express/node_modules/express/Makefile +++ /dev/null @@ -1,33 +0,0 @@ - -MOCHA_OPTS= --check-leaks -REPORTER = dot - -check: test - -test: test-unit test-acceptance - -test-unit: - @NODE_ENV=test ./node_modules/.bin/mocha \ - --reporter $(REPORTER) \ - $(MOCHA_OPTS) - -test-acceptance: - @NODE_ENV=test ./node_modules/.bin/mocha \ - --reporter $(REPORTER) \ - --bail \ - test/acceptance/*.js - -test-cov: lib-cov - @EXPRESS_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html - -lib-cov: - @jscoverage lib lib-cov - -benchmark: - @./support/bench - -clean: - rm -f coverage.html - rm -fr lib-cov - -.PHONY: test test-unit test-acceptance benchmark clean diff --git a/frontend/express/node_modules/express/Readme.md b/frontend/express/node_modules/express/Readme.md deleted file mode 100644 index 00158b89960..00000000000 --- a/frontend/express/node_modules/express/Readme.md +++ /dev/null @@ -1,179 +0,0 @@ -![express logo](http://f.cl.ly/items/0V2S1n0K1i3y1c122g04/Screen%20Shot%202012-04-11%20at%209.59.42%20AM.png) - - Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [![Build Status](https://secure.travis-ci.org/visionmedia/express.png)](http://travis-ci.org/visionmedia/express) [![Dependency Status](https://gemnasium.com/visionmedia/express.png)](https://gemnasium.com/visionmedia/express) - -```js -var express = require('express'); -var app = express(); - -app.get('/', function(req, res){ - res.send('Hello World'); -}); - -app.listen(3000); -``` - -## Installation - - $ npm install -g express - -## Quick Start - - The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below: - - Create the app: - - $ npm install -g express - $ express /tmp/foo && cd /tmp/foo - - Install dependencies: - - $ npm install - - Start the server: - - $ node app - -## Features - - * Built on [Connect](http://github.com/senchalabs/connect) - * Robust routing - * HTTP helpers (redirection, caching, etc) - * View system supporting 14+ template engines - * Content negotiation - * Focus on high performance - * Environment based configuration - * Executable for generating applications quickly - * High test coverage - -## Philosophy - - The Express philosophy is to provide small, robust tooling for HTTP servers. Making - it a great solution for single page applications, web sites, hybrids, or public - HTTP APIs. - - Built on Connect you can use _only_ what you need, and nothing more, applications - can be as big or as small as you like, even a single file. Express does - not force you to use any specific ORM or template engine. With support for over - 14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js) - you can quickly craft your perfect framework. - -## More Information - - * Join #express on freenode - * [Google Group](http://groups.google.com/group/express-js) for discussion - * Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates - * Visit the [Wiki](http://github.com/visionmedia/express/wiki) - * [РуÑÑкоÑÐ·Ñ‹Ñ‡Ð½Ð°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ](http://jsman.ru/express/) - * Run express examples [online](https://runnable.com/express) - -## Viewing Examples - -Clone the Express repo, then install the dev dependencies to install all the example / test suite deps: - - $ git clone git://github.com/visionmedia/express.git --depth 1 - $ cd express - $ npm install - -then run whichever tests you want: - - $ node examples/content-negotiation - -## Running Tests - -To run the test suite first invoke the following command within the repo, installing the development dependencies: - - $ npm install - -then run the tests: - - $ make test - -## Contributors - -``` -project: express -commits: 3559 -active : 468 days -files : 237 -authors: - 1891 Tj Holowaychuk 53.1% - 1285 visionmedia 36.1% - 182 TJ Holowaychuk 5.1% - 54 Aaron Heckmann 1.5% - 34 csausdev 1.0% - 26 ciaranj 0.7% - 21 Robert Sköld 0.6% - 6 Guillermo Rauch 0.2% - 3 Dav Glass 0.1% - 3 Nick Poulden 0.1% - 2 Randy Merrill 0.1% - 2 Benny Wong 0.1% - 2 Hunter Loftis 0.1% - 2 Jake Gordon 0.1% - 2 Brian McKinney 0.1% - 2 Roman Shtylman 0.1% - 2 Ben Weaver 0.1% - 2 Dave Hoover 0.1% - 2 Eivind Fjeldstad 0.1% - 2 Daniel Shaw 0.1% - 1 Matt Colyer 0.0% - 1 Pau Ramon 0.0% - 1 Pero Pejovic 0.0% - 1 Peter Rekdal Sunde 0.0% - 1 Raynos 0.0% - 1 Teng Siong Ong 0.0% - 1 Viktor Kelemen 0.0% - 1 ctide 0.0% - 1 8bitDesigner 0.0% - 1 isaacs 0.0% - 1 mgutz 0.0% - 1 pikeas 0.0% - 1 shuwatto 0.0% - 1 tstrimple 0.0% - 1 ewoudj 0.0% - 1 Adam Sanderson 0.0% - 1 Andrii Kostenko 0.0% - 1 Andy Hiew 0.0% - 1 Arpad Borsos 0.0% - 1 Ashwin Purohit 0.0% - 1 Benjen 0.0% - 1 Darren Torpey 0.0% - 1 Greg Ritter 0.0% - 1 Gregory Ritter 0.0% - 1 James Herdman 0.0% - 1 Jim Snodgrass 0.0% - 1 Joe McCann 0.0% - 1 Jonathan Dumaine 0.0% - 1 Jonathan Palardy 0.0% - 1 Jonathan Zacsh 0.0% - 1 Justin Lilly 0.0% - 1 Ken Sato 0.0% - 1 Maciej MaÅ‚ecki 0.0% - 1 Masahiro Hayashi 0.0% -``` - -## License - -(The MIT License) - -Copyright (c) 2009-2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/express/bin/express b/frontend/express/node_modules/express/bin/express deleted file mode 100644 index b2b98c80253..00000000000 --- a/frontend/express/node_modules/express/bin/express +++ /dev/null @@ -1,422 +0,0 @@ -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var exec = require('child_process').exec - , program = require('commander') - , mkdirp = require('mkdirp') - , pkg = require('../package.json') - , version = pkg.version - , os = require('os') - , fs = require('fs'); - -// CLI - -program - .version(version) - .option('-s, --sessions', 'add session support') - .option('-e, --ejs', 'add ejs engine support (defaults to jade)') - .option('-J, --jshtml', 'add jshtml engine support (defaults to jade)') - .option('-H, --hogan', 'add hogan.js engine support') - .option('-c, --css ', 'add stylesheet support (less|stylus) (defaults to plain css)') - .option('-f, --force', 'force on non-empty directory') - .parse(process.argv); - -// Path - -var path = program.args.shift() || '.'; - -// end-of-line code - -var eol = os.EOL - -// Template engine - -program.template = 'jade'; -if (program.ejs) program.template = 'ejs'; -if (program.jshtml) program.template = 'jshtml'; -if (program.hogan) program.template = 'hjs'; - -/** - * Routes index template. - */ - -var index = [ - '' - , '/*' - , ' * GET home page.' - , ' */' - , '' - , 'exports.index = function(req, res){' - , ' res.render(\'index\', { title: \'Express\' });' - , '};' -].join(eol); - -/** - * Routes users template. - */ - -var users = [ - '' - , '/*' - , ' * GET users listing.' - , ' */' - , '' - , 'exports.list = function(req, res){' - , ' res.send("respond with a resource");' - , '};' -].join(eol); - -/** - * Jade layout template. - */ - -var jadeLayout = [ - 'doctype 5' - , 'html' - , ' head' - , ' title= title' - , ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')' - , ' body' - , ' block content' -].join(eol); - -/** - * Jade index template. - */ - -var jadeIndex = [ - 'extends layout' - , '' - , 'block content' - , ' h1= title' - , ' p Welcome to #{title}' -].join(eol); - -/** - * EJS index template. - */ - -var ejsIndex = [ - '' - , '' - , ' ' - , ' <%= title %>' - , ' ' - , ' ' - , ' ' - , '

    <%= title %>

    ' - , '

    Welcome to <%= title %>

    ' - , ' ' - , '' -].join(eol); - -/** - * JSHTML layout template. - */ - -var jshtmlLayout = [ - '' - , '' - , ' ' - , ' @write(title) ' - , ' ' - , ' ' - , ' ' - , ' @write(body)' - , ' ' - , '' -].join(eol); - -/** - * JSHTML index template. - */ - -var jshtmlIndex = [ - '

    @write(title)

    ' - , '

    Welcome to @write(title)

    ' -].join(eol); - -/** - * Hogan.js index template. - */ -var hoganIndex = [ - '' - , '' - , ' ' - , ' {{ title }}' - , ' ' - , ' ' - , ' ' - , '

    {{ title }}

    ' - , '

    Welcome to {{ title }}

    ' - , ' ' - , '' -].join(eol); - -/** - * Default css template. - */ - -var css = [ - 'body {' - , ' padding: 50px;' - , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;' - , '}' - , '' - , 'a {' - , ' color: #00B7FF;' - , '}' -].join(eol); - -/** - * Default less template. - */ - -var less = [ - 'body {' - , ' padding: 50px;' - , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;' - , '}' - , '' - , 'a {' - , ' color: #00B7FF;' - , '}' -].join(eol); - -/** - * Default stylus template. - */ - -var stylus = [ - 'body' - , ' padding: 50px' - , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif' - , 'a' - , ' color: #00B7FF' -].join(eol); - -/** - * App template. - */ - -var app = [ - '' - , '/**' - , ' * Module dependencies.' - , ' */' - , '' - , 'var express = require(\'express\')' - , ' , routes = require(\'./routes\')' - , ' , user = require(\'./routes/user\')' - , ' , http = require(\'http\')' - , ' , path = require(\'path\');' - , '' - , 'var app = express();' - , '' - , '// all environments' - , 'app.set(\'port\', process.env.PORT || 3000);' - , 'app.set(\'views\', __dirname + \'/views\');' - , 'app.set(\'view engine\', \':TEMPLATE\');' - , 'app.use(express.favicon());' - , 'app.use(express.logger(\'dev\'));' - , 'app.use(express.bodyParser());' - , 'app.use(express.methodOverride());{sess}' - , 'app.use(app.router);{css}' - , 'app.use(express.static(path.join(__dirname, \'public\')));' - , '' - , '// development only' - , 'if (\'development\' == app.get(\'env\')) {' - , ' app.use(express.errorHandler());' - , '}' - , '' - , 'app.get(\'/\', routes.index);' - , 'app.get(\'/users\', user.list);' - , '' - , 'http.createServer(app).listen(app.get(\'port\'), function(){' - , ' console.log(\'Express server listening on port \' + app.get(\'port\'));' - , '});' - , '' -].join(eol); - -// Generate application - -(function createApplication(path) { - emptyDirectory(path, function(empty){ - if (empty || program.force) { - createApplicationAt(path); - } else { - program.confirm('destination is not empty, continue? ', function(ok){ - if (ok) { - process.stdin.destroy(); - createApplicationAt(path); - } else { - abort('aborting'); - } - }); - } - }); -})(path); - -/** - * Create application at the given directory `path`. - * - * @param {String} path - */ - -function createApplicationAt(path) { - console.log(); - process.on('exit', function(){ - console.log(); - console.log(' install dependencies:'); - console.log(' $ cd %s && npm install', path); - console.log(); - console.log(' run the app:'); - console.log(' $ node app'); - console.log(); - }); - - mkdir(path, function(){ - mkdir(path + '/public'); - mkdir(path + '/public/javascripts'); - mkdir(path + '/public/images'); - mkdir(path + '/public/stylesheets', function(){ - switch (program.css) { - case 'less': - write(path + '/public/stylesheets/style.less', less); - break; - case 'stylus': - write(path + '/public/stylesheets/style.styl', stylus); - break; - default: - write(path + '/public/stylesheets/style.css', css); - } - }); - - mkdir(path + '/routes', function(){ - write(path + '/routes/index.js', index); - write(path + '/routes/user.js', users); - }); - - mkdir(path + '/views', function(){ - switch (program.template) { - case 'ejs': - write(path + '/views/index.ejs', ejsIndex); - break; - case 'jade': - write(path + '/views/layout.jade', jadeLayout); - write(path + '/views/index.jade', jadeIndex); - break; - case 'jshtml': - write(path + '/views/layout.jshtml', jshtmlLayout); - write(path + '/views/index.jshtml', jshtmlIndex); - break; - case 'hjs': - write(path + '/views/index.hjs', hoganIndex); - break; - - } - }); - - // CSS Engine support - switch (program.css) { - case 'less': - app = app.replace('{css}', eol + 'app.use(require(\'less-middleware\')({ src: __dirname + \'/public\' }));'); - break; - case 'stylus': - app = app.replace('{css}', eol + 'app.use(require(\'stylus\').middleware(__dirname + \'/public\'));'); - break; - default: - app = app.replace('{css}', ''); - } - - // Session support - app = app.replace('{sess}', program.sessions - ? eol + 'app.use(express.cookieParser(\'your secret here\'));' + eol + 'app.use(express.session());' - : ''); - - // Template support - app = app.replace(':TEMPLATE', program.template); - - // package.json - var pkg = { - name: 'application-name' - , version: '0.0.1' - , private: true - , scripts: { start: 'node app.js' } - , dependencies: { - express: version - } - } - - if (program.template) pkg.dependencies[program.template] = '*'; - - // CSS Engine support - switch (program.css) { - case 'less': - pkg.dependencies['less-middleware'] = '*'; - break; - default: - if (program.css) { - pkg.dependencies[program.css] = '*'; - } - } - - write(path + '/package.json', JSON.stringify(pkg, null, 2)); - write(path + '/app.js', app); - }); -} - -/** - * Check if the given directory `path` is empty. - * - * @param {String} path - * @param {Function} fn - */ - -function emptyDirectory(path, fn) { - fs.readdir(path, function(err, files){ - if (err && 'ENOENT' != err.code) throw err; - fn(!files || !files.length); - }); -} - -/** - * echo str > path. - * - * @param {String} path - * @param {String} str - */ - -function write(path, str) { - fs.writeFile(path, str); - console.log(' \x1b[36mcreate\x1b[0m : ' + path); -} - -/** - * Mkdir -p. - * - * @param {String} path - * @param {Function} fn - */ - -function mkdir(path, fn) { - mkdirp(path, 0755, function(err){ - if (err) throw err; - console.log(' \033[36mcreate\033[0m : ' + path); - fn && fn(); - }); -} - -/** - * Exit with the given `str`. - * - * @param {String} str - */ - -function abort(str) { - console.error(str); - process.exit(1); -} diff --git a/frontend/express/node_modules/express/index.js b/frontend/express/node_modules/express/index.js deleted file mode 100644 index bfe99345b76..00000000000 --- a/frontend/express/node_modules/express/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = process.env.EXPRESS_COV - ? require('./lib-cov/express') - : require('./lib/express'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/lib-cov/application.js b/frontend/express/node_modules/express/lib-cov/application.js deleted file mode 100644 index 86c80b48d58..00000000000 --- a/frontend/express/node_modules/express/lib-cov/application.js +++ /dev/null @@ -1,510 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['application.js']) { - _$jscoverage['application.js'] = []; - _$jscoverage['application.js'][12] = 0; - _$jscoverage['application.js'][29] = 0; - _$jscoverage['application.js'][41] = 0; - _$jscoverage['application.js'][42] = 0; - _$jscoverage['application.js'][43] = 0; - _$jscoverage['application.js'][44] = 0; - _$jscoverage['application.js'][45] = 0; - _$jscoverage['application.js'][46] = 0; - _$jscoverage['application.js'][47] = 0; - _$jscoverage['application.js'][50] = 0; - _$jscoverage['application.js'][51] = 0; - _$jscoverage['application.js'][52] = 0; - _$jscoverage['application.js'][55] = 0; - _$jscoverage['application.js'][56] = 0; - _$jscoverage['application.js'][61] = 0; - _$jscoverage['application.js'][62] = 0; - _$jscoverage['application.js'][71] = 0; - _$jscoverage['application.js'][72] = 0; - _$jscoverage['application.js'][75] = 0; - _$jscoverage['application.js'][76] = 0; - _$jscoverage['application.js'][79] = 0; - _$jscoverage['application.js'][80] = 0; - _$jscoverage['application.js'][83] = 0; - _$jscoverage['application.js'][84] = 0; - _$jscoverage['application.js'][85] = 0; - _$jscoverage['application.js'][89] = 0; - _$jscoverage['application.js'][90] = 0; - _$jscoverage['application.js'][91] = 0; - _$jscoverage['application.js'][93] = 0; - _$jscoverage['application.js'][94] = 0; - _$jscoverage['application.js'][95] = 0; - _$jscoverage['application.js'][98] = 0; - _$jscoverage['application.js'][102] = 0; - _$jscoverage['application.js'][103] = 0; - _$jscoverage['application.js'][104] = 0; - _$jscoverage['application.js'][105] = 0; - _$jscoverage['application.js'][106] = 0; - _$jscoverage['application.js'][107] = 0; - _$jscoverage['application.js'][108] = 0; - _$jscoverage['application.js'][112] = 0; - _$jscoverage['application.js'][115] = 0; - _$jscoverage['application.js'][116] = 0; - _$jscoverage['application.js'][119] = 0; - _$jscoverage['application.js'][120] = 0; - _$jscoverage['application.js'][132] = 0; - _$jscoverage['application.js'][133] = 0; - _$jscoverage['application.js'][145] = 0; - _$jscoverage['application.js'][146] = 0; - _$jscoverage['application.js'][159] = 0; - _$jscoverage['application.js'][160] = 0; - _$jscoverage['application.js'][163] = 0; - _$jscoverage['application.js'][166] = 0; - _$jscoverage['application.js'][169] = 0; - _$jscoverage['application.js'][170] = 0; - _$jscoverage['application.js'][171] = 0; - _$jscoverage['application.js'][172] = 0; - _$jscoverage['application.js'][173] = 0; - _$jscoverage['application.js'][174] = 0; - _$jscoverage['application.js'][175] = 0; - _$jscoverage['application.js'][180] = 0; - _$jscoverage['application.js'][181] = 0; - _$jscoverage['application.js'][184] = 0; - _$jscoverage['application.js'][185] = 0; - _$jscoverage['application.js'][186] = 0; - _$jscoverage['application.js'][189] = 0; - _$jscoverage['application.js'][209] = 0; - _$jscoverage['application.js'][210] = 0; - _$jscoverage['application.js'][211] = 0; - _$jscoverage['application.js'][212] = 0; - _$jscoverage['application.js'][274] = 0; - _$jscoverage['application.js'][275] = 0; - _$jscoverage['application.js'][279] = 0; - _$jscoverage['application.js'][280] = 0; - _$jscoverage['application.js'][281] = 0; - _$jscoverage['application.js'][282] = 0; - _$jscoverage['application.js'][286] = 0; - _$jscoverage['application.js'][287] = 0; - _$jscoverage['application.js'][290] = 0; - _$jscoverage['application.js'][291] = 0; - _$jscoverage['application.js'][292] = 0; - _$jscoverage['application.js'][296] = 0; - _$jscoverage['application.js'][309] = 0; - _$jscoverage['application.js'][310] = 0; - _$jscoverage['application.js'][311] = 0; - _$jscoverage['application.js'][312] = 0; - _$jscoverage['application.js'][313] = 0; - _$jscoverage['application.js'][314] = 0; - _$jscoverage['application.js'][317] = 0; - _$jscoverage['application.js'][318] = 0; - _$jscoverage['application.js'][331] = 0; - _$jscoverage['application.js'][332] = 0; - _$jscoverage['application.js'][345] = 0; - _$jscoverage['application.js'][346] = 0; - _$jscoverage['application.js'][357] = 0; - _$jscoverage['application.js'][358] = 0; - _$jscoverage['application.js'][369] = 0; - _$jscoverage['application.js'][370] = 0; - _$jscoverage['application.js'][381] = 0; - _$jscoverage['application.js'][382] = 0; - _$jscoverage['application.js'][411] = 0; - _$jscoverage['application.js'][412] = 0; - _$jscoverage['application.js'][414] = 0; - _$jscoverage['application.js'][415] = 0; - _$jscoverage['application.js'][416] = 0; - _$jscoverage['application.js'][417] = 0; - _$jscoverage['application.js'][430] = 0; - _$jscoverage['application.js'][431] = 0; - _$jscoverage['application.js'][432] = 0; - _$jscoverage['application.js'][439] = 0; - _$jscoverage['application.js'][440] = 0; - _$jscoverage['application.js'][441] = 0; - _$jscoverage['application.js'][442] = 0; - _$jscoverage['application.js'][443] = 0; - _$jscoverage['application.js'][444] = 0; - _$jscoverage['application.js'][458] = 0; - _$jscoverage['application.js'][459] = 0; - _$jscoverage['application.js'][460] = 0; - _$jscoverage['application.js'][461] = 0; - _$jscoverage['application.js'][462] = 0; - _$jscoverage['application.js'][464] = 0; - _$jscoverage['application.js'][469] = 0; - _$jscoverage['application.js'][482] = 0; - _$jscoverage['application.js'][483] = 0; - _$jscoverage['application.js'][490] = 0; - _$jscoverage['application.js'][491] = 0; - _$jscoverage['application.js'][495] = 0; - _$jscoverage['application.js'][498] = 0; - _$jscoverage['application.js'][501] = 0; - _$jscoverage['application.js'][504] = 0; - _$jscoverage['application.js'][509] = 0; - _$jscoverage['application.js'][512] = 0; - _$jscoverage['application.js'][513] = 0; - _$jscoverage['application.js'][520] = 0; - _$jscoverage['application.js'][524] = 0; - _$jscoverage['application.js'][525] = 0; - _$jscoverage['application.js'][527] = 0; -} -_$jscoverage['application.js'][12]++; -var connect = require("connect"), Router = require("./router"), methods = Router.methods.concat("del", "all"), middleware = require("./middleware"), debug = require("debug")("express:application"), View = require("./view"), url = require("url"), utils = connect.utils, path = require("path"), http = require("http"), join = path.join, fs = require("fs"); -_$jscoverage['application.js'][29]++; -var app = exports = module.exports = {}; -_$jscoverage['application.js'][41]++; -app.init = (function () { - _$jscoverage['application.js'][42]++; - var self = this; - _$jscoverage['application.js'][43]++; - this.cache = {}; - _$jscoverage['application.js'][44]++; - this.settings = {}; - _$jscoverage['application.js'][45]++; - this.engines = {}; - _$jscoverage['application.js'][46]++; - this.viewCallbacks = []; - _$jscoverage['application.js'][47]++; - this.defaultConfiguration(); - _$jscoverage['application.js'][50]++; - methods.forEach((function (method) { - _$jscoverage['application.js'][51]++; - self.lookup[method] = (function (path) { - _$jscoverage['application.js'][52]++; - return self._router.lookup(method, path); -}); - _$jscoverage['application.js'][55]++; - self.remove[method] = (function (path) { - _$jscoverage['application.js'][56]++; - return self._router.lookup(method, path).remove(); -}); -})); - _$jscoverage['application.js'][61]++; - self.lookup.del = self.lookup["delete"]; - _$jscoverage['application.js'][62]++; - self.remove.del = self.remove["delete"]; -}); -_$jscoverage['application.js'][71]++; -app.defaultConfiguration = (function () { - _$jscoverage['application.js'][72]++; - var self = this; - _$jscoverage['application.js'][75]++; - this.set("env", process.env.NODE_ENV || "development"); - _$jscoverage['application.js'][76]++; - debug("booting in %s mode", this.get("env")); - _$jscoverage['application.js'][79]++; - this.use(connect.query()); - _$jscoverage['application.js'][80]++; - this.use(middleware.init(this)); - _$jscoverage['application.js'][83]++; - this.locals = (function (obj) { - _$jscoverage['application.js'][84]++; - for (var key in obj) { - _$jscoverage['application.js'][84]++; - self.locals[key] = obj[key]; -} - _$jscoverage['application.js'][85]++; - return self; -}); - _$jscoverage['application.js'][89]++; - this.locals.use = (function (fn) { - _$jscoverage['application.js'][90]++; - if (3 == fn.length) { - _$jscoverage['application.js'][91]++; - self.viewCallbacks.push(fn); - } - else { - _$jscoverage['application.js'][93]++; - self.viewCallbacks.push((function (req, res, done) { - _$jscoverage['application.js'][94]++; - fn(req, res); - _$jscoverage['application.js'][95]++; - done(); -})); - } - _$jscoverage['application.js'][98]++; - return this; -}); - _$jscoverage['application.js'][102]++; - this._router = new Router(this); - _$jscoverage['application.js'][103]++; - this.routes = this._router.routes; - _$jscoverage['application.js'][104]++; - this.__defineGetter__("router", (function () { - _$jscoverage['application.js'][105]++; - this._usedRouter = true; - _$jscoverage['application.js'][106]++; - this._router.caseSensitive = this.enabled("case sensitive routing"); - _$jscoverage['application.js'][107]++; - this._router.strict = this.enabled("strict routing"); - _$jscoverage['application.js'][108]++; - return this._router.middleware; -})); - _$jscoverage['application.js'][112]++; - this.locals.settings = this.settings; - _$jscoverage['application.js'][115]++; - this.configure("development", (function () { - _$jscoverage['application.js'][116]++; - this.set("json spaces", 2); -})); - _$jscoverage['application.js'][119]++; - this.configure("production", (function () { - _$jscoverage['application.js'][120]++; - this.enable("view cache"); -})); -}); -_$jscoverage['application.js'][132]++; -app.remove = (function (path) { - _$jscoverage['application.js'][133]++; - return this._router.lookup("all", path).remove(); -}); -_$jscoverage['application.js'][145]++; -app.lookup = (function (path) { - _$jscoverage['application.js'][146]++; - return this._router.lookup("all", path); -}); -_$jscoverage['application.js'][159]++; -app.use = (function (route, fn) { - _$jscoverage['application.js'][160]++; - var app, home, handle; - _$jscoverage['application.js'][163]++; - if ("string" != typeof route) { - _$jscoverage['application.js'][163]++; - fn = route, route = "/"; - } - _$jscoverage['application.js'][166]++; - if (fn.handle && fn.set) { - _$jscoverage['application.js'][166]++; - app = fn; - } - _$jscoverage['application.js'][169]++; - if (app) { - _$jscoverage['application.js'][170]++; - app.route = route; - _$jscoverage['application.js'][171]++; - fn = (function (req, res, next) { - _$jscoverage['application.js'][172]++; - var orig = req.app; - _$jscoverage['application.js'][173]++; - app.handle(req, res, (function (err) { - _$jscoverage['application.js'][174]++; - req.app = res.app = orig; - _$jscoverage['application.js'][175]++; - next(err); -})); -}); - } - _$jscoverage['application.js'][180]++; - debug("use %s %s", route, fn.name || "unnamed"); - _$jscoverage['application.js'][181]++; - connect.proto.use.call(this, route, fn); - _$jscoverage['application.js'][184]++; - if (app) { - _$jscoverage['application.js'][185]++; - app.parent = this; - _$jscoverage['application.js'][186]++; - app.emit("mount", this); - } - _$jscoverage['application.js'][189]++; - return this; -}); -_$jscoverage['application.js'][209]++; -app.engine = (function (ext, fn) { - _$jscoverage['application.js'][210]++; - if ("." != ext[0]) { - _$jscoverage['application.js'][210]++; - ext = "." + ext; - } - _$jscoverage['application.js'][211]++; - this.engines[ext] = fn; - _$jscoverage['application.js'][212]++; - return this; -}); -_$jscoverage['application.js'][274]++; -app.param = (function (name, fn) { - _$jscoverage['application.js'][275]++; - var self = this, fns = [].slice.call(arguments, 1); - _$jscoverage['application.js'][279]++; - if (Array.isArray(name)) { - _$jscoverage['application.js'][280]++; - name.forEach((function (name) { - _$jscoverage['application.js'][281]++; - fns.forEach((function (fn) { - _$jscoverage['application.js'][282]++; - self.param(name, fn); -})); -})); - } - else { - _$jscoverage['application.js'][286]++; - if ("function" == typeof name) { - _$jscoverage['application.js'][287]++; - this._router.param(name); - } - else { - _$jscoverage['application.js'][290]++; - if (":" == name[0]) { - _$jscoverage['application.js'][290]++; - name = name.substr(1); - } - _$jscoverage['application.js'][291]++; - fns.forEach((function (fn) { - _$jscoverage['application.js'][292]++; - self._router.param(name, fn); -})); - } - } - _$jscoverage['application.js'][296]++; - return this; -}); -_$jscoverage['application.js'][309]++; -app.set = (function (setting, val) { - _$jscoverage['application.js'][310]++; - if (1 == arguments.length) { - _$jscoverage['application.js'][311]++; - if (this.settings.hasOwnProperty(setting)) { - _$jscoverage['application.js'][312]++; - return this.settings[setting]; - } - else { - _$jscoverage['application.js'][313]++; - if (this.parent) { - _$jscoverage['application.js'][314]++; - return this.parent.set(setting); - } - } - } - else { - _$jscoverage['application.js'][317]++; - this.settings[setting] = val; - _$jscoverage['application.js'][318]++; - return this; - } -}); -_$jscoverage['application.js'][331]++; -app.path = (function () { - _$jscoverage['application.js'][332]++; - return this.parent? this.parent.path() + this.route: ""; -}); -_$jscoverage['application.js'][345]++; -app.enabled = (function (setting) { - _$jscoverage['application.js'][346]++; - return ! ! this.set(setting); -}); -_$jscoverage['application.js'][357]++; -app.disabled = (function (setting) { - _$jscoverage['application.js'][358]++; - return ! this.set(setting); -}); -_$jscoverage['application.js'][369]++; -app.enable = (function (setting) { - _$jscoverage['application.js'][370]++; - return this.set(setting, true); -}); -_$jscoverage['application.js'][381]++; -app.disable = (function (setting) { - _$jscoverage['application.js'][382]++; - return this.set(setting, false); -}); -_$jscoverage['application.js'][411]++; -app.configure = (function (env, fn) { - _$jscoverage['application.js'][412]++; - var envs = "all", args = [].slice.call(arguments); - _$jscoverage['application.js'][414]++; - fn = args.pop(); - _$jscoverage['application.js'][415]++; - if (args.length) { - _$jscoverage['application.js'][415]++; - envs = args; - } - _$jscoverage['application.js'][416]++; - if ("all" == envs || ~ envs.indexOf(this.settings.env)) { - _$jscoverage['application.js'][416]++; - fn.call(this); - } - _$jscoverage['application.js'][417]++; - return this; -}); -_$jscoverage['application.js'][430]++; -app.listen = (function () { - _$jscoverage['application.js'][431]++; - var server = http.createServer(this); - _$jscoverage['application.js'][432]++; - return server.listen.apply(server, arguments); -}); -_$jscoverage['application.js'][439]++; -methods.forEach((function (method) { - _$jscoverage['application.js'][440]++; - app[method] = (function (path) { - _$jscoverage['application.js'][441]++; - if ("get" == method && 1 == arguments.length) { - _$jscoverage['application.js'][441]++; - return this.set(path); - } - _$jscoverage['application.js'][442]++; - var args = [method].concat([].slice.call(arguments)); - _$jscoverage['application.js'][443]++; - if (! this._usedRouter) { - _$jscoverage['application.js'][443]++; - this.use(this.router); - } - _$jscoverage['application.js'][444]++; - return this._router.route.apply(this._router, args); -}); -})); -_$jscoverage['application.js'][458]++; -app.all = (function (path) { - _$jscoverage['application.js'][459]++; - var args = arguments; - _$jscoverage['application.js'][460]++; - methods.forEach((function (method) { - _$jscoverage['application.js'][461]++; - if ("all" == method || "del" == method) { - _$jscoverage['application.js'][461]++; - return; - } - _$jscoverage['application.js'][462]++; - app[method].apply(this, args); -}), this); - _$jscoverage['application.js'][464]++; - return this; -}); -_$jscoverage['application.js'][469]++; -app.del = app["delete"]; -_$jscoverage['application.js'][482]++; -app.render = (function (name, options, fn) { - _$jscoverage['application.js'][483]++; - var self = this, opts = {}, cache = this.cache, engines = this.engines, view; - _$jscoverage['application.js'][490]++; - if ("function" == typeof options) { - _$jscoverage['application.js'][491]++; - fn = options, options = {}; - } - _$jscoverage['application.js'][495]++; - utils.merge(opts, this.locals); - _$jscoverage['application.js'][498]++; - if (options.locals) { - _$jscoverage['application.js'][498]++; - utils.merge(opts, options.locals); - } - _$jscoverage['application.js'][501]++; - utils.merge(opts, options); - _$jscoverage['application.js'][504]++; - opts.cache = null == opts.cache? this.enabled("view cache"): opts.cache; - _$jscoverage['application.js'][509]++; - if (opts.cache) { - _$jscoverage['application.js'][509]++; - view = cache[name]; - } - _$jscoverage['application.js'][512]++; - if (! view) { - _$jscoverage['application.js'][513]++; - view = new View(name, {defaultEngine: this.get("view engine"), root: this.get("views") || process.cwd() + "/views", engines: engines}); - _$jscoverage['application.js'][520]++; - if (opts.cache) { - _$jscoverage['application.js'][520]++; - cache[name] = view; - } - } - _$jscoverage['application.js'][524]++; - try { - _$jscoverage['application.js'][525]++; - view.render(opts, fn); - } - catch (err) { - _$jscoverage['application.js'][527]++; - fn(err); - } -}); -_$jscoverage['application.js'].source = ["","/*!"," * Express - proto"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var connect = require('connect')"," , Router = require('./router')"," , methods = Router.methods.concat('del', 'all')"," , middleware = require('./middleware')"," , debug = require('debug')('express:application')"," , View = require('./view')"," , url = require('url')"," , utils = connect.utils"," , path = require('path')"," , http = require('http')"," , join = path.join"," , fs = require('fs');","","/**"," * Application prototype."," */","","var app = exports = module.exports = {};","","/**"," * Initialize the server."," *"," * - setup default configuration"," * - setup default middleware"," * - setup route reflection methods"," *"," * @api private"," */","","app.init = function(){"," var self = this;"," this.cache = {};"," this.settings = {};"," this.engines = {};"," this.viewCallbacks = [];"," this.defaultConfiguration();",""," // route reflection methods"," methods.forEach(function(method){"," self.lookup[method] = function(path){"," return self._router.lookup(method, path);"," };",""," self.remove[method] = function(path){"," return self._router.lookup(method, path).remove();"," };"," });",""," // del -> delete"," self.lookup.del = self.lookup.delete;"," self.remove.del = self.remove.delete;","};","","/**"," * Initialize application configuration."," *"," * @api private"," */","","app.defaultConfiguration = function(){"," var self = this;",""," // default settings"," this.set('env', process.env.NODE_ENV || 'development');"," debug('booting in %s mode', this.get('env'));",""," // implicit middleware"," this.use(connect.query());"," this.use(middleware.init(this));",""," // app locals"," this.locals = function(obj){"," for (var key in obj) self.locals[key] = obj[key];"," return self;"," };",""," // response locals"," this.locals.use = function(fn){"," if (3 == fn.length) {"," self.viewCallbacks.push(fn);"," } else {"," self.viewCallbacks.push(function(req, res, done){"," fn(req, res);"," done();"," });"," }"," return this;"," };",""," // router"," this._router = new Router(this);"," this.routes = this._router.routes;"," this.__defineGetter__('router', function(){"," this._usedRouter = true;"," this._router.caseSensitive = this.enabled('case sensitive routing');"," this._router.strict = this.enabled('strict routing');"," return this._router.middleware;"," });",""," // default locals"," this.locals.settings = this.settings;",""," // default configuration"," this.configure('development', function(){"," this.set('json spaces', 2);"," });",""," this.configure('production', function(){"," this.enable('view cache');"," });","};","","/**"," * Remove routes matching the given `path`."," *"," * @param {Route} path"," * @return {Boolean}"," * @api public"," */","","app.remove = function(path){"," return this._router.lookup('all', path).remove();","};","","/**"," * Lookup routes defined with a path"," * equivalent to `path`."," *"," * @param {String} path"," * @return {Array}"," * @api public"," */","","app.lookup = function(path){"," return this._router.lookup('all', path);","};","","/**"," * Proxy `connect#use()` to apply settings to"," * mounted applications."," *"," * @param {String|Function|Server} route"," * @param {Function|Server} fn"," * @return {app} for chaining"," * @api public"," */","","app.use = function(route, fn){"," var app, home, handle;",""," // default route to '/'"," if ('string' != typeof route) fn = route, route = '/';",""," // express app"," if (fn.handle && fn.set) app = fn;",""," // restore .app property on req and res"," if (app) {"," app.route = route;"," fn = function(req, res, next) {"," var orig = req.app;"," app.handle(req, res, function(err){"," req.app = res.app = orig;"," next(err);"," });"," };"," }",""," debug('use %s %s', route, fn.name || 'unnamed');"," connect.proto.use.call(this, route, fn);",""," // mounted an app"," if (app) {"," app.parent = this;"," app.emit('mount', this);"," }",""," return this;","};","","/**"," * Register the given template engine callback `fn`"," * as `ext`. For example we may wish to map \".html\""," * files to ejs rather than using the \".ejs\" extension."," *"," * app.engine('.html', require('ejs').render);"," *"," * or"," *"," * app.engine('html', require('ejs').render);"," *"," * @param {String} ext"," * @param {Function} fn"," * @return {app} for chaining"," * @api public"," */","","app.engine = function(ext, fn){"," if ('.' != ext[0]) ext = '.' + ext;"," this.engines[ext] = fn;"," return this;","};","","/**"," * Map the given param placeholder `name`(s) to the given callback(s)."," *"," * Param mapping is used to provide pre-conditions to routes"," * which us normalized placeholders. This callback has the same"," * signature as regular middleware, for example below when \":userId\""," * is used this function will be invoked in an attempt to load the user."," *"," * app.param('userId', function(req, res, next, id){"," * User.find(id, function(err, user){"," * if (err) {"," * next(err);"," * } else if (user) {"," * req.user = user;"," * next();"," * } else {"," * next(new Error('failed to load user'));"," * }"," * });"," * });"," *"," * Passing a single function allows you to map logic"," * to the values passed to `app.param()`, for example"," * this is useful to provide coercion support in a concise manner."," *"," * The following example maps regular expressions to param values"," * ensuring that they match, otherwise passing control to the next"," * route:"," *"," * app.param(function(name, regexp){"," * if (regexp instanceof RegExp) {"," * return function(req, res, next, val){"," * var captures;"," * if (captures = regexp.exec(String(val))) {"," * req.params[name] = captures;"," * next();"," * } else {"," * next('route');"," * }"," * }"," * }"," * });"," *"," * We can now use it as shown below, where \"/commit/:commit\" expects"," * that the value for \":commit\" is at 5 or more digits. The capture"," * groups are then available as `req.params.commit` as we defined"," * in the function above."," *"," * app.param('commit', /^\\d{5,}$/);"," *"," * For more of this useful functionality take a look"," * at [express-params](http://github.com/visionmedia/express-params)."," *"," * @param {String|Array|Function} name"," * @param {Function} fn"," * @return {app} for chaining"," * @api public"," */","","app.param = function(name, fn){"," var self = this"," , fns = [].slice.call(arguments, 1);",""," // array"," if (Array.isArray(name)) {"," name.forEach(function(name){"," fns.forEach(function(fn){"," self.param(name, fn);"," });"," });"," // param logic"," } else if ('function' == typeof name) {"," this._router.param(name);"," // single"," } else {"," if (':' == name[0]) name = name.substr(1);"," fns.forEach(function(fn){"," self._router.param(name, fn);"," });"," }",""," return this;","};","","/**"," * Assign `setting` to `val`, or return `setting`'s value."," * Mounted servers inherit their parent server's settings."," *"," * @param {String} setting"," * @param {String} val"," * @return {Server|Mixed} for chaining, or the setting value"," * @api public"," */","","app.set = function(setting, val){"," if (1 == arguments.length) {"," if (this.settings.hasOwnProperty(setting)) {"," return this.settings[setting];"," } else if (this.parent) {"," return this.parent.set(setting);"," }"," } else {"," this.settings[setting] = val;"," return this;"," }","};","","/**"," * Return the app's absolute pathname"," * based on the parent(s) that have"," * mounted it."," *"," * @return {String}"," * @api private"," */","","app.path = function(){"," return this.parent"," ? this.parent.path() + this.route"," : '';","};","","/**"," * Check if `setting` is enabled."," *"," * @param {String} setting"," * @return {Boolean}"," * @api public"," */","","app.enabled = function(setting){"," return !!this.set(setting);","};","","/**"," * Check if `setting` is disabled."," *"," * @param {String} setting"," * @return {Boolean}"," * @api public"," */","","app.disabled = function(setting){"," return !this.set(setting);","};","","/**"," * Enable `setting`."," *"," * @param {String} setting"," * @return {app} for chaining"," * @api public"," */","","app.enable = function(setting){"," return this.set(setting, true);","};","","/**"," * Disable `setting`."," *"," * @param {String} setting"," * @return {app} for chaining"," * @api public"," */","","app.disable = function(setting){"," return this.set(setting, false);","};","","/**"," * Configure callback for zero or more envs,"," * when no env is specified that callback will"," * be invoked for all environments. Any combination"," * can be used multiple times, in any order desired."," *"," * Examples:"," *"," * app.configure(function(){"," * // executed for all envs"," * });"," *"," * app.configure('stage', function(){"," * // executed staging env"," * });"," *"," * app.configure('stage', 'production', function(){"," * // executed for stage and production"," * });"," *"," * @param {String} env..."," * @param {Function} fn"," * @return {app} for chaining"," * @api public"," */","","app.configure = function(env, fn){"," var envs = 'all'"," , args = [].slice.call(arguments);"," fn = args.pop();"," if (args.length) envs = args;"," if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this);"," return this;","};","","/**"," * Listen for connections."," *"," * This method takes the same arguments"," * as node's `http.Server#listen()`. "," *"," * @return {http.Server}"," * @api public"," */","","app.listen = function(){"," var server = http.createServer(this);"," return server.listen.apply(server, arguments);","};","","/**"," * Delegate `.VERB(...)` calls to `.route(VERB, ...)`."," */","","methods.forEach(function(method){"," app[method] = function(path){"," if ('get' == method && 1 == arguments.length) return this.set(path); "," var args = [method].concat([].slice.call(arguments));"," if (!this._usedRouter) this.use(this.router);"," return this._router.route.apply(this._router, args);"," }","});","","/**"," * Special-cased \"all\" method, applying the given route `path`,"," * middleware, and callback to _every_ HTTP method."," *"," * @param {String} path"," * @param {Function} ..."," * @return {app} for chaining"," * @api public"," */","","app.all = function(path){"," var args = arguments;"," methods.forEach(function(method){"," if ('all' == method || 'del' == method) return;"," app[method].apply(this, args);"," }, this);"," return this;","};","","// del -> delete alias","","app.del = app.delete;","","/**"," * Render the given view `name` name with `options`"," * and a callback accepting an error and the"," * rendered template string."," *"," * @param {String} name"," * @param {String|Function} options or fn"," * @param {Function} fn"," * @api public"," */","","app.render = function(name, options, fn){"," var self = this"," , opts = {}"," , cache = this.cache"," , engines = this.engines"," , view;",""," // support callback function as second arg"," if ('function' == typeof options) {"," fn = options, options = {};"," }",""," // merge app.locals"," utils.merge(opts, this.locals);",""," // merge options.locals"," if (options.locals) utils.merge(opts, options.locals);",""," // merge options"," utils.merge(opts, options);",""," // set .cache unless explicitly provided"," opts.cache = null == opts.cache"," ? this.enabled('view cache')"," : opts.cache;",""," // primed cache"," if (opts.cache) view = cache[name];",""," // view"," if (!view) {"," view = new View(name, {"," defaultEngine: this.get('view engine')"," , root: this.get('views') || process.cwd() + '/views'"," , engines: engines"," });",""," // prime the cache"," if (opts.cache) cache[name] = view;"," }",""," // render"," try {"," view.render(opts, fn);"," } catch (err) {"," fn(err);"," }","};"]; diff --git a/frontend/express/node_modules/express/lib-cov/express.js b/frontend/express/node_modules/express/lib-cov/express.js deleted file mode 100644 index 8e191abf3fa..00000000000 --- a/frontend/express/node_modules/express/lib-cov/express.js +++ /dev/null @@ -1,65 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['express.js']) { - _$jscoverage['express.js'] = []; - _$jscoverage['express.js'][12] = 0; - _$jscoverage['express.js'][25] = 0; - _$jscoverage['express.js'][31] = 0; - _$jscoverage['express.js'][40] = 0; - _$jscoverage['express.js'][41] = 0; - _$jscoverage['express.js'][42] = 0; - _$jscoverage['express.js'][43] = 0; - _$jscoverage['express.js'][44] = 0; - _$jscoverage['express.js'][45] = 0; - _$jscoverage['express.js'][46] = 0; - _$jscoverage['express.js'][54] = 0; - _$jscoverage['express.js'][55] = 0; - _$jscoverage['express.js'][65] = 0; - _$jscoverage['express.js'][66] = 0; - _$jscoverage['express.js'][67] = 0; - _$jscoverage['express.js'][73] = 0; - _$jscoverage['express.js'][74] = 0; - _$jscoverage['express.js'][80] = 0; - _$jscoverage['express.js'][84] = 0; -} -_$jscoverage['express.js'][12]++; -var http = require("http"), connect = require("connect"), proto = require("./application"), Route = require("./router/route"), Router = require("./router"), req = require("./request"), res = require("./response"), utils = connect.utils; -_$jscoverage['express.js'][25]++; -exports = module.exports = createApplication; -_$jscoverage['express.js'][31]++; -exports.version = "3.0.0alpha1-pre"; -_$jscoverage['express.js'][40]++; -function createApplication() { - _$jscoverage['express.js'][41]++; - var app = connect(); - _$jscoverage['express.js'][42]++; - utils.merge(app, proto); - _$jscoverage['express.js'][43]++; - app.request = {__proto__: req}; - _$jscoverage['express.js'][44]++; - app.response = {__proto__: res}; - _$jscoverage['express.js'][45]++; - app.init(); - _$jscoverage['express.js'][46]++; - return app; -} -_$jscoverage['express.js'][54]++; -for (var key in connect.middleware) { - _$jscoverage['express.js'][55]++; - Object.defineProperty(exports, key, Object.getOwnPropertyDescriptor(connect.middleware, key)); -} -_$jscoverage['express.js'][65]++; -exports.application = proto; -_$jscoverage['express.js'][66]++; -exports.request = req; -_$jscoverage['express.js'][67]++; -exports.response = res; -_$jscoverage['express.js'][73]++; -exports.Route = Route; -_$jscoverage['express.js'][74]++; -exports.Router = Router; -_$jscoverage['express.js'][80]++; -exports.methods = require("./router/methods"); -_$jscoverage['express.js'][84]++; -exports.errorHandler.title = "Express"; -_$jscoverage['express.js'].source = ["","/*!"," * Express"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var http = require('http')"," , connect = require('connect')"," , proto = require('./application')"," , Route = require('./router/route')"," , Router = require('./router')"," , req = require('./request')"," , res = require('./response')"," , utils = connect.utils;","","/**"," * Expose `createApplication()`."," */","","exports = module.exports = createApplication;","","/**"," * Framework version."," */","","exports.version = '3.0.0alpha1-pre';","","/**"," * Create an express application."," *"," * @return {Function}"," * @api public"," */","","function createApplication() {"," var app = connect();"," utils.merge(app, proto);"," app.request = { __proto__: req };"," app.response = { __proto__: res };"," app.init();"," return app;","}","","/**"," * Expose connect.middleware as express.*"," * for example `express.logger` etc. "," */","","for (var key in connect.middleware) {"," Object.defineProperty("," exports"," , key"," , Object.getOwnPropertyDescriptor(connect.middleware, key));","}","","/**"," * Expose the prototypes."," */","","exports.application = proto;","exports.request = req;","exports.response = res;","","/**"," * Expose constructors."," */","","exports.Route = Route;","exports.Router = Router;","","/**"," * Expose HTTP methods."," */","","exports.methods = require('./router/methods');","","// Error handler title","","exports.errorHandler.title = 'Express';",""]; diff --git a/frontend/express/node_modules/express/lib-cov/middleware.js b/frontend/express/node_modules/express/lib-cov/middleware.js deleted file mode 100644 index f1a3e6d597d..00000000000 --- a/frontend/express/node_modules/express/lib-cov/middleware.js +++ /dev/null @@ -1,54 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['middleware.js']) { - _$jscoverage['middleware.js'] = []; - _$jscoverage['middleware.js'][18] = 0; - _$jscoverage['middleware.js'][19] = 0; - _$jscoverage['middleware.js'][20] = 0; - _$jscoverage['middleware.js'][21] = 0; - _$jscoverage['middleware.js'][22] = 0; - _$jscoverage['middleware.js'][23] = 0; - _$jscoverage['middleware.js'][24] = 0; - _$jscoverage['middleware.js'][25] = 0; - _$jscoverage['middleware.js'][27] = 0; - _$jscoverage['middleware.js'][28] = 0; - _$jscoverage['middleware.js'][30] = 0; - _$jscoverage['middleware.js'][31] = 0; - _$jscoverage['middleware.js'][32] = 0; - _$jscoverage['middleware.js'][35] = 0; -} -_$jscoverage['middleware.js'][18]++; -exports.init = (function (app) { - _$jscoverage['middleware.js'][19]++; - return (function (req, res, next) { - _$jscoverage['middleware.js'][20]++; - var charset; - _$jscoverage['middleware.js'][21]++; - res.setHeader("X-Powered-By", "Express"); - _$jscoverage['middleware.js'][22]++; - req.app = res.app = app; - _$jscoverage['middleware.js'][23]++; - req.res = res; - _$jscoverage['middleware.js'][24]++; - res.req = req; - _$jscoverage['middleware.js'][25]++; - req.next = next; - _$jscoverage['middleware.js'][27]++; - req.__proto__ = app.request; - _$jscoverage['middleware.js'][28]++; - res.__proto__ = app.response; - _$jscoverage['middleware.js'][30]++; - res.locals = (function (obj) { - _$jscoverage['middleware.js'][31]++; - for (var key in obj) { - _$jscoverage['middleware.js'][31]++; - res.locals[key] = obj[key]; -} - _$jscoverage['middleware.js'][32]++; - return res; -}); - _$jscoverage['middleware.js'][35]++; - next(); -}); -}); -_$jscoverage['middleware.js'].source = ["","/*!"," * Express - middleware - init"," * Copyright(c) 2010-2011 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Initialization middleware, exposing the"," * request and response to eachother, as well"," * as defaulting the X-Powered-By header field."," *"," * @param {Function} app"," * @return {Function}"," * @api private"," */","","exports.init = function(app){"," return function(req, res, next){"," var charset;"," res.setHeader('X-Powered-By', 'Express');"," req.app = res.app = app;"," req.res = res;"," res.req = req;"," req.next = next;",""," req.__proto__ = app.request;"," res.__proto__ = app.response;",""," res.locals = function(obj){"," for (var key in obj) res.locals[key] = obj[key];"," return res;"," };",""," next();"," }","};"]; diff --git a/frontend/express/node_modules/express/lib-cov/request.js b/frontend/express/node_modules/express/lib-cov/request.js deleted file mode 100644 index 2fdf100b0c2..00000000000 --- a/frontend/express/node_modules/express/lib-cov/request.js +++ /dev/null @@ -1,225 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['request.js']) { - _$jscoverage['request.js'] = []; - _$jscoverage['request.js'][12] = 0; - _$jscoverage['request.js'][22] = 0; - _$jscoverage['request.js'][49] = 0; - _$jscoverage['request.js'][50] = 0; - _$jscoverage['request.js'][53] = 0; - _$jscoverage['request.js'][56] = 0; - _$jscoverage['request.js'][86] = 0; - _$jscoverage['request.js'][87] = 0; - _$jscoverage['request.js'][99] = 0; - _$jscoverage['request.js'][100] = 0; - _$jscoverage['request.js'][101] = 0; - _$jscoverage['request.js'][115] = 0; - _$jscoverage['request.js'][116] = 0; - _$jscoverage['request.js'][117] = 0; - _$jscoverage['request.js'][141] = 0; - _$jscoverage['request.js'][142] = 0; - _$jscoverage['request.js'][143] = 0; - _$jscoverage['request.js'][161] = 0; - _$jscoverage['request.js'][162] = 0; - _$jscoverage['request.js'][163] = 0; - _$jscoverage['request.js'][167] = 0; - _$jscoverage['request.js'][185] = 0; - _$jscoverage['request.js'][186] = 0; - _$jscoverage['request.js'][187] = 0; - _$jscoverage['request.js'][191] = 0; - _$jscoverage['request.js'][213] = 0; - _$jscoverage['request.js'][215] = 0; - _$jscoverage['request.js'][218] = 0; - _$jscoverage['request.js'][221] = 0; - _$jscoverage['request.js'][225] = 0; - _$jscoverage['request.js'][227] = 0; - _$jscoverage['request.js'][267] = 0; - _$jscoverage['request.js'][268] = 0; - _$jscoverage['request.js'][269] = 0; - _$jscoverage['request.js'][270] = 0; - _$jscoverage['request.js'][271] = 0; - _$jscoverage['request.js'][272] = 0; - _$jscoverage['request.js'][273] = 0; - _$jscoverage['request.js'][274] = 0; - _$jscoverage['request.js'][275] = 0; - _$jscoverage['request.js'][276] = 0; - _$jscoverage['request.js'][277] = 0; - _$jscoverage['request.js'][279] = 0; - _$jscoverage['request.js'][294] = 0; - _$jscoverage['request.js'][295] = 0; - _$jscoverage['request.js'][296] = 0; - _$jscoverage['request.js'][310] = 0; - _$jscoverage['request.js'][311] = 0; - _$jscoverage['request.js'][324] = 0; - _$jscoverage['request.js'][325] = 0; - _$jscoverage['request.js'][338] = 0; - _$jscoverage['request.js'][339] = 0; - _$jscoverage['request.js'][351] = 0; - _$jscoverage['request.js'][352] = 0; - _$jscoverage['request.js'][364] = 0; - _$jscoverage['request.js'][365] = 0; - _$jscoverage['request.js'][375] = 0; - _$jscoverage['request.js'][376] = 0; - _$jscoverage['request.js'][377] = 0; -} -_$jscoverage['request.js'][12]++; -var http = require("http"), utils = require("./utils"), connect = require("connect"), parse = require("url").parse, mime = require("mime"); -_$jscoverage['request.js'][22]++; -var req = exports = module.exports = {__proto__: http.IncomingMessage.prototype}; -_$jscoverage['request.js'][49]++; -req.get = (function (name) { - _$jscoverage['request.js'][50]++; - switch (name = name.toLowerCase()) { - case "referer": - case "referrer": - _$jscoverage['request.js'][53]++; - return this.headers.referrer || this.headers.referer; - default: - _$jscoverage['request.js'][56]++; - return this.headers[name]; - } -}); -_$jscoverage['request.js'][86]++; -req.accepts = (function (type) { - _$jscoverage['request.js'][87]++; - return utils.accepts(type, this.get("Accept")); -}); -_$jscoverage['request.js'][99]++; -req.acceptsCharset = (function (charset) { - _$jscoverage['request.js'][100]++; - var accepted = this.acceptedCharsets; - _$jscoverage['request.js'][101]++; - return accepted.length? ~ accepted.indexOf(charset): true; -}); -_$jscoverage['request.js'][115]++; -req.acceptsLanguage = (function (lang) { - _$jscoverage['request.js'][116]++; - var accepted = this.acceptedLanguages; - _$jscoverage['request.js'][117]++; - return accepted.length? ~ accepted.indexOf(lang): true; -}); -_$jscoverage['request.js'][141]++; -req.__defineGetter__("accepted", (function () { - _$jscoverage['request.js'][142]++; - var accept = this.get("Accept"); - _$jscoverage['request.js'][143]++; - return accept? utils.parseAccept(accept): []; -})); -_$jscoverage['request.js'][161]++; -req.__defineGetter__("acceptedLanguages", (function () { - _$jscoverage['request.js'][162]++; - var accept = this.get("Accept-Language"); - _$jscoverage['request.js'][163]++; - return accept? utils.parseQuality(accept).map((function (obj) { - _$jscoverage['request.js'][167]++; - return obj.value; -})): []; -})); -_$jscoverage['request.js'][185]++; -req.__defineGetter__("acceptedCharsets", (function () { - _$jscoverage['request.js'][186]++; - var accept = this.get("Accept-Charset"); - _$jscoverage['request.js'][187]++; - return accept? utils.parseQuality(accept).map((function (obj) { - _$jscoverage['request.js'][191]++; - return obj.value; -})): []; -})); -_$jscoverage['request.js'][213]++; -req.param = (function (name, defaultValue) { - _$jscoverage['request.js'][215]++; - if (this.body && undefined !== this.body[name]) { - _$jscoverage['request.js'][215]++; - return this.body[name]; - } - _$jscoverage['request.js'][218]++; - if (this.params && this.params.hasOwnProperty(name) && undefined !== this.params[name]) { - _$jscoverage['request.js'][221]++; - return this.params[name]; - } - _$jscoverage['request.js'][225]++; - if (undefined !== this.query[name]) { - _$jscoverage['request.js'][225]++; - return this.query[name]; - } - _$jscoverage['request.js'][227]++; - return defaultValue; -}); -_$jscoverage['request.js'][267]++; -req.is = (function (type) { - _$jscoverage['request.js'][268]++; - var ct = this.get("Content-Type"); - _$jscoverage['request.js'][269]++; - if (! ct) { - _$jscoverage['request.js'][269]++; - return false; - } - _$jscoverage['request.js'][270]++; - ct = ct.split(";")[0]; - _$jscoverage['request.js'][271]++; - if (! ~ type.indexOf("/")) { - _$jscoverage['request.js'][271]++; - type = mime.lookup(type); - } - _$jscoverage['request.js'][272]++; - if (~ type.indexOf("*")) { - _$jscoverage['request.js'][273]++; - type = type.split("/"); - _$jscoverage['request.js'][274]++; - ct = ct.split("/"); - _$jscoverage['request.js'][275]++; - if ("*" == type[0] && type[1] == ct[1]) { - _$jscoverage['request.js'][275]++; - return true; - } - _$jscoverage['request.js'][276]++; - if ("*" == type[1] && type[0] == ct[0]) { - _$jscoverage['request.js'][276]++; - return true; - } - _$jscoverage['request.js'][277]++; - return false; - } - _$jscoverage['request.js'][279]++; - return ! ! ~ ct.indexOf(type); -}); -_$jscoverage['request.js'][294]++; -req.__defineGetter__("protocol", (function (trustProxy) { - _$jscoverage['request.js'][295]++; - var trustProxy = this.app.settings["trust proxy"]; - _$jscoverage['request.js'][296]++; - return this.secure? "https": trustProxy? (this.get("X-Forwarded-Proto") || "http"): "http"; -})); -_$jscoverage['request.js'][310]++; -req.__defineGetter__("secure", (function () { - _$jscoverage['request.js'][311]++; - return this.connection.encrypted; -})); -_$jscoverage['request.js'][324]++; -req.__defineGetter__("subdomains", (function () { - _$jscoverage['request.js'][325]++; - return this.get("Host").split(".").slice(0, -2).reverse(); -})); -_$jscoverage['request.js'][338]++; -req.__defineGetter__("path", (function () { - _$jscoverage['request.js'][339]++; - return parse(this.url).pathname; -})); -_$jscoverage['request.js'][351]++; -req.__defineGetter__("fresh", (function () { - _$jscoverage['request.js'][352]++; - return ! this.stale; -})); -_$jscoverage['request.js'][364]++; -req.__defineGetter__("stale", (function () { - _$jscoverage['request.js'][365]++; - return connect.utils.modified(this, this.res); -})); -_$jscoverage['request.js'][375]++; -req.__defineGetter__("xhr", (function () { - _$jscoverage['request.js'][376]++; - var val = this.get("X-Requested-With") || ""; - _$jscoverage['request.js'][377]++; - return "xmlhttprequest" == val.toLowerCase(); -})); -_$jscoverage['request.js'].source = ["","/*!"," * Express - request"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var http = require('http')"," , utils = require('./utils')"," , connect = require('connect')"," , parse = require('url').parse"," , mime = require('mime');","","/**"," * Request prototype."," */","","var req = exports = module.exports = {"," __proto__: http.IncomingMessage.prototype","};","","/**"," * Return request header."," *"," * The `Referrer` header field is special-cased,"," * both `Referrer` and `Referer` will yield are"," * interchangeable."," *"," * Examples:"," *"," * req.get('Content-Type');"," * // => \"text/plain\""," * "," * req.get('content-type');"," * // => \"text/plain\""," * "," * req.get('Something');"," * // => undefined"," * "," * @param {String} name"," * @return {String} "," * @api public"," */","","req.get = function(name){"," switch (name = name.toLowerCase()) {"," case 'referer':"," case 'referrer':"," return this.headers.referrer"," || this.headers.referer;"," default:"," return this.headers[name];"," }","};","","/**"," * Check if the given `type` is acceptable,"," * otherwise you should respond with 406 \"Not Acceptable\"."," *"," * Examples:"," * "," * // Accept: text/html"," * req.accepts('html');"," * // => true"," *"," * // Accept: text/*; application/json"," * req.accepts('html');"," * req.accepts('text/html');"," * req.accepts('text/plain');"," * req.accepts('application/json');"," * // => true"," *"," * req.accepts('image/png');"," * req.accepts('png');"," * // => false"," *"," * @param {String} type"," * @return {Boolean}"," * @api public"," */","","req.accepts = function(type){"," return utils.accepts(type, this.get('Accept'));","};","","/**"," * Check if the given `charset` is acceptable,"," * otherwise you should respond with 406 \"Not Acceptable\"."," *"," * @param {String} charset"," * @return {Boolean}"," * @api public"," */","","req.acceptsCharset = function(charset){"," var accepted = this.acceptedCharsets;"," return accepted.length"," ? ~accepted.indexOf(charset)"," : true;","};","","/**"," * Check if the given `lang` is acceptable,"," * otherwise you should respond with 406 \"Not Acceptable\"."," *"," * @param {String} lang"," * @return {Boolean}"," * @api public"," */","","req.acceptsLanguage = function(lang){"," var accepted = this.acceptedLanguages;"," return accepted.length"," ? ~accepted.indexOf(lang)"," : true;","};","","/**"," * Return an array of Accepted media types"," * ordered from highest quality to lowest."," *"," * Examples:"," *"," * [ { value: 'application/json',"," * quality: 1,"," * type: 'application',"," * subtype: 'json' },"," * { value: 'text/html',"," * quality: 0.5,"," * type: 'text',"," * subtype: 'html' } ]"," *"," * @return {Array}"," * @api public"," */","","req.__defineGetter__('accepted', function(){"," var accept = this.get('Accept');"," return accept"," ? utils.parseAccept(accept)"," : [];","});","","/**"," * Return an array of Accepted languages"," * ordered from highest quality to lowest."," *"," * Examples:"," *"," * Accept-Language: en;q=.5, en-us"," * ['en-us', 'en']"," *"," * @return {Array}"," * @api public"," */","","req.__defineGetter__('acceptedLanguages', function(){"," var accept = this.get('Accept-Language');"," return accept"," ? utils"," .parseQuality(accept)"," .map(function(obj){"," return obj.value;"," })"," : [];","});","","/**"," * Return an array of Accepted charsets"," * ordered from highest quality to lowest."," *"," * Examples:"," *"," * Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8"," * ['unicode-1-1', 'iso-8859-5']"," *"," * @return {Array}"," * @api public"," */","","req.__defineGetter__('acceptedCharsets', function(){"," var accept = this.get('Accept-Charset');"," return accept"," ? utils"," .parseQuality(accept)"," .map(function(obj){"," return obj.value;"," })"," : [];","});","","/**"," * Return the value of param `name` when present or `defaultValue`."," *"," * - Checks body params, ex: id=12, {\"id\":12}"," * - Checks route placeholders, ex: _/user/:id_"," * - Checks query string params, ex: ?id=12"," *"," * To utilize request bodies, `req.body`"," * should be an object. This can be done by using"," * the `connect.bodyParser()` middleware."," *"," * @param {String} name"," * @param {Mixed} defaultValue"," * @return {String}"," * @api public"," */","","req.param = function(name, defaultValue){"," // req.body"," if (this.body && undefined !== this.body[name]) return this.body[name];",""," // route params"," if (this.params"," && this.params.hasOwnProperty(name)"," && undefined !== this.params[name]) {"," return this.params[name]; "," }",""," // query-string"," if (undefined !== this.query[name]) return this.query[name]; ",""," return defaultValue;","};","","/**"," * Check if the incoming request contains the \"Content-Type\" "," * header field, and it contains the give mime `type`."," *"," * Examples:"," *"," * // With Content-Type: text/html; charset=utf-8"," * req.is('html');"," * req.is('text/html');"," * req.is('text/*');"," * // => true"," * "," * // When Content-Type is application/json"," * req.is('json');"," * req.is('application/json');"," * req.is('application/*');"," * // => true"," * "," * req.is('html');"," * // => false"," * "," * Now within our route callbacks, we can use to to assert content types"," * such as \"image/jpeg\", \"image/png\", etc."," * "," * app.post('/image/upload', function(req, res, next){"," * if (req.is('image/*')) {"," * // do something"," * } else {"," * next();"," * }"," * });"," * "," * @param {String} type"," * @return {Boolean}"," * @api public"," */","","req.is = function(type){"," var ct = this.get('Content-Type');"," if (!ct) return false;"," ct = ct.split(';')[0];"," if (!~type.indexOf('/')) type = mime.lookup(type);"," if (~type.indexOf('*')) {"," type = type.split('/');"," ct = ct.split('/');"," if ('*' == type[0] && type[1] == ct[1]) return true;"," if ('*' == type[1] && type[0] == ct[0]) return true;"," return false;"," }"," return !! ~ct.indexOf(type);","};","","/**"," * Return the protocol string \"http\" or \"https\""," * when requested with TLS. When the \"trust proxy\" "," * setting is enabled the \"X-Forwarded-Proto\" header"," * field will be trusted. If you're running behind"," * a reverse proxy that supplies https for you this"," * may be enabled."," *"," * @return {String}"," * @api public"," */","","req.__defineGetter__('protocol', function(trustProxy){"," var trustProxy = this.app.settings['trust proxy'];"," return this.secure"," ? 'https'"," : trustProxy"," ? (this.get('X-Forwarded-Proto') || 'http')"," : 'http';","});","","/**"," * Short-hand for `req.connection.encrypted`."," *"," * @return {Boolean}"," * @api public"," */","","req.__defineGetter__('secure', function(){"," return this.connection.encrypted;","});","","/**"," * Return subdomains as an array."," *"," * For example \"tobi.ferrets.example.com\""," * would provide `[\"ferrets\", \"tobi\"]`."," *"," * @return {Array}"," * @api public"," */","","req.__defineGetter__('subdomains', function(){"," return this.get('Host')"," .split('.')"," .slice(0, -2)"," .reverse();","});","","/**"," * Short-hand for `require('url').parse(req.url).pathname`."," *"," * @return {String}"," * @api public"," */","","req.__defineGetter__('path', function(){"," return parse(this.url).pathname;","});","","/**"," * Check if the request is fresh, aka"," * Last-Modified and/or the ETag"," * still match."," *"," * @return {Boolean}"," * @api public"," */","","req.__defineGetter__('fresh', function(){"," return ! this.stale;","});","","/**"," * Check if the request is stale, aka"," * \"Last-Modified\" and / or the \"ETag\" for the"," * resource has changed."," *"," * @return {Boolean}"," * @api public"," */","","req.__defineGetter__('stale', function(){"," return connect.utils.modified(this, this.res);","});","","/**"," * Check if the request was an _XMLHttpRequest_."," *"," * @return {Boolean}"," * @api public"," */","","req.__defineGetter__('xhr', function(){"," var val = this.get('X-Requested-With') || '';"," return 'xmlhttprequest' == val.toLowerCase();","});"]; diff --git a/frontend/express/node_modules/express/lib-cov/response.js b/frontend/express/node_modules/express/lib-cov/response.js deleted file mode 100644 index a33f97e1359..00000000000 --- a/frontend/express/node_modules/express/lib-cov/response.js +++ /dev/null @@ -1,611 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['response.js']) { - _$jscoverage['response.js'] = []; - _$jscoverage['response.js'][12] = 0; - _$jscoverage['response.js'][28] = 0; - _$jscoverage['response.js'][40] = 0; - _$jscoverage['response.js'][41] = 0; - _$jscoverage['response.js'][42] = 0; - _$jscoverage['response.js'][58] = 0; - _$jscoverage['response.js'][59] = 0; - _$jscoverage['response.js'][60] = 0; - _$jscoverage['response.js'][61] = 0; - _$jscoverage['response.js'][62] = 0; - _$jscoverage['response.js'][82] = 0; - _$jscoverage['response.js'][83] = 0; - _$jscoverage['response.js'][87] = 0; - _$jscoverage['response.js'][88] = 0; - _$jscoverage['response.js'][89] = 0; - _$jscoverage['response.js'][92] = 0; - _$jscoverage['response.js'][95] = 0; - _$jscoverage['response.js'][96] = 0; - _$jscoverage['response.js'][97] = 0; - _$jscoverage['response.js'][98] = 0; - _$jscoverage['response.js'][101] = 0; - _$jscoverage['response.js'][102] = 0; - _$jscoverage['response.js'][103] = 0; - _$jscoverage['response.js'][105] = 0; - _$jscoverage['response.js'][108] = 0; - _$jscoverage['response.js'][109] = 0; - _$jscoverage['response.js'][110] = 0; - _$jscoverage['response.js'][111] = 0; - _$jscoverage['response.js'][113] = 0; - _$jscoverage['response.js'][115] = 0; - _$jscoverage['response.js'][119] = 0; - _$jscoverage['response.js'][120] = 0; - _$jscoverage['response.js'][126] = 0; - _$jscoverage['response.js'][127] = 0; - _$jscoverage['response.js'][128] = 0; - _$jscoverage['response.js'][129] = 0; - _$jscoverage['response.js'][133] = 0; - _$jscoverage['response.js'][134] = 0; - _$jscoverage['response.js'][153] = 0; - _$jscoverage['response.js'][155] = 0; - _$jscoverage['response.js'][156] = 0; - _$jscoverage['response.js'][157] = 0; - _$jscoverage['response.js'][160] = 0; - _$jscoverage['response.js'][167] = 0; - _$jscoverage['response.js'][168] = 0; - _$jscoverage['response.js'][170] = 0; - _$jscoverage['response.js'][171] = 0; - _$jscoverage['response.js'][172] = 0; - _$jscoverage['response.js'][175] = 0; - _$jscoverage['response.js'][198] = 0; - _$jscoverage['response.js'][199] = 0; - _$jscoverage['response.js'][205] = 0; - _$jscoverage['response.js'][206] = 0; - _$jscoverage['response.js'][207] = 0; - _$jscoverage['response.js'][211] = 0; - _$jscoverage['response.js'][212] = 0; - _$jscoverage['response.js'][214] = 0; - _$jscoverage['response.js'][219] = 0; - _$jscoverage['response.js'][222] = 0; - _$jscoverage['response.js'][225] = 0; - _$jscoverage['response.js'][228] = 0; - _$jscoverage['response.js'][230] = 0; - _$jscoverage['response.js'][233] = 0; - _$jscoverage['response.js'][237] = 0; - _$jscoverage['response.js'][238] = 0; - _$jscoverage['response.js'][255] = 0; - _$jscoverage['response.js'][257] = 0; - _$jscoverage['response.js'][258] = 0; - _$jscoverage['response.js'][259] = 0; - _$jscoverage['response.js'][262] = 0; - _$jscoverage['response.js'][285] = 0; - _$jscoverage['response.js'][287] = 0; - _$jscoverage['response.js'][341] = 0; - _$jscoverage['response.js'][342] = 0; - _$jscoverage['response.js'][352] = 0; - _$jscoverage['response.js'][353] = 0; - _$jscoverage['response.js'][354] = 0; - _$jscoverage['response.js'][361] = 0; - _$jscoverage['response.js'][363] = 0; - _$jscoverage['response.js'][364] = 0; - _$jscoverage['response.js'][365] = 0; - _$jscoverage['response.js'][366] = 0; - _$jscoverage['response.js'][367] = 0; - _$jscoverage['response.js'][373] = 0; - _$jscoverage['response.js'][374] = 0; - _$jscoverage['response.js'][375] = 0; - _$jscoverage['response.js'][378] = 0; - _$jscoverage['response.js'][379] = 0; - _$jscoverage['response.js'][380] = 0; - _$jscoverage['response.js'][382] = 0; - _$jscoverage['response.js'][383] = 0; - _$jscoverage['response.js'][384] = 0; - _$jscoverage['response.js'][385] = 0; - _$jscoverage['response.js'][388] = 0; - _$jscoverage['response.js'][399] = 0; - _$jscoverage['response.js'][400] = 0; - _$jscoverage['response.js'][401] = 0; - _$jscoverage['response.js'][404] = 0; - _$jscoverage['response.js'][422] = 0; - _$jscoverage['response.js'][423] = 0; - _$jscoverage['response.js'][424] = 0; - _$jscoverage['response.js'][426] = 0; - _$jscoverage['response.js'][427] = 0; - _$jscoverage['response.js'][430] = 0; - _$jscoverage['response.js'][441] = 0; - _$jscoverage['response.js'][442] = 0; - _$jscoverage['response.js'][454] = 0; - _$jscoverage['response.js'][455] = 0; - _$jscoverage['response.js'][456] = 0; - _$jscoverage['response.js'][471] = 0; - _$jscoverage['response.js'][472] = 0; - _$jscoverage['response.js'][473] = 0; - _$jscoverage['response.js'][474] = 0; - _$jscoverage['response.js'][475] = 0; - _$jscoverage['response.js'][476] = 0; - _$jscoverage['response.js'][501] = 0; - _$jscoverage['response.js'][502] = 0; - _$jscoverage['response.js'][503] = 0; - _$jscoverage['response.js'][504] = 0; - _$jscoverage['response.js'][505] = 0; - _$jscoverage['response.js'][506] = 0; - _$jscoverage['response.js'][507] = 0; - _$jscoverage['response.js'][508] = 0; - _$jscoverage['response.js'][543] = 0; - _$jscoverage['response.js'][544] = 0; - _$jscoverage['response.js'][551] = 0; - _$jscoverage['response.js'][552] = 0; - _$jscoverage['response.js'][553] = 0; - _$jscoverage['response.js'][557] = 0; - _$jscoverage['response.js'][560] = 0; - _$jscoverage['response.js'][563] = 0; - _$jscoverage['response.js'][564] = 0; - _$jscoverage['response.js'][567] = 0; - _$jscoverage['response.js'][568] = 0; - _$jscoverage['response.js'][570] = 0; - _$jscoverage['response.js'][571] = 0; - _$jscoverage['response.js'][575] = 0; - _$jscoverage['response.js'][576] = 0; - _$jscoverage['response.js'][580] = 0; - _$jscoverage['response.js'][582] = 0; - _$jscoverage['response.js'][586] = 0; - _$jscoverage['response.js'][591] = 0; - _$jscoverage['response.js'][592] = 0; - _$jscoverage['response.js'][593] = 0; - _$jscoverage['response.js'][617] = 0; - _$jscoverage['response.js'][618] = 0; - _$jscoverage['response.js'][624] = 0; - _$jscoverage['response.js'][625] = 0; - _$jscoverage['response.js'][628] = 0; - _$jscoverage['response.js'][630] = 0; - _$jscoverage['response.js'][633] = 0; - _$jscoverage['response.js'][634] = 0; - _$jscoverage['response.js'][635] = 0; - _$jscoverage['response.js'][639] = 0; - _$jscoverage['response.js'][643] = 0; - _$jscoverage['response.js'][648] = 0; - _$jscoverage['response.js'][649] = 0; - _$jscoverage['response.js'][650] = 0; - _$jscoverage['response.js'][651] = 0; - _$jscoverage['response.js'][653] = 0; - _$jscoverage['response.js'][654] = 0; - _$jscoverage['response.js'][655] = 0; - _$jscoverage['response.js'][656] = 0; - _$jscoverage['response.js'][659] = 0; - _$jscoverage['response.js'][663] = 0; -} -_$jscoverage['response.js'][12]++; -var fs = require("fs"), http = require("http"), path = require("path"), connect = require("connect"), utils = connect.utils, accept = require("./utils").accept, statusCodes = http.STATUS_CODES, send = connect["static"].send, mime = require("mime"), basename = path.basename, join = path.join; -_$jscoverage['response.js'][28]++; -var res = module.exports = {__proto__: http.ServerResponse.prototype}; -_$jscoverage['response.js'][40]++; -res.status = (function (code) { - _$jscoverage['response.js'][41]++; - this.statusCode = code; - _$jscoverage['response.js'][42]++; - return this; -}); -_$jscoverage['response.js'][58]++; -res.cache = (function (type, options) { - _$jscoverage['response.js'][59]++; - var val = type; - _$jscoverage['response.js'][60]++; - options = options || {}; - _$jscoverage['response.js'][61]++; - if (options.maxAge) { - _$jscoverage['response.js'][61]++; - val += ", max-age=" + (options.maxAge / 1000); - } - _$jscoverage['response.js'][62]++; - return this.set("Cache-Control", val); -}); -_$jscoverage['response.js'][82]++; -res.send = (function (body) { - _$jscoverage['response.js'][83]++; - var req = this.req, head = "HEAD" == req.method; - _$jscoverage['response.js'][87]++; - if (2 == arguments.length) { - _$jscoverage['response.js'][88]++; - this.statusCode = body; - _$jscoverage['response.js'][89]++; - body = arguments[1]; - } - _$jscoverage['response.js'][92]++; - switch (typeof body) { - case "number": - _$jscoverage['response.js'][95]++; - this.get("Content-Type") || this.contentType(".txt"); - _$jscoverage['response.js'][96]++; - this.statusCode = body; - _$jscoverage['response.js'][97]++; - body = http.STATUS_CODES[body]; - _$jscoverage['response.js'][98]++; - break; - case "string": - _$jscoverage['response.js'][101]++; - if (! this.get("Content-Type")) { - _$jscoverage['response.js'][102]++; - this.charset = this.charset || "utf-8"; - _$jscoverage['response.js'][103]++; - this.contentType(".html"); - } - _$jscoverage['response.js'][105]++; - break; - case "boolean": - case "object": - _$jscoverage['response.js'][108]++; - if (null == body) { - _$jscoverage['response.js'][109]++; - body = ""; - } - else { - _$jscoverage['response.js'][110]++; - if (Buffer.isBuffer(body)) { - _$jscoverage['response.js'][111]++; - this.get("Content-Type") || this.contentType(".bin"); - } - else { - _$jscoverage['response.js'][113]++; - return this.json(body); - } - } - _$jscoverage['response.js'][115]++; - break; - } - _$jscoverage['response.js'][119]++; - if (undefined !== body && ! this.get("Content-Length")) { - _$jscoverage['response.js'][120]++; - this.set("Content-Length", Buffer.isBuffer(body)? body.length: Buffer.byteLength(body)); - } - _$jscoverage['response.js'][126]++; - if (204 == this.statusCode || 304 == this.statusCode) { - _$jscoverage['response.js'][127]++; - this.removeHeader("Content-Type"); - _$jscoverage['response.js'][128]++; - this.removeHeader("Content-Length"); - _$jscoverage['response.js'][129]++; - body = ""; - } - _$jscoverage['response.js'][133]++; - this.end(head? null: body); - _$jscoverage['response.js'][134]++; - return this; -}); -_$jscoverage['response.js'][153]++; -res.json = (function (obj) { - _$jscoverage['response.js'][155]++; - if (2 == arguments.length) { - _$jscoverage['response.js'][156]++; - this.statusCode = obj; - _$jscoverage['response.js'][157]++; - obj = arguments[1]; - } - _$jscoverage['response.js'][160]++; - var settings = this.app.settings, jsonp = settings["jsonp callback"], replacer = settings["json replacer"], spaces = settings["json spaces"], body = JSON.stringify(obj, replacer, spaces), callback = this.req.query.callback; - _$jscoverage['response.js'][167]++; - this.charset = this.charset || "utf-8"; - _$jscoverage['response.js'][168]++; - this.set("Content-Type", "application/json"); - _$jscoverage['response.js'][170]++; - if (callback && jsonp) { - _$jscoverage['response.js'][171]++; - this.set("Content-Type", "text/javascript"); - _$jscoverage['response.js'][172]++; - body = callback.replace(/[^\w$.]/g, "") + "(" + body + ");"; - } - _$jscoverage['response.js'][175]++; - return this.send(body); -}); -_$jscoverage['response.js'][198]++; -res.sendfile = (function (path, options, fn) { - _$jscoverage['response.js'][199]++; - var self = this, req = self.req, next = this.req.next, options = options || {}; - _$jscoverage['response.js'][205]++; - if ("function" == typeof options) { - _$jscoverage['response.js'][206]++; - fn = options; - _$jscoverage['response.js'][207]++; - options = {}; - } - _$jscoverage['response.js'][211]++; - options.callback = (function (err) { - _$jscoverage['response.js'][212]++; - if (err) { - _$jscoverage['response.js'][214]++; - if ("ENOENT" == err.code) { - _$jscoverage['response.js'][214]++; - err = 404; - } - _$jscoverage['response.js'][219]++; - if ("number" == typeof err) { - _$jscoverage['response.js'][219]++; - err = utils.error(err); - } - _$jscoverage['response.js'][222]++; - if (! self.headerSent) { - _$jscoverage['response.js'][222]++; - self.removeHeader("Content-Disposition"); - } - _$jscoverage['response.js'][225]++; - if (fn) { - _$jscoverage['response.js'][225]++; - return fn(err); - } - _$jscoverage['response.js'][228]++; - if (self.headerSent) { - _$jscoverage['response.js'][228]++; - return; - } - _$jscoverage['response.js'][230]++; - return req.next(err); - } - _$jscoverage['response.js'][233]++; - fn && fn(); -}); - _$jscoverage['response.js'][237]++; - options.path = encodeURIComponent(path); - _$jscoverage['response.js'][238]++; - send(this.req, this, next, options); -}); -_$jscoverage['response.js'][255]++; -res.download = (function (path, filename, fn) { - _$jscoverage['response.js'][257]++; - if ("function" == typeof filename) { - _$jscoverage['response.js'][258]++; - fn = filename; - _$jscoverage['response.js'][259]++; - filename = null; - } - _$jscoverage['response.js'][262]++; - return this.attachment(filename || path).sendfile(path, fn); -}); -_$jscoverage['response.js'][285]++; -res.contentType = res.type = (function (type) { - _$jscoverage['response.js'][287]++; - return this.set("Content-Type", mime.lookup(type)); -}); -_$jscoverage['response.js'][341]++; -res.format = (function (obj) { - _$jscoverage['response.js'][342]++; - var keys = Object.keys(obj), types = [], req = this.req, next = req.next, accepted = req.accepted, acceptedlen = accepted.length, type, key; - _$jscoverage['response.js'][352]++; - if (acceptedlen) { - _$jscoverage['response.js'][353]++; - for (var i = 0; i < keys.length; ++i) { - _$jscoverage['response.js'][354]++; - types.push(~ keys[i].indexOf("/")? keys[i]: mime.lookup(keys[i])); -} - } - _$jscoverage['response.js'][361]++; -out: - for (var i = 0; i < acceptedlen; ++i) { - _$jscoverage['response.js'][363]++; - for (var j = 0, jlen = types.length; j < jlen; ++j) { - _$jscoverage['response.js'][364]++; - if (accept(types[j].split("/"), accepted[i])) { - _$jscoverage['response.js'][365]++; - key = keys[j]; - _$jscoverage['response.js'][366]++; - type = types[j]; - _$jscoverage['response.js'][367]++; - break out; - } -} -} - _$jscoverage['response.js'][373]++; - if (! acceptedlen) { - _$jscoverage['response.js'][374]++; - key = keys[0]; - _$jscoverage['response.js'][375]++; - type = types[0]; - } - _$jscoverage['response.js'][378]++; - if (key) { - _$jscoverage['response.js'][379]++; - this.set("Content-Type", type); - _$jscoverage['response.js'][380]++; - obj[key](req, this, next); - } - else { - _$jscoverage['response.js'][382]++; - var err = new Error("Not Acceptable"); - _$jscoverage['response.js'][383]++; - err.status = 406; - _$jscoverage['response.js'][384]++; - err.types = types; - _$jscoverage['response.js'][385]++; - next(err); - } - _$jscoverage['response.js'][388]++; - return this; -}); -_$jscoverage['response.js'][399]++; -res.attachment = (function (filename) { - _$jscoverage['response.js'][400]++; - if (filename) { - _$jscoverage['response.js'][400]++; - this.type(filename); - } - _$jscoverage['response.js'][401]++; - this.set("Content-Disposition", filename? "attachment; filename=\"" + basename(filename) + "\"": "attachment"); - _$jscoverage['response.js'][404]++; - return this; -}); -_$jscoverage['response.js'][422]++; -res.set = (function (field, val) { - _$jscoverage['response.js'][423]++; - if (2 == arguments.length) { - _$jscoverage['response.js'][424]++; - this.setHeader(field, val); - } - else { - _$jscoverage['response.js'][426]++; - for (var key in field) { - _$jscoverage['response.js'][427]++; - this.setHeader(key, field[key]); -} - } - _$jscoverage['response.js'][430]++; - return this; -}); -_$jscoverage['response.js'][441]++; -res.get = (function (field) { - _$jscoverage['response.js'][442]++; - return this.getHeader(field); -}); -_$jscoverage['response.js'][454]++; -res.clearCookie = (function (name, options) { - _$jscoverage['response.js'][455]++; - var opts = {expires: new Date(1), path: "/"}; - _$jscoverage['response.js'][456]++; - return this.cookie(name, "", options? utils.merge(opts, options): opts); -}); -_$jscoverage['response.js'][471]++; -res.signedCookie = (function (name, val, options) { - _$jscoverage['response.js'][472]++; - var secret = this.req.secret; - _$jscoverage['response.js'][473]++; - if (! secret) { - _$jscoverage['response.js'][473]++; - throw new Error("connect.cookieParser(\"secret\") required for signed cookies"); - } - _$jscoverage['response.js'][474]++; - if ("object" == typeof val) { - _$jscoverage['response.js'][474]++; - val = "j:" + JSON.stringify(val); - } - _$jscoverage['response.js'][475]++; - val = utils.sign(val, secret); - _$jscoverage['response.js'][476]++; - return this.cookie(name, val, options); -}); -_$jscoverage['response.js'][501]++; -res.cookie = (function (name, val, options) { - _$jscoverage['response.js'][502]++; - options = options || {}; - _$jscoverage['response.js'][503]++; - if ("object" == typeof val) { - _$jscoverage['response.js'][503]++; - val = "j:" + JSON.stringify(val); - } - _$jscoverage['response.js'][504]++; - if ("maxAge" in options) { - _$jscoverage['response.js'][504]++; - options.expires = new Date(Date.now() + options.maxAge); - } - _$jscoverage['response.js'][505]++; - if (null == options.path) { - _$jscoverage['response.js'][505]++; - options.path = "/"; - } - _$jscoverage['response.js'][506]++; - var cookie = utils.serializeCookie(name, val, options); - _$jscoverage['response.js'][507]++; - this.set("Set-Cookie", cookie); - _$jscoverage['response.js'][508]++; - return this; -}); -_$jscoverage['response.js'][543]++; -res.redirect = (function (url) { - _$jscoverage['response.js'][544]++; - var app = this.app, req = this.req, head = "HEAD" == req.method, status = 302, body; - _$jscoverage['response.js'][551]++; - if (2 == arguments.length) { - _$jscoverage['response.js'][552]++; - status = url; - _$jscoverage['response.js'][553]++; - url = arguments[1]; - } - _$jscoverage['response.js'][557]++; - var map = {back: req.get("Referrer") || "/"}; - _$jscoverage['response.js'][560]++; - url = map[url] || url; - _$jscoverage['response.js'][563]++; - if (! ~ url.indexOf("://")) { - _$jscoverage['response.js'][564]++; - var path = app.path(); - _$jscoverage['response.js'][567]++; - if (0 == url.indexOf("./") || 0 == url.indexOf("..")) { - _$jscoverage['response.js'][568]++; - url = req.path + "/" + url; - } - else { - _$jscoverage['response.js'][570]++; - if ("/" != url[0]) { - _$jscoverage['response.js'][571]++; - url = path + "/" + url; - } - } - _$jscoverage['response.js'][575]++; - var host = req.get("Host"); - _$jscoverage['response.js'][576]++; - url = req.protocol + "://" + host + url; - } - _$jscoverage['response.js'][580]++; - this.format({"text/plain": (function () { - _$jscoverage['response.js'][582]++; - body = statusCodes[status] + ". Redirecting to " + url; -}), "text/html": (function () { - _$jscoverage['response.js'][586]++; - body = "

    " + statusCodes[status] + ". Redirecting to " + url + "

    "; -})}); - _$jscoverage['response.js'][591]++; - this.statusCode = status; - _$jscoverage['response.js'][592]++; - this.set("Location", url); - _$jscoverage['response.js'][593]++; - this.end(head? null: body); -}); -_$jscoverage['response.js'][617]++; -res.render = (function (view, options, fn) { - _$jscoverage['response.js'][618]++; - var self = this, options = options || {}, req = this.req, app = req.app; - _$jscoverage['response.js'][624]++; - if ("function" == typeof options) { - _$jscoverage['response.js'][625]++; - fn = options, options = {}; - } - _$jscoverage['response.js'][628]++; - function render() { - _$jscoverage['response.js'][630]++; - options.locals = self.locals; - _$jscoverage['response.js'][633]++; - fn = fn || (function (err, str) { - _$jscoverage['response.js'][634]++; - if (err) { - _$jscoverage['response.js'][634]++; - return req.next(err); - } - _$jscoverage['response.js'][635]++; - self.send(str); -}); - _$jscoverage['response.js'][639]++; - app.render(view, options, fn); -} - _$jscoverage['response.js'][643]++; - var callbacks = app.viewCallbacks, pending = callbacks.length, len = pending, done; - _$jscoverage['response.js'][648]++; - if (len) { - _$jscoverage['response.js'][649]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['response.js'][650]++; - callbacks[i](req, self, (function (err) { - _$jscoverage['response.js'][651]++; - if (done) { - _$jscoverage['response.js'][651]++; - return; - } - _$jscoverage['response.js'][653]++; - if (err) { - _$jscoverage['response.js'][654]++; - req.next(err); - _$jscoverage['response.js'][655]++; - done = true; - _$jscoverage['response.js'][656]++; - return; - } - _$jscoverage['response.js'][659]++; - --pending || render(); -})); -} - } - else { - _$jscoverage['response.js'][663]++; - render(); - } -}); -_$jscoverage['response.js'].source = ["","/*!"," * Express - response"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var fs = require('fs')"," , http = require('http')"," , path = require('path')"," , connect = require('connect')"," , utils = connect.utils"," , accept = require('./utils').accept"," , statusCodes = http.STATUS_CODES"," , send = connect.static.send"," , mime = require('mime')"," , basename = path.basename"," , join = path.join;","","/**"," * Response prototype."," */","","var res = module.exports = {"," __proto__: http.ServerResponse.prototype","};","","/**"," * Set status `code`."," *"," * @param {Number} code"," * @return {ServerResponse}"," * @api public"," */","","res.status = function(code){"," this.statusCode = code;"," return this;","};","","/**"," * Set Cache-Control to the given `type` and `options`."," *"," * Options:"," *"," * - `maxAge` in milliseconds"," *"," * @param {String} type"," * @param {Object} options"," * @return {ServerResponse}"," * @api public"," */","","res.cache = function(type, options){"," var val = type;"," options = options || {};"," if (options.maxAge) val += ', max-age=' + (options.maxAge / 1000); "," return this.set('Cache-Control', val);","};","","/**"," * Send a response."," *"," * Examples:"," *"," * res.send(new Buffer('wahoo'));"," * res.send({ some: 'json' });"," * res.send('<p>some html</p>');"," * res.send(404, 'Sorry, cant find that');"," * res.send(404);"," *"," * @param {Mixed} body or status"," * @param {Mixed} body"," * @return {ServerResponse}"," * @api public"," */","","res.send = function(body){"," var req = this.req"," , head = 'HEAD' == req.method;",""," // allow status / body"," if (2 == arguments.length) {"," this.statusCode = body;"," body = arguments[1];"," }",""," switch (typeof body) {"," // response status"," case 'number':"," this.get('Content-Type') || this.contentType('.txt');"," this.statusCode = body;"," body = http.STATUS_CODES[body];"," break;"," // string defaulting to html"," case 'string':"," if (!this.get('Content-Type')) {"," this.charset = this.charset || 'utf-8';"," this.contentType('.html');"," }"," break;"," case 'boolean':"," case 'object':"," if (null == body) {"," body = '';"," } else if (Buffer.isBuffer(body)) {"," this.get('Content-Type') || this.contentType('.bin');"," } else {"," return this.json(body);"," }"," break;"," }",""," // populate Content-Length"," if (undefined !== body && !this.get('Content-Length')) {"," this.set('Content-Length', Buffer.isBuffer(body)"," ? body.length"," : Buffer.byteLength(body));"," }",""," // strip irrelevant headers"," if (204 == this.statusCode || 304 == this.statusCode) {"," this.removeHeader('Content-Type');"," this.removeHeader('Content-Length');"," body = '';"," }",""," // respond"," this.end(head ? null : body);"," return this;","};","","/**"," * Send JSON response."," *"," * Examples:"," *"," * res.json(null);"," * res.json({ user: 'tj' });"," * res.json(500, 'oh noes!');"," * res.json(404, 'I dont have that');"," *"," * @param {Mixed} obj or status"," * @param {Mixed} obj"," * @return {ServerResponse}"," * @api public"," */","","res.json = function(obj){"," // allow status / body"," if (2 == arguments.length) {"," this.statusCode = obj;"," obj = arguments[1];"," }",""," var settings = this.app.settings"," , jsonp = settings['jsonp callback']"," , replacer = settings['json replacer']"," , spaces = settings['json spaces']"," , body = JSON.stringify(obj, replacer, spaces)"," , callback = this.req.query.callback;",""," this.charset = this.charset || 'utf-8';"," this.set('Content-Type', 'application/json');",""," if (callback && jsonp) {"," this.set('Content-Type', 'text/javascript');"," body = callback.replace(/[^\\w$.]/g, '') + '(' + body + ');';"," }",""," return this.send(body);","};","","/**"," * Transfer the file at the given `path`."," * "," * Automatically sets the _Content-Type_ response header field."," * The callback `fn(err)` is invoked when the transfer is complete"," * or when an error occurs. Be sure to check `res.sentHeader`"," * if you wish to attempt responding, as the header and some data"," * may have already been transferred."," *"," * Options:"," *"," * - `maxAge` defaulting to 0"," * - `root` root directory for relative filenames"," *"," * @param {String} path"," * @param {Object|Function} options or fn"," * @param {Function} fn"," * @api public"," */","","res.sendfile = function(path, options, fn){"," var self = this"," , req = self.req"," , next = this.req.next"," , options = options || {};",""," // support function as second arg"," if ('function' == typeof options) {"," fn = options;"," options = {};"," }",""," // callback"," options.callback = function(err){"," if (err) {"," // cast ENOENT"," if ('ENOENT' == err.code) err = 404;",""," // coerce numeric error to an Error"," // TODO: remove"," // TODO: remove docs for headerSent?"," if ('number' == typeof err) err = utils.error(err);",""," // ditch content-disposition to prevent funky responses"," if (!self.headerSent) self.removeHeader('Content-Disposition');",""," // woot! callback available"," if (fn) return fn(err);",""," // lost in limbo if there's no callback"," if (self.headerSent) return;",""," return req.next(err);"," }",""," fn && fn();"," };",""," // transfer"," options.path = encodeURIComponent(path);"," send(this.req, this, next, options);","};","","/**"," * Transfer the file at the given `path` as an attachment."," *"," * Optionally providing an alternate attachment `filename`,"," * and optional callback `fn(err)`. The callback is invoked"," * when the data transfer is complete, or when an error has"," * ocurred. Be sure to check `res.headerSent` if you plan to respond."," *"," * @param {String} path"," * @param {String|Function} filename or fn"," * @param {Function} fn"," * @api public"," */","","res.download = function(path, filename, fn){"," // support function as second arg"," if ('function' == typeof filename) {"," fn = filename;"," filename = null;"," }",""," return this.attachment(filename || path).sendfile(path, fn);","};","","/**"," * Set _Content-Type_ response header passed through `mime.lookup()`."," *"," * Examples:"," *"," * var filename = 'path/to/image.png';"," * res.contentType(filename);"," * // res.headers['Content-Type'] is now \"image/png\""," *"," * res.contentType('.html');"," * res.contentType('html');"," * res.contentType('json');"," * res.contentType('png');"," * res.type('png');"," *"," * @param {String} type"," * @return {ServerResponse} for chaining"," * @api public"," */","","res.contentType =","res.type = function(type){"," return this.set('Content-Type', mime.lookup(type));","};","","/**"," * Respond to the Acceptable formats using an `obj`"," * of mime-type callbacks."," *"," * This method uses `req.accepted`, an array of"," * acceptable types ordered by their quality values."," * When \"Accept\" is not present the _first_ callback"," * is invoked, otherwise the first match is used. When"," * no match is performed the server responds with"," * 406 \"Not Acceptable\"."," *"," * Content-Type is set for you, however if you choose"," * you may alter this within the callback using `res.type()`"," * or `res.set('Content-Type', ...)`."," *"," * res.format({"," * 'text/plain': function(){"," * res.send('hey');"," * },"," * "," * 'text/html': function(){"," * res.send('<p>hey</p>');"," * },"," * "," * 'appliation/json': function(){"," * res.send({ message: 'hey' });"," * }"," * });"," *"," * In addition to canonicalized MIME types you may"," * also use extnames mapped to these types:"," *"," * res.format({"," * text: function(){"," * res.send('hey');"," * },"," * "," * html: function(){"," * res.send('<p>hey</p>');"," * },"," * "," * json: function(){"," * res.send({ message: 'hey' });"," * }"," * });"," *"," * @param {Object} obj"," * @return {ServerResponse} for chaining"," * @api public"," */","","res.format = function(obj){"," var keys = Object.keys(obj)"," , types = []"," , req = this.req"," , next = req.next"," , accepted = req.accepted"," , acceptedlen = accepted.length"," , type"," , key;",""," // normalize extnames -> mime"," if (acceptedlen) {"," for (var i = 0; i < keys.length; ++i) {"," types.push(~keys[i].indexOf('/')"," ? keys[i]"," : mime.lookup(keys[i]));"," }"," }",""," // determine most acceptable format"," out:"," for (var i = 0; i < acceptedlen; ++i) {"," for (var j = 0, jlen = types.length; j < jlen; ++j) {"," if (accept(types[j].split('/'), accepted[i])) {"," key = keys[j];"," type = types[j];"," break out;"," }"," }"," }",""," // default to the first"," if (!acceptedlen) {"," key = keys[0];"," type = types[0];"," }",""," if (key) {"," this.set('Content-Type', type);"," obj[key](req, this, next);"," } else {"," var err = new Error('Not Acceptable');"," err.status = 406;"," err.types = types;"," next(err);"," }",""," return this;","};","","/**"," * Set _Content-Disposition_ header to _attachment_ with optional `filename`."," *"," * @param {String} filename"," * @return {ServerResponse}"," * @api public"," */","","res.attachment = function(filename){"," if (filename) this.type(filename);"," this.set('Content-Disposition', filename"," ? 'attachment; filename=\"' + basename(filename) + '\"'"," : 'attachment');"," return this;","};","","/**"," * Set header `field` to `val`, or pass"," * an object of of header fields."," *"," * Examples:"," *"," * res.set('Accept', 'application/json');"," * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });"," *"," * @param {String|Object} field"," * @param {String} val"," * @return {ServerResponse} for chaining"," * @api public"," */","","res.set = function(field, val){"," if (2 == arguments.length) {"," this.setHeader(field, val);"," } else {"," for (var key in field) {"," this.setHeader(key, field[key]);"," }"," }"," return this;","};","","/**"," * Get value for header `field`."," *"," * @param {String} field"," * @return {String}"," * @api public"," */","","res.get = function(field){"," return this.getHeader(field);","};","","/**"," * Clear cookie `name`."," *"," * @param {String} name"," * @param {Object} options"," * @param {ServerResponse} for chaining"," * @api public"," */","","res.clearCookie = function(name, options){"," var opts = { expires: new Date(1), path: '/' };"," return this.cookie(name, '', options"," ? utils.merge(opts, options)"," : opts);","};","","/**"," * Set a signed cookie with the given `name` and `val`."," * See `res.cookie()` for details."," *"," * @param {String} name"," * @param {String|Object} val"," * @param {Object} options"," * @api public"," */","","res.signedCookie = function(name, val, options){"," var secret = this.req.secret;"," if (!secret) throw new Error('connect.cookieParser(\"secret\") required for signed cookies');"," if ('object' == typeof val) val = 'j:' + JSON.stringify(val);"," val = utils.sign(val, secret);"," return this.cookie(name, val, options);","};","","/**"," * Set cookie `name` to `val`, with the given `options`."," *"," * Options:"," *"," * - `maxAge` max-age in milliseconds, converted to `expires`"," * - `path` defaults to \"/\""," *"," * Examples:"," *"," * // \"Remember Me\" for 15 minutes"," * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });"," *"," * // save as above"," * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })"," *"," * @param {String} name"," * @param {String|Object} val"," * @param {Options} options"," * @api public"," */","","res.cookie = function(name, val, options){"," options = options || {};"," if ('object' == typeof val) val = 'j:' + JSON.stringify(val);"," if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);"," if (null == options.path) options.path = '/';"," var cookie = utils.serializeCookie(name, val, options);"," this.set('Set-Cookie', cookie);"," return this;","};","","/**"," * Redirect to the given `url` with optional response `status`"," * defaulting to 302."," *"," * The given `url` can also be the name of a mapped url, for"," * example by default express supports \"back\" which redirects"," * to the _Referrer_ or _Referer_ headers or \"/\"."," *"," * Examples:"," *"," * res.redirect('/foo/bar');"," * res.redirect('http://example.com');"," * res.redirect(301, 'http://example.com');"," *"," * Mounting:"," *"," * When an application is mounted, and `res.redirect()`"," * is given a path that does _not_ lead with \"/\". For "," * example suppose a \"blog\" app is mounted at \"/blog\","," * the following redirect would result in \"/blog/login\":"," *"," * res.redirect('login');"," *"," * While the leading slash would result in a redirect to \"/login\":"," *"," * res.redirect('/login');"," *"," * @param {String} url"," * @param {Number} code"," * @api public"," */","","res.redirect = function(url){"," var app = this.app"," , req = this.req"," , head = 'HEAD' == req.method"," , status = 302"," , body;",""," // allow status / url"," if (2 == arguments.length) {"," status = url;"," url = arguments[1];"," }",""," // setup redirect map"," var map = { back: req.get('Referrer') || '/' };",""," // perform redirect"," url = map[url] || url;",""," // relative"," if (!~url.indexOf('://')) {"," var path = app.path();",""," // relative to path"," if (0 == url.indexOf('./') || 0 == url.indexOf('..')) {"," url = req.path + '/' + url;"," // relative to mount-point"," } else if ('/' != url[0]) {"," url = path + '/' + url;"," }",""," // Absolute"," var host = req.get('Host');"," url = req.protocol + '://' + host + url;"," }",""," // Support text/{plain,html} by default"," this.format({"," 'text/plain': function(){"," body = statusCodes[status] + '. Redirecting to ' + url;"," },",""," 'text/html': function(){"," body = '<p>' + statusCodes[status] + '. Redirecting to <a href=\"' + url + '\">' + url + '</a></p>';"," }"," })",""," // Respond"," this.statusCode = status;"," this.set('Location', url);"," this.end(head ? null : body);","};","","/**"," * Render `view` with the given `options` and optional callback `fn`."," * When a callback function is given a response will _not_ be made"," * automatically, otherwise a response of _200_ and _text/html_ is given."," *"," * Options:"," * "," * - `status` Response status code (`res.statusCode`)"," * - `charset` Set the charset (`res.charset`)"," *"," * Reserved locals:"," *"," * - `cache` boolean hinting to the engine it should cache"," * - `filename` filename of the view being rendered"," *"," * @param {String} view"," * @param {Object|Function} options or callback function"," * @param {Function} fn"," * @api public"," */","","res.render = function(view, options, fn){"," var self = this"," , options = options || {}"," , req = this.req"," , app = req.app;",""," // support callback function as second arg"," if ('function' == typeof options) {"," fn = options, options = {};"," }",""," function render() {"," // merge res.locals"," options.locals = self.locals;",""," // default callback to respond"," fn = fn || function(err, str){"," if (err) return req.next(err);"," self.send(str);"," };",""," // render"," app.render(view, options, fn);"," }",""," // invoke view callbacks"," var callbacks = app.viewCallbacks"," , pending = callbacks.length"," , len = pending"," , done;",""," if (len) {"," for (var i = 0; i < len; ++i) {"," callbacks[i](req, self, function(err){"," if (done) return;",""," if (err) {"," req.next(err);"," done = true;"," return;"," }",""," --pending || render();"," });"," }"," } else {"," render();"," }","};"]; diff --git a/frontend/express/node_modules/express/lib-cov/router/collection.js b/frontend/express/node_modules/express/lib-cov/router/collection.js deleted file mode 100644 index 33808a96087..00000000000 --- a/frontend/express/node_modules/express/lib-cov/router/collection.js +++ /dev/null @@ -1,40 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['router/collection.js']) { - _$jscoverage['router/collection.js'] = []; - _$jscoverage['router/collection.js'][12] = 0; - _$jscoverage['router/collection.js'][22] = 0; - _$jscoverage['router/collection.js'][23] = 0; - _$jscoverage['router/collection.js'][30] = 0; - _$jscoverage['router/collection.js'][39] = 0; - _$jscoverage['router/collection.js'][40] = 0; - _$jscoverage['router/collection.js'][44] = 0; - _$jscoverage['router/collection.js'][45] = 0; - _$jscoverage['router/collection.js'][46] = 0; - _$jscoverage['router/collection.js'][50] = 0; -} -_$jscoverage['router/collection.js'][12]++; -module.exports = Collection; -_$jscoverage['router/collection.js'][22]++; -function Collection(router) { - _$jscoverage['router/collection.js'][23]++; - Object.defineProperty(this, "router", {value: router}); -} -_$jscoverage['router/collection.js'][30]++; -Collection.prototype.__proto__ = Array.prototype; -_$jscoverage['router/collection.js'][39]++; -Collection.prototype.remove = (function () { - _$jscoverage['router/collection.js'][40]++; - var router = this.router, len = this.length, ret = new Collection(this.router); - _$jscoverage['router/collection.js'][44]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['router/collection.js'][45]++; - if (router.remove(this[i])) { - _$jscoverage['router/collection.js'][46]++; - ret.push(this[i]); - } -} - _$jscoverage['router/collection.js'][50]++; - return ret; -}); -_$jscoverage['router/collection.js'].source = ["","/*!"," * Express - router - Collection"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Expose `Collection`."," */","","module.exports = Collection;","","/**"," * Initialize a new route `Collection`"," * with the given `router`."," * "," * @param {Router} router"," * @api private"," */","","function Collection(router) {"," Object.defineProperty(this, 'router', { value: router });","}","","/**"," * Inherit from `Array.prototype`."," */","","Collection.prototype.__proto__ = Array.prototype;","","/**"," * Remove the routes in this collection."," *"," * @return {Collection} of routes removed"," * @api public"," */","","Collection.prototype.remove = function(){"," var router = this.router"," , len = this.length"," , ret = new Collection(this.router);",""," for (var i = 0; i < len; ++i) {"," if (router.remove(this[i])) {"," ret.push(this[i]);"," }"," }",""," return ret;","};",""]; diff --git a/frontend/express/node_modules/express/lib-cov/router/index.js b/frontend/express/node_modules/express/lib-cov/router/index.js deleted file mode 100644 index abc2c84f313..00000000000 --- a/frontend/express/node_modules/express/lib-cov/router/index.js +++ /dev/null @@ -1,515 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['router/index.js']) { - _$jscoverage['router/index.js'] = []; - _$jscoverage['router/index.js'][11] = 0; - _$jscoverage['router/index.js'][21] = 0; - _$jscoverage['router/index.js'][27] = 0; - _$jscoverage['router/index.js'][36] = 0; - _$jscoverage['router/index.js'][37] = 0; - _$jscoverage['router/index.js'][38] = 0; - _$jscoverage['router/index.js'][39] = 0; - _$jscoverage['router/index.js'][40] = 0; - _$jscoverage['router/index.js'][41] = 0; - _$jscoverage['router/index.js'][42] = 0; - _$jscoverage['router/index.js'][43] = 0; - _$jscoverage['router/index.js'][44] = 0; - _$jscoverage['router/index.js'][46] = 0; - _$jscoverage['router/index.js'][47] = 0; - _$jscoverage['router/index.js'][60] = 0; - _$jscoverage['router/index.js'][62] = 0; - _$jscoverage['router/index.js'][63] = 0; - _$jscoverage['router/index.js'][64] = 0; - _$jscoverage['router/index.js'][68] = 0; - _$jscoverage['router/index.js'][72] = 0; - _$jscoverage['router/index.js'][73] = 0; - _$jscoverage['router/index.js'][74] = 0; - _$jscoverage['router/index.js'][80] = 0; - _$jscoverage['router/index.js'][81] = 0; - _$jscoverage['router/index.js'][84] = 0; - _$jscoverage['router/index.js'][85] = 0; - _$jscoverage['router/index.js'][95] = 0; - _$jscoverage['router/index.js'][96] = 0; - _$jscoverage['router/index.js'][97] = 0; - _$jscoverage['router/index.js'][111] = 0; - _$jscoverage['router/index.js'][112] = 0; - _$jscoverage['router/index.js'][116] = 0; - _$jscoverage['router/index.js'][117] = 0; - _$jscoverage['router/index.js'][120] = 0; - _$jscoverage['router/index.js'][121] = 0; - _$jscoverage['router/index.js'][122] = 0; - _$jscoverage['router/index.js'][123] = 0; - _$jscoverage['router/index.js'][137] = 0; - _$jscoverage['router/index.js'][138] = 0; - _$jscoverage['router/index.js'][139] = 0; - _$jscoverage['router/index.js'][171] = 0; - _$jscoverage['router/index.js'][172] = 0; - _$jscoverage['router/index.js'][178] = 0; - _$jscoverage['router/index.js'][179] = 0; - _$jscoverage['router/index.js'][180] = 0; - _$jscoverage['router/index.js'][181] = 0; - _$jscoverage['router/index.js'][182] = 0; - _$jscoverage['router/index.js'][183] = 0; - _$jscoverage['router/index.js'][184] = 0; - _$jscoverage['router/index.js'][188] = 0; - _$jscoverage['router/index.js'][200] = 0; - _$jscoverage['router/index.js'][201] = 0; - _$jscoverage['router/index.js'][204] = 0; - _$jscoverage['router/index.js'][207] = 0; - _$jscoverage['router/index.js'][208] = 0; - _$jscoverage['router/index.js'][217] = 0; - _$jscoverage['router/index.js'][218] = 0; - _$jscoverage['router/index.js'][222] = 0; - _$jscoverage['router/index.js'][225] = 0; - _$jscoverage['router/index.js'][228] = 0; - _$jscoverage['router/index.js'][229] = 0; - _$jscoverage['router/index.js'][233] = 0; - _$jscoverage['router/index.js'][234] = 0; - _$jscoverage['router/index.js'][235] = 0; - _$jscoverage['router/index.js'][238] = 0; - _$jscoverage['router/index.js'][239] = 0; - _$jscoverage['router/index.js'][240] = 0; - _$jscoverage['router/index.js'][241] = 0; - _$jscoverage['router/index.js'][242] = 0; - _$jscoverage['router/index.js'][244] = 0; - _$jscoverage['router/index.js'][245] = 0; - _$jscoverage['router/index.js'][246] = 0; - _$jscoverage['router/index.js'][247] = 0; - _$jscoverage['router/index.js'][248] = 0; - _$jscoverage['router/index.js'][249] = 0; - _$jscoverage['router/index.js'][250] = 0; - _$jscoverage['router/index.js'][251] = 0; - _$jscoverage['router/index.js'][252] = 0; - _$jscoverage['router/index.js'][253] = 0; - _$jscoverage['router/index.js'][255] = 0; - _$jscoverage['router/index.js'][256] = 0; - _$jscoverage['router/index.js'][259] = 0; - _$jscoverage['router/index.js'][261] = 0; - _$jscoverage['router/index.js'][263] = 0; - _$jscoverage['router/index.js'][266] = 0; - _$jscoverage['router/index.js'][267] = 0; - _$jscoverage['router/index.js'][268] = 0; - _$jscoverage['router/index.js'][269] = 0; - _$jscoverage['router/index.js'][273] = 0; - _$jscoverage['router/index.js'][274] = 0; - _$jscoverage['router/index.js'][275] = 0; - _$jscoverage['router/index.js'][276] = 0; - _$jscoverage['router/index.js'][277] = 0; - _$jscoverage['router/index.js'][278] = 0; - _$jscoverage['router/index.js'][279] = 0; - _$jscoverage['router/index.js'][280] = 0; - _$jscoverage['router/index.js'][281] = 0; - _$jscoverage['router/index.js'][282] = 0; - _$jscoverage['router/index.js'][284] = 0; - _$jscoverage['router/index.js'][287] = 0; - _$jscoverage['router/index.js'][301] = 0; - _$jscoverage['router/index.js'][302] = 0; - _$jscoverage['router/index.js'][304] = 0; - _$jscoverage['router/index.js'][315] = 0; - _$jscoverage['router/index.js'][316] = 0; - _$jscoverage['router/index.js'][317] = 0; - _$jscoverage['router/index.js'][318] = 0; - _$jscoverage['router/index.js'][319] = 0; - _$jscoverage['router/index.js'][320] = 0; - _$jscoverage['router/index.js'][321] = 0; - _$jscoverage['router/index.js'][324] = 0; - _$jscoverage['router/index.js'][339] = 0; - _$jscoverage['router/index.js'][340] = 0; - _$jscoverage['router/index.js'][351] = 0; - _$jscoverage['router/index.js'][353] = 0; - _$jscoverage['router/index.js'][354] = 0; - _$jscoverage['router/index.js'][358] = 0; - _$jscoverage['router/index.js'][362] = 0; - _$jscoverage['router/index.js'][365] = 0; - _$jscoverage['router/index.js'][366] = 0; - _$jscoverage['router/index.js'][367] = 0; - _$jscoverage['router/index.js'][368] = 0; - _$jscoverage['router/index.js'][369] = 0; - _$jscoverage['router/index.js'][372] = 0; - _$jscoverage['router/index.js'][373] = 0; - _$jscoverage['router/index.js'][377] = 0; - _$jscoverage['router/index.js'][378] = 0; - _$jscoverage['router/index.js'][380] = 0; - _$jscoverage['router/index.js'][385] = 0; - _$jscoverage['router/index.js'][386] = 0; - _$jscoverage['router/index.js'][402] = 0; - _$jscoverage['router/index.js'][403] = 0; - _$jscoverage['router/index.js'][408] = 0; - _$jscoverage['router/index.js'][411] = 0; - _$jscoverage['router/index.js'][412] = 0; - _$jscoverage['router/index.js'][418] = 0; - _$jscoverage['router/index.js'][419] = 0; - _$jscoverage['router/index.js'][420] = 0; -} -_$jscoverage['router/index.js'][11]++; -var Route = require("./route"), Collection = require("./collection"), utils = require("../utils"), debug = require("debug")("express:router"), parse = require("url").parse; -_$jscoverage['router/index.js'][21]++; -exports = module.exports = Router; -_$jscoverage['router/index.js'][27]++; -var methods = exports.methods = require("./methods"); -_$jscoverage['router/index.js'][36]++; -function Router(options) { - _$jscoverage['router/index.js'][37]++; - options = options || {}; - _$jscoverage['router/index.js'][38]++; - var self = this; - _$jscoverage['router/index.js'][39]++; - this.routes = new Collection(); - _$jscoverage['router/index.js'][40]++; - this.map = {}; - _$jscoverage['router/index.js'][41]++; - this.params = {}; - _$jscoverage['router/index.js'][42]++; - this._params = []; - _$jscoverage['router/index.js'][43]++; - this.caseSensitive = options.caseSensitive; - _$jscoverage['router/index.js'][44]++; - this.strict = options.strict; - _$jscoverage['router/index.js'][46]++; - this.middleware = (function router(req, res, next) { - _$jscoverage['router/index.js'][47]++; - self._dispatch(req, res, next); -}); -} -_$jscoverage['router/index.js'][60]++; -Router.prototype.param = (function (name, fn) { - _$jscoverage['router/index.js'][62]++; - if ("function" == typeof name) { - _$jscoverage['router/index.js'][63]++; - this._params.push(name); - _$jscoverage['router/index.js'][64]++; - return; - } - _$jscoverage['router/index.js'][68]++; - var params = this._params, len = params.length, ret; - _$jscoverage['router/index.js'][72]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['router/index.js'][73]++; - if (ret = params[i](name, fn)) { - _$jscoverage['router/index.js'][74]++; - fn = ret; - } -} - _$jscoverage['router/index.js'][80]++; - if ("function" != typeof fn) { - _$jscoverage['router/index.js'][81]++; - throw new Error("invalid param() call for " + name + ", got " + fn); - } - _$jscoverage['router/index.js'][84]++; - (this.params[name] = this.params[name] || []).push(fn); - _$jscoverage['router/index.js'][85]++; - return this; -}); -_$jscoverage['router/index.js'][95]++; -Router.prototype.all = (function () { - _$jscoverage['router/index.js'][96]++; - return this.find((function () { - _$jscoverage['router/index.js'][97]++; - return true; -})); -}); -_$jscoverage['router/index.js'][111]++; -Router.prototype.remove = (function (route) { - _$jscoverage['router/index.js'][112]++; - var routes = this.map[route.method], len = routes.length; - _$jscoverage['router/index.js'][116]++; - var i = this.routes.indexOf(route); - _$jscoverage['router/index.js'][117]++; - this.routes.splice(i, 1); - _$jscoverage['router/index.js'][120]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['router/index.js'][121]++; - if (route == routes[i]) { - _$jscoverage['router/index.js'][122]++; - routes.splice(i, 1); - _$jscoverage['router/index.js'][123]++; - return true; - } -} -}); -_$jscoverage['router/index.js'][137]++; -Router.prototype.lookup = (function (method, path) { - _$jscoverage['router/index.js'][138]++; - return this.find((function (route) { - _$jscoverage['router/index.js'][139]++; - return path == route.path && (route.method == method || method == "all"); -})); -}); -_$jscoverage['router/index.js'][171]++; -Router.prototype.find = (function (fn) { - _$jscoverage['router/index.js'][172]++; - var len = methods.length, ret = new Collection(this), method, routes, route; - _$jscoverage['router/index.js'][178]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['router/index.js'][179]++; - method = methods[i]; - _$jscoverage['router/index.js'][180]++; - routes = this.map[method]; - _$jscoverage['router/index.js'][181]++; - if (! routes) { - _$jscoverage['router/index.js'][181]++; - continue; - } - _$jscoverage['router/index.js'][182]++; - for (var j = 0, jlen = routes.length; j < jlen; ++j) { - _$jscoverage['router/index.js'][183]++; - route = routes[j]; - _$jscoverage['router/index.js'][184]++; - if (fn(route)) { - _$jscoverage['router/index.js'][184]++; - ret.push(route); - } -} -} - _$jscoverage['router/index.js'][188]++; - return ret; -}); -_$jscoverage['router/index.js'][200]++; -Router.prototype._dispatch = (function (req, res, next) { - _$jscoverage['router/index.js'][201]++; - var params = this.params, self = this; - _$jscoverage['router/index.js'][204]++; - debug("dispatching %s %s", req.method, req.url); - _$jscoverage['router/index.js'][207]++; - (function pass(i, err) { - _$jscoverage['router/index.js'][208]++; - var paramCallbacks, paramIndex = 0, paramVal, route, keys, key, ret; - _$jscoverage['router/index.js'][217]++; - function nextRoute(err) { - _$jscoverage['router/index.js'][218]++; - pass(req._route_index + 1, err); -} - _$jscoverage['router/index.js'][222]++; - req.route = route = self.match(req, i); - _$jscoverage['router/index.js'][225]++; - if (! route && "OPTIONS" == req.method) { - _$jscoverage['router/index.js'][225]++; - return self._options(req, res); - } - _$jscoverage['router/index.js'][228]++; - if (! route) { - _$jscoverage['router/index.js'][228]++; - return next(err); - } - _$jscoverage['router/index.js'][229]++; - debug("matched %s %s", route.method, route.path); - _$jscoverage['router/index.js'][233]++; - req.params = route.params; - _$jscoverage['router/index.js'][234]++; - keys = route.keys; - _$jscoverage['router/index.js'][235]++; - i = 0; - _$jscoverage['router/index.js'][238]++; - function param(err) { - _$jscoverage['router/index.js'][239]++; - paramIndex = 0; - _$jscoverage['router/index.js'][240]++; - key = keys[i++]; - _$jscoverage['router/index.js'][241]++; - paramVal = key && req.params[key.name]; - _$jscoverage['router/index.js'][242]++; - paramCallbacks = key && params[key.name]; - _$jscoverage['router/index.js'][244]++; - try { - _$jscoverage['router/index.js'][245]++; - if ("route" == err) { - _$jscoverage['router/index.js'][246]++; - nextRoute(); - } - else { - _$jscoverage['router/index.js'][247]++; - if (err) { - _$jscoverage['router/index.js'][248]++; - i = 0; - _$jscoverage['router/index.js'][249]++; - callbacks(err); - } - else { - _$jscoverage['router/index.js'][250]++; - if (paramCallbacks && undefined !== paramVal) { - _$jscoverage['router/index.js'][251]++; - paramCallback(); - } - else { - _$jscoverage['router/index.js'][252]++; - if (key) { - _$jscoverage['router/index.js'][253]++; - param(); - } - else { - _$jscoverage['router/index.js'][255]++; - i = 0; - _$jscoverage['router/index.js'][256]++; - callbacks(); - } - } - } - } - } - catch (err) { - _$jscoverage['router/index.js'][259]++; - param(err); - } -} - _$jscoverage['router/index.js'][261]++; - ; - _$jscoverage['router/index.js'][263]++; - param(err); - _$jscoverage['router/index.js'][266]++; - function paramCallback(err) { - _$jscoverage['router/index.js'][267]++; - var fn = paramCallbacks[paramIndex++]; - _$jscoverage['router/index.js'][268]++; - if (err || ! fn) { - _$jscoverage['router/index.js'][268]++; - return param(err); - } - _$jscoverage['router/index.js'][269]++; - fn(req, res, paramCallback, paramVal, key.name); -} - _$jscoverage['router/index.js'][273]++; - function callbacks(err) { - _$jscoverage['router/index.js'][274]++; - var fn = route.callbacks[i++]; - _$jscoverage['router/index.js'][275]++; - try { - _$jscoverage['router/index.js'][276]++; - if ("route" == err) { - _$jscoverage['router/index.js'][277]++; - nextRoute(); - } - else { - _$jscoverage['router/index.js'][278]++; - if (err && fn) { - _$jscoverage['router/index.js'][279]++; - if (fn.length < 4) { - _$jscoverage['router/index.js'][279]++; - return callbacks(err); - } - _$jscoverage['router/index.js'][280]++; - fn(err, req, res, callbacks); - } - else { - _$jscoverage['router/index.js'][281]++; - if (fn) { - _$jscoverage['router/index.js'][282]++; - fn(req, res, callbacks); - } - else { - _$jscoverage['router/index.js'][284]++; - nextRoute(err); - } - } - } - } - catch (err) { - _$jscoverage['router/index.js'][287]++; - callbacks(err); - } -} -})(0); -}); -_$jscoverage['router/index.js'][301]++; -Router.prototype._options = (function (req, res) { - _$jscoverage['router/index.js'][302]++; - var path = parse(req.url).pathname, body = this._optionsFor(path).join(","); - _$jscoverage['router/index.js'][304]++; - res.set("Allow", body).send(body); -}); -_$jscoverage['router/index.js'][315]++; -Router.prototype._optionsFor = (function (path) { - _$jscoverage['router/index.js'][316]++; - var self = this; - _$jscoverage['router/index.js'][317]++; - return methods.filter((function (method) { - _$jscoverage['router/index.js'][318]++; - var routes = self.map[method]; - _$jscoverage['router/index.js'][319]++; - if (! routes || "options" == method) { - _$jscoverage['router/index.js'][319]++; - return; - } - _$jscoverage['router/index.js'][320]++; - for (var i = 0, len = routes.length; i < len; ++i) { - _$jscoverage['router/index.js'][321]++; - if (routes[i].match(path)) { - _$jscoverage['router/index.js'][321]++; - return true; - } -} -})).map((function (method) { - _$jscoverage['router/index.js'][324]++; - return method.toUpperCase(); -})); -}); -_$jscoverage['router/index.js'][339]++; -Router.prototype.match = (function (req, i, head) { - _$jscoverage['router/index.js'][340]++; - var method = req.method.toLowerCase(), url = parse(req.url), path = url.pathname, routes = this.map, i = i || 0, captures, route, keys; - _$jscoverage['router/index.js'][351]++; - if (! head && "head" == method) { - _$jscoverage['router/index.js'][353]++; - route = this.match(req, i, true); - _$jscoverage['router/index.js'][354]++; - if (route) { - _$jscoverage['router/index.js'][354]++; - return route; - } - _$jscoverage['router/index.js'][358]++; - method = "get"; - } - _$jscoverage['router/index.js'][362]++; - if (routes = routes[method]) { - _$jscoverage['router/index.js'][365]++; - for (var len = routes.length; i < len; ++i) { - _$jscoverage['router/index.js'][366]++; - route = routes[i]; - _$jscoverage['router/index.js'][367]++; - if (captures = route.match(path)) { - _$jscoverage['router/index.js'][368]++; - keys = route.keys; - _$jscoverage['router/index.js'][369]++; - route.params = []; - _$jscoverage['router/index.js'][372]++; - for (var j = 1, jlen = captures.length; j < jlen; ++j) { - _$jscoverage['router/index.js'][373]++; - var key = keys[j - 1], val = "string" == typeof captures[j]? decodeURIComponent(captures[j]): captures[j]; - _$jscoverage['router/index.js'][377]++; - if (key) { - _$jscoverage['router/index.js'][378]++; - route.params[key.name] = val; - } - else { - _$jscoverage['router/index.js'][380]++; - route.params.push(val); - } -} - _$jscoverage['router/index.js'][385]++; - req._route_index = i; - _$jscoverage['router/index.js'][386]++; - return route; - } -} - } -}); -_$jscoverage['router/index.js'][402]++; -Router.prototype.route = (function (method, path, callbacks) { - _$jscoverage['router/index.js'][403]++; - var app = this.app, method = method.toLowerCase(), callbacks = utils.flatten([].slice.call(arguments, 2)); - _$jscoverage['router/index.js'][408]++; - if (! path) { - _$jscoverage['router/index.js'][408]++; - throw new Error("Router#" + method + "() requires a path"); - } - _$jscoverage['router/index.js'][411]++; - debug("defined %s %s", method, path); - _$jscoverage['router/index.js'][412]++; - var route = new Route(method, path, callbacks, {sensitive: this.caseSensitive, strict: this.strict}); - _$jscoverage['router/index.js'][418]++; - (this.map[method] = this.map[method] || []).push(route); - _$jscoverage['router/index.js'][419]++; - this.routes.push(route); - _$jscoverage['router/index.js'][420]++; - return this; -}); -_$jscoverage['router/index.js'].source = ["/*!"," * Express - Router"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var Route = require('./route')"," , Collection = require('./collection')"," , utils = require('../utils')"," , debug = require('debug')('express:router')"," , parse = require('url').parse;","","/**"," * Expose `Router` constructor."," */","","exports = module.exports = Router;","","/**"," * Expose HTTP methods."," */","","var methods = exports.methods = require('./methods');","","/**"," * Initialize a new `Router` with the given `options`."," * "," * @param {Object} options"," * @api private"," */","","function Router(options) {"," options = options || {};"," var self = this;"," this.routes = new Collection;"," this.map = {};"," this.params = {};"," this._params = [];"," this.caseSensitive = options.caseSensitive;"," this.strict = options.strict;",""," this.middleware = function router(req, res, next){"," self._dispatch(req, res, next);"," };","}","","/**"," * Register a param callback `fn` for the given `name`."," *"," * @param {String|Function} name"," * @param {Function} fn"," * @return {Router} for chaining"," * @api public"," */","","Router.prototype.param = function(name, fn){"," // param logic"," if ('function' == typeof name) {"," this._params.push(name);"," return;"," }",""," // apply param functions"," var params = this._params"," , len = params.length"," , ret;",""," for (var i = 0; i < len; ++i) {"," if (ret = params[i](name, fn)) {"," fn = ret;"," }"," }",""," // ensure we end up with a"," // middleware function"," if ('function' != typeof fn) {"," throw new Error('invalid param() call for ' + name + ', got ' + fn);"," }",""," (this.params[name] = this.params[name] || []).push(fn);"," return this;","};","","/**"," * Return a `Collection` of all routes defined."," *"," * @return {Collection}"," * @api public"," */","","Router.prototype.all = function(){"," return this.find(function(){"," return true;"," });","};","","/**"," * Remove the given `route`, returns"," * a bool indicating if the route was present"," * or not."," *"," * @param {Route} route"," * @return {Boolean}"," * @api public"," */","","Router.prototype.remove = function(route){"," var routes = this.map[route.method]"," , len = routes.length;",""," // remove from array"," var i = this.routes.indexOf(route);"," this.routes.splice(i, 1);",""," // remove from map"," for (var i = 0; i < len; ++i) {"," if (route == routes[i]) {"," routes.splice(i, 1);"," return true;"," }"," }","};","","/**"," * Return routes with route paths matching `path`."," *"," * @param {String} method"," * @param {String} path"," * @return {Collection}"," * @api public"," */","","Router.prototype.lookup = function(method, path){"," return this.find(function(route){"," return path == route.path"," && (route.method == method"," || method == 'all');"," });","};","","// /**","// * Return routes with regexps that match the given `url`.","// *","// * @param {String} method","// * @param {String} url","// * @return {Collection}","// * @api public","// */","// ","// Router.prototype.match = function(method, url){","// return this.find(function(route){","// return route.match(url)","// && (route.method == method","// || method == 'all');","// });","// };","","/**"," * Find routes based on the return value of `fn`"," * which is invoked once per route."," *"," * @param {Function} fn"," * @return {Collection}"," * @api public"," */","","Router.prototype.find = function(fn){"," var len = methods.length"," , ret = new Collection(this)"," , method"," , routes"," , route;",""," for (var i = 0; i < len; ++i) {"," method = methods[i];"," routes = this.map[method];"," if (!routes) continue;"," for (var j = 0, jlen = routes.length; j < jlen; ++j) {"," route = routes[j];"," if (fn(route)) ret.push(route);"," }"," }",""," return ret;","};","","/**"," * Route dispatcher aka the route \"middleware\"."," *"," * @param {IncomingMessage} req"," * @param {ServerResponse} res"," * @param {Function} next"," * @api private"," */","","Router.prototype._dispatch = function(req, res, next){"," var params = this.params"," , self = this;",""," debug('dispatching %s %s', req.method, req.url);",""," // route dispatch"," (function pass(i, err){"," var paramCallbacks"," , paramIndex = 0"," , paramVal"," , route"," , keys"," , key"," , ret;",""," // match next route"," function nextRoute(err) {"," pass(req._route_index + 1, err);"," }",""," // match route"," req.route = route = self.match(req, i);",""," // implied OPTIONS"," if (!route && 'OPTIONS' == req.method) return self._options(req, res);",""," // no route"," if (!route) return next(err);"," debug('matched %s %s', route.method, route.path);",""," // we have a route"," // start at param 0"," req.params = route.params;"," keys = route.keys;"," i = 0;",""," // param callbacks"," function param(err) {"," paramIndex = 0;"," key = keys[i++];"," paramVal = key && req.params[key.name];"," paramCallbacks = key && params[key.name];",""," try {"," if ('route' == err) {"," nextRoute();"," } else if (err) {"," i = 0;"," callbacks(err);"," } else if (paramCallbacks && undefined !== paramVal) {"," paramCallback();"," } else if (key) {"," param();"," } else {"," i = 0;"," callbacks();"," }"," } catch (err) {"," param(err);"," }"," };",""," param(err);"," "," // single param callbacks"," function paramCallback(err) {"," var fn = paramCallbacks[paramIndex++];"," if (err || !fn) return param(err);"," fn(req, res, paramCallback, paramVal, key.name);"," }",""," // invoke route callbacks"," function callbacks(err) {"," var fn = route.callbacks[i++];"," try {"," if ('route' == err) {"," nextRoute();"," } else if (err && fn) {"," if (fn.length < 4) return callbacks(err);"," fn(err, req, res, callbacks);"," } else if (fn) {"," fn(req, res, callbacks);"," } else {"," nextRoute(err);"," }"," } catch (err) {"," callbacks(err);"," }"," }"," })(0);","};","","/**"," * Respond to __OPTIONS__ method."," *"," * @param {IncomingMessage} req"," * @param {ServerResponse} res"," * @api private"," */","","Router.prototype._options = function(req, res){"," var path = parse(req.url).pathname"," , body = this._optionsFor(path).join(',');"," res.set('Allow', body).send(body);","};","","/**"," * Return an array of HTTP verbs or \"options\" for `path`."," *"," * @param {String} path"," * @return {Array}"," * @api private"," */","","Router.prototype._optionsFor = function(path){"," var self = this;"," return methods.filter(function(method){"," var routes = self.map[method];"," if (!routes || 'options' == method) return;"," for (var i = 0, len = routes.length; i < len; ++i) {"," if (routes[i].match(path)) return true;"," }"," }).map(function(method){"," return method.toUpperCase();"," });","};","","/**"," * Attempt to match a route for `req`"," * with optional starting index of `i`"," * defaulting to 0."," *"," * @param {IncomingMessage} req"," * @param {Number} i"," * @return {Route}"," * @api private"," */","","Router.prototype.match = function(req, i, head){"," var method = req.method.toLowerCase()"," , url = parse(req.url)"," , path = url.pathname"," , routes = this.map"," , i = i || 0"," , captures"," , route"," , keys;",""," // HEAD support"," // TODO: clean this up"," if (!head && 'head' == method) {"," // attempt lookup"," route = this.match(req, i, true);"," if (route) return route;",""," // default to GET as res.render() / res.send()"," // etc support HEAD"," method = 'get';"," }",""," // routes for this method"," if (routes = routes[method]) {",""," // matching routes"," for (var len = routes.length; i < len; ++i) {"," route = routes[i];"," if (captures = route.match(path)) {"," keys = route.keys;"," route.params = [];",""," // params from capture groups"," for (var j = 1, jlen = captures.length; j < jlen; ++j) {"," var key = keys[j-1]"," , val = 'string' == typeof captures[j]"," ? decodeURIComponent(captures[j])"," : captures[j];"," if (key) {"," route.params[key.name] = val;"," } else {"," route.params.push(val);"," }"," }",""," // all done"," req._route_index = i;"," return route;"," }"," }"," }","};","","/**"," * Route `method`, `path`, and one or more callbacks."," *"," * @param {String} method"," * @param {String} path"," * @param {Function} callback..."," * @return {Router} for chaining"," * @api private"," */","","Router.prototype.route = function(method, path, callbacks){"," var app = this.app"," , method = method.toLowerCase()"," , callbacks = utils.flatten([].slice.call(arguments, 2));",""," // ensure path was given"," if (!path) throw new Error('Router#' + method + '() requires a path');",""," // create the route"," debug('defined %s %s', method, path);"," var route = new Route(method, path, callbacks, {"," sensitive: this.caseSensitive"," , strict: this.strict"," });",""," // add it"," (this.map[method] = this.map[method] || []).push(route);"," this.routes.push(route);"," return this;","};"]; diff --git a/frontend/express/node_modules/express/lib-cov/router/methods.js b/frontend/express/node_modules/express/lib-cov/router/methods.js deleted file mode 100644 index cfe9c844a55..00000000000 --- a/frontend/express/node_modules/express/lib-cov/router/methods.js +++ /dev/null @@ -1,9 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['router/methods.js']) { - _$jscoverage['router/methods.js'] = []; - _$jscoverage['router/methods.js'][12] = 0; -} -_$jscoverage['router/methods.js'][12]++; -module.exports = ["get", "post", "put", "head", "delete", "options", "trace", "copy", "lock", "mkcol", "move", "propfind", "proppatch", "unlock", "report", "mkactivity", "checkout", "merge", "m-search", "notify", "subscribe", "unsubscribe", "patch"]; -_$jscoverage['router/methods.js'].source = ["","/*!"," * Express - router - methods"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * HTTP methods supported by node."," */","","module.exports = ["," 'get'"," , 'post'"," , 'put'"," , 'head'"," , 'delete'"," , 'options'"," , 'trace'"," , 'copy'"," , 'lock'"," , 'mkcol'"," , 'move'"," , 'propfind'"," , 'proppatch'"," , 'unlock'"," , 'report'"," , 'mkactivity'"," , 'checkout'"," , 'merge'"," , 'm-search'"," , 'notify'"," , 'subscribe'"," , 'unsubscribe'"," , 'patch'","];"]; diff --git a/frontend/express/node_modules/express/lib-cov/router/route.js b/frontend/express/node_modules/express/lib-cov/router/route.js deleted file mode 100644 index 6aae8a10150..00000000000 --- a/frontend/express/node_modules/express/lib-cov/router/route.js +++ /dev/null @@ -1,68 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['router/route.js']) { - _$jscoverage['router/route.js'] = []; - _$jscoverage['router/route.js'][11] = 0; - _$jscoverage['router/route.js'][29] = 0; - _$jscoverage['router/route.js'][30] = 0; - _$jscoverage['router/route.js'][31] = 0; - _$jscoverage['router/route.js'][32] = 0; - _$jscoverage['router/route.js'][33] = 0; - _$jscoverage['router/route.js'][34] = 0; - _$jscoverage['router/route.js'][48] = 0; - _$jscoverage['router/route.js'][49] = 0; - _$jscoverage['router/route.js'][69] = 0; - _$jscoverage['router/route.js'][70] = 0; - _$jscoverage['router/route.js'][71] = 0; - _$jscoverage['router/route.js'][72] = 0; - _$jscoverage['router/route.js'][73] = 0; - _$jscoverage['router/route.js'][77] = 0; - _$jscoverage['router/route.js'][78] = 0; - _$jscoverage['router/route.js'][79] = 0; - _$jscoverage['router/route.js'][88] = 0; -} -_$jscoverage['router/route.js'][11]++; -module.exports = Route; -_$jscoverage['router/route.js'][29]++; -function Route(method, path, callbacks, options) { - _$jscoverage['router/route.js'][30]++; - options = options || {}; - _$jscoverage['router/route.js'][31]++; - this.path = path; - _$jscoverage['router/route.js'][32]++; - this.method = method; - _$jscoverage['router/route.js'][33]++; - this.callbacks = callbacks; - _$jscoverage['router/route.js'][34]++; - this.regexp = normalize(path, this.keys = [], options.sensitive, options.strict); -} -_$jscoverage['router/route.js'][48]++; -Route.prototype.match = (function (path) { - _$jscoverage['router/route.js'][49]++; - return this.regexp.exec(path); -}); -_$jscoverage['router/route.js'][69]++; -function normalize(path, keys, sensitive, strict) { - _$jscoverage['router/route.js'][70]++; - if (path instanceof RegExp) { - _$jscoverage['router/route.js'][70]++; - return path; - } - _$jscoverage['router/route.js'][71]++; - if (path instanceof Array) { - _$jscoverage['router/route.js'][72]++; - path = "(" + path.join("|") + ")"; - } - _$jscoverage['router/route.js'][73]++; - path = path.concat(strict? "": "/?").replace(/\/\(/g, "(?:/").replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, (function (_, slash, format, key, capture, optional) { - _$jscoverage['router/route.js'][77]++; - keys.push({name: key, optional: ! ! optional}); - _$jscoverage['router/route.js'][78]++; - slash = slash || ""; - _$jscoverage['router/route.js'][79]++; - return "" + (optional? "": slash) + "(?:" + (optional? slash: "") + (format || "") + (capture || (format && "([^/.]+?)" || "([^/]+?)")) + ")" + (optional || ""); -})).replace(/([\/.])/g, "\\$1").replace(/\*/g, "(.*)"); - _$jscoverage['router/route.js'][88]++; - return new RegExp("^" + path + "$", sensitive? "": "i"); -} -_$jscoverage['router/route.js'].source = ["/*!"," * Express - router - Route"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Expose `Route`."," */","","module.exports = Route;","","/**"," * Initialize `Route` with the given HTTP `method`, `path`,"," * and an array of `callbacks` and `options`."," *"," * Options:"," *"," * - `sensitive` enable case-sensitive routes"," * - `strict` enable strict matching for trailing slashes"," *"," * @param {String} method"," * @param {String} path"," * @param {Array} callbacks"," * @param {Object} options."," * @api private"," */","","function Route(method, path, callbacks, options) {"," options = options || {};"," this.path = path;"," this.method = method;"," this.callbacks = callbacks;"," this.regexp = normalize(path"," , this.keys = []"," , options.sensitive"," , options.strict);","}","","/**"," * Check if this route matches `path` and return captures made."," *"," * @param {String} path"," * @return {Array}"," * @api private"," */","","Route.prototype.match = function(path){"," return this.regexp.exec(path);","};","","/**"," * Normalize the given path string,"," * returning a regular expression."," *"," * An empty array should be passed,"," * which will contain the placeholder"," * key names. For example \"/user/:id\" will"," * then contain [\"id\"]."," *"," * @param {String|RegExp|Array} path"," * @param {Array} keys"," * @param {Boolean} sensitive"," * @param {Boolean} strict"," * @return {RegExp}"," * @api private"," */","","function normalize(path, keys, sensitive, strict) {"," if (path instanceof RegExp) return path;"," if (path instanceof Array) "," \tpath = '(' + path.join('|') + ')';"," path = path"," .concat(strict ? '' : '/?')"," .replace(/\\/\\(/g, '(?:/')"," .replace(/(\\/)?(\\.)?:(\\w+)(?:(\\(.*?\\)))?(\\?)?/g, function(_, slash, format, key, capture, optional){"," keys.push({ name: key, optional: !! optional });"," slash = slash || '';"," return ''"," + (optional ? '' : slash)"," + '(?:'"," + (optional ? slash : '')"," + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'"," + (optional || '');"," })"," .replace(/([\\/.])/g, '\\\\$1')"," .replace(/\\*/g, '(.*)');"," return new RegExp('^' + path + '$', sensitive ? '' : 'i');","}"]; diff --git a/frontend/express/node_modules/express/lib-cov/utils.js b/frontend/express/node_modules/express/lib-cov/utils.js deleted file mode 100644 index e87dad05710..00000000000 --- a/frontend/express/node_modules/express/lib-cov/utils.js +++ /dev/null @@ -1,151 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['utils.js']) { - _$jscoverage['utils.js'] = []; - _$jscoverage['utils.js'][12] = 0; - _$jscoverage['utils.js'][22] = 0; - _$jscoverage['utils.js'][23] = 0; - _$jscoverage['utils.js'][24] = 0; - _$jscoverage['utils.js'][35] = 0; - _$jscoverage['utils.js'][36] = 0; - _$jscoverage['utils.js'][38] = 0; - _$jscoverage['utils.js'][39] = 0; - _$jscoverage['utils.js'][40] = 0; - _$jscoverage['utils.js'][42] = 0; - _$jscoverage['utils.js'][45] = 0; - _$jscoverage['utils.js'][58] = 0; - _$jscoverage['utils.js'][60] = 0; - _$jscoverage['utils.js'][63] = 0; - _$jscoverage['utils.js'][66] = 0; - _$jscoverage['utils.js'][69] = 0; - _$jscoverage['utils.js'][74] = 0; - _$jscoverage['utils.js'][75] = 0; - _$jscoverage['utils.js'][76] = 0; - _$jscoverage['utils.js'][79] = 0; - _$jscoverage['utils.js'][91] = 0; - _$jscoverage['utils.js'][92] = 0; - _$jscoverage['utils.js'][108] = 0; - _$jscoverage['utils.js'][109] = 0; - _$jscoverage['utils.js'][112] = 0; - _$jscoverage['utils.js'][113] = 0; - _$jscoverage['utils.js'][114] = 0; - _$jscoverage['utils.js'][115] = 0; - _$jscoverage['utils.js'][129] = 0; - _$jscoverage['utils.js'][130] = 0; - _$jscoverage['utils.js'][134] = 0; - _$jscoverage['utils.js'][137] = 0; - _$jscoverage['utils.js'][150] = 0; - _$jscoverage['utils.js'][151] = 0; - _$jscoverage['utils.js'][154] = 0; - _$jscoverage['utils.js'][158] = 0; - _$jscoverage['utils.js'][169] = 0; - _$jscoverage['utils.js'][170] = 0; -} -_$jscoverage['utils.js'][12]++; -var mime = require("mime"); -_$jscoverage['utils.js'][22]++; -exports.isAbsolute = (function (path) { - _$jscoverage['utils.js'][23]++; - if ("/" == path[0]) { - _$jscoverage['utils.js'][23]++; - return true; - } - _$jscoverage['utils.js'][24]++; - if (":" == path[1] && "\\" == path[2]) { - _$jscoverage['utils.js'][24]++; - return true; - } -}); -_$jscoverage['utils.js'][35]++; -exports.flatten = (function (arr, ret) { - _$jscoverage['utils.js'][36]++; - var ret = ret || [], len = arr.length; - _$jscoverage['utils.js'][38]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['utils.js'][39]++; - if (Array.isArray(arr[i])) { - _$jscoverage['utils.js'][40]++; - exports.flatten(arr[i], ret); - } - else { - _$jscoverage['utils.js'][42]++; - ret.push(arr[i]); - } -} - _$jscoverage['utils.js'][45]++; - return ret; -}); -_$jscoverage['utils.js'][58]++; -exports.accepts = (function (type, str) { - _$jscoverage['utils.js'][60]++; - if (! str) { - _$jscoverage['utils.js'][60]++; - return true; - } - _$jscoverage['utils.js'][63]++; - if (! ~ type.indexOf("/")) { - _$jscoverage['utils.js'][63]++; - type = mime.lookup(type); - } - _$jscoverage['utils.js'][66]++; - type = type.split("/"); - _$jscoverage['utils.js'][69]++; - var accepted = exports.parseAccept(str), len = accepted.length, obj, ok; - _$jscoverage['utils.js'][74]++; - for (var i = 0; i < len; ++i) { - _$jscoverage['utils.js'][75]++; - obj = accepted[i]; - _$jscoverage['utils.js'][76]++; - if (exports.accept(type, obj)) { - _$jscoverage['utils.js'][76]++; - return true; - } -} - _$jscoverage['utils.js'][79]++; - return false; -}); -_$jscoverage['utils.js'][91]++; -exports.accept = (function (type, other) { - _$jscoverage['utils.js'][92]++; - return (type[0] == other.type || "*" == other.type) && (type[1] == other.subtype || "*" == other.subtype); -}); -_$jscoverage['utils.js'][108]++; -exports.parseAccept = (function (str) { - _$jscoverage['utils.js'][109]++; - return exports.parseQuality(str).map((function (obj) { - _$jscoverage['utils.js'][112]++; - var parts = obj.value.split("/"); - _$jscoverage['utils.js'][113]++; - obj.type = parts[0]; - _$jscoverage['utils.js'][114]++; - obj.subtype = parts[1]; - _$jscoverage['utils.js'][115]++; - return obj; -})); -}); -_$jscoverage['utils.js'][129]++; -exports.parseQuality = (function (str) { - _$jscoverage['utils.js'][130]++; - return str.split(/ *, */).map(quality).filter((function (obj) { - _$jscoverage['utils.js'][134]++; - return obj.quality; -})).sort((function (a, b) { - _$jscoverage['utils.js'][137]++; - return b.quality - a.quality; -})); -}); -_$jscoverage['utils.js'][150]++; -function quality(str) { - _$jscoverage['utils.js'][151]++; - var parts = str.split(/ *; */), val = parts[0]; - _$jscoverage['utils.js'][154]++; - var q = parts[1]? parseFloat(parts[1].split(/ *= */)[1]): 1; - _$jscoverage['utils.js'][158]++; - return ({value: val, quality: q}); -} -_$jscoverage['utils.js'][169]++; -exports.escape = (function (html) { - _$jscoverage['utils.js'][170]++; - return String(html).replace(/&/g, "&").replace(/"/g, """).replace(//g, ">"); -}); -_$jscoverage['utils.js'].source = ["","/*!"," * Express - utils"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var mime = require('mime');","","/**"," * Check if `path` looks absolute."," *"," * @param {String} path"," * @return {Boolean}"," * @api private"," */","","exports.isAbsolute = function(path){"," if ('/' == path[0]) return true;"," if (':' == path[1] && '\\\\' == path[2]) return true;","};","","/**"," * Flatten the given `arr`."," *"," * @param {Array} arr"," * @return {Array}"," * @api private"," */","","exports.flatten = function(arr, ret){"," var ret = ret || []"," , len = arr.length;"," for (var i = 0; i < len; ++i) {"," if (Array.isArray(arr[i])) {"," exports.flatten(arr[i], ret);"," } else {"," ret.push(arr[i]);"," }"," }"," return ret;","};","","/**"," * Check if `type` is acceptable based on"," * the given `str`."," *"," * @param {String} type"," * @param {String} str"," * @return {Boolean}"," * @api private"," */","","exports.accepts = function(type, str){"," // accept anything when Accept is not present"," if (!str) return true;",""," // resolve mime"," if (!~type.indexOf('/')) type = mime.lookup(type);",""," // split type/subtype"," type = type.split('/');",""," // parse"," var accepted = exports.parseAccept(str)"," , len = accepted.length"," , obj"," , ok;",""," for (var i = 0; i < len; ++i) {"," obj = accepted[i];"," if (exports.accept(type, obj)) return true;"," }",""," return false;","};","","/**"," * Check if `type` array is acceptable for `other`."," *"," * @param {Array} type"," * @param {Object} other"," * @return {Boolean}"," * @api private"," */","","exports.accept = function(type, other){"," return (type[0] == other.type || '*' == other.type)"," && (type[1] == other.subtype || '*' == other.subtype);","};","","/**"," * Parse accept `str`, returning"," * an array objects containing"," * `.type` and `.subtype` along"," * with the values provided by"," * `parseQuality()`."," *"," * @param {Type} name"," * @return {Type}"," * @api private"," */","","exports.parseAccept = function(str){"," return exports"," .parseQuality(str)"," .map(function(obj){"," var parts = obj.value.split('/');"," obj.type = parts[0];"," obj.subtype = parts[1];"," return obj;"," });","};","","/**"," * Parse quality `str`, returning an"," * array of objects with `.value` and"," * `.quality`."," *"," * @param {Type} name"," * @return {Type}"," * @api private"," */","","exports.parseQuality = function(str){"," return str"," .split(/ *, */)"," .map(quality)"," .filter(function(obj){"," return obj.quality;"," })"," .sort(function(a, b){"," return b.quality - a.quality;"," });","};","","/**"," * Parse quality `str` returning an"," * object with `.value` and `.quality`."," *"," * @param {String} str"," * @return {Object}"," * @api private"," */","","function quality(str) {"," var parts = str.split(/ *; */)"," , val = parts[0];",""," var q = parts[1]"," ? parseFloat(parts[1].split(/ *= */)[1])"," : 1;",""," return { value: val, quality: q };","}","","/**"," * Escape special characters in the given string of html."," *"," * @param {String} html"," * @return {String}"," * @api private"," */","","exports.escape = function(html) {"," return String(html)"," .replace(/&/g, '&amp;')"," .replace(/\"/g, '&quot;')"," .replace(/</g, '&lt;')"," .replace(/>/g, '&gt;');","};"]; diff --git a/frontend/express/node_modules/express/lib-cov/view.js b/frontend/express/node_modules/express/lib-cov/view.js deleted file mode 100644 index 70b56ccbb3d..00000000000 --- a/frontend/express/node_modules/express/lib-cov/view.js +++ /dev/null @@ -1,81 +0,0 @@ -/* automatically generated by JSCoverage - do not edit */ -if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; -if (! _$jscoverage['view.js']) { - _$jscoverage['view.js'] = []; - _$jscoverage['view.js'][12] = 0; - _$jscoverage['view.js'][25] = 0; - _$jscoverage['view.js'][41] = 0; - _$jscoverage['view.js'][42] = 0; - _$jscoverage['view.js'][43] = 0; - _$jscoverage['view.js'][44] = 0; - _$jscoverage['view.js'][45] = 0; - _$jscoverage['view.js'][46] = 0; - _$jscoverage['view.js'][47] = 0; - _$jscoverage['view.js'][48] = 0; - _$jscoverage['view.js'][49] = 0; - _$jscoverage['view.js'][50] = 0; - _$jscoverage['view.js'][61] = 0; - _$jscoverage['view.js'][62] = 0; - _$jscoverage['view.js'][65] = 0; - _$jscoverage['view.js'][66] = 0; - _$jscoverage['view.js'][69] = 0; - _$jscoverage['view.js'][70] = 0; - _$jscoverage['view.js'][81] = 0; - _$jscoverage['view.js'][82] = 0; -} -_$jscoverage['view.js'][12]++; -var path = require("path"), utils = require("./utils"), fs = require("fs"), dirname = path.dirname, basename = path.basename, extname = path.extname, exists = path.existsSync, join = path.join; -_$jscoverage['view.js'][25]++; -module.exports = View; -_$jscoverage['view.js'][41]++; -function View(name, options) { - _$jscoverage['view.js'][42]++; - options = options || {}; - _$jscoverage['view.js'][43]++; - this.name = name; - _$jscoverage['view.js'][44]++; - this.root = options.root; - _$jscoverage['view.js'][45]++; - var engines = options.engines; - _$jscoverage['view.js'][46]++; - this.defaultEngine = options.defaultEngine; - _$jscoverage['view.js'][47]++; - var ext = this.ext = extname(name); - _$jscoverage['view.js'][48]++; - if (! ext) { - _$jscoverage['view.js'][48]++; - name += (ext = this.ext = "." + this.defaultEngine); - } - _$jscoverage['view.js'][49]++; - this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express); - _$jscoverage['view.js'][50]++; - this.path = this.lookup(name); -} -_$jscoverage['view.js'][61]++; -View.prototype.lookup = (function (path) { - _$jscoverage['view.js'][62]++; - var ext = this.ext; - _$jscoverage['view.js'][65]++; - if (! utils.isAbsolute(path)) { - _$jscoverage['view.js'][65]++; - path = join(this.root, path); - } - _$jscoverage['view.js'][66]++; - if (exists(path)) { - _$jscoverage['view.js'][66]++; - return path; - } - _$jscoverage['view.js'][69]++; - path = join(dirname(path), basename(path, ext), "index" + ext); - _$jscoverage['view.js'][70]++; - if (exists(path)) { - _$jscoverage['view.js'][70]++; - return path; - } -}); -_$jscoverage['view.js'][81]++; -View.prototype.render = (function (options, fn) { - _$jscoverage['view.js'][82]++; - this.engine(this.path, options, fn); -}); -_$jscoverage['view.js'].source = ["","/*!"," * Express - View"," * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var path = require('path')"," , utils = require('./utils')"," , fs = require('fs')"," , dirname = path.dirname"," , basename = path.basename"," , extname = path.extname"," , exists = path.existsSync"," , join = path.join;","","/**"," * Expose `View`."," */","","module.exports = View;","","/**"," * Initialize a new `View` with the given `name`."," *"," * Options:"," *"," * - `defaultEngine` the default template engine name "," * - `engines` template engine require() cache "," * - `root` root path for view lookup "," *"," * @param {String} name"," * @param {Object} options"," * @api private"," */","","function View(name, options) {"," options = options || {};"," this.name = name;"," this.root = options.root;"," var engines = options.engines;"," this.defaultEngine = options.defaultEngine;"," var ext = this.ext = extname(name);"," if (!ext) name += (ext = this.ext = '.' + this.defaultEngine);"," this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);"," this.path = this.lookup(name);","}","","/**"," * Lookup view by the given `path`"," *"," * @param {String} path"," * @return {String}"," * @api private"," */","","View.prototype.lookup = function(path){"," var ext = this.ext;",""," // <path>.<engine>"," if (!utils.isAbsolute(path)) path = join(this.root, path);"," if (exists(path)) return path;",""," // <path>/index.<engine>"," path = join(dirname(path), basename(path, ext), 'index' + ext);"," if (exists(path)) return path;","};","","/**"," * Render with the given `options` and callback `fn(err, str)`."," *"," * @param {Object} options"," * @param {Function} fn"," * @api private"," */","","View.prototype.render = function(options, fn){"," this.engine(this.path, options, fn);","};"]; diff --git a/frontend/express/node_modules/express/lib/application.js b/frontend/express/node_modules/express/lib/application.js deleted file mode 100644 index 6a3cf13899e..00000000000 --- a/frontend/express/node_modules/express/lib/application.js +++ /dev/null @@ -1,536 +0,0 @@ -/** - * Module dependencies. - */ - -var connect = require('connect') - , Router = require('./router') - , methods = require('methods') - , middleware = require('./middleware') - , debug = require('debug')('express:application') - , locals = require('./utils').locals - , View = require('./view') - , utils = connect.utils - , path = require('path') - , http = require('http') - , join = path.join; - -/** - * Application prototype. - */ - -var app = exports = module.exports = {}; - -/** - * Initialize the server. - * - * - setup default configuration - * - setup default middleware - * - setup route reflection methods - * - * @api private - */ - -app.init = function(){ - this.cache = {}; - this.settings = {}; - this.engines = {}; - this.defaultConfiguration(); -}; - -/** - * Initialize application configuration. - * - * @api private - */ - -app.defaultConfiguration = function(){ - // default settings - this.enable('x-powered-by'); - this.set('env', process.env.NODE_ENV || 'development'); - this.set('subdomain offset', 2); - debug('booting in %s mode', this.get('env')); - - // implicit middleware - this.use(connect.query()); - this.use(middleware.init(this)); - - // inherit protos - this.on('mount', function(parent){ - this.request.__proto__ = parent.request; - this.response.__proto__ = parent.response; - this.engines.__proto__ = parent.engines; - this.settings.__proto__ = parent.settings; - }); - - // router - this._router = new Router(this); - this.routes = this._router.map; - this.__defineGetter__('router', function(){ - this._usedRouter = true; - this._router.caseSensitive = this.enabled('case sensitive routing'); - this._router.strict = this.enabled('strict routing'); - return this._router.middleware; - }); - - // setup locals - this.locals = locals(this); - - // default locals - this.locals.settings = this.settings; - - // default configuration - this.set('view', View); - this.set('views', process.cwd() + '/views'); - this.set('jsonp callback name', 'callback'); - - this.configure('development', function(){ - this.set('json spaces', 2); - }); - - this.configure('production', function(){ - this.enable('view cache'); - }); -}; - -/** - * Proxy `connect#use()` to apply settings to - * mounted applications. - * - * @param {String|Function|Server} route - * @param {Function|Server} fn - * @return {app} for chaining - * @api public - */ - -app.use = function(route, fn){ - var app; - - // default route to '/' - if ('string' != typeof route) fn = route, route = '/'; - - // express app - if (fn.handle && fn.set) app = fn; - - // restore .app property on req and res - if (app) { - app.route = route; - fn = function(req, res, next) { - var orig = req.app; - app.handle(req, res, function(err){ - req.app = res.app = orig; - req.__proto__ = orig.request; - res.__proto__ = orig.response; - next(err); - }); - }; - } - - connect.proto.use.call(this, route, fn); - - // mounted an app - if (app) { - app.parent = this; - app.emit('mount', this); - } - - return this; -}; - -/** - * Register the given template engine callback `fn` - * as `ext`. - * - * By default will `require()` the engine based on the - * file extension. For example if you try to render - * a "foo.jade" file Express will invoke the following internally: - * - * app.engine('jade', require('jade').__express); - * - * For engines that do not provide `.__express` out of the box, - * or if you wish to "map" a different extension to the template engine - * you may use this method. For example mapping the EJS template engine to - * ".html" files: - * - * app.engine('html', require('ejs').renderFile); - * - * In this case EJS provides a `.renderFile()` method with - * the same signature that Express expects: `(path, options, callback)`, - * though note that it aliases this method as `ejs.__express` internally - * so if you're using ".ejs" extensions you dont need to do anything. - * - * Some template engines do not follow this convention, the - * [Consolidate.js](https://github.com/visionmedia/consolidate.js) - * library was created to map all of node's popular template - * engines to follow this convention, thus allowing them to - * work seamlessly within Express. - * - * @param {String} ext - * @param {Function} fn - * @return {app} for chaining - * @api public - */ - -app.engine = function(ext, fn){ - if ('function' != typeof fn) throw new Error('callback function required'); - if ('.' != ext[0]) ext = '.' + ext; - this.engines[ext] = fn; - return this; -}; - -/** - * Map the given param placeholder `name`(s) to the given callback(s). - * - * Parameter mapping is used to provide pre-conditions to routes - * which use normalized placeholders. For example a _:user_id_ parameter - * could automatically load a user's information from the database without - * any additional code, - * - * The callback uses the samesignature as middleware, the only differencing - * being that the value of the placeholder is passed, in this case the _id_ - * of the user. Once the `next()` function is invoked, just like middleware - * it will continue on to execute the route, or subsequent parameter functions. - * - * app.param('user_id', function(req, res, next, id){ - * User.find(id, function(err, user){ - * if (err) { - * next(err); - * } else if (user) { - * req.user = user; - * next(); - * } else { - * next(new Error('failed to load user')); - * } - * }); - * }); - * - * @param {String|Array} name - * @param {Function} fn - * @return {app} for chaining - * @api public - */ - -app.param = function(name, fn){ - var self = this - , fns = [].slice.call(arguments, 1); - - // array - if (Array.isArray(name)) { - name.forEach(function(name){ - fns.forEach(function(fn){ - self.param(name, fn); - }); - }); - // param logic - } else if ('function' == typeof name) { - this._router.param(name); - // single - } else { - if (':' == name[0]) name = name.substr(1); - fns.forEach(function(fn){ - self._router.param(name, fn); - }); - } - - return this; -}; - -/** - * Assign `setting` to `val`, or return `setting`'s value. - * - * app.set('foo', 'bar'); - * app.get('foo'); - * // => "bar" - * - * Mounted servers inherit their parent server's settings. - * - * @param {String} setting - * @param {String} val - * @return {Server} for chaining - * @api public - */ - -app.set = function(setting, val){ - if (1 == arguments.length) { - return this.settings[setting]; - } else { - this.settings[setting] = val; - return this; - } -}; - -/** - * Return the app's absolute pathname - * based on the parent(s) that have - * mounted it. - * - * For example if the application was - * mounted as "/admin", which itself - * was mounted as "/blog" then the - * return value would be "/blog/admin". - * - * @return {String} - * @api private - */ - -app.path = function(){ - return this.parent - ? this.parent.path() + this.route - : ''; -}; - -/** - * Check if `setting` is enabled (truthy). - * - * app.enabled('foo') - * // => false - * - * app.enable('foo') - * app.enabled('foo') - * // => true - * - * @param {String} setting - * @return {Boolean} - * @api public - */ - -app.enabled = function(setting){ - return !!this.set(setting); -}; - -/** - * Check if `setting` is disabled. - * - * app.disabled('foo') - * // => true - * - * app.enable('foo') - * app.disabled('foo') - * // => false - * - * @param {String} setting - * @return {Boolean} - * @api public - */ - -app.disabled = function(setting){ - return !this.set(setting); -}; - -/** - * Enable `setting`. - * - * @param {String} setting - * @return {app} for chaining - * @api public - */ - -app.enable = function(setting){ - return this.set(setting, true); -}; - -/** - * Disable `setting`. - * - * @param {String} setting - * @return {app} for chaining - * @api public - */ - -app.disable = function(setting){ - return this.set(setting, false); -}; - -/** - * Configure callback for zero or more envs, - * when no `env` is specified that callback will - * be invoked for all environments. Any combination - * can be used multiple times, in any order desired. - * - * Examples: - * - * app.configure(function(){ - * // executed for all envs - * }); - * - * app.configure('stage', function(){ - * // executed staging env - * }); - * - * app.configure('stage', 'production', function(){ - * // executed for stage and production - * }); - * - * Note: - * - * These callbacks are invoked immediately, and - * are effectively sugar for the following: - * - * var env = process.env.NODE_ENV || 'development'; - * - * switch (env) { - * case 'development': - * ... - * break; - * case 'stage': - * ... - * break; - * case 'production': - * ... - * break; - * } - * - * @param {String} env... - * @param {Function} fn - * @return {app} for chaining - * @api public - */ - -app.configure = function(env, fn){ - var envs = 'all' - , args = [].slice.call(arguments); - fn = args.pop(); - if (args.length) envs = args; - if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this); - return this; -}; - -/** - * Delegate `.VERB(...)` calls to `router.VERB(...)`. - */ - -methods.forEach(function(method){ - app[method] = function(path){ - if ('get' == method && 1 == arguments.length) return this.set(path); - - // deprecated - if (Array.isArray(path)) { - console.trace('passing an array to app.VERB() is deprecated and will be removed in 4.0'); - } - - // if no router attached yet, attach the router - if (!this._usedRouter) this.use(this.router); - - // setup route - this._router[method].apply(this._router, arguments); - return this; - }; -}); - -/** - * Special-cased "all" method, applying the given route `path`, - * middleware, and callback to _every_ HTTP method. - * - * @param {String} path - * @param {Function} ... - * @return {app} for chaining - * @api public - */ - -app.all = function(path){ - var args = arguments; - methods.forEach(function(method){ - app[method].apply(this, args); - }, this); - return this; -}; - -// del -> delete alias - -app.del = app.delete; - -/** - * Render the given view `name` name with `options` - * and a callback accepting an error and the - * rendered template string. - * - * Example: - * - * app.render('email', { name: 'Tobi' }, function(err, html){ - * // ... - * }) - * - * @param {String} name - * @param {String|Function} options or fn - * @param {Function} fn - * @api public - */ - -app.render = function(name, options, fn){ - var opts = {} - , cache = this.cache - , engines = this.engines - , view; - - // support callback function as second arg - if ('function' == typeof options) { - fn = options, options = {}; - } - - // merge app.locals - utils.merge(opts, this.locals); - - // merge options._locals - if (options._locals) utils.merge(opts, options._locals); - - // merge options - utils.merge(opts, options); - - // set .cache unless explicitly provided - opts.cache = null == opts.cache - ? this.enabled('view cache') - : opts.cache; - - // primed cache - if (opts.cache) view = cache[name]; - - // view - if (!view) { - view = new (this.get('view'))(name, { - defaultEngine: this.get('view engine'), - root: this.get('views'), - engines: engines - }); - - if (!view.path) { - var err = new Error('Failed to lookup view "' + name + '"'); - err.view = view; - return fn(err); - } - - // prime the cache - if (opts.cache) cache[name] = view; - } - - // render - try { - view.render(opts, fn); - } catch (err) { - fn(err); - } -}; - -/** - * Listen for connections. - * - * A node `http.Server` is returned, with this - * application (which is a `Function`) as its - * callback. If you wish to create both an HTTP - * and HTTPS server you may do so with the "http" - * and "https" modules as shown here: - * - * var http = require('http') - * , https = require('https') - * , express = require('express') - * , app = express(); - * - * http.createServer(app).listen(80); - * https.createServer({ ... }, app).listen(443); - * - * @return {http.Server} - * @api public - */ - -app.listen = function(){ - var server = http.createServer(this); - return server.listen.apply(server, arguments); -}; diff --git a/frontend/express/node_modules/express/lib/express.js b/frontend/express/node_modules/express/lib/express.js deleted file mode 100644 index f4258f1297e..00000000000 --- a/frontend/express/node_modules/express/lib/express.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Module dependencies. - */ - -var connect = require('connect') - , proto = require('./application') - , Route = require('./router/route') - , Router = require('./router') - , req = require('./request') - , res = require('./response') - , utils = connect.utils; - -/** - * Expose `createApplication()`. - */ - -exports = module.exports = createApplication; - -/** - * Framework version. - */ - -exports.version = '3.2.5'; - -/** - * Expose mime. - */ - -exports.mime = connect.mime; - -/** - * Create an express application. - * - * @return {Function} - * @api public - */ - -function createApplication() { - var app = connect(); - utils.merge(app, proto); - app.request = { __proto__: req }; - app.response = { __proto__: res }; - app.init(); - return app; -} - -/** - * Expose connect.middleware as express.* - * for example `express.logger` etc. - */ - -for (var key in connect.middleware) { - Object.defineProperty( - exports - , key - , Object.getOwnPropertyDescriptor(connect.middleware, key)); -} - -/** - * Error on createServer(). - */ - -exports.createServer = function(){ - console.warn('Warning: express.createServer() is deprecated, express'); - console.warn('applications no longer inherit from http.Server,'); - console.warn('please use:'); - console.warn(''); - console.warn(' var express = require("express");'); - console.warn(' var app = express();'); - console.warn(''); - return createApplication(); -}; - -/** - * Expose the prototypes. - */ - -exports.application = proto; -exports.request = req; -exports.response = res; - -/** - * Expose constructors. - */ - -exports.Route = Route; -exports.Router = Router; - -// Error handler title - -exports.errorHandler.title = 'Express'; - diff --git a/frontend/express/node_modules/express/lib/http.js b/frontend/express/node_modules/express/lib/http.js deleted file mode 100644 index da2158f3162..00000000000 --- a/frontend/express/node_modules/express/lib/http.js +++ /dev/null @@ -1,582 +0,0 @@ -/*! - * Express - HTTPServer - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var qs = require('qs') - , connect = require('connect') - , router = require('./router') - , Router = require('./router') - , view = require('./view') - , toArray = require('./utils').toArray - , methods = router.methods.concat('del', 'all') - , url = require('url') - , utils = connect.utils; - -/** - * Expose `HTTPServer`. - */ - -exports = module.exports = HTTPServer; - -/** - * Server proto. - */ - -var app = HTTPServer.prototype; - -/** - * Initialize a new `HTTPServer` with optional `middleware`. - * - * @param {Array} middleware - * @api public - */ - -function HTTPServer(middleware){ - connect.HTTPServer.call(this, []); - this.init(middleware); -}; - -/** - * Inherit from `connect.HTTPServer`. - */ - -app.__proto__ = connect.HTTPServer.prototype; - -/** - * Initialize the server. - * - * @param {Array} middleware - * @api private - */ - -app.init = function(middleware){ - var self = this; - this.cache = {}; - this.settings = {}; - this.redirects = {}; - this.isCallbacks = {}; - this._locals = {}; - this.dynamicViewHelpers = {}; - this.errorHandlers = []; - - this.set('env', process.env.NODE_ENV || 'development'); - - // expose objects to each other - this.use(function(req, res, next){ - req.query = req.query || {}; - res.setHeader('X-Powered-By', 'Express'); - req.app = res.app = self; - req.res = res; - res.req = req; - req.next = next; - // assign req.query - if (req.url.indexOf('?') > 0) { - var query = url.parse(req.url).query; - req.query = qs.parse(query); - } - next(); - }); - - // apply middleware - if (middleware) middleware.forEach(self.use.bind(self)); - - // router - this.routes = new Router(this); - this.__defineGetter__('router', function(){ - this.__usedRouter = true; - return self.routes.middleware; - }); - - // default locals - this.locals({ - settings: this.settings - , app: this - }); - - // default development configuration - this.configure('development', function(){ - this.enable('hints'); - }); - - // default production configuration - this.configure('production', function(){ - this.enable('view cache'); - }); - - // register error handlers on "listening" - // so that they disregard definition position. - this.on('listening', this.registerErrorHandlers.bind(this)); - - // route manipulation methods - methods.forEach(function(method){ - self.lookup[method] = function(path){ - return self.routes.lookup(method, path); - }; - - self.match[method] = function(path){ - return self.routes.match(method, path); - }; - - self.remove[method] = function(path){ - return self.routes.lookup(method, path).remove(); - }; - }); - - // del -> delete - self.lookup.del = self.lookup.delete; - self.match.del = self.match.delete; - self.remove.del = self.remove.delete; -}; - -/** - * Remove routes matching the given `path`. - * - * @param {Route} path - * @return {Boolean} - * @api public - */ - -app.remove = function(path){ - return this.routes.lookup('all', path).remove(); -}; - -/** - * Lookup routes defined with a path - * equivalent to `path`. - * - * @param {Stirng} path - * @return {Array} - * @api public - */ - -app.lookup = function(path){ - return this.routes.lookup('all', path); -}; - -/** - * Lookup routes matching the given `url`. - * - * @param {Stirng} url - * @return {Array} - * @api public - */ - -app.match = function(url){ - return this.routes.match('all', url); -}; - -/** - * When using the vhost() middleware register error handlers. - */ - -app.onvhost = function(){ - this.registerErrorHandlers(); -}; - -/** - * Register error handlers. - * - * @return {Server} for chaining - * @api public - */ - -app.registerErrorHandlers = function(){ - this.errorHandlers.forEach(function(fn){ - this.use(function(err, req, res, next){ - fn.apply(this, arguments); - }); - }, this); - return this; -}; - -/** - * Proxy `connect.HTTPServer#use()` to apply settings to - * mounted applications. - * - * @param {String|Function|Server} route - * @param {Function|Server} middleware - * @return {Server} for chaining - * @api public - */ - -app.use = function(route, middleware){ - var app, base, handle; - - if ('string' != typeof route) { - middleware = route, route = '/'; - } - - // express app - if (middleware.handle && middleware.set) app = middleware; - - // restore .app property on req and res - if (app) { - app.route = route; - middleware = function(req, res, next) { - var orig = req.app; - app.handle(req, res, function(err){ - req.app = res.app = orig; - next(err); - }); - }; - } - - connect.HTTPServer.prototype.use.call(this, route, middleware); - - // mounted an app, invoke the hook - // and adjust some settings - if (app) { - base = this.set('basepath') || this.route; - if ('/' == base) base = ''; - base = base + (app.set('basepath') || app.route); - app.set('basepath', base); - app.parent = this; - if (app.__mounted) app.__mounted.call(app, this); - } - - return this; -}; - -/** - * Assign a callback `fn` which is called - * when this `Server` is passed to `Server#use()`. - * - * Examples: - * - * var app = express.createServer() - * , blog = express.createServer(); - * - * blog.mounted(function(parent){ - * // parent is app - * // "this" is blog - * }); - * - * app.use(blog); - * - * @param {Function} fn - * @return {Server} for chaining - * @api public - */ - -app.mounted = function(fn){ - this.__mounted = fn; - return this; -}; - -/** - * See: view.register. - * - * @return {Server} for chaining - * @api public - */ - -app.register = function(){ - view.register.apply(this, arguments); - return this; -}; - -/** - * Register the given view helpers `obj`. This method - * can be called several times to apply additional helpers. - * - * @param {Object} obj - * @return {Server} for chaining - * @api public - */ - -app.helpers = -app.locals = function(obj){ - utils.merge(this._locals, obj); - return this; -}; - -/** - * Register the given dynamic view helpers `obj`. This method - * can be called several times to apply additional helpers. - * - * @param {Object} obj - * @return {Server} for chaining - * @api public - */ - -app.dynamicHelpers = function(obj){ - utils.merge(this.dynamicViewHelpers, obj); - return this; -}; - -/** - * Map the given param placeholder `name`(s) to the given callback(s). - * - * Param mapping is used to provide pre-conditions to routes - * which us normalized placeholders. This callback has the same - * signature as regular middleware, for example below when ":userId" - * is used this function will be invoked in an attempt to load the user. - * - * app.param('userId', function(req, res, next, id){ - * User.find(id, function(err, user){ - * if (err) { - * next(err); - * } else if (user) { - * req.user = user; - * next(); - * } else { - * next(new Error('failed to load user')); - * } - * }); - * }); - * - * Passing a single function allows you to map logic - * to the values passed to `app.param()`, for example - * this is useful to provide coercion support in a concise manner. - * - * The following example maps regular expressions to param values - * ensuring that they match, otherwise passing control to the next - * route: - * - * app.param(function(name, regexp){ - * if (regexp instanceof RegExp) { - * return function(req, res, next, val){ - * var captures; - * if (captures = regexp.exec(String(val))) { - * req.params[name] = captures; - * next(); - * } else { - * next('route'); - * } - * } - * } - * }); - * - * We can now use it as shown below, where "/commit/:commit" expects - * that the value for ":commit" is at 5 or more digits. The capture - * groups are then available as `req.params.commit` as we defined - * in the function above. - * - * app.param('commit', /^\d{5,}$/); - * - * For more of this useful functionality take a look - * at [express-params](http://github.com/visionmedia/express-params). - * - * @param {String|Array|Function} name - * @param {Function} fn - * @return {Server} for chaining - * @api public - */ - -app.param = function(name, fn){ - var self = this - , fns = [].slice.call(arguments, 1); - - // array - if (Array.isArray(name)) { - name.forEach(function(name){ - fns.forEach(function(fn){ - self.param(name, fn); - }); - }); - // param logic - } else if ('function' == typeof name) { - this.routes.param(name); - // single - } else { - if (':' == name[0]) name = name.substr(1); - fns.forEach(function(fn){ - self.routes.param(name, fn); - }); - } - - return this; -}; - -/** - * Assign a custom exception handler callback `fn`. - * These handlers are always _last_ in the middleware stack. - * - * @param {Function} fn - * @return {Server} for chaining - * @api public - */ - -app.error = function(fn){ - this.errorHandlers.push(fn); - return this; -}; - -/** - * Register the given callback `fn` for the given `type`. - * - * @param {String} type - * @param {Function} fn - * @return {Server} for chaining - * @api public - */ - -app.is = function(type, fn){ - if (!fn) return this.isCallbacks[type]; - this.isCallbacks[type] = fn; - return this; -}; - -/** - * Assign `setting` to `val`, or return `setting`'s value. - * Mounted servers inherit their parent server's settings. - * - * @param {String} setting - * @param {String} val - * @return {Server|Mixed} for chaining, or the setting value - * @api public - */ - -app.set = function(setting, val){ - if (val === undefined) { - if (this.settings.hasOwnProperty(setting)) { - return this.settings[setting]; - } else if (this.parent) { - return this.parent.set(setting); - } - } else { - this.settings[setting] = val; - return this; - } -}; - -/** - * Check if `setting` is enabled. - * - * @param {String} setting - * @return {Boolean} - * @api public - */ - -app.enabled = function(setting){ - return !!this.set(setting); -}; - -/** - * Check if `setting` is disabled. - * - * @param {String} setting - * @return {Boolean} - * @api public - */ - -app.disabled = function(setting){ - return !this.set(setting); -}; - -/** - * Enable `setting`. - * - * @param {String} setting - * @return {Server} for chaining - * @api public - */ - -app.enable = function(setting){ - return this.set(setting, true); -}; - -/** - * Disable `setting`. - * - * @param {String} setting - * @return {Server} for chaining - * @api public - */ - -app.disable = function(setting){ - return this.set(setting, false); -}; - -/** - * Redirect `key` to `url`. - * - * @param {String} key - * @param {String} url - * @return {Server} for chaining - * @api public - */ - -app.redirect = function(key, url){ - this.redirects[key] = url; - return this; -}; - -/** - * Configure callback for zero or more envs, - * when no env is specified that callback will - * be invoked for all environments. Any combination - * can be used multiple times, in any order desired. - * - * Examples: - * - * app.configure(function(){ - * // executed for all envs - * }); - * - * app.configure('stage', function(){ - * // executed staging env - * }); - * - * app.configure('stage', 'production', function(){ - * // executed for stage and production - * }); - * - * @param {String} env... - * @param {Function} fn - * @return {Server} for chaining - * @api public - */ - -app.configure = function(env, fn){ - var envs = 'all' - , args = toArray(arguments); - fn = args.pop(); - if (args.length) envs = args; - if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this); - return this; -}; - -/** - * Delegate `.VERB(...)` calls to `.route(VERB, ...)`. - */ - -methods.forEach(function(method){ - app[method] = function(path){ - if (1 == arguments.length) return this.routes.lookup(method, path); - var args = [method].concat(toArray(arguments)); - if (!this.__usedRouter) this.use(this.router); - return this.routes._route.apply(this.routes, args); - } -}); - -/** - * Special-cased "all" method, applying the given route `path`, - * middleware, and callback to _every_ HTTP method. - * - * @param {String} path - * @param {Function} ... - * @return {Server} for chaining - * @api public - */ - -app.all = function(path){ - var args = arguments; - if (1 == args.length) return this.routes.lookup('all', path); - methods.forEach(function(method){ - if ('all' == method || 'del' == method) return; - app[method].apply(this, args); - }, this); - return this; -}; - -// del -> delete alias - -app.del = app.delete; - diff --git a/frontend/express/node_modules/express/lib/https.js b/frontend/express/node_modules/express/lib/https.js deleted file mode 100644 index 8a8c008ae26..00000000000 --- a/frontend/express/node_modules/express/lib/https.js +++ /dev/null @@ -1,52 +0,0 @@ - -/*! - * Express - HTTPSServer - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var connect = require('connect') - , HTTPServer = require('./http') - , https = require('https'); - -/** - * Expose `HTTPSServer`. - */ - -exports = module.exports = HTTPSServer; - -/** - * Server proto. - */ - -var app = HTTPSServer.prototype; - -/** - * Initialize a new `HTTPSServer` with the - * given `options`, and optional `middleware`. - * - * @param {Object} options - * @param {Array} middleware - * @api public - */ - -function HTTPSServer(options, middleware){ - connect.HTTPSServer.call(this, options, []); - this.init(middleware); -}; - -/** - * Inherit from `connect.HTTPSServer`. - */ - -app.__proto__ = connect.HTTPSServer.prototype; - -// mixin HTTPServer methods - -Object.keys(HTTPServer.prototype).forEach(function(method){ - app[method] = HTTPServer.prototype[method]; -}); diff --git a/frontend/express/node_modules/express/lib/middleware.js b/frontend/express/node_modules/express/lib/middleware.js deleted file mode 100644 index 308c5bb6d55..00000000000 --- a/frontend/express/node_modules/express/lib/middleware.js +++ /dev/null @@ -1,33 +0,0 @@ - -/** - * Module dependencies. - */ - -var utils = require('./utils'); - -/** - * Initialization middleware, exposing the - * request and response to eachother, as well - * as defaulting the X-Powered-By header field. - * - * @param {Function} app - * @return {Function} - * @api private - */ - -exports.init = function(app){ - return function expressInit(req, res, next){ - req.app = res.app = app; - if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express'); - req.res = res; - res.req = req; - req.next = next; - - req.__proto__ = app.request; - res.__proto__ = app.response; - - res.locals = res.locals || utils.locals(res); - - next(); - } -}; diff --git a/frontend/express/node_modules/express/lib/request.js b/frontend/express/node_modules/express/lib/request.js deleted file mode 100644 index 1205c6c25af..00000000000 --- a/frontend/express/node_modules/express/lib/request.js +++ /dev/null @@ -1,527 +0,0 @@ - -/** - * Module dependencies. - */ - -var http = require('http') - , utils = require('./utils') - , connect = require('connect') - , fresh = require('fresh') - , parseRange = require('range-parser') - , parse = connect.utils.parseUrl - , mime = connect.mime; - -/** - * Request prototype. - */ - -var req = exports = module.exports = { - __proto__: http.IncomingMessage.prototype -}; - -/** - * Return request header. - * - * The `Referrer` header field is special-cased, - * both `Referrer` and `Referer` are interchangeable. - * - * Examples: - * - * req.get('Content-Type'); - * // => "text/plain" - * - * req.get('content-type'); - * // => "text/plain" - * - * req.get('Something'); - * // => undefined - * - * Aliased as `req.header()`. - * - * @param {String} name - * @return {String} - * @api public - */ - -req.get = -req.header = function(name){ - switch (name = name.toLowerCase()) { - case 'referer': - case 'referrer': - return this.headers.referrer - || this.headers.referer; - default: - return this.headers[name]; - } -}; - -/** - * Check if the given `type(s)` is acceptable, returning - * the best match when true, otherwise `undefined`, in which - * case you should respond with 406 "Not Acceptable". - * - * The `type` value may be a single mime type string - * such as "application/json", the extension name - * such as "json", a comma-delimted list such as "json, html, text/plain", - * or an array `["json", "html", "text/plain"]`. When a list - * or array is given the _best_ match, if any is returned. - * - * Examples: - * - * // Accept: text/html - * req.accepts('html'); - * // => "html" - * - * // Accept: text/*, application/json - * req.accepts('html'); - * // => "html" - * req.accepts('text/html'); - * // => "text/html" - * req.accepts('json, text'); - * // => "json" - * req.accepts('application/json'); - * // => "application/json" - * - * // Accept: text/*, application/json - * req.accepts('image/png'); - * req.accepts('png'); - * // => undefined - * - * // Accept: text/*;q=.5, application/json - * req.accepts(['html', 'json']); - * req.accepts('html, json'); - * // => "json" - * - * @param {String|Array} type(s) - * @return {String} - * @api public - */ - -req.accepts = function(type){ - return utils.accepts(type, this.get('Accept')); -}; - -/** - * Check if the given `encoding` is accepted. - * - * @param {String} encoding - * @return {Boolean} - * @api public - */ - -req.acceptsEncoding = function(encoding){ - return ~this.acceptedEncodings.indexOf(encoding); -}; - -/** - * Check if the given `charset` is acceptable, - * otherwise you should respond with 406 "Not Acceptable". - * - * @param {String} charset - * @return {Boolean} - * @api public - */ - -req.acceptsCharset = function(charset){ - var accepted = this.acceptedCharsets; - return accepted.length - ? ~accepted.indexOf(charset) - : true; -}; - -/** - * Check if the given `lang` is acceptable, - * otherwise you should respond with 406 "Not Acceptable". - * - * @param {String} lang - * @return {Boolean} - * @api public - */ - -req.acceptsLanguage = function(lang){ - var accepted = this.acceptedLanguages; - return accepted.length - ? ~accepted.indexOf(lang) - : true; -}; - -/** - * Parse Range header field, - * capping to the given `size`. - * - * Unspecified ranges such as "0-" require - * knowledge of your resource length. In - * the case of a byte range this is of course - * the total number of bytes. If the Range - * header field is not given `null` is returned, - * `-1` when unsatisfiable, `-2` when syntactically invalid. - * - * NOTE: remember that ranges are inclusive, so - * for example "Range: users=0-3" should respond - * with 4 users when available, not 3. - * - * @param {Number} size - * @return {Array} - * @api public - */ - -req.range = function(size){ - var range = this.get('Range'); - if (!range) return; - return parseRange(size, range); -}; - -/** - * Return an array of encodings. - * - * Examples: - * - * ['gzip', 'deflate'] - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('acceptedEncodings', function(){ - var accept = this.get('Accept-Encoding'); - return accept - ? accept.trim().split(/ *, */) - : []; -}); - -/** - * Return an array of Accepted media types - * ordered from highest quality to lowest. - * - * Examples: - * - * [ { value: 'application/json', - * quality: 1, - * type: 'application', - * subtype: 'json' }, - * { value: 'text/html', - * quality: 0.5, - * type: 'text', - * subtype: 'html' } ] - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('accepted', function(){ - var accept = this.get('Accept'); - return accept - ? utils.parseAccept(accept) - : []; -}); - -/** - * Return an array of Accepted languages - * ordered from highest quality to lowest. - * - * Examples: - * - * Accept-Language: en;q=.5, en-us - * ['en-us', 'en'] - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('acceptedLanguages', function(){ - var accept = this.get('Accept-Language'); - return accept - ? utils - .parseParams(accept) - .map(function(obj){ - return obj.value; - }) - : []; -}); - -/** - * Return an array of Accepted charsets - * ordered from highest quality to lowest. - * - * Examples: - * - * Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8 - * ['unicode-1-1', 'iso-8859-5'] - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('acceptedCharsets', function(){ - var accept = this.get('Accept-Charset'); - return accept - ? utils - .parseParams(accept) - .map(function(obj){ - return obj.value; - }) - : []; -}); - -/** - * Return the value of param `name` when present or `defaultValue`. - * - * - Checks route placeholders, ex: _/user/:id_ - * - Checks body params, ex: id=12, {"id":12} - * - Checks query string params, ex: ?id=12 - * - * To utilize request bodies, `req.body` - * should be an object. This can be done by using - * the `connect.bodyParser()` middleware. - * - * @param {String} name - * @param {Mixed} [defaultValue] - * @return {String} - * @api public - */ - -req.param = function(name, defaultValue){ - var params = this.params || {}; - var body = this.body || {}; - var query = this.query || {}; - if (null != params[name] && params.hasOwnProperty(name)) return params[name]; - if (null != body[name]) return body[name]; - if (null != query[name]) return query[name]; - return defaultValue; -}; - -/** - * Check if the incoming request contains the "Content-Type" - * header field, and it contains the give mime `type`. - * - * Examples: - * - * // With Content-Type: text/html; charset=utf-8 - * req.is('html'); - * req.is('text/html'); - * req.is('text/*'); - * // => true - * - * // When Content-Type is application/json - * req.is('json'); - * req.is('application/json'); - * req.is('application/*'); - * // => true - * - * req.is('html'); - * // => false - * - * @param {String} type - * @return {Boolean} - * @api public - */ - -req.is = function(type){ - var ct = this.get('Content-Type'); - if (!ct) return false; - ct = ct.split(';')[0]; - if (!~type.indexOf('/')) type = mime.lookup(type); - if (~type.indexOf('*')) { - type = type.split('/'); - ct = ct.split('/'); - if ('*' == type[0] && type[1] == ct[1]) return true; - if ('*' == type[1] && type[0] == ct[0]) return true; - return false; - } - return !! ~ct.indexOf(type); -}; - -/** - * Return the protocol string "http" or "https" - * when requested with TLS. When the "trust proxy" - * setting is enabled the "X-Forwarded-Proto" header - * field will be trusted. If you're running behind - * a reverse proxy that supplies https for you this - * may be enabled. - * - * @return {String} - * @api public - */ - -req.__defineGetter__('protocol', function(){ - var trustProxy = this.app.get('trust proxy'); - return this.connection.encrypted - ? 'https' - : trustProxy - ? (this.get('X-Forwarded-Proto') || 'http') - : 'http'; -}); - -/** - * Short-hand for: - * - * req.protocol == 'https' - * - * @return {Boolean} - * @api public - */ - -req.__defineGetter__('secure', function(){ - return 'https' == this.protocol; -}); - -/** - * Return the remote address, or when - * "trust proxy" is `true` return - * the upstream addr. - * - * @return {String} - * @api public - */ - -req.__defineGetter__('ip', function(){ - return this.ips[0] || this.connection.remoteAddress; -}); - -/** - * When "trust proxy" is `true`, parse - * the "X-Forwarded-For" ip address list. - * - * For example if the value were "client, proxy1, proxy2" - * you would receive the array `["client", "proxy1", "proxy2"]` - * where "proxy2" is the furthest down-stream. - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('ips', function(){ - var trustProxy = this.app.get('trust proxy'); - var val = this.get('X-Forwarded-For'); - return trustProxy && val - ? val.split(/ *, */) - : []; -}); - -/** - * Return basic auth credentials. - * - * Examples: - * - * // http://tobi:hello@example.com - * req.auth - * // => { username: 'tobi', password: 'hello' } - * - * @return {Object} or undefined - * @api public - */ - -req.__defineGetter__('auth', function(){ - // missing - var auth = this.get('Authorization'); - if (!auth) return; - - // malformed - var parts = auth.split(' '); - if ('basic' != parts[0].toLowerCase()) return; - if (!parts[1]) return; - auth = parts[1]; - - // credentials - auth = new Buffer(auth, 'base64').toString().match(/^([^:]*):(.*)$/); - if (!auth) return; - return { username: auth[1], password: auth[2] }; -}); - -/** - * Return subdomains as an array. - * - * Subdomains are the dot-separated parts of the host before the main domain of - * the app. By default, the domain of the app is assumed to be the last two - * parts of the host. This can be changed by setting "subdomain offset". - * - * For example, if the domain is "tobi.ferrets.example.com": - * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`. - * If "subdomain offset" is 3, req.subdomains is `["tobi"]`. - * - * @return {Array} - * @api public - */ - -req.__defineGetter__('subdomains', function(){ - var offset = this.app.get('subdomain offset'); - return (this.host || '') - .split('.') - .reverse() - .slice(offset); -}); - -/** - * Short-hand for `url.parse(req.url).pathname`. - * - * @return {String} - * @api public - */ - -req.__defineGetter__('path', function(){ - return parse(this).pathname; -}); - -/** - * Parse the "Host" header field hostname. - * - * @return {String} - * @api public - */ - -req.__defineGetter__('host', function(){ - var trustProxy = this.app.get('trust proxy'); - var host = trustProxy && this.get('X-Forwarded-Host'); - host = host || this.get('Host'); - if (!host) return; - return host.split(':')[0]; -}); - -/** - * Check if the request is fresh, aka - * Last-Modified and/or the ETag - * still match. - * - * @return {Boolean} - * @api public - */ - -req.__defineGetter__('fresh', function(){ - var method = this.method; - var s = this.res.statusCode; - - // GET or HEAD for weak freshness validation only - if ('GET' != method && 'HEAD' != method) return false; - - // 2xx or 304 as per rfc2616 14.26 - if ((s >= 200 && s < 300) || 304 == s) { - return fresh(this.headers, this.res._headers); - } - - return false; -}); - -/** - * Check if the request is stale, aka - * "Last-Modified" and / or the "ETag" for the - * resource has changed. - * - * @return {Boolean} - * @api public - */ - -req.__defineGetter__('stale', function(){ - return !this.fresh; -}); - -/** - * Check if the request was an _XMLHttpRequest_. - * - * @return {Boolean} - * @api public - */ - -req.__defineGetter__('xhr', function(){ - var val = this.get('X-Requested-With') || ''; - return 'xmlhttprequest' == val.toLowerCase(); -}); diff --git a/frontend/express/node_modules/express/lib/response.js b/frontend/express/node_modules/express/lib/response.js deleted file mode 100644 index 68b7266b927..00000000000 --- a/frontend/express/node_modules/express/lib/response.js +++ /dev/null @@ -1,757 +0,0 @@ -/** - * Module dependencies. - */ - -var http = require('http') - , path = require('path') - , connect = require('connect') - , utils = connect.utils - , sign = require('cookie-signature').sign - , normalizeType = require('./utils').normalizeType - , normalizeTypes = require('./utils').normalizeTypes - , etag = require('./utils').etag - , statusCodes = http.STATUS_CODES - , cookie = require('cookie') - , send = require('send') - , mime = connect.mime - , basename = path.basename - , extname = path.extname - , join = path.join; - -/** - * Response prototype. - */ - -var res = module.exports = { - __proto__: http.ServerResponse.prototype -}; - -/** - * Set status `code`. - * - * @param {Number} code - * @return {ServerResponse} - * @api public - */ - -res.status = function(code){ - this.statusCode = code; - return this; -}; - -/** - * Set Link header field with the given `links`. - * - * Examples: - * - * res.links({ - * next: 'http://api.example.com/users?page=2', - * last: 'http://api.example.com/users?page=5' - * }); - * - * @param {Object} links - * @return {ServerResponse} - * @api public - */ - -res.links = function(links){ - return this.set('Link', Object.keys(links).map(function(rel){ - return '<' + links[rel] + '>; rel="' + rel + '"'; - }).join(', ')); -}; - -/** - * Send a response. - * - * Examples: - * - * res.send(new Buffer('wahoo')); - * res.send({ some: 'json' }); - * res.send('

    some html

    '); - * res.send(404, 'Sorry, cant find that'); - * res.send(404); - * - * @param {Mixed} body or status - * @param {Mixed} body - * @return {ServerResponse} - * @api public - */ - -res.send = function(body){ - var req = this.req; - var head = 'HEAD' == req.method; - var len; - - // allow status / body - if (2 == arguments.length) { - // res.send(body, status) backwards compat - if ('number' != typeof body && 'number' == typeof arguments[1]) { - this.statusCode = arguments[1]; - } else { - this.statusCode = body; - body = arguments[1]; - } - } - - switch (typeof body) { - // response status - case 'number': - this.get('Content-Type') || this.type('txt'); - this.statusCode = body; - body = http.STATUS_CODES[body]; - break; - // string defaulting to html - case 'string': - if (!this.get('Content-Type')) { - this.charset = this.charset || 'utf-8'; - this.type('html'); - } - break; - case 'boolean': - case 'object': - if (null == body) { - body = ''; - } else if (Buffer.isBuffer(body)) { - this.get('Content-Type') || this.type('bin'); - } else { - return this.json(body); - } - break; - } - - // populate Content-Length - if (undefined !== body && !this.get('Content-Length')) { - this.set('Content-Length', len = Buffer.isBuffer(body) - ? body.length - : Buffer.byteLength(body)); - } - - // ETag support - // TODO: W/ support - if (len > 1024 && 'GET' == req.method) { - if (!this.get('ETag')) { - this.set('ETag', etag(body)); - } - } - - // freshness - if (req.fresh) this.statusCode = 304; - - // strip irrelevant headers - if (204 == this.statusCode || 304 == this.statusCode) { - this.removeHeader('Content-Type'); - this.removeHeader('Content-Length'); - this.removeHeader('Transfer-Encoding'); - body = ''; - } - - // respond - this.end(head ? null : body); - return this; -}; - -/** - * Send JSON response. - * - * Examples: - * - * res.json(null); - * res.json({ user: 'tj' }); - * res.json(500, 'oh noes!'); - * res.json(404, 'I dont have that'); - * - * @param {Mixed} obj or status - * @param {Mixed} obj - * @return {ServerResponse} - * @api public - */ - -res.json = function(obj){ - // allow status / body - if (2 == arguments.length) { - // res.json(body, status) backwards compat - if ('number' == typeof arguments[1]) { - this.statusCode = arguments[1]; - } else { - this.statusCode = obj; - obj = arguments[1]; - } - } - - // settings - var app = this.app; - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = JSON.stringify(obj, replacer, spaces); - - // content-type - this.charset = this.charset || 'utf-8'; - this.get('Content-Type') || this.set('Content-Type', 'application/json'); - - return this.send(body); -}; - -/** - * Send JSON response with JSONP callback support. - * - * Examples: - * - * res.jsonp(null); - * res.jsonp({ user: 'tj' }); - * res.jsonp(500, 'oh noes!'); - * res.jsonp(404, 'I dont have that'); - * - * @param {Mixed} obj or status - * @param {Mixed} obj - * @return {ServerResponse} - * @api public - */ - -res.jsonp = function(obj){ - // allow status / body - if (2 == arguments.length) { - // res.json(body, status) backwards compat - if ('number' == typeof arguments[1]) { - this.statusCode = arguments[1]; - } else { - this.statusCode = obj; - obj = arguments[1]; - } - } - - // settings - var app = this.app; - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = JSON.stringify(obj, replacer, spaces) - .replace(/\u2028/g, '\\u2028') - .replace(/\u2029/g, '\\u2029'); - var callback = this.req.query[app.get('jsonp callback name')]; - - // content-type - this.charset = this.charset || 'utf-8'; - this.set('Content-Type', 'application/json'); - - // jsonp - if (callback) { - this.set('Content-Type', 'text/javascript'); - var cb = callback.replace(/[^\[\]\w$.]/g, ''); - body = cb + ' && ' + cb + '(' + body + ');'; - } - - return this.send(body); -}; - -/** - * Transfer the file at the given `path`. - * - * Automatically sets the _Content-Type_ response header field. - * The callback `fn(err)` is invoked when the transfer is complete - * or when an error occurs. Be sure to check `res.sentHeader` - * if you wish to attempt responding, as the header and some data - * may have already been transferred. - * - * Options: - * - * - `maxAge` defaulting to 0 - * - `root` root directory for relative filenames - * - * Examples: - * - * The following example illustrates how `res.sendfile()` may - * be used as an alternative for the `static()` middleware for - * dynamic situations. The code backing `res.sendfile()` is actually - * the same code, so HTTP cache support etc is identical. - * - * app.get('/user/:uid/photos/:file', function(req, res){ - * var uid = req.params.uid - * , file = req.params.file; - * - * req.user.mayViewFilesFrom(uid, function(yes){ - * if (yes) { - * res.sendfile('/uploads/' + uid + '/' + file); - * } else { - * res.send(403, 'Sorry! you cant see that.'); - * } - * }); - * }); - * - * @param {String} path - * @param {Object|Function} options or fn - * @param {Function} fn - * @api public - */ - -res.sendfile = function(path, options, fn){ - var self = this - , req = self.req - , next = this.req.next - , options = options || {} - , done; - - // support function as second arg - if ('function' == typeof options) { - fn = options; - options = {}; - } - - // socket errors - req.socket.on('error', error); - - // errors - function error(err) { - if (done) return; - done = true; - - // clean up - cleanup(); - if (!self.headerSent) self.removeHeader('Content-Disposition'); - - // callback available - if (fn) return fn(err); - - // list in limbo if there's no callback - if (self.headerSent) return; - - // delegate - next(err); - } - - // streaming - function stream() { - if (done) return; - cleanup(); - if (fn) self.on('finish', fn); - } - - // cleanup - function cleanup() { - req.socket.removeListener('error', error); - } - - // transfer - var file = send(req, path); - if (options.root) file.root(options.root); - file.maxage(options.maxAge || 0); - file.on('error', error); - file.on('directory', next); - file.on('stream', stream); - file.pipe(this); - this.on('finish', cleanup); -}; - -/** - * Transfer the file at the given `path` as an attachment. - * - * Optionally providing an alternate attachment `filename`, - * and optional callback `fn(err)`. The callback is invoked - * when the data transfer is complete, or when an error has - * ocurred. Be sure to check `res.headerSent` if you plan to respond. - * - * This method uses `res.sendfile()`. - * - * @param {String} path - * @param {String|Function} filename or fn - * @param {Function} fn - * @api public - */ - -res.download = function(path, filename, fn){ - // support function as second arg - if ('function' == typeof filename) { - fn = filename; - filename = null; - } - - filename = filename || path; - this.set('Content-Disposition', 'attachment; filename="' + basename(filename) + '"'); - return this.sendfile(path, fn); -}; - -/** - * Set _Content-Type_ response header with `type` through `mime.lookup()` - * when it does not contain "/", or set the Content-Type to `type` otherwise. - * - * Examples: - * - * res.type('.html'); - * res.type('html'); - * res.type('json'); - * res.type('application/json'); - * res.type('png'); - * - * @param {String} type - * @return {ServerResponse} for chaining - * @api public - */ - -res.contentType = -res.type = function(type){ - return this.set('Content-Type', ~type.indexOf('/') - ? type - : mime.lookup(type)); -}; - -/** - * Respond to the Acceptable formats using an `obj` - * of mime-type callbacks. - * - * This method uses `req.accepted`, an array of - * acceptable types ordered by their quality values. - * When "Accept" is not present the _first_ callback - * is invoked, otherwise the first match is used. When - * no match is performed the server responds with - * 406 "Not Acceptable". - * - * Content-Type is set for you, however if you choose - * you may alter this within the callback using `res.type()` - * or `res.set('Content-Type', ...)`. - * - * res.format({ - * 'text/plain': function(){ - * res.send('hey'); - * }, - * - * 'text/html': function(){ - * res.send('

    hey

    '); - * }, - * - * 'appliation/json': function(){ - * res.send({ message: 'hey' }); - * } - * }); - * - * In addition to canonicalized MIME types you may - * also use extnames mapped to these types: - * - * res.format({ - * text: function(){ - * res.send('hey'); - * }, - * - * html: function(){ - * res.send('

    hey

    '); - * }, - * - * json: function(){ - * res.send({ message: 'hey' }); - * } - * }); - * - * By default Express passes an `Error` - * with a `.status` of 406 to `next(err)` - * if a match is not made. If you provide - * a `.default` callback it will be invoked - * instead. - * - * @param {Object} obj - * @return {ServerResponse} for chaining - * @api public - */ - -res.format = function(obj){ - var req = this.req - , next = req.next; - - var fn = obj.default; - if (fn) delete obj.default; - var keys = Object.keys(obj); - - var key = req.accepts(keys); - - this.set('Vary', 'Accept'); - - if (key) { - this.set('Content-Type', normalizeType(key).value); - obj[key](req, this, next); - } else if (fn) { - fn(); - } else { - var err = new Error('Not Acceptable'); - err.status = 406; - err.types = normalizeTypes(keys).map(function(o){ return o.value }); - next(err); - } - - return this; -}; - -/** - * Set _Content-Disposition_ header to _attachment_ with optional `filename`. - * - * @param {String} filename - * @return {ServerResponse} - * @api public - */ - -res.attachment = function(filename){ - if (filename) this.type(extname(filename)); - this.set('Content-Disposition', filename - ? 'attachment; filename="' + basename(filename) + '"' - : 'attachment'); - return this; -}; - -/** - * Set header `field` to `val`, or pass - * an object of header fields. - * - * Examples: - * - * res.set('Foo', ['bar', 'baz']); - * res.set('Accept', 'application/json'); - * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' }); - * - * Aliased as `res.header()`. - * - * @param {String|Object|Array} field - * @param {String} val - * @return {ServerResponse} for chaining - * @api public - */ - -res.set = -res.header = function(field, val){ - if (2 == arguments.length) { - if (Array.isArray(val)) val = val.map(String); - else val = String(val); - this.setHeader(field, val); - } else { - for (var key in field) { - this.set(key, field[key]); - } - } - return this; -}; - -/** - * Get value for header `field`. - * - * @param {String} field - * @return {String} - * @api public - */ - -res.get = function(field){ - return this.getHeader(field); -}; - -/** - * Clear cookie `name`. - * - * @param {String} name - * @param {Object} options - * @param {ServerResponse} for chaining - * @api public - */ - -res.clearCookie = function(name, options){ - var opts = { expires: new Date(1), path: '/' }; - return this.cookie(name, '', options - ? utils.merge(opts, options) - : opts); -}; - -/** - * Set cookie `name` to `val`, with the given `options`. - * - * Options: - * - * - `maxAge` max-age in milliseconds, converted to `expires` - * - `signed` sign the cookie - * - `path` defaults to "/" - * - * Examples: - * - * // "Remember Me" for 15 minutes - * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }); - * - * // save as above - * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true }) - * - * @param {String} name - * @param {String|Object} val - * @param {Options} options - * @api public - */ - -res.cookie = function(name, val, options){ - options = utils.merge({}, options); - var secret = this.req.secret; - var signed = options.signed; - if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies'); - if ('number' == typeof val) val = val.toString(); - if ('object' == typeof val) val = 'j:' + JSON.stringify(val); - if (signed) val = 's:' + sign(val, secret); - if ('maxAge' in options) { - options.expires = new Date(Date.now() + options.maxAge); - options.maxAge /= 1000; - } - if (null == options.path) options.path = '/'; - this.set('Set-Cookie', cookie.serialize(name, String(val), options)); - return this; -}; - - -/** - * Set the location header to `url`. - * - * The given `url` can also be the name of a mapped url, for - * example by default express supports "back" which redirects - * to the _Referrer_ or _Referer_ headers or "/". - * - * Examples: - * - * res.location('/foo/bar').; - * res.location('http://example.com'); - * res.location('../login'); // /blog/post/1 -> /blog/login - * - * Mounting: - * - * When an application is mounted and `res.location()` - * is given a path that does _not_ lead with "/" it becomes - * relative to the mount-point. For example if the application - * is mounted at "/blog", the following would become "/blog/login". - * - * res.location('login'); - * - * While the leading slash would result in a location of "/login": - * - * res.location('/login'); - * - * @param {String} url - * @api public - */ - -res.location = function(url){ - var app = this.app - , req = this.req; - - // setup redirect map - var map = { back: req.get('Referrer') || '/' }; - - // perform redirect - url = map[url] || url; - - // relative - if (!~url.indexOf('://') && 0 != url.indexOf('//')) { - var path - - // relative to path - if ('.' == url[0]) { - path = req.originalUrl.split('?')[0] - url = path + ('/' == path[path.length - 1] ? '' : '/') + url; - // relative to mount-point - } else if ('/' != url[0]) { - path = app.path(); - url = path + '/' + url; - } - } - - // Respond - this.set('Location', url); - return this; -}; - -/** - * Redirect to the given `url` with optional response `status` - * defaulting to 302. - * - * The resulting `url` is determined by `res.location()`, so - * it will play nicely with mounted apps, relative paths, - * `"back"` etc. - * - * Examples: - * - * res.redirect('/foo/bar'); - * res.redirect('http://example.com'); - * res.redirect(301, 'http://example.com'); - * res.redirect('http://example.com', 301); - * res.redirect('../login'); // /blog/post/1 -> /blog/login - * - * @param {String} url - * @param {Number} code - * @api public - */ - -res.redirect = function(url){ - var app = this.app - , head = 'HEAD' == this.req.method - , status = 302 - , body; - - // allow status / url - if (2 == arguments.length) { - if ('number' == typeof url) { - status = url; - url = arguments[1]; - } else { - status = arguments[1]; - } - } - - // Set location header - this.location(url); - url = this.get('Location'); - - // Support text/{plain,html} by default - this.format({ - text: function(){ - body = statusCodes[status] + '. Redirecting to ' + encodeURI(url); - }, - - html: function(){ - var u = utils.escape(url); - body = '

    ' + statusCodes[status] + '. Redirecting to ' + u + '

    '; - }, - - default: function(){ - body = ''; - } - }); - - // Respond - this.statusCode = status; - this.set('Content-Length', Buffer.byteLength(body)); - this.end(head ? null : body); -}; - -/** - * Render `view` with the given `options` and optional callback `fn`. - * When a callback function is given a response will _not_ be made - * automatically, otherwise a response of _200_ and _text/html_ is given. - * - * Options: - * - * - `cache` boolean hinting to the engine it should cache - * - `filename` filename of the view being rendered - * - * @param {String} view - * @param {Object|Function} options or callback function - * @param {Function} fn - * @api public - */ - -res.render = function(view, options, fn){ - var self = this - , options = options || {} - , req = this.req - , app = req.app; - - // support callback function as second arg - if ('function' == typeof options) { - fn = options, options = {}; - } - - // merge res.locals - options._locals = self.locals; - - // default callback to respond - fn = fn || function(err, str){ - if (err) return req.next(err); - self.send(str); - }; - - // render - app.render(view, options, fn); -}; diff --git a/frontend/express/node_modules/express/lib/router/collection.js b/frontend/express/node_modules/express/lib/router/collection.js deleted file mode 100644 index 991a9a239c3..00000000000 --- a/frontend/express/node_modules/express/lib/router/collection.js +++ /dev/null @@ -1,53 +0,0 @@ - -/*! - * Express - router - Collection - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Expose `Collection`. - */ - -module.exports = Collection; - -/** - * Initialize a new route `Collection` - * with the given `router`. - * - * @param {Router} router - * @api private - */ - -function Collection(router) { - Array.apply(this, arguments); - this.router = router; -} - -/** - * Inherit from `Array.prototype`. - */ - -Collection.prototype.__proto__ = Array.prototype; - -/** - * Remove the routes in this collection. - * - * @return {Collection} of routes removed - * @api public - */ - -Collection.prototype.remove = function(){ - var router = this.router - , len = this.length - , ret = new Collection(this.router); - - for (var i = 0; i < len; ++i) { - if (router.remove(this[i])) { - ret.push(this[i]); - } - } - - return ret; -}; - diff --git a/frontend/express/node_modules/express/lib/router/index.js b/frontend/express/node_modules/express/lib/router/index.js deleted file mode 100644 index 662dc29bff2..00000000000 --- a/frontend/express/node_modules/express/lib/router/index.js +++ /dev/null @@ -1,273 +0,0 @@ -/** - * Module dependencies. - */ - -var Route = require('./route') - , utils = require('../utils') - , methods = require('methods') - , debug = require('debug')('express:router') - , parse = require('connect').utils.parseUrl; - -/** - * Expose `Router` constructor. - */ - -exports = module.exports = Router; - -/** - * Initialize a new `Router` with the given `options`. - * - * @param {Object} options - * @api private - */ - -function Router(options) { - options = options || {}; - var self = this; - this.map = {}; - this.params = {}; - this._params = []; - this.caseSensitive = options.caseSensitive; - this.strict = options.strict; - this.middleware = function router(req, res, next){ - self._dispatch(req, res, next); - }; -} - -/** - * Register a param callback `fn` for the given `name`. - * - * @param {String|Function} name - * @param {Function} fn - * @return {Router} for chaining - * @api public - */ - -Router.prototype.param = function(name, fn){ - // param logic - if ('function' == typeof name) { - this._params.push(name); - return; - } - - // apply param functions - var params = this._params - , len = params.length - , ret; - - for (var i = 0; i < len; ++i) { - if (ret = params[i](name, fn)) { - fn = ret; - } - } - - // ensure we end up with a - // middleware function - if ('function' != typeof fn) { - throw new Error('invalid param() call for ' + name + ', got ' + fn); - } - - (this.params[name] = this.params[name] || []).push(fn); - return this; -}; - -/** - * Route dispatcher aka the route "middleware". - * - * @param {IncomingMessage} req - * @param {ServerResponse} res - * @param {Function} next - * @api private - */ - -Router.prototype._dispatch = function(req, res, next){ - var params = this.params - , self = this; - - debug('dispatching %s %s (%s)', req.method, req.url, req.originalUrl); - - // route dispatch - (function pass(i, err){ - var paramCallbacks - , paramIndex = 0 - , paramVal - , route - , keys - , key; - - // match next route - function nextRoute(err) { - pass(req._route_index + 1, err); - } - - // match route - req.route = route = self.matchRequest(req, i); - - // no route - if (!route) return next(err); - debug('matched %s %s', route.method, route.path); - - // we have a route - // start at param 0 - req.params = route.params; - keys = route.keys; - i = 0; - - // param callbacks - function param(err) { - paramIndex = 0; - key = keys[i++]; - paramVal = key && req.params[key.name]; - paramCallbacks = key && params[key.name]; - - try { - if ('route' == err) { - nextRoute(); - } else if (err) { - i = 0; - callbacks(err); - } else if (paramCallbacks && undefined !== paramVal) { - paramCallback(); - } else if (key) { - param(); - } else { - i = 0; - callbacks(); - } - } catch (err) { - param(err); - } - }; - - param(err); - - // single param callbacks - function paramCallback(err) { - var fn = paramCallbacks[paramIndex++]; - if (err || !fn) return param(err); - fn(req, res, paramCallback, paramVal, key.name); - } - - // invoke route callbacks - function callbacks(err) { - var fn = route.callbacks[i++]; - try { - if ('route' == err) { - nextRoute(); - } else if (err && fn) { - if (fn.length < 4) return callbacks(err); - fn(err, req, res, callbacks); - } else if (fn) { - if (fn.length < 4) return fn(req, res, callbacks); - callbacks(); - } else { - nextRoute(err); - } - } catch (err) { - callbacks(err); - } - } - })(0); -}; - -/** - * Attempt to match a route for `req` - * with optional starting index of `i` - * defaulting to 0. - * - * @param {IncomingMessage} req - * @param {Number} i - * @return {Route} - * @api private - */ - -Router.prototype.matchRequest = function(req, i, head){ - var method = req.method.toLowerCase() - , url = parse(req) - , path = url.pathname - , routes = this.map - , i = i || 0 - , route; - - // HEAD support - if (!head && 'head' == method) { - route = this.matchRequest(req, i, true); - if (route) return route; - method = 'get'; - } - - // routes for this method - if (routes = routes[method]) { - - // matching routes - for (var len = routes.length; i < len; ++i) { - route = routes[i]; - if (route.match(path)) { - req._route_index = i; - return route; - } - } - } -}; - -/** - * Attempt to match a route for `method` - * and `url` with optional starting - * index of `i` defaulting to 0. - * - * @param {String} method - * @param {String} url - * @param {Number} i - * @return {Route} - * @api private - */ - -Router.prototype.match = function(method, url, i, head){ - var req = { method: method, url: url }; - return this.matchRequest(req, i, head); -}; - -/** - * Route `method`, `path`, and one or more callbacks. - * - * @param {String} method - * @param {String} path - * @param {Function} callback... - * @return {Router} for chaining - * @api private - */ - -Router.prototype.route = function(method, path, callbacks){ - var method = method.toLowerCase() - , callbacks = utils.flatten([].slice.call(arguments, 2)); - - // ensure path was given - if (!path) throw new Error('Router#' + method + '() requires a path'); - - // ensure all callbacks are functions - callbacks.forEach(function(fn, i){ - if ('function' == typeof fn) return; - var type = {}.toString.call(fn); - var msg = '.' + method + '() requires callback functions but got a ' + type; - throw new Error(msg); - }); - - // create the route - debug('defined %s %s', method, path); - var route = new Route(method, path, callbacks, { - sensitive: this.caseSensitive, - strict: this.strict - }); - - // add it - (this.map[method] = this.map[method] || []).push(route); - return this; -}; - -methods.forEach(function(method){ - Router.prototype[method] = function(path){ - var args = [method].concat([].slice.call(arguments)); - this.route.apply(this, args); - return this; - }; -}); diff --git a/frontend/express/node_modules/express/lib/router/methods.js b/frontend/express/node_modules/express/lib/router/methods.js deleted file mode 100644 index 71a969adeb0..00000000000 --- a/frontend/express/node_modules/express/lib/router/methods.js +++ /dev/null @@ -1,79 +0,0 @@ - -/*! - * Express - router - methods - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Hypertext Transfer Protocol -- HTTP/1.1 - * http://www.ietf.org/rfc/rfc2616.txt - */ - -var RFC2616 = ['OPTIONS', 'GET', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT']; - -/** - * HTTP Extensions for Distributed Authoring -- WEBDAV - * http://www.ietf.org/rfc/rfc2518.txt - */ - -var RFC2518 = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK']; - -/** - * Versioning Extensions to WebDAV - * http://www.ietf.org/rfc/rfc3253.txt - */ - -var RFC3253 = ['VERSION-CONTROL', 'REPORT', 'CHECKOUT', 'CHECKIN', 'UNCHECKOUT', 'MKWORKSPACE', 'UPDATE', 'LABEL', 'MERGE', 'BASELINE-CONTROL', 'MKACTIVITY']; - -/** - * Ordered Collections Protocol (WebDAV) - * http://www.ietf.org/rfc/rfc3648.txt - */ - -var RFC3648 = ['ORDERPATCH']; - -/** - * Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol - * http://www.ietf.org/rfc/rfc3744.txt - */ - -var RFC3744 = ['ACL']; - -/** - * Web Distributed Authoring and Versioning (WebDAV) SEARCH - * http://www.ietf.org/rfc/rfc5323.txt - */ - -var RFC5323 = ['SEARCH']; - -/** - * PATCH Method for HTTP - * http://www.ietf.org/rfc/rfc5789.txt - */ - -var RFC5789 = ['PATCH']; - -/** - * PURGE Method for caching reverse-proxy - * http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F - * https://www.varnish-cache.org/docs/trunk/tutorial/purging.html - */ - -var CACHE_PURGE = ['PURGE']; - -/** - * Expose the methods. - */ - -module.exports = [].concat( - RFC2616 - , RFC2518 - , RFC3253 - , RFC3648 - , RFC3744 - , RFC5323 - , RFC5789 - , CACHE_PURGE).map(function(method){ - return method.toLowerCase(); - }); diff --git a/frontend/express/node_modules/express/lib/router/route.js b/frontend/express/node_modules/express/lib/router/route.js deleted file mode 100644 index c1a0b5ea804..00000000000 --- a/frontend/express/node_modules/express/lib/router/route.js +++ /dev/null @@ -1,72 +0,0 @@ - -/** - * Module dependencies. - */ - -var utils = require('../utils'); - -/** - * Expose `Route`. - */ - -module.exports = Route; - -/** - * Initialize `Route` with the given HTTP `method`, `path`, - * and an array of `callbacks` and `options`. - * - * Options: - * - * - `sensitive` enable case-sensitive routes - * - `strict` enable strict matching for trailing slashes - * - * @param {String} method - * @param {String} path - * @param {Array} callbacks - * @param {Object} options. - * @api private - */ - -function Route(method, path, callbacks, options) { - options = options || {}; - this.path = path; - this.method = method; - this.callbacks = callbacks; - this.regexp = utils.pathRegexp(path - , this.keys = [] - , options.sensitive - , options.strict); -} - -/** - * Check if this route matches `path`, if so - * populate `.params`. - * - * @param {String} path - * @return {Boolean} - * @api private - */ - -Route.prototype.match = function(path){ - var keys = this.keys - , params = this.params = [] - , m = this.regexp.exec(path); - - if (!m) return false; - - for (var i = 1, len = m.length; i < len; ++i) { - var key = keys[i - 1]; - - var val = 'string' == typeof m[i] - ? decodeURIComponent(m[i]) - : m[i]; - - if (key) { - params[key.name] = val; - } else { - params.push(val); - } - } - - return true; -}; diff --git a/frontend/express/node_modules/express/lib/utils.js b/frontend/express/node_modules/express/lib/utils.js deleted file mode 100644 index fd245a8fbbc..00000000000 --- a/frontend/express/node_modules/express/lib/utils.js +++ /dev/null @@ -1,313 +0,0 @@ - -/** - * Module dependencies. - */ - -var mime = require('connect').mime - , crc32 = require('buffer-crc32'); - -/** - * toString ref. - */ - -var toString = {}.toString; - -/** - * Return ETag for `body`. - * - * @param {String|Buffer} body - * @return {String} - * @api private - */ - -exports.etag = function(body){ - return '"' + crc32.signed(body) + '"'; -}; - -/** - * Make `locals()` bound to the given `obj`. - * - * This is used for `app.locals` and `res.locals`. - * - * @param {Object} obj - * @return {Function} - * @api private - */ - -exports.locals = function(obj){ - function locals(obj){ - for (var key in obj) locals[key] = obj[key]; - return obj; - }; - - return locals; -}; - -/** - * Check if `path` looks absolute. - * - * @param {String} path - * @return {Boolean} - * @api private - */ - -exports.isAbsolute = function(path){ - if ('/' == path[0]) return true; - if (':' == path[1] && '\\' == path[2]) return true; -}; - -/** - * Flatten the given `arr`. - * - * @param {Array} arr - * @return {Array} - * @api private - */ - -exports.flatten = function(arr, ret){ - var ret = ret || [] - , len = arr.length; - for (var i = 0; i < len; ++i) { - if (Array.isArray(arr[i])) { - exports.flatten(arr[i], ret); - } else { - ret.push(arr[i]); - } - } - return ret; -}; - -/** - * Normalize the given `type`, for example "html" becomes "text/html". - * - * @param {String} type - * @return {Object} - * @api private - */ - -exports.normalizeType = function(type){ - return ~type.indexOf('/') - ? acceptParams(type) - : { value: mime.lookup(type), params: {} }; -}; - -/** - * Normalize `types`, for example "html" becomes "text/html". - * - * @param {Array} types - * @return {Array} - * @api private - */ - -exports.normalizeTypes = function(types){ - var ret = []; - - for (var i = 0; i < types.length; ++i) { - ret.push(exports.normalizeType(types[i])); - } - - return ret; -}; - -/** - * Return the acceptable type in `types`, if any. - * - * @param {Array} types - * @param {String} str - * @return {String} - * @api private - */ - -exports.acceptsArray = function(types, str){ - // accept anything when Accept is not present - if (!str) return types[0]; - - // parse - var accepted = exports.parseAccept(str) - , normalized = exports.normalizeTypes(types) - , len = accepted.length; - - for (var i = 0; i < len; ++i) { - for (var j = 0, jlen = types.length; j < jlen; ++j) { - if (exports.accept(normalized[j], accepted[i])) { - return types[j]; - } - } - } -}; - -/** - * Check if `type(s)` are acceptable based on - * the given `str`. - * - * @param {String|Array} type(s) - * @param {String} str - * @return {Boolean|String} - * @api private - */ - -exports.accepts = function(type, str){ - if ('string' == typeof type) type = type.split(/ *, */); - return exports.acceptsArray(type, str); -}; - -/** - * Check if `type` array is acceptable for `other`. - * - * @param {Object} type - * @param {Object} other - * @return {Boolean} - * @api private - */ - -exports.accept = function(type, other){ - var t = type.value.split('/'); - return (t[0] == other.type || '*' == other.type) - && (t[1] == other.subtype || '*' == other.subtype) - && paramsEqual(type.params, other.params); -}; - -/** - * Check if accept params are equal. - * - * @param {Object} a - * @param {Object} b - * @return {Boolean} - * @api private - */ - -function paramsEqual(a, b){ - return !Object.keys(a).some(function(k) { - return a[k] != b[k]; - }); -} - -/** - * Parse accept `str`, returning - * an array objects containing - * `.type` and `.subtype` along - * with the values provided by - * `parseQuality()`. - * - * @param {Type} name - * @return {Type} - * @api private - */ - -exports.parseAccept = function(str){ - return exports - .parseParams(str) - .map(function(obj){ - var parts = obj.value.split('/'); - obj.type = parts[0]; - obj.subtype = parts[1]; - return obj; - }); -}; - -/** - * Parse quality `str`, returning an - * array of objects with `.value`, - * `.quality` and optional `.params` - * - * @param {String} str - * @return {Array} - * @api private - */ - -exports.parseParams = function(str){ - return str - .split(/ *, */) - .map(acceptParams) - .filter(function(obj){ - return obj.quality; - }) - .sort(function(a, b){ - if (a.quality === b.quality) { - return a.originalIndex - b.originalIndex; - } else { - return b.quality - a.quality; - } - }); -}; - -/** - * Parse accept params `str` returning an - * object with `.value`, `.quality` and `.params`. - * also includes `.originalIndex` for stable sorting - * - * @param {String} str - * @return {Object} - * @api private - */ - -function acceptParams(str, index) { - var parts = str.split(/ *; */); - var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index }; - - for (var i = 1; i < parts.length; ++i) { - var pms = parts[i].split(/ *= */); - if ('q' == pms[0]) { - ret.quality = parseFloat(pms[1]); - } else { - ret.params[pms[0]] = pms[1]; - } - } - - return ret; -} - -/** - * Escape special characters in the given string of html. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html) { - return String(html) - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(//g, '>'); -}; - -/** - * Normalize the given path string, - * returning a regular expression. - * - * An empty array should be passed, - * which will contain the placeholder - * key names. For example "/user/:id" will - * then contain ["id"]. - * - * @param {String|RegExp|Array} path - * @param {Array} keys - * @param {Boolean} sensitive - * @param {Boolean} strict - * @return {RegExp} - * @api private - */ - -exports.pathRegexp = function(path, keys, sensitive, strict) { - if (toString.call(path) == '[object RegExp]') return path; - if (Array.isArray(path)) path = '(' + path.join('|') + ')'; - path = path - .concat(strict ? '' : '/?') - .replace(/\/\(/g, '(?:/') - .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g, function(_, slash, format, key, capture, optional, star){ - keys.push({ name: key, optional: !! optional }); - slash = slash || ''; - return '' - + (optional ? '' : slash) - + '(?:' - + (optional ? slash : '') - + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' - + (optional || '') - + (star ? '(/*)?' : ''); - }) - .replace(/([\/.])/g, '\\$1') - .replace(/\*/g, '(.*)'); - return new RegExp('^' + path + '$', sensitive ? '' : 'i'); -} diff --git a/frontend/express/node_modules/express/lib/view.js b/frontend/express/node_modules/express/lib/view.js deleted file mode 100644 index b9dc69e0e4d..00000000000 --- a/frontend/express/node_modules/express/lib/view.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Module dependencies. - */ - -var path = require('path') - , fs = require('fs') - , utils = require('./utils') - , dirname = path.dirname - , basename = path.basename - , extname = path.extname - , exists = fs.existsSync || path.existsSync - , join = path.join; - -/** - * Expose `View`. - */ - -module.exports = View; - -/** - * Initialize a new `View` with the given `name`. - * - * Options: - * - * - `defaultEngine` the default template engine name - * - `engines` template engine require() cache - * - `root` root path for view lookup - * - * @param {String} name - * @param {Object} options - * @api private - */ - -function View(name, options) { - options = options || {}; - this.name = name; - this.root = options.root; - var engines = options.engines; - this.defaultEngine = options.defaultEngine; - var ext = this.ext = extname(name); - if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.'); - if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine); - this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express); - this.path = this.lookup(name); -} - -/** - * Lookup view by the given `path` - * - * @param {String} path - * @return {String} - * @api private - */ - -View.prototype.lookup = function(path){ - var ext = this.ext; - - // . - if (!utils.isAbsolute(path)) path = join(this.root, path); - if (exists(path)) return path; - - // /index. - path = join(dirname(path), basename(path, ext), 'index' + ext); - if (exists(path)) return path; -}; - -/** - * Render with the given `options` and callback `fn(err, str)`. - * - * @param {Object} options - * @param {Function} fn - * @api private - */ - -View.prototype.render = function(options, fn){ - this.engine(this.path, options, fn); -}; diff --git a/frontend/express/node_modules/express/lib/view/partial.js b/frontend/express/node_modules/express/lib/view/partial.js deleted file mode 100644 index 7d2f69b20ad..00000000000 --- a/frontend/express/node_modules/express/lib/view/partial.js +++ /dev/null @@ -1,40 +0,0 @@ - -/*! - * Express - view - Partial - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Memory cache. - */ - -var cache = {}; - -/** - * Resolve partial object name from the view path. - * - * Examples: - * - * "user.ejs" becomes "user" - * "forum thread.ejs" becomes "forumThread" - * "forum/thread/post.ejs" becomes "post" - * "blog-post.ejs" becomes "blogPost" - * - * @return {String} - * @api private - */ - -exports.resolveObjectName = function(view){ - return cache[view] || (cache[view] = view - .split('/') - .slice(-1)[0] - .split('.')[0] - .replace(/^_/, '') - .replace(/[^a-zA-Z0-9 ]+/g, ' ') - .split(/ +/).map(function(word, i){ - return i - ? word[0].toUpperCase() + word.substr(1) - : word; - }).join('')); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/lib/view/view.js b/frontend/express/node_modules/express/lib/view/view.js deleted file mode 100644 index 7d9392cb367..00000000000 --- a/frontend/express/node_modules/express/lib/view/view.js +++ /dev/null @@ -1,210 +0,0 @@ - -/*! - * Express - View - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var path = require('path') - , utils = require('../utils') - , extname = path.extname - , dirname = path.dirname - , basename = path.basename - , fs = require('fs') - , stat = fs.statSync; - -/** - * Expose `View`. - */ - -exports = module.exports = View; - -/** - * Require cache. - */ - -var cache = {}; - -/** - * Initialize a new `View` with the given `view` path and `options`. - * - * @param {String} view - * @param {Object} options - * @api private - */ - -function View(view, options) { - options = options || {}; - this.view = view; - this.root = options.root; - this.relative = false !== options.relative; - this.defaultEngine = options.defaultEngine; - this.parent = options.parentView; - this.basename = basename(view); - this.engine = this.resolveEngine(); - this.extension = '.' + this.engine; - this.name = this.basename.replace(this.extension, ''); - this.path = this.resolvePath(); - this.dirname = dirname(this.path); - if (options.attempts) { - if (!~options.attempts.indexOf(this.path)) - options.attempts.push(this.path); - } -}; - -/** - * Check if the view path exists. - * - * @return {Boolean} - * @api public - */ - -View.prototype.__defineGetter__('exists', function(){ - try { - stat(this.path); - return true; - } catch (err) { - return false; - } -}); - -/** - * Resolve view engine. - * - * @return {String} - * @api private - */ - -View.prototype.resolveEngine = function(){ - // Explicit - if (~this.basename.indexOf('.')) return extname(this.basename).substr(1); - // Inherit from parent - if (this.parent) return this.parent.engine; - // Default - return this.defaultEngine; -}; - -/** - * Resolve view path. - * - * @return {String} - * @api private - */ - -View.prototype.resolvePath = function(){ - var path = this.view; - // Implicit engine - if (!~this.basename.indexOf('.')) path += this.extension; - // Absolute - if (utils.isAbsolute(path)) return path; - // Relative to parent - if (this.relative && this.parent) return this.parent.dirname + '/' + path; - // Relative to root - return this.root - ? this.root + '/' + path - : path; -}; - -/** - * Get view contents. This is a one-time hit, so we - * can afford to be sync. - * - * @return {String} - * @api public - */ - -View.prototype.__defineGetter__('contents', function(){ - return fs.readFileSync(this.path, 'utf8'); -}); - -/** - * Get template engine api, cache exports to reduce - * require() calls. - * - * @return {Object} - * @api public - */ - -View.prototype.__defineGetter__('templateEngine', function(){ - var ext = this.extension; - return cache[ext] || (cache[ext] = require(this.engine)); -}); - -/** - * Return root path alternative. - * - * @return {String} - * @api public - */ - -View.prototype.__defineGetter__('rootPath', function(){ - this.relative = false; - return this.resolvePath(); -}); - -/** - * Return index path alternative. - * - * @return {String} - * @api public - */ - -View.prototype.__defineGetter__('indexPath', function(){ - return this.dirname - + '/' + this.basename.replace(this.extension, '') - + '/index' + this.extension; -}); - -/** - * Return ..//index path alternative. - * - * @return {String} - * @api public - */ - -View.prototype.__defineGetter__('upIndexPath', function(){ - return this.dirname + '/../' + this.name + '/index' + this.extension; -}); - -/** - * Return _ prefix path alternative - * - * @return {String} - * @api public - */ - -View.prototype.__defineGetter__('prefixPath', function(){ - return this.dirname + '/_' + this.basename; -}); - -/** - * Register the given template engine `exports` - * as `ext`. For example we may wish to map ".html" - * files to jade: - * - * app.register('.html', require('jade')); - * - * or - * - * app.register('html', require('jade')); - * - * This is also useful for libraries that may not - * match extensions correctly. For example my haml.js - * library is installed from npm as "hamljs" so instead - * of layout.hamljs, we can register the engine as ".haml": - * - * app.register('.haml', require('haml-js')); - * - * @param {String} ext - * @param {Object} obj - * @api public - */ - -exports.register = function(ext, exports) { - if ('.' != ext[0]) ext = '.' + ext; - cache[ext] = exports; -}; diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/.npmignore b/frontend/express/node_modules/express/node_modules/buffer-crc32/.npmignore deleted file mode 100644 index b512c09d476..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/.travis.yml b/frontend/express/node_modules/express/node_modules/buffer-crc32/.travis.yml deleted file mode 100644 index 7a902e8c86d..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 -notifications: - email: - recipients: - - brianloveswords@gmail.com \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/README.md b/frontend/express/node_modules/express/node_modules/buffer-crc32/README.md deleted file mode 100644 index 0d9d8b83595..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# buffer-crc32 - -[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32) - -crc32 that works with binary data and fancy character sets, outputs -buffer, signed or unsigned data and has tests. - -Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix - -# install -``` -npm install buffer-crc32 -``` - -# example -```js -var crc32 = require('buffer-crc32'); -// works with buffers -var buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00]) -crc32(buf) // -> - -// has convenience methods for getting signed or unsigned ints -crc32.signed(buf) // -> -1805997238 -crc32.unsigned(buf) // -> 2488970058 - -// will cast to buffer if given a string, so you can -// directly use foreign characters safely -crc32('自動販売機') // -> - -// and works in append mode too -var partialCrc = crc32('hey'); -var partialCrc = crc32(' ', partialCrc); -var partialCrc = crc32('sup', partialCrc); -var partialCrc = crc32(' ', partialCrc); -var finalCrc = crc32('bros', partialCrc); // -> -``` - -# tests -This was tested against the output of zlib's crc32 method. You can run -the tests with`npm test` (requires tap) - -# see also -https://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also -supports buffer inputs and return unsigned ints (thanks @tjholowaychuk). - -# license -MIT/X11 diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/index.js b/frontend/express/node_modules/express/node_modules/buffer-crc32/index.js deleted file mode 100644 index e29ce3ebce2..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/index.js +++ /dev/null @@ -1,88 +0,0 @@ -var Buffer = require('buffer').Buffer; - -var CRC_TABLE = [ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d -]; - -function bufferizeInt(num) { - var tmp = Buffer(4); - tmp.writeInt32BE(num, 0); - return tmp; -} - -function _crc32(buf, previous) { - if (!Buffer.isBuffer(buf)) { - buf = Buffer(buf); - } - if (Buffer.isBuffer(previous)) { - previous = previous.readUInt32BE(0); - } - var crc = ~~previous ^ -1; - for (var n = 0; n < buf.length; n++) { - crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8); - } - return (crc ^ -1); -} - -function crc32() { - return bufferizeInt(_crc32.apply(null, arguments)); -} -crc32.signed = function () { - return _crc32.apply(null, arguments); -}; -crc32.unsigned = function () { - return _crc32.apply(null, arguments) >>> 0; -}; - -module.exports = crc32; diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/package.json b/frontend/express/node_modules/express/node_modules/buffer-crc32/package.json deleted file mode 100644 index 4bb469a04b1..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "author": { - "name": "Brian J. Brennan", - "email": "brianloveswords@gmail.com", - "url": "http://bjb.io" - }, - "name": "buffer-crc32", - "description": "A pure javascript CRC32 algorithm that plays nice with binary data", - "version": "0.2.1", - "contributors": [ - { - "name": "Vladimir Kuznetsov" - } - ], - "homepage": "https://github.com/brianloveswords/buffer-crc32", - "repository": { - "type": "git", - "url": "git://github.com/brianloveswords/buffer-crc32.git" - }, - "main": "index.js", - "scripts": { - "test": "./node_modules/.bin/tap tests/*.test.js" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.2.5" - }, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "# buffer-crc32\n\n[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)\n\ncrc32 that works with binary data and fancy character sets, outputs\nbuffer, signed or unsigned data and has tests.\n\nDerived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix\n\n# install\n```\nnpm install buffer-crc32\n```\n\n# example\n```js\nvar crc32 = require('buffer-crc32');\n// works with buffers\nvar buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])\ncrc32(buf) // -> \n\n// has convenience methods for getting signed or unsigned ints\ncrc32.signed(buf) // -> -1805997238\ncrc32.unsigned(buf) // -> 2488970058\n\n// will cast to buffer if given a string, so you can\n// directly use foreign characters safely\ncrc32('自動販売機') // -> \n\n// and works in append mode too\nvar partialCrc = crc32('hey');\nvar partialCrc = crc32(' ', partialCrc);\nvar partialCrc = crc32('sup', partialCrc);\nvar partialCrc = crc32(' ', partialCrc);\nvar finalCrc = crc32('bros', partialCrc); // -> \n```\n\n# tests\nThis was tested against the output of zlib's crc32 method. You can run\nthe tests with`npm test` (requires tap)\n\n# see also\nhttps://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also\nsupports buffer inputs and return unsigned ints (thanks @tjholowaychuk).\n\n# license\nMIT/X11\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/brianloveswords/buffer-crc32/issues" - }, - "_id": "buffer-crc32@0.2.1", - "_from": "buffer-crc32@0.2.1" -} diff --git a/frontend/express/node_modules/express/node_modules/buffer-crc32/tests/crc.test.js b/frontend/express/node_modules/express/node_modules/buffer-crc32/tests/crc.test.js deleted file mode 100644 index bb0f9efccbe..00000000000 --- a/frontend/express/node_modules/express/node_modules/buffer-crc32/tests/crc.test.js +++ /dev/null @@ -1,89 +0,0 @@ -var crc32 = require('..'); -var test = require('tap').test; - -test('simple crc32 is no problem', function (t) { - var input = Buffer('hey sup bros'); - var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); - t.same(crc32(input), expected); - t.end(); -}); - -test('another simple one', function (t) { - var input = Buffer('IEND'); - var expected = Buffer([0xae, 0x42, 0x60, 0x82]); - t.same(crc32(input), expected); - t.end(); -}); - -test('slightly more complex', function (t) { - var input = Buffer([0x00, 0x00, 0x00]); - var expected = Buffer([0xff, 0x41, 0xd9, 0x12]); - t.same(crc32(input), expected); - t.end(); -}); - -test('complex crc32 gets calculated like a champ', function (t) { - var input = Buffer('शीरà¥à¤·à¤•'); - var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); - t.same(crc32(input), expected); - t.end(); -}); - -test('casts to buffer if necessary', function (t) { - var input = 'शीरà¥à¤·à¤•'; - var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); - t.same(crc32(input), expected); - t.end(); -}); - -test('can do signed', function (t) { - var input = 'ham sandwich'; - var expected = -1891873021; - t.same(crc32.signed(input), expected); - t.end(); -}); - -test('can do unsigned', function (t) { - var input = 'bear sandwich'; - var expected = 3711466352; - t.same(crc32.unsigned(input), expected); - t.end(); -}); - - -test('simple crc32 in append mode', function (t) { - var input = [Buffer('hey'), Buffer(' '), Buffer('sup'), Buffer(' '), Buffer('bros')]; - var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); - for (var crc = 0, i = 0; i < input.length; i++) { - crc = crc32(input[i], crc); - } - t.same(crc, expected); - t.end(); -}); - - -test('can do signed in append mode', function (t) { - var input1 = 'ham'; - var input2 = ' '; - var input3 = 'sandwich'; - var expected = -1891873021; - - var crc = crc32.signed(input1); - crc = crc32.signed(input2, crc); - crc = crc32.signed(input3, crc); - - t.same(crc, expected); - t.end(); -}); - -test('can do unsigned in append mode', function (t) { - var input1 = 'bear san'; - var input2 = 'dwich'; - var expected = 3711466352; - - var crc = crc32.unsigned(input1); - crc = crc32.unsigned(input2, crc); - t.same(crc, expected); - t.end(); -}); - diff --git a/frontend/express/node_modules/express/node_modules/commander/.npmignore b/frontend/express/node_modules/express/node_modules/commander/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/commander/.travis.yml b/frontend/express/node_modules/express/node_modules/commander/.travis.yml deleted file mode 100644 index f1d0f13c8a5..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.6 diff --git a/frontend/express/node_modules/express/node_modules/commander/History.md b/frontend/express/node_modules/express/node_modules/commander/History.md deleted file mode 100644 index 4961d2e272c..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/History.md +++ /dev/null @@ -1,107 +0,0 @@ - -0.6.1 / 2012-06-01 -================== - - * Added: append (yes or no) on confirmation - * Added: allow node.js v0.7.x - -0.6.0 / 2012-04-10 -================== - - * Added `.prompt(obj, callback)` support. Closes #49 - * Added default support to .choose(). Closes #41 - * Fixed the choice example - -0.5.1 / 2011-12-20 -================== - - * Fixed `password()` for recent nodes. Closes #36 - -0.5.0 / 2011-12-04 -================== - - * Added sub-command option support [itay] - -0.4.3 / 2011-12-04 -================== - - * Fixed custom help ordering. Closes #32 - -0.4.2 / 2011-11-24 -================== - - * Added travis support - * Fixed: line-buffered input automatically trimmed. Closes #31 - -0.4.1 / 2011-11-18 -================== - - * Removed listening for "close" on --help - -0.4.0 / 2011-11-15 -================== - - * Added support for `--`. Closes #24 - -0.3.3 / 2011-11-14 -================== - - * Fixed: wait for close event when writing help info [Jerry Hamlet] - -0.3.2 / 2011-11-01 -================== - - * Fixed long flag definitions with values [felixge] - -0.3.1 / 2011-10-31 -================== - - * Changed `--version` short flag to `-V` from `-v` - * Changed `.version()` so it's configurable [felixge] - -0.3.0 / 2011-10-31 -================== - - * Added support for long flags only. Closes #18 - -0.2.1 / 2011-10-24 -================== - - * "node": ">= 0.4.x < 0.7.0". Closes #20 - -0.2.0 / 2011-09-26 -================== - - * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs] - -0.1.0 / 2011-08-24 -================== - - * Added support for custom `--help` output - -0.0.5 / 2011-08-18 -================== - - * Changed: when the user enters nothing prompt for password again - * Fixed issue with passwords beginning with numbers [NuckChorris] - -0.0.4 / 2011-08-15 -================== - - * Fixed `Commander#args` - -0.0.3 / 2011-08-15 -================== - - * Added default option value support - -0.0.2 / 2011-08-15 -================== - - * Added mask support to `Command#password(str[, mask], fn)` - * Added `Command#password(str, fn)` - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/commander/Makefile b/frontend/express/node_modules/express/node_modules/commander/Makefile deleted file mode 100644 index 00746255373..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -TESTS = $(shell find test/test.*.js) - -test: - @./test/run $(TESTS) - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/commander/Readme.md b/frontend/express/node_modules/express/node_modules/commander/Readme.md deleted file mode 100644 index b8328c37563..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/Readme.md +++ /dev/null @@ -1,262 +0,0 @@ -# Commander.js - - The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). - - [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js) - -## Installation - - $ npm install commander - -## Option parsing - - Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. - -```js -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var program = require('commander'); - -program - .version('0.0.1') - .option('-p, --peppers', 'Add peppers') - .option('-P, --pineapple', 'Add pineapple') - .option('-b, --bbq', 'Add bbq sauce') - .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') - .parse(process.argv); - -console.log('you ordered a pizza with:'); -if (program.peppers) console.log(' - peppers'); -if (program.pineapple) console.log(' - pineappe'); -if (program.bbq) console.log(' - bbq'); -console.log(' - %s cheese', program.cheese); -``` - - Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. - -## Automated --help - - The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: - -``` - $ ./examples/pizza --help - - Usage: pizza [options] - - Options: - - -V, --version output the version number - -p, --peppers Add peppers - -P, --pineapple Add pineappe - -b, --bbq Add bbq sauce - -c, --cheese Add the specified type of cheese [marble] - -h, --help output usage information - -``` - -## Coercion - -```js -function range(val) { - return val.split('..').map(Number); -} - -function list(val) { - return val.split(','); -} - -program - .version('0.0.1') - .usage('[options] ') - .option('-i, --integer ', 'An integer argument', parseInt) - .option('-f, --float ', 'A float argument', parseFloat) - .option('-r, --range ..', 'A range', range) - .option('-l, --list ', 'A list', list) - .option('-o, --optional [value]', 'An optional value') - .parse(process.argv); - -console.log(' int: %j', program.integer); -console.log(' float: %j', program.float); -console.log(' optional: %j', program.optional); -program.range = program.range || []; -console.log(' range: %j..%j', program.range[0], program.range[1]); -console.log(' list: %j', program.list); -console.log(' args: %j', program.args); -``` - -## Custom help - - You can display arbitrary `-h, --help` information - by listening for "--help". Commander will automatically - exit once you are done so that the remainder of your program - does not execute causing undesired behaviours, for example - in the following executable "stuff" will not output when - `--help` is used. - -```js -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var program = require('../'); - -function list(val) { - return val.split(',').map(Number); -} - -program - .version('0.0.1') - .option('-f, --foo', 'enable some foo') - .option('-b, --bar', 'enable some bar') - .option('-B, --baz', 'enable some baz'); - -// must be before .parse() since -// node's emit() is immediate - -program.on('--help', function(){ - console.log(' Examples:'); - console.log(''); - console.log(' $ custom-help --help'); - console.log(' $ custom-help -h'); - console.log(''); -}); - -program.parse(process.argv); - -console.log('stuff'); -``` - -yielding the following help output: - -``` - -Usage: custom-help [options] - -Options: - - -h, --help output usage information - -V, --version output the version number - -f, --foo enable some foo - -b, --bar enable some bar - -B, --baz enable some baz - -Examples: - - $ custom-help --help - $ custom-help -h - -``` - -## .prompt(msg, fn) - - Single-line prompt: - -```js -program.prompt('name: ', function(name){ - console.log('hi %s', name); -}); -``` - - Multi-line prompt: - -```js -program.prompt('description:', function(name){ - console.log('hi %s', name); -}); -``` - - Coercion: - -```js -program.prompt('Age: ', Number, function(age){ - console.log('age: %j', age); -}); -``` - -```js -program.prompt('Birthdate: ', Date, function(date){ - console.log('date: %s', date); -}); -``` - -## .password(msg[, mask], fn) - -Prompt for password without echoing: - -```js -program.password('Password: ', function(pass){ - console.log('got "%s"', pass); - process.stdin.destroy(); -}); -``` - -Prompt for password with mask char "*": - -```js -program.password('Password: ', '*', function(pass){ - console.log('got "%s"', pass); - process.stdin.destroy(); -}); -``` - -## .confirm(msg, fn) - - Confirm with the given `msg`: - -```js -program.confirm('continue? ', function(ok){ - console.log(' got %j', ok); -}); -``` - -## .choose(list, fn) - - Let the user choose from a `list`: - -```js -var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; - -console.log('Choose the coolest pet:'); -program.choose(list, function(i){ - console.log('you chose %d "%s"', i, list[i]); -}); -``` - -## Links - - - [API documentation](http://visionmedia.github.com/commander.js/) - - [ascii tables](https://github.com/LearnBoost/cli-table) - - [progress bars](https://github.com/visionmedia/node-progress) - - [more progress bars](https://github.com/substack/node-multimeter) - - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) - -## License - -(The MIT License) - -Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/commander/index.js b/frontend/express/node_modules/express/node_modules/commander/index.js deleted file mode 100644 index 06ec1e4bcd8..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/commander'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/commander/lib/commander.js b/frontend/express/node_modules/express/node_modules/commander/lib/commander.js deleted file mode 100644 index 5ba87ebb85d..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/lib/commander.js +++ /dev/null @@ -1,1026 +0,0 @@ - -/*! - * commander - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter - , path = require('path') - , tty = require('tty') - , basename = path.basename; - -/** - * Expose the root command. - */ - -exports = module.exports = new Command; - -/** - * Expose `Command`. - */ - -exports.Command = Command; - -/** - * Expose `Option`. - */ - -exports.Option = Option; - -/** - * Initialize a new `Option` with the given `flags` and `description`. - * - * @param {String} flags - * @param {String} description - * @api public - */ - -function Option(flags, description) { - this.flags = flags; - this.required = ~flags.indexOf('<'); - this.optional = ~flags.indexOf('['); - this.bool = !~flags.indexOf('-no-'); - flags = flags.split(/[ ,|]+/); - if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); - this.long = flags.shift(); - this.description = description; -} - -/** - * Return option name. - * - * @return {String} - * @api private - */ - -Option.prototype.name = function(){ - return this.long - .replace('--', '') - .replace('no-', ''); -}; - -/** - * Check if `arg` matches the short or long flag. - * - * @param {String} arg - * @return {Boolean} - * @api private - */ - -Option.prototype.is = function(arg){ - return arg == this.short - || arg == this.long; -}; - -/** - * Initialize a new `Command`. - * - * @param {String} name - * @api public - */ - -function Command(name) { - this.commands = []; - this.options = []; - this.args = []; - this.name = name; -} - -/** - * Inherit from `EventEmitter.prototype`. - */ - -Command.prototype.__proto__ = EventEmitter.prototype; - -/** - * Add command `name`. - * - * The `.action()` callback is invoked when the - * command `name` is specified via __ARGV__, - * and the remaining arguments are applied to the - * function for access. - * - * When the `name` is "*" an un-matched command - * will be passed as the first arg, followed by - * the rest of __ARGV__ remaining. - * - * Examples: - * - * program - * .version('0.0.1') - * .option('-C, --chdir ', 'change the working directory') - * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') - * .option('-T, --no-tests', 'ignore test hook') - * - * program - * .command('setup') - * .description('run remote setup commands') - * .action(function(){ - * console.log('setup'); - * }); - * - * program - * .command('exec ') - * .description('run the given remote command') - * .action(function(cmd){ - * console.log('exec "%s"', cmd); - * }); - * - * program - * .command('*') - * .description('deploy the given env') - * .action(function(env){ - * console.log('deploying "%s"', env); - * }); - * - * program.parse(process.argv); - * - * @param {String} name - * @return {Command} the new command - * @api public - */ - -Command.prototype.command = function(name){ - var args = name.split(/ +/); - var cmd = new Command(args.shift()); - this.commands.push(cmd); - cmd.parseExpectedArgs(args); - cmd.parent = this; - return cmd; -}; - -/** - * Parse expected `args`. - * - * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. - * - * @param {Array} args - * @return {Command} for chaining - * @api public - */ - -Command.prototype.parseExpectedArgs = function(args){ - if (!args.length) return; - var self = this; - args.forEach(function(arg){ - switch (arg[0]) { - case '<': - self.args.push({ required: true, name: arg.slice(1, -1) }); - break; - case '[': - self.args.push({ required: false, name: arg.slice(1, -1) }); - break; - } - }); - return this; -}; - -/** - * Register callback `fn` for the command. - * - * Examples: - * - * program - * .command('help') - * .description('display verbose help') - * .action(function(){ - * // output help here - * }); - * - * @param {Function} fn - * @return {Command} for chaining - * @api public - */ - -Command.prototype.action = function(fn){ - var self = this; - this.parent.on(this.name, function(args, unknown){ - // Parse any so-far unknown options - unknown = unknown || []; - var parsed = self.parseOptions(unknown); - - // Output help if necessary - outputHelpIfNecessary(self, parsed.unknown); - - // If there are still any unknown options, then we simply - // die, unless someone asked for help, in which case we give it - // to them, and then we die. - if (parsed.unknown.length > 0) { - self.unknownOption(parsed.unknown[0]); - } - - self.args.forEach(function(arg, i){ - if (arg.required && null == args[i]) { - self.missingArgument(arg.name); - } - }); - - // Always append ourselves to the end of the arguments, - // to make sure we match the number of arguments the user - // expects - if (self.args.length) { - args[self.args.length] = self; - } else { - args.push(self); - } - - fn.apply(this, args); - }); - return this; -}; - -/** - * Define option with `flags`, `description` and optional - * coercion `fn`. - * - * The `flags` string should contain both the short and long flags, - * separated by comma, a pipe or space. The following are all valid - * all will output this way when `--help` is used. - * - * "-p, --pepper" - * "-p|--pepper" - * "-p --pepper" - * - * Examples: - * - * // simple boolean defaulting to false - * program.option('-p, --pepper', 'add pepper'); - * - * --pepper - * program.pepper - * // => Boolean - * - * // simple boolean defaulting to false - * program.option('-C, --no-cheese', 'remove cheese'); - * - * program.cheese - * // => true - * - * --no-cheese - * program.cheese - * // => true - * - * // required argument - * program.option('-C, --chdir ', 'change the working directory'); - * - * --chdir /tmp - * program.chdir - * // => "/tmp" - * - * // optional argument - * program.option('-c, --cheese [type]', 'add cheese [marble]'); - * - * @param {String} flags - * @param {String} description - * @param {Function|Mixed} fn or default - * @param {Mixed} defaultValue - * @return {Command} for chaining - * @api public - */ - -Command.prototype.option = function(flags, description, fn, defaultValue){ - var self = this - , option = new Option(flags, description) - , oname = option.name() - , name = camelcase(oname); - - // default as 3rd arg - if ('function' != typeof fn) defaultValue = fn, fn = null; - - // preassign default value only for --no-*, [optional], or - if (false == option.bool || option.optional || option.required) { - // when --no-* we make sure default is true - if (false == option.bool) defaultValue = true; - // preassign only if we have a default - if (undefined !== defaultValue) self[name] = defaultValue; - } - - // register the option - this.options.push(option); - - // when it's passed assign the value - // and conditionally invoke the callback - this.on(oname, function(val){ - // coercion - if (null != val && fn) val = fn(val); - - // unassigned or bool - if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { - // if no value, bool true, and we have a default, then use it! - if (null == val) { - self[name] = option.bool - ? defaultValue || true - : false; - } else { - self[name] = val; - } - } else if (null !== val) { - // reassign - self[name] = val; - } - }); - - return this; -}; - -/** - * Parse `argv`, settings options and invoking commands when defined. - * - * @param {Array} argv - * @return {Command} for chaining - * @api public - */ - -Command.prototype.parse = function(argv){ - // store raw args - this.rawArgs = argv; - - // guess name - if (!this.name) this.name = basename(argv[1]); - - // process argv - var parsed = this.parseOptions(this.normalize(argv.slice(2))); - this.args = parsed.args; - return this.parseArgs(this.args, parsed.unknown); -}; - -/** - * Normalize `args`, splitting joined short flags. For example - * the arg "-abc" is equivalent to "-a -b -c". - * - * @param {Array} args - * @return {Array} - * @api private - */ - -Command.prototype.normalize = function(args){ - var ret = [] - , arg; - - for (var i = 0, len = args.length; i < len; ++i) { - arg = args[i]; - if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { - arg.slice(1).split('').forEach(function(c){ - ret.push('-' + c); - }); - } else { - ret.push(arg); - } - } - - return ret; -}; - -/** - * Parse command `args`. - * - * When listener(s) are available those - * callbacks are invoked, otherwise the "*" - * event is emitted and those actions are invoked. - * - * @param {Array} args - * @return {Command} for chaining - * @api private - */ - -Command.prototype.parseArgs = function(args, unknown){ - var cmds = this.commands - , len = cmds.length - , name; - - if (args.length) { - name = args[0]; - if (this.listeners(name).length) { - this.emit(args.shift(), args, unknown); - } else { - this.emit('*', args); - } - } else { - outputHelpIfNecessary(this, unknown); - - // If there were no args and we have unknown options, - // then they are extraneous and we need to error. - if (unknown.length > 0) { - this.unknownOption(unknown[0]); - } - } - - return this; -}; - -/** - * Return an option matching `arg` if any. - * - * @param {String} arg - * @return {Option} - * @api private - */ - -Command.prototype.optionFor = function(arg){ - for (var i = 0, len = this.options.length; i < len; ++i) { - if (this.options[i].is(arg)) { - return this.options[i]; - } - } -}; - -/** - * Parse options from `argv` returning `argv` - * void of these options. - * - * @param {Array} argv - * @return {Array} - * @api public - */ - -Command.prototype.parseOptions = function(argv){ - var args = [] - , len = argv.length - , literal - , option - , arg; - - var unknownOptions = []; - - // parse options - for (var i = 0; i < len; ++i) { - arg = argv[i]; - - // literal args after -- - if ('--' == arg) { - literal = true; - continue; - } - - if (literal) { - args.push(arg); - continue; - } - - // find matching Option - option = this.optionFor(arg); - - // option is defined - if (option) { - // requires arg - if (option.required) { - arg = argv[++i]; - if (null == arg) return this.optionMissingArgument(option); - if ('-' == arg[0]) return this.optionMissingArgument(option, arg); - this.emit(option.name(), arg); - // optional arg - } else if (option.optional) { - arg = argv[i+1]; - if (null == arg || '-' == arg[0]) { - arg = null; - } else { - ++i; - } - this.emit(option.name(), arg); - // bool - } else { - this.emit(option.name()); - } - continue; - } - - // looks like an option - if (arg.length > 1 && '-' == arg[0]) { - unknownOptions.push(arg); - - // If the next argument looks like it might be - // an argument for this option, we pass it on. - // If it isn't, then it'll simply be ignored - if (argv[i+1] && '-' != argv[i+1][0]) { - unknownOptions.push(argv[++i]); - } - continue; - } - - // arg - args.push(arg); - } - - return { args: args, unknown: unknownOptions }; -}; - -/** - * Argument `name` is missing. - * - * @param {String} name - * @api private - */ - -Command.prototype.missingArgument = function(name){ - console.error(); - console.error(" error: missing required argument `%s'", name); - console.error(); - process.exit(1); -}; - -/** - * `Option` is missing an argument, but received `flag` or nothing. - * - * @param {String} option - * @param {String} flag - * @api private - */ - -Command.prototype.optionMissingArgument = function(option, flag){ - console.error(); - if (flag) { - console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); - } else { - console.error(" error: option `%s' argument missing", option.flags); - } - console.error(); - process.exit(1); -}; - -/** - * Unknown option `flag`. - * - * @param {String} flag - * @api private - */ - -Command.prototype.unknownOption = function(flag){ - console.error(); - console.error(" error: unknown option `%s'", flag); - console.error(); - process.exit(1); -}; - -/** - * Set the program version to `str`. - * - * This method auto-registers the "-V, --version" flag - * which will print the version number when passed. - * - * @param {String} str - * @param {String} flags - * @return {Command} for chaining - * @api public - */ - -Command.prototype.version = function(str, flags){ - if (0 == arguments.length) return this._version; - this._version = str; - flags = flags || '-V, --version'; - this.option(flags, 'output the version number'); - this.on('version', function(){ - console.log(str); - process.exit(0); - }); - return this; -}; - -/** - * Set the description `str`. - * - * @param {String} str - * @return {String|Command} - * @api public - */ - -Command.prototype.description = function(str){ - if (0 == arguments.length) return this._description; - this._description = str; - return this; -}; - -/** - * Set / get the command usage `str`. - * - * @param {String} str - * @return {String|Command} - * @api public - */ - -Command.prototype.usage = function(str){ - var args = this.args.map(function(arg){ - return arg.required - ? '<' + arg.name + '>' - : '[' + arg.name + ']'; - }); - - var usage = '[options' - + (this.commands.length ? '] [command' : '') - + ']' - + (this.args.length ? ' ' + args : ''); - if (0 == arguments.length) return this._usage || usage; - this._usage = str; - - return this; -}; - -/** - * Return the largest option length. - * - * @return {Number} - * @api private - */ - -Command.prototype.largestOptionLength = function(){ - return this.options.reduce(function(max, option){ - return Math.max(max, option.flags.length); - }, 0); -}; - -/** - * Return help for options. - * - * @return {String} - * @api private - */ - -Command.prototype.optionHelp = function(){ - var width = this.largestOptionLength(); - - // Prepend the help information - return [pad('-h, --help', width) + ' ' + 'output usage information'] - .concat(this.options.map(function(option){ - return pad(option.flags, width) - + ' ' + option.description; - })) - .join('\n'); -}; - -/** - * Return command help documentation. - * - * @return {String} - * @api private - */ - -Command.prototype.commandHelp = function(){ - if (!this.commands.length) return ''; - return [ - '' - , ' Commands:' - , '' - , this.commands.map(function(cmd){ - var args = cmd.args.map(function(arg){ - return arg.required - ? '<' + arg.name + '>' - : '[' + arg.name + ']'; - }).join(' '); - - return cmd.name - + (cmd.options.length - ? ' [options]' - : '') + ' ' + args - + (cmd.description() - ? '\n' + cmd.description() - : ''); - }).join('\n\n').replace(/^/gm, ' ') - , '' - ].join('\n'); -}; - -/** - * Return program help documentation. - * - * @return {String} - * @api private - */ - -Command.prototype.helpInformation = function(){ - return [ - '' - , ' Usage: ' + this.name + ' ' + this.usage() - , '' + this.commandHelp() - , ' Options:' - , '' - , '' + this.optionHelp().replace(/^/gm, ' ') - , '' - , '' - ].join('\n'); -}; - -/** - * Prompt for a `Number`. - * - * @param {String} str - * @param {Function} fn - * @api private - */ - -Command.prototype.promptForNumber = function(str, fn){ - var self = this; - this.promptSingleLine(str, function parseNumber(val){ - val = Number(val); - if (isNaN(val)) return self.promptSingleLine(str + '(must be a number) ', parseNumber); - fn(val); - }); -}; - -/** - * Prompt for a `Date`. - * - * @param {String} str - * @param {Function} fn - * @api private - */ - -Command.prototype.promptForDate = function(str, fn){ - var self = this; - this.promptSingleLine(str, function parseDate(val){ - val = new Date(val); - if (isNaN(val.getTime())) return self.promptSingleLine(str + '(must be a date) ', parseDate); - fn(val); - }); -}; - -/** - * Single-line prompt. - * - * @param {String} str - * @param {Function} fn - * @api private - */ - -Command.prototype.promptSingleLine = function(str, fn){ - if ('function' == typeof arguments[2]) { - return this['promptFor' + (fn.name || fn)](str, arguments[2]); - } - - process.stdout.write(str); - process.stdin.setEncoding('utf8'); - process.stdin.once('data', function(val){ - fn(val.trim()); - }).resume(); -}; - -/** - * Multi-line prompt. - * - * @param {String} str - * @param {Function} fn - * @api private - */ - -Command.prototype.promptMultiLine = function(str, fn){ - var buf = []; - console.log(str); - process.stdin.setEncoding('utf8'); - process.stdin.on('data', function(val){ - if ('\n' == val || '\r\n' == val) { - process.stdin.removeAllListeners('data'); - fn(buf.join('\n')); - } else { - buf.push(val.trimRight()); - } - }).resume(); -}; - -/** - * Prompt `str` and callback `fn(val)` - * - * Commander supports single-line and multi-line prompts. - * To issue a single-line prompt simply add white-space - * to the end of `str`, something like "name: ", whereas - * for a multi-line prompt omit this "description:". - * - * - * Examples: - * - * program.prompt('Username: ', function(name){ - * console.log('hi %s', name); - * }); - * - * program.prompt('Description:', function(desc){ - * console.log('description was "%s"', desc.trim()); - * }); - * - * @param {String|Object} str - * @param {Function} fn - * @api public - */ - -Command.prototype.prompt = function(str, fn){ - var self = this; - - if ('string' == typeof str) { - if (/ $/.test(str)) return this.promptSingleLine.apply(this, arguments); - this.promptMultiLine(str, fn); - } else { - var keys = Object.keys(str) - , obj = {}; - - function next() { - var key = keys.shift() - , label = str[key]; - - if (!key) return fn(obj); - self.prompt(label, function(val){ - obj[key] = val; - next(); - }); - } - - next(); - } -}; - -/** - * Prompt for password with `str`, `mask` char and callback `fn(val)`. - * - * The mask string defaults to '', aka no output is - * written while typing, you may want to use "*" etc. - * - * Examples: - * - * program.password('Password: ', function(pass){ - * console.log('got "%s"', pass); - * process.stdin.destroy(); - * }); - * - * program.password('Password: ', '*', function(pass){ - * console.log('got "%s"', pass); - * process.stdin.destroy(); - * }); - * - * @param {String} str - * @param {String} mask - * @param {Function} fn - * @api public - */ - -Command.prototype.password = function(str, mask, fn){ - var self = this - , buf = ''; - - // default mask - if ('function' == typeof mask) { - fn = mask; - mask = ''; - } - - process.stdin.resume(); - tty.setRawMode(true); - process.stdout.write(str); - - // keypress - process.stdin.on('keypress', function(c, key){ - if (key && 'enter' == key.name) { - console.log(); - process.stdin.removeAllListeners('keypress'); - tty.setRawMode(false); - if (!buf.trim().length) return self.password(str, mask, fn); - fn(buf); - return; - } - - if (key && key.ctrl && 'c' == key.name) { - console.log('%s', buf); - process.exit(); - } - - process.stdout.write(mask); - buf += c; - }).resume(); -}; - -/** - * Confirmation prompt with `str` and callback `fn(bool)` - * - * Examples: - * - * program.confirm('continue? ', function(ok){ - * console.log(' got %j', ok); - * process.stdin.destroy(); - * }); - * - * @param {String} str - * @param {Function} fn - * @api public - */ - - -Command.prototype.confirm = function(str, fn, verbose){ - var self = this; - this.prompt(str, function(ok){ - if (!ok.trim()) { - if (!verbose) str += '(yes or no) '; - return self.confirm(str, fn, true); - } - fn(parseBool(ok)); - }); -}; - -/** - * Choice prompt with `list` of items and callback `fn(index, item)` - * - * Examples: - * - * var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; - * - * console.log('Choose the coolest pet:'); - * program.choose(list, function(i){ - * console.log('you chose %d "%s"', i, list[i]); - * process.stdin.destroy(); - * }); - * - * @param {Array} list - * @param {Number|Function} index or fn - * @param {Function} fn - * @api public - */ - -Command.prototype.choose = function(list, index, fn){ - var self = this - , hasDefault = 'number' == typeof index; - - if (!hasDefault) { - fn = index; - index = null; - } - - list.forEach(function(item, i){ - if (hasDefault && i == index) { - console.log('* %d) %s', i + 1, item); - } else { - console.log(' %d) %s', i + 1, item); - } - }); - - function again() { - self.prompt(' : ', function(val){ - val = parseInt(val, 10) - 1; - if (hasDefault && isNaN(val)) val = index; - - if (null == list[val]) { - again(); - } else { - fn(val, list[val]); - } - }); - } - - again(); -}; - -/** - * Camel-case the given `flag` - * - * @param {String} flag - * @return {String} - * @api private - */ - -function camelcase(flag) { - return flag.split('-').reduce(function(str, word){ - return str + word[0].toUpperCase() + word.slice(1); - }); -} - -/** - * Parse a boolean `str`. - * - * @param {String} str - * @return {Boolean} - * @api private - */ - -function parseBool(str) { - return /^y|yes|ok|true$/i.test(str); -} - -/** - * Pad `str` to `width`. - * - * @param {String} str - * @param {Number} width - * @return {String} - * @api private - */ - -function pad(str, width) { - var len = Math.max(0, width - str.length); - return str + Array(len + 1).join(' '); -} - -/** - * Output help information if necessary - * - * @param {Command} command to output help for - * @param {Array} array of options to search for -h or --help - * @api private - */ - -function outputHelpIfNecessary(cmd, options) { - options = options || []; - for (var i = 0; i < options.length; i++) { - if (options[i] == '--help' || options[i] == '-h') { - process.stdout.write(cmd.helpInformation()); - cmd.emit('--help'); - process.exit(0); - } - } -} diff --git a/frontend/express/node_modules/express/node_modules/commander/package.json b/frontend/express/node_modules/express/node_modules/commander/package.json deleted file mode 100644 index 6f9d567f6d6..00000000000 --- a/frontend/express/node_modules/express/node_modules/commander/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "commander", - "version": "0.6.1", - "description": "the complete solution for node.js command-line programs", - "keywords": [ - "command", - "option", - "parser", - "prompt", - "stdin" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "repository": { - "type": "git", - "url": "https://github.com/visionmedia/commander.js.git" - }, - "dependencies": {}, - "devDependencies": { - "should": ">= 0.0.1" - }, - "scripts": { - "test": "make test" - }, - "main": "index", - "engines": { - "node": ">= 0.4.x" - }, - "readme": "# Commander.js\n\n The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).\n\n [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)\n\n## Installation\n\n $ npm install commander\n\n## Option parsing\n\n Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('commander');\n\nprogram\n .version('0.0.1')\n .option('-p, --peppers', 'Add peppers')\n .option('-P, --pineapple', 'Add pineapple')\n .option('-b, --bbq', 'Add bbq sauce')\n .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')\n .parse(process.argv);\n\nconsole.log('you ordered a pizza with:');\nif (program.peppers) console.log(' - peppers');\nif (program.pineapple) console.log(' - pineappe');\nif (program.bbq) console.log(' - bbq');\nconsole.log(' - %s cheese', program.cheese);\n```\n\n Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as \"--template-engine\" are camel-cased, becoming `program.templateEngine` etc.\n\n## Automated --help\n\n The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:\n\n``` \n $ ./examples/pizza --help\n\n Usage: pizza [options]\n\n Options:\n\n -V, --version output the version number\n -p, --peppers Add peppers\n -P, --pineapple Add pineappe\n -b, --bbq Add bbq sauce\n -c, --cheese Add the specified type of cheese [marble]\n -h, --help output usage information\n\n```\n\n## Coercion\n\n```js\nfunction range(val) {\n return val.split('..').map(Number);\n}\n\nfunction list(val) {\n return val.split(',');\n}\n\nprogram\n .version('0.0.1')\n .usage('[options] ')\n .option('-i, --integer ', 'An integer argument', parseInt)\n .option('-f, --float ', 'A float argument', parseFloat)\n .option('-r, --range ..', 'A range', range)\n .option('-l, --list ', 'A list', list)\n .option('-o, --optional [value]', 'An optional value')\n .parse(process.argv);\n\nconsole.log(' int: %j', program.integer);\nconsole.log(' float: %j', program.float);\nconsole.log(' optional: %j', program.optional);\nprogram.range = program.range || [];\nconsole.log(' range: %j..%j', program.range[0], program.range[1]);\nconsole.log(' list: %j', program.list);\nconsole.log(' args: %j', program.args);\n```\n\n## Custom help\n\n You can display arbitrary `-h, --help` information\n by listening for \"--help\". Commander will automatically\n exit once you are done so that the remainder of your program\n does not execute causing undesired behaviours, for example\n in the following executable \"stuff\" will not output when\n `--help` is used.\n\n```js\n#!/usr/bin/env node\n\n/**\n * Module dependencies.\n */\n\nvar program = require('../');\n\nfunction list(val) {\n return val.split(',').map(Number);\n}\n\nprogram\n .version('0.0.1')\n .option('-f, --foo', 'enable some foo')\n .option('-b, --bar', 'enable some bar')\n .option('-B, --baz', 'enable some baz');\n\n// must be before .parse() since\n// node's emit() is immediate\n\nprogram.on('--help', function(){\n console.log(' Examples:');\n console.log('');\n console.log(' $ custom-help --help');\n console.log(' $ custom-help -h');\n console.log('');\n});\n\nprogram.parse(process.argv);\n\nconsole.log('stuff');\n```\n\nyielding the following help output:\n\n```\n\nUsage: custom-help [options]\n\nOptions:\n\n -h, --help output usage information\n -V, --version output the version number\n -f, --foo enable some foo\n -b, --bar enable some bar\n -B, --baz enable some baz\n\nExamples:\n\n $ custom-help --help\n $ custom-help -h\n\n```\n\n## .prompt(msg, fn)\n\n Single-line prompt:\n\n```js\nprogram.prompt('name: ', function(name){\n console.log('hi %s', name);\n});\n```\n\n Multi-line prompt:\n\n```js\nprogram.prompt('description:', function(name){\n console.log('hi %s', name);\n});\n```\n\n Coercion:\n\n```js\nprogram.prompt('Age: ', Number, function(age){\n console.log('age: %j', age);\n});\n```\n\n```js\nprogram.prompt('Birthdate: ', Date, function(date){\n console.log('date: %s', date);\n});\n```\n\n## .password(msg[, mask], fn)\n\nPrompt for password without echoing:\n\n```js\nprogram.password('Password: ', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\nPrompt for password with mask char \"*\":\n\n```js\nprogram.password('Password: ', '*', function(pass){\n console.log('got \"%s\"', pass);\n process.stdin.destroy();\n});\n```\n\n## .confirm(msg, fn)\n\n Confirm with the given `msg`:\n\n```js\nprogram.confirm('continue? ', function(ok){\n console.log(' got %j', ok);\n});\n```\n\n## .choose(list, fn)\n\n Let the user choose from a `list`:\n\n```js\nvar list = ['tobi', 'loki', 'jane', 'manny', 'luna'];\n\nconsole.log('Choose the coolest pet:');\nprogram.choose(list, function(i){\n console.log('you chose %d \"%s\"', i, list[i]);\n});\n```\n\n## Links\n\n - [API documentation](http://visionmedia.github.com/commander.js/)\n - [ascii tables](https://github.com/LearnBoost/cli-table)\n - [progress bars](https://github.com/visionmedia/node-progress)\n - [more progress bars](https://github.com/substack/node-multimeter)\n - [examples](https://github.com/visionmedia/commander.js/tree/master/examples)\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/commander.js/issues" - }, - "_id": "commander@0.6.1", - "_from": "commander@0.6.1" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/.npmignore b/frontend/express/node_modules/express/node_modules/connect/.npmignore deleted file mode 100644 index 9046dde51c6..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -*.markdown -*.md -.git* -Makefile -benchmarks/ -docs/ -examples/ -install.sh -support/ -test/ -.DS_Store -coverage.html diff --git a/frontend/express/node_modules/express/node_modules/connect/.travis.yml b/frontend/express/node_modules/express/node_modules/connect/.travis.yml deleted file mode 100644 index a12e3f0fdeb..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/LICENSE b/frontend/express/node_modules/express/node_modules/connect/LICENSE deleted file mode 100644 index 0c5d22d96df..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -(The MIT License) - -Copyright (c) 2010 Sencha Inc. -Copyright (c) 2011 LearnBoost -Copyright (c) 2011 TJ Holowaychuk - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/Readme.md b/frontend/express/node_modules/express/node_modules/connect/Readme.md deleted file mode 100644 index 7d65f9c15f9..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/Readme.md +++ /dev/null @@ -1,133 +0,0 @@ -[![build status](https://secure.travis-ci.org/senchalabs/connect.png)](http://travis-ci.org/senchalabs/connect) -# Connect - - Connect is an extensible HTTP server framework for [node](http://nodejs.org), providing high performance "plugins" known as _middleware_. - - Connect is bundled with over _20_ commonly used middleware, including - a logger, session support, cookie parser, and [more](http://senchalabs.github.com/connect). Be sure to view the 2.x [documentation](http://senchalabs.github.com/connect/). - -```js -var connect = require('connect') - , http = require('http'); - -var app = connect() - .use(connect.favicon()) - .use(connect.logger('dev')) - .use(connect.static('public')) - .use(connect.directory('public')) - .use(connect.cookieParser()) - .use(connect.session({ secret: 'my secret here' })) - .use(function(req, res){ - res.end('Hello from Connect!\n'); - }); - -http.createServer(app).listen(3000); -``` - -## Middleware - - - [csrf](http://www.senchalabs.org/connect/csrf.html) - - [basicAuth](http://www.senchalabs.org/connect/basicAuth.html) - - [bodyParser](http://www.senchalabs.org/connect/bodyParser.html) - - [json](http://www.senchalabs.org/connect/json.html) - - [multipart](http://www.senchalabs.org/connect/multipart.html) - - [urlencoded](http://www.senchalabs.org/connect/urlencoded.html) - - [cookieParser](http://www.senchalabs.org/connect/cookieParser.html) - - [directory](http://www.senchalabs.org/connect/directory.html) - - [compress](http://www.senchalabs.org/connect/compress.html) - - [errorHandler](http://www.senchalabs.org/connect/errorHandler.html) - - [favicon](http://www.senchalabs.org/connect/favicon.html) - - [limit](http://www.senchalabs.org/connect/limit.html) - - [logger](http://www.senchalabs.org/connect/logger.html) - - [methodOverride](http://www.senchalabs.org/connect/methodOverride.html) - - [query](http://www.senchalabs.org/connect/query.html) - - [responseTime](http://www.senchalabs.org/connect/responseTime.html) - - [session](http://www.senchalabs.org/connect/session.html) - - [static](http://www.senchalabs.org/connect/static.html) - - [staticCache](http://www.senchalabs.org/connect/staticCache.html) - - [vhost](http://www.senchalabs.org/connect/vhost.html) - - [subdomains](http://www.senchalabs.org/connect/subdomains.html) - - [cookieSession](http://www.senchalabs.org/connect/cookieSession.html) - -## Running Tests - -first: - - $ npm install -d - -then: - - $ make test - -## Authors - - Below is the output from [git-summary](http://github.com/visionmedia/git-extras). - - - project: connect - commits: 2033 - active : 301 days - files : 171 - authors: - 1414 Tj Holowaychuk 69.6% - 298 visionmedia 14.7% - 191 Tim Caswell 9.4% - 51 TJ Holowaychuk 2.5% - 10 Ryan Olds 0.5% - 8 Astro 0.4% - 5 Nathan Rajlich 0.2% - 5 Jakub NeÅ¡etÅ™il 0.2% - 3 Daniel Dickison 0.1% - 3 David Rio Deiros 0.1% - 3 Alexander Simmerl 0.1% - 3 Andreas Lind Petersen 0.1% - 2 Aaron Heckmann 0.1% - 2 Jacques Crocker 0.1% - 2 Fabian Jakobs 0.1% - 2 Brian J Brennan 0.1% - 2 Adam Malcontenti-Wilson 0.1% - 2 Glen Mailer 0.1% - 2 James Campos 0.1% - 1 Trent Mick 0.0% - 1 Troy Kruthoff 0.0% - 1 Wei Zhu 0.0% - 1 comerc 0.0% - 1 darobin 0.0% - 1 nateps 0.0% - 1 Marco Sanson 0.0% - 1 Arthur Taylor 0.0% - 1 Aseem Kishore 0.0% - 1 Bart Teeuwisse 0.0% - 1 Cameron Howey 0.0% - 1 Chad Weider 0.0% - 1 Craig Barnes 0.0% - 1 Eran Hammer-Lahav 0.0% - 1 Gregory McWhirter 0.0% - 1 Guillermo Rauch 0.0% - 1 Jae Kwon 0.0% - 1 Jakub Nesetril 0.0% - 1 Joshua Peek 0.0% - 1 Jxck 0.0% - 1 AJ ONeal 0.0% - 1 Michael Hemesath 0.0% - 1 Morten Siebuhr 0.0% - 1 Samori Gorse 0.0% - 1 Tom Jensen 0.0% - -## Node Compatibility - - Connect `< 1.x` is compatible with node 0.2.x - - - Connect `1.x` is compatible with node 0.4.x - - - Connect (_master_) `2.x` is compatible with node 0.6.x - -## CLA - - [http://sencha.com/cla](http://sencha.com/cla) - -## License - -View the [LICENSE](https://github.com/senchalabs/connect/blob/master/LICENSE) file. The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons used by the `directory` middleware created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/). diff --git a/frontend/express/node_modules/express/node_modules/connect/index.js b/frontend/express/node_modules/express/node_modules/connect/index.js deleted file mode 100644 index 23240eedaa5..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = process.env.CONNECT_COV - ? require('./lib-cov/connect') - : require('./lib/connect'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/cache.js b/frontend/express/node_modules/express/node_modules/connect/lib/cache.js deleted file mode 100644 index 052fcdb3d5c..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/cache.js +++ /dev/null @@ -1,81 +0,0 @@ - -/*! - * Connect - Cache - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Expose `Cache`. - */ - -module.exports = Cache; - -/** - * LRU cache store. - * - * @param {Number} limit - * @api private - */ - -function Cache(limit) { - this.store = {}; - this.keys = []; - this.limit = limit; -} - -/** - * Touch `key`, promoting the object. - * - * @param {String} key - * @param {Number} i - * @api private - */ - -Cache.prototype.touch = function(key, i){ - this.keys.splice(i,1); - this.keys.push(key); -}; - -/** - * Remove `key`. - * - * @param {String} key - * @api private - */ - -Cache.prototype.remove = function(key){ - delete this.store[key]; -}; - -/** - * Get the object stored for `key`. - * - * @param {String} key - * @return {Array} - * @api private - */ - -Cache.prototype.get = function(key){ - return this.store[key]; -}; - -/** - * Add a cache `key`. - * - * @param {String} key - * @return {Array} - * @api private - */ - -Cache.prototype.add = function(key){ - // initialize store - var len = this.keys.push(key); - - // limit reached, invalidate LRU - if (len > this.limit) this.remove(this.keys.shift()); - - var arr = this.store[key] = []; - arr.createdAt = new Date; - return arr; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/connect.js b/frontend/express/node_modules/express/node_modules/connect/lib/connect.js deleted file mode 100644 index 72961dca712..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/connect.js +++ /dev/null @@ -1,92 +0,0 @@ -/*! - * Connect - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter - , proto = require('./proto') - , utils = require('./utils') - , path = require('path') - , basename = path.basename - , fs = require('fs'); - -// node patches - -require('./patch'); - -// expose createServer() as the module - -exports = module.exports = createServer; - -/** - * Framework version. - */ - -exports.version = '2.7.11'; - -/** - * Expose mime module. - */ - -exports.mime = require('./middleware/static').mime; - -/** - * Expose the prototype. - */ - -exports.proto = proto; - -/** - * Auto-load middleware getters. - */ - -exports.middleware = {}; - -/** - * Expose utilities. - */ - -exports.utils = utils; - -/** - * Create a new connect server. - * - * @return {Function} - * @api public - */ - -function createServer() { - function app(req, res, next){ app.handle(req, res, next); } - utils.merge(app, proto); - utils.merge(app, EventEmitter.prototype); - app.route = '/'; - app.stack = []; - for (var i = 0; i < arguments.length; ++i) { - app.use(arguments[i]); - } - return app; -}; - -/** - * Support old `.createServer()` method. - */ - -createServer.createServer = createServer; - -/** - * Auto-load bundled middleware with getters. - */ - -fs.readdirSync(__dirname + '/middleware').forEach(function(filename){ - if (!/\.js$/.test(filename)) return; - var name = basename(filename, '.js'); - function load(){ return require('./middleware/' + name); } - exports.middleware.__defineGetter__(name, load); - exports.__defineGetter__(name, load); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/http.js b/frontend/express/node_modules/express/node_modules/connect/lib/http.js deleted file mode 100644 index 1d35f1259c0..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/http.js +++ /dev/null @@ -1,218 +0,0 @@ - -/*! - * Connect - HTTPServer - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , parse = require('url').parse - , assert = require('assert') - , utils = require('./utils'); - -// environment - -var env = process.env.NODE_ENV || 'development'; - -/** - * Initialize a new `Server` with the given `middleware`. - * - * Examples: - * - * var server = connect.createServer( - * connect.favicon() - * , connect.logger() - * , connect.static(__dirname + '/public') - * ); - * - * @params {Array} middleware - * @return {Server} - * @api public - */ - -var Server = exports.Server = function HTTPServer(middleware) { - this.stack = []; - middleware.forEach(function(fn){ - this.use(fn); - }, this); - http.Server.call(this, this.handle); -}; - -/** - * Inherit from `http.Server.prototype`. - */ - -Server.prototype.__proto__ = http.Server.prototype; - -/** - * Utilize the given middleware `handle` to the given `route`, - * defaulting to _/_. This "route" is the mount-point for the - * middleware, when given a value other than _/_ the middleware - * is only effective when that segment is present in the request's - * pathname. - * - * For example if we were to mount a function at _/admin_, it would - * be invoked on _/admin_, and _/admin/settings_, however it would - * not be invoked for _/_, or _/posts_. - * - * This is effectively the same as passing middleware to `connect.createServer()`, - * however provides a progressive api. - * - * Examples: - * - * var server = connect.createServer(); - * server.use(connect.favicon()); - * server.use(connect.logger()); - * server.use(connect.static(__dirname + '/public')); - * - * If we wanted to prefix static files with _/public_, we could - * "mount" the `static()` middleware: - * - * server.use('/public', connect.static(__dirname + '/public')); - * - * This api is chainable, meaning the following is valid: - * - * connect.createServer() - * .use(connect.favicon()) - * .use(connect.logger()) - * .use(connect.static(__dirname + '/public')) - * .listen(3000); - * - * @param {String|Function} route or handle - * @param {Function} handle - * @return {Server} - * @api public - */ - -Server.prototype.use = function(route, handle){ - this.route = '/'; - - // default route to '/' - if ('string' != typeof route) { - handle = route; - route = '/'; - } - - // wrap sub-apps - if ('function' == typeof handle.handle) { - var server = handle; - server.route = route; - handle = function(req, res, next) { - server.handle(req, res, next); - }; - } - - // wrap vanilla http.Servers - if (handle instanceof http.Server) { - handle = handle.listeners('request')[0]; - } - - // normalize route to not trail with slash - if ('/' == route[route.length - 1]) { - route = route.substr(0, route.length - 1); - } - - // add the middleware - this.stack.push({ route: route, handle: handle }); - - // allow chaining - return this; -}; - -/** - * Handle server requests, punting them down - * the middleware stack. - * - * @api private - */ - -Server.prototype.handle = function(req, res, out) { - var writeHead = res.writeHead - , stack = this.stack - , removed = '' - , index = 0; - - function next(err) { - var layer, path, c; - req.url = removed + req.url; - req.originalUrl = req.originalUrl || req.url; - removed = ''; - - layer = stack[index++]; - - // all done - if (!layer || res.headerSent) { - // but wait! we have a parent - if (out) return out(err); - - // error - if (err) { - var msg = 'production' == env - ? 'Internal Server Error' - : err.stack || err.toString(); - - // output to stderr in a non-test env - if ('test' != env) console.error(err.stack || err.toString()); - - // unable to respond - if (res.headerSent) return req.socket.destroy(); - - res.statusCode = 500; - res.setHeader('Content-Type', 'text/plain'); - if ('HEAD' == req.method) return res.end(); - res.end(msg); - } else { - res.statusCode = 404; - res.setHeader('Content-Type', 'text/plain'); - if ('HEAD' == req.method) return res.end(); - res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl)); - } - return; - } - - try { - path = parse(req.url).pathname; - if (undefined == path) path = '/'; - - // skip this layer if the route doesn't match. - if (0 != path.indexOf(layer.route)) return next(err); - - c = path[layer.route.length]; - if (c && '/' != c && '.' != c) return next(err); - - // Call the layer handler - // Trim off the part of the url that matches the route - removed = layer.route; - req.url = req.url.substr(removed.length); - - // Ensure leading slash - if ('/' != req.url[0]) req.url = '/' + req.url; - - var arity = layer.handle.length; - if (err) { - if (arity === 4) { - layer.handle(err, req, res, next); - } else { - next(err); - } - } else if (arity < 4) { - layer.handle(req, res, next); - } else { - next(); - } - } catch (e) { - if (e instanceof assert.AssertionError) { - console.error(e.stack + '\n'); - next(e); - } else { - next(e); - } - } - } - next(); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/https.js b/frontend/express/node_modules/express/node_modules/connect/lib/https.js deleted file mode 100644 index 9b09fa49344..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/https.js +++ /dev/null @@ -1,47 +0,0 @@ - -/*! - * Connect - HTTPServer - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var HTTPServer = require('./http').Server - , https = require('https'); - -/** - * Initialize a new `Server` with the given - *`options` and `middleware`. The HTTPS api - * is identical to the [HTTP](http.html) server, - * however TLS `options` must be provided before - * passing in the optional middleware. - * - * @params {Object} options - * @params {Array} middleawre - * @return {Server} - * @api public - */ - -var Server = exports.Server = function HTTPSServer(options, middleware) { - this.stack = []; - middleware.forEach(function(fn){ - this.use(fn); - }, this); - https.Server.call(this, options, this.handle); -}; - -/** - * Inherit from `http.Server.prototype`. - */ - -Server.prototype.__proto__ = https.Server.prototype; - -// mixin HTTPServer methods - -Object.keys(HTTPServer.prototype).forEach(function(method){ - Server.prototype[method] = HTTPServer.prototype[method]; -}); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/index.js b/frontend/express/node_modules/express/node_modules/connect/lib/index.js deleted file mode 100644 index 2618ddca415..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/index.js +++ /dev/null @@ -1,50 +0,0 @@ - -/** - * Connect is a middleware framework for node, - * shipping with over 18 bundled middleware and a rich selection of - * 3rd-party middleware. - * - * var app = connect() - * .use(connect.logger('dev')) - * .use(connect.static('public')) - * .use(function(req, res){ - * res.end('hello world\n'); - * }) - * .listen(3000); - * - * Installation: - * - * $ npm install connect - * - * Middleware: - * - * - [logger](logger.html) request logger with custom format support - * - [csrf](csrf.html) Cross-site request forgery protection - * - [compress](compress.html) Gzip compression middleware - * - [basicAuth](basicAuth.html) basic http authentication - * - [bodyParser](bodyParser.html) extensible request body parser - * - [json](json.html) application/json parser - * - [urlencoded](urlencoded.html) application/x-www-form-urlencoded parser - * - [multipart](multipart.html) multipart/form-data parser - * - [timeout](timeout.html) request timeouts - * - [cookieParser](cookieParser.html) cookie parser - * - [session](session.html) session management support with bundled MemoryStore - * - [cookieSession](cookieSession.html) cookie-based session support - * - [methodOverride](methodOverride.html) faux HTTP method support - * - [responseTime](responseTime.html) calculates response-time and exposes via X-Response-Time - * - [staticCache](staticCache.html) memory cache layer for the static() middleware - * - [static](static.html) streaming static file server supporting `Range` and more - * - [directory](directory.html) directory listing middleware - * - [vhost](vhost.html) virtual host sub-domain mapping middleware - * - [favicon](favicon.html) efficient favicon server (with default icon) - * - [limit](limit.html) limit the bytesize of request bodies - * - [query](query.html) automatic querystring parser, populating `req.query` - * - [errorHandler](errorHandler.html) flexible error handler - * - * Links: - * - * - list of [3rd-party](https://github.com/senchalabs/connect/wiki) middleware - * - GitHub [repository](http://github.com/senchalabs/connect) - * - [test documentation](https://github.com/senchalabs/connect/blob/gh-pages/tests.md) - * - */ \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js deleted file mode 100644 index bc7ec97aa7d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js +++ /dev/null @@ -1,103 +0,0 @@ - -/*! - * Connect - basicAuth - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , unauthorized = utils.unauthorized; - -/** - * Basic Auth: - * - * Enfore basic authentication by providing a `callback(user, pass)`, - * which must return `true` in order to gain access. Alternatively an async - * method is provided as well, invoking `callback(user, pass, callback)`. Populates - * `req.user`. The final alternative is simply passing username / password - * strings. - * - * Simple username and password - * - * connect(connect.basicAuth('username', 'password')); - * - * Callback verification - * - * connect() - * .use(connect.basicAuth(function(user, pass){ - * return 'tj' == user & 'wahoo' == pass; - * })) - * - * Async callback verification, accepting `fn(err, user)`. - * - * connect() - * .use(connect.basicAuth(function(user, pass, fn){ - * User.authenticate({ user: user, pass: pass }, fn); - * })) - * - * @param {Function|String} callback or username - * @param {String} realm - * @api public - */ - -module.exports = function basicAuth(callback, realm) { - var username, password; - - // user / pass strings - if ('string' == typeof callback) { - username = callback; - password = realm; - if ('string' != typeof password) throw new Error('password argument required'); - realm = arguments[2]; - callback = function(user, pass){ - return user == username && pass == password; - } - } - - realm = realm || 'Authorization Required'; - - return function(req, res, next) { - var authorization = req.headers.authorization; - - if (req.user) return next(); - if (!authorization) return unauthorized(res, realm); - - var parts = authorization.split(' '); - - if (parts.length !== 2) return next(utils.error(400)); - - var scheme = parts[0] - , credentials = new Buffer(parts[1], 'base64').toString() - , index = credentials.indexOf(':'); - - if ('Basic' != scheme || index < 0) return next(utils.error(400)); - - var user = credentials.slice(0, index) - , pass = credentials.slice(index + 1); - - // async - if (callback.length >= 3) { - var pause = utils.pause(req); - callback(user, pass, function(err, user){ - if (err || !user) return unauthorized(res, realm); - req.user = req.remoteUser = user; - next(); - pause.resume(); - }); - // sync - } else { - if (callback(user, pass)) { - req.user = req.remoteUser = user; - next(); - } else { - unauthorized(res, realm); - } - } - } -}; - diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js deleted file mode 100644 index 9f692cdcaac..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js +++ /dev/null @@ -1,61 +0,0 @@ - -/*! - * Connect - bodyParser - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var multipart = require('./multipart') - , urlencoded = require('./urlencoded') - , json = require('./json'); - -/** - * Body parser: - * - * Parse request bodies, supports _application/json_, - * _application/x-www-form-urlencoded_, and _multipart/form-data_. - * - * This is equivalent to: - * - * app.use(connect.json()); - * app.use(connect.urlencoded()); - * app.use(connect.multipart()); - * - * Examples: - * - * connect() - * .use(connect.bodyParser()) - * .use(function(req, res) { - * res.end('viewing user ' + req.body.user.name); - * }); - * - * $ curl -d 'user[name]=tj' http://local/ - * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/ - * - * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function bodyParser(options){ - var _urlencoded = urlencoded(options) - , _multipart = multipart(options) - , _json = json(options); - - return function bodyParser(req, res, next) { - _json(req, res, function(err){ - if (err) return next(err); - _urlencoded(req, res, function(err){ - if (err) return next(err); - _multipart(req, res, next); - }); - }); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compiler.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compiler.js deleted file mode 100644 index dc4dd66aa90..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compiler.js +++ /dev/null @@ -1,163 +0,0 @@ - -/*! - * Connect - compiler - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var fs = require('fs') - , path = require('path') - , parse = require('url').parse; - -/** - * Require cache. - */ - -var cache = {}; - -/** - * Setup compiler. - * - * Options: - * - * - `src` Source directory, defaults to **CWD**. - * - `dest` Destination directory, defaults `src`. - * - `enable` Array of enabled compilers. - * - * Compilers: - * - * - `sass` Compiles sass to css - * - `less` Compiles less to css - * - `coffeescript` Compiles coffee to js - * - * @param {Object} options - * @api public - */ - -exports = module.exports = function compiler(options){ - options = options || {}; - - var srcDir = options.src || process.cwd() - , destDir = options.dest || srcDir - , enable = options.enable; - - if (!enable || enable.length === 0) { - throw new Error('compiler\'s "enable" option is not set, nothing will be compiled.'); - } - - return function compiler(req, res, next){ - if ('GET' != req.method) return next(); - var pathname = parse(req.url).pathname; - for (var i = 0, len = enable.length; i < len; ++i) { - var name = enable[i] - , compiler = compilers[name]; - if (compiler.match.test(pathname)) { - var src = (srcDir + pathname).replace(compiler.match, compiler.ext) - , dest = destDir + pathname; - - // Compare mtimes - fs.stat(src, function(err, srcStats){ - if (err) { - if ('ENOENT' == err.code) { - next(); - } else { - next(err); - } - } else { - fs.stat(dest, function(err, destStats){ - if (err) { - // Oh snap! it does not exist, compile it - if ('ENOENT' == err.code) { - compile(); - } else { - next(err); - } - } else { - // Source has changed, compile it - if (srcStats.mtime > destStats.mtime) { - compile(); - } else { - // Defer file serving - next(); - } - } - }); - } - }); - - // Compile to the destination - function compile() { - fs.readFile(src, 'utf8', function(err, str){ - if (err) { - next(err); - } else { - compiler.compile(str, function(err, str){ - if (err) { - next(err); - } else { - fs.writeFile(dest, str, 'utf8', function(err){ - next(err); - }); - } - }); - } - }); - } - return; - } - } - next(); - }; -}; - -/** - * Bundled compilers: - * - * - [sass](http://github.com/visionmedia/sass.js) to _css_ - * - [less](http://github.com/cloudhead/less.js) to _css_ - * - [coffee](http://github.com/jashkenas/coffee-script) to _js_ - */ - -var compilers = exports.compilers = { - sass: { - match: /\.css$/, - ext: '.sass', - compile: function(str, fn){ - var sass = cache.sass || (cache.sass = require('sass')); - try { - fn(null, sass.render(str)); - } catch (err) { - fn(err); - } - } - }, - less: { - match: /\.css$/, - ext: '.less', - compile: function(str, fn){ - var less = cache.less || (cache.less = require('less')); - try { - less.render(str, fn); - } catch (err) { - fn(err); - } - } - }, - coffeescript: { - match: /\.js$/, - ext: '.coffee', - compile: function(str, fn){ - var coffee = cache.coffee || (cache.coffee = require('coffee-script')); - try { - fn(null, coffee.compile(str)); - } catch (err) { - fn(err); - } - } - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compress.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compress.js deleted file mode 100644 index 97b2449158e..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/compress.js +++ /dev/null @@ -1,157 +0,0 @@ -/*! - * Connect - compress - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var zlib = require('zlib'); - -/** - * Supported content-encoding methods. - */ - -exports.methods = { - gzip: zlib.createGzip - , deflate: zlib.createDeflate -}; - -/** - * Default filter function. - */ - -exports.filter = function(req, res){ - return /json|text|javascript/.test(res.getHeader('Content-Type')); -}; - -/** - * Compress: - * - * Compress response data with gzip/deflate. - * - * Filter: - * - * A `filter` callback function may be passed to - * replace the default logic of: - * - * exports.filter = function(req, res){ - * return /json|text|javascript/.test(res.getHeader('Content-Type')); - * }; - * - * Options: - * - * All remaining options are passed to the gzip/deflate - * creation functions. Consult node's docs for additional details. - * - * - `chunkSize` (default: 16*1024) - * - `windowBits` - * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression - * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more - * - `strategy`: compression strategy - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function compress(options) { - options = options || {}; - var names = Object.keys(exports.methods) - , filter = options.filter || exports.filter; - - return function compress(req, res, next){ - var accept = req.headers['accept-encoding'] - , vary = res.getHeader('Vary') - , write = res.write - , end = res.end - , stream - , method; - - // vary - if (!vary) { - res.setHeader('Vary', 'Accept-Encoding'); - } else if (!~vary.indexOf('Accept-Encoding')) { - res.setHeader('Vary', vary + ', Accept-Encoding'); - } - - // see #724 - req.on('close', function(){ - res.write = res.end = function(){}; - }); - - // proxy - - res.write = function(chunk, encoding){ - if (!this.headerSent) this._implicitHeader(); - return stream - ? stream.write(new Buffer(chunk, encoding)) - : write.call(res, chunk, encoding); - }; - - res.end = function(chunk, encoding){ - if (chunk) this.write(chunk, encoding); - return stream - ? stream.end() - : end.call(res); - }; - - res.on('header', function(){ - var encoding = res.getHeader('Content-Encoding') || 'identity'; - - // already encoded - if ('identity' != encoding) return; - - // default request filter - if (!filter(req, res)) return; - - // SHOULD use identity - if (!accept) return; - - // head - if ('HEAD' == req.method) return; - - // default to gzip - if ('*' == accept.trim()) method = 'gzip'; - - // compression method - if (!method) { - for (var i = 0, len = names.length; i < len; ++i) { - if (~accept.indexOf(names[i])) { - method = names[i]; - break; - } - } - } - - // compression method - if (!method) return; - - // compression stream - stream = exports.methods[method](options); - - // header fields - res.setHeader('Content-Encoding', method); - res.removeHeader('Content-Length'); - - // compression - - stream.on('data', function(chunk){ - write.call(res, chunk); - }); - - stream.on('end', function(){ - end.call(res); - }); - - stream.on('drain', function() { - res.emit('drain'); - }); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js deleted file mode 100644 index 5da23f25803..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js +++ /dev/null @@ -1,62 +0,0 @@ - -/*! - * Connect - cookieParser - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./../utils') - , cookie = require('cookie'); - -/** - * Cookie parser: - * - * Parse _Cookie_ header and populate `req.cookies` - * with an object keyed by the cookie names. Optionally - * you may enabled signed cookie support by passing - * a `secret` string, which assigns `req.secret` so - * it may be used by other middleware. - * - * Examples: - * - * connect() - * .use(connect.cookieParser('optional secret string')) - * .use(function(req, res, next){ - * res.end(JSON.stringify(req.cookies)); - * }) - * - * @param {String} secret - * @return {Function} - * @api public - */ - -module.exports = function cookieParser(secret){ - return function cookieParser(req, res, next) { - if (req.cookies) return next(); - var cookies = req.headers.cookie; - - req.secret = secret; - req.cookies = {}; - req.signedCookies = {}; - - if (cookies) { - try { - req.cookies = cookie.parse(cookies); - if (secret) { - req.signedCookies = utils.parseSignedCookies(req.cookies, secret); - req.signedCookies = utils.parseJSONCookies(req.signedCookies); - } - req.cookies = utils.parseJSONCookies(req.cookies); - } catch (err) { - err.status = 400; - return next(err); - } - } - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js deleted file mode 100644 index 402fd55f4b5..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js +++ /dev/null @@ -1,117 +0,0 @@ - -/*! - * Connect - cookieSession - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('./../utils') - , Cookie = require('./session/cookie') - , debug = require('debug')('connect:cookieSession') - , signature = require('cookie-signature') - , crc32 = require('buffer-crc32'); - -/** - * Cookie Session: - * - * Cookie session middleware. - * - * var app = connect(); - * app.use(connect.cookieParser()); - * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }})); - * - * Options: - * - * - `key` cookie name defaulting to `connect.sess` - * - `secret` prevents cookie tampering - * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") - * - * Clearing sessions: - * - * To clear the session simply set its value to `null`, - * `cookieSession()` will then respond with a 1970 Set-Cookie. - * - * req.session = null; - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function cookieSession(options){ - // TODO: utilize Session/Cookie to unify API - options = options || {}; - var key = options.key || 'connect.sess' - , trustProxy = options.proxy; - - return function cookieSession(req, res, next) { - - // req.secret is for backwards compatibility - var secret = options.secret || req.secret; - if (!secret) throw new Error('`secret` option required for cookie sessions'); - - // default session - req.session = {}; - var cookie = req.session.cookie = new Cookie(options.cookie); - - // pathname mismatch - if (0 != req.originalUrl.indexOf(cookie.path)) return next(); - - // cookieParser secret - if (!options.secret && req.secret) { - req.session = req.signedCookies[key] || {}; - req.session.cookie = cookie; - } else { - // TODO: refactor - var rawCookie = req.cookies[key]; - if (rawCookie) { - var unsigned = utils.parseSignedCookie(rawCookie, secret); - if (unsigned) { - var originalHash = crc32.signed(unsigned); - req.session = utils.parseJSONCookie(unsigned) || {}; - req.session.cookie = cookie; - } - } - } - - res.on('header', function(){ - // removed - if (!req.session) { - debug('clear session'); - cookie.expires = new Date(0); - res.setHeader('Set-Cookie', cookie.serialize(key, '')); - return; - } - - delete req.session.cookie; - - // check security - var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase() - , tls = req.connection.encrypted || (trustProxy && 'https' == proto) - , secured = cookie.secure && tls; - - // only send secure cookies via https - if (cookie.secure && !secured) return debug('not secured'); - - // serialize - debug('serializing %j', req.session); - var val = 'j:' + JSON.stringify(req.session); - - // compare hashes, no need to set-cookie if unchanged - if (originalHash == crc32.signed(val)) return debug('unmodified session'); - - // set-cookie - val = 's:' + signature.sign(val, secret); - val = cookie.serialize(key, val); - debug('set-cookie %j', cookie); - res.setHeader('Set-Cookie', val); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/csrf.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/csrf.js deleted file mode 100644 index e3c353ea761..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/csrf.js +++ /dev/null @@ -1,73 +0,0 @@ -/*! - * Connect - csrf - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils'); - -/** - * Anti CSRF: - * - * CRSF protection middleware. - * - * By default this middleware generates a token named "_csrf" - * which should be added to requests which mutate - * state, within a hidden form field, query-string etc. This - * token is validated against the visitor's `req.session._csrf` - * property. - * - * The default `value` function checks `req.body` generated - * by the `bodyParser()` middleware, `req.query` generated - * by `query()`, and the "X-CSRF-Token" header field. - * - * This middleware requires session support, thus should be added - * somewhere _below_ `session()` and `cookieParser()`. - * - * Options: - * - * - `value` a function accepting the request, returning the token - * - * @param {Object} options - * @api public - */ - -module.exports = function csrf(options) { - options = options || {}; - var value = options.value || defaultValue; - - return function(req, res, next){ - // generate CSRF token - var token = req.session._csrf || (req.session._csrf = utils.uid(24)); - - // ignore these methods - if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next(); - - // determine value - var val = value(req); - - // check - if (val != token) return next(utils.error(403)); - - next(); - } -}; - -/** - * Default value function, checking the `req.body` - * and `req.query` for the CSRF token. - * - * @param {IncomingMessage} req - * @return {String} - * @api private - */ - -function defaultValue(req) { - return (req.body && req.body._csrf) - || (req.query && req.query._csrf) - || (req.headers['x-csrf-token']); -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/directory.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/directory.js deleted file mode 100644 index 1c925a7da3e..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/directory.js +++ /dev/null @@ -1,229 +0,0 @@ - -/*! - * Connect - directory - * Copyright(c) 2011 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -// TODO: icon / style for directories -// TODO: arrow key navigation -// TODO: make icons extensible - -/** - * Module dependencies. - */ - -var fs = require('fs') - , parse = require('url').parse - , utils = require('../utils') - , path = require('path') - , normalize = path.normalize - , extname = path.extname - , join = path.join; - -/*! - * Icon cache. - */ - -var cache = {}; - -/** - * Directory: - * - * Serve directory listings with the given `root` path. - * - * Options: - * - * - `hidden` display hidden (dot) files. Defaults to false. - * - `icons` display icons. Defaults to false. - * - `filter` Apply this filter function to files. Defaults to false. - * - * @param {String} root - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function directory(root, options){ - options = options || {}; - - // root required - if (!root) throw new Error('directory() root path required'); - var hidden = options.hidden - , icons = options.icons - , filter = options.filter - , root = normalize(root); - - return function directory(req, res, next) { - if ('GET' != req.method && 'HEAD' != req.method) return next(); - - var accept = req.headers.accept || 'text/plain' - , url = parse(req.url) - , dir = decodeURIComponent(url.pathname) - , path = normalize(join(root, dir)) - , originalUrl = parse(req.originalUrl) - , originalDir = decodeURIComponent(originalUrl.pathname) - , showUp = path != root && path != root + '/'; - - // null byte(s), bad request - if (~path.indexOf('\0')) return next(utils.error(400)); - - // malicious path, forbidden - if (0 != path.indexOf(root)) return next(utils.error(403)); - - // check if we have a directory - fs.stat(path, function(err, stat){ - if (err) return 'ENOENT' == err.code - ? next() - : next(err); - - if (!stat.isDirectory()) return next(); - - // fetch files - fs.readdir(path, function(err, files){ - if (err) return next(err); - if (!hidden) files = removeHidden(files); - if (filter) files = files.filter(filter); - files.sort(); - - // content-negotiation - for (var key in exports) { - if (~accept.indexOf(key) || ~accept.indexOf('*/*')) { - exports[key](req, res, files, next, originalDir, showUp, icons); - return; - } - } - - // not acceptable - next(utils.error(406)); - }); - }); - }; -}; - -/** - * Respond with text/html. - */ - -exports.html = function(req, res, files, next, dir, showUp, icons){ - fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){ - if (err) return next(err); - fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){ - if (err) return next(err); - if (showUp) files.unshift('..'); - str = str - .replace('{style}', style) - .replace('{files}', html(files, dir, icons)) - .replace('{directory}', dir) - .replace('{linked-path}', htmlPath(dir)); - res.setHeader('Content-Type', 'text/html'); - res.setHeader('Content-Length', str.length); - res.end(str); - }); - }); -}; - -/** - * Respond with application/json. - */ - -exports.json = function(req, res, files){ - files = JSON.stringify(files); - res.setHeader('Content-Type', 'application/json'); - res.setHeader('Content-Length', files.length); - res.end(files); -}; - -/** - * Respond with text/plain. - */ - -exports.plain = function(req, res, files){ - files = files.join('\n') + '\n'; - res.setHeader('Content-Type', 'text/plain'); - res.setHeader('Content-Length', files.length); - res.end(files); -}; - -/** - * Map html `dir`, returning a linked path. - */ - -function htmlPath(dir) { - var curr = []; - return dir.split('/').map(function(part){ - curr.push(part); - return '' + part + ''; - }).join(' / '); -} - -/** - * Map html `files`, returning an html unordered list. - */ - -function html(files, dir, useIcons) { - return '
      ' + files.map(function(file){ - var icon = '' - , classes = []; - - if (useIcons && '..' != file) { - icon = icons[extname(file)] || icons.default; - icon = ''; - classes.push('icon'); - } - - return '
    • ' - + icon + file + '
    • '; - - }).join('\n') + '
    '; -} - -/** - * Load and cache the given `icon`. - * - * @param {String} icon - * @return {String} - * @api private - */ - -function load(icon) { - if (cache[icon]) return cache[icon]; - return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64'); -} - -/** - * Filter "hidden" `files`, aka files - * beginning with a `.`. - * - * @param {Array} files - * @return {Array} - * @api private - */ - -function removeHidden(files) { - return files.filter(function(file){ - return '.' != file[0]; - }); -} - -/** - * Icon map. - */ - -var icons = { - '.js': 'page_white_code_red.png' - , '.c': 'page_white_c.png' - , '.h': 'page_white_h.png' - , '.cc': 'page_white_cplusplus.png' - , '.php': 'page_white_php.png' - , '.rb': 'page_white_ruby.png' - , '.cpp': 'page_white_cplusplus.png' - , '.swf': 'page_white_flash.png' - , '.pdf': 'page_white_acrobat.png' - , 'default': 'page_white.png' -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js deleted file mode 100644 index 4a84edca010..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * Connect - errorHandler - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , fs = require('fs'); - -// environment - -var env = process.env.NODE_ENV || 'development'; - -/** - * Error handler: - * - * Development error handler, providing stack traces - * and error message responses for requests accepting text, html, - * or json. - * - * Text: - * - * By default, and when _text/plain_ is accepted a simple stack trace - * or error message will be returned. - * - * JSON: - * - * When _application/json_ is accepted, connect will respond with - * an object in the form of `{ "error": error }`. - * - * HTML: - * - * When accepted connect will output a nice html stack trace. - * - * @return {Function} - * @api public - */ - -exports = module.exports = function errorHandler(){ - return function errorHandler(err, req, res, next){ - if (err.status) res.statusCode = err.status; - if (res.statusCode < 400) res.statusCode = 500; - if ('test' != env) console.error(err.stack); - var accept = req.headers.accept || ''; - // html - if (~accept.indexOf('html')) { - fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){ - fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){ - var stack = (err.stack || '') - .split('\n').slice(1) - .map(function(v){ return '
  • ' + v + '
  • '; }).join(''); - html = html - .replace('{style}', style) - .replace('{stack}', stack) - .replace('{title}', exports.title) - .replace('{statusCode}', res.statusCode) - .replace(/\{error\}/g, utils.escape(err.toString())); - res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.end(html); - }); - }); - // json - } else if (~accept.indexOf('json')) { - var error = { message: err.message, stack: err.stack }; - for (var prop in err) error[prop] = err[prop]; - var json = JSON.stringify({ error: error }); - res.setHeader('Content-Type', 'application/json'); - res.end(json); - // plain text - } else { - res.writeHead(res.statusCode, { 'Content-Type': 'text/plain' }); - res.end(err.stack); - } - }; -}; - -/** - * Template title, framework authors may override this value. - */ - -exports.title = 'Connect'; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/favicon.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/favicon.js deleted file mode 100644 index ef543544ce6..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/favicon.js +++ /dev/null @@ -1,80 +0,0 @@ -/*! - * Connect - favicon - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var fs = require('fs') - , utils = require('../utils'); - -/** - * Favicon: - * - * By default serves the connect favicon, or the favicon - * located by the given `path`. - * - * Options: - * - * - `maxAge` cache-control max-age directive, defaulting to 1 day - * - * Examples: - * - * Serve default favicon: - * - * connect() - * .use(connect.favicon()) - * - * Serve favicon before logging for brevity: - * - * connect() - * .use(connect.favicon()) - * .use(connect.logger('dev')) - * - * Serve custom favicon: - * - * connect() - * .use(connect.favicon('public/favicon.ico')) - * - * @param {String} path - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function favicon(path, options){ - var options = options || {} - , path = path || __dirname + '/../public/favicon.ico' - , maxAge = options.maxAge || 86400000 - , icon; // favicon cache - - return function favicon(req, res, next){ - if ('/favicon.ico' == req.url) { - if (icon) { - res.writeHead(200, icon.headers); - res.end(icon.body); - } else { - fs.readFile(path, function(err, buf){ - if (err) return next(err); - icon = { - headers: { - 'Content-Type': 'image/x-icon' - , 'Content-Length': buf.length - , 'ETag': '"' + utils.md5(buf) + '"' - , 'Cache-Control': 'public, max-age=' + (maxAge / 1000) - }, - body: buf - }; - res.writeHead(200, icon.headers); - res.end(icon.body); - }); - } - } else { - next(); - } - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/json.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/json.js deleted file mode 100644 index 17e591838a3..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/json.js +++ /dev/null @@ -1,86 +0,0 @@ - -/*! - * Connect - json - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , _limit = require('./limit'); - -/** - * noop middleware. - */ - -function noop(req, res, next) { - next(); -} - -/** - * JSON: - * - * Parse JSON request bodies, providing the - * parsed object as `req.body`. - * - * Options: - * - * - `strict` when `false` anything `JSON.parse()` accepts will be parsed - * - `reviver` used as the second "reviver" argument for JSON.parse - * - `limit` byte limit disabled by default - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - var options = options || {} - , strict = options.strict !== false; - - var limit = options.limit - ? _limit(options.limit) - : noop; - - return function json(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - - if (!utils.hasBody(req)) return next(); - - // check Content-Type - if ('application/json' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - var buf = ''; - req.setEncoding('utf8'); - req.on('data', function(chunk){ buf += chunk }); - req.on('end', function(){ - var first = buf.trim()[0]; - - if (0 == buf.length) { - return next(utils.error(400, 'invalid json, empty body')); - } - - if (strict && '{' != first && '[' != first) return next(utils.error(400, 'invalid json')); - try { - req.body = JSON.parse(buf, options.reviver); - } catch (err){ - err.body = buf; - err.status = 400; - return next(err); - } - next(); - }); - }); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/limit.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/limit.js deleted file mode 100644 index 09bd1c47ced..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/limit.js +++ /dev/null @@ -1,78 +0,0 @@ - -/*! - * Connect - limit - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils'), - brokenPause = utils.brokenPause; - -/** - * Limit: - * - * Limit request bodies to the given size in `bytes`. - * - * A string representation of the bytesize may also be passed, - * for example "5mb", "200kb", "1gb", etc. - * - * connect() - * .use(connect.limit('5.5mb')) - * .use(handleImageUpload) - * - * @param {Number|String} bytes - * @return {Function} - * @api public - */ - -module.exports = function limit(bytes){ - if ('string' == typeof bytes) bytes = utils.parseBytes(bytes); - if ('number' != typeof bytes) throw new Error('limit() bytes required'); - return function limit(req, res, next){ - var received = 0 - , len = req.headers['content-length'] - ? parseInt(req.headers['content-length'], 10) - : null; - - // self-awareness - if (req._limit) return next(); - req._limit = true; - - // limit by content-length - if (len && len > bytes) return next(utils.error(413)); - - // limit - if (brokenPause) { - listen(); - } else { - req.on('newListener', function handler(event) { - if (event !== 'data') return; - - req.removeListener('newListener', handler); - // Start listening at the end of the current loop - // otherwise the request will be consumed too early. - // Sideaffect is `limit` will miss the first chunk, - // but that's not a big deal. - // Unfortunately, the tests don't have large enough - // request bodies to test this. - process.nextTick(listen); - }); - }; - - next(); - - function listen() { - req.on('data', function(chunk) { - received += Buffer.isBuffer(chunk) - ? chunk.length : - Buffer.byteLength(chunk); - - if (received > bytes) req.destroy(); - }); - }; - }; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/logger.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/logger.js deleted file mode 100644 index de72244991a..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/logger.js +++ /dev/null @@ -1,339 +0,0 @@ -/*! - * Connect - logger - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var bytes = require('bytes'); - -/*! - * Log buffer. - */ - -var buf = []; - -/*! - * Default log buffer duration. - */ - -var defaultBufferDuration = 1000; - -/** - * Logger: - * - * Log requests with the given `options` or a `format` string. - * - * Options: - * - * - `format` Format string, see below for tokens - * - `stream` Output stream, defaults to _stdout_ - * - `buffer` Buffer duration, defaults to 1000ms when _true_ - * - `immediate` Write log line on request instead of response (for response times) - * - * Tokens: - * - * - `:req[header]` ex: `:req[Accept]` - * - `:res[header]` ex: `:res[Content-Length]` - * - `:http-version` - * - `:response-time` - * - `:remote-addr` - * - `:date` - * - `:method` - * - `:url` - * - `:referrer` - * - `:user-agent` - * - `:status` - * - * Formats: - * - * Pre-defined formats that ship with connect: - * - * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' - * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' - * - `tiny` ':method :url :status :res[content-length] - :response-time ms' - * - `dev` concise output colored by response status for development use - * - * Examples: - * - * connect.logger() // default - * connect.logger('short') - * connect.logger('tiny') - * connect.logger({ immediate: true, format: 'dev' }) - * connect.logger(':method :url - :referrer') - * connect.logger(':req[content-type] -> :res[content-type]') - * connect.logger(function(tokens, req, res){ return 'some format string' }) - * - * Defining Tokens: - * - * To define a token, simply invoke `connect.logger.token()` with the - * name and a callback function. The value returned is then available - * as ":type" in this case. - * - * connect.logger.token('type', function(req, res){ return req.headers['content-type']; }) - * - * Defining Formats: - * - * All default formats are defined this way, however it's public API as well: - * - * connect.logger.format('name', 'string or function') - * - * @param {String|Function|Object} format or options - * @return {Function} - * @api public - */ - -exports = module.exports = function logger(options) { - if ('object' == typeof options) { - options = options || {}; - } else if (options) { - options = { format: options }; - } else { - options = {}; - } - - // output on request instead of response - var immediate = options.immediate; - - // format name - var fmt = exports[options.format] || options.format || exports.default; - - // compile format - if ('function' != typeof fmt) fmt = compile(fmt); - - // options - var stream = options.stream || process.stdout - , buffer = options.buffer; - - // buffering support - if (buffer) { - var realStream = stream - , interval = 'number' == typeof buffer - ? buffer - : defaultBufferDuration; - - // flush interval - setInterval(function(){ - if (buf.length) { - realStream.write(buf.join('')); - buf.length = 0; - } - }, interval); - - // swap the stream - stream = { - write: function(str){ - buf.push(str); - } - }; - } - - return function logger(req, res, next) { - req._startTime = new Date; - - // immediate - if (immediate) { - var line = fmt(exports, req, res); - if (null == line) return; - stream.write(line + '\n'); - // proxy end to output logging - } else { - var end = res.end; - res.end = function(chunk, encoding){ - res.end = end; - res.end(chunk, encoding); - var line = fmt(exports, req, res); - if (null == line) return; - stream.write(line + '\n'); - }; - } - - - next(); - }; -}; - -/** - * Compile `fmt` into a function. - * - * @param {String} fmt - * @return {Function} - * @api private - */ - -function compile(fmt) { - fmt = fmt.replace(/"/g, '\\"'); - var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){ - return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "'; - }) + '";' - return new Function('tokens, req, res', js); -}; - -/** - * Define a token function with the given `name`, - * and callback `fn(req, res)`. - * - * @param {String} name - * @param {Function} fn - * @return {Object} exports for chaining - * @api public - */ - -exports.token = function(name, fn) { - exports[name] = fn; - return this; -}; - -/** - * Define a `fmt` with the given `name`. - * - * @param {String} name - * @param {String|Function} fmt - * @return {Object} exports for chaining - * @api public - */ - -exports.format = function(name, str){ - exports[name] = str; - return this; -}; - -/** - * Default format. - */ - -exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'); - -/** - * Short format. - */ - -exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'); - -/** - * Tiny format. - */ - -exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms'); - -/** - * dev (colored) - */ - -exports.format('dev', function(tokens, req, res){ - var status = res.statusCode - , len = parseInt(res.getHeader('Content-Length'), 10) - , color = 32; - - if (status >= 500) color = 31 - else if (status >= 400) color = 33 - else if (status >= 300) color = 36; - - len = isNaN(len) - ? '' - : len = ' - ' + bytes(len); - - return '\033[90m' + req.method - + ' ' + req.originalUrl + ' ' - + '\033[' + color + 'm' + res.statusCode - + ' \033[90m' - + (new Date - req._startTime) - + 'ms' + len - + '\033[0m'; -}); - -/** - * request url - */ - -exports.token('url', function(req){ - return req.originalUrl || req.url; -}); - -/** - * request method - */ - -exports.token('method', function(req){ - return req.method; -}); - -/** - * response time in milliseconds - */ - -exports.token('response-time', function(req){ - return new Date - req._startTime; -}); - -/** - * UTC date - */ - -exports.token('date', function(){ - return new Date().toUTCString(); -}); - -/** - * response status code - */ - -exports.token('status', function(req, res){ - return res.statusCode; -}); - -/** - * normalized referrer - */ - -exports.token('referrer', function(req){ - return req.headers['referer'] || req.headers['referrer']; -}); - -/** - * remote address - */ - -exports.token('remote-addr', function(req){ - if (req.ip) return req.ip; - var sock = req.socket; - if (sock.socket) return sock.socket.remoteAddress; - return sock.remoteAddress; -}); - -/** - * HTTP version - */ - -exports.token('http-version', function(req){ - return req.httpVersionMajor + '.' + req.httpVersionMinor; -}); - -/** - * UA string - */ - -exports.token('user-agent', function(req){ - return req.headers['user-agent']; -}); - -/** - * request header - */ - -exports.token('req', function(req, res, field){ - return req.headers[field.toLowerCase()]; -}); - -/** - * response header - */ - -exports.token('res', function(req, res, field){ - return (res._headers || {})[field.toLowerCase()]; -}); - diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js deleted file mode 100644 index aaf4014f26f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js +++ /dev/null @@ -1,40 +0,0 @@ - -/*! - * Connect - methodOverride - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Method Override: - * - * Provides faux HTTP method support. - * - * Pass an optional `key` to use when checking for - * a method override, othewise defaults to _\_method_. - * The original method is available via `req.originalMethod`. - * - * @param {String} key - * @return {Function} - * @api public - */ - -module.exports = function methodOverride(key){ - key = key || "_method"; - return function methodOverride(req, res, next) { - req.originalMethod = req.originalMethod || req.method; - - // req.body - if (req.body && key in req.body) { - req.method = req.body[key].toUpperCase(); - delete req.body[key]; - // check X-HTTP-Method-Override - } else if (req.headers['x-http-method-override']) { - req.method = req.headers['x-http-method-override'].toUpperCase(); - } - - next(); - }; -}; - diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/multipart.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/multipart.js deleted file mode 100644 index 7b26fae807a..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/multipart.js +++ /dev/null @@ -1,133 +0,0 @@ -/*! - * Connect - multipart - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var formidable = require('formidable') - , _limit = require('./limit') - , utils = require('../utils') - , qs = require('qs'); - -/** - * noop middleware. - */ - -function noop(req, res, next) { - next(); -} - -/** - * Multipart: - * - * Parse multipart/form-data request bodies, - * providing the parsed object as `req.body` - * and `req.files`. - * - * Configuration: - * - * The options passed are merged with [formidable](https://github.com/felixge/node-formidable)'s - * `IncomingForm` object, allowing you to configure the upload directory, - * size limits, etc. For example if you wish to change the upload dir do the following. - * - * app.use(connect.multipart({ uploadDir: path })); - * - * Options: - * - * - `limit` byte limit defaulting to none - * - `defer` defers processing and exposes the Formidable form object as `req.form`. - * `next()` is called without waiting for the form's "end" event. - * This option is useful if you need to bind to the "progress" event, for example. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - options = options || {}; - - var limit = options.limit - ? _limit(options.limit) - : noop; - - return function multipart(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - req.files = req.files || {}; - - if (!utils.hasBody(req)) return next(); - - // ignore GET - if ('GET' == req.method || 'HEAD' == req.method) return next(); - - // check Content-Type - if ('multipart/form-data' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - - var form = new formidable.IncomingForm - , data = {} - , files = {} - , done; - - Object.keys(options).forEach(function(key){ - form[key] = options[key]; - }); - - function ondata(name, val, data){ - if (Array.isArray(data[name])) { - data[name].push(val); - } else if (data[name]) { - data[name] = [data[name], val]; - } else { - data[name] = val; - } - } - - form.on('field', function(name, val){ - ondata(name, val, data); - }); - - form.on('file', function(name, val){ - ondata(name, val, files); - }); - - form.on('error', function(err){ - if (!options.defer) { - err.status = 400; - next(err); - } - done = true; - }); - - form.on('end', function(){ - if (done) return; - try { - req.body = qs.parse(data); - req.files = qs.parse(files); - if (!options.defer) next(); - } catch (err) { - form.emit('error', err); - } - }); - - form.parse(req); - - if (options.defer) { - req.form = form; - next(); - } - }); - } -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/profiler.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/profiler.js deleted file mode 100644 index b0b5bac46c0..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/profiler.js +++ /dev/null @@ -1,100 +0,0 @@ - -/*! - * Connect - profiler - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Profile the duration of a request. - * - * Typically this middleware should be utilized - * _above_ all others, as it proxies the `res.end()` - * method, being first allows it to encapsulate all - * other middleware. - * - * Example Output: - * - * GET / - * response time 2ms - * memory rss 52.00kb - * memory vsize 2.07mb - * heap before 3.76mb / 8.15mb - * heap after 3.80mb / 8.15mb - * - * @api public - */ - -module.exports = function profiler(){ - return function(req, res, next){ - var end = res.end - , start = snapshot(); - - // state snapshot - function snapshot() { - return { - mem: process.memoryUsage() - , time: new Date - }; - } - - // proxy res.end() - res.end = function(data, encoding){ - res.end = end; - res.end(data, encoding); - compare(req, start, snapshot()) - }; - - next(); - } -}; - -/** - * Compare `start` / `end` snapshots. - * - * @param {IncomingRequest} req - * @param {Object} start - * @param {Object} end - * @api private - */ - -function compare(req, start, end) { - console.log(); - row(req.method, req.url); - row('response time:', (end.time - start.time) + 'ms'); - row('memory rss:', formatBytes(end.mem.rss - start.mem.rss)); - row('memory vsize:', formatBytes(end.mem.vsize - start.mem.vsize)); - row('heap before:', formatBytes(start.mem.heapUsed) + ' / ' + formatBytes(start.mem.heapTotal)); - row('heap after:', formatBytes(end.mem.heapUsed) + ' / ' + formatBytes(end.mem.heapTotal)); - console.log(); -} - -/** - * Row helper - * - * @param {String} key - * @param {String} val - * @api private - */ - -function row(key, val) { - console.log(' \033[90m%s\033[0m \033[36m%s\033[0m', key, val); -} - -/** - * Format byte-size. - * - * @param {Number} bytes - * @return {String} - * @api private - */ - -function formatBytes(bytes) { - var kb = 1024 - , mb = 1024 * kb - , gb = 1024 * mb; - if (bytes < kb) return bytes + 'b'; - if (bytes < mb) return (bytes / kb).toFixed(2) + 'kb'; - if (bytes < gb) return (bytes / mb).toFixed(2) + 'mb'; - return (bytes / gb).toFixed(2) + 'gb'; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/query.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/query.js deleted file mode 100644 index 93fc5d347ba..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/query.js +++ /dev/null @@ -1,46 +0,0 @@ -/*! - * Connect - query - * Copyright(c) 2011 TJ Holowaychuk - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var qs = require('qs') - , parse = require('../utils').parseUrl; - -/** - * Query: - * - * Automatically parse the query-string when available, - * populating the `req.query` object. - * - * Examples: - * - * connect() - * .use(connect.query()) - * .use(function(req, res){ - * res.end(JSON.stringify(req.query)); - * }); - * - * The `options` passed are provided to qs.parse function. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function query(options){ - return function query(req, res, next){ - if (!req.query) { - req.query = ~req.url.indexOf('?') - ? qs.parse(parse(req).query, options) - : {}; - } - - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/responseTime.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/responseTime.js deleted file mode 100644 index 62abc049489..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/responseTime.js +++ /dev/null @@ -1,32 +0,0 @@ - -/*! - * Connect - responseTime - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Reponse time: - * - * Adds the `X-Response-Time` header displaying the response - * duration in milliseconds. - * - * @return {Function} - * @api public - */ - -module.exports = function responseTime(){ - return function(req, res, next){ - var start = new Date; - - if (res._responseTime) return next(); - res._responseTime = true; - - res.on('header', function(){ - var duration = new Date - start; - res.setHeader('X-Response-Time', duration + 'ms'); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/router.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/router.js deleted file mode 100644 index a07452e6b8a..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/router.js +++ /dev/null @@ -1,379 +0,0 @@ - -/*! - * Connect - router - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , parse = require('url').parse; - -/** - * Expose router. - */ - -exports = module.exports = router; - -/** - * Supported HTTP / WebDAV methods. - */ - -var _methods = exports.methods = [ - 'get' - , 'post' - , 'put' - , 'delete' - , 'connect' - , 'options' - , 'trace' - , 'copy' - , 'lock' - , 'mkcol' - , 'move' - , 'propfind' - , 'proppatch' - , 'unlock' - , 'report' - , 'mkactivity' - , 'checkout' - , 'merge' -]; - -/** - * Provides Sinatra and Express-like routing capabilities. - * - * Examples: - * - * connect.router(function(app){ - * app.get('/user/:id', function(req, res, next){ - * // populates req.params.id - * }); - * app.put('/user/:id', function(req, res, next){ - * // populates req.params.id - * }); - * }) - * - * @param {Function} fn - * @return {Function} - * @api public - */ - -function router(fn){ - var self = this - , methods = {} - , routes = {} - , params = {}; - - if (!fn) throw new Error('router provider requires a callback function'); - - // Generate method functions - _methods.forEach(function(method){ - methods[method] = generateMethodFunction(method.toUpperCase()); - }); - - // Alias del -> delete - methods.del = methods.delete; - - // Apply callback to all methods - methods.all = function(){ - var args = arguments; - _methods.forEach(function(name){ - methods[name].apply(this, args); - }); - return self; - }; - - // Register param callback - methods.param = function(name, fn){ - params[name] = fn; - }; - - fn.call(this, methods); - - function generateMethodFunction(name) { - var localRoutes = routes[name] = routes[name] || []; - return function(path, fn){ - var keys = [] - , middleware = []; - - // slice middleware - if (arguments.length > 2) { - middleware = Array.prototype.slice.call(arguments, 1, arguments.length); - fn = middleware.pop(); - middleware = utils.flatten(middleware); - } - - fn.middleware = middleware; - - if (!path) throw new Error(name + ' route requires a path'); - if (!fn) throw new Error(name + ' route ' + path + ' requires a callback'); - var regexp = path instanceof RegExp - ? path - : normalizePath(path, keys); - localRoutes.push({ - fn: fn - , path: regexp - , keys: keys - , orig: path - , method: name - }); - return self; - }; - } - - function router(req, res, next){ - var route - , self = this; - - (function pass(i){ - if (route = match(req, routes, i)) { - var i = 0 - , keys = route.keys; - - req.params = route.params; - - // Param preconditions - (function param(err) { - try { - var key = keys[i++] - , val = req.params[key] - , fn = params[key]; - - if ('route' == err) { - pass(req._route_index + 1); - // Error - } else if (err) { - next(err); - // Param has callback - } else if (fn) { - // Return style - if (1 == fn.length) { - req.params[key] = fn(val); - param(); - // Middleware style - } else { - fn(req, res, param, val); - } - // Finished processing params - } else if (!key) { - // route middleware - i = 0; - (function nextMiddleware(err){ - var fn = route.middleware[i++]; - if ('route' == err) { - pass(req._route_index + 1); - } else if (err) { - next(err); - } else if (fn) { - fn(req, res, nextMiddleware); - } else { - route.call(self, req, res, function(err){ - if (err) { - next(err); - } else { - pass(req._route_index + 1); - } - }); - } - })(); - // More params - } else { - param(); - } - } catch (err) { - next(err); - } - })(); - } else if ('OPTIONS' == req.method) { - options(req, res, routes); - } else { - next(); - } - })(); - }; - - router.remove = function(path, method){ - var fns = router.lookup(path, method); - fns.forEach(function(fn){ - routes[fn.method].splice(fn.index, 1); - }); - }; - - router.lookup = function(path, method, ret){ - ret = ret || []; - - // method specific lookup - if (method) { - method = method.toUpperCase(); - if (routes[method]) { - routes[method].forEach(function(route, i){ - if (path == route.orig) { - var fn = route.fn; - fn.regexp = route.path; - fn.keys = route.keys; - fn.path = route.orig; - fn.method = route.method; - fn.index = i; - ret.push(fn); - } - }); - } - // global lookup - } else { - _methods.forEach(function(method){ - router.lookup(path, method, ret); - }); - } - - return ret; - }; - - router.match = function(url, method, ret){ - var ret = ret || [] - , i = 0 - , fn - , req; - - // method specific matches - if (method) { - method = method.toUpperCase(); - req = { url: url, method: method }; - while (fn = match(req, routes, i)) { - i = req._route_index + 1; - ret.push(fn); - } - // global matches - } else { - _methods.forEach(function(method){ - router.match(url, method, ret); - }); - } - - return ret; - }; - - return router; -} - -/** - * Respond to OPTIONS. - * - * @param {ServerRequest} req - * @param {ServerResponse} req - * @param {Array} routes - * @api private - */ - -function options(req, res, routes) { - var pathname = parse(req.url).pathname - , body = optionsFor(pathname, routes).join(','); - res.writeHead(200, { - 'Content-Length': body.length - , 'Allow': body - }); - res.end(body); -} - -/** - * Return OPTIONS array for the given `path`, matching `routes`. - * - * @param {String} path - * @param {Array} routes - * @return {Array} - * @api private - */ - -function optionsFor(path, routes) { - return _methods.filter(function(method){ - var arr = routes[method.toUpperCase()]; - for (var i = 0, len = arr.length; i < len; ++i) { - if (arr[i].path.test(path)) return true; - } - }).map(function(method){ - return method.toUpperCase(); - }); -} - -/** - * Normalize the given path string, - * returning a regular expression. - * - * An empty array should be passed, - * which will contain the placeholder - * key names. For example "/user/:id" will - * then contain ["id"]. - * - * @param {String} path - * @param {Array} keys - * @return {RegExp} - * @api private - */ - -function normalizePath(path, keys) { - path = path - .concat('/?') - .replace(/\/\(/g, '(?:/') - .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){ - keys.push(key); - slash = slash || ''; - return '' - + (optional ? '' : slash) - + '(?:' - + (optional ? slash : '') - + (format || '') + (capture || '([^/]+?)') + ')' - + (optional || ''); - }) - .replace(/([\/.])/g, '\\$1') - .replace(/\*/g, '(.+)'); - return new RegExp('^' + path + '$', 'i'); -} - -/** - * Attempt to match the given request to - * one of the routes. When successful - * a route function is returned. - * - * @param {ServerRequest} req - * @param {Object} routes - * @return {Function} - * @api private - */ - -function match(req, routes, i) { - var captures - , method = req.method - , i = i || 0; - if ('HEAD' == method) method = 'GET'; - if (routes = routes[method]) { - var url = parse(req.url) - , pathname = url.pathname; - for (var len = routes.length; i < len; ++i) { - var route = routes[i] - , fn = route.fn - , path = route.path - , keys = fn.keys = route.keys; - if (captures = path.exec(pathname)) { - fn.method = method; - fn.params = []; - for (var j = 1, len = captures.length; j < len; ++j) { - var key = keys[j-1], - val = typeof captures[j] === 'string' - ? decodeURIComponent(captures[j]) - : captures[j]; - if (key) { - fn.params[key] = val; - } else { - fn.params.push(val); - } - } - req._route_index = i; - return fn; - } - } - } -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session.js deleted file mode 100644 index 9be6c8b6e83..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session.js +++ /dev/null @@ -1,356 +0,0 @@ - -/*! - * Connect - session - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var Session = require('./session/session') - , debug = require('debug')('connect:session') - , MemoryStore = require('./session/memory') - , signature = require('cookie-signature') - , Cookie = require('./session/cookie') - , Store = require('./session/store') - , utils = require('./../utils') - , parse = utils.parseUrl - , crc32 = require('buffer-crc32'); - -// environment - -var env = process.env.NODE_ENV; - -/** - * Expose the middleware. - */ - -exports = module.exports = session; - -/** - * Expose constructors. - */ - -exports.Store = Store; -exports.Cookie = Cookie; -exports.Session = Session; -exports.MemoryStore = MemoryStore; - -/** - * Warning message for `MemoryStore` usage in production. - */ - -var warning = 'Warning: connection.session() MemoryStore is not\n' - + 'designed for a production environment, as it will leak\n' - + 'memory, and will not scale past a single process.'; - -/** - * Session: - * - * Setup session store with the given `options`. - * - * Session data is _not_ saved in the cookie itself, however - * cookies are used, so we must use the [cookieParser()](cookieParser.html) - * middleware _before_ `session()`. - * - * Examples: - * - * connect() - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }})) - * - * Options: - * - * - `key` cookie name defaulting to `connect.sid` - * - `store` session store instance - * - `secret` session cookie is signed with this secret to prevent tampering - * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` - * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") - * - * Cookie option: - * - * By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set - * so the cookie becomes a browser-session cookie. When the user closes the - * browser the cookie (and session) will be removed. - * - * ## req.session - * - * To store or access session data, simply use the request property `req.session`, - * which is (generally) serialized as JSON by the store, so nested objects - * are typically fine. For example below is a user-specific view counter: - * - * connect() - * .use(connect.favicon()) - * .use(connect.cookieParser()) - * .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})) - * .use(function(req, res, next){ - * var sess = req.session; - * if (sess.views) { - * res.setHeader('Content-Type', 'text/html'); - * res.write('

    views: ' + sess.views + '

    '); - * res.write('

    expires in: ' + (sess.cookie.maxAge / 1000) + 's

    '); - * res.end(); - * sess.views++; - * } else { - * sess.views = 1; - * res.end('welcome to the session demo. refresh!'); - * } - * } - * )).listen(3000); - * - * ## Session#regenerate() - * - * To regenerate the session simply invoke the method, once complete - * a new SID and `Session` instance will be initialized at `req.session`. - * - * req.session.regenerate(function(err){ - * // will have a new session here - * }); - * - * ## Session#destroy() - * - * Destroys the session, removing `req.session`, will be re-generated next request. - * - * req.session.destroy(function(err){ - * // cannot access session here - * }); - * - * ## Session#reload() - * - * Reloads the session data. - * - * req.session.reload(function(err){ - * // session updated - * }); - * - * ## Session#save() - * - * Save the session. - * - * req.session.save(function(err){ - * // session saved - * }); - * - * ## Session#touch() - * - * Updates the `.maxAge` property. Typically this is - * not necessary to call, as the session middleware does this for you. - * - * ## Session#cookie - * - * Each session has a unique cookie object accompany it. This allows - * you to alter the session cookie per visitor. For example we can - * set `req.session.cookie.expires` to `false` to enable the cookie - * to remain for only the duration of the user-agent. - * - * ## Session#maxAge - * - * Alternatively `req.session.cookie.maxAge` will return the time - * remaining in milliseconds, which we may also re-assign a new value - * to adjust the `.expires` property appropriately. The following - * are essentially equivalent - * - * var hour = 3600000; - * req.session.cookie.expires = new Date(Date.now() + hour); - * req.session.cookie.maxAge = hour; - * - * For example when `maxAge` is set to `60000` (one minute), and 30 seconds - * has elapsed it will return `30000` until the current request has completed, - * at which time `req.session.touch()` is called to reset `req.session.maxAge` - * to its original value. - * - * req.session.cookie.maxAge; - * // => 30000 - * - * Session Store Implementation: - * - * Every session store _must_ implement the following methods - * - * - `.get(sid, callback)` - * - `.set(sid, session, callback)` - * - `.destroy(sid, callback)` - * - * Recommended methods include, but are not limited to: - * - * - `.length(callback)` - * - `.clear(callback)` - * - * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo. - * - * @param {Object} options - * @return {Function} - * @api public - */ - -function session(options){ - var options = options || {} - , key = options.key || 'connect.sid' - , store = options.store || new MemoryStore - , cookie = options.cookie || {} - , trustProxy = options.proxy - , storeReady = true; - - // notify user that this store is not - // meant for a production environment - if ('production' == env && store instanceof MemoryStore) { - console.warn(warning); - } - - // generates the new session - store.generate = function(req){ - req.sessionID = utils.uid(24); - req.session = new Session(req); - req.session.cookie = new Cookie(cookie); - }; - - store.on('disconnect', function(){ storeReady = false; }); - store.on('connect', function(){ storeReady = true; }); - - return function session(req, res, next) { - // self-awareness - if (req.session) return next(); - - // Handle connection as if there is no session if - // the store has temporarily disconnected etc - if (!storeReady) return debug('store is disconnected'), next(); - - // pathname mismatch - if (0 != req.originalUrl.indexOf(cookie.path || '/')) return next(); - - // backwards compatibility for signed cookies - // req.secret is passed from the cookie parser middleware - var secret = options.secret || req.secret; - - // ensure secret is available or bail - if (!secret) throw new Error('`secret` option required for sessions'); - - // parse url - var originalHash - , originalId; - - // expose store - req.sessionStore = store; - - // grab the session cookie value and check the signature - var rawCookie = req.cookies[key]; - - // get signedCookies for backwards compat with signed cookies - var unsignedCookie = req.signedCookies[key]; - - if (!unsignedCookie && rawCookie) { - unsignedCookie = utils.parseSignedCookie(rawCookie, secret); - } - - // set-cookie - res.on('header', function(){ - if (!req.session) return; - var cookie = req.session.cookie - , proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim() - , tls = req.connection.encrypted || (trustProxy && 'https' == proto) - , secured = cookie.secure && tls - , isNew = unsignedCookie != req.sessionID; - - // only send secure cookies via https - if (cookie.secure && !secured) return debug('not secured'); - - // long expires, handle expiry server-side - if (!isNew && cookie.hasLongExpires) return debug('already set cookie'); - - // browser-session length cookie - if (null == cookie.expires) { - if (!isNew) return debug('already set browser-session cookie'); - // compare hashes and ids - } else if (originalHash == hash(req.session) && originalId == req.session.id) { - return debug('unmodified session'); - } - - var val = 's:' + signature.sign(req.sessionID, secret); - val = cookie.serialize(key, val); - debug('set-cookie %s', val); - res.setHeader('Set-Cookie', val); - }); - - // proxy end() to commit the session - var end = res.end; - res.end = function(data, encoding){ - res.end = end; - if (!req.session) return res.end(data, encoding); - debug('saving'); - req.session.resetMaxAge(); - req.session.save(function(err){ - if (err) console.error(err.stack); - debug('saved'); - res.end(data, encoding); - }); - }; - - // generate the session - function generate() { - store.generate(req); - } - - // get the sessionID from the cookie - req.sessionID = unsignedCookie; - - // generate a session if the browser doesn't send a sessionID - if (!req.sessionID) { - debug('no SID sent, generating session'); - generate(); - next(); - return; - } - - // generate the session object - var pause = utils.pause(req); - debug('fetching %s', req.sessionID); - store.get(req.sessionID, function(err, sess){ - // proxy to resume() events - var _next = next; - next = function(err){ - _next(err); - pause.resume(); - }; - - // error handling - if (err) { - debug('error %j', err); - if ('ENOENT' == err.code) { - generate(); - next(); - } else { - next(err); - } - // no session - } else if (!sess) { - debug('no session found'); - generate(); - next(); - // populate req.session - } else { - debug('session found'); - store.createSession(req, sess); - originalId = req.sessionID; - originalHash = hash(sess); - next(); - } - }); - }; -}; - -/** - * Hash the given `sess` object omitting changes - * to `.cookie`. - * - * @param {Object} sess - * @return {String} - * @api private - */ - -function hash(sess) { - return crc32.signed(JSON.stringify(sess, function(key, val){ - if ('cookie' != key) return val; - })); -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js deleted file mode 100644 index cdce2a5e675..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js +++ /dev/null @@ -1,140 +0,0 @@ - -/*! - * Connect - session - Cookie - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../../utils') - , cookie = require('cookie'); - -/** - * Initialize a new `Cookie` with the given `options`. - * - * @param {IncomingMessage} req - * @param {Object} options - * @api private - */ - -var Cookie = module.exports = function Cookie(options) { - this.path = '/'; - this.maxAge = null; - this.httpOnly = true; - if (options) utils.merge(this, options); - this.originalMaxAge = undefined == this.originalMaxAge - ? this.maxAge - : this.originalMaxAge; -}; - -/*! - * Prototype. - */ - -Cookie.prototype = { - - /** - * Set expires `date`. - * - * @param {Date} date - * @api public - */ - - set expires(date) { - this._expires = date; - this.originalMaxAge = this.maxAge; - }, - - /** - * Get expires `date`. - * - * @return {Date} - * @api public - */ - - get expires() { - return this._expires; - }, - - /** - * Set expires via max-age in `ms`. - * - * @param {Number} ms - * @api public - */ - - set maxAge(ms) { - this.expires = 'number' == typeof ms - ? new Date(Date.now() + ms) - : ms; - }, - - /** - * Get expires max-age in `ms`. - * - * @return {Number} - * @api public - */ - - get maxAge() { - return this.expires instanceof Date - ? this.expires.valueOf() - Date.now() - : this.expires; - }, - - /** - * Return cookie data object. - * - * @return {Object} - * @api private - */ - - get data() { - return { - originalMaxAge: this.originalMaxAge - , expires: this._expires - , secure: this.secure - , httpOnly: this.httpOnly - , domain: this.domain - , path: this.path - } - }, - - /** - * Check if the cookie has a reasonably large max-age. - * - * @return {Boolean} - * @api private - */ - - get hasLongExpires() { - var week = 604800000; - return this.maxAge > (4 * week); - }, - - /** - * Return a serialized cookie string. - * - * @return {String} - * @api public - */ - - serialize: function(name, val){ - return cookie.serialize(name, val, this.data); - }, - - /** - * Return JSON representation of this cookie. - * - * @return {Object} - * @api private - */ - - toJSON: function(){ - return this.data; - } -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/memory.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/memory.js deleted file mode 100644 index fb939392801..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/memory.js +++ /dev/null @@ -1,129 +0,0 @@ - -/*! - * Connect - session - MemoryStore - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var Store = require('./store'); - -/** - * Initialize a new `MemoryStore`. - * - * @api public - */ - -var MemoryStore = module.exports = function MemoryStore() { - this.sessions = {}; -}; - -/** - * Inherit from `Store.prototype`. - */ - -MemoryStore.prototype.__proto__ = Store.prototype; - -/** - * Attempt to fetch session by the given `sid`. - * - * @param {String} sid - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.get = function(sid, fn){ - var self = this; - process.nextTick(function(){ - var expires - , sess = self.sessions[sid]; - if (sess) { - sess = JSON.parse(sess); - expires = 'string' == typeof sess.cookie.expires - ? new Date(sess.cookie.expires) - : sess.cookie.expires; - if (!expires || new Date < expires) { - fn(null, sess); - } else { - self.destroy(sid, fn); - } - } else { - fn(); - } - }); -}; - -/** - * Commit the given `sess` object associated with the given `sid`. - * - * @param {String} sid - * @param {Session} sess - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.set = function(sid, sess, fn){ - var self = this; - process.nextTick(function(){ - self.sessions[sid] = JSON.stringify(sess); - fn && fn(); - }); -}; - -/** - * Destroy the session associated with the given `sid`. - * - * @param {String} sid - * @api public - */ - -MemoryStore.prototype.destroy = function(sid, fn){ - var self = this; - process.nextTick(function(){ - delete self.sessions[sid]; - fn && fn(); - }); -}; - -/** - * Invoke the given callback `fn` with all active sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.all = function(fn){ - var arr = [] - , keys = Object.keys(this.sessions); - for (var i = 0, len = keys.length; i < len; ++i) { - arr.push(this.sessions[keys[i]]); - } - fn(null, arr); -}; - -/** - * Clear all sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.clear = function(fn){ - this.sessions = {}; - fn && fn(); -}; - -/** - * Fetch number of sessions. - * - * @param {Function} fn - * @api public - */ - -MemoryStore.prototype.length = function(fn){ - fn(null, Object.keys(this.sessions).length); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/session.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/session.js deleted file mode 100644 index 0dd4b400726..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/session.js +++ /dev/null @@ -1,116 +0,0 @@ - -/*! - * Connect - session - Session - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../../utils'); - -/** - * Create a new `Session` with the given request and `data`. - * - * @param {IncomingRequest} req - * @param {Object} data - * @api private - */ - -var Session = module.exports = function Session(req, data) { - Object.defineProperty(this, 'req', { value: req }); - Object.defineProperty(this, 'id', { value: req.sessionID }); - if ('object' == typeof data) utils.merge(this, data); -}; - -/** - * Update reset `.cookie.maxAge` to prevent - * the cookie from expiring when the - * session is still active. - * - * @return {Session} for chaining - * @api public - */ - -Session.prototype.touch = function(){ - return this.resetMaxAge(); -}; - -/** - * Reset `.maxAge` to `.originalMaxAge`. - * - * @return {Session} for chaining - * @api public - */ - -Session.prototype.resetMaxAge = function(){ - this.cookie.maxAge = this.cookie.originalMaxAge; - return this; -}; - -/** - * Save the session data with optional callback `fn(err)`. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.save = function(fn){ - this.req.sessionStore.set(this.id, this, fn || function(){}); - return this; -}; - -/** - * Re-loads the session data _without_ altering - * the maxAge properties. Invokes the callback `fn(err)`, - * after which time if no exception has occurred the - * `req.session` property will be a new `Session` object, - * although representing the same session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.reload = function(fn){ - var req = this.req - , store = this.req.sessionStore; - store.get(this.id, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(new Error('failed to load session')); - store.createSession(req, sess); - fn(); - }); - return this; -}; - -/** - * Destroy `this` session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.destroy = function(fn){ - delete this.req.session; - this.req.sessionStore.destroy(this.id, fn); - return this; -}; - -/** - * Regenerate this request's session. - * - * @param {Function} fn - * @return {Session} for chaining - * @api public - */ - -Session.prototype.regenerate = function(fn){ - this.req.sessionStore.regenerate(this.req, fn); - return this; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/store.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/store.js deleted file mode 100644 index 54294cbdf73..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/session/store.js +++ /dev/null @@ -1,84 +0,0 @@ - -/*! - * Connect - session - Store - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter - , Session = require('./session') - , Cookie = require('./cookie'); - -/** - * Initialize abstract `Store`. - * - * @api private - */ - -var Store = module.exports = function Store(options){}; - -/** - * Inherit from `EventEmitter.prototype`. - */ - -Store.prototype.__proto__ = EventEmitter.prototype; - -/** - * Re-generate the given requests's session. - * - * @param {IncomingRequest} req - * @return {Function} fn - * @api public - */ - -Store.prototype.regenerate = function(req, fn){ - var self = this; - this.destroy(req.sessionID, function(err){ - self.generate(req); - fn(err); - }); -}; - -/** - * Load a `Session` instance via the given `sid` - * and invoke the callback `fn(err, sess)`. - * - * @param {String} sid - * @param {Function} fn - * @api public - */ - -Store.prototype.load = function(sid, fn){ - var self = this; - this.get(sid, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(); - var req = { sessionID: sid, sessionStore: self }; - sess = self.createSession(req, sess); - fn(null, sess); - }); -}; - -/** - * Create session from JSON `sess` data. - * - * @param {IncomingRequest} req - * @param {Object} sess - * @return {Session} - * @api private - */ - -Store.prototype.createSession = function(req, sess){ - var expires = sess.cookie.expires - , orig = sess.cookie.originalMaxAge; - sess.cookie = new Cookie(sess.cookie); - if ('string' == typeof expires) sess.cookie.expires = new Date(expires); - sess.cookie.originalMaxAge = orig; - req.session = new Session(req, sess); - return req.session; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/static.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/static.js deleted file mode 100644 index 093e73f9620..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/static.js +++ /dev/null @@ -1,95 +0,0 @@ -/*! - * Connect - static - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var send = require('send') - , utils = require('../utils') - , parse = utils.parseUrl - , url = require('url'); - -/** - * Static: - * - * Static file server with the given `root` path. - * - * Examples: - * - * var oneDay = 86400000; - * - * connect() - * .use(connect.static(__dirname + '/public')) - * - * connect() - * .use(connect.static(__dirname + '/public', { maxAge: oneDay })) - * - * Options: - * - * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0 - * - `hidden` Allow transfer of hidden files. defaults to false - * - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true - * - `index` Default file name, defaults to 'index.html' - * - * @param {String} root - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(root, options){ - options = options || {}; - - // root required - if (!root) throw new Error('static() root path required'); - - // default redirect - var redirect = false !== options.redirect; - - return function static(req, res, next) { - if ('GET' != req.method && 'HEAD' != req.method) return next(); - var path = parse(req).pathname; - var pause = utils.pause(req); - - function resume() { - next(); - pause.resume(); - } - - function directory() { - if (!redirect) return resume(); - var pathname = url.parse(req.originalUrl).pathname; - res.statusCode = 301; - res.setHeader('Location', pathname + '/'); - res.end('Redirecting to ' + utils.escape(pathname) + '/'); - } - - function error(err) { - if (404 == err.status) return resume(); - next(err); - } - - send(req, path) - .maxage(options.maxAge || 0) - .root(root) - .index(options.index || 'index.html') - .hidden(options.hidden) - .on('error', error) - .on('directory', directory) - .pipe(res); - }; -}; - -/** - * Expose mime module. - * - * If you wish to extend the mime table use this - * reference to the "mime" module in the npm registry. - */ - -exports.mime = send.mime; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/staticCache.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/staticCache.js deleted file mode 100644 index 7354a8ffdb4..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/staticCache.js +++ /dev/null @@ -1,231 +0,0 @@ - -/*! - * Connect - staticCache - * Copyright(c) 2011 Sencha Inc. - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , Cache = require('../cache') - , fresh = require('fresh'); - -/** - * Static cache: - * - * Enables a memory cache layer on top of - * the `static()` middleware, serving popular - * static files. - * - * By default a maximum of 128 objects are - * held in cache, with a max of 256k each, - * totalling ~32mb. - * - * A Least-Recently-Used (LRU) cache algo - * is implemented through the `Cache` object, - * simply rotating cache objects as they are - * hit. This means that increasingly popular - * objects maintain their positions while - * others get shoved out of the stack and - * garbage collected. - * - * Benchmarks: - * - * static(): 2700 rps - * node-static: 5300 rps - * static() + staticCache(): 7500 rps - * - * Options: - * - * - `maxObjects` max cache objects [128] - * - `maxLength` max cache object length 256kb - * - * @param {Object} options - * @return {Function} - * @api public - */ - -module.exports = function staticCache(options){ - var options = options || {} - , cache = new Cache(options.maxObjects || 128) - , maxlen = options.maxLength || 1024 * 256; - - console.warn('connect.staticCache() is deprecated and will be removed in 3.0'); - console.warn('use varnish or similar reverse proxy caches.'); - - return function staticCache(req, res, next){ - var key = cacheKey(req) - , ranges = req.headers.range - , hasCookies = req.headers.cookie - , hit = cache.get(key); - - // cache static - // TODO: change from staticCache() -> cache() - // and make this work for any request - req.on('static', function(stream){ - var headers = res._headers - , cc = utils.parseCacheControl(headers['cache-control'] || '') - , contentLength = headers['content-length'] - , hit; - - // dont cache set-cookie responses - if (headers['set-cookie']) return hasCookies = true; - - // dont cache when cookies are present - if (hasCookies) return; - - // ignore larger files - if (!contentLength || contentLength > maxlen) return; - - // don't cache partial files - if (headers['content-range']) return; - - // dont cache items we shouldn't be - // TODO: real support for must-revalidate / no-cache - if ( cc['no-cache'] - || cc['no-store'] - || cc['private'] - || cc['must-revalidate']) return; - - // if already in cache then validate - if (hit = cache.get(key)){ - if (headers.etag == hit[0].etag) { - hit[0].date = new Date; - return; - } else { - cache.remove(key); - } - } - - // validation notifiactions don't contain a steam - if (null == stream) return; - - // add the cache object - var arr = []; - - // store the chunks - stream.on('data', function(chunk){ - arr.push(chunk); - }); - - // flag it as complete - stream.on('end', function(){ - var cacheEntry = cache.add(key); - delete headers['x-cache']; // Clean up (TODO: others) - cacheEntry.push(200); - cacheEntry.push(headers); - cacheEntry.push.apply(cacheEntry, arr); - }); - }); - - if (req.method == 'GET' || req.method == 'HEAD') { - if (ranges) { - next(); - } else if (!hasCookies && hit && !mustRevalidate(req, hit)) { - res.setHeader('X-Cache', 'HIT'); - respondFromCache(req, res, hit); - } else { - res.setHeader('X-Cache', 'MISS'); - next(); - } - } else { - next(); - } - } -}; - -/** - * Respond with the provided cached value. - * TODO: Assume 200 code, that's iffy. - * - * @param {Object} req - * @param {Object} res - * @param {Object} cacheEntry - * @return {String} - * @api private - */ - -function respondFromCache(req, res, cacheEntry) { - var status = cacheEntry[0] - , headers = utils.merge({}, cacheEntry[1]) - , content = cacheEntry.slice(2); - - headers.age = (new Date - new Date(headers.date)) / 1000 || 0; - - switch (req.method) { - case 'HEAD': - res.writeHead(status, headers); - res.end(); - break; - case 'GET': - if (utils.conditionalGET(req) && fresh(req.headers, headers)) { - headers['content-length'] = 0; - res.writeHead(304, headers); - res.end(); - } else { - res.writeHead(status, headers); - - function write() { - while (content.length) { - if (false === res.write(content.shift())) { - res.once('drain', write); - return; - } - } - res.end(); - } - - write(); - } - break; - default: - // This should never happen. - res.writeHead(500, ''); - res.end(); - } -} - -/** - * Determine whether or not a cached value must be revalidated. - * - * @param {Object} req - * @param {Object} cacheEntry - * @return {String} - * @api private - */ - -function mustRevalidate(req, cacheEntry) { - var cacheHeaders = cacheEntry[1] - , reqCC = utils.parseCacheControl(req.headers['cache-control'] || '') - , cacheCC = utils.parseCacheControl(cacheHeaders['cache-control'] || '') - , cacheAge = (new Date - new Date(cacheHeaders.date)) / 1000 || 0; - - if ( cacheCC['no-cache'] - || cacheCC['must-revalidate'] - || cacheCC['proxy-revalidate']) return true; - - if (reqCC['no-cache']) return true; - - if (null != reqCC['max-age']) return reqCC['max-age'] < cacheAge; - - if (null != cacheCC['max-age']) return cacheCC['max-age'] < cacheAge; - - return false; -} - -/** - * The key to use in the cache. For now, this is the URL path and query. - * - * 'http://example.com?key=value' -> '/?key=value' - * - * @param {Object} req - * @return {String} - * @api private - */ - -function cacheKey(req) { - return utils.parseUrl(req).path; -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/timeout.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/timeout.js deleted file mode 100644 index dba4654d305..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/timeout.js +++ /dev/null @@ -1,55 +0,0 @@ -/*! - * Connect - timeout - * Ported from https://github.com/LearnBoost/connect-timeout - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var debug = require('debug')('connect:timeout'); - -/** - * Timeout: - * - * Times out the request in `ms`, defaulting to `5000`. The - * method `req.clearTimeout()` is added to revert this behaviour - * programmatically within your application's middleware, routes, etc. - * - * The timeout error is passed to `next()` so that you may customize - * the response behaviour. This error has the `.timeout` property as - * well as `.status == 408`. - * - * @param {Number} ms - * @return {Function} - * @api public - */ - -module.exports = function timeout(ms) { - ms = ms || 5000; - - return function(req, res, next) { - var id = setTimeout(function(){ - req.emit('timeout', ms); - }, ms); - - req.on('timeout', function(){ - if (res.headerSent) return debug('response started, cannot timeout'); - var err = new Error('Response timeout'); - err.timeout = ms; - err.status = 503; - next(err); - }); - - req.clearTimeout = function(){ - clearTimeout(id); - }; - - res.on('header', function(){ - clearTimeout(id); - }); - - next(); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js deleted file mode 100644 index cceafc0c899..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js +++ /dev/null @@ -1,78 +0,0 @@ - -/*! - * Connect - urlencoded - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var utils = require('../utils') - , _limit = require('./limit') - , qs = require('qs'); - -/** - * noop middleware. - */ - -function noop(req, res, next) { - next(); -} - -/** - * Urlencoded: - * - * Parse x-ww-form-urlencoded request bodies, - * providing the parsed object as `req.body`. - * - * Options: - * - * - `limit` byte limit disabled by default - * - * @param {Object} options - * @return {Function} - * @api public - */ - -exports = module.exports = function(options){ - options = options || {}; - - var limit = options.limit - ? _limit(options.limit) - : noop; - - return function urlencoded(req, res, next) { - if (req._body) return next(); - req.body = req.body || {}; - - if (!utils.hasBody(req)) return next(); - - // check Content-Type - if ('application/x-www-form-urlencoded' != utils.mime(req)) return next(); - - // flag as parsed - req._body = true; - - // parse - limit(req, res, function(err){ - if (err) return next(err); - var buf = ''; - req.setEncoding('utf8'); - req.on('data', function(chunk){ buf += chunk }); - req.on('end', function(){ - try { - req.body = buf.length - ? qs.parse(buf, options) - : {}; - next(); - } catch (err){ - err.body = buf; - next(err); - } - }); - }); - } -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/vhost.js b/frontend/express/node_modules/express/node_modules/connect/lib/middleware/vhost.js deleted file mode 100644 index abbb0500a7f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/middleware/vhost.js +++ /dev/null @@ -1,40 +0,0 @@ - -/*! - * Connect - vhost - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Vhost: - * - * Setup vhost for the given `hostname` and `server`. - * - * connect() - * .use(connect.vhost('foo.com', fooApp)) - * .use(connect.vhost('bar.com', barApp)) - * .use(connect.vhost('*.com', mainApp)) - * - * The `server` may be a Connect server or - * a regular Node `http.Server`. - * - * @param {String} hostname - * @param {Server} server - * @return {Function} - * @api public - */ - -module.exports = function vhost(hostname, server){ - if (!hostname) throw new Error('vhost hostname required'); - if (!server) throw new Error('vhost server required'); - var regexp = new RegExp('^' + hostname.replace(/[^*\w]/g, '\\$&').replace(/[*]/g, '(?:.*?)') + '$', 'i'); - if (server.onvhost) server.onvhost(hostname); - return function vhost(req, res, next){ - if (!req.headers.host) return next(); - var host = req.headers.host.split(':')[0]; - if (!regexp.test(host)) return next(); - if ('function' == typeof server) return server(req, res, next); - server.emit('request', req, res); - }; -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/patch.js b/frontend/express/node_modules/express/node_modules/connect/lib/patch.js deleted file mode 100644 index 7cf001255d5..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/patch.js +++ /dev/null @@ -1,79 +0,0 @@ - -/*! - * Connect - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , res = http.ServerResponse.prototype - , setHeader = res.setHeader - , _renderHeaders = res._renderHeaders - , writeHead = res.writeHead; - -// apply only once - -if (!res._hasConnectPatch) { - - /** - * Provide a public "header sent" flag - * until node does. - * - * @return {Boolean} - * @api public - */ - - res.__defineGetter__('headerSent', function(){ - return this._header; - }); - - /** - * Set header `field` to `val`, special-casing - * the `Set-Cookie` field for multiple support. - * - * @param {String} field - * @param {String} val - * @api public - */ - - res.setHeader = function(field, val){ - var key = field.toLowerCase() - , prev; - - // special-case Set-Cookie - if (this._headers && 'set-cookie' == key) { - if (prev = this.getHeader(field)) { - val = Array.isArray(prev) - ? prev.concat(val) - : [prev, val]; - } - // charset - } else if ('content-type' == key && this.charset) { - val += '; charset=' + this.charset; - } - - return setHeader.call(this, field, val); - }; - - /** - * Proxy to emit "header" event. - */ - - res._renderHeaders = function(){ - if (!this._emittedHeader) this.emit('header'); - this._emittedHeader = true; - return _renderHeaders.call(this); - }; - - res.writeHead = function(){ - if (!this._emittedHeader) this.emit('header'); - this._emittedHeader = true; - return writeHead.apply(this, arguments); - }; - - res._hasConnectPatch = true; -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/proto.js b/frontend/express/node_modules/express/node_modules/connect/lib/proto.js deleted file mode 100644 index b304cf72ff8..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/proto.js +++ /dev/null @@ -1,230 +0,0 @@ - -/*! - * Connect - HTTPServer - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , utils = require('./utils') - , debug = require('debug')('connect:dispatcher'); - -// prototype - -var app = module.exports = {}; - -// environment - -var env = process.env.NODE_ENV || 'development'; - -/** - * Utilize the given middleware `handle` to the given `route`, - * defaulting to _/_. This "route" is the mount-point for the - * middleware, when given a value other than _/_ the middleware - * is only effective when that segment is present in the request's - * pathname. - * - * For example if we were to mount a function at _/admin_, it would - * be invoked on _/admin_, and _/admin/settings_, however it would - * not be invoked for _/_, or _/posts_. - * - * Examples: - * - * var app = connect(); - * app.use(connect.favicon()); - * app.use(connect.logger()); - * app.use(connect.static(__dirname + '/public')); - * - * If we wanted to prefix static files with _/public_, we could - * "mount" the `static()` middleware: - * - * app.use('/public', connect.static(__dirname + '/public')); - * - * This api is chainable, so the following is valid: - * - * connect() - * .use(connect.favicon()) - * .use(connect.logger()) - * .use(connect.static(__dirname + '/public')) - * .listen(3000); - * - * @param {String|Function|Server} route, callback or server - * @param {Function|Server} callback or server - * @return {Server} for chaining - * @api public - */ - -app.use = function(route, fn){ - // default route to '/' - if ('string' != typeof route) { - fn = route; - route = '/'; - } - - // wrap sub-apps - if ('function' == typeof fn.handle) { - var server = fn; - fn.route = route; - fn = function(req, res, next){ - server.handle(req, res, next); - }; - } - - // wrap vanilla http.Servers - if (fn instanceof http.Server) { - fn = fn.listeners('request')[0]; - } - - // strip trailing slash - if ('/' == route[route.length - 1]) { - route = route.slice(0, -1); - } - - // add the middleware - debug('use %s %s', route || '/', fn.name || 'anonymous'); - this.stack.push({ route: route, handle: fn }); - - return this; -}; - -/** - * Handle server requests, punting them down - * the middleware stack. - * - * @api private - */ - -app.handle = function(req, res, out) { - var stack = this.stack - , fqdn = ~req.url.indexOf('://') - , removed = '' - , slashAdded = false - , index = 0; - - function next(err) { - var layer, path, status, c; - - if (slashAdded) { - req.url = req.url.substr(1); - slashAdded = false; - } - - req.url = removed + req.url; - req.originalUrl = req.originalUrl || req.url; - removed = ''; - - // next callback - layer = stack[index++]; - - // all done - if (!layer || res.headerSent) { - // delegate to parent - if (out) return out(err); - - // unhandled error - if (err) { - // default to 500 - if (res.statusCode < 400) res.statusCode = 500; - debug('default %s', res.statusCode); - - // respect err.status - if (err.status) res.statusCode = err.status; - - // production gets a basic error message - var msg = 'production' == env - ? http.STATUS_CODES[res.statusCode] - : err.stack || err.toString(); - - // log to stderr in a non-test env - if ('test' != env) console.error(err.stack || err.toString()); - if (res.headerSent) return req.socket.destroy(); - res.setHeader('Content-Type', 'text/plain'); - res.setHeader('Content-Length', Buffer.byteLength(msg)); - if ('HEAD' == req.method) return res.end(); - res.end(msg); - } else { - debug('default 404'); - res.statusCode = 404; - res.setHeader('Content-Type', 'text/plain'); - if ('HEAD' == req.method) return res.end(); - res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl)); - } - return; - } - - try { - path = utils.parseUrl(req).pathname; - if (undefined == path) path = '/'; - - // skip this layer if the route doesn't match. - if (0 != path.toLowerCase().indexOf(layer.route.toLowerCase())) return next(err); - - c = path[layer.route.length]; - if (c && '/' != c && '.' != c) return next(err); - - // Call the layer handler - // Trim off the part of the url that matches the route - removed = layer.route; - req.url = req.url.substr(removed.length); - - // Ensure leading slash - if (!fqdn && '/' != req.url[0]) { - req.url = '/' + req.url; - slashAdded = true; - } - - debug('%s', layer.handle.name || 'anonymous'); - var arity = layer.handle.length; - if (err) { - if (arity === 4) { - layer.handle(err, req, res, next); - } else { - next(err); - } - } else if (arity < 4) { - layer.handle(req, res, next); - } else { - next(); - } - } catch (e) { - next(e); - } - } - next(); -}; - -/** - * Listen for connections. - * - * This method takes the same arguments - * as node's `http.Server#listen()`. - * - * HTTP and HTTPS: - * - * If you run your application both as HTTP - * and HTTPS you may wrap them individually, - * since your Connect "server" is really just - * a JavaScript `Function`. - * - * var connect = require('connect') - * , http = require('http') - * , https = require('https'); - * - * var app = connect(); - * - * http.createServer(app).listen(80); - * https.createServer(options, app).listen(443); - * - * @return {http.Server} - * @api public - */ - -app.listen = function(){ - var server = http.createServer(this); - return server.listen.apply(server, arguments); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/directory.html b/frontend/express/node_modules/express/node_modules/connect/lib/public/directory.html deleted file mode 100644 index 2d637042140..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/public/directory.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - listing directory {directory} - - - - - -
    -

    {linked-path}

    - {files} -
    - - \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/error.html b/frontend/express/node_modules/express/node_modules/connect/lib/public/error.html deleted file mode 100644 index a6d3fafd873..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/public/error.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - {error} - - - -
    -

    {title}

    -

    {statusCode} {error}

    -
      {stack}
    -
    - - diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/favicon.ico b/frontend/express/node_modules/express/node_modules/connect/lib/public/favicon.ico deleted file mode 100644 index 895fc96a76b..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/favicon.ico and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page.png deleted file mode 100644 index 03ddd799fa0..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_add.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_add.png deleted file mode 100644 index d5bfa0719bc..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_add.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_attach.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_attach.png deleted file mode 100644 index 89ee2da0753..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_attach.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_code.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_code.png deleted file mode 100644 index f7ea90419d9..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_code.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_copy.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_copy.png deleted file mode 100644 index 195dc6d6c36..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_copy.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_delete.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_delete.png deleted file mode 100644 index 3141467c678..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_delete.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_edit.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_edit.png deleted file mode 100644 index 046811ed7a6..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_edit.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_error.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_error.png deleted file mode 100644 index f07f449a44f..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_error.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_excel.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_excel.png deleted file mode 100644 index eb6158eb5ca..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_excel.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_find.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_find.png deleted file mode 100644 index 2f193889f7e..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_find.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_gear.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_gear.png deleted file mode 100644 index 8e83281c5f8..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_gear.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_go.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_go.png deleted file mode 100644 index 80fe1ed0cc7..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_go.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_green.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_green.png deleted file mode 100644 index de8e003f9fb..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_green.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_key.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_key.png deleted file mode 100644 index d6626cb09eb..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_key.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png deleted file mode 100644 index 7e568703d64..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_link.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_link.png deleted file mode 100644 index 312eab0914a..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_link.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png deleted file mode 100644 index 246a2f0b426..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paste.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paste.png deleted file mode 100644 index 968f073fddd..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_paste.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_red.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_red.png deleted file mode 100644 index 0b18247da58..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_red.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png deleted file mode 100644 index cf347c7d468..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_save.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_save.png deleted file mode 100644 index caea546af54..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_save.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white.png deleted file mode 100644 index 8b8b1ca0000..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png deleted file mode 100644 index 8f8095e46fa..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png deleted file mode 100644 index 159b2407519..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png deleted file mode 100644 index aa23dde3746..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png deleted file mode 100644 index 34a05cccf06..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png deleted file mode 100644 index f501a593a4e..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png deleted file mode 100644 index 848bdaf3f15..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png deleted file mode 100644 index 0c76bd12977..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png deleted file mode 100644 index 87a69145075..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png deleted file mode 100644 index c66011fb0fb..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png deleted file mode 100644 index 2b6b1007f33..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png deleted file mode 100644 index a9f31a278e1..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png deleted file mode 100644 index a87cf847cb7..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png deleted file mode 100644 index ffb8fc932f3..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png deleted file mode 100644 index 0a7d6f4a6f6..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png deleted file mode 100644 index bddba1f98ca..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png deleted file mode 100644 index af1ecaf2981..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png deleted file mode 100644 index 4cc537af0b3..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png deleted file mode 100644 index b93e77600de..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png deleted file mode 100644 index 9fc5a0a103d..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png deleted file mode 100644 index b977d7e52e2..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png deleted file mode 100644 index 58184363707..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png deleted file mode 100644 index 5769120b1b6..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png deleted file mode 100644 index 8d719df5205..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png deleted file mode 100644 index 106f5aa3611..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png deleted file mode 100644 index e4a1ecba1b6..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png deleted file mode 100644 index 7e62a924bc5..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png deleted file mode 100644 index e902abb0767..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png deleted file mode 100644 index 1d2d0a49870..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png deleted file mode 100644 index d6164845228..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png deleted file mode 100644 index 7215d1e8b06..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png deleted file mode 100644 index bf7bd1c9bfd..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png deleted file mode 100644 index f6b74cc40f8..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png deleted file mode 100644 index d3fffb6d989..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png deleted file mode 100644 index a65bcb3e1e9..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png deleted file mode 100644 index 23a37b891c2..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png deleted file mode 100644 index f907e44b333..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png deleted file mode 100644 index 5b2cbb3fd02..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png deleted file mode 100644 index 7868a25945c..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png deleted file mode 100644 index 134b6693687..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png deleted file mode 100644 index c4eff0387d5..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png deleted file mode 100644 index 884ffd6f0aa..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png deleted file mode 100644 index f59b7c4365f..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png deleted file mode 100644 index 44084add79b..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png deleted file mode 100644 index 3a1441c9a12..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png deleted file mode 100644 index e7708292ada..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png deleted file mode 100644 index 813f712f726..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png deleted file mode 100644 index d9cf13256f4..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png deleted file mode 100644 index 52699bfee0c..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png deleted file mode 100644 index 4a05955b337..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png deleted file mode 100644 index a0a433dfbb6..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png deleted file mode 100644 index 1eb880947dd..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png deleted file mode 100644 index ae8ecbf4767..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png deleted file mode 100644 index 6ed2490ed14..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png deleted file mode 100644 index fecadd08afe..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png deleted file mode 100644 index fd4bbccdf16..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_word.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_word.png deleted file mode 100644 index 834cdfaf48a..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_word.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_world.png b/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_world.png deleted file mode 100644 index b8895ddecf5..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/lib/public/icons/page_world.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/public/style.css b/frontend/express/node_modules/express/node_modules/connect/lib/public/style.css deleted file mode 100644 index 32b65071036..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/public/style.css +++ /dev/null @@ -1,141 +0,0 @@ -body { - margin: 0; - padding: 80px 100px; - font: 13px "Helvetica Neue", "Lucida Grande", "Arial"; - background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9)); - background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9); - background-repeat: no-repeat; - color: #555; - -webkit-font-smoothing: antialiased; -} -h1, h2, h3 { - margin: 0; - font-size: 22px; - color: #343434; -} -h1 em, h2 em { - padding: 0 5px; - font-weight: normal; -} -h1 { - font-size: 60px; -} -h2 { - margin-top: 10px; -} -h3 { - margin: 5px 0 10px 0; - padding-bottom: 5px; - border-bottom: 1px solid #eee; - font-size: 18px; -} -ul { - margin: 0; - padding: 0; -} -ul li { - margin: 5px 0; - padding: 3px 8px; - list-style: none; -} -ul li:hover { - cursor: pointer; - color: #2e2e2e; -} -ul li .path { - padding-left: 5px; - font-weight: bold; -} -ul li .line { - padding-right: 5px; - font-style: italic; -} -ul li:first-child .path { - padding-left: 0; -} -p { - line-height: 1.5; -} -a { - color: #555; - text-decoration: none; -} -a:hover { - color: #303030; -} -#stacktrace { - margin-top: 15px; -} -.directory h1 { - margin-bottom: 15px; - font-size: 18px; -} -ul#files { - width: 100%; - height: 500px; -} -ul#files li { - padding: 0; -} -ul#files li img { - position: absolute; - top: 5px; - left: 5px; -} -ul#files li a { - position: relative; - display: block; - margin: 1px; - width: 30%; - height: 25px; - line-height: 25px; - text-indent: 8px; - float: left; - border: 1px solid transparent; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - overflow: hidden; - text-overflow: ellipsis; -} -ul#files li a.icon { - text-indent: 25px; -} -ul#files li a:focus, -ul#files li a:hover { - outline: none; - background: rgba(255,255,255,0.65); - border: 1px solid #ececec; -} -ul#files li a.highlight { - -webkit-transition: background .4s ease-in-out; - background: #ffff4f; - border-color: #E9DC51; -} -#search { - display: block; - position: fixed; - top: 20px; - right: 20px; - width: 90px; - -webkit-transition: width ease 0.2s, opacity ease 0.4s; - -moz-transition: width ease 0.2s, opacity ease 0.4s; - -webkit-border-radius: 32px; - -moz-border-radius: 32px; - -webkit-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); - -moz-box-shadow: inset 0px 0px 3px rgba(0, 0, 0, 0.25), inset 0px 1px 3px rgba(0, 0, 0, 0.7), 0px 1px 0px rgba(255, 255, 255, 0.03); - -webkit-font-smoothing: antialiased; - text-align: left; - font: 13px "Helvetica Neue", Arial, sans-serif; - padding: 4px 10px; - border: none; - background: transparent; - margin-bottom: 0; - outline: none; - opacity: 0.7; - color: #888; -} -#search:focus { - width: 120px; - opacity: 1.0; -} diff --git a/frontend/express/node_modules/express/node_modules/connect/lib/utils.js b/frontend/express/node_modules/express/node_modules/connect/lib/utils.js deleted file mode 100644 index 35738b8c141..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/lib/utils.js +++ /dev/null @@ -1,404 +0,0 @@ - -/*! - * Connect - utils - * Copyright(c) 2010 Sencha Inc. - * Copyright(c) 2011 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var http = require('http') - , crypto = require('crypto') - , parse = require('url').parse - , signature = require('cookie-signature') - , nodeVersion = process.versions.node.split('.'); - -// pause is broken in node < 0.10 -exports.brokenPause = parseInt(nodeVersion[0], 10) === 0 - && parseInt(nodeVersion[1], 10) < 10; - -/** - * Return `true` if the request has a body, otherwise return `false`. - * - * @param {IncomingMessage} req - * @return {Boolean} - * @api private - */ - -exports.hasBody = function(req) { - return 'transfer-encoding' in req.headers || 'content-length' in req.headers; -}; - -/** - * Extract the mime type from the given request's - * _Content-Type_ header. - * - * @param {IncomingMessage} req - * @return {String} - * @api private - */ - -exports.mime = function(req) { - var str = req.headers['content-type'] || ''; - return str.split(';')[0]; -}; - -/** - * Generate an `Error` from the given status `code` - * and optional `msg`. - * - * @param {Number} code - * @param {String} msg - * @return {Error} - * @api private - */ - -exports.error = function(code, msg){ - var err = new Error(msg || http.STATUS_CODES[code]); - err.status = code; - return err; -}; - -/** - * Return md5 hash of the given string and optional encoding, - * defaulting to hex. - * - * utils.md5('wahoo'); - * // => "e493298061761236c96b02ea6aa8a2ad" - * - * @param {String} str - * @param {String} encoding - * @return {String} - * @api private - */ - -exports.md5 = function(str, encoding){ - return crypto - .createHash('md5') - .update(str) - .digest(encoding || 'hex'); -}; - -/** - * Merge object b with object a. - * - * var a = { foo: 'bar' } - * , b = { bar: 'baz' }; - * - * utils.merge(a, b); - * // => { foo: 'bar', bar: 'baz' } - * - * @param {Object} a - * @param {Object} b - * @return {Object} - * @api private - */ - -exports.merge = function(a, b){ - if (a && b) { - for (var key in b) { - a[key] = b[key]; - } - } - return a; -}; - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; - - -/** - * Return a unique identifier with the given `len`. - * - * utils.uid(10); - * // => "FDaS435D2z" - * - * @param {Number} len - * @return {String} - * @api private - */ - -exports.uid = function(len) { - return crypto.randomBytes(Math.ceil(len * 3 / 4)) - .toString('base64') - .slice(0, len) - .replace(/\//g, '-') - .replace(/\+/g, '_'); -}; - -/** - * Sign the given `val` with `secret`. - * - * @param {String} val - * @param {String} secret - * @return {String} - * @api private - */ - -exports.sign = function(val, secret){ - console.warn('do not use utils.sign(), use https://github.com/visionmedia/node-cookie-signature') - return val + '.' + crypto - .createHmac('sha256', secret) - .update(val) - .digest('base64') - .replace(/=+$/, ''); -}; - -/** - * Unsign and decode the given `val` with `secret`, - * returning `false` if the signature is invalid. - * - * @param {String} val - * @param {String} secret - * @return {String|Boolean} - * @api private - */ - -exports.unsign = function(val, secret){ - console.warn('do not use utils.unsign(), use https://github.com/visionmedia/node-cookie-signature') - var str = val.slice(0, val.lastIndexOf('.')); - return exports.sign(str, secret) == val - ? str - : false; -}; - -/** - * Parse signed cookies, returning an object - * containing the decoded key/value pairs, - * while removing the signed key from `obj`. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.parseSignedCookies = function(obj, secret){ - var ret = {}; - Object.keys(obj).forEach(function(key){ - var val = obj[key]; - if (0 == val.indexOf('s:')) { - val = signature.unsign(val.slice(2), secret); - if (val) { - ret[key] = val; - delete obj[key]; - } - } - }); - return ret; -}; - -/** - * Parse a signed cookie string, return the decoded value - * - * @param {String} str signed cookie string - * @param {String} secret - * @return {String} decoded value - * @api private - */ - -exports.parseSignedCookie = function(str, secret){ - return 0 == str.indexOf('s:') - ? signature.unsign(str.slice(2), secret) - : str; -}; - -/** - * Parse JSON cookies. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.parseJSONCookies = function(obj){ - Object.keys(obj).forEach(function(key){ - var val = obj[key]; - var res = exports.parseJSONCookie(val); - if (res) obj[key] = res; - }); - return obj; -}; - -/** - * Parse JSON cookie string - * - * @param {String} str - * @return {Object} Parsed object or null if not json cookie - * @api private - */ - -exports.parseJSONCookie = function(str) { - if (0 == str.indexOf('j:')) { - try { - return JSON.parse(str.slice(2)); - } catch (err) { - // no op - } - } -}; - -/** - * Pause `data` and `end` events on the given `obj`. - * Middleware performing async tasks _should_ utilize - * this utility (or similar), to re-emit data once - * the async operation has completed, otherwise these - * events may be lost. Pause is only required for - * node versions less than 10, and is replaced with - * noop's otherwise. - * - * var pause = utils.pause(req); - * fs.readFile(path, function(){ - * next(); - * pause.resume(); - * }); - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -exports.pause = exports.brokenPause - ? require('pause') - : function () { - return { - end: noop, - resume: noop - } - } - -/** - * Strip `Content-*` headers from `res`. - * - * @param {ServerResponse} res - * @api private - */ - -exports.removeContentHeaders = function(res){ - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); - } - }); -}; - -/** - * Check if `req` is a conditional GET request. - * - * @param {IncomingMessage} req - * @return {Boolean} - * @api private - */ - -exports.conditionalGET = function(req) { - return req.headers['if-modified-since'] - || req.headers['if-none-match']; -}; - -/** - * Respond with 401 "Unauthorized". - * - * @param {ServerResponse} res - * @param {String} realm - * @api private - */ - -exports.unauthorized = function(res, realm) { - res.statusCode = 401; - res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"'); - res.end('Unauthorized'); -}; - -/** - * Respond with 304 "Not Modified". - * - * @param {ServerResponse} res - * @param {Object} headers - * @api private - */ - -exports.notModified = function(res) { - exports.removeContentHeaders(res); - res.statusCode = 304; - res.end(); -}; - -/** - * Return an ETag in the form of `"-"` - * from the given `stat`. - * - * @param {Object} stat - * @return {String} - * @api private - */ - -exports.etag = function(stat) { - return '"' + stat.size + '-' + Number(stat.mtime) + '"'; -}; - -/** - * Parse the given Cache-Control `str`. - * - * @param {String} str - * @return {Object} - * @api private - */ - -exports.parseCacheControl = function(str){ - var directives = str.split(',') - , obj = {}; - - for(var i = 0, len = directives.length; i < len; i++) { - var parts = directives[i].split('=') - , key = parts.shift().trim() - , val = parseInt(parts.shift(), 10); - - obj[key] = isNaN(val) ? true : val; - } - - return obj; -}; - -/** - * Parse the `req` url with memoization. - * - * @param {ServerRequest} req - * @return {Object} - * @api private - */ - -exports.parseUrl = function(req){ - var parsed = req._parsedUrl; - if (parsed && parsed.href == req.url) { - return parsed; - } else { - return req._parsedUrl = parse(req.url); - } -}; - -/** - * Parse byte `size` string. - * - * @param {String} size - * @return {Number} - * @api private - */ - -exports.parseBytes = require('bytes'); - -function noop() {} \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/History.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/History.md deleted file mode 100644 index 1332808c8b4..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/History.md +++ /dev/null @@ -1,10 +0,0 @@ - -0.2.0 / 2012-10-28 -================== - - * bytes(200).should.eql('200b') - -0.1.0 / 2012-07-04 -================== - - * add bytes to string conversion [yields] diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Makefile b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Readme.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Readme.md deleted file mode 100644 index 9325d5bf419..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/Readme.md +++ /dev/null @@ -1,51 +0,0 @@ -# node-bytes - - Byte string parser / formatter. - -## Example: - -```js -bytes('1kb') -// => 1024 - -bytes('2mb') -// => 2097152 - -bytes('1gb') -// => 1073741824 - -bytes(1073741824) -// => 1gb -``` - -## Installation - -``` -$ npm install bytes -$ component install visionmedia/bytes.js -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/component.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/component.json deleted file mode 100644 index 76a6057b020..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/component.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "bytes", - "description": "byte size string parser / serializer", - "keywords": ["bytes", "utility"], - "version": "0.1.0", - "scripts": ["index.js"] -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/index.js deleted file mode 100644 index 70b2e01a41b..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/index.js +++ /dev/null @@ -1,39 +0,0 @@ - -/** - * Parse byte `size` string. - * - * @param {String} size - * @return {Number} - * @api public - */ - -module.exports = function(size) { - if ('number' == typeof size) return convert(size); - var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/) - , n = parseFloat(parts[1]) - , type = parts[2]; - - var map = { - kb: 1 << 10 - , mb: 1 << 20 - , gb: 1 << 30 - }; - - return map[type] * n; -}; - -/** - * convert bytes into string. - * - * @param {Number} b - bytes to convert - * @return {String} - * @api public - */ - -function convert (b) { - var gb = 1 << 30, mb = 1 << 20, kb = 1 << 10; - if (b >= gb) return (Math.round(b / gb * 100) / 100) + 'gb'; - if (b >= mb) return (Math.round(b / mb * 100) / 100) + 'mb'; - if (b >= kb) return (Math.round(b / kb * 100) / 100) + 'kb'; - return b + 'b'; -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/package.json deleted file mode 100644 index 0db9bc90da6..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/bytes/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "bytes", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "byte size string parser / serializer", - "version": "0.2.0", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "readme": "# node-bytes\n\n Byte string parser / formatter.\n\n## Example:\n\n```js\nbytes('1kb')\n// => 1024\n\nbytes('2mb')\n// => 2097152\n\nbytes('1gb')\n// => 1073741824\n\nbytes(1073741824)\n// => 1gb\n```\n\n## Installation\n\n```\n$ npm install bytes\n$ component install visionmedia/bytes.js\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "_id": "bytes@0.2.0", - "_from": "bytes@0.2.0" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.npmignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.travis.yml b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.travis.yml deleted file mode 100644 index 320698af0f5..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/README.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/README.md deleted file mode 100644 index 5187ed1ccad..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) # - -cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers. - -See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies. - -## how? - -``` -npm install cookie -``` - -```javascript -var cookie = require('cookie'); - -var hdr = cookie.serialize('foo', 'bar'); -// hdr = 'foo=bar'; - -var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff'); -// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' }; -``` - -## more - -The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values. - -### path -> cookie path - -### expires -> absolute expiration date for the cookie (Date object) - -### maxAge -> relative max age of the cookie from when the client receives it (seconds) - -### domain -> domain for the cookie - -### secure -> true or false - -### httpOnly -> true or false - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/index.js deleted file mode 100644 index db04ad3f7eb..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/index.js +++ /dev/null @@ -1,61 +0,0 @@ - -/// Serialize the a name value pair into a cookie string suitable for -/// http headers. An optional options object specified cookie parameters -/// -/// serialize('foo', 'bar', { httpOnly: true }) -/// => "foo=bar; httpOnly" -/// -/// @param {String} name -/// @param {String} val -/// @param {Object} options -/// @return {String} -var serialize = function(name, val, opt){ - var pairs = [name + '=' + encode(val)]; - opt = opt || {}; - - if (opt.maxAge) pairs.push('Max-Age=' + opt.maxAge); - if (opt.domain) pairs.push('Domain=' + opt.domain); - if (opt.path) pairs.push('Path=' + opt.path); - if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); - if (opt.httpOnly) pairs.push('HttpOnly'); - if (opt.secure) pairs.push('Secure'); - - return pairs.join('; '); -}; - -/// Parse the given cookie header string into an object -/// The object has the various cookies as keys(names) => values -/// @param {String} str -/// @return {Object} -var parse = function(str) { - var obj = {} - var pairs = str.split(/[;,] */); - - pairs.forEach(function(pair) { - var eq_idx = pair.indexOf('=') - var key = pair.substr(0, eq_idx).trim() - var val = pair.substr(++eq_idx, pair.length).trim(); - - // quoted values - if ('"' == val[0]) { - val = val.slice(1, -1); - } - - // only assign once - if (undefined == obj[key]) { - try { - obj[key] = decode(val); - } catch (e) { - obj[key] = val; - } - } - }); - - return obj; -}; - -var encode = encodeURIComponent; -var decode = decodeURIComponent; - -module.exports.serialize = serialize; -module.exports.parse = parse; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/package.json deleted file mode 100644 index 208cdadd7fb..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "author": { - "name": "Roman Shtylman", - "email": "shtylman@gmail.com" - }, - "name": "cookie", - "description": "cookie parsing and serialization", - "version": "0.0.5", - "repository": { - "type": "git", - "url": "git://github.com/shtylman/node-cookie.git" - }, - "keywords": [ - "cookie", - "cookies" - ], - "main": "index.js", - "scripts": { - "test": "mocha" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "1.x.x" - }, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/shtylman/node-cookie/issues" - }, - "_id": "cookie@0.0.5", - "_from": "cookie@0.0.5" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/mocha.opts b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/mocha.opts deleted file mode 100644 index e2bfcc5ac3f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---ui qunit diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/parse.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/parse.js deleted file mode 100644 index d8c03ab7116..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/parse.js +++ /dev/null @@ -1,28 +0,0 @@ - -var assert = require('assert'); - -var cookie = require('..'); - -suite('parse'); - -test('basic', function() { - assert.deepEqual({ foo: 'bar' }, cookie.parse('foo=bar')); - assert.deepEqual({ foo: '123' }, cookie.parse('foo=123')); -}); - -test('ignore spaces', function() { - assert.deepEqual({ FOO: 'bar', baz: 'raz' }, - cookie.parse('FOO = bar; baz = raz')); -}); - -test('escaping', function() { - assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, - cookie.parse('foo="bar=123456789&name=Magic+Mouse"')); - - assert.deepEqual({ email: ' ",;/' }, - cookie.parse('email=%20%22%2c%3b%2f')); -}); - -test('ignore escaping error and return original value', function() { - assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar')); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/serialize.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/serialize.js deleted file mode 100644 index d38768d6ab3..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/cookie/test/serialize.js +++ /dev/null @@ -1,59 +0,0 @@ -// builtin -var assert = require('assert'); - -var cookie = require('..'); - -suite('serialize'); - -test('basic', function() { - assert.equal('foo=bar', cookie.serialize('foo', 'bar')); - assert.equal('foo=bar%20baz', cookie.serialize('foo', 'bar baz')); -}); - -test('path', function() { - assert.equal('foo=bar; Path=/', cookie.serialize('foo', 'bar', { - path: '/' - })); -}); - -test('secure', function() { - assert.equal('foo=bar; Secure', cookie.serialize('foo', 'bar', { - secure: true - })); - - assert.equal('foo=bar', cookie.serialize('foo', 'bar', { - secure: false - })); -}); - -test('domain', function() { - assert.equal('foo=bar; Domain=example.com', cookie.serialize('foo', 'bar', { - domain: 'example.com' - })); -}); - -test('httpOnly', function() { - assert.equal('foo=bar; HttpOnly', cookie.serialize('foo', 'bar', { - httpOnly: true - })); -}); - -test('maxAge', function() { - assert.equal('foo=bar; Max-Age=1000', cookie.serialize('foo', 'bar', { - maxAge: 1000 - })); -}); - -test('escaping', function() { - assert.deepEqual('cat=%2B%20', cookie.serialize('cat', '+ ')); -}); - -test('parse->serialize', function() { - - assert.deepEqual({ cat: 'foo=123&name=baz five' }, cookie.parse( - cookie.serialize('cat', 'foo=123&name=baz five'))); - - assert.deepEqual({ cat: ' ";/' }, cookie.parse( - cookie.serialize('cat', ' ";/'))); -}); - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore deleted file mode 100644 index 4fbabb338d7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -/test/tmp/ -*.upload -*.un~ -*.http diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.travis.yml b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.travis.yml deleted file mode 100644 index cb931cb03ef..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.8 - - 0.9 - - "0.10" diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/LICENSE b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/LICENSE deleted file mode 100644 index 38d3c9cf421..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (C) 2011 Felix Geisendörfer - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Makefile b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Makefile deleted file mode 100644 index 8945872410e..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -build: npm test - -npm: - npm install . - -clean: - rm test/tmp/* - -.PHONY: test clean build diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md deleted file mode 100644 index 08e9eca1509..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md +++ /dev/null @@ -1,419 +0,0 @@ -# Formidable - -[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable) - -## Purpose - -A node.js module for parsing form data, especially file uploads. - -## Current status - -This module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading -and encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from -a large variety of clients and is considered production-ready. - -## Features - -* Fast (~500mb/sec), non-buffering multipart parser -* Automatically writing file uploads to disk -* Low memory footprint -* Graceful error handling -* Very high test coverage - -## Installation - -Via [npm](http://github.com/isaacs/npm): -``` -npm install formidable@latest -``` -Manually: -``` -git clone git://github.com/felixge/node-formidable.git formidable -vim my.js -# var formidable = require('./formidable'); -``` - -Note: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library. - -## Example - -Parse an incoming file upload. -```javascript -var formidable = require('formidable'), - http = require('http'), - util = require('util'); - -http.createServer(function(req, res) { - if (req.url == '/upload' && req.method.toLowerCase() == 'post') { - // parse a file upload - var form = new formidable.IncomingForm(); - - form.parse(req, function(err, fields, files) { - res.writeHead(200, {'content-type': 'text/plain'}); - res.write('received upload:\n\n'); - res.end(util.inspect({fields: fields, files: files})); - }); - - return; - } - - // show a file upload form - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); -}).listen(8080); -``` -## API - -### Formidable.IncomingForm -```javascript -var form = new formidable.IncomingForm() -``` -Creates a new incoming form. - -```javascript -form.encoding = 'utf-8'; -``` -Sets encoding for incoming form fields. - -```javascript -form.uploadDir = process.env.TMP || process.env.TMPDIR || process.env.TEMP || '/tmp' || process.cwd(); -``` -The directory for placing file uploads in. You can move them later on using -`fs.rename()`. The default directory is picked at module load time depending on -the first existing directory from those listed above. - -```javascript -form.keepExtensions = false; -``` -If you want the files written to `form.uploadDir` to include the extensions of the original files, set this property to `true`. - -```javascript -form.type -``` -Either 'multipart' or 'urlencoded' depending on the incoming request. - -```javascript -form.maxFieldsSize = 2 * 1024 * 1024; -``` -Limits the amount of memory a field (not file) can allocate in bytes. -If this value is exceeded, an `'error'` event is emitted. The default -size is 2MB. - -```javascript -form.maxFields = 0; -``` -Limits the number of fields that the querystring parser will decode. Defaults -to 0 (unlimited). - -```javascript -form.hash = false; -``` -If you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`. - -```javascript -form.bytesReceived -``` -The amount of bytes received for this form so far. - -```javascript -form.bytesExpected -``` -The expected number of bytes in this form. - -```javascript -form.parse(request, [cb]); -``` -Parses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback: - - -```javascript -form.parse(req, function(err, fields, files) { - // ... -}); - -form.onPart(part); -``` -You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing. - -```javascript -form.onPart = function(part) { - part.addListener('data', function() { - // ... - }); -} -``` -If you want to use formidable to only handle certain parts for you, you can do so: -```javascript -form.onPart = function(part) { - if (!part.filename) { - // let formidable handle all non-file parts - form.handlePart(part); - } -} -``` -Check the code in this method for further inspiration. - - -### Formidable.File -```javascript -file.size = 0 -``` -The size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet. -```javascript -file.path = null -``` -The path this file is being written to. You can modify this in the `'fileBegin'` event in -case you are unhappy with the way formidable generates a temporary path for your files. -```javascript -file.name = null -``` -The name this file had according to the uploading client. -```javascript -file.type = null -``` -The mime type of this file, according to the uploading client. -```javascript -file.lastModifiedDate = null -``` -A date object (or `null`) containing the time this file was last written to. Mostly -here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/). -```javascript -file.hash = null -``` -If hash calculation was set, you can read the hex digest out of this var. - -#### Formidable.File#toJSON() - - This method returns a JSON-representation of the file, allowing you to - `JSON.stringify()` the file which is useful for logging and responding - to requests. - -### Events - - -#### 'progress' -```javascript -form.on('progress', function(bytesReceived, bytesExpected) { -}); -``` -Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar. - - - -#### 'field' -```javascript -form.on('field', function(name, value) { -}); -``` - -#### 'fileBegin' - -Emitted whenever a field / value pair has been received. -```javascript -form.on('fileBegin', function(name, file) { -}); -``` - -#### 'file' - -Emitted whenever a new file is detected in the upload stream. Use this even if -you want to stream the file to somewhere else while buffering the upload on -the file system. - -Emitted whenever a field / file pair has been received. `file` is an instance of `File`. -```javascript -form.on('file', function(name, file) { -}); -``` - -#### 'error' - -Emitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events. -```javascript -form.on('error', function(err) { -}); -``` - -#### 'aborted' - - -Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core). -```javascript -form.on('aborted', function() { -}); -``` - -##### 'end' -```javascript -form.on('end', function() { -}); -``` -Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response. - - - -## Changelog - -### v1.0.14 - -* Add failing hash tests. (Ben Trask) -* Enable hash calculation again (Eugene Girshov) -* Test for immediate data events (Tim Smart) -* Re-arrange IncomingForm#parse (Tim Smart) - -### v1.0.13 - -* Only update hash if update method exists (Sven Lito) -* According to travis v0.10 needs to go quoted (Sven Lito) -* Bumping build node versions (Sven Lito) -* Additional fix for empty requests (Eugene Girshov) -* Change the default to 1000, to match the new Node behaviour. (OrangeDog) -* Add ability to control maxKeys in the querystring parser. (OrangeDog) -* Adjust test case to work with node 0.9.x (Eugene Girshov) -* Update package.json (Sven Lito) -* Path adjustment according to eb4468b (Markus Ast) - -### v1.0.12 - -* Emit error on aborted connections (Eugene Girshov) -* Add support for empty requests (Eugene Girshov) -* Fix name/filename handling in Content-Disposition (jesperp) -* Tolerate malformed closing boundary in multipart (Eugene Girshov) -* Ignore preamble in multipart messages (Eugene Girshov) -* Add support for application/json (Mike Frey, Carlos Rodriguez) -* Add support for Base64 encoding (Elmer Bulthuis) -* Add File#toJSON (TJ Holowaychuk) -* Remove support for Node.js 0.4 & 0.6 (Andrew Kelley) -* Documentation improvements (Sven Lito, Andre Azevedo) -* Add support for application/octet-stream (Ion Lupascu, Chris Scribner) -* Use os.tmpDir() to get tmp directory (Andrew Kelley) -* Improve package.json (Andrew Kelley, Sven Lito) -* Fix benchmark script (Andrew Kelley) -* Fix scope issue in incoming_forms (Sven Lito) -* Fix file handle leak on error (OrangeDog) - -### v1.0.11 - -* Calculate checksums for incoming files (sreuter) -* Add definition parameters to "IncomingForm" as an argument (Math-) - -### v1.0.10 - -* Make parts to be proper Streams (Matt Robenolt) - -### v1.0.9 - -* Emit progress when content length header parsed (Tim Koschützki) -* Fix Readme syntax due to GitHub changes (goob) -* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara) - -### v1.0.8 - -* Strip potentially unsafe characters when using `keepExtensions: true`. -* Switch to utest / urun for testing -* Add travis build - -### v1.0.7 - -* Remove file from package that was causing problems when installing on windows. (#102) -* Fix typos in Readme (Jason Davies). - -### v1.0.6 - -* Do not default to the default to the field name for file uploads where - filename="". - -### v1.0.5 - -* Support filename="" in multipart parts -* Explain unexpected end() errors in parser better - -**Note:** Starting with this version, formidable emits 'file' events for empty -file input fields. Previously those were incorrectly emitted as regular file -input fields with value = "". - -### v1.0.4 - -* Detect a good default tmp directory regardless of platform. (#88) - -### v1.0.3 - -* Fix problems with utf8 characters (#84) / semicolons in filenames (#58) -* Small performance improvements -* New test suite and fixture system - -### v1.0.2 - -* Exclude node\_modules folder from git -* Implement new `'aborted'` event -* Fix files in example folder to work with recent node versions -* Make gently a devDependency - -[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2) - -### v1.0.1 - -* Fix package.json to refer to proper main directory. (#68, Dean Landolt) - -[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1) - -### v1.0.0 - -* Add support for multipart boundaries that are quoted strings. (Jeff Craig) - -This marks the beginning of development on version 2.0 which will include -several architectural improvements. - -[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0) - -### v0.9.11 - -* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki) -* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class - -**Important:** The old property names of the File class will be removed in a -future release. - -[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11) - -### Older releases - -These releases were done before starting to maintain the above Changelog: - -* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10) -* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9) -* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8) -* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7) -* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6) -* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5) -* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4) -* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3) -* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2) -* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0) -* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0) - -## License - -Formidable is licensed under the MIT license. - -## Ports - -* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable - -## Credits - -* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/TODO b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/TODO deleted file mode 100644 index e1107f2a55f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- Better bufferMaxSize handling approach -- Add tests for JSON parser pull request and merge it -- Implement QuerystringParser the same way as MultipartParser diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js deleted file mode 100644 index 49abc43e2ec..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js +++ /dev/null @@ -1,71 +0,0 @@ -var assert = require('assert'); -require('../test/common'); -var multipartParser = require('../lib/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - parser = new MultipartParser(), - Buffer = require('buffer').Buffer, - boundary = '-----------------------------168072824752491622650073', - mb = 100, - buffer = createMultipartBuffer(boundary, mb * 1024 * 1024), - callbacks = - { partBegin: -1, - partEnd: -1, - headerField: -1, - headerValue: -1, - partData: -1, - end: -1, - }; - - -parser.initWithBoundary(boundary); -parser.onHeaderField = function() { - callbacks.headerField++; -}; - -parser.onHeaderValue = function() { - callbacks.headerValue++; -}; - -parser.onPartBegin = function() { - callbacks.partBegin++; -}; - -parser.onPartData = function() { - callbacks.partData++; -}; - -parser.onPartEnd = function() { - callbacks.partEnd++; -}; - -parser.onEnd = function() { - callbacks.end++; -}; - -var start = +new Date(), - nparsed = parser.write(buffer), - duration = +new Date - start, - mbPerSec = (mb / (duration / 1000)).toFixed(2); - -console.log(mbPerSec+' mb/sec'); - -assert.equal(nparsed, buffer.length); - -function createMultipartBuffer(boundary, size) { - var head = - '--'+boundary+'\r\n' - + 'content-disposition: form-data; name="field1"\r\n' - + '\r\n' - , tail = '\r\n--'+boundary+'--\r\n' - , buffer = new Buffer(size); - - buffer.write(head, 'ascii', 0); - buffer.write(tail, 'ascii', buffer.length - tail.length); - return buffer; -} - -process.on('exit', function() { - for (var k in callbacks) { - assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]); - } -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/json.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/json.js deleted file mode 100644 index eb8a7245f70..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/json.js +++ /dev/null @@ -1,67 +0,0 @@ -var common = require('../test/common'), - http = require('http'), - util = require('util'), - formidable = common.formidable, - Buffer = require('buffer').Buffer, - port = common.port, - server; - -server = http.createServer(function(req, res) { - if (req.method !== 'POST') { - res.writeHead(200, {'content-type': 'text/plain'}) - res.end('Please POST a JSON payload to http://localhost:'+port+'/') - return; - } - - var form = new formidable.IncomingForm(), - fields = {}; - - form - .on('error', function(err) { - res.writeHead(500, {'content-type': 'text/plain'}); - res.end('error:\n\n'+util.inspect(err)); - console.error(err); - }) - .on('field', function(field, value) { - console.log(field, value); - fields[field] = value; - }) - .on('end', function() { - console.log('-> post done'); - res.writeHead(200, {'content-type': 'text/plain'}); - res.end('received fields:\n\n '+util.inspect(fields)); - }); - form.parse(req); -}); -server.listen(port); - -console.log('listening on http://localhost:'+port+'/'); - - -var request = http.request({ - host: 'localhost', - path: '/', - port: port, - method: 'POST', - headers: { 'content-type':'application/json', 'content-length':48 } -}, function(response) { - var data = ''; - console.log('\nServer responded with:'); - console.log('Status:', response.statusCode); - response.pipe(process.stdout); - response.on('end', function() { - console.log('\n') - process.exit(); - }); - // response.on('data', function(chunk) { - // data += chunk.toString('utf8'); - // }); - // response.on('end', function() { - // console.log('Response Data:') - // console.log(data); - // process.exit(); - // }); -}) - -request.write('{"numbers":[1,2,3,4,5],"nested":{"key":"value"}}'); -request.end(); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js deleted file mode 100644 index f6c15a64c68..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js +++ /dev/null @@ -1,43 +0,0 @@ -require('../test/common'); -var http = require('http'), - util = require('util'), - formidable = require('formidable'), - server; - -server = http.createServer(function(req, res) { - if (req.url == '/') { - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - } else if (req.url == '/post') { - var form = new formidable.IncomingForm(), - fields = []; - - form - .on('error', function(err) { - res.writeHead(200, {'content-type': 'text/plain'}); - res.end('error:\n\n'+util.inspect(err)); - }) - .on('field', function(field, value) { - console.log(field, value); - fields.push([field, value]); - }) - .on('end', function() { - console.log('-> post done'); - res.writeHead(200, {'content-type': 'text/plain'}); - res.end('received fields:\n\n '+util.inspect(fields)); - }); - form.parse(req); - } else { - res.writeHead(404, {'content-type': 'text/plain'}); - res.end('404'); - } -}); -server.listen(TEST_PORT); - -console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js deleted file mode 100644 index 050cdd9de54..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js +++ /dev/null @@ -1,48 +0,0 @@ -require('../test/common'); -var http = require('http'), - util = require('util'), - formidable = require('formidable'), - server; - -server = http.createServer(function(req, res) { - if (req.url == '/') { - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - } else if (req.url == '/upload') { - var form = new formidable.IncomingForm(), - files = [], - fields = []; - - form.uploadDir = TEST_TMP; - - form - .on('field', function(field, value) { - console.log(field, value); - fields.push([field, value]); - }) - .on('file', function(field, file) { - console.log(field, file); - files.push([field, file]); - }) - .on('end', function() { - console.log('-> upload done'); - res.writeHead(200, {'content-type': 'text/plain'}); - res.write('received fields:\n\n '+util.inspect(fields)); - res.write('\n\n'); - res.end('received files:\n\n '+util.inspect(files)); - }); - form.parse(req); - } else { - res.writeHead(404, {'content-type': 'text/plain'}); - res.end('404'); - } -}); -server.listen(TEST_PORT); - -console.log('listening on http://localhost:'+TEST_PORT+'/'); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/index.js deleted file mode 100644 index 4cc88b35877..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js deleted file mode 100644 index e34c10e4dfb..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js +++ /dev/null @@ -1,72 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -var util = require('util'), - WriteStream = require('fs').WriteStream, - EventEmitter = require('events').EventEmitter, - crypto = require('crypto'); - -function File(properties) { - EventEmitter.call(this); - - this.size = 0; - this.path = null; - this.name = null; - this.type = null; - this.hash = null; - this.lastModifiedDate = null; - - this._writeStream = null; - - for (var key in properties) { - this[key] = properties[key]; - } - - if(typeof this.hash === 'string') { - this.hash = crypto.createHash(properties.hash); - } else { - this.hash = null; - } -} -module.exports = File; -util.inherits(File, EventEmitter); - -File.prototype.open = function() { - this._writeStream = new WriteStream(this.path); -}; - -File.prototype.toJSON = function() { - return { - size: this.size, - path: this.path, - name: this.name, - type: this.type, - mtime: this.lastModifiedDate, - length: this.length, - filename: this.filename, - mime: this.mime - }; -}; - -File.prototype.write = function(buffer, cb) { - var self = this; - if (self.hash) { - self.hash.update(buffer); - } - this._writeStream.write(buffer, function() { - self.lastModifiedDate = new Date(); - self.size += buffer.length; - self.emit('progress', self.size); - cb(); - }); -}; - -File.prototype.end = function(cb) { - var self = this; - if (self.hash) { - self.hash = self.hash.digest('hex'); - } - this._writeStream.end(function() { - self.emit('end'); - cb(); - }); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js deleted file mode 100644 index c2eeaf81cd9..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js +++ /dev/null @@ -1,535 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -var fs = require('fs'); -var util = require('util'), - path = require('path'), - File = require('./file'), - MultipartParser = require('./multipart_parser').MultipartParser, - QuerystringParser = require('./querystring_parser').QuerystringParser, - OctetParser = require('./octet_parser').OctetParser, - JSONParser = require('./json_parser').JSONParser, - StringDecoder = require('string_decoder').StringDecoder, - EventEmitter = require('events').EventEmitter, - Stream = require('stream').Stream, - os = require('os'); - -function IncomingForm(opts) { - if (!(this instanceof IncomingForm)) return new IncomingForm(opts); - EventEmitter.call(this); - - opts=opts||{}; - - this.error = null; - this.ended = false; - - this.maxFields = opts.maxFields || 1000; - this.maxFieldsSize = opts.maxFieldsSize || 2 * 1024 * 1024; - this.keepExtensions = opts.keepExtensions || false; - this.uploadDir = opts.uploadDir || os.tmpDir(); - this.encoding = opts.encoding || 'utf-8'; - this.headers = null; - this.type = null; - this.hash = false; - - this.bytesReceived = null; - this.bytesExpected = null; - - this._parser = null; - this._flushing = 0; - this._fieldsSize = 0; - this.openedFiles = []; - - return this; -}; -util.inherits(IncomingForm, EventEmitter); -exports.IncomingForm = IncomingForm; - -IncomingForm.prototype.parse = function(req, cb) { - this.pause = function() { - try { - req.pause(); - } catch (err) { - // the stream was destroyed - if (!this.ended) { - // before it was completed, crash & burn - this._error(err); - } - return false; - } - return true; - }; - - this.resume = function() { - try { - req.resume(); - } catch (err) { - // the stream was destroyed - if (!this.ended) { - // before it was completed, crash & burn - this._error(err); - } - return false; - } - - return true; - }; - - // Setup callback first, so we don't miss anything from data events emitted - // immediately. - if (cb) { - var fields = {}, files = {}; - this - .on('field', function(name, value) { - fields[name] = value; - }) - .on('file', function(name, file) { - files[name] = file; - }) - .on('error', function(err) { - cb(err, fields, files); - }) - .on('end', function() { - cb(null, fields, files); - }); - } - - // Parse headers and setup the parser, ready to start listening for data. - this.writeHeaders(req.headers); - - // Start listening for data. - var self = this; - req - .on('error', function(err) { - self._error(err); - }) - .on('aborted', function() { - self.emit('aborted'); - self._error(new Error('Request aborted')); - }) - .on('data', function(buffer) { - self.write(buffer); - }) - .on('end', function() { - if (self.error) { - return; - } - - var err = self._parser.end(); - if (err) { - self._error(err); - } - }); - - return this; -}; - -IncomingForm.prototype.writeHeaders = function(headers) { - this.headers = headers; - this._parseContentLength(); - this._parseContentType(); -}; - -IncomingForm.prototype.write = function(buffer) { - if (!this._parser) { - this._error(new Error('unintialized parser')); - return; - } - - this.bytesReceived += buffer.length; - this.emit('progress', this.bytesReceived, this.bytesExpected); - - var bytesParsed = this._parser.write(buffer); - if (bytesParsed !== buffer.length) { - this._error(new Error('parser error, '+bytesParsed+' of '+buffer.length+' bytes parsed')); - } - - return bytesParsed; -}; - -IncomingForm.prototype.pause = function() { - // this does nothing, unless overwritten in IncomingForm.parse - return false; -}; - -IncomingForm.prototype.resume = function() { - // this does nothing, unless overwritten in IncomingForm.parse - return false; -}; - -IncomingForm.prototype.onPart = function(part) { - // this method can be overwritten by the user - this.handlePart(part); -}; - -IncomingForm.prototype.handlePart = function(part) { - var self = this; - - if (part.filename === undefined) { - var value = '' - , decoder = new StringDecoder(this.encoding); - - part.on('data', function(buffer) { - self._fieldsSize += buffer.length; - if (self._fieldsSize > self.maxFieldsSize) { - self._error(new Error('maxFieldsSize exceeded, received '+self._fieldsSize+' bytes of field data')); - return; - } - value += decoder.write(buffer); - }); - - part.on('end', function() { - self.emit('field', part.name, value); - }); - return; - } - - this._flushing++; - - var file = new File({ - path: this._uploadPath(part.filename), - name: part.filename, - type: part.mime, - hash: self.hash - }); - - this.emit('fileBegin', part.name, file); - - file.open(); - this.openedFiles.push(file); - - part.on('data', function(buffer) { - self.pause(); - file.write(buffer, function() { - self.resume(); - }); - }); - - part.on('end', function() { - file.end(function() { - self._flushing--; - self.emit('file', part.name, file); - self._maybeEnd(); - }); - }); -}; - -function dummyParser(self) { - return { - end: function () { - self.ended = true; - self._maybeEnd(); - return null; - } - }; -} - -IncomingForm.prototype._parseContentType = function() { - if (this.bytesExpected === 0) { - this._parser = dummyParser(this); - return; - } - - if (!this.headers['content-type']) { - this._error(new Error('bad content-type header, no content-type')); - return; - } - - if (this.headers['content-type'].match(/octet-stream/i)) { - this._initOctetStream(); - return; - } - - if (this.headers['content-type'].match(/urlencoded/i)) { - this._initUrlencoded(); - return; - } - - if (this.headers['content-type'].match(/multipart/i)) { - var m; - if (m = this.headers['content-type'].match(/boundary=(?:"([^"]+)"|([^;]+))/i)) { - this._initMultipart(m[1] || m[2]); - } else { - this._error(new Error('bad content-type header, no multipart boundary')); - } - return; - } - - if (this.headers['content-type'].match(/json/i)) { - this._initJSONencoded(); - return; - } - - this._error(new Error('bad content-type header, unknown content-type: '+this.headers['content-type'])); -}; - -IncomingForm.prototype._error = function(err) { - if (this.error || this.ended) { - return; - } - - this.error = err; - this.pause(); - this.emit('error', err); - - if (Array.isArray(this.openedFiles)) { - this.openedFiles.forEach(function(file) { - file._writeStream.destroy(); - setTimeout(fs.unlink, 0, file.path); - }); - } -}; - -IncomingForm.prototype._parseContentLength = function() { - this.bytesReceived = 0; - if (this.headers['content-length']) { - this.bytesExpected = parseInt(this.headers['content-length'], 10); - } else if (this.headers['transfer-encoding'] === undefined) { - this.bytesExpected = 0; - } - - if (this.bytesExpected !== null) { - this.emit('progress', this.bytesReceived, this.bytesExpected); - } -}; - -IncomingForm.prototype._newParser = function() { - return new MultipartParser(); -}; - -IncomingForm.prototype._initMultipart = function(boundary) { - this.type = 'multipart'; - - var parser = new MultipartParser(), - self = this, - headerField, - headerValue, - part; - - parser.initWithBoundary(boundary); - - parser.onPartBegin = function() { - part = new Stream(); - part.readable = true; - part.headers = {}; - part.name = null; - part.filename = null; - part.mime = null; - - part.transferEncoding = 'binary'; - part.transferBuffer = ''; - - headerField = ''; - headerValue = ''; - }; - - parser.onHeaderField = function(b, start, end) { - headerField += b.toString(self.encoding, start, end); - }; - - parser.onHeaderValue = function(b, start, end) { - headerValue += b.toString(self.encoding, start, end); - }; - - parser.onHeaderEnd = function() { - headerField = headerField.toLowerCase(); - part.headers[headerField] = headerValue; - - var m; - if (headerField == 'content-disposition') { - if (m = headerValue.match(/\bname="([^"]+)"/i)) { - part.name = m[1]; - } - - part.filename = self._fileName(headerValue); - } else if (headerField == 'content-type') { - part.mime = headerValue; - } else if (headerField == 'content-transfer-encoding') { - part.transferEncoding = headerValue.toLowerCase(); - } - - headerField = ''; - headerValue = ''; - }; - - parser.onHeadersEnd = function() { - switch(part.transferEncoding){ - case 'binary': - case '7bit': - case '8bit': - parser.onPartData = function(b, start, end) { - part.emit('data', b.slice(start, end)); - }; - - parser.onPartEnd = function() { - part.emit('end'); - }; - break; - - case 'base64': - parser.onPartData = function(b, start, end) { - part.transferBuffer += b.slice(start, end).toString('ascii'); - - /* - four bytes (chars) in base64 converts to three bytes in binary - encoding. So we should always work with a number of bytes that - can be divided by 4, it will result in a number of buytes that - can be divided vy 3. - */ - var offset = parseInt(part.transferBuffer.length / 4) * 4; - part.emit('data', new Buffer(part.transferBuffer.substring(0, offset), 'base64')) - part.transferBuffer = part.transferBuffer.substring(offset); - }; - - parser.onPartEnd = function() { - part.emit('data', new Buffer(part.transferBuffer, 'base64')) - part.emit('end'); - }; - break; - - default: - return self._error(new Error('unknown transfer-encoding')); - } - - self.onPart(part); - }; - - - parser.onEnd = function() { - self.ended = true; - self._maybeEnd(); - }; - - this._parser = parser; -}; - -IncomingForm.prototype._fileName = function(headerValue) { - var m = headerValue.match(/\bfilename="(.*?)"($|; )/i); - if (!m) return; - - var filename = m[1].substr(m[1].lastIndexOf('\\') + 1); - filename = filename.replace(/%22/g, '"'); - filename = filename.replace(/&#([\d]{4});/g, function(m, code) { - return String.fromCharCode(code); - }); - return filename; -}; - -IncomingForm.prototype._initUrlencoded = function() { - this.type = 'urlencoded'; - - var parser = new QuerystringParser(this.maxFields) - , self = this; - - parser.onField = function(key, val) { - self.emit('field', key, val); - }; - - parser.onEnd = function() { - self.ended = true; - self._maybeEnd(); - }; - - this._parser = parser; -}; - -IncomingForm.prototype._initOctetStream = function() { - this.type = 'octet-stream'; - var filename = this.headers['x-file-name']; - var mime = this.headers['content-type']; - - var file = new File({ - path: this._uploadPath(filename), - name: filename, - type: mime - }); - - file.open(); - - this.emit('fileBegin', filename, file); - - this._flushing++; - - var self = this; - - self._parser = new OctetParser(); - - //Keep track of writes that haven't finished so we don't emit the file before it's done being written - var outstandingWrites = 0; - - self._parser.on('data', function(buffer){ - self.pause(); - outstandingWrites++; - - file.write(buffer, function() { - outstandingWrites--; - self.resume(); - - if(self.ended){ - self._parser.emit('doneWritingFile'); - } - }); - }); - - self._parser.on('end', function(){ - self._flushing--; - self.ended = true; - - var done = function(){ - self.emit('file', 'file', file); - self._maybeEnd(); - }; - - if(outstandingWrites === 0){ - done(); - } else { - self._parser.once('doneWritingFile', done); - } - }); -}; - -IncomingForm.prototype._initJSONencoded = function() { - this.type = 'json'; - - var parser = new JSONParser() - , self = this; - - if (this.bytesExpected) { - parser.initWithLength(this.bytesExpected); - } - - parser.onField = function(key, val) { - self.emit('field', key, val); - } - - parser.onEnd = function() { - self.ended = true; - self._maybeEnd(); - }; - - this._parser = parser; -}; - -IncomingForm.prototype._uploadPath = function(filename) { - var name = ''; - for (var i = 0; i < 32; i++) { - name += Math.floor(Math.random() * 16).toString(16); - } - - if (this.keepExtensions) { - var ext = path.extname(filename); - ext = ext.replace(/(\.[a-z0-9]+).*/, '$1'); - - name += ext; - } - - return path.join(this.uploadDir, name); -}; - -IncomingForm.prototype._maybeEnd = function() { - if (!this.ended || this._flushing || this.error) { - return; - } - - this.emit('end'); -}; - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js deleted file mode 100644 index 7a6e3e1097c..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js +++ /dev/null @@ -1,3 +0,0 @@ -var IncomingForm = require('./incoming_form').IncomingForm; -IncomingForm.IncomingForm = IncomingForm; -module.exports = IncomingForm; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/json_parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/json_parser.js deleted file mode 100644 index 6ce966b4fd7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/json_parser.js +++ /dev/null @@ -1,35 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -var Buffer = require('buffer').Buffer - -function JSONParser() { - this.data = new Buffer(''); - this.bytesWritten = 0; -}; -exports.JSONParser = JSONParser; - -JSONParser.prototype.initWithLength = function(length) { - this.data = new Buffer(length); -} - -JSONParser.prototype.write = function(buffer) { - if (this.data.length >= this.bytesWritten + buffer.length) { - buffer.copy(this.data, this.bytesWritten); - } else { - this.data = Buffer.concat([this.data, buffer]); - } - this.bytesWritten += buffer.length; - return buffer.length; -} - -JSONParser.prototype.end = function() { - try { - var fields = JSON.parse(this.data.toString('utf8')) - for (var field in fields) { - this.onField(field, fields[field]); - } - } catch (e) {} - this.data = null; - - this.onEnd(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js deleted file mode 100644 index 98a68560ebb..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js +++ /dev/null @@ -1,324 +0,0 @@ -var Buffer = require('buffer').Buffer, - s = 0, - S = - { PARSER_UNINITIALIZED: s++, - START: s++, - START_BOUNDARY: s++, - HEADER_FIELD_START: s++, - HEADER_FIELD: s++, - HEADER_VALUE_START: s++, - HEADER_VALUE: s++, - HEADER_VALUE_ALMOST_DONE: s++, - HEADERS_ALMOST_DONE: s++, - PART_DATA_START: s++, - PART_DATA: s++, - PART_END: s++, - END: s++ - }, - - f = 1, - F = - { PART_BOUNDARY: f, - LAST_BOUNDARY: f *= 2 - }, - - LF = 10, - CR = 13, - SPACE = 32, - HYPHEN = 45, - COLON = 58, - A = 97, - Z = 122, - - lower = function(c) { - return c | 0x20; - }; - -for (s in S) { - exports[s] = S[s]; -} - -function MultipartParser() { - this.boundary = null; - this.boundaryChars = null; - this.lookbehind = null; - this.state = S.PARSER_UNINITIALIZED; - - this.index = null; - this.flags = 0; -}; -exports.MultipartParser = MultipartParser; - -MultipartParser.stateToString = function(stateNumber) { - for (var state in S) { - var number = S[state]; - if (number === stateNumber) return state; - } -}; - -MultipartParser.prototype.initWithBoundary = function(str) { - this.boundary = new Buffer(str.length+4); - this.boundary.write('\r\n--', 'ascii', 0); - this.boundary.write(str, 'ascii', 4); - this.lookbehind = new Buffer(this.boundary.length+8); - this.state = S.START; - - this.boundaryChars = {}; - for (var i = 0; i < this.boundary.length; i++) { - this.boundaryChars[this.boundary[i]] = true; - } -}; - -MultipartParser.prototype.write = function(buffer) { - var self = this, - i = 0, - len = buffer.length, - prevIndex = this.index, - index = this.index, - state = this.state, - flags = this.flags, - lookbehind = this.lookbehind, - boundary = this.boundary, - boundaryChars = this.boundaryChars, - boundaryLength = this.boundary.length, - boundaryEnd = boundaryLength - 1, - bufferLength = buffer.length, - c, - cl, - - mark = function(name) { - self[name+'Mark'] = i; - }, - clear = function(name) { - delete self[name+'Mark']; - }, - callback = function(name, buffer, start, end) { - if (start !== undefined && start === end) { - return; - } - - var callbackSymbol = 'on'+name.substr(0, 1).toUpperCase()+name.substr(1); - if (callbackSymbol in self) { - self[callbackSymbol](buffer, start, end); - } - }, - dataCallback = function(name, clear) { - var markSymbol = name+'Mark'; - if (!(markSymbol in self)) { - return; - } - - if (!clear) { - callback(name, buffer, self[markSymbol], buffer.length); - self[markSymbol] = 0; - } else { - callback(name, buffer, self[markSymbol], i); - delete self[markSymbol]; - } - }; - - for (i = 0; i < len; i++) { - c = buffer[i]; - switch (state) { - case S.PARSER_UNINITIALIZED: - return i; - case S.START: - index = 0; - state = S.START_BOUNDARY; - case S.START_BOUNDARY: - if (index == boundary.length - 2) { - if (c != CR) { - return i; - } - index++; - break; - } else if (index - 1 == boundary.length - 2) { - if (c != LF) { - return i; - } - index = 0; - callback('partBegin'); - state = S.HEADER_FIELD_START; - break; - } - - if (c != boundary[index+2]) { - index = -2; - } - if (c == boundary[index+2]) { - index++; - } - break; - case S.HEADER_FIELD_START: - state = S.HEADER_FIELD; - mark('headerField'); - index = 0; - case S.HEADER_FIELD: - if (c == CR) { - clear('headerField'); - state = S.HEADERS_ALMOST_DONE; - break; - } - - index++; - if (c == HYPHEN) { - break; - } - - if (c == COLON) { - if (index == 1) { - // empty header field - return i; - } - dataCallback('headerField', true); - state = S.HEADER_VALUE_START; - break; - } - - cl = lower(c); - if (cl < A || cl > Z) { - return i; - } - break; - case S.HEADER_VALUE_START: - if (c == SPACE) { - break; - } - - mark('headerValue'); - state = S.HEADER_VALUE; - case S.HEADER_VALUE: - if (c == CR) { - dataCallback('headerValue', true); - callback('headerEnd'); - state = S.HEADER_VALUE_ALMOST_DONE; - } - break; - case S.HEADER_VALUE_ALMOST_DONE: - if (c != LF) { - return i; - } - state = S.HEADER_FIELD_START; - break; - case S.HEADERS_ALMOST_DONE: - if (c != LF) { - return i; - } - - callback('headersEnd'); - state = S.PART_DATA_START; - break; - case S.PART_DATA_START: - state = S.PART_DATA; - mark('partData'); - case S.PART_DATA: - prevIndex = index; - - if (index == 0) { - // boyer-moore derrived algorithm to safely skip non-boundary data - i += boundaryEnd; - while (i < bufferLength && !(buffer[i] in boundaryChars)) { - i += boundaryLength; - } - i -= boundaryEnd; - c = buffer[i]; - } - - if (index < boundary.length) { - if (boundary[index] == c) { - if (index == 0) { - dataCallback('partData', true); - } - index++; - } else { - index = 0; - } - } else if (index == boundary.length) { - index++; - if (c == CR) { - // CR = part boundary - flags |= F.PART_BOUNDARY; - } else if (c == HYPHEN) { - // HYPHEN = end boundary - flags |= F.LAST_BOUNDARY; - } else { - index = 0; - } - } else if (index - 1 == boundary.length) { - if (flags & F.PART_BOUNDARY) { - index = 0; - if (c == LF) { - // unset the PART_BOUNDARY flag - flags &= ~F.PART_BOUNDARY; - callback('partEnd'); - callback('partBegin'); - state = S.HEADER_FIELD_START; - break; - } - } else if (flags & F.LAST_BOUNDARY) { - if (c == HYPHEN) { - callback('partEnd'); - callback('end'); - state = S.END; - } else { - index = 0; - } - } else { - index = 0; - } - } - - if (index > 0) { - // when matching a possible boundary, keep a lookbehind reference - // in case it turns out to be a false lead - lookbehind[index-1] = c; - } else if (prevIndex > 0) { - // if our boundary turned out to be rubbish, the captured lookbehind - // belongs to partData - callback('partData', lookbehind, 0, prevIndex); - prevIndex = 0; - mark('partData'); - - // reconsider the current character even so it interrupted the sequence - // it could be the beginning of a new sequence - i--; - } - - break; - case S.END: - break; - default: - return i; - } - } - - dataCallback('headerField'); - dataCallback('headerValue'); - dataCallback('partData'); - - this.index = index; - this.state = state; - this.flags = flags; - - return len; -}; - -MultipartParser.prototype.end = function() { - var callback = function(self, name) { - var callbackSymbol = 'on'+name.substr(0, 1).toUpperCase()+name.substr(1); - if (callbackSymbol in self) { - self[callbackSymbol](); - } - }; - if ((this.state == S.HEADER_FIELD_START && this.index == 0) || - (this.state == S.PART_DATA && this.index == this.boundary.length)) { - callback(this, 'partEnd'); - callback(this, 'end'); - } else if (this.state != S.END) { - return new Error('MultipartParser.end(): stream ended unexpectedly: ' + this.explain()); - } -}; - -MultipartParser.prototype.explain = function() { - return 'state = ' + MultipartParser.stateToString(this.state); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/octet_parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/octet_parser.js deleted file mode 100644 index 6e8b551556a..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/octet_parser.js +++ /dev/null @@ -1,20 +0,0 @@ -var EventEmitter = require('events').EventEmitter - , util = require('util'); - -function OctetParser(options){ - if(!(this instanceof OctetParser)) return new OctetParser(options); - EventEmitter.call(this); -} - -util.inherits(OctetParser, EventEmitter); - -exports.OctetParser = OctetParser; - -OctetParser.prototype.write = function(buffer) { - this.emit('data', buffer); - return buffer.length; -}; - -OctetParser.prototype.end = function() { - this.emit('end'); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js deleted file mode 100644 index 320ce5a1ba0..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js +++ /dev/null @@ -1,27 +0,0 @@ -if (global.GENTLY) require = GENTLY.hijack(require); - -// This is a buffering parser, not quite as nice as the multipart one. -// If I find time I'll rewrite this to be fully streaming as well -var querystring = require('querystring'); - -function QuerystringParser(maxKeys) { - this.maxKeys = maxKeys; - this.buffer = ''; -}; -exports.QuerystringParser = QuerystringParser; - -QuerystringParser.prototype.write = function(buffer) { - this.buffer += buffer.toString('ascii'); - return buffer.length; -}; - -QuerystringParser.prototype.end = function() { - var fields = querystring.parse(this.buffer, '&', '=', { maxKeys: this.maxKeys }); - for (var field in fields) { - this.onField(field, fields[field]); - } - this.buffer = ''; - - this.onEnd(); -}; - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js deleted file mode 100644 index e9493e9baf3..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js +++ /dev/null @@ -1,6 +0,0 @@ -// Backwards compatibility ... -try { - module.exports = require('util'); -} catch (e) { - module.exports = require('sys'); -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/package.json deleted file mode 100644 index 4679a11ac79..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "formidable", - "description": "A node.js module for parsing form data, especially file uploads.", - "homepage": "https://github.com/felixge/node-formidable", - "version": "1.0.14", - "devDependencies": { - "gently": "0.8.0", - "findit": "0.1.1", - "hashish": "0.0.4", - "urun": "~0.0.6", - "utest": "0.0.3", - "request": "~2.11.4" - }, - "directories": { - "lib": "./lib" - }, - "main": "./lib/index", - "scripts": { - "test": "node test/run.js", - "clean": "rm test/tmp/*" - }, - "engines": { - "node": ">=0.8.0" - }, - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-formidable.git" - }, - "bugs": { - "url": "http://github.com/felixge/node-formidable/issues" - }, - "optionalDependencies": {}, - "readme": "# Formidable\n\n[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable)\n\n## Purpose\n\nA node.js module for parsing form data, especially file uploads.\n\n## Current status\n\nThis module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading\nand encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from\na large variety of clients and is considered production-ready.\n\n## Features\n\n* Fast (~500mb/sec), non-buffering multipart parser\n* Automatically writing file uploads to disk\n* Low memory footprint\n* Graceful error handling\n* Very high test coverage\n\n## Installation\n\nVia [npm](http://github.com/isaacs/npm):\n```\nnpm install formidable@latest\n```\nManually:\n```\ngit clone git://github.com/felixge/node-formidable.git formidable\nvim my.js\n# var formidable = require('./formidable');\n```\n\nNote: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library.\n\n## Example\n\nParse an incoming file upload.\n```javascript\nvar formidable = require('formidable'),\n http = require('http'),\n util = require('util');\n\nhttp.createServer(function(req, res) {\n if (req.url == '/upload' && req.method.toLowerCase() == 'post') {\n // parse a file upload\n var form = new formidable.IncomingForm();\n\n form.parse(req, function(err, fields, files) {\n res.writeHead(200, {'content-type': 'text/plain'});\n res.write('received upload:\\n\\n');\n res.end(util.inspect({fields: fields, files: files}));\n });\n\n return;\n }\n\n // show a file upload form\n res.writeHead(200, {'content-type': 'text/html'});\n res.end(\n '
    '+\n '
    '+\n '
    '+\n ''+\n '
    '\n );\n}).listen(8080);\n```\n## API\n\n### Formidable.IncomingForm\n```javascript\nvar form = new formidable.IncomingForm()\n```\nCreates a new incoming form.\n\n```javascript\nform.encoding = 'utf-8';\n```\nSets encoding for incoming form fields.\n\n```javascript\nform.uploadDir = process.env.TMP || process.env.TMPDIR || process.env.TEMP || '/tmp' || process.cwd();\n```\nThe directory for placing file uploads in. You can move them later on using\n`fs.rename()`. The default directory is picked at module load time depending on\nthe first existing directory from those listed above.\n\n```javascript\nform.keepExtensions = false;\n```\nIf you want the files written to `form.uploadDir` to include the extensions of the original files, set this property to `true`.\n\n```javascript\nform.type\n```\nEither 'multipart' or 'urlencoded' depending on the incoming request.\n\n```javascript\nform.maxFieldsSize = 2 * 1024 * 1024;\n```\nLimits the amount of memory a field (not file) can allocate in bytes.\nIf this value is exceeded, an `'error'` event is emitted. The default\nsize is 2MB.\n\n```javascript\nform.maxFields = 0;\n```\nLimits the number of fields that the querystring parser will decode. Defaults\nto 0 (unlimited).\n\n```javascript\nform.hash = false;\n```\nIf you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`.\n\n```javascript\nform.bytesReceived\n```\nThe amount of bytes received for this form so far.\n\n```javascript\nform.bytesExpected\n```\nThe expected number of bytes in this form.\n\n```javascript\nform.parse(request, [cb]);\n```\nParses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback:\n\n\n```javascript\nform.parse(req, function(err, fields, files) {\n // ...\n});\n\nform.onPart(part);\n```\nYou may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing.\n\n```javascript\nform.onPart = function(part) {\n part.addListener('data', function() {\n // ...\n });\n}\n```\nIf you want to use formidable to only handle certain parts for you, you can do so:\n```javascript\nform.onPart = function(part) {\n if (!part.filename) {\n // let formidable handle all non-file parts\n form.handlePart(part);\n }\n}\n```\nCheck the code in this method for further inspiration.\n\n\n### Formidable.File\n```javascript\nfile.size = 0\n```\nThe size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet.\n```javascript\nfile.path = null\n```\nThe path this file is being written to. You can modify this in the `'fileBegin'` event in\ncase you are unhappy with the way formidable generates a temporary path for your files.\n```javascript\nfile.name = null\n```\nThe name this file had according to the uploading client.\n```javascript\nfile.type = null\n```\nThe mime type of this file, according to the uploading client.\n```javascript\nfile.lastModifiedDate = null\n```\nA date object (or `null`) containing the time this file was last written to. Mostly\nhere for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).\n```javascript\nfile.hash = null\n```\nIf hash calculation was set, you can read the hex digest out of this var.\n\n#### Formidable.File#toJSON()\n\n This method returns a JSON-representation of the file, allowing you to\n `JSON.stringify()` the file which is useful for logging and responding\n to requests.\n\n### Events\n\n\n#### 'progress'\n```javascript\nform.on('progress', function(bytesReceived, bytesExpected) {\n});\n```\nEmitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.\n\n\n\n#### 'field'\n```javascript\nform.on('field', function(name, value) {\n});\n```\n\n#### 'fileBegin'\n\nEmitted whenever a field / value pair has been received.\n```javascript\nform.on('fileBegin', function(name, file) {\n});\n```\n\n#### 'file'\n\nEmitted whenever a new file is detected in the upload stream. Use this even if\nyou want to stream the file to somewhere else while buffering the upload on\nthe file system.\n\nEmitted whenever a field / file pair has been received. `file` is an instance of `File`.\n```javascript\nform.on('file', function(name, file) {\n});\n```\n\n#### 'error'\n\nEmitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events.\n```javascript\nform.on('error', function(err) {\n});\n```\n\n#### 'aborted'\n\n\nEmitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core).\n```javascript\nform.on('aborted', function() {\n});\n```\n\n##### 'end'\n```javascript\nform.on('end', function() {\n});\n```\nEmitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.\n\n\n\n## Changelog\n\n### v1.0.14\n\n* Add failing hash tests. (Ben Trask)\n* Enable hash calculation again (Eugene Girshov)\n* Test for immediate data events (Tim Smart)\n* Re-arrange IncomingForm#parse (Tim Smart)\n\n### v1.0.13\n\n* Only update hash if update method exists (Sven Lito)\n* According to travis v0.10 needs to go quoted (Sven Lito)\n* Bumping build node versions (Sven Lito)\n* Additional fix for empty requests (Eugene Girshov)\n* Change the default to 1000, to match the new Node behaviour. (OrangeDog)\n* Add ability to control maxKeys in the querystring parser. (OrangeDog)\n* Adjust test case to work with node 0.9.x (Eugene Girshov)\n* Update package.json (Sven Lito)\n* Path adjustment according to eb4468b (Markus Ast)\n\n### v1.0.12\n\n* Emit error on aborted connections (Eugene Girshov)\n* Add support for empty requests (Eugene Girshov)\n* Fix name/filename handling in Content-Disposition (jesperp)\n* Tolerate malformed closing boundary in multipart (Eugene Girshov)\n* Ignore preamble in multipart messages (Eugene Girshov)\n* Add support for application/json (Mike Frey, Carlos Rodriguez)\n* Add support for Base64 encoding (Elmer Bulthuis)\n* Add File#toJSON (TJ Holowaychuk)\n* Remove support for Node.js 0.4 & 0.6 (Andrew Kelley)\n* Documentation improvements (Sven Lito, Andre Azevedo)\n* Add support for application/octet-stream (Ion Lupascu, Chris Scribner)\n* Use os.tmpDir() to get tmp directory (Andrew Kelley)\n* Improve package.json (Andrew Kelley, Sven Lito)\n* Fix benchmark script (Andrew Kelley)\n* Fix scope issue in incoming_forms (Sven Lito)\n* Fix file handle leak on error (OrangeDog)\n\n### v1.0.11\n\n* Calculate checksums for incoming files (sreuter)\n* Add definition parameters to \"IncomingForm\" as an argument (Math-)\n\n### v1.0.10\n\n* Make parts to be proper Streams (Matt Robenolt)\n\n### v1.0.9\n\n* Emit progress when content length header parsed (Tim Koschützki)\n* Fix Readme syntax due to GitHub changes (goob)\n* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara)\n\n### v1.0.8\n\n* Strip potentially unsafe characters when using `keepExtensions: true`.\n* Switch to utest / urun for testing\n* Add travis build\n\n### v1.0.7\n\n* Remove file from package that was causing problems when installing on windows. (#102)\n* Fix typos in Readme (Jason Davies).\n\n### v1.0.6\n\n* Do not default to the default to the field name for file uploads where\n filename=\"\".\n\n### v1.0.5\n\n* Support filename=\"\" in multipart parts\n* Explain unexpected end() errors in parser better\n\n**Note:** Starting with this version, formidable emits 'file' events for empty\nfile input fields. Previously those were incorrectly emitted as regular file\ninput fields with value = \"\".\n\n### v1.0.4\n\n* Detect a good default tmp directory regardless of platform. (#88)\n\n### v1.0.3\n\n* Fix problems with utf8 characters (#84) / semicolons in filenames (#58)\n* Small performance improvements\n* New test suite and fixture system\n\n### v1.0.2\n\n* Exclude node\\_modules folder from git\n* Implement new `'aborted'` event\n* Fix files in example folder to work with recent node versions\n* Make gently a devDependency\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2)\n\n### v1.0.1\n\n* Fix package.json to refer to proper main directory. (#68, Dean Landolt)\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1)\n\n### v1.0.0\n\n* Add support for multipart boundaries that are quoted strings. (Jeff Craig)\n\nThis marks the beginning of development on version 2.0 which will include\nseveral architectural improvements.\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0)\n\n### v0.9.11\n\n* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki)\n* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class\n\n**Important:** The old property names of the File class will be removed in a\nfuture release.\n\n[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11)\n\n### Older releases\n\nThese releases were done before starting to maintain the above Changelog:\n\n* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10)\n* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9)\n* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8)\n* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7)\n* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6)\n* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5)\n* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4)\n* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3)\n* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2)\n* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)\n* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0)\n\n## License\n\nFormidable is licensed under the MIT license.\n\n## Ports\n\n* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable\n\n## Credits\n\n* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js\n", - "readmeFilename": "Readme.md", - "dependencies": {}, - "_id": "formidable@1.0.14", - "_from": "formidable@1.0.14" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js deleted file mode 100644 index 6a942951392..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js +++ /dev/null @@ -1,18 +0,0 @@ -var path = require('path'); - -var root = path.join(__dirname, '../'); -exports.dir = { - root : root, - lib : root + '/lib', - fixture : root + '/test/fixture', - tmp : root + '/test/tmp', -}; - -exports.port = 13532; - -exports.formidable = require('..'); -exports.assert = require('assert'); - -exports.require = function(lib) { - return require(exports.dir.lib + '/' + lib); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/beta-sticker-1.png b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/beta-sticker-1.png deleted file mode 100644 index 20b1a7f1779..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/beta-sticker-1.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/binaryfile.tar.gz b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/binaryfile.tar.gz deleted file mode 100644 index 4a85af7a1c8..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/binaryfile.tar.gz and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/blank.gif b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/blank.gif deleted file mode 100644 index 75b945d2553..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/blank.gif and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt deleted file mode 100644 index e7a4785e00c..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt +++ /dev/null @@ -1 +0,0 @@ -I am a text file with a funky name! diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/menu_separator.png b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/menu_separator.png deleted file mode 100644 index 1c16a71ed41..00000000000 Binary files a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/menu_separator.png and /dev/null differ diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt deleted file mode 100644 index 9b6903e26fc..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt +++ /dev/null @@ -1 +0,0 @@ -I am a plain text file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md deleted file mode 100644 index 3c9dbe3dd07..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md +++ /dev/null @@ -1,3 +0,0 @@ -* Opera does not allow submitting this file, it shows a warning to the - user that the file could not be found instead. Tested in 9.8, 11.51 on OSX. - Reported to Opera on 08.09.2011 (tracking email DSK-346009@bugs.opera.com). diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/encoding.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/encoding.js deleted file mode 100644 index fc22026548a..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/encoding.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports['menu_seperator.png.http'] = [ - {type: 'file', name: 'image', filename: 'menu_separator.png', fixture: 'menu_separator.png', - sha1: 'c845ca3ea794be298f2a1b79769b71939eaf4e54'} -]; - -module.exports['beta-sticker-1.png.http'] = [ - {type: 'file', name: 'sticker', filename: 'beta-sticker-1.png', fixture: 'beta-sticker-1.png', - sha1: '6abbcffd12b4ada5a6a084fe9e4584f846331bc4'} -]; - -module.exports['blank.gif.http'] = [ - {type: 'file', name: 'file', filename: 'blank.gif', fixture: 'blank.gif', - sha1: 'a1fdee122b95748d81cee426d717c05b5174fe96'} -]; - -module.exports['binaryfile.tar.gz.http'] = [ - {type: 'file', name: 'file', filename: 'binaryfile.tar.gz', fixture: 'binaryfile.tar.gz', - sha1: 'cfabe13b348e5e69287d677860880c52a69d2155'} -]; - -module.exports['plain.txt.http'] = [ - {type: 'file', name: 'file', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'} -]; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/misc.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/misc.js deleted file mode 100644 index 4489176d971..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/misc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - 'empty.http': [], - 'empty-urlencoded.http': [], - 'empty-multipart.http': [], - 'minimal.http': [], -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js deleted file mode 100644 index f03b4f01d80..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports['generic.http'] = [ - {type: 'file', name: 'upload', filename: '', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; - -module.exports['filename-name.http'] = [ - {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/preamble.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/preamble.js deleted file mode 100644 index d2e4cfdb24d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/preamble.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports['crlf.http'] = [ - {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; - -module.exports['preamble.http'] = [ - {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js deleted file mode 100644 index eb76fdc147d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +++ /dev/null @@ -1,21 +0,0 @@ -var properFilename = 'funkyfilename.txt'; - -function expect(filename) { - return [ - {type: 'field', name: 'title', value: 'Weird filename'}, - {type: 'file', name: 'upload', filename: filename, fixture: properFilename}, - ]; -}; - -var webkit = " ? % * | \" < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; -var ffOrIe = " ? % * | \" < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt"; - -module.exports = { - 'osx-chrome-13.http' : expect(webkit), - 'osx-firefox-3.6.http' : expect(ffOrIe), - 'osx-safari-5.http' : expect(webkit), - 'xp-chrome-12.http' : expect(webkit), - 'xp-ie-7.http' : expect(ffOrIe), - 'xp-ie-8.http' : expect(ffOrIe), - 'xp-safari-5.http' : expect(webkit), -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/workarounds.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/workarounds.js deleted file mode 100644 index e59c5b265d7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/workarounds.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports['missing-hyphens1.http'] = [ - {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; -module.exports['missing-hyphens2.http'] = [ - {type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt', - sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}, -]; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js deleted file mode 100644 index a4761699e9c..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js +++ /dev/null @@ -1,72 +0,0 @@ -exports['rfc1867'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--\r\n', - parts: - [ { headers: { - 'content-disposition': 'form-data; name="field1"', - }, - data: 'Joe Blow\r\nalmost tricked you!', - }, - { headers: { - 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', - 'Content-Type': 'text/plain', - }, - data: '... contents of file1.txt ...\r', - } - ] - }; - -exports['noTrailing\r\n'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--', - parts: - [ { headers: { - 'content-disposition': 'form-data; name="field1"', - }, - data: 'Joe Blow\r\nalmost tricked you!', - }, - { headers: { - 'content-disposition': 'form-data; name="pics"; filename="file1.txt"', - 'Content-Type': 'text/plain', - }, - data: '... contents of file1.txt ...\r', - } - ] - }; - -exports['emptyHeader'] = - { boundary: 'AaB03x', - raw: - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="field1"\r\n'+ - ': foo\r\n'+ - '\r\n'+ - 'Joe Blow\r\nalmost tricked you!\r\n'+ - '--AaB03x\r\n'+ - 'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+ - 'Content-Type: text/plain\r\n'+ - '\r\n'+ - '... contents of file1.txt ...\r\r\n'+ - '--AaB03x--\r\n', - expectError: true, - }; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js deleted file mode 100644 index 8e10ac97b2b..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js +++ /dev/null @@ -1,96 +0,0 @@ -var hashish = require('hashish'); -var fs = require('fs'); -var findit = require('findit'); -var path = require('path'); -var http = require('http'); -var net = require('net'); -var assert = require('assert'); - -var common = require('../common'); -var formidable = common.formidable; - -var server = http.createServer(); -server.listen(common.port, findFixtures); - -function findFixtures() { - var fixtures = []; - findit - .sync(common.dir.fixture + '/js') - .forEach(function(jsPath) { - if (!/\.js$/.test(jsPath)) return; - - var group = path.basename(jsPath, '.js'); - hashish.forEach(require(jsPath), function(fixture, name) { - fixtures.push({ - name : group + '/' + name, - fixture : fixture, - }); - }); - }); - - testNext(fixtures); -} - -function testNext(fixtures) { - var fixture = fixtures.shift(); - if (!fixture) return server.close(); - - var name = fixture.name; - var fixture = fixture.fixture; - - uploadFixture(name, function(err, parts) { - if (err) throw err; - - fixture.forEach(function(expectedPart, i) { - var parsedPart = parts[i]; - assert.equal(parsedPart.type, expectedPart.type); - assert.equal(parsedPart.name, expectedPart.name); - - if (parsedPart.type === 'file') { - var file = parsedPart.value; - assert.equal(file.name, expectedPart.filename); - if(expectedPart.sha1) assert.equal(file.hash, expectedPart.sha1); - } - }); - - testNext(fixtures); - }); -}; - -function uploadFixture(name, cb) { - server.once('request', function(req, res) { - var form = new formidable.IncomingForm(); - form.uploadDir = common.dir.tmp; - form.hash = "sha1"; - form.parse(req); - - function callback() { - var realCallback = cb; - cb = function() {}; - realCallback.apply(null, arguments); - } - - var parts = []; - form - .on('error', callback) - .on('fileBegin', function(name, value) { - parts.push({type: 'file', name: name, value: value}); - }) - .on('field', function(name, value) { - parts.push({type: 'field', name: name, value: value}); - }) - .on('end', function() { - res.end('OK'); - callback(null, parts); - }); - }); - - var socket = net.createConnection(common.port); - var file = fs.createReadStream(common.dir.fixture + '/http/' + name); - - file.pipe(socket, {end: false}); - socket.on('data', function () { - socket.end(); - }); - -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-json.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-json.js deleted file mode 100644 index 28e758e540f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-json.js +++ /dev/null @@ -1,38 +0,0 @@ -var common = require('../common'); -var formidable = common.formidable; -var http = require('http'); -var assert = require('assert'); - -var testData = { - numbers: [1, 2, 3, 4, 5], - nested: { key: 'value' } -}; - -var server = http.createServer(function(req, res) { - var form = new formidable.IncomingForm(); - - form.parse(req, function(err, fields, files) { - assert.deepEqual(fields, testData); - - res.end(); - server.close(); - }); -}); - -var port = common.port; - -server.listen(port, function(err){ - assert.equal(err, null); - - var request = http.request({ - port: port, - method: 'POST', - headers: { - 'Content-Type': 'application/json' - } - }); - - request.write(JSON.stringify(testData)); - request.end(); -}); - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-octet-stream.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-octet-stream.js deleted file mode 100644 index 643d2c6f84f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-octet-stream.js +++ /dev/null @@ -1,45 +0,0 @@ -var common = require('../common'); -var formidable = common.formidable; -var http = require('http'); -var fs = require('fs'); -var path = require('path'); -var hashish = require('hashish'); -var assert = require('assert'); - -var testFilePath = path.join(__dirname, '../fixture/file/binaryfile.tar.gz'); - -var server = http.createServer(function(req, res) { - var form = new formidable.IncomingForm(); - - form.parse(req, function(err, fields, files) { - assert.equal(hashish(files).length, 1); - var file = files.file; - - assert.equal(file.size, 301); - - var uploaded = fs.readFileSync(file.path); - var original = fs.readFileSync(testFilePath); - - assert.deepEqual(uploaded, original); - - res.end(); - server.close(); - }); -}); - -var port = common.port; - -server.listen(port, function(err){ - assert.equal(err, null); - - var request = http.request({ - port: port, - method: 'POST', - headers: { - 'Content-Type': 'application/octet-stream' - } - }); - - fs.createReadStream(testFilePath).pipe(request); -}); - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js deleted file mode 100644 index 2b985981dc8..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js +++ /dev/null @@ -1,24 +0,0 @@ -var path = require('path'), - fs = require('fs'); - -try { - global.Gently = require('gently'); -} catch (e) { - throw new Error('this test suite requires node-gently'); -} - -exports.lib = path.join(__dirname, '../../lib'); - -global.GENTLY = new Gently(); - -global.assert = require('assert'); -global.TEST_PORT = 13532; -global.TEST_FIXTURES = path.join(__dirname, '../fixture'); -global.TEST_TMP = path.join(__dirname, '../tmp'); - -// Stupid new feature in node that complains about gently attaching too many -// listeners to process 'exit'. This is a workaround until I can think of a -// better way to deal with this. -if (process.setMaxListeners) { - process.setMaxListeners(10000); -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js deleted file mode 100644 index 75232aa43b7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js +++ /dev/null @@ -1,80 +0,0 @@ -var common = require('../common'); -var CHUNK_LENGTH = 10, - multipartParser = require(common.lib + '/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - parser = new MultipartParser(), - fixtures = require(TEST_FIXTURES + '/multipart'), - Buffer = require('buffer').Buffer; - -Object.keys(fixtures).forEach(function(name) { - var fixture = fixtures[name], - buffer = new Buffer(Buffer.byteLength(fixture.raw, 'binary')), - offset = 0, - chunk, - nparsed, - - parts = [], - part = null, - headerField, - headerValue, - endCalled = ''; - - parser.initWithBoundary(fixture.boundary); - parser.onPartBegin = function() { - part = {headers: {}, data: ''}; - parts.push(part); - headerField = ''; - headerValue = ''; - }; - - parser.onHeaderField = function(b, start, end) { - headerField += b.toString('ascii', start, end); - }; - - parser.onHeaderValue = function(b, start, end) { - headerValue += b.toString('ascii', start, end); - } - - parser.onHeaderEnd = function() { - part.headers[headerField] = headerValue; - headerField = ''; - headerValue = ''; - }; - - parser.onPartData = function(b, start, end) { - var str = b.toString('ascii', start, end); - part.data += b.slice(start, end); - } - - parser.onEnd = function() { - endCalled = true; - } - - buffer.write(fixture.raw, 'binary', 0); - - while (offset < buffer.length) { - if (offset + CHUNK_LENGTH < buffer.length) { - chunk = buffer.slice(offset, offset+CHUNK_LENGTH); - } else { - chunk = buffer.slice(offset, buffer.length); - } - offset = offset + CHUNK_LENGTH; - - nparsed = parser.write(chunk); - if (nparsed != chunk.length) { - if (fixture.expectError) { - return; - } - puts('-- ERROR --'); - p(chunk.toString('ascii')); - throw new Error(chunk.length+' bytes written, but only '+nparsed+' bytes parsed!'); - } - } - - if (fixture.expectError) { - throw new Error('expected parse error did not happen'); - } - - assert.ok(endCalled); - assert.deepEqual(parts, fixture.parts); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js deleted file mode 100644 index 52ceedb425d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js +++ /dev/null @@ -1,104 +0,0 @@ -var common = require('../common'); -var WriteStreamStub = GENTLY.stub('fs', 'WriteStream'); - -var File = require(common.lib + '/file'), - EventEmitter = require('events').EventEmitter, - file, - gently; - -function test(test) { - gently = new Gently(); - file = new File(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.ok(file instanceof EventEmitter); - assert.strictEqual(file.size, 0); - assert.strictEqual(file.path, null); - assert.strictEqual(file.name, null); - assert.strictEqual(file.type, null); - assert.strictEqual(file.lastModifiedDate, null); - - assert.strictEqual(file._writeStream, null); - - (function testSetProperties() { - var file2 = new File({foo: 'bar'}); - assert.equal(file2.foo, 'bar'); - })(); -}); - -test(function open() { - var WRITE_STREAM; - file.path = '/foo'; - - gently.expect(WriteStreamStub, 'new', function (path) { - WRITE_STREAM = this; - assert.strictEqual(path, file.path); - }); - - file.open(); - assert.strictEqual(file._writeStream, WRITE_STREAM); -}); - -test(function write() { - var BUFFER = {length: 10}, - CB_STUB, - CB = function() { - CB_STUB.apply(this, arguments); - }; - - file._writeStream = {}; - - gently.expect(file._writeStream, 'write', function (buffer, cb) { - assert.strictEqual(buffer, BUFFER); - - gently.expect(file, 'emit', function (event, bytesWritten) { - assert.ok(file.lastModifiedDate instanceof Date); - assert.equal(event, 'progress'); - assert.equal(bytesWritten, file.size); - }); - - CB_STUB = gently.expect(function writeCb() { - assert.equal(file.size, 10); - }); - - cb(); - - gently.expect(file, 'emit', function (event, bytesWritten) { - assert.equal(event, 'progress'); - assert.equal(bytesWritten, file.size); - }); - - CB_STUB = gently.expect(function writeCb() { - assert.equal(file.size, 20); - }); - - cb(); - }); - - file.write(BUFFER, CB); -}); - -test(function end() { - var CB_STUB, - CB = function() { - CB_STUB.apply(this, arguments); - }; - - file._writeStream = {}; - - gently.expect(file._writeStream, 'end', function (cb) { - gently.expect(file, 'emit', function (event) { - assert.equal(event, 'end'); - }); - - CB_STUB = gently.expect(function endCb() { - }); - - cb(); - }); - - file.end(CB); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js deleted file mode 100644 index 25bd887f7a4..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +++ /dev/null @@ -1,756 +0,0 @@ -var common = require('../common'); -var MultipartParserStub = GENTLY.stub('./multipart_parser', 'MultipartParser'), - QuerystringParserStub = GENTLY.stub('./querystring_parser', 'QuerystringParser'), - EventEmitterStub = GENTLY.stub('events', 'EventEmitter'), - StreamStub = GENTLY.stub('stream', 'Stream'), - FileStub = GENTLY.stub('./file'); - -var formidable = require(common.lib + '/index'), - IncomingForm = formidable.IncomingForm, - events = require('events'), - fs = require('fs'), - path = require('path'), - Buffer = require('buffer').Buffer, - fixtures = require(TEST_FIXTURES + '/multipart'), - form, - gently; - -function test(test) { - gently = new Gently(); - gently.expect(EventEmitterStub, 'call'); - form = new IncomingForm(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.strictEqual(form.error, null); - assert.strictEqual(form.ended, false); - assert.strictEqual(form.type, null); - assert.strictEqual(form.headers, null); - assert.strictEqual(form.keepExtensions, false); - // Can't assume dir === '/tmp' for portability - // assert.strictEqual(form.uploadDir, '/tmp'); - // Make sure it is a directory instead - assert.doesNotThrow(function () { - assert(fs.statSync(form.uploadDir).isDirectory()); - }); - assert.strictEqual(form.encoding, 'utf-8'); - assert.strictEqual(form.bytesReceived, null); - assert.strictEqual(form.bytesExpected, null); - assert.strictEqual(form.maxFieldsSize, 2 * 1024 * 1024); - assert.strictEqual(form._parser, null); - assert.strictEqual(form._flushing, 0); - assert.strictEqual(form._fieldsSize, 0); - assert.ok(form instanceof EventEmitterStub); - assert.equal(form.constructor.name, 'IncomingForm'); - - (function testSimpleConstructor() { - gently.expect(EventEmitterStub, 'call'); - var form = IncomingForm(); - assert.ok(form instanceof IncomingForm); - })(); - - (function testSimpleConstructorShortcut() { - gently.expect(EventEmitterStub, 'call'); - var form = formidable(); - assert.ok(form instanceof IncomingForm); - })(); -}); - -test(function parse() { - var REQ = {headers: {}} - , emit = {}; - - gently.expect(form, 'writeHeaders', function(headers) { - assert.strictEqual(headers, REQ.headers); - }); - - var EVENTS = ['error', 'aborted', 'data', 'end']; - gently.expect(REQ, 'on', EVENTS.length, function(event, fn) { - assert.equal(event, EVENTS.shift()); - emit[event] = fn; - return this; - }); - - form.parse(REQ); - - (function testPause() { - gently.expect(REQ, 'pause'); - assert.strictEqual(form.pause(), true); - })(); - - (function testPauseCriticalException() { - form.ended = false; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'pause', function() { - throw ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - assert.strictEqual(form.pause(), false); - })(); - - (function testPauseHarmlessException() { - form.ended = true; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'pause', function() { - throw ERR; - }); - - assert.strictEqual(form.pause(), false); - })(); - - (function testResume() { - gently.expect(REQ, 'resume'); - assert.strictEqual(form.resume(), true); - })(); - - (function testResumeCriticalException() { - form.ended = false; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'resume', function() { - throw ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - assert.strictEqual(form.resume(), false); - })(); - - (function testResumeHarmlessException() { - form.ended = true; - - var ERR = new Error('dasdsa'); - gently.expect(REQ, 'resume', function() { - throw ERR; - }); - - assert.strictEqual(form.resume(), false); - })(); - - (function testEmitError() { - var ERR = new Error('something bad happened'); - gently.expect(form, '_error',function(err) { - assert.strictEqual(err, ERR); - }); - emit.error(ERR); - })(); - - (function testEmitAborted() { - gently.expect(form, 'emit',function(event) { - assert.equal(event, 'aborted'); - }); - gently.expect(form, '_error'); - - emit.aborted(); - })(); - - - (function testEmitData() { - var BUFFER = [1, 2, 3]; - gently.expect(form, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - }); - emit.data(BUFFER); - })(); - - (function testEmitEnd() { - form._parser = {}; - - (function testWithError() { - var ERR = new Error('haha'); - gently.expect(form._parser, 'end', function() { - return ERR; - }); - - gently.expect(form, '_error', function(err) { - assert.strictEqual(err, ERR); - }); - - emit.end(); - })(); - - (function testWithoutError() { - gently.expect(form._parser, 'end'); - emit.end(); - })(); - - (function testAfterError() { - form.error = true; - emit.end(); - })(); - })(); - - (function testWithCallback() { - gently.expect(EventEmitterStub, 'call'); - var form = new IncomingForm(), - REQ = {headers: {}}, - parseCalled = 0; - - gently.expect(form, 'on', 4, function(event, fn) { - if (event == 'field') { - fn('field1', 'foo'); - fn('field1', 'bar'); - fn('field2', 'nice'); - } - - if (event == 'file') { - fn('file1', '1'); - fn('file1', '2'); - fn('file2', '3'); - } - - if (event == 'end') { - fn(); - } - return this; - }); - - gently.expect(form, 'writeHeaders'); - - gently.expect(REQ, 'on', 4, function() { - return this; - }); - - var parseCbOk = function (err, fields, files) { - assert.deepEqual(fields, {field1: 'bar', field2: 'nice'}); - assert.deepEqual(files, {file1: '2', file2: '3'}); - }; - form.parse(REQ, parseCbOk); - - var ERR = new Error('test'); - gently.expect(form, 'on', 3, function(event, fn) { - if (event == 'field') { - fn('foo', 'bar'); - } - - if (event == 'error') { - fn(ERR); - gently.expect(form, 'on'); - gently.expect(form, 'writeHeaders'); - gently.expect(REQ, 'on', 4, function() { - return this; - }); - } - return this; - }); - - form.parse(REQ, function parseCbErr(err, fields, files) { - assert.strictEqual(err, ERR); - assert.deepEqual(fields, {foo: 'bar'}); - }); - })(); - - (function testWriteOrder() { - gently.expect(EventEmitterStub, 'call'); - var form = new IncomingForm(); - var REQ = new events.EventEmitter(); - var BUF = {}; - var DATACB = null; - - REQ.on('newListener', function(event, fn) { - if ('data' === event) fn(BUF); - }); - - gently.expect(form, 'writeHeaders'); - gently.expect(form, 'write', function(buf) { - assert.strictEqual(buf, BUF); - }); - - form.parse(REQ); - })(); -}); - -test(function pause() { - assert.strictEqual(form.pause(), false); -}); - -test(function resume() { - assert.strictEqual(form.resume(), false); -}); - - -test(function writeHeaders() { - var HEADERS = {}; - gently.expect(form, '_parseContentLength'); - gently.expect(form, '_parseContentType'); - - form.writeHeaders(HEADERS); - assert.strictEqual(form.headers, HEADERS); -}); - -test(function write() { - var parser = {}, - BUFFER = [1, 2, 3]; - - form._parser = parser; - form.bytesExpected = 523423; - - (function testBasic() { - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, BUFFER.length); - assert.equal(bytesExpected, form.bytesExpected); - }); - - gently.expect(parser, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - return buffer.length; - }); - - assert.equal(form.write(BUFFER), BUFFER.length); - assert.equal(form.bytesReceived, BUFFER.length); - })(); - - (function testParserError() { - gently.expect(form, 'emit'); - - gently.expect(parser, 'write', function(buffer) { - assert.strictEqual(buffer, BUFFER); - return buffer.length - 1; - }); - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/parser error/i)); - }); - - assert.equal(form.write(BUFFER), BUFFER.length - 1); - assert.equal(form.bytesReceived, BUFFER.length + BUFFER.length); - })(); - - (function testUninitialized() { - delete form._parser; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/unintialized parser/i)); - }); - form.write(BUFFER); - })(); -}); - -test(function parseContentType() { - var HEADERS = {}; - - form.headers = {'content-type': 'application/x-www-form-urlencoded'}; - gently.expect(form, '_initUrlencoded'); - form._parseContentType(); - - // accept anything that has 'urlencoded' in it - form.headers = {'content-type': 'broken-client/urlencoded-stupid'}; - gently.expect(form, '_initUrlencoded'); - form._parseContentType(); - - var BOUNDARY = '---------------------------57814261102167618332366269'; - form.headers = {'content-type': 'multipart/form-data; boundary='+BOUNDARY}; - - gently.expect(form, '_initMultipart', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - form._parseContentType(); - - (function testQuotedBoundary() { - form.headers = {'content-type': 'multipart/form-data; boundary="' + BOUNDARY + '"'}; - - gently.expect(form, '_initMultipart', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - form._parseContentType(); - })(); - - (function testNoBoundary() { - form.headers = {'content-type': 'multipart/form-data'}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/no multipart boundary/i)); - }); - form._parseContentType(); - })(); - - (function testNoContentType() { - form.headers = {}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/no content-type/i)); - }); - form._parseContentType(); - })(); - - (function testUnknownContentType() { - form.headers = {'content-type': 'invalid'}; - - gently.expect(form, '_error', function(err) { - assert.ok(err.message.match(/unknown content-type/i)); - }); - form._parseContentType(); - })(); -}); - -test(function parseContentLength() { - var HEADERS = {}; - - form.headers = {}; - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, 0); - assert.equal(bytesExpected, 0); - }); - form._parseContentLength(); - - form.headers['content-length'] = '8'; - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, 0); - assert.equal(bytesExpected, 8); - }); - form._parseContentLength(); - assert.strictEqual(form.bytesReceived, 0); - assert.strictEqual(form.bytesExpected, 8); - - // JS can be evil, lets make sure we are not - form.headers['content-length'] = '08'; - gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) { - assert.equal(event, 'progress'); - assert.equal(bytesReceived, 0); - assert.equal(bytesExpected, 8); - }); - form._parseContentLength(); - assert.strictEqual(form.bytesExpected, 8); -}); - -test(function _initMultipart() { - var BOUNDARY = '123', - PARSER; - - gently.expect(MultipartParserStub, 'new', function() { - PARSER = this; - }); - - gently.expect(MultipartParserStub.prototype, 'initWithBoundary', function(boundary) { - assert.equal(boundary, BOUNDARY); - }); - - form._initMultipart(BOUNDARY); - assert.equal(form.type, 'multipart'); - assert.strictEqual(form._parser, PARSER); - - (function testRegularField() { - var PART; - gently.expect(StreamStub, 'new', function() { - PART = this; - }); - - gently.expect(form, 'onPart', function(part) { - assert.strictEqual(part, PART); - assert.deepEqual - ( part.headers - , { 'content-disposition': 'form-data; name="field1"' - , 'foo': 'bar' - } - ); - assert.equal(part.name, 'field1'); - - var strings = ['hello', ' world']; - gently.expect(part, 'emit', 2, function(event, b) { - assert.equal(event, 'data'); - assert.equal(b.toString(), strings.shift()); - }); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'end'); - }); - }); - - PARSER.onPartBegin(); - PARSER.onHeaderField(new Buffer('content-disposition'), 0, 10); - PARSER.onHeaderField(new Buffer('content-disposition'), 10, 19); - PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 0, 14); - PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 14, 24); - PARSER.onHeaderEnd(); - PARSER.onHeaderField(new Buffer('foo'), 0, 3); - PARSER.onHeaderValue(new Buffer('bar'), 0, 3); - PARSER.onHeaderEnd(); - PARSER.onHeadersEnd(); - PARSER.onPartData(new Buffer('hello world'), 0, 5); - PARSER.onPartData(new Buffer('hello world'), 5, 11); - PARSER.onPartEnd(); - })(); - - (function testFileField() { - var PART; - gently.expect(StreamStub, 'new', function() { - PART = this; - }); - - gently.expect(form, 'onPart', function(part) { - assert.deepEqual - ( part.headers - , { 'content-disposition': 'form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"' - , 'content-type': 'text/plain' - } - ); - assert.equal(part.name, 'field2'); - assert.equal(part.filename, 'Sun"et.jpg'); - assert.equal(part.mime, 'text/plain'); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'data'); - assert.equal(b.toString(), '... contents of file1.txt ...'); - }); - - gently.expect(part, 'emit', function(event, b) { - assert.equal(event, 'end'); - }); - }); - - PARSER.onPartBegin(); - PARSER.onHeaderField(new Buffer('content-disposition'), 0, 19); - PARSER.onHeaderValue(new Buffer('form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'), 0, 85); - PARSER.onHeaderEnd(); - PARSER.onHeaderField(new Buffer('Content-Type'), 0, 12); - PARSER.onHeaderValue(new Buffer('text/plain'), 0, 10); - PARSER.onHeaderEnd(); - PARSER.onHeadersEnd(); - PARSER.onPartData(new Buffer('... contents of file1.txt ...'), 0, 29); - PARSER.onPartEnd(); - })(); - - (function testEnd() { - gently.expect(form, '_maybeEnd'); - PARSER.onEnd(); - assert.ok(form.ended); - })(); -}); - -test(function _fileName() { - // TODO - return; -}); - -test(function _initUrlencoded() { - var PARSER; - - gently.expect(QuerystringParserStub, 'new', function() { - PARSER = this; - }); - - form._initUrlencoded(); - assert.equal(form.type, 'urlencoded'); - assert.strictEqual(form._parser, PARSER); - - (function testOnField() { - var KEY = 'KEY', VAL = 'VAL'; - gently.expect(form, 'emit', function(field, key, val) { - assert.equal(field, 'field'); - assert.equal(key, KEY); - assert.equal(val, VAL); - }); - - PARSER.onField(KEY, VAL); - })(); - - (function testOnEnd() { - gently.expect(form, '_maybeEnd'); - - PARSER.onEnd(); - assert.equal(form.ended, true); - })(); -}); - -test(function _error() { - var ERR = new Error('bla'); - - gently.expect(form, 'pause'); - gently.expect(form, 'emit', function(event, err) { - assert.equal(event, 'error'); - assert.strictEqual(err, ERR); - }); - - form._error(ERR); - assert.strictEqual(form.error, ERR); - - // make sure _error only does its thing once - form._error(ERR); -}); - -test(function onPart() { - var PART = {}; - gently.expect(form, 'handlePart', function(part) { - assert.strictEqual(part, PART); - }); - - form.onPart(PART); -}); - -test(function handlePart() { - (function testUtf8Field() { - var PART = new events.EventEmitter(); - PART.name = 'my_field'; - - gently.expect(form, 'emit', function(event, field, value) { - assert.equal(event, 'field'); - assert.equal(field, 'my_field'); - assert.equal(value, 'hello world: €'); - }); - - form.handlePart(PART); - PART.emit('data', new Buffer('hello')); - PART.emit('data', new Buffer(' world: ')); - PART.emit('data', new Buffer([0xE2])); - PART.emit('data', new Buffer([0x82, 0xAC])); - PART.emit('end'); - })(); - - (function testBinaryField() { - var PART = new events.EventEmitter(); - PART.name = 'my_field2'; - - gently.expect(form, 'emit', function(event, field, value) { - assert.equal(event, 'field'); - assert.equal(field, 'my_field2'); - assert.equal(value, 'hello world: '+new Buffer([0xE2, 0x82, 0xAC]).toString('binary')); - }); - - form.encoding = 'binary'; - form.handlePart(PART); - PART.emit('data', new Buffer('hello')); - PART.emit('data', new Buffer(' world: ')); - PART.emit('data', new Buffer([0xE2])); - PART.emit('data', new Buffer([0x82, 0xAC])); - PART.emit('end'); - })(); - - (function testFieldSize() { - form.maxFieldsSize = 8; - var PART = new events.EventEmitter(); - PART.name = 'my_field'; - - gently.expect(form, '_error', function(err) { - assert.equal(err.message, 'maxFieldsSize exceeded, received 9 bytes of field data'); - }); - - form.handlePart(PART); - form._fieldsSize = 1; - PART.emit('data', new Buffer(7)); - PART.emit('data', new Buffer(1)); - })(); - - (function testFilePart() { - var PART = new events.EventEmitter(), - FILE = new events.EventEmitter(), - PATH = '/foo/bar'; - - PART.name = 'my_file'; - PART.filename = 'sweet.txt'; - PART.mime = 'sweet.txt'; - - gently.expect(form, '_uploadPath', function(filename) { - assert.equal(filename, PART.filename); - return PATH; - }); - - gently.expect(FileStub, 'new', function(properties) { - assert.equal(properties.path, PATH); - assert.equal(properties.name, PART.filename); - assert.equal(properties.type, PART.mime); - FILE = this; - - gently.expect(form, 'emit', function (event, field, file) { - assert.equal(event, 'fileBegin'); - assert.strictEqual(field, PART.name); - assert.strictEqual(file, FILE); - }); - - gently.expect(FILE, 'open'); - }); - - form.handlePart(PART); - assert.equal(form._flushing, 1); - - var BUFFER; - gently.expect(form, 'pause'); - gently.expect(FILE, 'write', function(buffer, cb) { - assert.strictEqual(buffer, BUFFER); - gently.expect(form, 'resume'); - // @todo handle cb(new Err) - cb(); - }); - - PART.emit('data', BUFFER = new Buffer('test')); - - gently.expect(FILE, 'end', function(cb) { - gently.expect(form, 'emit', function(event, field, file) { - assert.equal(event, 'file'); - assert.strictEqual(file, FILE); - }); - - gently.expect(form, '_maybeEnd'); - - cb(); - assert.equal(form._flushing, 0); - }); - - PART.emit('end'); - })(); -}); - -test(function _uploadPath() { - (function testUniqueId() { - var UUID_A, UUID_B; - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { - assert.equal(uploadDir, form.uploadDir); - UUID_A = uuid; - }); - form._uploadPath(); - - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) { - UUID_B = uuid; - }); - form._uploadPath(); - - assert.notEqual(UUID_A, UUID_B); - })(); - - (function testFileExtension() { - form.keepExtensions = true; - var FILENAME = 'foo.jpg', - EXT = '.bar'; - - gently.expect(GENTLY.hijacked.path, 'extname', function(filename) { - assert.equal(filename, FILENAME); - gently.restore(path, 'extname'); - - return EXT; - }); - - gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) { - assert.equal(path.extname(name), EXT); - }); - form._uploadPath(FILENAME); - })(); -}); - -test(function _maybeEnd() { - gently.expect(form, 'emit', 0); - form._maybeEnd(); - - form.ended = true; - form._flushing = 1; - form._maybeEnd(); - - gently.expect(form, 'emit', function(event) { - assert.equal(event, 'end'); - }); - - form.ended = true; - form._flushing = 0; - form._maybeEnd(); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js deleted file mode 100644 index bf2cd5e13f4..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js +++ /dev/null @@ -1,50 +0,0 @@ -var common = require('../common'); -var multipartParser = require(common.lib + '/multipart_parser'), - MultipartParser = multipartParser.MultipartParser, - events = require('events'), - Buffer = require('buffer').Buffer, - parser; - -function test(test) { - parser = new MultipartParser(); - test(); -} - -test(function constructor() { - assert.equal(parser.boundary, null); - assert.equal(parser.state, 0); - assert.equal(parser.flags, 0); - assert.equal(parser.boundaryChars, null); - assert.equal(parser.index, null); - assert.equal(parser.lookbehind, null); - assert.equal(parser.constructor.name, 'MultipartParser'); -}); - -test(function initWithBoundary() { - var boundary = 'abc'; - parser.initWithBoundary(boundary); - assert.deepEqual(Array.prototype.slice.call(parser.boundary), [13, 10, 45, 45, 97, 98, 99]); - assert.equal(parser.state, multipartParser.START); - - assert.deepEqual(parser.boundaryChars, {10: true, 13: true, 45: true, 97: true, 98: true, 99: true}); -}); - -test(function parserError() { - var boundary = 'abc', - buffer = new Buffer(5); - - parser.initWithBoundary(boundary); - buffer.write('--ad', 'ascii', 0); - assert.equal(parser.write(buffer), 5); -}); - -test(function end() { - (function testError() { - assert.equal(parser.end().message, 'MultipartParser.end(): stream ended unexpectedly: ' + parser.explain()); - })(); - - (function testRegular() { - parser.state = multipartParser.END; - assert.strictEqual(parser.end(), undefined); - })(); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js deleted file mode 100644 index 54d3e2d55d9..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js +++ /dev/null @@ -1,45 +0,0 @@ -var common = require('../common'); -var QuerystringParser = require(common.lib + '/querystring_parser').QuerystringParser, - Buffer = require('buffer').Buffer, - gently, - parser; - -function test(test) { - gently = new Gently(); - parser = new QuerystringParser(); - test(); - gently.verify(test.name); -} - -test(function constructor() { - assert.equal(parser.buffer, ''); - assert.equal(parser.constructor.name, 'QuerystringParser'); -}); - -test(function write() { - var a = new Buffer('a=1'); - assert.equal(parser.write(a), a.length); - - var b = new Buffer('&b=2'); - parser.write(b); - assert.equal(parser.buffer, a + b); -}); - -test(function end() { - var FIELDS = {a: ['b', {c: 'd'}], e: 'f'}; - - gently.expect(GENTLY.hijacked.querystring, 'parse', function(str) { - assert.equal(str, parser.buffer); - return FIELDS; - }); - - gently.expect(parser, 'onField', Object.keys(FIELDS).length, function(key, val) { - assert.deepEqual(FIELDS[key], val); - }); - - gently.expect(parser, 'onEnd'); - - parser.buffer = 'my buffer'; - parser.end(); - assert.equal(parser.buffer, ''); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js deleted file mode 100644 index b35ffd682c3..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js +++ /dev/null @@ -1,71 +0,0 @@ -var common = require('../common'); -var BOUNDARY = '---------------------------10102754414578508781458777923', - FIXTURE = TEST_FIXTURES+'/multi_video.upload', - fs = require('fs'), - http = require('http'), - formidable = require(common.lib + '/index'), - server = http.createServer(); - -server.on('request', function(req, res) { - var form = new formidable.IncomingForm(), - uploads = {}; - - form.uploadDir = TEST_TMP; - form.hash = 'sha1'; - form.parse(req); - - form - .on('fileBegin', function(field, file) { - assert.equal(field, 'upload'); - - var tracker = {file: file, progress: [], ended: false}; - uploads[file.name] = tracker; - file - .on('progress', function(bytesReceived) { - tracker.progress.push(bytesReceived); - assert.equal(bytesReceived, file.size); - }) - .on('end', function() { - tracker.ended = true; - }); - }) - .on('field', function(field, value) { - assert.equal(field, 'title'); - assert.equal(value, ''); - }) - .on('file', function(field, file) { - assert.equal(field, 'upload'); - assert.strictEqual(uploads[file.name].file, file); - }) - .on('end', function() { - assert.ok(uploads['shortest_video.flv']); - assert.ok(uploads['shortest_video.flv'].ended); - assert.ok(uploads['shortest_video.flv'].progress.length > 3); - assert.equal(uploads['shortest_video.flv'].file.hash, 'd6a17616c7143d1b1438ceeef6836d1a09186b3a'); - assert.equal(uploads['shortest_video.flv'].progress.slice(-1), uploads['shortest_video.flv'].file.size); - assert.ok(uploads['shortest_video.mp4']); - assert.ok(uploads['shortest_video.mp4'].ended); - assert.ok(uploads['shortest_video.mp4'].progress.length > 3); - assert.equal(uploads['shortest_video.mp4'].file.hash, '937dfd4db263f4887ceae19341dcc8d63bcd557f'); - - server.close(); - res.writeHead(200); - res.end('good'); - }); -}); - -server.listen(TEST_PORT, function() { - var stat, headers, request, fixture; - - stat = fs.statSync(FIXTURE); - request = http.request({ - port: TEST_PORT, - path: '/', - method: 'POST', - headers: { - 'content-type': 'multipart/form-data; boundary='+BOUNDARY, - 'content-length': stat.size, - }, - }); - fs.createReadStream(FIXTURE).pipe(request); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js deleted file mode 100644 index 02d6d5c1358..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js +++ /dev/null @@ -1 +0,0 @@ -require('urun')(__dirname) diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-connection-aborted.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-connection-aborted.js deleted file mode 100644 index 4ea4431ab82..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-connection-aborted.js +++ /dev/null @@ -1,27 +0,0 @@ -var assert = require('assert'); -var http = require('http'); -var net = require('net'); -var formidable = require('../../lib/index'); - -var server = http.createServer(function (req, res) { - var form = new formidable.IncomingForm(); - var aborted_received = false; - form.on('aborted', function () { - aborted_received = true; - }); - form.on('error', function () { - assert(aborted_received, 'Error event should follow aborted'); - server.close(); - }); - form.on('end', function () { - throw new Error('Unexpected "end" event'); - }); - form.parse(req); -}).listen(0, 'localhost', function () { - var client = net.connect(server.address().port); - client.write( - "POST / HTTP/1.1\r\n" + - "Content-Length: 70\r\n" + - "Content-Type: multipart/form-data; boundary=foo\r\n\r\n"); - client.end(); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-content-transfer-encoding.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-content-transfer-encoding.js deleted file mode 100644 index 165628abdce..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-content-transfer-encoding.js +++ /dev/null @@ -1,48 +0,0 @@ -var assert = require('assert'); -var common = require('../common'); -var formidable = require('../../lib/index'); -var http = require('http'); - -var server = http.createServer(function(req, res) { - var form = new formidable.IncomingForm(); - form.uploadDir = common.dir.tmp; - form.on('end', function () { - throw new Error('Unexpected "end" event'); - }); - form.on('error', function (e) { - res.writeHead(500); - res.end(e.message); - }); - form.parse(req); -}); - -server.listen(0, function() { - var body = - '--foo\r\n' + - 'Content-Disposition: form-data; name="file1"; filename="file1"\r\n' + - 'Content-Type: application/octet-stream\r\n' + - '\r\nThis is the first file\r\n' + - '--foo\r\n' + - 'Content-Type: application/octet-stream\r\n' + - 'Content-Disposition: form-data; name="file2"; filename="file2"\r\n' + - 'Content-Transfer-Encoding: unknown\r\n' + - '\r\nThis is the second file\r\n' + - '--foo--\r\n'; - - var req = http.request({ - method: 'POST', - port: server.address().port, - headers: { - 'Content-Length': body.length, - 'Content-Type': 'multipart/form-data; boundary=foo' - } - }); - req.on('response', function (res) { - assert.equal(res.statusCode, 500); - res.on('data', function () {}); - res.on('end', function () { - server.close(); - }); - }); - req.end(body); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-issue-46.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-issue-46.js deleted file mode 100644 index 19393287890..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-issue-46.js +++ /dev/null @@ -1,49 +0,0 @@ -var http = require('http'), - formidable = require('../../lib/index'), - request = require('request'), - assert = require('assert'); - -var host = 'localhost'; - -var index = [ - '
    ', - ' ', - ' ', - '
    ' -].join("\n"); - -var server = http.createServer(function(req, res) { - - // Show a form for testing purposes. - if (req.method == 'GET') { - res.writeHead(200, {'content-type': 'text/html'}); - res.end(index); - return; - } - - // Parse form and write results to response. - var form = new formidable.IncomingForm(); - form.parse(req, function(err, fields, files) { - res.writeHead(200, {'content-type': 'text/plain'}); - res.write(JSON.stringify({err: err, fields: fields, files: files})); - res.end(); - }); - -}).listen(0, host, function() { - - console.log("Server up and running..."); - - var server = this, - url = 'http://' + host + ':' + server.address().port; - - var parts = [ - {'Content-Disposition': 'form-data; name="foo"', 'body': 'bar'} - ] - - var req = request({method: 'POST', url: url, multipart: parts}, function(e, res, body) { - var obj = JSON.parse(body); - assert.equal("bar", obj.fields.foo); - server.close(); - }); - -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/tools/base64.html b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/tools/base64.html deleted file mode 100644 index 48ad92e0f67..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/tools/base64.html +++ /dev/null @@ -1,67 +0,0 @@ - - - Convert a file to a base64 request - - - - - - - -
    -
    -
    -
    -
    -
    -

    -Don't forget to save the output with windows (CRLF) line endings! -

    - - - diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-file.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-file.js deleted file mode 100644 index fc8f36e5040..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-file.js +++ /dev/null @@ -1,33 +0,0 @@ -var common = require('../common'); -var test = require('utest'); -var assert = common.assert; -var File = common.require('file'); - -var file; -var now = new Date; -test('IncomingForm', { - before: function() { - file = new File({ - size: 1024, - path: '/tmp/cat.png', - name: 'cat.png', - type: 'image/png', - lastModifiedDate: now, - filename: 'cat.png', - mime: 'image/png' - }) - }, - - '#toJSON()': function() { - var obj = file.toJSON(); - var len = Object.keys(obj).length; - assert.equal(1024, obj.size); - assert.equal('/tmp/cat.png', obj.path); - assert.equal('cat.png', obj.name); - assert.equal('image/png', obj.type); - assert.equal('image/png', obj.mime); - assert.equal('cat.png', obj.filename); - assert.equal(now, obj.mtime); - assert.equal(len, 8); - } -}); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js deleted file mode 100644 index fe2ac1c6cd4..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js +++ /dev/null @@ -1,63 +0,0 @@ -var common = require('../common'); -var test = require('utest'); -var assert = common.assert; -var IncomingForm = common.require('incoming_form').IncomingForm; -var path = require('path'); - -var form; -test('IncomingForm', { - before: function() { - form = new IncomingForm(); - }, - - '#_fileName with regular characters': function() { - var filename = 'foo.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'foo.txt'); - }, - - '#_fileName with unescaped quote': function() { - var filename = 'my".txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); - }, - - '#_fileName with escaped quote': function() { - var filename = 'my%22.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my".txt'); - }, - - '#_fileName with bad quote and additional sub-header': function() { - var filename = 'my".txt'; - var header = makeHeader(filename) + '; foo="bar"'; - assert.equal(form._fileName(header), filename); - }, - - '#_fileName with semicolon': function() { - var filename = 'my;.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my;.txt'); - }, - - '#_fileName with utf8 character': function() { - var filename = 'my☃.txt'; - assert.equal(form._fileName(makeHeader(filename)), 'my☃.txt'); - }, - - '#_uploadPath strips harmful characters from extension when keepExtensions': function() { - form.keepExtensions = true; - - var ext = path.extname(form._uploadPath('fine.jpg?foo=bar')); - assert.equal(ext, '.jpg'); - - var ext = path.extname(form._uploadPath('fine?foo=bar')); - assert.equal(ext, ''); - - var ext = path.extname(form._uploadPath('super.cr2+dsad')); - assert.equal(ext, '.cr2'); - - var ext = path.extname(form._uploadPath('super.bar')); - assert.equal(ext, '.bar'); - }, -}); - -function makeHeader(filename) { - return 'Content-Disposition: form-data; name="upload"; filename="' + filename + '"'; -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js deleted file mode 100644 index 9f1cef86fad..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js +++ /dev/null @@ -1,47 +0,0 @@ -var http = require('http'); -var fs = require('fs'); -var connections = 0; - -var server = http.createServer(function(req, res) { - var socket = req.socket; - console.log('Request: %s %s -> %s', req.method, req.url, socket.filename); - - req.on('end', function() { - if (req.url !== '/') { - res.end(JSON.stringify({ - method: req.method, - url: req.url, - filename: socket.filename, - })); - return; - } - - res.writeHead(200, {'content-type': 'text/html'}); - res.end( - '
    '+ - '
    '+ - '
    '+ - ''+ - '
    ' - ); - }); -}); - -server.on('connection', function(socket) { - connections++; - - socket.id = connections; - socket.filename = 'connection-' + socket.id + '.http'; - socket.file = fs.createWriteStream(socket.filename); - socket.pipe(socket.file); - - console.log('--> %s', socket.filename); - socket.on('close', function() { - console.log('<-- %s', socket.filename); - }); -}); - -var port = process.env.PORT || 8080; -server.listen(port, function() { - console.log('Recording connections on port %s', port); -}); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/History.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/History.md deleted file mode 100644 index c8aa68fa881..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/History.md +++ /dev/null @@ -1,5 +0,0 @@ - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Makefile b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Makefile deleted file mode 100644 index 4e9c8d36ebc..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Readme.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Readme.md deleted file mode 100644 index 1cdd68a2a83..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/Readme.md +++ /dev/null @@ -1,29 +0,0 @@ - -# pause - - Pause streams... - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/index.js deleted file mode 100644 index 1b7b37948c1..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/index.js +++ /dev/null @@ -1,29 +0,0 @@ - -module.exports = function(obj){ - var onData - , onEnd - , events = []; - - // buffer data - obj.on('data', onData = function(data, encoding){ - events.push(['data', data, encoding]); - }); - - // buffer end - obj.on('end', onEnd = function(data, encoding){ - events.push(['end', data, encoding]); - }); - - return { - end: function(){ - obj.removeListener('data', onData); - obj.removeListener('end', onEnd); - }, - resume: function(){ - this.end(); - for (var i = 0, len = events.length; i < len; ++i) { - obj.emit.apply(obj, events[i]); - } - } - }; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/package.json deleted file mode 100644 index 73cfe4009f7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/pause/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "pause", - "version": "0.0.1", - "description": "Pause streams...", - "keywords": [], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "main": "index", - "readme": "\n# pause\n\n Pause streams...\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "_id": "pause@0.0.1", - "_from": "pause@0.0.1" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules b/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules deleted file mode 100644 index 49e31dac7d7..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "support/expresso"] - path = support/expresso - url = git://github.com/visionmedia/expresso.git -[submodule "support/should"] - path = support/should - url = git://github.com/visionmedia/should.js.git diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.npmignore deleted file mode 100644 index e85ce2afa21..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -test -.travis.yml -benchmark.js -component.json -examples.js -History.md -Makefile diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/Readme.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/Readme.md deleted file mode 100644 index 27e54a4af18..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/Readme.md +++ /dev/null @@ -1,58 +0,0 @@ -# node-querystring - - query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. - -## Installation - - $ npm install qs - -## Examples - -```js -var qs = require('qs'); - -qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); -// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } - -qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) -// => user[name]=Tobi&user[email]=tobi%40learnboost.com -``` - -## Testing - -Install dev dependencies: - - $ npm install -d - -and execute: - - $ make test - -browser: - - $ open test/browser/index.html - -## License - -(The MIT License) - -Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/index.js deleted file mode 100644 index 590491e31ed..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/index.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * Object#toString() ref for stringify(). - */ - -var toString = Object.prototype.toString; - -/** - * Object#hasOwnProperty ref - */ - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Array#indexOf shim. - */ - -var indexOf = typeof Array.prototype.indexOf === 'function' - ? function(arr, el) { return arr.indexOf(el); } - : function(arr, el) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] === el) return i; - } - return -1; - }; - -/** - * Array.isArray shim. - */ - -var isArray = Array.isArray || function(arr) { - return toString.call(arr) == '[object Array]'; -}; - -/** - * Object.keys shim. - */ - -var objectKeys = Object.keys || function(obj) { - var ret = []; - for (var key in obj) ret.push(key); - return ret; -}; - -/** - * Array#forEach shim. - */ - -var forEach = typeof Array.prototype.forEach === 'function' - ? function(arr, fn) { return arr.forEach(fn); } - : function(arr, fn) { - for (var i = 0; i < arr.length; i++) fn(arr[i]); - }; - -/** - * Array#reduce shim. - */ - -var reduce = function(arr, fn, initial) { - if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); - var res = initial; - for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); - return res; -}; - -/** - * Create a nullary object if possible - */ - -function createObject() { - return Object.create - ? Object.create(null) - : {}; -} - -/** - * Cache non-integer test regexp. - */ - -var isint = /^[0-9]+$/; - -function promote(parent, key) { - if (parent[key].length == 0) return parent[key] = createObject(); - var t = createObject(); - for (var i in parent[key]) { - if (hasOwnProperty.call(parent[key], i)) { - t[i] = parent[key][i]; - } - } - parent[key] = t; - return t; -} - -function parse(parts, parent, key, val) { - var part = parts.shift(); - // end - if (!part) { - if (isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } - // array - } else { - var obj = parent[key] = parent[key] || []; - if (']' == part) { - if (isArray(obj)) { - if ('' != val) obj.push(val); - } else if ('object' == typeof obj) { - obj[objectKeys(obj).length] = val; - } else { - obj = parent[key] = [parent[key], val]; - } - // prop - } else if (~indexOf(part, ']')) { - part = part.substr(0, part.length - 1); - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - // key - } else { - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - } - } -} - -/** - * Merge parent key/val pair. - */ - -function merge(parent, key, val){ - if (~indexOf(key, ']')) { - var parts = key.split('[') - , len = parts.length - , last = len - 1; - parse(parts, parent, 'base', val); - // optimize - } else { - if (!isint.test(key) && isArray(parent.base)) { - var t = createObject(); - for (var k in parent.base) t[k] = parent.base[k]; - parent.base = t; - } - set(parent.base, key, val); - } - - return parent; -} - -/** - * Compact sparse arrays. - */ - -function compact(obj) { - if ('object' != typeof obj) return obj; - - if (isArray(obj)) { - var ret = []; - - for (var i in obj) { - if (hasOwnProperty.call(obj, i)) { - ret.push(obj[i]); - } - } - - return ret; - } - - for (var key in obj) { - obj[key] = compact(obj[key]); - } - - return obj; -} - -/** - * Restore Object.prototype. - * see pull-request #58 - */ - -function restoreProto(obj) { - if (!Object.create) return obj; - if (isArray(obj)) return obj; - if (obj && 'object' != typeof obj) return obj; - - for (var key in obj) { - if (hasOwnProperty.call(obj, key)) { - obj[key] = restoreProto(obj[key]); - } - } - - obj.__proto__ = Object.prototype; - return obj; -} - -/** - * Parse the given obj. - */ - -function parseObject(obj){ - var ret = { base: {} }; - - forEach(objectKeys(obj), function(name){ - merge(ret, name, obj[name]); - }); - - return compact(ret.base); -} - -/** - * Parse the given str. - */ - -function parseString(str){ - var ret = reduce(String(str).split('&'), function(ret, pair){ - var eql = indexOf(pair, '=') - , brace = lastBraceInKey(pair) - , key = pair.substr(0, brace || eql) - , val = pair.substr(brace || eql, pair.length) - , val = val.substr(indexOf(val, '=') + 1, val.length); - - // ?foo - if ('' == key) key = pair, val = ''; - if ('' == key) return ret; - - return merge(ret, decode(key), decode(val)); - }, { base: createObject() }).base; - - return restoreProto(compact(ret)); -} - -/** - * Parse the given query `str` or `obj`, returning an object. - * - * @param {String} str | {Object} obj - * @return {Object} - * @api public - */ - -exports.parse = function(str){ - if (null == str || '' == str) return {}; - return 'object' == typeof str - ? parseObject(str) - : parseString(str); -}; - -/** - * Turn the given `obj` into a query string - * - * @param {Object} obj - * @return {String} - * @api public - */ - -var stringify = exports.stringify = function(obj, prefix) { - if (isArray(obj)) { - return stringifyArray(obj, prefix); - } else if ('[object Object]' == toString.call(obj)) { - return stringifyObject(obj, prefix); - } else if ('string' == typeof obj) { - return stringifyString(obj, prefix); - } else { - return prefix + '=' + encodeURIComponent(String(obj)); - } -}; - -/** - * Stringify the given `str`. - * - * @param {String} str - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyString(str, prefix) { - if (!prefix) throw new TypeError('stringify expects an object'); - return prefix + '=' + encodeURIComponent(str); -} - -/** - * Stringify the given `arr`. - * - * @param {Array} arr - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyArray(arr, prefix) { - var ret = []; - if (!prefix) throw new TypeError('stringify expects an object'); - for (var i = 0; i < arr.length; i++) { - ret.push(stringify(arr[i], prefix + '[' + i + ']')); - } - return ret.join('&'); -} - -/** - * Stringify the given `obj`. - * - * @param {Object} obj - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyObject(obj, prefix) { - var ret = [] - , keys = objectKeys(obj) - , key; - - for (var i = 0, len = keys.length; i < len; ++i) { - key = keys[i]; - if ('' == key) continue; - if (null == obj[key]) { - ret.push(encodeURIComponent(key) + '='); - } else { - ret.push(stringify(obj[key], prefix - ? prefix + '[' + encodeURIComponent(key) + ']' - : encodeURIComponent(key))); - } - } - - return ret.join('&'); -} - -/** - * Set `obj`'s `key` to `val` respecting - * the weird and wonderful syntax of a qs, - * where "foo=bar&foo=baz" becomes an array. - * - * @param {Object} obj - * @param {String} key - * @param {String} val - * @api private - */ - -function set(obj, key, val) { - var v = obj[key]; - if (undefined === v) { - obj[key] = val; - } else if (isArray(v)) { - v.push(val); - } else { - obj[key] = [v, val]; - } -} - -/** - * Locate last brace in `str` within the key. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function lastBraceInKey(str) { - var len = str.length - , brace - , c; - for (var i = 0; i < len; ++i) { - c = str[i]; - if (']' == c) brace = false; - if ('[' == c) brace = true; - if ('=' == c && !brace) return i; - } -} - -/** - * Decode `str`. - * - * @param {String} str - * @return {String} - * @api private - */ - -function decode(str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (err) { - return str; - } -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/package.json deleted file mode 100644 index c11401b16f3..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/qs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "qs", - "description": "querystring parser", - "version": "0.6.5", - "keywords": [ - "query string", - "parser", - "component" - ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/node-querystring.git" - }, - "devDependencies": { - "mocha": "*", - "expect.js": "*" - }, - "scripts": { - "test": "make test" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "main": "index", - "engines": { - "node": "*" - }, - "readme": "# node-querystring\n\n query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others.\n\n## Installation\n\n $ npm install qs\n\n## Examples\n\n```js\nvar qs = require('qs');\n\nqs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com');\n// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } }\n\nqs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }})\n// => user[name]=Tobi&user[email]=tobi%40learnboost.com\n```\n\n## Testing\n\nInstall dev dependencies:\n\n $ npm install -d\n\nand execute:\n\n $ make test\n\nbrowser:\n\n $ open test/browser/index.html\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/node-querystring/issues" - }, - "_id": "qs@0.6.5", - "_from": "qs@0.6.5" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/.npmignore b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/History.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/History.md deleted file mode 100644 index 20c5319094b..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/History.md +++ /dev/null @@ -1,25 +0,0 @@ - -0.1.0 / 2012-08-25 -================== - - * add options parameter to send() that is passed to fs.createReadStream() [kanongil] - -0.0.4 / 2012-08-16 -================== - - * allow custom "Accept-Ranges" definition - -0.0.3 / 2012-07-16 -================== - - * fix normalization of the root directory. Closes #3 - -0.0.2 / 2012-07-09 -================== - - * add passing of req explicitly for now (YUCK) - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Makefile b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Makefile deleted file mode 100644 index a9dcfd50dbd..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec \ - --bail - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Readme.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Readme.md deleted file mode 100644 index ea7b234109f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/Readme.md +++ /dev/null @@ -1,128 +0,0 @@ -# send - - Send is Connect's `static()` extracted for generalized use, a streaming static file - server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework. - -## Installation - - $ npm install send - -## Examples - - Small: - -```js -var http = require('http'); -var send = require('send'); - -var app = http.createServer(function(req, res){ - send(req, req.url).pipe(res); -}).listen(3000); -``` - - Serving from a root directory with custom error-handling: - -```js -var http = require('http'); -var send = require('send'); -var url = require('url'); - -var app = http.createServer(function(req, res){ - // your custom error-handling logic: - function error(err) { - res.statusCode = err.status || 500; - res.end(err.message); - } - - // your custom directory handling logic: - function redirect() { - res.statusCode = 301; - res.setHeader('Location', req.url + '/'); - res.end('Redirecting to ' + req.url + '/'); - } - - // transfer arbitrary files from within - // /www/example.com/public/* - send(req, url.parse(req.url).pathname) - .root('/www/example.com/public') - .on('error', error) - .on('directory', redirect) - .pipe(res); -}).listen(3000); -``` - -## API - -### Events - - - `error` an error occurred `(err)` - - `directory` a directory was requested - - `file` a file was requested `(path, stat)` - - `stream` file streaming has started `(stream)` - - `end` streaming has completed - -### .root(dir) - - Serve files relative to `path`. Aliased as `.from(dir)`. - -### .index(path) - - By default send supports "index.html" files, to disable this - invoke `.index(false)` or to supply a new index pass a string. - -### .maxage(ms) - - Provide a max-age in milliseconds for http caching, defaults to 0. - -### .hidden(bool) - - Enable or disable transfer of hidden files, defaults to false. - -## Error-handling - - By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc. - -## Caching - - It does _not_ perform internal caching, you should use a reverse proxy cache such - as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;). - -## Debugging - - To enable `debug()` instrumentation output export __DEBUG__: - -``` -$ DEBUG=send node app -``` - -## Running tests - -``` -$ npm install -$ make test -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/index.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/index.js deleted file mode 100644 index f17158d853e..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/send'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/send.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/send.js deleted file mode 100644 index a3d94a69d45..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/send.js +++ /dev/null @@ -1,474 +0,0 @@ - -/** - * Module dependencies. - */ - -var debug = require('debug')('send') - , parseRange = require('range-parser') - , Stream = require('stream') - , mime = require('mime') - , fresh = require('fresh') - , path = require('path') - , http = require('http') - , fs = require('fs') - , basename = path.basename - , normalize = path.normalize - , join = path.join - , utils = require('./utils'); - -/** - * Expose `send`. - */ - -exports = module.exports = send; - -/** - * Expose mime module. - */ - -exports.mime = mime; - -/** - * Return a `SendStream` for `req` and `path`. - * - * @param {Request} req - * @param {String} path - * @param {Object} options - * @return {SendStream} - * @api public - */ - -function send(req, path, options) { - return new SendStream(req, path, options); -} - -/** - * Initialize a `SendStream` with the given `path`. - * - * Events: - * - * - `error` an error occurred - * - `stream` file streaming has started - * - `end` streaming has completed - * - `directory` a directory was requested - * - * @param {Request} req - * @param {String} path - * @param {Object} options - * @api private - */ - -function SendStream(req, path, options) { - var self = this; - this.req = req; - this.path = path; - this.options = options || {}; - this.maxage(0); - this.hidden(false); - this.index('index.html'); -} - -/** - * Inherits from `Stream.prototype`. - */ - -SendStream.prototype.__proto__ = Stream.prototype; - -/** - * Enable or disable "hidden" (dot) files. - * - * @param {Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.hidden = function(val){ - debug('hidden %s', val); - this._hidden = val; - return this; -}; - -/** - * Set index `path`, set to a falsy - * value to disable index support. - * - * @param {String|Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.index = function(path){ - debug('index %s', path); - this._index = path; - return this; -}; - -/** - * Set root `path`. - * - * @param {String} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.root = -SendStream.prototype.from = function(path){ - this._root = normalize(path); - return this; -}; - -/** - * Set max-age to `ms`. - * - * @param {Number} ms - * @return {SendStream} - * @api public - */ - -SendStream.prototype.maxage = function(ms){ - if (Infinity == ms) ms = 60 * 60 * 24 * 365 * 1000; - debug('max-age %d', ms); - this._maxage = ms; - return this; -}; - -/** - * Emit error with `status`. - * - * @param {Number} status - * @api private - */ - -SendStream.prototype.error = function(status, err){ - var res = this.res; - var msg = http.STATUS_CODES[status]; - err = err || new Error(msg); - err.status = status; - if (this.listeners('error').length) return this.emit('error', err); - res.statusCode = err.status; - res.end(msg); -}; - -/** - * Check if the pathname is potentially malicious. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isMalicious = function(){ - return !this._root && ~this.path.indexOf('..'); -}; - -/** - * Check if the pathname ends with "/". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasTrailingSlash = function(){ - return '/' == this.path[this.path.length - 1]; -}; - -/** - * Check if the basename leads with ".". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasLeadingDot = function(){ - return '.' == basename(this.path)[0]; -}; - -/** - * Check if this is a conditional GET request. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isConditionalGET = function(){ - return this.req.headers['if-none-match'] - || this.req.headers['if-modified-since']; -}; - -/** - * Strip content-* header fields. - * - * @api private - */ - -SendStream.prototype.removeContentHeaderFields = function(){ - var res = this.res; - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); - } - }); -}; - -/** - * Respond with 304 not modified. - * - * @api private - */ - -SendStream.prototype.notModified = function(){ - var res = this.res; - debug('not modified'); - this.removeContentHeaderFields(); - res.statusCode = 304; - res.end(); -}; - -/** - * Check if the request is cacheable, aka - * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isCachable = function(){ - var res = this.res; - return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode; -}; - -/** - * Handle stat() error. - * - * @param {Error} err - * @api private - */ - -SendStream.prototype.onStatError = function(err){ - var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; - if (~notfound.indexOf(err.code)) return this.error(404, err); - this.error(500, err); -}; - -/** - * Check if the cache is fresh. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isFresh = function(){ - return fresh(this.req.headers, this.res._headers); -}; - -/** - * Redirect to `path`. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.redirect = function(path){ - if (this.listeners('directory').length) return this.emit('directory'); - var res = this.res; - path += '/'; - res.statusCode = 301; - res.setHeader('Location', path); - res.end('Redirecting to ' + utils.escape(path)); -}; - -/** - * Pipe to `res. - * - * @param {Stream} res - * @return {Stream} res - * @api public - */ - -SendStream.prototype.pipe = function(res){ - var self = this - , args = arguments - , path = this.path - , root = this._root; - - // references - this.res = res; - - // invalid request uri - path = utils.decode(path); - if (-1 == path) return this.error(400); - - // null byte(s) - if (~path.indexOf('\0')) return this.error(400); - - // join / normalize from optional root dir - if (root) path = normalize(join(this._root, path)); - - // ".." is malicious without "root" - if (this.isMalicious()) return this.error(403); - - // malicious path - if (root && 0 != path.indexOf(root)) return this.error(403); - - // hidden file support - if (!this._hidden && this.hasLeadingDot()) return this.error(404); - - // index file support - if (this._index && this.hasTrailingSlash()) path += this._index; - - debug('stat "%s"', path); - fs.stat(path, function(err, stat){ - if (err) return self.onStatError(err); - if (stat.isDirectory()) return self.redirect(self.path); - self.emit('file', path, stat); - self.send(path, stat); - }); - - return res; -}; - -/** - * Transfer `path`. - * - * @param {String} path - * @api public - */ - -SendStream.prototype.send = function(path, stat){ - var options = this.options; - var len = stat.size; - var res = this.res; - var req = this.req; - var ranges = req.headers.range; - var offset = options.start || 0; - - // set header fields - this.setHeader(stat); - - // set content-type - this.type(path); - - // conditional GET support - if (this.isConditionalGET() - && this.isCachable() - && this.isFresh()) { - return this.notModified(); - } - - // adjust len to start/end options - len = Math.max(0, len - offset); - if (options.end !== undefined) { - var bytes = options.end - offset + 1; - if (len > bytes) len = bytes; - } - - // Range support - if (ranges) { - ranges = parseRange(len, ranges); - - // unsatisfiable - if (-1 == ranges) { - res.setHeader('Content-Range', 'bytes */' + stat.size); - return this.error(416); - } - - // valid (syntactically invalid ranges are treated as a regular response) - if (-2 != ranges) { - options.start = offset + ranges[0].start; - options.end = offset + ranges[0].end; - - // Content-Range - res.statusCode = 206; - res.setHeader('Content-Range', 'bytes ' - + ranges[0].start - + '-' - + ranges[0].end - + '/' - + len); - len = options.end - options.start + 1; - } - } - - // content-length - res.setHeader('Content-Length', len); - - // HEAD support - if ('HEAD' == req.method) return res.end(); - - this.stream(path, options); -}; - -/** - * Stream `path` to the response. - * - * @param {String} path - * @param {Object} options - * @api private - */ - -SendStream.prototype.stream = function(path, options){ - // TODO: this is all lame, refactor meeee - var self = this; - var res = this.res; - var req = this.req; - - // pipe - var stream = fs.createReadStream(path, options); - this.emit('stream', stream); - stream.pipe(res); - - // socket closed, done with the fd - req.on('close', stream.destroy.bind(stream)); - - // error handling code-smell - stream.on('error', function(err){ - // no hope in responding - if (res._header) { - console.error(err.stack); - req.destroy(); - return; - } - - // 500 - err.status = 500; - self.emit('error', err); - }); - - // end - stream.on('end', function(){ - self.emit('end'); - }); -}; - -/** - * Set content-type based on `path` - * if it hasn't been explicitly set. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.type = function(path){ - var res = this.res; - if (res.getHeader('Content-Type')) return; - var type = mime.lookup(path); - var charset = mime.charsets.lookup(type); - debug('content-type %s', type); - res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); -}; - -/** - * Set reaponse header fields, most - * fields may be pre-defined. - * - * @param {Object} stat - * @api private - */ - -SendStream.prototype.setHeader = function(stat){ - var res = this.res; - if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes'); - if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat)); - if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); - if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (this._maxage / 1000)); - if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString()); -}; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/utils.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/utils.js deleted file mode 100644 index 950e5a2c13d..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/lib/utils.js +++ /dev/null @@ -1,47 +0,0 @@ - -/** - * Return an ETag in the form of `"-"` - * from the given `stat`. - * - * @param {Object} stat - * @return {String} - * @api private - */ - -exports.etag = function(stat) { - return '"' + stat.size + '-' + Number(stat.mtime) + '"'; -}; - -/** - * decodeURIComponent. - * - * Allows V8 to only deoptimize this fn instead of all - * of send(). - * - * @param {String} path - * @api private - */ - -exports.decode = function(path){ - try { - return decodeURIComponent(path); - } catch (err) { - return -1; - } -}; - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/LICENSE b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/LICENSE deleted file mode 100644 index 451fc4550c2..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Benjamin Thomas, Robert Kieffer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/README.md b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/README.md deleted file mode 100644 index b90552a3b96..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# mime - -Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community. - -## Install - -Install with [npm](http://github.com/isaacs/npm): - - npm install mime - -## API - Queries - -### mime.lookup(path) -Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. - - var mime = require('mime'); - - mime.lookup('/path/to/file.txt'); // => 'text/plain' - mime.lookup('file.txt'); // => 'text/plain' - mime.lookup('.TXT'); // => 'text/plain' - mime.lookup('htm'); // => 'text/html' - -### mime.extension(type) -Get the default extension for `type` - - mime.extension('text/html'); // => 'html' - mime.extension('application/octet-stream'); // => 'bin' - -### mime.charsets.lookup() - -Map mime-type to charset - - mime.charsets.lookup('text/plain'); // => 'UTF-8' - -(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) - -## API - Defining Custom Types - -The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types). - -### mime.define() - -Add custom mime/extension mappings - - mime.define({ - 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], - 'application/x-my-type': ['x-mt', 'x-mtt'], - // etc ... - }); - - mime.lookup('x-sft'); // => 'text/x-some-format' - -The first entry in the extensions array is returned by `mime.extension()`. E.g. - - mime.extension('text/x-some-format'); // => 'x-sf' - -### mime.load(filepath) - -Load mappings from an Apache ".types" format file - - mime.load('./my_project.types'); - -The .types file format is simple - See the `types` dir for examples. diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/mime.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/mime.js deleted file mode 100644 index 70a63842486..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/mime.js +++ /dev/null @@ -1,113 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -function Mime() { - // Map of extension -> mime type - this.types = Object.create(null); - - // Map of mime type -> extension - this.extensions = Object.create(null); -} - -/** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * @param map (Object) type definitions - */ -Mime.prototype.define = function (map) { - for (var type in map) { - var exts = map[type]; - - for (var i = 0; i < exts.length; i++) { - if (process.env.DEBUG_MIME && this.types[exts]) { - console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' + - this.types[exts] + ' to ' + type); - } - - this.types[exts[i]] = type; - } - - // Default extension is the first one we encounter - if (!this.extensions[type]) { - this.extensions[type] = exts[0]; - } - } -}; - -/** - * Load an Apache2-style ".types" file - * - * This may be called multiple times (it's expected). Where files declare - * overlapping types/extensions, the last file wins. - * - * @param file (String) path of file to load. - */ -Mime.prototype.load = function(file) { - - this._loading = file; - // Read file and split into lines - var map = {}, - content = fs.readFileSync(file, 'ascii'), - lines = content.split(/[\r\n]+/); - - lines.forEach(function(line) { - // Clean up whitespace/comments, and split into fields - var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); - map[fields.shift()] = fields; - }); - - this.define(map); - - this._loading = null; -}; - -/** - * Lookup a mime type based on extension - */ -Mime.prototype.lookup = function(path, fallback) { - var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); - - return this.types[ext] || fallback || this.default_type; -}; - -/** - * Return file extension associated with a mime type - */ -Mime.prototype.extension = function(mimeType) { - return this.extensions[mimeType]; -}; - -// Default instance -var mime = new Mime(); - -// Load local copy of -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -mime.load(path.join(__dirname, 'types/mime.types')); - -// Load additional types from node.js community -mime.load(path.join(__dirname, 'types/node.types')); - -// Default type -mime.default_type = mime.lookup('bin'); - -// -// Additional API specific to the default instance -// - -mime.Mime = Mime; - -/** - * Lookup a charset based on mime type. - */ -mime.charsets = { - lookup: function(mimeType, fallback) { - // Assume text types are utf8 - return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; - } -}; - -module.exports = mime; diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/package.json deleted file mode 100644 index d7492f5bc8e..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "dependencies": {}, - "description": "A comprehensive library for mime-type mapping", - "devDependencies": {}, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "https://github.com/broofa/node-mime", - "type": "git" - }, - "version": "1.2.9", - "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-mime/issues" - }, - "_id": "mime@1.2.9", - "_from": "mime@~1.2.9", - "scripts": {} -} diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/test.js b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/test.js deleted file mode 100644 index cbad034a18f..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/test.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Usage: node test.js - */ - -var mime = require('./mime'); -var assert = require('assert'); - -function eq(a, b) { - console.log('Test: ' + a + ' === ' + b); - assert.strictEqual.apply(null, arguments); -} - -console.log(Object.keys(mime.extensions).length + ' types'); -console.log(Object.keys(mime.types).length + ' extensions\n'); - -// -// Test mime lookups -// - -eq('text/plain', mime.lookup('text.txt')); -eq('text/plain', mime.lookup('.text.txt')); -eq('text/plain', mime.lookup('.txt')); -eq('text/plain', mime.lookup('txt')); -eq('application/octet-stream', mime.lookup('text.nope')); -eq('fallback', mime.lookup('text.fallback', 'fallback')); -eq('application/octet-stream', mime.lookup('constructor')); -eq('text/plain', mime.lookup('TEXT.TXT')); -eq('text/event-stream', mime.lookup('text/event-stream')); -eq('application/x-web-app-manifest+json', mime.lookup('text.webapp')); - -// -// Test extensions -// - -eq('txt', mime.extension(mime.types.text)); -eq('html', mime.extension(mime.types.htm)); -eq('bin', mime.extension('application/octet-stream')); -eq(undefined, mime.extension('constructor')); - -// -// Test node types -// - -eq('application/octet-stream', mime.lookup('file.buffer')); -eq('audio/mp4', mime.lookup('file.m4a')); - -// -// Test charsets -// - -eq('UTF-8', mime.charsets.lookup('text/plain')); -eq(undefined, mime.charsets.lookup(mime.types.js)); -eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); - -console.log('\nOK'); diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types deleted file mode 100644 index b90b1658761..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/mime.types +++ /dev/null @@ -1,1588 +0,0 @@ -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/calendar+xml -# application/cals-1840 -# application/ccmp+xml -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -application/docbook+xml dbk -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -application/gml+xml gml -application/gpx+xml gpx -application/gxf gxf -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -application/inkml+xml ink inkml -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -application/jsonml+json jsonml -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink+xml metalink -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/omdoc+xml omdoc -application/onenote onetoc onetoc2 onetmp onepkg -application/oxps oxps -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rpki-ghostbusters gbr -application/rpki-manifest mft -application/rpki-roa roa -# application/rpki-updown -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssdl+xml ssdl -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vcard+xml -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.formscentral.fcdt fcdt -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.astraea-software.iota iota -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.collection+json -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -# application/vnd.curl -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.dart dart -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.dece.zip uvz uvvz -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.ds-keypoint kpxx -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -# application/vnd.eprints.data+xml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -# application/vnd.hal+json -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -# application/vnd.hzn-3d-crossword -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -# application/vnd.innopath.wamp.notification -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.newsmessage+xml -# application/vnd.iptc.g2.packageitem+xml -# application/vnd.iptc.g2.planningitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -# application/vnd.ms-color.iccprofile -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -# application/vnd.ms-opentype -# application/vnd.ms-package.obfuscated-opentype -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -# application/vnd.ms-printing.printticket+xml -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -application/vnd.mynfc taglet -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.nitf ntf nitf -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oftn.l10n+json -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-feature-handler+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.cab-user-prefs+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.pal+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -application/vnd.osgi.subsystem esa -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.rn-realmedia-vbr rmvb -application/vnd.route66.link66+xml link66 -# application/vnd.rs-274x -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.package smzip -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tcpdump.pcap pcap cap dmp -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.through-ngn -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -# application/x-amf -application/x-apple-diskimage dmg -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-blorb blb blorb -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cbr cbr cba cbt cbz cb7 -application/x-cdlink vcd -application/x-cfs-compressed cfs -application/x-chat chat -application/x-chess-pgn pgn -application/x-conference nsc -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-dgc-compressed dgc -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-envoy evy -application/x-eva eva -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff -# application/x-font-vfont -application/x-freearc arc -application/x-futuresplash spl -application/x-gca-compressed gca -application/x-glulx ulx -application/x-gnumeric gnumeric -application/x-gramps-xml gramps -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-install-instructions install -application/x-iso9660-image iso -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-lzh-compressed lzh lha -application/x-mie mie -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-shortcut lnk -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf wmz emf emz -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-nzb nzb -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-research-info-systems ris -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-sql sql -application/x-stuffit sit -application/x-stuffitx sitx -application/x-subrip srt -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-t3vm-image t3 -application/x-tads gam -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-tgif obj -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xliff+xml xlf -application/x-xpinstall xpi -application/x-xz xz -application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 -# application/x400-bp -application/xaml+xml xaml -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xproc+xml xpl -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dv -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/fwdred -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/ip-mr_v2.5 -# audio/isac -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -# audio/musepack -audio/ogg oga ogg spx -# audio/opus -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -audio/s3m s3m -audio/silk sil -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.dvb.file -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-caf caf -audio/x-flac flac -audio/x-matroska mka -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -# audio/x-tta -audio/x-wav wav -audio/xm xm -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/sgi sgi -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.ms-photo wdp -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-3ds 3ds -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-mrsid-image sid -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-tga tga -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -model/x3d+binary x3db x3dbz -model/x3d+vrml x3dv x3dvz -model/x3d+xml x3d x3dz -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/cache-manifest appcache -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -# text/fwdred -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -text/vcard vcard -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -text/vnd.dvb.subtitle sub -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-java-source java -text/x-opml opml -text/x-pascal p pas -text/x-nfo nfo -text/x-setext etx -text/x-sfv sfv -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.dvb.file dvb -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-matroska mkv mk3d mks -video/x-mng mng -video/x-ms-asf asf asx -video/x-ms-vob vob -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -video/x-smv smv -x-conference/x-cooltalk ice diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/node.types b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/node.types deleted file mode 100644 index 970a1bd85d6..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/node_modules/mime/types/node.types +++ /dev/null @@ -1,60 +0,0 @@ -# What: WebVTT -# Why: To allow formats intended for marking up external text track resources. -# http://dev.w3.org/html5/webvtt/ -# Added by: niftylettuce -text/vtt vtt - -# What: Google Chrome Extension -# Why: To allow apps to (work) be served with the right content type header. -# http://codereview.chromium.org/2830017 -# Added by: niftylettuce -application/x-chrome-extension crx - -# What: HTC support -# Why: To properly render .htc files such as CSS3PIE -# Added by: niftylettuce -text/x-component htc - -# What: HTML5 application cache manifest -# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps -# per https://developer.mozilla.org/en/offline_resources_in_firefox -# Added by: louisremi -text/cache-manifest appcache manifest - -# What: node binary buffer format -# Why: semi-standard extension w/in the node community -# Added by: tootallnate -application/octet-stream buffer - -# What: The "protected" MP-4 formats used by iTunes. -# Why: Required for streaming music to browsers (?) -# Added by: broofa -application/mp4 m4p -audio/mp4 m4a - -# What: Video format, Part of RFC1890 -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -video/MP2T ts - -# What: EventSource mime type -# Why: mime type of Server-Sent Events stream -# http://www.w3.org/TR/eventsource/#text-event-stream -# Added by: francois2metz -text/event-stream event-stream - -# What: Mozilla App manifest mime type -# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests -# Added by: ednapiranha -application/x-web-app-manifest+json webapp - -# What: Lua file types -# Why: Googling around shows de-facto consensus on these -# Added by: creationix (Issue #45) -text/x-lua lua -application/x-lua-bytecode luac - -# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax -# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown -# Added by: avoidwork -text/x-markdown markdown md mkd diff --git a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/package.json b/frontend/express/node_modules/express/node_modules/connect/node_modules/send/package.json deleted file mode 100644 index 2c00d3b4c40..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/node_modules/send/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "send", - "version": "0.1.1", - "description": "Better streaming static file server with Range and conditional-GET support", - "keywords": [ - "static", - "file", - "server" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": { - "debug": "*", - "mime": "~1.2.9", - "fresh": "0.1.0", - "range-parser": "0.0.4" - }, - "devDependencies": { - "mocha": "*", - "should": "*", - "supertest": "0.0.1", - "connect": "2.x" - }, - "scripts": { - "test": "make test" - }, - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/send.git" - }, - "main": "index", - "readme": "# send\n\n Send is Connect's `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n $ npm install send\n\n## Examples\n\n Small:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n}).listen(3000);\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require('http');\nvar send = require('send');\nvar url = require('url');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader('Location', req.url + '/');\n res.end('Redirecting to ' + req.url + '/');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname)\n .root('/www/example.com/public')\n .on('error', error)\n .on('directory', redirect)\n .pipe(res);\n}).listen(3000);\n```\n\n## API\n\n### Events\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `file` a file was requested `(path, stat)`\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .root(dir)\n\n Serve files relative to `path`. Aliased as `.from(dir)`.\n\n### .index(path)\n\n By default send supports \"index.html\" files, to disable this\n invoke `.index(false)` or to supply a new index pass a string.\n\n### .maxage(ms)\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n\n### .hidden(bool)\n\n Enable or disable transfer of hidden files, defaults to false.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ make test\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/send/issues" - }, - "_id": "send@0.1.1", - "_from": "send@0.1.1" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/package.json b/frontend/express/node_modules/express/node_modules/connect/package.json deleted file mode 100644 index 9b47f278d57..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "connect", - "version": "2.7.11", - "description": "High performance middleware framework", - "keywords": [ - "framework", - "web", - "middleware", - "connect", - "rack" - ], - "repository": { - "type": "git", - "url": "git://github.com/senchalabs/connect.git" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "dependencies": { - "qs": "0.6.5", - "formidable": "1.0.14", - "cookie-signature": "1.0.1", - "buffer-crc32": "0.2.1", - "cookie": "0.0.5", - "send": "0.1.1", - "bytes": "0.2.0", - "fresh": "0.1.0", - "pause": "0.0.1", - "debug": "*" - }, - "devDependencies": { - "should": "*", - "mocha": "*", - "jade": "*", - "dox": "*" - }, - "main": "index", - "engines": { - "node": ">= 0.8.0" - }, - "scripts": { - "test": "make" - }, - "readme": "[![build status](https://secure.travis-ci.org/senchalabs/connect.png)](http://travis-ci.org/senchalabs/connect)\n# Connect\n\n Connect is an extensible HTTP server framework for [node](http://nodejs.org), providing high performance \"plugins\" known as _middleware_.\n\n Connect is bundled with over _20_ commonly used middleware, including\n a logger, session support, cookie parser, and [more](http://senchalabs.github.com/connect). Be sure to view the 2.x [documentation](http://senchalabs.github.com/connect/).\n\n```js\nvar connect = require('connect')\n , http = require('http');\n\nvar app = connect()\n .use(connect.favicon())\n .use(connect.logger('dev'))\n .use(connect.static('public'))\n .use(connect.directory('public'))\n .use(connect.cookieParser())\n .use(connect.session({ secret: 'my secret here' }))\n .use(function(req, res){\n res.end('Hello from Connect!\\n');\n });\n\nhttp.createServer(app).listen(3000);\n```\n\n## Middleware\n\n - [csrf](http://www.senchalabs.org/connect/csrf.html)\n - [basicAuth](http://www.senchalabs.org/connect/basicAuth.html)\n - [bodyParser](http://www.senchalabs.org/connect/bodyParser.html)\n - [json](http://www.senchalabs.org/connect/json.html)\n - [multipart](http://www.senchalabs.org/connect/multipart.html)\n - [urlencoded](http://www.senchalabs.org/connect/urlencoded.html)\n - [cookieParser](http://www.senchalabs.org/connect/cookieParser.html)\n - [directory](http://www.senchalabs.org/connect/directory.html)\n - [compress](http://www.senchalabs.org/connect/compress.html)\n - [errorHandler](http://www.senchalabs.org/connect/errorHandler.html)\n - [favicon](http://www.senchalabs.org/connect/favicon.html)\n - [limit](http://www.senchalabs.org/connect/limit.html)\n - [logger](http://www.senchalabs.org/connect/logger.html)\n - [methodOverride](http://www.senchalabs.org/connect/methodOverride.html)\n - [query](http://www.senchalabs.org/connect/query.html)\n - [responseTime](http://www.senchalabs.org/connect/responseTime.html)\n - [session](http://www.senchalabs.org/connect/session.html)\n - [static](http://www.senchalabs.org/connect/static.html)\n - [staticCache](http://www.senchalabs.org/connect/staticCache.html)\n - [vhost](http://www.senchalabs.org/connect/vhost.html)\n - [subdomains](http://www.senchalabs.org/connect/subdomains.html)\n - [cookieSession](http://www.senchalabs.org/connect/cookieSession.html)\n\n## Running Tests\n\nfirst:\n\n $ npm install -d\n\nthen:\n\n $ make test\n\n## Authors\n\n Below is the output from [git-summary](http://github.com/visionmedia/git-extras).\n\n\n project: connect\n commits: 2033\n active : 301 days\n files : 171\n authors: \n 1414\tTj Holowaychuk 69.6%\n 298\tvisionmedia 14.7%\n 191\tTim Caswell 9.4%\n 51\tTJ Holowaychuk 2.5%\n 10\tRyan Olds 0.5%\n 8\tAstro 0.4%\n 5\tNathan Rajlich 0.2%\n 5\tJakub NeÅ¡etÅ™il 0.2%\n 3\tDaniel Dickison 0.1%\n 3\tDavid Rio Deiros 0.1%\n 3\tAlexander Simmerl 0.1%\n 3\tAndreas Lind Petersen 0.1%\n 2\tAaron Heckmann 0.1%\n 2\tJacques Crocker 0.1%\n 2\tFabian Jakobs 0.1%\n 2\tBrian J Brennan 0.1%\n 2\tAdam Malcontenti-Wilson 0.1%\n 2\tGlen Mailer 0.1%\n 2\tJames Campos 0.1%\n 1\tTrent Mick 0.0%\n 1\tTroy Kruthoff 0.0%\n 1\tWei Zhu 0.0%\n 1\tcomerc 0.0%\n 1\tdarobin 0.0%\n 1\tnateps 0.0%\n 1\tMarco Sanson 0.0%\n 1\tArthur Taylor 0.0%\n 1\tAseem Kishore 0.0%\n 1\tBart Teeuwisse 0.0%\n 1\tCameron Howey 0.0%\n 1\tChad Weider 0.0%\n 1\tCraig Barnes 0.0%\n 1\tEran Hammer-Lahav 0.0%\n 1\tGregory McWhirter 0.0%\n 1\tGuillermo Rauch 0.0%\n 1\tJae Kwon 0.0%\n 1\tJakub Nesetril 0.0%\n 1\tJoshua Peek 0.0%\n 1\tJxck 0.0%\n 1\tAJ ONeal 0.0%\n 1\tMichael Hemesath 0.0%\n 1\tMorten Siebuhr 0.0%\n 1\tSamori Gorse 0.0%\n 1\tTom Jensen 0.0%\n\n## Node Compatibility\n\n Connect `< 1.x` is compatible with node 0.2.x\n\n\n Connect `1.x` is compatible with node 0.4.x\n\n\n Connect (_master_) `2.x` is compatible with node 0.6.x\n\n## CLA\n\n [http://sencha.com/cla](http://sencha.com/cla)\n\n## License\n\nView the [LICENSE](https://github.com/senchalabs/connect/blob/master/LICENSE) file. The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons used by the `directory` middleware created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/).\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/senchalabs/connect/issues" - }, - "_id": "connect@2.7.11", - "_from": "connect@2.7.11" -} diff --git a/frontend/express/node_modules/express/node_modules/connect/test.js b/frontend/express/node_modules/express/node_modules/connect/test.js deleted file mode 100644 index 92b7003d342..00000000000 --- a/frontend/express/node_modules/express/node_modules/connect/test.js +++ /dev/null @@ -1,40 +0,0 @@ - -var connect = require('./'); -var app = connect(); - -app.use(connect.logger('dev')); -app.use(connect.bodyParser()); - -app.use(function(req, res, next){ - if (req.checkContinue) { - res.writeContinue(); - } - res.end('hello'); -}); - -var server = app.listen(3000); - -server.on('checkContinue', function(req, res){ - req.checkContinue = true; - app(req, res); -}); - - -// var http = require('http'); - -// var app = http.createServer(function(req, res){ -// console.log(req.headers); -// }); - -// app.on('checkContinue', function(req, res){ -// if ('application/json' == req.headers['content-type']) { -// res.writeContinue(); -// console.log('ok'); -// res.end('thanks') -// } else { -// res.writeHead(400); -// res.end('bad request, json only'); -// } -// }); - -// app.listen(3000); diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/.npmignore b/frontend/express/node_modules/express/node_modules/cookie-signature/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/History.md b/frontend/express/node_modules/express/node_modules/cookie-signature/History.md deleted file mode 100644 index 9e301799832..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/History.md +++ /dev/null @@ -1,11 +0,0 @@ - -1.0.1 / 2013-04-15 -================== - - * Revert "Changed underlying HMAC algo. to sha512." - * Revert "Fix for timing attacks on MAC verification." - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/Makefile b/frontend/express/node_modules/express/node_modules/cookie-signature/Makefile deleted file mode 100644 index 4e9c8d36ebc..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/Readme.md b/frontend/express/node_modules/express/node_modules/cookie-signature/Readme.md deleted file mode 100644 index 2559e841b02..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/Readme.md +++ /dev/null @@ -1,42 +0,0 @@ - -# cookie-signature - - Sign and unsign cookies. - -## Example - -```js -var cookie = require('cookie-signature'); - -var val = cookie.sign('hello', 'tobiiscool'); -val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI'); - -var val = cookie.sign('hello', 'tobiiscool'); -cookie.unsign(val, 'tobiiscool').should.equal('hello'); -cookie.unsign(val, 'luna').should.be.false; -``` - -## License - -(The MIT License) - -Copyright (c) 2012 LearnBoost <tj@learnboost.com> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/index.js b/frontend/express/node_modules/express/node_modules/cookie-signature/index.js deleted file mode 100644 index ed62814e6c5..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/index.js +++ /dev/null @@ -1,42 +0,0 @@ - -/** - * Module dependencies. - */ - -var crypto = require('crypto'); - -/** - * Sign the given `val` with `secret`. - * - * @param {String} val - * @param {String} secret - * @return {String} - * @api private - */ - -exports.sign = function(val, secret){ - if ('string' != typeof val) throw new TypeError('cookie required'); - if ('string' != typeof secret) throw new TypeError('secret required'); - return val + '.' + crypto - .createHmac('sha256', secret) - .update(val) - .digest('base64') - .replace(/\=+$/, ''); -}; - -/** - * Unsign and decode the given `val` with `secret`, - * returning `false` if the signature is invalid. - * - * @param {String} val - * @param {String} secret - * @return {String|Boolean} - * @api private - */ - -exports.unsign = function(val, secret){ - if ('string' != typeof val) throw new TypeError('cookie required'); - if ('string' != typeof secret) throw new TypeError('secret required'); - var str = val.slice(0, val.lastIndexOf('.')); - return exports.sign(str, secret) == val ? str : false; -}; diff --git a/frontend/express/node_modules/express/node_modules/cookie-signature/package.json b/frontend/express/node_modules/express/node_modules/cookie-signature/package.json deleted file mode 100644 index 83bea32ca92..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie-signature/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "cookie-signature", - "version": "1.0.1", - "description": "Sign and unsign cookies", - "keywords": [ - "cookie", - "sign", - "unsign" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@learnboost.com" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "main": "index", - "readme": "\n# cookie-signature\n\n Sign and unsign cookies.\n\n## Example\n\n```js\nvar cookie = require('cookie-signature');\n\nvar val = cookie.sign('hello', 'tobiiscool');\nval.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI');\n\nvar val = cookie.sign('hello', 'tobiiscool');\ncookie.unsign(val, 'tobiiscool').should.equal('hello');\ncookie.unsign(val, 'luna').should.be.false;\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 LearnBoost <tj@learnboost.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "_id": "cookie-signature@1.0.1", - "_from": "cookie-signature@1.0.1" -} diff --git a/frontend/express/node_modules/express/node_modules/cookie/.npmignore b/frontend/express/node_modules/express/node_modules/cookie/.npmignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/frontend/express/node_modules/express/node_modules/cookie/.travis.yml b/frontend/express/node_modules/express/node_modules/cookie/.travis.yml deleted file mode 100644 index 9400c1188eb..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - "0.6" - - "0.8" - - "0.10" diff --git a/frontend/express/node_modules/express/node_modules/cookie/LICENSE b/frontend/express/node_modules/express/node_modules/cookie/LICENSE deleted file mode 100644 index 249d9def928..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -// MIT License - -Copyright (C) Roman Shtylman - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/cookie/README.md b/frontend/express/node_modules/express/node_modules/cookie/README.md deleted file mode 100644 index 5187ed1ccad..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) # - -cookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers. - -See [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies. - -## how? - -``` -npm install cookie -``` - -```javascript -var cookie = require('cookie'); - -var hdr = cookie.serialize('foo', 'bar'); -// hdr = 'foo=bar'; - -var cookies = cookie.parse('foo=bar; cat=meow; dog=ruff'); -// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' }; -``` - -## more - -The serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values. - -### path -> cookie path - -### expires -> absolute expiration date for the cookie (Date object) - -### maxAge -> relative max age of the cookie from when the client receives it (seconds) - -### domain -> domain for the cookie - -### secure -> true or false - -### httpOnly -> true or false - diff --git a/frontend/express/node_modules/express/node_modules/cookie/index.js b/frontend/express/node_modules/express/node_modules/cookie/index.js deleted file mode 100644 index 16bdb65dda8..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/index.js +++ /dev/null @@ -1,70 +0,0 @@ - -/// Serialize the a name value pair into a cookie string suitable for -/// http headers. An optional options object specified cookie parameters -/// -/// serialize('foo', 'bar', { httpOnly: true }) -/// => "foo=bar; httpOnly" -/// -/// @param {String} name -/// @param {String} val -/// @param {Object} options -/// @return {String} -var serialize = function(name, val, opt){ - opt = opt || {}; - var enc = opt.encode || encode; - var pairs = [name + '=' + enc(val)]; - - if (opt.maxAge) pairs.push('Max-Age=' + opt.maxAge); - if (opt.domain) pairs.push('Domain=' + opt.domain); - if (opt.path) pairs.push('Path=' + opt.path); - if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); - if (opt.httpOnly) pairs.push('HttpOnly'); - if (opt.secure) pairs.push('Secure'); - - return pairs.join('; '); -}; - -/// Parse the given cookie header string into an object -/// The object has the various cookies as keys(names) => values -/// @param {String} str -/// @return {Object} -var parse = function(str, opt) { - opt = opt || {}; - var obj = {} - var pairs = str.split(/[;,] */); - var dec = opt.decode || decode; - - pairs.forEach(function(pair) { - var eq_idx = pair.indexOf('=') - - // skip things that don't look like key=value - if (eq_idx < 0) { - return; - } - - var key = pair.substr(0, eq_idx).trim() - var val = pair.substr(++eq_idx, pair.length).trim(); - - // quoted values - if ('"' == val[0]) { - val = val.slice(1, -1); - } - - // only assign once - if (undefined == obj[key]) { - try { - obj[key] = dec(val); - } catch (e) { - obj[key] = val; - } - } - }); - - return obj; -}; - -var encode = encodeURIComponent; -var decode = decodeURIComponent; - -module.exports.serialize = serialize; -module.exports.parse = parse; diff --git a/frontend/express/node_modules/express/node_modules/cookie/package.json b/frontend/express/node_modules/express/node_modules/cookie/package.json deleted file mode 100644 index 99a390f7ed4..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "author": { - "name": "Roman Shtylman", - "email": "shtylman@gmail.com" - }, - "name": "cookie", - "description": "cookie parsing and serialization", - "version": "0.1.0", - "repository": { - "type": "git", - "url": "git://github.com/shtylman/node-cookie.git" - }, - "keywords": [ - "cookie", - "cookies" - ], - "main": "index.js", - "scripts": { - "test": "mocha" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "1.x.x" - }, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "# cookie [![Build Status](https://secure.travis-ci.org/shtylman/node-cookie.png?branch=master)](http://travis-ci.org/shtylman/node-cookie) #\n\ncookie is a basic cookie parser and serializer. It doesn't make assumptions about how you are going to deal with your cookies. It basically just provides a way to read and write the HTTP cookie headers.\n\nSee [RFC6265](http://tools.ietf.org/html/rfc6265) for details about the http header for cookies.\n\n## how?\n\n```\nnpm install cookie\n```\n\n```javascript\nvar cookie = require('cookie');\n\nvar hdr = cookie.serialize('foo', 'bar');\n// hdr = 'foo=bar';\n\nvar cookies = cookie.parse('foo=bar; cat=meow; dog=ruff');\n// cookies = { foo: 'bar', cat: 'meow', dog: 'ruff' };\n```\n\n## more\n\nThe serialize function takes a third parameter, an object, to set cookie options. See the RFC for valid values.\n\n### path\n> cookie path\n\n### expires\n> absolute expiration date for the cookie (Date object)\n\n### maxAge\n> relative max age of the cookie from when the client receives it (seconds)\n\n### domain\n> domain for the cookie\n\n### secure\n> true or false\n\n### httpOnly\n> true or false\n\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/shtylman/node-cookie/issues" - }, - "_id": "cookie@0.1.0", - "_from": "cookie@0.1.0" -} diff --git a/frontend/express/node_modules/express/node_modules/cookie/test/mocha.opts b/frontend/express/node_modules/express/node_modules/cookie/test/mocha.opts deleted file mode 100644 index e2bfcc5ac3f..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---ui qunit diff --git a/frontend/express/node_modules/express/node_modules/cookie/test/parse.js b/frontend/express/node_modules/express/node_modules/cookie/test/parse.js deleted file mode 100644 index c6c27a20bb5..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/test/parse.js +++ /dev/null @@ -1,44 +0,0 @@ - -var assert = require('assert'); - -var cookie = require('..'); - -suite('parse'); - -test('basic', function() { - assert.deepEqual({ foo: 'bar' }, cookie.parse('foo=bar')); - assert.deepEqual({ foo: '123' }, cookie.parse('foo=123')); -}); - -test('ignore spaces', function() { - assert.deepEqual({ FOO: 'bar', baz: 'raz' }, - cookie.parse('FOO = bar; baz = raz')); -}); - -test('escaping', function() { - assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, - cookie.parse('foo="bar=123456789&name=Magic+Mouse"')); - - assert.deepEqual({ email: ' ",;/' }, - cookie.parse('email=%20%22%2c%3b%2f')); -}); - -test('ignore escaping error and return original value', function() { - assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar')); -}); - -test('ignore non values', function() { - assert.deepEqual({ foo: '%1', bar: 'bar' }, cookie.parse('foo=%1;bar=bar;HttpOnly;Secure')); -}); - -test('unencoded', function() { - assert.deepEqual({ foo: 'bar=123456789&name=Magic+Mouse' }, - cookie.parse('foo="bar=123456789&name=Magic+Mouse"',{ - decode: function(value) { return value; } - })); - - assert.deepEqual({ email: '%20%22%2c%3b%2f' }, - cookie.parse('email=%20%22%2c%3b%2f',{ - decode: function(value) { return value; } - })); -}) diff --git a/frontend/express/node_modules/express/node_modules/cookie/test/serialize.js b/frontend/express/node_modules/express/node_modules/cookie/test/serialize.js deleted file mode 100644 index 86bb8c935c6..00000000000 --- a/frontend/express/node_modules/express/node_modules/cookie/test/serialize.js +++ /dev/null @@ -1,64 +0,0 @@ -// builtin -var assert = require('assert'); - -var cookie = require('..'); - -suite('serialize'); - -test('basic', function() { - assert.equal('foo=bar', cookie.serialize('foo', 'bar')); - assert.equal('foo=bar%20baz', cookie.serialize('foo', 'bar baz')); -}); - -test('path', function() { - assert.equal('foo=bar; Path=/', cookie.serialize('foo', 'bar', { - path: '/' - })); -}); - -test('secure', function() { - assert.equal('foo=bar; Secure', cookie.serialize('foo', 'bar', { - secure: true - })); - - assert.equal('foo=bar', cookie.serialize('foo', 'bar', { - secure: false - })); -}); - -test('domain', function() { - assert.equal('foo=bar; Domain=example.com', cookie.serialize('foo', 'bar', { - domain: 'example.com' - })); -}); - -test('httpOnly', function() { - assert.equal('foo=bar; HttpOnly', cookie.serialize('foo', 'bar', { - httpOnly: true - })); -}); - -test('maxAge', function() { - assert.equal('foo=bar; Max-Age=1000', cookie.serialize('foo', 'bar', { - maxAge: 1000 - })); -}); - -test('escaping', function() { - assert.deepEqual('cat=%2B%20', cookie.serialize('cat', '+ ')); -}); - -test('parse->serialize', function() { - - assert.deepEqual({ cat: 'foo=123&name=baz five' }, cookie.parse( - cookie.serialize('cat', 'foo=123&name=baz five'))); - - assert.deepEqual({ cat: ' ";/' }, cookie.parse( - cookie.serialize('cat', ' ";/'))); -}); - -test('unencoded', function() { - assert.deepEqual('cat=+ ', cookie.serialize('cat', '+ ', { - encode: function(value) { return value; } - })); -}) diff --git a/frontend/express/node_modules/express/node_modules/debug/.npmignore b/frontend/express/node_modules/express/node_modules/debug/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/debug/History.md b/frontend/express/node_modules/express/node_modules/debug/History.md deleted file mode 100644 index f023269bed8..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/History.md +++ /dev/null @@ -1,62 +0,0 @@ - -0.7.2 / 2013-02-06 -================== - - * fix package.json - * fix: Mobile Safari (private mode) is broken with debug - * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript - -0.7.1 / 2013-02-05 -================== - - * add repository URL to package.json - * add DEBUG_COLORED to force colored output - * add browserify support - * fix component. Closes #24 - -0.7.0 / 2012-05-04 -================== - - * Added .component to package.json - * Added debug.component.js build - -0.6.0 / 2012-03-16 -================== - - * Added support for "-" prefix in DEBUG [Vinay Pulim] - * Added `.enabled` flag to the node version [TooTallNate] - -0.5.0 / 2012-02-02 -================== - - * Added: humanize diffs. Closes #8 - * Added `debug.disable()` to the CS variant - * Removed padding. Closes #10 - * Fixed: persist client-side variant again. Closes #9 - -0.4.0 / 2012-02-01 -================== - - * Added browser variant support for older browsers [TooTallNate] - * Added `debug.enable('project:*')` to browser variant [TooTallNate] - * Added padding to diff (moved it to the right) - -0.3.0 / 2012-01-26 -================== - - * Added millisecond diff when isatty, otherwise UTC string - -0.2.0 / 2012-01-22 -================== - - * Added wildcard support - -0.1.0 / 2011-12-02 -================== - - * Added: remove colors unless stderr isatty [TooTallNate] - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/debug/Readme.md b/frontend/express/node_modules/express/node_modules/debug/Readme.md deleted file mode 100644 index 15ee50193fc..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/Readme.md +++ /dev/null @@ -1,115 +0,0 @@ - -# debug - - tiny node.js debugging utility modelled after node core's debugging technique. - -## Installation - -``` -$ npm install debug -``` - -## Usage - - With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. - -Example _app.js_: - -```js -var debug = require('debug')('http') - , http = require('http') - , name = 'My App'; - -// fake app - -debug('booting %s', name); - -http.createServer(function(req, res){ - debug(req.method + ' ' + req.url); - res.end('hello\n'); -}).listen(3000, function(){ - debug('listening'); -}); - -// fake worker of some kind - -require('./worker'); -``` - -Example _worker.js_: - -```js -var debug = require('debug')('worker'); - -setInterval(function(){ - debug('doing some work'); -}, 1000); -``` - - The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: - - ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) - - ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) - -## Millisecond diff - - When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. - - ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) - - When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: - - ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) - -## Conventions - - If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". - -## Wildcards - - The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. - - You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:". - -## Browser support - - Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. - -```js -a = debug('worker:a'); -b = debug('worker:b'); - -setInterval(function(){ - a('doing some work'); -}, 1000); - -setInterval(function(){ - a('doing some work'); -}, 1200); -``` - -## License - -(The MIT License) - -Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/debug/component.json b/frontend/express/node_modules/express/node_modules/debug/component.json deleted file mode 100644 index 4ad09718e3d..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/component.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "debug", - "repo": "visionmedia/debug", - "description": "small debugging utility", - "version": "0.7.2", - "keywords": ["debug", "log", "debugger"], - "scripts": ["index.js", "debug.js"], - "dependencies": {} -} diff --git a/frontend/express/node_modules/express/node_modules/debug/debug.js b/frontend/express/node_modules/express/node_modules/debug/debug.js deleted file mode 100644 index e47ba5b0841..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/debug.js +++ /dev/null @@ -1,124 +0,0 @@ - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - if (!debug.enabled(name)) return function(){}; - - return function(fmt){ - var curr = new Date; - var ms = curr - (debug[name] || curr); - debug[name] = curr; - - fmt = name - + ' ' - + fmt - + ' +' + debug.humanize(ms); - - // This hackery is required for IE8 - // where `console.log` doesn't have 'apply' - window.console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); - } -} - -/** - * The currently active debug mode names. - */ - -debug.names = []; -debug.skips = []; - -/** - * Enables a debug mode by name. This can include modes - * separated by a colon and wildcards. - * - * @param {String} name - * @api public - */ - -debug.enable = function(name) { - try { - localStorage.debug = name; - } catch(e){} - - var split = (name || '').split(/[\s,]+/) - , len = split.length; - - for (var i = 0; i < len; i++) { - name = split[i].replace('*', '.*?'); - if (name[0] === '-') { - debug.skips.push(new RegExp('^' + name.substr(1) + '$')); - } - else { - debug.names.push(new RegExp('^' + name + '$')); - } - } -}; - -/** - * Disable debug output. - * - * @api public - */ - -debug.disable = function(){ - debug.enable(''); -}; - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -debug.humanize = function(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -}; - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -debug.enabled = function(name) { - for (var i = 0, len = debug.skips.length; i < len; i++) { - if (debug.skips[i].test(name)) { - return false; - } - } - for (var i = 0, len = debug.names.length; i < len; i++) { - if (debug.names[i].test(name)) { - return true; - } - } - return false; -}; - -// persist - -if (window.localStorage) debug.enable(localStorage.debug); diff --git a/frontend/express/node_modules/express/node_modules/debug/example/app.js b/frontend/express/node_modules/express/node_modules/debug/example/app.js deleted file mode 100644 index 05374d98dd4..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/example/app.js +++ /dev/null @@ -1,19 +0,0 @@ - -var debug = require('../')('http') - , http = require('http') - , name = 'My App'; - -// fake app - -debug('booting %s', name); - -http.createServer(function(req, res){ - debug(req.method + ' ' + req.url); - res.end('hello\n'); -}).listen(3000, function(){ - debug('listening'); -}); - -// fake worker of some kind - -require('./worker'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/debug/example/browser.html b/frontend/express/node_modules/express/node_modules/debug/example/browser.html deleted file mode 100644 index 7510eee7b4c..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/example/browser.html +++ /dev/null @@ -1,24 +0,0 @@ - - - debug() - - - - - - - diff --git a/frontend/express/node_modules/express/node_modules/debug/example/wildcards.js b/frontend/express/node_modules/express/node_modules/debug/example/wildcards.js deleted file mode 100644 index 1fdac20a968..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/example/wildcards.js +++ /dev/null @@ -1,10 +0,0 @@ - -var debug = { - foo: require('../')('test:foo'), - bar: require('../')('test:bar'), - baz: require('../')('test:baz') -}; - -debug.foo('foo') -debug.bar('bar') -debug.baz('baz') \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/debug/example/worker.js b/frontend/express/node_modules/express/node_modules/debug/example/worker.js deleted file mode 100644 index 7f6d2886c00..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/example/worker.js +++ /dev/null @@ -1,22 +0,0 @@ - -// DEBUG=* node example/worker -// DEBUG=worker:* node example/worker -// DEBUG=worker:a node example/worker -// DEBUG=worker:b node example/worker - -var a = require('../')('worker:a') - , b = require('../')('worker:b'); - -function work() { - a('doing lots of uninteresting work'); - setTimeout(work, Math.random() * 1000); -} - -work(); - -function workb() { - b('doing some work'); - setTimeout(workb, Math.random() * 2000); -} - -workb(); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/debug/index.js b/frontend/express/node_modules/express/node_modules/debug/index.js deleted file mode 100644 index e02c13b7f6a..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/index.js +++ /dev/null @@ -1,5 +0,0 @@ -if ('undefined' == typeof window) { - module.exports = require('./lib/debug'); -} else { - module.exports = require('./debug'); -} diff --git a/frontend/express/node_modules/express/node_modules/debug/lib/debug.js b/frontend/express/node_modules/express/node_modules/debug/lib/debug.js deleted file mode 100644 index 0b07aa1d120..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/lib/debug.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Module dependencies. - */ - -var tty = require('tty'); - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Enabled debuggers. - */ - -var names = [] - , skips = []; - -(process.env.DEBUG || '') - .split(/[\s,]+/) - .forEach(function(name){ - name = name.replace('*', '.*?'); - if (name[0] === '-') { - skips.push(new RegExp('^' + name.substr(1) + '$')); - } else { - names.push(new RegExp('^' + name + '$')); - } - }); - -/** - * Colors. - */ - -var colors = [6, 2, 3, 4, 5, 1]; - -/** - * Previous debug() call. - */ - -var prev = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Is stdout a TTY? Colored output is disabled when `true`. - */ - -var isatty = tty.isatty(2); - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function color() { - return colors[prevColor++ % colors.length]; -} - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -function humanize(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -} - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - function disabled(){} - disabled.enabled = false; - - var match = skips.some(function(re){ - return re.test(name); - }); - - if (match) return disabled; - - match = names.some(function(re){ - return re.test(name); - }); - - if (!match) return disabled; - var c = color(); - - function colored(fmt) { - var curr = new Date; - var ms = curr - (prev[name] || curr); - prev[name] = curr; - - fmt = ' \u001b[9' + c + 'm' + name + ' ' - + '\u001b[3' + c + 'm\u001b[90m' - + fmt + '\u001b[3' + c + 'm' - + ' +' + humanize(ms) + '\u001b[0m'; - - console.error.apply(this, arguments); - } - - function plain(fmt) { - fmt = new Date().toUTCString() - + ' ' + name + ' ' + fmt; - console.error.apply(this, arguments); - } - - colored.enabled = plain.enabled = true; - - return isatty || process.env.DEBUG_COLORS - ? colored - : plain; -} diff --git a/frontend/express/node_modules/express/node_modules/debug/package.json b/frontend/express/node_modules/express/node_modules/debug/package.json deleted file mode 100644 index 112d22bea19..00000000000 --- a/frontend/express/node_modules/express/node_modules/debug/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "debug", - "version": "0.7.2", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/debug.git" - }, - "description": "small debugging utility", - "keywords": [ - "debug", - "log", - "debugger" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "*" - }, - "main": "lib/debug.js", - "browserify": "debug.js", - "engines": { - "node": "*" - }, - "component": { - "scripts": { - "debug/index.js": "index.js", - "debug/debug.js": "debug.js" - } - }, - "readme": "\n# debug\n\n tiny node.js debugging utility modelled after node core's debugging technique.\n\n## Installation\n\n```\n$ npm install debug\n```\n\n## Usage\n\n With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.\n \nExample _app.js_:\n\n```js\nvar debug = require('debug')('http')\n , http = require('http')\n , name = 'My App';\n\n// fake app\n\ndebug('booting %s', name);\n\nhttp.createServer(function(req, res){\n debug(req.method + ' ' + req.url);\n res.end('hello\\n');\n}).listen(3000, function(){\n debug('listening');\n});\n\n// fake worker of some kind\n\nrequire('./worker');\n```\n\nExample _worker.js_:\n\n```js\nvar debug = require('debug')('worker');\n\nsetInterval(function(){\n debug('doing some work');\n}, 1000);\n```\n\n The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:\n\n ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)\n\n ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)\n\n## Millisecond diff\n\n When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the \"+NNNms\" will show you how much time was spent between calls.\n\n ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)\n\n When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:\n \n ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)\n\n## Conventions\n\n If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use \":\" to separate features. For example \"bodyParser\" from Connect would then be \"connect:bodyParser\". \n\n## Wildcards\n\n The \"*\" character may be used as a wildcard. Suppose for example your library has debuggers named \"connect:bodyParser\", \"connect:compress\", \"connect:session\", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.\n\n You can also exclude specific debuggers by prefixing them with a \"-\" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with \"connect:\".\n\n## Browser support\n\n Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. \n\n```js\na = debug('worker:a');\nb = debug('worker:b');\n\nsetInterval(function(){\n a('doing some work');\n}, 1000);\n\nsetInterval(function(){\n a('doing some work');\n}, 1200);\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/debug/issues" - }, - "_id": "debug@0.7.2", - "_from": "debug@*" -} diff --git a/frontend/express/node_modules/express/node_modules/fresh/.npmignore b/frontend/express/node_modules/express/node_modules/fresh/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/express/node_modules/fresh/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/express/node_modules/fresh/Makefile b/frontend/express/node_modules/express/node_modules/fresh/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/express/node_modules/fresh/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/fresh/Readme.md b/frontend/express/node_modules/express/node_modules/fresh/Readme.md deleted file mode 100644 index 273130d4771..00000000000 --- a/frontend/express/node_modules/express/node_modules/fresh/Readme.md +++ /dev/null @@ -1,32 +0,0 @@ - -# node-fresh - - HTTP response freshness testing - -## fresh(req, res) - - Check freshness of `req` and `res` headers. - - When the cache is "fresh" __true__ is returned, - otherwise __false__ is returned to indicate that - the cache is now stale. - -## Example: - -```js -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'luna' }; -fresh(req, res); -// => false - -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'tobi' }; -fresh(req, res); -// => true -``` - -## Installation - -``` -$ npm install fresh -``` \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/fresh/index.js b/frontend/express/node_modules/express/node_modules/fresh/index.js deleted file mode 100644 index b2f4d4132f0..00000000000 --- a/frontend/express/node_modules/express/node_modules/fresh/index.js +++ /dev/null @@ -1,49 +0,0 @@ - -/** - * Expose `fresh()`. - */ - -module.exports = fresh; - -/** - * Check freshness of `req` and `res` headers. - * - * When the cache is "fresh" __true__ is returned, - * otherwise __false__ is returned to indicate that - * the cache is now stale. - * - * @param {Object} req - * @param {Object} res - * @return {Boolean} - * @api public - */ - -function fresh(req, res) { - // defaults - var etagMatches = true; - var notModified = true; - - // fields - var modifiedSince = req['if-modified-since']; - var noneMatch = req['if-none-match']; - var lastModified = res['last-modified']; - var etag = res['etag']; - - // unconditional request - if (!modifiedSince && !noneMatch) return false; - - // parse if-none-match - if (noneMatch) noneMatch = noneMatch.split(/ *, */); - - // if-none-match - if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0]; - - // if-modified-since - if (modifiedSince) { - modifiedSince = new Date(modifiedSince); - lastModified = new Date(lastModified); - notModified = lastModified <= modifiedSince; - } - - return !! (etagMatches && notModified); -} \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/fresh/package.json b/frontend/express/node_modules/express/node_modules/fresh/package.json deleted file mode 100644 index d9fddb20935..00000000000 --- a/frontend/express/node_modules/express/node_modules/fresh/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "fresh", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "HTTP response freshness testing", - "version": "0.1.0", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "readme": "\n# node-fresh\n\n HTTP response freshness testing\n\n## fresh(req, res)\n\n Check freshness of `req` and `res` headers.\n\n When the cache is \"fresh\" __true__ is returned,\n otherwise __false__ is returned to indicate that\n the cache is now stale.\n\n## Example:\n\n```js\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'luna' };\nfresh(req, res);\n// => false\n\nvar req = { 'if-none-match': 'tobi' };\nvar res = { 'etag': 'tobi' };\nfresh(req, res);\n// => true\n```\n\n## Installation\n\n```\n$ npm install fresh\n```", - "readmeFilename": "Readme.md", - "_id": "fresh@0.1.0", - "_from": "fresh@0.1.0" -} diff --git a/frontend/express/node_modules/express/node_modules/methods/index.js b/frontend/express/node_modules/express/node_modules/methods/index.js deleted file mode 100644 index 297d0223331..00000000000 --- a/frontend/express/node_modules/express/node_modules/methods/index.js +++ /dev/null @@ -1,26 +0,0 @@ - -module.exports = [ - 'get' - , 'post' - , 'put' - , 'head' - , 'delete' - , 'options' - , 'trace' - , 'copy' - , 'lock' - , 'mkcol' - , 'move' - , 'propfind' - , 'proppatch' - , 'unlock' - , 'report' - , 'mkactivity' - , 'checkout' - , 'merge' - , 'm-search' - , 'notify' - , 'subscribe' - , 'unsubscribe' - , 'patch' -]; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/methods/package.json b/frontend/express/node_modules/express/node_modules/methods/package.json deleted file mode 100644 index f867a8b575f..00000000000 --- a/frontend/express/node_modules/express/node_modules/methods/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "methods", - "version": "0.0.1", - "description": "HTTP methods that node supports", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [ - "http", - "methods" - ], - "author": { - "name": "TJ Holowaychuk" - }, - "license": "MIT", - "readme": "ERROR: No README data found!", - "_id": "methods@0.0.1", - "_from": "methods@0.0.1" -} diff --git a/frontend/express/node_modules/express/node_modules/mime/LICENSE b/frontend/express/node_modules/express/node_modules/mime/LICENSE deleted file mode 100644 index 451fc4550c2..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Benjamin Thomas, Robert Kieffer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/mime/README.md b/frontend/express/node_modules/express/node_modules/mime/README.md deleted file mode 100644 index a157de1a197..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# mime - -Support for mapping between file extensions and MIME types. This module uses the latest version of the Apache "mime.types" file (maps over 620 types to 800+ extensions). It is also trivially easy to add your own types and extensions, should you need to do that. - -## Install - -Install with [npm](http://github.com/isaacs/npm): - - npm install mime - -## API - Queries - -### mime.lookup(path) -Get the mime type associated with a file. This is method is case-insensitive. Everything in path up to and including the last '/' or '.' is ignored, so you can pass it paths, filenames, or extensions, like so: - - var mime = require('mime'); - - mime.lookup('/path/to/file.txt'); // => 'text/plain' - mime.lookup('file.txt'); // => 'text/plain' - mime.lookup('.txt'); // => 'text/plain' - mime.lookup('htm'); // => 'text/html' - -### mime.extension(type) - lookup the default extension for type - - mime.extension('text/html'); // => 'html' - mime.extension('application/octet-stream'); // => 'bin' - -### mime.charsets.lookup() - map mime-type to charset - - mime.charsets.lookup('text/plain'); // => 'UTF-8' - -(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) - -## API - Customizing - -The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types). -### mime.define() - Add custom mime/extension mappings - - mime.define({ - 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], - 'application/x-my-type': ['x-mt', 'x-mtt'], - // etc ... - }); - - mime.lookup('x-sft'); // => 'text/x-some-format' - mime.extension('text/x-some-format'); // => 'x-sf' - -### mime.load(filepath) - Load mappings from an Apache ".types" format file - - mime.load('./my_project.types'); diff --git a/frontend/express/node_modules/express/node_modules/mime/mime.js b/frontend/express/node_modules/express/node_modules/mime/mime.js deleted file mode 100644 index 5fac753234d..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/mime.js +++ /dev/null @@ -1,92 +0,0 @@ -var path = require('path'), - fs = require('fs'); - -var mime = module.exports = { - /** Map of extension to mime type */ - types: {}, - - /** Map of mime type to extension */ - extensions :{}, - - /** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * @param map (Object) type definitions - */ - define: function(map) { - for (var type in map) { - var exts = map[type]; - - for (var i = 0; i < exts.length; i++) { - mime.types[exts[i]] = type; - } - - // Default extension is the first one we encounter - if (!mime.extensions[type]) { - mime.extensions[type] = exts[0]; - } - } - }, - - /** - * Load an Apache2-style ".types" file - * - * This may be called multiple times (it's expected). Where files declare - * overlapping types/extensions, the last file wins. - * - * @param file (String) path of file to load. - */ - load: function(file) { - // Read file and split into lines - var map = {}, - content = fs.readFileSync(file, 'ascii'), - lines = content.split(/[\r\n]+/); - - lines.forEach(function(line, lineno) { - // Clean up whitespace/comments, and split into fields - var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); - map[fields.shift()] = fields; - }); - - mime.define(map); - }, - - /** - * Lookup a mime type based on extension - */ - lookup: function(path, fallback) { - var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); - return mime.types[ext] || fallback || mime.default_type; - }, - - /** - * Return file extension associated with a mime type - */ - extension: function(mimeType) { - return mime.extensions[mimeType]; - }, - - /** - * Lookup a charset based on mime type. - */ - charsets: { - lookup: function (mimeType, fallback) { - // Assume text types are utf8. Modify mime logic as needed. - return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; - } - } -}; - -// Load our local copy of -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -mime.load(path.join(__dirname, 'types/mime.types')); - -// Overlay enhancements submitted by the node.js community -mime.load(path.join(__dirname, 'types/node.types')); - -// Set the default type -mime.default_type = mime.types.bin; diff --git a/frontend/express/node_modules/express/node_modules/mime/package.json b/frontend/express/node_modules/express/node_modules/mime/package.json deleted file mode 100644 index a82def2d270..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "dependencies": {}, - "description": "A comprehensive library for mime-type mapping", - "devDependencies": { - "async_testing": "" - }, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "git://github.com/bentomas/node-mime.git", - "type": "git" - }, - "version": "1.2.4", - "_id": "mime@1.2.4", - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "_engineSupported": true, - "_npmVersion": "1.1.21", - "_nodeVersion": "v0.6.18", - "_defaultsLoaded": true, - "dist": { - "shasum": "f89f56d7a748089295dae8497a20fdf467ab3fc3" - }, - "_from": "mime@1.2.4" -} diff --git a/frontend/express/node_modules/express/node_modules/mime/test.js b/frontend/express/node_modules/express/node_modules/mime/test.js deleted file mode 100644 index b904895417e..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/test.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Requires the async_testing module - * - * Usage: node test.js - */ -var mime = require('./mime'); -exports["test mime lookup"] = function(test) { - // easy - test.equal('text/plain', mime.lookup('text.txt')); - - // hidden file or multiple periods - test.equal('text/plain', mime.lookup('.text.txt')); - - // just an extension - test.equal('text/plain', mime.lookup('.txt')); - - // just an extension without a dot - test.equal('text/plain', mime.lookup('txt')); - - // default - test.equal('application/octet-stream', mime.lookup('text.nope')); - - // fallback - test.equal('fallback', mime.lookup('text.fallback', 'fallback')); - - test.finish(); -}; - -exports["test extension lookup"] = function(test) { - // easy - test.equal('txt', mime.extension(mime.types.text)); - test.equal('html', mime.extension(mime.types.htm)); - test.equal('bin', mime.extension('application/octet-stream')); - - test.finish(); -}; - -exports["test mime lookup uppercase"] = function(test) { - // easy - test.equal('text/plain', mime.lookup('TEXT.TXT')); - - // just an extension - test.equal('text/plain', mime.lookup('.TXT')); - - // just an extension without a dot - test.equal('text/plain', mime.lookup('TXT')); - - // default - test.equal('application/octet-stream', mime.lookup('TEXT.NOPE')); - - // fallback - test.equal('fallback', mime.lookup('TEXT.FALLBACK', 'fallback')); - - test.finish(); -}; - -exports["test custom types"] = function(test) { - test.equal('application/octet-stream', mime.lookup('file.buffer')); - test.equal('audio/mp4', mime.lookup('file.m4a')); - - test.finish(); -}; - -exports["test charset lookup"] = function(test) { - // easy - test.equal('UTF-8', mime.charsets.lookup('text/plain')); - - // none - test.ok(typeof mime.charsets.lookup(mime.types.js) == 'undefined'); - - // fallback - test.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); - - test.finish(); -}; - -if (module == require.main) { - require('async_testing').run(__filename, process.ARGV); -} diff --git a/frontend/express/node_modules/express/node_modules/mime/types/mime.types b/frontend/express/node_modules/express/node_modules/mime/types/mime.types deleted file mode 100644 index 6a90929c0d2..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/types/mime.types +++ /dev/null @@ -1,1479 +0,0 @@ -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/cals-1840 -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/onenote onetoc onetoc2 onetmp onepkg -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -application/vnd.hzn-3d-crossword x3d -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.packageitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.route66.link66+xml link66 -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cdlink vcd -application/x-chat chat -application/x-chess-pgn pgn -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff -# application/x-font-vfont -application/x-futuresplash spl -application/x-gnumeric gnumeric -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-stuffit sit -application/x-stuffitx sitx -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xpinstall xpi -# application/x400-bp -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -audio/ogg oga ogg spx -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -audio/x-wav wav -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-pascal p pas -text/x-java-source java -text/x-setext etx -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-ms-asf asf asx -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/frontend/express/node_modules/express/node_modules/mime/types/node.types b/frontend/express/node_modules/express/node_modules/mime/types/node.types deleted file mode 100644 index fdabaa433e1..00000000000 --- a/frontend/express/node_modules/express/node_modules/mime/types/node.types +++ /dev/null @@ -1,43 +0,0 @@ -# What: Google Chrome Extension -# Why: To allow apps to (work) be served with the right content type header. -# http://codereview.chromium.org/2830017 -# Added by: niftylettuce -application/x-chrome-extension crx - -# What: OTF Message Silencer -# Why: To silence the "Resource interpreted as font but transferred with MIME -# type font/otf" message that occurs in Google Chrome -# Added by: niftylettuce -font/opentype otf - -# What: HTC support -# Why: To properly render .htc files such as CSS3PIE -# Added by: niftylettuce -text/x-component htc - -# What: HTML5 application cache manifest -# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps -# per https://developer.mozilla.org/en/offline_resources_in_firefox -# Added by: louisremi -text/cache-manifest appcache manifest - -# What: node binary buffer format -# Why: semi-standard extension w/in the node community -# Added by: tootallnate -application/octet-stream buffer - -# What: The "protected" MP-4 formats used by iTunes. -# Why: Required for streaming music to browsers (?) -# Added by: broofa -application/mp4 m4p -audio/mp4 m4a - -# What: Music playlist format (http://en.wikipedia.org/wiki/M3U) -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -application/x-mpegURL m3u8 - -# What: Video format, Part of RFC1890 -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -video/MP2T ts diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.orig b/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.orig deleted file mode 100644 index 9303c347ee6..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.orig +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -npm-debug.log \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.rej b/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.rej deleted file mode 100644 index 69244ff8773..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/.gitignore.rej +++ /dev/null @@ -1,5 +0,0 @@ ---- /dev/null -+++ .gitignore -@@ -0,0 +1,2 @@ -+node_modules/ -+npm-debug.log \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/.npmignore b/frontend/express/node_modules/express/node_modules/mkdirp/.npmignore deleted file mode 100644 index 9303c347ee6..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -npm-debug.log \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/.travis.yml b/frontend/express/node_modules/express/node_modules/mkdirp/.travis.yml deleted file mode 100644 index f1d0f13c8a5..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.4 - - 0.6 diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/LICENSE b/frontend/express/node_modules/express/node_modules/mkdirp/LICENSE deleted file mode 100644 index 432d1aeb01d..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright 2010 James Halliday (mail@substack.net) - -This project is free software released under the MIT/X11 license: - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/README.markdown b/frontend/express/node_modules/express/node_modules/mkdirp/README.markdown deleted file mode 100644 index 40de04f71e1..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/README.markdown +++ /dev/null @@ -1,61 +0,0 @@ -mkdirp -====== - -Like `mkdir -p`, but in node.js! - -[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp) - -example -======= - -pow.js ------- - var mkdirp = require('mkdirp'); - - mkdirp('/tmp/foo/bar/baz', function (err) { - if (err) console.error(err) - else console.log('pow!') - }); - -Output - pow! - -And now /tmp/foo/bar/baz exists, huzzah! - -methods -======= - -var mkdirp = require('mkdirp'); - -mkdirp(dir, mode, cb) ---------------------- - -Create a new directory and any necessary subdirectories at `dir` with octal -permission string `mode`. - -If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. - -`cb(err, made)` fires with the error or the first directory `made` -that had to be created, if any. - -mkdirp.sync(dir, mode) ----------------------- - -Synchronously create a new directory and any necessary subdirectories at `dir` -with octal permission string `mode`. - -If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. - -Returns the first directory that had to be created, if any. - -install -======= - -With [npm](http://npmjs.org) do: - - npm install mkdirp - -license -======= - -MIT/X11 diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js b/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js deleted file mode 100644 index e6924212e6a..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js +++ /dev/null @@ -1,6 +0,0 @@ -var mkdirp = require('mkdirp'); - -mkdirp('/tmp/foo/bar/baz', function (err) { - if (err) console.error(err) - else console.log('pow!') -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.orig b/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.orig deleted file mode 100644 index 77414622120..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.orig +++ /dev/null @@ -1,6 +0,0 @@ -var mkdirp = require('mkdirp'); - -mkdirp('/tmp/foo/bar/baz', 0755, function (err) { - if (err) console.error(err) - else console.log('pow!') -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.rej b/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.rej deleted file mode 100644 index 81e7f431156..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/examples/pow.js.rej +++ /dev/null @@ -1,19 +0,0 @@ ---- examples/pow.js -+++ examples/pow.js -@@ -1,6 +1,15 @@ --var mkdirp = require('mkdirp').mkdirp; -+var mkdirp = require('../').mkdirp, -+ mkdirpSync = require('../').mkdirpSync; - - mkdirp('/tmp/foo/bar/baz', 0755, function (err) { - if (err) console.error(err) - else console.log('pow!') - }); -+ -+try { -+ mkdirpSync('/tmp/bar/foo/baz', 0755); -+ console.log('double pow!'); -+} -+catch (ex) { -+ console.log(ex); -+} \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/index.js b/frontend/express/node_modules/express/node_modules/mkdirp/index.js deleted file mode 100644 index fda6de8a2c2..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/index.js +++ /dev/null @@ -1,82 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; - -function mkdirP (p, mode, f, made) { - if (typeof mode === 'function' || mode === undefined) { - f = mode; - mode = 0777 & (~process.umask()); - } - if (!made) made = null; - - var cb = f || function () {}; - if (typeof mode === 'string') mode = parseInt(mode, 8); - p = path.resolve(p); - - fs.mkdir(p, mode, function (er) { - if (!er) { - made = made || p; - return cb(null, made); - } - switch (er.code) { - case 'ENOENT': - mkdirP(path.dirname(p), mode, function (er, made) { - if (er) cb(er, made); - else mkdirP(p, mode, cb, made); - }); - break; - - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - fs.stat(p, function (er2, stat) { - // if the stat fails, then that's super weird. - // let the original error be the failure reason. - if (er2 || !stat.isDirectory()) cb(er, made) - else cb(null, made); - }); - break; - } - }); -} - -mkdirP.sync = function sync (p, mode, made) { - if (mode === undefined) { - mode = 0777 & (~process.umask()); - } - if (!made) made = null; - - if (typeof mode === 'string') mode = parseInt(mode, 8); - p = path.resolve(p); - - try { - fs.mkdirSync(p, mode); - made = made || p; - } - catch (err0) { - switch (err0.code) { - case 'ENOENT' : - made = sync(path.dirname(p), mode, made); - sync(p, mode, made); - break; - - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - var stat; - try { - stat = fs.statSync(p); - } - catch (err1) { - throw err0; - } - if (!stat.isDirectory()) throw err0; - break; - } - } - - return made; -}; diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/package.json b/frontend/express/node_modules/express/node_modules/mkdirp/package.json deleted file mode 100644 index 64955a28e4d..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "mkdirp", - "description": "Recursively mkdir, like `mkdir -p`", - "version": "0.3.4", - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "main": "./index", - "keywords": [ - "mkdir", - "directory" - ], - "repository": { - "type": "git", - "url": "http://github.com/substack/node-mkdirp.git" - }, - "scripts": { - "test": "tap test/*.js" - }, - "devDependencies": { - "tap": "~0.2.4" - }, - "license": "MIT/X11", - "engines": { - "node": "*" - }, - "readme": "mkdirp\n======\n\nLike `mkdir -p`, but in node.js!\n\n[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)\n\nexample\n=======\n\npow.js\n------\n var mkdirp = require('mkdirp');\n \n mkdirp('/tmp/foo/bar/baz', function (err) {\n if (err) console.error(err)\n else console.log('pow!')\n });\n\nOutput\n pow!\n\nAnd now /tmp/foo/bar/baz exists, huzzah!\n\nmethods\n=======\n\nvar mkdirp = require('mkdirp');\n\nmkdirp(dir, mode, cb)\n---------------------\n\nCreate a new directory and any necessary subdirectories at `dir` with octal\npermission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\n`cb(err, made)` fires with the error or the first directory `made`\nthat had to be created, if any.\n\nmkdirp.sync(dir, mode)\n----------------------\n\nSynchronously create a new directory and any necessary subdirectories at `dir`\nwith octal permission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\nReturns the first directory that had to be created, if any.\n\ninstall\n=======\n\nWith [npm](http://npmjs.org) do:\n\n npm install mkdirp\n\nlicense\n=======\n\nMIT/X11\n", - "readmeFilename": "README.markdown", - "bugs": { - "url": "https://github.com/substack/node-mkdirp/issues" - }, - "_id": "mkdirp@0.3.4", - "_from": "mkdirp@0.3.4" -} diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/chmod.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/chmod.js deleted file mode 100644 index 520dcb8e9b5..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/chmod.js +++ /dev/null @@ -1,38 +0,0 @@ -var mkdirp = require('../').mkdirp; -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -var ps = [ '', 'tmp' ]; - -for (var i = 0; i < 25; i++) { - var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - ps.push(dir); -} - -var file = ps.join('/'); - -test('chmod-pre', function (t) { - var mode = 0744 - mkdirp(file, mode, function (er) { - t.ifError(er, 'should not error'); - fs.stat(file, function (er, stat) { - t.ifError(er, 'should exist'); - t.ok(stat && stat.isDirectory(), 'should be directory'); - t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); - t.end(); - }); - }); -}); - -test('chmod', function (t) { - var mode = 0755 - mkdirp(file, mode, function (er) { - t.ifError(er, 'should not error'); - fs.stat(file, function (er, stat) { - t.ifError(er, 'should exist'); - t.ok(stat && stat.isDirectory(), 'should be directory'); - t.end(); - }); - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/clobber.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/clobber.js deleted file mode 100644 index 0eb70998700..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/clobber.js +++ /dev/null @@ -1,37 +0,0 @@ -var mkdirp = require('../').mkdirp; -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -var ps = [ '', 'tmp' ]; - -for (var i = 0; i < 25; i++) { - var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - ps.push(dir); -} - -var file = ps.join('/'); - -// a file in the way -var itw = ps.slice(0, 3).join('/'); - - -test('clobber-pre', function (t) { - console.error("about to write to "+itw) - fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); - - fs.stat(itw, function (er, stat) { - t.ifError(er) - t.ok(stat && stat.isFile(), 'should be file') - t.end() - }) -}) - -test('clobber', function (t) { - t.plan(2); - mkdirp(file, 0755, function (err) { - t.ok(err); - t.equal(err.code, 'ENOTDIR'); - t.end(); - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/mkdirp.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/mkdirp.js deleted file mode 100644 index b07cd70c109..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/mkdirp.js +++ /dev/null @@ -1,28 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('woo', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - mkdirp(file, 0755, function (err) { - if (err) t.fail(err); - else path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }) - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/perm.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/perm.js deleted file mode 100644 index 23a7abbd232..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/perm.js +++ /dev/null @@ -1,32 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('async perm', function (t) { - t.plan(2); - var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); - - mkdirp(file, 0755, function (err) { - if (err) t.fail(err); - else path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }) - }); -}); - -test('async root perm', function (t) { - mkdirp('/tmp', 0755, function (err) { - if (err) t.fail(err); - t.end(); - }); - t.end(); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/perm_sync.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/perm_sync.js deleted file mode 100644 index f685f609069..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/perm_sync.js +++ /dev/null @@ -1,39 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('sync perm', function (t) { - t.plan(2); - var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; - - mkdirp.sync(file, 0755); - path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }); -}); - -test('sync root perm', function (t) { - t.plan(1); - - var file = '/tmp'; - mkdirp.sync(file, 0755); - path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/race.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/race.js deleted file mode 100644 index 96a04476365..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/race.js +++ /dev/null @@ -1,41 +0,0 @@ -var mkdirp = require('../').mkdirp; -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('race', function (t) { - t.plan(4); - var ps = [ '', 'tmp' ]; - - for (var i = 0; i < 25; i++) { - var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - ps.push(dir); - } - var file = ps.join('/'); - - var res = 2; - mk(file, function () { - if (--res === 0) t.end(); - }); - - mk(file, function () { - if (--res === 0) t.end(); - }); - - function mk (file, cb) { - mkdirp(file, 0755, function (err) { - if (err) t.fail(err); - else path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - if (cb) cb(); - } - }) - }) - }); - } -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/rel.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/rel.js deleted file mode 100644 index 79858243ab9..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/rel.js +++ /dev/null @@ -1,32 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('rel', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var cwd = process.cwd(); - process.chdir('/tmp'); - - var file = [x,y,z].join('/'); - - mkdirp(file, 0755, function (err) { - if (err) t.fail(err); - else path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - process.chdir(cwd); - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }) - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/return.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/return.js deleted file mode 100644 index bce68e5613e..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/return.js +++ /dev/null @@ -1,25 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('return value', function (t) { - t.plan(4); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - // should return the first dir created. - // By this point, it would be profoundly surprising if /tmp didn't - // already exist, since every other test makes things in there. - mkdirp(file, function (err, made) { - t.ifError(err); - t.equal(made, '/tmp/' + x); - mkdirp(file, function (err, made) { - t.ifError(err); - t.equal(made, null); - }); - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/return_sync.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/return_sync.js deleted file mode 100644 index 7c222d3558d..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/return_sync.js +++ /dev/null @@ -1,24 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('return value', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - // should return the first dir created. - // By this point, it would be profoundly surprising if /tmp didn't - // already exist, since every other test makes things in there. - // Note that this will throw on failure, which will fail the test. - var made = mkdirp.sync(file); - t.equal(made, '/tmp/' + x); - - // making the same file again should have no effect. - made = mkdirp.sync(file); - t.equal(made, null); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/root.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/root.js deleted file mode 100644 index 97ad7a2f358..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/root.js +++ /dev/null @@ -1,18 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('root', function (t) { - // '/' on unix, 'c:/' on windows. - var file = path.resolve('/'); - - mkdirp(file, 0755, function (err) { - if (err) throw err - fs.stat(file, function (er, stat) { - if (er) throw er - t.ok(stat.isDirectory(), 'target is a directory'); - t.end(); - }) - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/sync.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/sync.js deleted file mode 100644 index 7530cada84c..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/sync.js +++ /dev/null @@ -1,32 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('sync', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - try { - mkdirp.sync(file, 0755); - } catch (err) { - t.fail(err); - return t.end(); - } - - path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0755); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }); - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/umask.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/umask.js deleted file mode 100644 index 64ccafe22bc..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/umask.js +++ /dev/null @@ -1,28 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('implicit mode from umask', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - mkdirp(file, function (err) { - if (err) t.fail(err); - else path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, 0777 & (~process.umask())); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }) - }) - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/mkdirp/test/umask_sync.js b/frontend/express/node_modules/express/node_modules/mkdirp/test/umask_sync.js deleted file mode 100644 index 35bd5cbbf41..00000000000 --- a/frontend/express/node_modules/express/node_modules/mkdirp/test/umask_sync.js +++ /dev/null @@ -1,32 +0,0 @@ -var mkdirp = require('../'); -var path = require('path'); -var fs = require('fs'); -var test = require('tap').test; - -test('umask sync modes', function (t) { - t.plan(2); - var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); - - var file = '/tmp/' + [x,y,z].join('/'); - - try { - mkdirp.sync(file); - } catch (err) { - t.fail(err); - return t.end(); - } - - path.exists(file, function (ex) { - if (!ex) t.fail('file not created') - else fs.stat(file, function (err, stat) { - if (err) t.fail(err) - else { - t.equal(stat.mode & 0777, (0777 & (~process.umask()))); - t.ok(stat.isDirectory(), 'target not a directory'); - t.end(); - } - }); - }); -}); diff --git a/frontend/express/node_modules/express/node_modules/qs/.gitmodules b/frontend/express/node_modules/express/node_modules/qs/.gitmodules deleted file mode 100644 index 49e31dac7d7..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "support/expresso"] - path = support/expresso - url = git://github.com/visionmedia/expresso.git -[submodule "support/should"] - path = support/should - url = git://github.com/visionmedia/should.js.git diff --git a/frontend/express/node_modules/express/node_modules/qs/.npmignore b/frontend/express/node_modules/express/node_modules/qs/.npmignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/frontend/express/node_modules/express/node_modules/qs/.travis.yml b/frontend/express/node_modules/express/node_modules/qs/.travis.yml deleted file mode 100644 index 2c0a8f63f4f..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.4 \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/History.md b/frontend/express/node_modules/express/node_modules/qs/History.md deleted file mode 100644 index 3eaf7dfdc75..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/History.md +++ /dev/null @@ -1,73 +0,0 @@ - -0.4.2 / 2012-02-08 -================== - - * Fixed: ensure objects are created when appropriate not arrays [aheckmann] - -0.4.1 / 2012-01-26 -================== - - * Fixed stringify()ing numbers. Closes #23 - -0.4.0 / 2011-11-21 -================== - - * Allow parsing of an existing object (for `bodyParser()`) [jackyz] - * Replaced expresso with mocha - -0.3.2 / 2011-11-08 -================== - - * Fixed global variable leak - -0.3.1 / 2011-08-17 -================== - - * Added `try/catch` around malformed uri components - * Add test coverage for Array native method bleed-though - -0.3.0 / 2011-07-19 -================== - - * Allow `array[index]` and `object[property]` syntaxes [Aria Stewart] - -0.2.0 / 2011-06-29 -================== - - * Added `qs.stringify()` [Cory Forsyth] - -0.1.0 / 2011-04-13 -================== - - * Added jQuery-ish array support - -0.0.7 / 2011-03-13 -================== - - * Fixed; handle empty string and `== null` in `qs.parse()` [dmit] - allows for convenient `qs.parse(url.parse(str).query)` - -0.0.6 / 2011-02-14 -================== - - * Fixed; support for implicit arrays - -0.0.4 / 2011-02-09 -================== - - * Fixed `+` as a space - -0.0.3 / 2011-02-08 -================== - - * Fixed case when right-hand value contains "]" - -0.0.2 / 2011-02-07 -================== - - * Fixed "=" presence in key - -0.0.1 / 2011-02-07 -================== - - * Initial release \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/Makefile b/frontend/express/node_modules/express/node_modules/qs/Makefile deleted file mode 100644 index e4df8370490..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - -test: - @./node_modules/.bin/mocha - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/Readme.md b/frontend/express/node_modules/express/node_modules/qs/Readme.md deleted file mode 100644 index db0d14548af..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/Readme.md +++ /dev/null @@ -1,54 +0,0 @@ -# node-querystring - - query string parser for node supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. - -## Installation - - $ npm install qs - -## Examples - -```js -var qs = require('qs'); - -qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); -// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } - -qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) -// => user[name]=Tobi&user[email]=tobi%40learnboost.com -``` - -## Testing - -Install dev dependencies: - - $ npm install -d - -and execute: - - $ make test - -## License - -(The MIT License) - -Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/benchmark.js b/frontend/express/node_modules/express/node_modules/qs/benchmark.js deleted file mode 100644 index 97e2c93ed0f..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/benchmark.js +++ /dev/null @@ -1,17 +0,0 @@ - -var qs = require('./'); - -var times = 100000 - , start = new Date - , n = times; - -console.log('times: %d', times); - -while (n--) qs.parse('foo=bar'); -console.log('simple: %dms', new Date - start); - -var start = new Date - , n = times; - -while (n--) qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); -console.log('nested: %dms', new Date - start); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/examples.js b/frontend/express/node_modules/express/node_modules/qs/examples.js deleted file mode 100644 index 27617b75f0d..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/examples.js +++ /dev/null @@ -1,51 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('./'); - -var obj = qs.parse('foo'); -console.log(obj) - -var obj = qs.parse('foo=bar=baz'); -console.log(obj) - -var obj = qs.parse('users[]'); -console.log(obj) - -var obj = qs.parse('name=tj&email=tj@vision-media.ca'); -console.log(obj) - -var obj = qs.parse('users[]=tj&users[]=tobi&users[]=jane'); -console.log(obj) - -var obj = qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'); -console.log(obj) - -var obj = qs.parse('users[][name][first]=tj&users[][name][last]=holowaychuk'); -console.log(obj) - -var obj = qs.parse('a=a&a=b&a=c'); -console.log(obj) - -var obj = qs.parse('user[tj]=tj&user[tj]=TJ'); -console.log(obj) - -var obj = qs.parse('user[names]=tj&user[names]=TJ&user[names]=Tyler'); -console.log(obj) - -var obj = qs.parse('user[name][first]=tj&user[name][first]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[1]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[]=TJ'); -console.log(obj) - -var obj = qs.parse('user[0]=tj&user[foo]=TJ'); -console.log(obj) - -var str = qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}); -console.log(str); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/index.js b/frontend/express/node_modules/express/node_modules/qs/index.js deleted file mode 100644 index d177d209b7b..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/querystring'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/qs/lib/querystring.js b/frontend/express/node_modules/express/node_modules/qs/lib/querystring.js deleted file mode 100644 index 6c727120a72..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/lib/querystring.js +++ /dev/null @@ -1,264 +0,0 @@ - -/*! - * querystring - * Copyright(c) 2010 TJ Holowaychuk - * MIT Licensed - */ - -/** - * Library version. - */ - -exports.version = '0.4.2'; - -/** - * Object#toString() ref for stringify(). - */ - -var toString = Object.prototype.toString; - -/** - * Cache non-integer test regexp. - */ - -var isint = /^[0-9]+$/; - -function promote(parent, key) { - if (parent[key].length == 0) return parent[key] = {}; - var t = {}; - for (var i in parent[key]) t[i] = parent[key][i]; - parent[key] = t; - return t; -} - -function parse(parts, parent, key, val) { - var part = parts.shift(); - // end - if (!part) { - if (Array.isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } - // array - } else { - var obj = parent[key] = parent[key] || []; - if (']' == part) { - if (Array.isArray(obj)) { - if ('' != val) obj.push(val); - } else if ('object' == typeof obj) { - obj[Object.keys(obj).length] = val; - } else { - obj = parent[key] = [parent[key], val]; - } - // prop - } else if (~part.indexOf(']')) { - part = part.substr(0, part.length - 1); - if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - // key - } else { - if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - } - } -} - -/** - * Merge parent key/val pair. - */ - -function merge(parent, key, val){ - if (~key.indexOf(']')) { - var parts = key.split('[') - , len = parts.length - , last = len - 1; - parse(parts, parent, 'base', val); - // optimize - } else { - if (!isint.test(key) && Array.isArray(parent.base)) { - var t = {}; - for (var k in parent.base) t[k] = parent.base[k]; - parent.base = t; - } - set(parent.base, key, val); - } - - return parent; -} - -/** - * Parse the given obj. - */ - -function parseObject(obj){ - var ret = { base: {} }; - Object.keys(obj).forEach(function(name){ - merge(ret, name, obj[name]); - }); - return ret.base; -} - -/** - * Parse the given str. - */ - -function parseString(str){ - return String(str) - .split('&') - .reduce(function(ret, pair){ - try{ - pair = decodeURIComponent(pair.replace(/\+/g, ' ')); - } catch(e) { - // ignore - } - - var eql = pair.indexOf('=') - , brace = lastBraceInKey(pair) - , key = pair.substr(0, brace || eql) - , val = pair.substr(brace || eql, pair.length) - , val = val.substr(val.indexOf('=') + 1, val.length); - - // ?foo - if ('' == key) key = pair, val = ''; - - return merge(ret, key, val); - }, { base: {} }).base; -} - -/** - * Parse the given query `str` or `obj`, returning an object. - * - * @param {String} str | {Object} obj - * @return {Object} - * @api public - */ - -exports.parse = function(str){ - if (null == str || '' == str) return {}; - return 'object' == typeof str - ? parseObject(str) - : parseString(str); -}; - -/** - * Turn the given `obj` into a query string - * - * @param {Object} obj - * @return {String} - * @api public - */ - -var stringify = exports.stringify = function(obj, prefix) { - if (Array.isArray(obj)) { - return stringifyArray(obj, prefix); - } else if ('[object Object]' == toString.call(obj)) { - return stringifyObject(obj, prefix); - } else if ('string' == typeof obj) { - return stringifyString(obj, prefix); - } else { - return prefix + '=' + obj; - } -}; - -/** - * Stringify the given `str`. - * - * @param {String} str - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyString(str, prefix) { - if (!prefix) throw new TypeError('stringify expects an object'); - return prefix + '=' + encodeURIComponent(str); -} - -/** - * Stringify the given `arr`. - * - * @param {Array} arr - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyArray(arr, prefix) { - var ret = []; - if (!prefix) throw new TypeError('stringify expects an object'); - for (var i = 0; i < arr.length; i++) { - ret.push(stringify(arr[i], prefix + '[]')); - } - return ret.join('&'); -} - -/** - * Stringify the given `obj`. - * - * @param {Object} obj - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyObject(obj, prefix) { - var ret = [] - , keys = Object.keys(obj) - , key; - - for (var i = 0, len = keys.length; i < len; ++i) { - key = keys[i]; - ret.push(stringify(obj[key], prefix - ? prefix + '[' + encodeURIComponent(key) + ']' - : encodeURIComponent(key))); - } - - return ret.join('&'); -} - -/** - * Set `obj`'s `key` to `val` respecting - * the weird and wonderful syntax of a qs, - * where "foo=bar&foo=baz" becomes an array. - * - * @param {Object} obj - * @param {String} key - * @param {String} val - * @api private - */ - -function set(obj, key, val) { - var v = obj[key]; - if (undefined === v) { - obj[key] = val; - } else if (Array.isArray(v)) { - v.push(val); - } else { - obj[key] = [v, val]; - } -} - -/** - * Locate last brace in `str` within the key. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function lastBraceInKey(str) { - var len = str.length - , brace - , c; - for (var i = 0; i < len; ++i) { - c = str[i]; - if (']' == c) brace = false; - if ('[' == c) brace = true; - if ('=' == c && !brace) return i; - } -} diff --git a/frontend/express/node_modules/express/node_modules/qs/package.json b/frontend/express/node_modules/express/node_modules/qs/package.json deleted file mode 100644 index 365a37edc89..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "qs", - "description": "querystring parser", - "version": "0.4.2", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/node-querystring.git" - }, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "main": "index", - "engines": { - "node": "*" - }, - "_id": "qs@0.4.2", - "dependencies": {}, - "optionalDependencies": {}, - "_engineSupported": true, - "_npmVersion": "1.1.21", - "_nodeVersion": "v0.6.18", - "_defaultsLoaded": true, - "dist": { - "shasum": "ac358b56a29d0be5f640338873707bdd1d341d5c" - }, - "_from": "qs@0.4.x" -} diff --git a/frontend/express/node_modules/express/node_modules/qs/test/mocha.opts b/frontend/express/node_modules/express/node_modules/qs/test/mocha.opts deleted file mode 100644 index 521cbb23543..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/test/mocha.opts +++ /dev/null @@ -1,2 +0,0 @@ ---require should ---ui exports diff --git a/frontend/express/node_modules/express/node_modules/qs/test/parse.js b/frontend/express/node_modules/express/node_modules/qs/test/parse.js deleted file mode 100644 index f219e27a276..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/test/parse.js +++ /dev/null @@ -1,167 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('../'); - -module.exports = { - 'test basics': function(){ - qs.parse('0=foo').should.eql({ '0': 'foo' }); - - qs.parse('foo=c++') - .should.eql({ foo: 'c ' }); - - qs.parse('a[>=]=23') - .should.eql({ a: { '>=': '23' }}); - - qs.parse('a[<=>]==23') - .should.eql({ a: { '<=>': '=23' }}); - - qs.parse('a[==]=23') - .should.eql({ a: { '==': '23' }}); - - qs.parse('foo') - .should.eql({ foo: '' }); - - qs.parse('foo=bar') - .should.eql({ foo: 'bar' }); - - qs.parse('foo%3Dbar=baz') - .should.eql({ foo: 'bar=baz' }); - - qs.parse(' foo = bar = baz ') - .should.eql({ ' foo ': ' bar = baz ' }); - - qs.parse('foo=bar=baz') - .should.eql({ foo: 'bar=baz' }); - - qs.parse('foo=bar&bar=baz') - .should.eql({ foo: 'bar', bar: 'baz' }); - - qs.parse('foo=bar&baz') - .should.eql({ foo: 'bar', baz: '' }); - - qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World') - .should.eql({ - cht: 'p3' - , chd: 't:60,40' - , chs: '250x100' - , chl: 'Hello|World' - }); - }, - - 'test nesting': function(){ - qs.parse('ops[>=]=25') - .should.eql({ ops: { '>=': '25' }}); - - qs.parse('user[name]=tj') - .should.eql({ user: { name: 'tj' }}); - - qs.parse('user[name][first]=tj&user[name][last]=holowaychuk') - .should.eql({ user: { name: { first: 'tj', last: 'holowaychuk' }}}); - }, - - 'test escaping': function(){ - qs.parse('foo=foo%20bar') - .should.eql({ foo: 'foo bar' }); - }, - - 'test arrays': function(){ - qs.parse('images[]') - .should.eql({ images: [] }); - - qs.parse('user[]=tj') - .should.eql({ user: ['tj'] }); - - qs.parse('user[]=tj&user[]=tobi&user[]=jane') - .should.eql({ user: ['tj', 'tobi', 'jane'] }); - - qs.parse('user[names][]=tj&user[names][]=tyler') - .should.eql({ user: { names: ['tj', 'tyler'] }}); - - qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca') - .should.eql({ user: { names: ['tj', 'tyler'], email: 'tj@vision-media.ca' }}); - - qs.parse('items=a&items=b') - .should.eql({ items: ['a', 'b'] }); - - qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ') - .should.eql({ user: { names: ['tj', 'holowaychuk', 'TJ'] }}); - - qs.parse('user[name][first]=tj&user[name][first]=TJ') - .should.eql({ user: { name: { first: ['tj', 'TJ'] }}}); - - var o = qs.parse('existing[fcbaebfecc][name][last]=tj') - o.should.eql({ existing: { 'fcbaebfecc': { name: { last: 'tj' }}}}) - Array.isArray(o.existing).should.be.false; - }, - - 'test right-hand brackets': function(){ - qs.parse('pets=["tobi"]') - .should.eql({ pets: '["tobi"]' }); - - qs.parse('operators=[">=", "<="]') - .should.eql({ operators: '[">=", "<="]' }); - - qs.parse('op[>=]=[1,2,3]') - .should.eql({ op: { '>=': '[1,2,3]' }}); - - qs.parse('op[>=]=[1,2,3]&op[=]=[[[[1]]]]') - .should.eql({ op: { '>=': '[1,2,3]', '=': '[[[[1]]]]' }}); - }, - - 'test duplicates': function(){ - qs.parse('items=bar&items=baz&items=raz') - .should.eql({ items: ['bar', 'baz', 'raz'] }); - }, - - 'test empty': function(){ - qs.parse('').should.eql({}); - qs.parse(undefined).should.eql({}); - qs.parse(null).should.eql({}); - }, - - 'test arrays with indexes': function(){ - qs.parse('foo[0]=bar&foo[1]=baz').should.eql({ foo: ['bar', 'baz'] }); - qs.parse('foo[1]=bar&foo[0]=baz').should.eql({ foo: ['baz', 'bar'] }); - qs.parse('foo[base64]=RAWR').should.eql({ foo: { base64: 'RAWR' }}); - qs.parse('foo[64base]=RAWR').should.eql({ foo: { '64base': 'RAWR' }}); - }, - - 'test arrays becoming objects': function(){ - qs.parse('foo[0]=bar&foo[bad]=baz').should.eql({ foo: { 0: "bar", bad: "baz" }}); - qs.parse('foo[bad]=baz&foo[0]=bar').should.eql({ foo: { 0: "bar", bad: "baz" }}); - }, - - 'test bleed-through of Array native properties/methods': function(){ - Array.prototype.protoProperty = true; - Array.prototype.protoFunction = function () {}; - qs.parse('foo=bar').should.eql({ foo: 'bar' }); - }, - - 'test malformed uri': function(){ - qs.parse('{%:%}').should.eql({ '{%:%}': '' }); - qs.parse('foo=%:%}').should.eql({ 'foo': '%:%}' }); - }, - - 'test semi-parsed': function(){ - qs.parse({ 'user[name]': 'tobi' }) - .should.eql({ user: { name: 'tobi' }}); - - qs.parse({ 'user[name]': 'tobi', 'user[email][main]': 'tobi@lb.com' }) - .should.eql({ user: { name: 'tobi', email: { main: 'tobi@lb.com' } }}); - } - - // 'test complex': function(){ - // qs.parse('users[][name][first]=tj&users[foo]=bar') - // .should.eql({ - // users: [ { name: 'tj' }, { name: 'tobi' }, { foo: 'bar' }] - // }); - // - // qs.parse('users[][name][first]=tj&users[][name][first]=tobi') - // .should.eql({ - // users: [ { name: 'tj' }, { name: 'tobi' }] - // }); - // } -}; diff --git a/frontend/express/node_modules/express/node_modules/qs/test/stringify.js b/frontend/express/node_modules/express/node_modules/qs/test/stringify.js deleted file mode 100644 index c2195cbca07..00000000000 --- a/frontend/express/node_modules/express/node_modules/qs/test/stringify.js +++ /dev/null @@ -1,103 +0,0 @@ - -/** - * Module dependencies. - */ - -var qs = require('../') - , should = require('should') - , str_identities = { - 'basics': [ - { str: 'foo=bar', obj: {'foo' : 'bar'}}, - { str: 'foo=%22bar%22', obj: {'foo' : '\"bar\"'}}, - { str: 'foo=', obj: {'foo': ''}}, - { str: 'foo=1&bar=2', obj: {'foo' : '1', 'bar' : '2'}}, - { str: 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F', obj: {'my weird field': "q1!2\"'w$5&7/z8)?"}}, - { str: 'foo%3Dbaz=bar', obj: {'foo=baz': 'bar'}}, - { str: 'foo=bar&bar=baz', obj: {foo: 'bar', bar: 'baz'}} - ], - 'escaping': [ - { str: 'foo=foo%20bar', obj: {foo: 'foo bar'}}, - { str: 'cht=p3&chd=t%3A60%2C40&chs=250x100&chl=Hello%7CWorld', obj: { - cht: 'p3' - , chd: 't:60,40' - , chs: '250x100' - , chl: 'Hello|World' - }} - ], - 'nested': [ - { str: 'foo[]=bar&foo[]=quux', obj: {'foo' : ['bar', 'quux']}}, - { str: 'foo[]=bar', obj: {foo: ['bar']}}, - { str: 'foo[]=1&foo[]=2', obj: {'foo' : ['1', '2']}}, - { str: 'foo=bar&baz[]=1&baz[]=2&baz[]=3', obj: {'foo' : 'bar', 'baz' : ['1', '2', '3']}}, - { str: 'foo[]=bar&baz[]=1&baz[]=2&baz[]=3', obj: {'foo' : ['bar'], 'baz' : ['1', '2', '3']}}, - { str: 'x[y][z]=1', obj: {'x' : {'y' : {'z' : '1'}}}}, - { str: 'x[y][z][]=1', obj: {'x' : {'y' : {'z' : ['1']}}}}, - { str: 'x[y][z]=2', obj: {'x' : {'y' : {'z' : '2'}}}}, - { str: 'x[y][z][]=1&x[y][z][]=2', obj: {'x' : {'y' : {'z' : ['1', '2']}}}}, - { str: 'x[y][][z]=1', obj: {'x' : {'y' : [{'z' : '1'}]}}}, - { str: 'x[y][][z][]=1', obj: {'x' : {'y' : [{'z' : ['1']}]}}}, - { str: 'x[y][][z]=1&x[y][][w]=2', obj: {'x' : {'y' : [{'z' : '1', 'w' : '2'}]}}}, - { str: 'x[y][][v][w]=1', obj: {'x' : {'y' : [{'v' : {'w' : '1'}}]}}}, - { str: 'x[y][][z]=1&x[y][][v][w]=2', obj: {'x' : {'y' : [{'z' : '1', 'v' : {'w' : '2'}}]}}}, - { str: 'x[y][][z]=1&x[y][][z]=2', obj: {'x' : {'y' : [{'z' : '1'}, {'z' : '2'}]}}}, - { str: 'x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3', obj: {'x' : {'y' : [{'z' : '1', 'w' : 'a'}, {'z' : '2', 'w' : '3'}]}}}, - { str: 'user[name][first]=tj&user[name][last]=holowaychuk', obj: { user: { name: { first: 'tj', last: 'holowaychuk' }}}} - ], - 'errors': [ - { obj: 'foo=bar', message: 'stringify expects an object' }, - { obj: ['foo', 'bar'], message: 'stringify expects an object' } - ], - 'numbers': [ - { str: 'limit[]=1&limit[]=2&limit[]=3', obj: { limit: [1, 2, '3'] }}, - { str: 'limit=1', obj: { limit: 1 }} - ] - }; - - -// Assert error -function err(fn, msg){ - var err; - try { - fn(); - } catch (e) { - should.equal(e.message, msg); - return; - } - throw new Error('no exception thrown, expected "' + msg + '"'); -} - -function test(type) { - var str, obj; - for (var i = 0; i < str_identities[type].length; i++) { - str = str_identities[type][i].str; - obj = str_identities[type][i].obj; - qs.stringify(obj).should.eql(str); - } -} - -module.exports = { - 'test basics': function() { - test('basics'); - }, - - 'test escaping': function() { - test('escaping'); - }, - - 'test nested': function() { - test('nested'); - }, - - 'test numbers': function(){ - test('numbers'); - }, - - 'test errors': function() { - var obj, message; - for (var i = 0; i < str_identities['errors'].length; i++) { - message = str_identities['errors'][i].message; - obj = str_identities['errors'][i].obj; - err(function(){ qs.stringify(obj) }, message); - } - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/range-parser/.npmignore b/frontend/express/node_modules/express/node_modules/range-parser/.npmignore deleted file mode 100644 index 9daeafb9864..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/frontend/express/node_modules/express/node_modules/range-parser/History.md b/frontend/express/node_modules/express/node_modules/range-parser/History.md deleted file mode 100644 index 82df7b1e41e..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/History.md +++ /dev/null @@ -1,15 +0,0 @@ - -0.0.4 / 2012-06-17 -================== - - * changed: ret -1 for unsatisfiable and -2 when invalid - -0.0.3 / 2012-06-17 -================== - - * fix last-byte-pos default to len - 1 - -0.0.2 / 2012-06-14 -================== - - * add `.type` diff --git a/frontend/express/node_modules/express/node_modules/range-parser/Makefile b/frontend/express/node_modules/express/node_modules/range-parser/Makefile deleted file mode 100644 index 8e8640f2e6d..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/range-parser/Readme.md b/frontend/express/node_modules/express/node_modules/range-parser/Readme.md deleted file mode 100644 index b2a67fe834d..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/Readme.md +++ /dev/null @@ -1,28 +0,0 @@ - -# node-range-parser - - Range header field parser. - -## Example: - -```js -assert(-1 == parse(200, 'bytes=500-20')); -assert(-2 == parse(200, 'bytes=malformed')); -parse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }])); -parse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }])); -parse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }])); -parse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }])); -parse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }])); -parse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }])); -parse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }])); -parse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }])); -parse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }])); -parse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }])); -parse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }])); -``` - -## Installation - -``` -$ npm install range-parser -``` \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/range-parser/index.js b/frontend/express/node_modules/express/node_modules/range-parser/index.js deleted file mode 100644 index 9b0f7a8ec11..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/index.js +++ /dev/null @@ -1,49 +0,0 @@ - -/** - * Parse "Range" header `str` relative to the given file `size`. - * - * @param {Number} size - * @param {String} str - * @return {Array} - * @api public - */ - -module.exports = function(size, str){ - var valid = true; - var i = str.indexOf('='); - - if (-1 == i) return -2; - - var arr = str.slice(i + 1).split(',').map(function(range){ - var range = range.split('-') - , start = parseInt(range[0], 10) - , end = parseInt(range[1], 10); - - // -nnn - if (isNaN(start)) { - start = size - end; - end = size - 1; - // nnn- - } else if (isNaN(end)) { - end = size - 1; - } - - // limit last-byte-pos to current length - if (end > size - 1) end = size - 1; - - // invalid - if (isNaN(start) - || isNaN(end) - || start > end - || start < 0) valid = false; - - return { - start: start, - end: end - }; - }); - - arr.type = str.slice(0, i); - - return valid ? arr : -1; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/range-parser/package.json b/frontend/express/node_modules/express/node_modules/range-parser/package.json deleted file mode 100644 index efdf450a999..00000000000 --- a/frontend/express/node_modules/express/node_modules/range-parser/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "range-parser", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "description": "Range header field string parser", - "version": "0.0.4", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "readme": "\n# node-range-parser\n\n Range header field parser.\n\n## Example:\n\n```js\nassert(-1 == parse(200, 'bytes=500-20'));\nassert(-2 == parse(200, 'bytes=malformed'));\nparse(200, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 199 }]));\nparse(1000, 'bytes=0-499').should.eql(arr('bytes', [{ start: 0, end: 499 }]));\nparse(1000, 'bytes=40-80').should.eql(arr('bytes', [{ start: 40, end: 80 }]));\nparse(1000, 'bytes=-500').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=-400').should.eql(arr('bytes', [{ start: 600, end: 999 }]));\nparse(1000, 'bytes=500-').should.eql(arr('bytes', [{ start: 500, end: 999 }]));\nparse(1000, 'bytes=400-').should.eql(arr('bytes', [{ start: 400, end: 999 }]));\nparse(1000, 'bytes=0-0').should.eql(arr('bytes', [{ start: 0, end: 0 }]));\nparse(1000, 'bytes=-1').should.eql(arr('bytes', [{ start: 999, end: 999 }]));\nparse(1000, 'items=0-5').should.eql(arr('items', [{ start: 0, end: 5 }]));\nparse(1000, 'bytes=40-80,-1').should.eql(arr('bytes', [{ start: 40, end: 80 }, { start: 999, end: 999 }]));\n```\n\n## Installation\n\n```\n$ npm install range-parser\n```", - "readmeFilename": "Readme.md", - "_id": "range-parser@0.0.4", - "_from": "range-parser@0.0.4" -} diff --git a/frontend/express/node_modules/express/node_modules/send/.npmignore b/frontend/express/node_modules/express/node_modules/send/.npmignore deleted file mode 100644 index f1250e584c9..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -support -test -examples -*.sock diff --git a/frontend/express/node_modules/express/node_modules/send/History.md b/frontend/express/node_modules/express/node_modules/send/History.md deleted file mode 100644 index 20c5319094b..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/History.md +++ /dev/null @@ -1,25 +0,0 @@ - -0.1.0 / 2012-08-25 -================== - - * add options parameter to send() that is passed to fs.createReadStream() [kanongil] - -0.0.4 / 2012-08-16 -================== - - * allow custom "Accept-Ranges" definition - -0.0.3 / 2012-07-16 -================== - - * fix normalization of the root directory. Closes #3 - -0.0.2 / 2012-07-09 -================== - - * add passing of req explicitly for now (YUCK) - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/frontend/express/node_modules/express/node_modules/send/Makefile b/frontend/express/node_modules/express/node_modules/send/Makefile deleted file mode 100644 index a9dcfd50dbd..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec \ - --bail - -.PHONY: test \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/send/Readme.md b/frontend/express/node_modules/express/node_modules/send/Readme.md deleted file mode 100644 index 85171a91039..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/Readme.md +++ /dev/null @@ -1,123 +0,0 @@ - -# send - - Send is Connect's `static()` extracted for generalized use, a streaming static file - server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework. - -## Installation - - $ npm install send - -## Examples - - Small: - -```js -var http = require('http'); -var send = require('send'); - -var app = http.createServer(function(req, res){ - send(req, req.url).pipe(res); -}); -``` - - Serving from a root directory with custom error-handling: - -```js -var http = require('http'); -var send = require('send'); - -var app = http.createServer(function(req, res){ - // your custom error-handling logic: - function error(err) { - res.statusCode = err.status || 500; - res.end(err.message); - } - - // your custom directory handling logic: - function redirect() { - res.statusCode = 301; - res.setHeader('Location', req.url + '/'); - res.end('Redirecting to ' + req.url + '/'); - } - - // transfer arbitrary files from within - // /www/example.com/public/* - send(req, url.parse(req.url).pathname) - .root('/www/example.com/public') - .on('error', error) - .on('directory', redirect) - .pipe(res); -}); -``` - -## API - -### Events - - - `error` an error occurred `(err)` - - `directory` a directory was requested - - `stream` file streaming has started `(stream)` - - `end` streaming has completed - -### .root(dir) - - Serve files relative to `path`. Aliased as `.from(dir)`. - -### .index(path) - - By default send supports "index.html" files, to disable this - invoke `.index(false)` or to supply a new index pass a string. - -### .maxage(ms) - - Provide a max-age in milliseconds for http caching, defaults to 0. - -## Error-handling - - By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc. - -## Caching - - It does _not_ perform internal caching, you should use a reverse proxy cache such - as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;). - -## Debugging - - To enable `debug()` instrumentation output export __DEBUG__: - -``` -$ DEBUG=send node app -``` - -## Running tests - -``` -$ npm install -$ make test -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/send/index.js b/frontend/express/node_modules/express/node_modules/send/index.js deleted file mode 100644 index f17158d853e..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/index.js +++ /dev/null @@ -1,2 +0,0 @@ - -module.exports = require('./lib/send'); \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/send/lib/send.js b/frontend/express/node_modules/express/node_modules/send/lib/send.js deleted file mode 100644 index de721466edb..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/lib/send.js +++ /dev/null @@ -1,473 +0,0 @@ - -/** - * Module dependencies. - */ - -var debug = require('debug')('send') - , parseRange = require('range-parser') - , Stream = require('stream') - , mime = require('mime') - , fresh = require('fresh') - , path = require('path') - , http = require('http') - , fs = require('fs') - , basename = path.basename - , normalize = path.normalize - , join = path.join - , utils = require('./utils'); - -/** - * Expose `send`. - */ - -exports = module.exports = send; - -/** - * Expose mime module. - */ - -exports.mime = mime; - -/** - * Return a `SendStream` for `req` and `path`. - * - * @param {Request} req - * @param {String} path - * @param {Object} options - * @return {SendStream} - * @api public - */ - -function send(req, path, options) { - return new SendStream(req, path, options); -} - -/** - * Initialize a `SendStream` with the given `path`. - * - * Events: - * - * - `error` an error occurred - * - `stream` file streaming has started - * - `end` streaming has completed - * - `directory` a directory was requested - * - * @param {Request} req - * @param {String} path - * @param {Object} options - * @api private - */ - -function SendStream(req, path, options) { - var self = this; - this.req = req; - this.path = path; - this.options = options || {}; - this.maxage(0); - this.hidden(false); - this.index('index.html'); -} - -/** - * Inherits from `Stream.prototype`. - */ - -SendStream.prototype.__proto__ = Stream.prototype; - -/** - * Enable or disable "hidden" (dot) files. - * - * @param {Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.hidden = function(val){ - debug('hidden %s', val); - this._hidden = val; - return this; -}; - -/** - * Set index `path`, set to a falsy - * value to disable index support. - * - * @param {String|Boolean} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.index = function(path){ - debug('index %s', path); - this._index = path; - return this; -}; - -/** - * Set root `path`. - * - * @param {String} path - * @return {SendStream} - * @api public - */ - -SendStream.prototype.root = -SendStream.prototype.from = function(path){ - this._root = normalize(path); - return this; -}; - -/** - * Set max-age to `ms`. - * - * @param {Number} ms - * @return {SendStream} - * @api public - */ - -SendStream.prototype.maxage = function(ms){ - if (Infinity == ms) ms = 60 * 60 * 24 * 365 * 1000; - debug('max-age %d', ms); - this._maxage = ms; - return this; -}; - -/** - * Emit error with `status`. - * - * @param {Number} status - * @api private - */ - -SendStream.prototype.error = function(status, err){ - var res = this.res; - var msg = http.STATUS_CODES[status]; - err = err || new Error(msg); - err.status = status; - if (this.listeners('error').length) return this.emit('error', err); - res.statusCode = err.status; - res.end(msg); -}; - -/** - * Check if the pathname is potentially malicious. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isMalicious = function(){ - return !this._root && ~this.path.indexOf('..'); -}; - -/** - * Check if the pathname ends with "/". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasTrailingSlash = function(){ - return '/' == this.path[this.path.length - 1]; -}; - -/** - * Check if the basename leads with ".". - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.hasLeadingDot = function(){ - return '.' == basename(this.path)[0]; -}; - -/** - * Check if this is a conditional GET request. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isConditionalGET = function(){ - return this.req.headers['if-none-match'] - || this.req.headers['if-modified-since']; -}; - -/** - * Strip content-* header fields. - * - * @api private - */ - -SendStream.prototype.removeContentHeaderFields = function(){ - var res = this.res; - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); - } - }); -}; - -/** - * Respond with 304 not modified. - * - * @api private - */ - -SendStream.prototype.notModified = function(){ - var res = this.res; - debug('not modified'); - this.removeContentHeaderFields(); - res.statusCode = 304; - res.end(); -}; - -/** - * Check if the request is cacheable, aka - * responded with 2xx or 304 (see RFC 2616 section 14.2{5,6}). - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isCachable = function(){ - var res = this.res; - return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode; -}; - -/** - * Handle stat() error. - * - * @param {Error} err - * @api private - */ - -SendStream.prototype.onStatError = function(err){ - var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; - if (~notfound.indexOf(err.code)) return this.error(404, err); - this.error(500, err); -}; - -/** - * Check if the cache is fresh. - * - * @return {Boolean} - * @api private - */ - -SendStream.prototype.isFresh = function(){ - return fresh(this.req.headers, this.res._headers); -}; - -/** - * Redirect to `path`. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.redirect = function(path){ - if (this.listeners('directory').length) return this.emit('directory'); - var res = this.res; - path += '/'; - res.statusCode = 301; - res.setHeader('Location', path); - res.end('Redirecting to ' + utils.escape(path)); -}; - -/** - * Pipe to `res. - * - * @param {Stream} res - * @return {Stream} res - * @api public - */ - -SendStream.prototype.pipe = function(res){ - var self = this - , args = arguments - , path = this.path - , root = this._root; - - // references - this.res = res; - - // invalid request uri - path = utils.decode(path); - if (-1 == path) return this.error(400); - - // null byte(s) - if (~path.indexOf('\0')) return this.error(400); - - // join / normalize from optional root dir - if (root) path = normalize(join(this._root, path)); - - // ".." is malicious without "root" - if (this.isMalicious()) return this.error(403); - - // malicious path - if (root && 0 != path.indexOf(root)) return this.error(403); - - // hidden file support - if (!this._hidden && this.hasLeadingDot()) return this.error(404); - - // index file support - if (this._index && this.hasTrailingSlash()) path += this._index; - - debug('stat "%s"', path); - fs.stat(path, function(err, stat){ - if (err) return self.onStatError(err); - if (stat.isDirectory()) return self.redirect(self.path); - self.send(path, stat); - }); - - return res; -}; - -/** - * Transfer `path`. - * - * @param {String} path - * @api public - */ - -SendStream.prototype.send = function(path, stat){ - var options = this.options; - var len = stat.size; - var res = this.res; - var req = this.req; - var ranges = req.headers.range; - var offset = options.start || 0; - - // set header fields - this.setHeader(stat); - - // set content-type - this.type(path); - - // conditional GET support - if (this.isConditionalGET() - && this.isCachable() - && this.isFresh()) { - return this.notModified(); - } - - // adjust len to start/end options - len = Math.max(0, len - offset); - if (options.end !== undefined) { - var bytes = options.end - offset + 1; - if (len > bytes) len = bytes; - } - - // Range support - if (ranges) { - ranges = parseRange(len, ranges); - - // unsatisfiable - if (-1 == ranges) { - res.setHeader('Content-Range', 'bytes */' + stat.size); - return this.error(416); - } - - // valid (syntactically invalid ranges are treated as a regular response) - if (-2 != ranges) { - options.start = offset + ranges[0].start; - options.end = offset + ranges[0].end; - - // Content-Range - res.statusCode = 206; - res.setHeader('Content-Range', 'bytes ' - + ranges[0].start - + '-' - + ranges[0].end - + '/' - + len); - len = options.end - options.start + 1; - } - } - - // content-length - res.setHeader('Content-Length', len); - - // HEAD support - if ('HEAD' == req.method) return res.end(); - - this.stream(path, options); -}; - -/** - * Stream `path` to the response. - * - * @param {String} path - * @param {Object} options - * @api private - */ - -SendStream.prototype.stream = function(path, options){ - // TODO: this is all lame, refactor meeee - var self = this; - var res = this.res; - var req = this.req; - - // pipe - var stream = fs.createReadStream(path, options); - this.emit('stream', stream); - stream.pipe(res); - - // socket closed, done with the fd - req.on('close', stream.destroy.bind(stream)); - - // error handling code-smell - stream.on('error', function(err){ - // no hope in responding - if (res._header) { - console.error(err.stack); - req.destroy(); - return; - } - - // 500 - err.status = 500; - self.emit('error', err); - }); - - // end - stream.on('end', function(){ - self.emit('end'); - }); -}; - -/** - * Set content-type based on `path` - * if it hasn't been explicitly set. - * - * @param {String} path - * @api private - */ - -SendStream.prototype.type = function(path){ - var res = this.res; - if (res.getHeader('Content-Type')) return; - var type = mime.lookup(path); - var charset = mime.charsets.lookup(type); - debug('content-type %s', type); - res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); -}; - -/** - * Set reaponse header fields, most - * fields may be pre-defined. - * - * @param {Object} stat - * @api private - */ - -SendStream.prototype.setHeader = function(stat){ - var res = this.res; - if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes'); - if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat)); - if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); - if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (this._maxage / 1000)); - if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString()); -}; diff --git a/frontend/express/node_modules/express/node_modules/send/lib/utils.js b/frontend/express/node_modules/express/node_modules/send/lib/utils.js deleted file mode 100644 index 950e5a2c13d..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/lib/utils.js +++ /dev/null @@ -1,47 +0,0 @@ - -/** - * Return an ETag in the form of `"-"` - * from the given `stat`. - * - * @param {Object} stat - * @return {String} - * @api private - */ - -exports.etag = function(stat) { - return '"' + stat.size + '-' + Number(stat.mtime) + '"'; -}; - -/** - * decodeURIComponent. - * - * Allows V8 to only deoptimize this fn instead of all - * of send(). - * - * @param {String} path - * @api private - */ - -exports.decode = function(path){ - try { - return decodeURIComponent(path); - } catch (err) { - return -1; - } -}; - -/** - * Escape the given string of `html`. - * - * @param {String} html - * @return {String} - * @api private - */ - -exports.escape = function(html){ - return String(html) - .replace(/&(?!\w+;)/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/LICENSE b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/LICENSE deleted file mode 100644 index 451fc4550c2..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Benjamin Thomas, Robert Kieffer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/README.md b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/README.md deleted file mode 100644 index d8b66a86aa6..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# mime - -Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community. - -## Install - -Install with [npm](http://github.com/isaacs/npm): - - npm install mime - -## API - Queries - -### mime.lookup(path) -Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. - - var mime = require('mime'); - - mime.lookup('/path/to/file.txt'); // => 'text/plain' - mime.lookup('file.txt'); // => 'text/plain' - mime.lookup('.TXT'); // => 'text/plain' - mime.lookup('htm'); // => 'text/html' - -### mime.extension(type) -Get the default extension for `type` - - mime.extension('text/html'); // => 'html' - mime.extension('application/octet-stream'); // => 'bin' - -### mime.charsets.lookup() - -Map mime-type to charset - - mime.charsets.lookup('text/plain'); // => 'UTF-8' - -(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.) - -## API - Defining Custom Types - -The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types). - -### mime.define() - -Add custom mime/extension mappings - - mime.define({ - 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'], - 'application/x-my-type': ['x-mt', 'x-mtt'], - // etc ... - }); - - mime.lookup('x-sft'); // => 'text/x-some-format' - -The first entry in the extensions array is returned by `mime.extension()`. E.g. - - mime.extension('text/x-some-format'); // => 'x-sf' - -### mime.load(filepath) - -Load mappings from an Apache ".types" format file - - mime.load('./my_project.types'); - -The .types file format is simple - See the `types` dir for examples. diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/mime.js b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/mime.js deleted file mode 100644 index 1e00585d300..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/mime.js +++ /dev/null @@ -1,104 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -function Mime() { - // Map of extension -> mime type - this.types = Object.create(null); - - // Map of mime type -> extension - this.extensions = Object.create(null); -} - -/** - * Define mimetype -> extension mappings. Each key is a mime-type that maps - * to an array of extensions associated with the type. The first extension is - * used as the default extension for the type. - * - * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); - * - * @param map (Object) type definitions - */ -Mime.prototype.define = function (map) { - for (var type in map) { - var exts = map[type]; - - for (var i = 0; i < exts.length; i++) { - this.types[exts[i]] = type; - } - - // Default extension is the first one we encounter - if (!this.extensions[type]) { - this.extensions[type] = exts[0]; - } - } -}; - -/** - * Load an Apache2-style ".types" file - * - * This may be called multiple times (it's expected). Where files declare - * overlapping types/extensions, the last file wins. - * - * @param file (String) path of file to load. - */ -Mime.prototype.load = function(file) { - // Read file and split into lines - var map = {}, - content = fs.readFileSync(file, 'ascii'), - lines = content.split(/[\r\n]+/); - - lines.forEach(function(line) { - // Clean up whitespace/comments, and split into fields - var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); - map[fields.shift()] = fields; - }); - - this.define(map); -}; - -/** - * Lookup a mime type based on extension - */ -Mime.prototype.lookup = function(path, fallback) { - var ext = path.replace(/.*[\.\/]/, '').toLowerCase(); - - return this.types[ext] || fallback || this.default_type; -}; - -/** - * Return file extension associated with a mime type - */ -Mime.prototype.extension = function(mimeType) { - return this.extensions[mimeType]; -}; - -// Default instance -var mime = new Mime(); - -// Load local copy of -// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types -mime.load(path.join(__dirname, 'types/mime.types')); - -// Load additional types from node.js community -mime.load(path.join(__dirname, 'types/node.types')); - -// Default type -mime.default_type = mime.lookup('bin'); - -// -// Additional API specific to the default instance -// - -mime.Mime = Mime; - -/** - * Lookup a charset based on mime type. - */ -mime.charsets = { - lookup: function(mimeType, fallback) { - // Assume text types are utf8 - return (/^text\//).test(mimeType) ? 'UTF-8' : fallback; - } -} - -module.exports = mime; diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/package.json b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/package.json deleted file mode 100644 index 74a6b690770..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com", - "url": "http://github.com/broofa" - }, - "contributors": [ - { - "name": "Benjamin Thomas", - "email": "benjamin@benjaminthomas.org", - "url": "http://github.com/bentomas" - } - ], - "dependencies": {}, - "description": "A comprehensive library for mime-type mapping", - "devDependencies": {}, - "keywords": [ - "util", - "mime" - ], - "main": "mime.js", - "name": "mime", - "repository": { - "url": "https://github.com/broofa/node-mime", - "type": "git" - }, - "version": "1.2.6", - "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/bentomas/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-mime/issues" - }, - "_id": "mime@1.2.6", - "_from": "mime@1.2.6" -} diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/test.js b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/test.js deleted file mode 100644 index cbad034a18f..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/test.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Usage: node test.js - */ - -var mime = require('./mime'); -var assert = require('assert'); - -function eq(a, b) { - console.log('Test: ' + a + ' === ' + b); - assert.strictEqual.apply(null, arguments); -} - -console.log(Object.keys(mime.extensions).length + ' types'); -console.log(Object.keys(mime.types).length + ' extensions\n'); - -// -// Test mime lookups -// - -eq('text/plain', mime.lookup('text.txt')); -eq('text/plain', mime.lookup('.text.txt')); -eq('text/plain', mime.lookup('.txt')); -eq('text/plain', mime.lookup('txt')); -eq('application/octet-stream', mime.lookup('text.nope')); -eq('fallback', mime.lookup('text.fallback', 'fallback')); -eq('application/octet-stream', mime.lookup('constructor')); -eq('text/plain', mime.lookup('TEXT.TXT')); -eq('text/event-stream', mime.lookup('text/event-stream')); -eq('application/x-web-app-manifest+json', mime.lookup('text.webapp')); - -// -// Test extensions -// - -eq('txt', mime.extension(mime.types.text)); -eq('html', mime.extension(mime.types.htm)); -eq('bin', mime.extension('application/octet-stream')); -eq(undefined, mime.extension('constructor')); - -// -// Test node types -// - -eq('application/octet-stream', mime.lookup('file.buffer')); -eq('audio/mp4', mime.lookup('file.m4a')); - -// -// Test charsets -// - -eq('UTF-8', mime.charsets.lookup('text/plain')); -eq(undefined, mime.charsets.lookup(mime.types.js)); -eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); - -console.log('\nOK'); diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/mime.types b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/mime.types deleted file mode 100644 index b3cae2ed810..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/mime.types +++ /dev/null @@ -1,1510 +0,0 @@ -# This file maps Internet media types to unique file extension(s). -# Although created for httpd, this file is used by many software systems -# and has been placed in the public domain for unlimited redisribution. -# -# The table below contains both registered and (common) unregistered types. -# A type that has no unique extension can be ignored -- they are listed -# here to guide configurations toward known types and to make it easier to -# identify "new" types. File extensions are also commonly used to indicate -# content languages and encodings, so choose them carefully. -# -# Internet media types should be registered as described in RFC 4288. -# The registry is at . -# -# MIME type (lowercased) Extensions -# ============================================ ========== -# application/1d-interleaved-parityfec -# application/3gpp-ims+xml -# application/activemessage -application/andrew-inset ez -# application/applefile -application/applixware aw -application/atom+xml atom -application/atomcat+xml atomcat -# application/atomicmail -application/atomsvc+xml atomsvc -# application/auth-policy+xml -# application/batch-smtp -# application/beep+xml -# application/calendar+xml -# application/cals-1840 -# application/ccmp+xml -application/ccxml+xml ccxml -application/cdmi-capability cdmia -application/cdmi-container cdmic -application/cdmi-domain cdmid -application/cdmi-object cdmio -application/cdmi-queue cdmiq -# application/cea-2018+xml -# application/cellml+xml -# application/cfw -# application/cnrp+xml -# application/commonground -# application/conference-info+xml -# application/cpl+xml -# application/csta+xml -# application/cstadata+xml -application/cu-seeme cu -# application/cybercash -application/davmount+xml davmount -# application/dca-rft -# application/dec-dx -# application/dialog-info+xml -# application/dicom -# application/dns -# application/dskpp+xml -application/dssc+der dssc -application/dssc+xml xdssc -# application/dvcs -application/ecmascript ecma -# application/edi-consent -# application/edi-x12 -# application/edifact -application/emma+xml emma -# application/epp+xml -application/epub+zip epub -# application/eshop -# application/example -application/exi exi -# application/fastinfoset -# application/fastsoap -# application/fits -application/font-tdpfr pfr -# application/framework-attributes+xml -# application/h224 -# application/held+xml -# application/http -application/hyperstudio stk -# application/ibe-key-request+xml -# application/ibe-pkg-reply+xml -# application/ibe-pp-data -# application/iges -# application/im-iscomposing+xml -# application/index -# application/index.cmd -# application/index.obj -# application/index.response -# application/index.vnd -application/inkml+xml ink inkml -# application/iotp -application/ipfix ipfix -# application/ipp -# application/isup -application/java-archive jar -application/java-serialized-object ser -application/java-vm class -application/javascript js -application/json json -# application/kpml-request+xml -# application/kpml-response+xml -application/lost+xml lostxml -application/mac-binhex40 hqx -application/mac-compactpro cpt -# application/macwriteii -application/mads+xml mads -application/marc mrc -application/marcxml+xml mrcx -application/mathematica ma nb mb -# application/mathml-content+xml -# application/mathml-presentation+xml -application/mathml+xml mathml -# application/mbms-associated-procedure-description+xml -# application/mbms-deregister+xml -# application/mbms-envelope+xml -# application/mbms-msk+xml -# application/mbms-msk-response+xml -# application/mbms-protection-description+xml -# application/mbms-reception-report+xml -# application/mbms-register+xml -# application/mbms-register-response+xml -# application/mbms-user-service-description+xml -application/mbox mbox -# application/media_control+xml -application/mediaservercontrol+xml mscml -application/metalink4+xml meta4 -application/mets+xml mets -# application/mikey -application/mods+xml mods -# application/moss-keys -# application/moss-signature -# application/mosskey-data -# application/mosskey-request -application/mp21 m21 mp21 -application/mp4 mp4s -# application/mpeg4-generic -# application/mpeg4-iod -# application/mpeg4-iod-xmt -# application/msc-ivr+xml -# application/msc-mixer+xml -application/msword doc dot -application/mxf mxf -# application/nasdata -# application/news-checkgroups -# application/news-groupinfo -# application/news-transmission -# application/nss -# application/ocsp-request -# application/ocsp-response -application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy -application/oda oda -application/oebps-package+xml opf -application/ogg ogx -application/onenote onetoc onetoc2 onetmp onepkg -application/oxps oxps -# application/parityfec -application/patch-ops-error+xml xer -application/pdf pdf -application/pgp-encrypted pgp -# application/pgp-keys -application/pgp-signature asc sig -application/pics-rules prf -# application/pidf+xml -# application/pidf-diff+xml -application/pkcs10 p10 -application/pkcs7-mime p7m p7c -application/pkcs7-signature p7s -application/pkcs8 p8 -application/pkix-attr-cert ac -application/pkix-cert cer -application/pkix-crl crl -application/pkix-pkipath pkipath -application/pkixcmp pki -application/pls+xml pls -# application/poc-settings+xml -application/postscript ai eps ps -# application/prs.alvestrand.titrax-sheet -application/prs.cww cww -# application/prs.nprend -# application/prs.plucker -# application/prs.rdf-xml-crypt -# application/prs.xsf+xml -application/pskc+xml pskcxml -# application/qsig -application/rdf+xml rdf -application/reginfo+xml rif -application/relax-ng-compact-syntax rnc -# application/remote-printing -application/resource-lists+xml rl -application/resource-lists-diff+xml rld -# application/riscos -# application/rlmi+xml -application/rls-services+xml rs -application/rpki-ghostbusters gbr -application/rpki-manifest mft -application/rpki-roa roa -# application/rpki-updown -application/rsd+xml rsd -application/rss+xml rss -application/rtf rtf -# application/rtx -# application/samlassertion+xml -# application/samlmetadata+xml -application/sbml+xml sbml -application/scvp-cv-request scq -application/scvp-cv-response scs -application/scvp-vp-request spq -application/scvp-vp-response spp -application/sdp sdp -# application/set-payment -application/set-payment-initiation setpay -# application/set-registration -application/set-registration-initiation setreg -# application/sgml -# application/sgml-open-catalog -application/shf+xml shf -# application/sieve -# application/simple-filter+xml -# application/simple-message-summary -# application/simplesymbolcontainer -# application/slate -# application/smil -application/smil+xml smi smil -# application/soap+fastinfoset -# application/soap+xml -application/sparql-query rq -application/sparql-results+xml srx -# application/spirits-event+xml -application/srgs gram -application/srgs+xml grxml -application/sru+xml sru -application/ssml+xml ssml -# application/tamp-apex-update -# application/tamp-apex-update-confirm -# application/tamp-community-update -# application/tamp-community-update-confirm -# application/tamp-error -# application/tamp-sequence-adjust -# application/tamp-sequence-adjust-confirm -# application/tamp-status-query -# application/tamp-status-response -# application/tamp-update -# application/tamp-update-confirm -application/tei+xml tei teicorpus -application/thraud+xml tfi -# application/timestamp-query -# application/timestamp-reply -application/timestamped-data tsd -# application/tve-trigger -# application/ulpfec -# application/vcard+xml -# application/vemmi -# application/vividence.scriptfile -# application/vnd.3gpp.bsf+xml -application/vnd.3gpp.pic-bw-large plb -application/vnd.3gpp.pic-bw-small psb -application/vnd.3gpp.pic-bw-var pvb -# application/vnd.3gpp.sms -# application/vnd.3gpp2.bcmcsinfo+xml -# application/vnd.3gpp2.sms -application/vnd.3gpp2.tcap tcap -application/vnd.3m.post-it-notes pwn -application/vnd.accpac.simply.aso aso -application/vnd.accpac.simply.imp imp -application/vnd.acucobol acu -application/vnd.acucorp atc acutc -application/vnd.adobe.air-application-installer-package+zip air -application/vnd.adobe.fxp fxp fxpl -# application/vnd.adobe.partial-upload -application/vnd.adobe.xdp+xml xdp -application/vnd.adobe.xfdf xfdf -# application/vnd.aether.imp -# application/vnd.ah-barcode -application/vnd.ahead.space ahead -application/vnd.airzip.filesecure.azf azf -application/vnd.airzip.filesecure.azs azs -application/vnd.amazon.ebook azw -application/vnd.americandynamics.acc acc -application/vnd.amiga.ami ami -# application/vnd.amundsen.maze+xml -application/vnd.android.package-archive apk -application/vnd.anser-web-certificate-issue-initiation cii -application/vnd.anser-web-funds-transfer-initiation fti -application/vnd.antix.game-component atx -application/vnd.apple.installer+xml mpkg -application/vnd.apple.mpegurl m3u8 -# application/vnd.arastra.swi -application/vnd.aristanetworks.swi swi -application/vnd.astraea-software.iota iota -application/vnd.audiograph aep -# application/vnd.autopackage -# application/vnd.avistar+xml -application/vnd.blueice.multipass mpm -# application/vnd.bluetooth.ep.oob -application/vnd.bmi bmi -application/vnd.businessobjects rep -# application/vnd.cab-jscript -# application/vnd.canon-cpdl -# application/vnd.canon-lips -# application/vnd.cendio.thinlinc.clientconf -application/vnd.chemdraw+xml cdxml -application/vnd.chipnuts.karaoke-mmd mmd -application/vnd.cinderella cdy -# application/vnd.cirpack.isdn-ext -application/vnd.claymore cla -application/vnd.cloanto.rp9 rp9 -application/vnd.clonk.c4group c4g c4d c4f c4p c4u -application/vnd.cluetrust.cartomobile-config c11amc -application/vnd.cluetrust.cartomobile-config-pkg c11amz -# application/vnd.collection+json -# application/vnd.commerce-battelle -application/vnd.commonspace csp -application/vnd.contact.cmsg cdbcmsg -application/vnd.cosmocaller cmc -application/vnd.crick.clicker clkx -application/vnd.crick.clicker.keyboard clkk -application/vnd.crick.clicker.palette clkp -application/vnd.crick.clicker.template clkt -application/vnd.crick.clicker.wordbank clkw -application/vnd.criticaltools.wbs+xml wbs -application/vnd.ctc-posml pml -# application/vnd.ctct.ws+xml -# application/vnd.cups-pdf -# application/vnd.cups-postscript -application/vnd.cups-ppd ppd -# application/vnd.cups-raster -# application/vnd.cups-raw -# application/vnd.curl -application/vnd.curl.car car -application/vnd.curl.pcurl pcurl -# application/vnd.cybank -application/vnd.data-vision.rdz rdz -application/vnd.dece.data uvf uvvf uvd uvvd -application/vnd.dece.ttml+xml uvt uvvt -application/vnd.dece.unspecified uvx uvvx -application/vnd.dece.zip uvz uvvz -application/vnd.denovo.fcselayout-link fe_launch -# application/vnd.dir-bi.plate-dl-nosuffix -application/vnd.dna dna -application/vnd.dolby.mlp mlp -# application/vnd.dolby.mobile.1 -# application/vnd.dolby.mobile.2 -application/vnd.dpgraph dpg -application/vnd.dreamfactory dfac -application/vnd.dvb.ait ait -# application/vnd.dvb.dvbj -# application/vnd.dvb.esgcontainer -# application/vnd.dvb.ipdcdftnotifaccess -# application/vnd.dvb.ipdcesgaccess -# application/vnd.dvb.ipdcesgaccess2 -# application/vnd.dvb.ipdcesgpdd -# application/vnd.dvb.ipdcroaming -# application/vnd.dvb.iptv.alfec-base -# application/vnd.dvb.iptv.alfec-enhancement -# application/vnd.dvb.notif-aggregate-root+xml -# application/vnd.dvb.notif-container+xml -# application/vnd.dvb.notif-generic+xml -# application/vnd.dvb.notif-ia-msglist+xml -# application/vnd.dvb.notif-ia-registration-request+xml -# application/vnd.dvb.notif-ia-registration-response+xml -# application/vnd.dvb.notif-init+xml -# application/vnd.dvb.pfr -application/vnd.dvb.service svc -# application/vnd.dxr -application/vnd.dynageo geo -# application/vnd.easykaraoke.cdgdownload -# application/vnd.ecdis-update -application/vnd.ecowin.chart mag -# application/vnd.ecowin.filerequest -# application/vnd.ecowin.fileupdate -# application/vnd.ecowin.series -# application/vnd.ecowin.seriesrequest -# application/vnd.ecowin.seriesupdate -# application/vnd.emclient.accessrequest+xml -application/vnd.enliven nml -# application/vnd.eprints.data+xml -application/vnd.epson.esf esf -application/vnd.epson.msf msf -application/vnd.epson.quickanime qam -application/vnd.epson.salt slt -application/vnd.epson.ssf ssf -# application/vnd.ericsson.quickcall -application/vnd.eszigno3+xml es3 et3 -# application/vnd.etsi.aoc+xml -# application/vnd.etsi.cug+xml -# application/vnd.etsi.iptvcommand+xml -# application/vnd.etsi.iptvdiscovery+xml -# application/vnd.etsi.iptvprofile+xml -# application/vnd.etsi.iptvsad-bc+xml -# application/vnd.etsi.iptvsad-cod+xml -# application/vnd.etsi.iptvsad-npvr+xml -# application/vnd.etsi.iptvservice+xml -# application/vnd.etsi.iptvsync+xml -# application/vnd.etsi.iptvueprofile+xml -# application/vnd.etsi.mcid+xml -# application/vnd.etsi.overload-control-policy-dataset+xml -# application/vnd.etsi.sci+xml -# application/vnd.etsi.simservs+xml -# application/vnd.etsi.tsl+xml -# application/vnd.etsi.tsl.der -# application/vnd.eudora.data -application/vnd.ezpix-album ez2 -application/vnd.ezpix-package ez3 -# application/vnd.f-secure.mobile -application/vnd.fdf fdf -application/vnd.fdsn.mseed mseed -application/vnd.fdsn.seed seed dataless -# application/vnd.ffsns -# application/vnd.fints -application/vnd.flographit gph -application/vnd.fluxtime.clip ftc -# application/vnd.font-fontforge-sfd -application/vnd.framemaker fm frame maker book -application/vnd.frogans.fnc fnc -application/vnd.frogans.ltf ltf -application/vnd.fsc.weblaunch fsc -application/vnd.fujitsu.oasys oas -application/vnd.fujitsu.oasys2 oa2 -application/vnd.fujitsu.oasys3 oa3 -application/vnd.fujitsu.oasysgp fg5 -application/vnd.fujitsu.oasysprs bh2 -# application/vnd.fujixerox.art-ex -# application/vnd.fujixerox.art4 -# application/vnd.fujixerox.hbpl -application/vnd.fujixerox.ddd ddd -application/vnd.fujixerox.docuworks xdw -application/vnd.fujixerox.docuworks.binder xbd -# application/vnd.fut-misnet -application/vnd.fuzzysheet fzs -application/vnd.genomatix.tuxedo txd -# application/vnd.geocube+xml -application/vnd.geogebra.file ggb -application/vnd.geogebra.tool ggt -application/vnd.geometry-explorer gex gre -application/vnd.geonext gxt -application/vnd.geoplan g2w -application/vnd.geospace g3w -# application/vnd.globalplatform.card-content-mgt -# application/vnd.globalplatform.card-content-mgt-response -application/vnd.gmx gmx -application/vnd.google-earth.kml+xml kml -application/vnd.google-earth.kmz kmz -application/vnd.grafeq gqf gqs -# application/vnd.gridmp -application/vnd.groove-account gac -application/vnd.groove-help ghf -application/vnd.groove-identity-message gim -application/vnd.groove-injector grv -application/vnd.groove-tool-message gtm -application/vnd.groove-tool-template tpl -application/vnd.groove-vcard vcg -# application/vnd.hal+json -application/vnd.hal+xml hal -application/vnd.handheld-entertainment+xml zmm -application/vnd.hbci hbci -# application/vnd.hcl-bireports -application/vnd.hhe.lesson-player les -application/vnd.hp-hpgl hpgl -application/vnd.hp-hpid hpid -application/vnd.hp-hps hps -application/vnd.hp-jlyt jlt -application/vnd.hp-pcl pcl -application/vnd.hp-pclxl pclxl -# application/vnd.httphone -application/vnd.hydrostatix.sof-data sfd-hdstx -application/vnd.hzn-3d-crossword x3d -# application/vnd.ibm.afplinedata -# application/vnd.ibm.electronic-media -application/vnd.ibm.minipay mpy -application/vnd.ibm.modcap afp listafp list3820 -application/vnd.ibm.rights-management irm -application/vnd.ibm.secure-container sc -application/vnd.iccprofile icc icm -application/vnd.igloader igl -application/vnd.immervision-ivp ivp -application/vnd.immervision-ivu ivu -# application/vnd.informedcontrol.rms+xml -# application/vnd.informix-visionary -# application/vnd.infotech.project -# application/vnd.infotech.project+xml -application/vnd.insors.igm igm -application/vnd.intercon.formnet xpw xpx -application/vnd.intergeo i2g -# application/vnd.intertrust.digibox -# application/vnd.intertrust.nncp -application/vnd.intu.qbo qbo -application/vnd.intu.qfx qfx -# application/vnd.iptc.g2.conceptitem+xml -# application/vnd.iptc.g2.knowledgeitem+xml -# application/vnd.iptc.g2.newsitem+xml -# application/vnd.iptc.g2.packageitem+xml -application/vnd.ipunplugged.rcprofile rcprofile -application/vnd.irepository.package+xml irp -application/vnd.is-xpr xpr -application/vnd.isac.fcs fcs -application/vnd.jam jam -# application/vnd.japannet-directory-service -# application/vnd.japannet-jpnstore-wakeup -# application/vnd.japannet-payment-wakeup -# application/vnd.japannet-registration -# application/vnd.japannet-registration-wakeup -# application/vnd.japannet-setstore-wakeup -# application/vnd.japannet-verification -# application/vnd.japannet-verification-wakeup -application/vnd.jcp.javame.midlet-rms rms -application/vnd.jisp jisp -application/vnd.joost.joda-archive joda -application/vnd.kahootz ktz ktr -application/vnd.kde.karbon karbon -application/vnd.kde.kchart chrt -application/vnd.kde.kformula kfo -application/vnd.kde.kivio flw -application/vnd.kde.kontour kon -application/vnd.kde.kpresenter kpr kpt -application/vnd.kde.kspread ksp -application/vnd.kde.kword kwd kwt -application/vnd.kenameaapp htke -application/vnd.kidspiration kia -application/vnd.kinar kne knp -application/vnd.koan skp skd skt skm -application/vnd.kodak-descriptor sse -application/vnd.las.las+xml lasxml -# application/vnd.liberty-request+xml -application/vnd.llamagraphics.life-balance.desktop lbd -application/vnd.llamagraphics.life-balance.exchange+xml lbe -application/vnd.lotus-1-2-3 123 -application/vnd.lotus-approach apr -application/vnd.lotus-freelance pre -application/vnd.lotus-notes nsf -application/vnd.lotus-organizer org -application/vnd.lotus-screencam scm -application/vnd.lotus-wordpro lwp -application/vnd.macports.portpkg portpkg -# application/vnd.marlin.drm.actiontoken+xml -# application/vnd.marlin.drm.conftoken+xml -# application/vnd.marlin.drm.license+xml -# application/vnd.marlin.drm.mdcf -application/vnd.mcd mcd -application/vnd.medcalcdata mc1 -application/vnd.mediastation.cdkey cdkey -# application/vnd.meridian-slingshot -application/vnd.mfer mwf -application/vnd.mfmp mfm -application/vnd.micrografx.flo flo -application/vnd.micrografx.igx igx -application/vnd.mif mif -# application/vnd.minisoft-hp3000-save -# application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.mobius.daf daf -application/vnd.mobius.dis dis -application/vnd.mobius.mbk mbk -application/vnd.mobius.mqy mqy -application/vnd.mobius.msl msl -application/vnd.mobius.plc plc -application/vnd.mobius.txf txf -application/vnd.mophun.application mpn -application/vnd.mophun.certificate mpc -# application/vnd.motorola.flexsuite -# application/vnd.motorola.flexsuite.adsi -# application/vnd.motorola.flexsuite.fis -# application/vnd.motorola.flexsuite.gotap -# application/vnd.motorola.flexsuite.kmr -# application/vnd.motorola.flexsuite.ttc -# application/vnd.motorola.flexsuite.wem -# application/vnd.motorola.iprm -application/vnd.mozilla.xul+xml xul -application/vnd.ms-artgalry cil -# application/vnd.ms-asf -application/vnd.ms-cab-compressed cab -application/vnd.ms-excel xls xlm xla xlc xlt xlw -application/vnd.ms-excel.addin.macroenabled.12 xlam -application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb -application/vnd.ms-excel.sheet.macroenabled.12 xlsm -application/vnd.ms-excel.template.macroenabled.12 xltm -application/vnd.ms-fontobject eot -application/vnd.ms-htmlhelp chm -application/vnd.ms-ims ims -application/vnd.ms-lrm lrm -# application/vnd.ms-office.activex+xml -application/vnd.ms-officetheme thmx -application/vnd.ms-pki.seccat cat -application/vnd.ms-pki.stl stl -# application/vnd.ms-playready.initiator+xml -application/vnd.ms-powerpoint ppt pps pot -application/vnd.ms-powerpoint.addin.macroenabled.12 ppam -application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm -application/vnd.ms-powerpoint.slide.macroenabled.12 sldm -application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm -application/vnd.ms-powerpoint.template.macroenabled.12 potm -application/vnd.ms-project mpp mpt -# application/vnd.ms-tnef -# application/vnd.ms-wmdrm.lic-chlg-req -# application/vnd.ms-wmdrm.lic-resp -# application/vnd.ms-wmdrm.meter-chlg-req -# application/vnd.ms-wmdrm.meter-resp -application/vnd.ms-word.document.macroenabled.12 docm -application/vnd.ms-word.template.macroenabled.12 dotm -application/vnd.ms-works wps wks wcm wdb -application/vnd.ms-wpl wpl -application/vnd.ms-xpsdocument xps -application/vnd.mseq mseq -# application/vnd.msign -# application/vnd.multiad.creator -# application/vnd.multiad.creator.cif -# application/vnd.music-niff -application/vnd.musician mus -application/vnd.muvee.style msty -application/vnd.mynfc taglet -# application/vnd.ncd.control -# application/vnd.ncd.reference -# application/vnd.nervana -# application/vnd.netfpx -application/vnd.neurolanguage.nlu nlu -application/vnd.noblenet-directory nnd -application/vnd.noblenet-sealer nns -application/vnd.noblenet-web nnw -# application/vnd.nokia.catalogs -# application/vnd.nokia.conml+wbxml -# application/vnd.nokia.conml+xml -# application/vnd.nokia.isds-radio-presets -# application/vnd.nokia.iptv.config+xml -# application/vnd.nokia.landmark+wbxml -# application/vnd.nokia.landmark+xml -# application/vnd.nokia.landmarkcollection+xml -# application/vnd.nokia.n-gage.ac+xml -application/vnd.nokia.n-gage.data ngdat -application/vnd.nokia.n-gage.symbian.install n-gage -# application/vnd.nokia.ncd -# application/vnd.nokia.pcd+wbxml -# application/vnd.nokia.pcd+xml -application/vnd.nokia.radio-preset rpst -application/vnd.nokia.radio-presets rpss -application/vnd.novadigm.edm edm -application/vnd.novadigm.edx edx -application/vnd.novadigm.ext ext -# application/vnd.ntt-local.file-transfer -# application/vnd.ntt-local.sip-ta_remote -# application/vnd.ntt-local.sip-ta_tcp_stream -application/vnd.oasis.opendocument.chart odc -application/vnd.oasis.opendocument.chart-template otc -application/vnd.oasis.opendocument.database odb -application/vnd.oasis.opendocument.formula odf -application/vnd.oasis.opendocument.formula-template odft -application/vnd.oasis.opendocument.graphics odg -application/vnd.oasis.opendocument.graphics-template otg -application/vnd.oasis.opendocument.image odi -application/vnd.oasis.opendocument.image-template oti -application/vnd.oasis.opendocument.presentation odp -application/vnd.oasis.opendocument.presentation-template otp -application/vnd.oasis.opendocument.spreadsheet ods -application/vnd.oasis.opendocument.spreadsheet-template ots -application/vnd.oasis.opendocument.text odt -application/vnd.oasis.opendocument.text-master odm -application/vnd.oasis.opendocument.text-template ott -application/vnd.oasis.opendocument.text-web oth -# application/vnd.obn -# application/vnd.oftn.l10n+json -# application/vnd.oipf.contentaccessdownload+xml -# application/vnd.oipf.contentaccessstreaming+xml -# application/vnd.oipf.cspg-hexbinary -# application/vnd.oipf.dae.svg+xml -# application/vnd.oipf.dae.xhtml+xml -# application/vnd.oipf.mippvcontrolmessage+xml -# application/vnd.oipf.pae.gem -# application/vnd.oipf.spdiscovery+xml -# application/vnd.oipf.spdlist+xml -# application/vnd.oipf.ueprofile+xml -# application/vnd.oipf.userprofile+xml -application/vnd.olpc-sugar xo -# application/vnd.oma-scws-config -# application/vnd.oma-scws-http-request -# application/vnd.oma-scws-http-response -# application/vnd.oma.bcast.associated-procedure-parameter+xml -# application/vnd.oma.bcast.drm-trigger+xml -# application/vnd.oma.bcast.imd+xml -# application/vnd.oma.bcast.ltkm -# application/vnd.oma.bcast.notification+xml -# application/vnd.oma.bcast.provisioningtrigger -# application/vnd.oma.bcast.sgboot -# application/vnd.oma.bcast.sgdd+xml -# application/vnd.oma.bcast.sgdu -# application/vnd.oma.bcast.simple-symbol-container -# application/vnd.oma.bcast.smartcard-trigger+xml -# application/vnd.oma.bcast.sprov+xml -# application/vnd.oma.bcast.stkm -# application/vnd.oma.cab-address-book+xml -# application/vnd.oma.cab-feature-handler+xml -# application/vnd.oma.cab-pcc+xml -# application/vnd.oma.cab-user-prefs+xml -# application/vnd.oma.dcd -# application/vnd.oma.dcdc -application/vnd.oma.dd2+xml dd2 -# application/vnd.oma.drm.risd+xml -# application/vnd.oma.group-usage-list+xml -# application/vnd.oma.pal+xml -# application/vnd.oma.poc.detailed-progress-report+xml -# application/vnd.oma.poc.final-report+xml -# application/vnd.oma.poc.groups+xml -# application/vnd.oma.poc.invocation-descriptor+xml -# application/vnd.oma.poc.optimized-progress-report+xml -# application/vnd.oma.push -# application/vnd.oma.scidm.messages+xml -# application/vnd.oma.xcap-directory+xml -# application/vnd.omads-email+xml -# application/vnd.omads-file+xml -# application/vnd.omads-folder+xml -# application/vnd.omaloc-supl-init -application/vnd.openofficeorg.extension oxt -# application/vnd.openxmlformats-officedocument.custom-properties+xml -# application/vnd.openxmlformats-officedocument.customxmlproperties+xml -# application/vnd.openxmlformats-officedocument.drawing+xml -# application/vnd.openxmlformats-officedocument.drawingml.chart+xml -# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml -# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml -# application/vnd.openxmlformats-officedocument.extended-properties+xml -# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml -# application/vnd.openxmlformats-officedocument.presentationml.comments+xml -# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml -# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml -application/vnd.openxmlformats-officedocument.presentationml.presentation pptx -# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml -application/vnd.openxmlformats-officedocument.presentationml.slide sldx -# application/vnd.openxmlformats-officedocument.presentationml.slide+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml -# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml -application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx -# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml -# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml -# application/vnd.openxmlformats-officedocument.presentationml.tags+xml -application/vnd.openxmlformats-officedocument.presentationml.template potx -# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml -# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml -application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx -# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml -# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml -# application/vnd.openxmlformats-officedocument.theme+xml -# application/vnd.openxmlformats-officedocument.themeoverride+xml -# application/vnd.openxmlformats-officedocument.vmldrawing -# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.document docx -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml -application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx -# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml -# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml -# application/vnd.openxmlformats-package.core-properties+xml -# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml -# application/vnd.openxmlformats-package.relationships+xml -# application/vnd.quobject-quoxdocument -# application/vnd.osa.netdeploy -application/vnd.osgeo.mapguide.package mgp -# application/vnd.osgi.bundle -application/vnd.osgi.dp dp -# application/vnd.otps.ct-kip+xml -application/vnd.palm pdb pqa oprc -# application/vnd.paos.xml -application/vnd.pawaafile paw -application/vnd.pg.format str -application/vnd.pg.osasli ei6 -# application/vnd.piaccess.application-licence -application/vnd.picsel efif -application/vnd.pmi.widget wg -# application/vnd.poc.group-advertisement+xml -application/vnd.pocketlearn plf -application/vnd.powerbuilder6 pbd -# application/vnd.powerbuilder6-s -# application/vnd.powerbuilder7 -# application/vnd.powerbuilder7-s -# application/vnd.powerbuilder75 -# application/vnd.powerbuilder75-s -# application/vnd.preminet -application/vnd.previewsystems.box box -application/vnd.proteus.magazine mgz -application/vnd.publishare-delta-tree qps -application/vnd.pvi.ptid1 ptid -# application/vnd.pwg-multiplexed -# application/vnd.pwg-xhtml-print+xml -# application/vnd.qualcomm.brew-app-res -application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb -# application/vnd.radisys.moml+xml -# application/vnd.radisys.msml+xml -# application/vnd.radisys.msml-audit+xml -# application/vnd.radisys.msml-audit-conf+xml -# application/vnd.radisys.msml-audit-conn+xml -# application/vnd.radisys.msml-audit-dialog+xml -# application/vnd.radisys.msml-audit-stream+xml -# application/vnd.radisys.msml-conf+xml -# application/vnd.radisys.msml-dialog+xml -# application/vnd.radisys.msml-dialog-base+xml -# application/vnd.radisys.msml-dialog-fax-detect+xml -# application/vnd.radisys.msml-dialog-fax-sendrecv+xml -# application/vnd.radisys.msml-dialog-group+xml -# application/vnd.radisys.msml-dialog-speech+xml -# application/vnd.radisys.msml-dialog-transform+xml -# application/vnd.rainstor.data -# application/vnd.rapid -application/vnd.realvnc.bed bed -application/vnd.recordare.musicxml mxl -application/vnd.recordare.musicxml+xml musicxml -# application/vnd.renlearn.rlprint -application/vnd.rig.cryptonote cryptonote -application/vnd.rim.cod cod -application/vnd.rn-realmedia rm -application/vnd.route66.link66+xml link66 -# application/vnd.ruckus.download -# application/vnd.s3sms -application/vnd.sailingtracker.track st -# application/vnd.sbm.cid -# application/vnd.sbm.mid2 -# application/vnd.scribus -# application/vnd.sealed.3df -# application/vnd.sealed.csf -# application/vnd.sealed.doc -# application/vnd.sealed.eml -# application/vnd.sealed.mht -# application/vnd.sealed.net -# application/vnd.sealed.ppt -# application/vnd.sealed.tiff -# application/vnd.sealed.xls -# application/vnd.sealedmedia.softseal.html -# application/vnd.sealedmedia.softseal.pdf -application/vnd.seemail see -application/vnd.sema sema -application/vnd.semd semd -application/vnd.semf semf -application/vnd.shana.informed.formdata ifm -application/vnd.shana.informed.formtemplate itp -application/vnd.shana.informed.interchange iif -application/vnd.shana.informed.package ipk -application/vnd.simtech-mindmapper twd twds -application/vnd.smaf mmf -# application/vnd.smart.notebook -application/vnd.smart.teacher teacher -# application/vnd.software602.filler.form+xml -# application/vnd.software602.filler.form-xml-zip -application/vnd.solent.sdkm+xml sdkm sdkd -application/vnd.spotfire.dxp dxp -application/vnd.spotfire.sfs sfs -# application/vnd.sss-cod -# application/vnd.sss-dtf -# application/vnd.sss-ntf -application/vnd.stardivision.calc sdc -application/vnd.stardivision.draw sda -application/vnd.stardivision.impress sdd -application/vnd.stardivision.math smf -application/vnd.stardivision.writer sdw vor -application/vnd.stardivision.writer-global sgl -application/vnd.stepmania.package smzip -application/vnd.stepmania.stepchart sm -# application/vnd.street-stream -application/vnd.sun.xml.calc sxc -application/vnd.sun.xml.calc.template stc -application/vnd.sun.xml.draw sxd -application/vnd.sun.xml.draw.template std -application/vnd.sun.xml.impress sxi -application/vnd.sun.xml.impress.template sti -application/vnd.sun.xml.math sxm -application/vnd.sun.xml.writer sxw -application/vnd.sun.xml.writer.global sxg -application/vnd.sun.xml.writer.template stw -# application/vnd.sun.wadl+xml -application/vnd.sus-calendar sus susp -application/vnd.svd svd -# application/vnd.swiftview-ics -application/vnd.symbian.install sis sisx -application/vnd.syncml+xml xsm -application/vnd.syncml.dm+wbxml bdm -application/vnd.syncml.dm+xml xdm -# application/vnd.syncml.dm.notification -# application/vnd.syncml.ds.notification -application/vnd.tao.intent-module-archive tao -application/vnd.tcpdump.pcap pcap cap dmp -application/vnd.tmobile-livetv tmo -application/vnd.trid.tpt tpt -application/vnd.triscape.mxs mxs -application/vnd.trueapp tra -# application/vnd.truedoc -# application/vnd.ubisoft.webplayer -application/vnd.ufdl ufd ufdl -application/vnd.uiq.theme utz -application/vnd.umajin umj -application/vnd.unity unityweb -application/vnd.uoml+xml uoml -# application/vnd.uplanet.alert -# application/vnd.uplanet.alert-wbxml -# application/vnd.uplanet.bearer-choice -# application/vnd.uplanet.bearer-choice-wbxml -# application/vnd.uplanet.cacheop -# application/vnd.uplanet.cacheop-wbxml -# application/vnd.uplanet.channel -# application/vnd.uplanet.channel-wbxml -# application/vnd.uplanet.list -# application/vnd.uplanet.list-wbxml -# application/vnd.uplanet.listcmd -# application/vnd.uplanet.listcmd-wbxml -# application/vnd.uplanet.signal -application/vnd.vcx vcx -# application/vnd.vd-study -# application/vnd.vectorworks -# application/vnd.verimatrix.vcas -# application/vnd.vidsoft.vidconference -application/vnd.visio vsd vst vss vsw -application/vnd.visionary vis -# application/vnd.vividence.scriptfile -application/vnd.vsf vsf -# application/vnd.wap.sic -# application/vnd.wap.slc -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/vnd.webturbo wtb -# application/vnd.wfa.wsc -# application/vnd.wmc -# application/vnd.wmf.bootstrap -# application/vnd.wolfram.mathematica -# application/vnd.wolfram.mathematica.package -application/vnd.wolfram.player nbp -application/vnd.wordperfect wpd -application/vnd.wqd wqd -# application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf stf -# application/vnd.wv.csp+wbxml -# application/vnd.wv.csp+xml -# application/vnd.wv.ssp+xml -application/vnd.xara xar -application/vnd.xfdl xfdl -# application/vnd.xfdl.webform -# application/vnd.xmi+xml -# application/vnd.xmpie.cpkg -# application/vnd.xmpie.dpkg -# application/vnd.xmpie.plan -# application/vnd.xmpie.ppkg -# application/vnd.xmpie.xlim -application/vnd.yamaha.hv-dic hvd -application/vnd.yamaha.hv-script hvs -application/vnd.yamaha.hv-voice hvp -application/vnd.yamaha.openscoreformat osf -application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg -# application/vnd.yamaha.remote-setup -application/vnd.yamaha.smaf-audio saf -application/vnd.yamaha.smaf-phrase spf -# application/vnd.yamaha.through-ngn -# application/vnd.yamaha.tunnel-udpencap -application/vnd.yellowriver-custom-menu cmp -application/vnd.zul zir zirz -application/vnd.zzazz.deck+xml zaz -application/voicexml+xml vxml -# application/vq-rtcpxr -# application/watcherinfo+xml -# application/whoispp-query -# application/whoispp-response -application/widget wgt -application/winhlp hlp -# application/wita -# application/wordperfect5.1 -application/wsdl+xml wsdl -application/wspolicy+xml wspolicy -application/x-7z-compressed 7z -application/x-abiword abw -application/x-ace-compressed ace -application/x-authorware-bin aab x32 u32 vox -application/x-authorware-map aam -application/x-authorware-seg aas -application/x-bcpio bcpio -application/x-bittorrent torrent -application/x-bzip bz -application/x-bzip2 bz2 boz -application/x-cdlink vcd -application/x-chat chat -application/x-chess-pgn pgn -# application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-debian-package deb udeb -application/x-director dir dcr dxr cst cct cxt w3d fgd swa -application/x-doom wad -application/x-dtbncx+xml ncx -application/x-dtbook+xml dtb -application/x-dtbresource+xml res -application/x-dvi dvi -application/x-font-bdf bdf -# application/x-font-dos -# application/x-font-framemaker -application/x-font-ghostscript gsf -# application/x-font-libgrx -application/x-font-linux-psf psf -application/x-font-otf otf -application/x-font-pcf pcf -application/x-font-snf snf -# application/x-font-speedo -# application/x-font-sunos-news -application/x-font-ttf ttf ttc -application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff -# application/x-font-vfont -application/x-futuresplash spl -application/x-gnumeric gnumeric -application/x-gtar gtar -# application/x-gzip -application/x-hdf hdf -application/x-java-jnlp-file jnlp -application/x-latex latex -application/x-mobipocket-ebook prc mobi -application/x-ms-application application -application/x-ms-wmd wmd -application/x-ms-wmz wmz -application/x-ms-xbap xbap -application/x-msaccess mdb -application/x-msbinder obd -application/x-mscardfile crd -application/x-msclip clp -application/x-msdownload exe dll com bat msi -application/x-msmediaview mvb m13 m14 -application/x-msmetafile wmf -application/x-msmoney mny -application/x-mspublisher pub -application/x-msschedule scd -application/x-msterminal trm -application/x-mswrite wri -application/x-netcdf nc cdf -application/x-pkcs12 p12 pfx -application/x-pkcs7-certificates p7b spc -application/x-pkcs7-certreqresp p7r -application/x-rar-compressed rar -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-silverlight-app xap -application/x-stuffit sit -application/x-stuffitx sitx -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-tex-tfm tfm -application/x-texinfo texinfo texi -application/x-ustar ustar -application/x-wais-source src -application/x-x509-ca-cert der crt -application/x-xfig fig -application/x-xpinstall xpi -# application/x400-bp -# application/xcap-att+xml -# application/xcap-caps+xml -application/xcap-diff+xml xdf -# application/xcap-el+xml -# application/xcap-error+xml -# application/xcap-ns+xml -# application/xcon-conference-info-diff+xml -# application/xcon-conference-info+xml -application/xenc+xml xenc -application/xhtml+xml xhtml xht -# application/xhtml-voice+xml -application/xml xml xsl -application/xml-dtd dtd -# application/xml-external-parsed-entity -# application/xmpp+xml -application/xop+xml xop -application/xslt+xml xslt -application/xspf+xml xspf -application/xv+xml mxml xhvml xvml xvm -application/yang yang -application/yin+xml yin -application/zip zip -# audio/1d-interleaved-parityfec -# audio/32kadpcm -# audio/3gpp -# audio/3gpp2 -# audio/ac3 -audio/adpcm adp -# audio/amr -# audio/amr-wb -# audio/amr-wb+ -# audio/asc -# audio/atrac-advanced-lossless -# audio/atrac-x -# audio/atrac3 -audio/basic au snd -# audio/bv16 -# audio/bv32 -# audio/clearmode -# audio/cn -# audio/dat12 -# audio/dls -# audio/dsr-es201108 -# audio/dsr-es202050 -# audio/dsr-es202211 -# audio/dsr-es202212 -# audio/dv -# audio/dvi4 -# audio/eac3 -# audio/evrc -# audio/evrc-qcp -# audio/evrc0 -# audio/evrc1 -# audio/evrcb -# audio/evrcb0 -# audio/evrcb1 -# audio/evrcwb -# audio/evrcwb0 -# audio/evrcwb1 -# audio/example -# audio/fwdred -# audio/g719 -# audio/g722 -# audio/g7221 -# audio/g723 -# audio/g726-16 -# audio/g726-24 -# audio/g726-32 -# audio/g726-40 -# audio/g728 -# audio/g729 -# audio/g7291 -# audio/g729d -# audio/g729e -# audio/gsm -# audio/gsm-efr -# audio/gsm-hr-08 -# audio/ilbc -# audio/ip-mr_v2.5 -# audio/l16 -# audio/l20 -# audio/l24 -# audio/l8 -# audio/lpc -audio/midi mid midi kar rmi -# audio/mobile-xmf -audio/mp4 mp4a -# audio/mp4a-latm -# audio/mpa -# audio/mpa-robust -audio/mpeg mpga mp2 mp2a mp3 m2a m3a -# audio/mpeg4-generic -audio/ogg oga ogg spx -# audio/parityfec -# audio/pcma -# audio/pcma-wb -# audio/pcmu-wb -# audio/pcmu -# audio/prs.sid -# audio/qcelp -# audio/red -# audio/rtp-enc-aescm128 -# audio/rtp-midi -# audio/rtx -# audio/smv -# audio/smv0 -# audio/smv-qcp -# audio/sp-midi -# audio/speex -# audio/t140c -# audio/t38 -# audio/telephone-event -# audio/tone -# audio/uemclip -# audio/ulpfec -# audio/vdvi -# audio/vmr-wb -# audio/vnd.3gpp.iufp -# audio/vnd.4sb -# audio/vnd.audiokoz -# audio/vnd.celp -# audio/vnd.cisco.nse -# audio/vnd.cmles.radio-events -# audio/vnd.cns.anp1 -# audio/vnd.cns.inf1 -audio/vnd.dece.audio uva uvva -audio/vnd.digital-winds eol -# audio/vnd.dlna.adts -# audio/vnd.dolby.heaac.1 -# audio/vnd.dolby.heaac.2 -# audio/vnd.dolby.mlp -# audio/vnd.dolby.mps -# audio/vnd.dolby.pl2 -# audio/vnd.dolby.pl2x -# audio/vnd.dolby.pl2z -# audio/vnd.dolby.pulse.1 -audio/vnd.dra dra -audio/vnd.dts dts -audio/vnd.dts.hd dtshd -# audio/vnd.dvb.file dvb -# audio/vnd.everad.plj -# audio/vnd.hns.audio -audio/vnd.lucent.voice lvp -audio/vnd.ms-playready.media.pya pya -# audio/vnd.nokia.mobile-xmf -# audio/vnd.nortel.vbk -audio/vnd.nuera.ecelp4800 ecelp4800 -audio/vnd.nuera.ecelp7470 ecelp7470 -audio/vnd.nuera.ecelp9600 ecelp9600 -# audio/vnd.octel.sbc -# audio/vnd.qcelp -# audio/vnd.rhetorex.32kadpcm -audio/vnd.rip rip -# audio/vnd.sealedmedia.softseal.mpeg -# audio/vnd.vmx.cvsd -# audio/vorbis -# audio/vorbis-config -audio/webm weba -audio/x-aac aac -audio/x-aiff aif aiff aifc -audio/x-mpegurl m3u -audio/x-ms-wax wax -audio/x-ms-wma wma -audio/x-pn-realaudio ram ra -audio/x-pn-realaudio-plugin rmp -audio/x-wav wav -chemical/x-cdx cdx -chemical/x-cif cif -chemical/x-cmdf cmdf -chemical/x-cml cml -chemical/x-csml csml -# chemical/x-pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -# image/example -# image/fits -image/g3fax g3 -image/gif gif -image/ief ief -# image/jp2 -image/jpeg jpeg jpg jpe -# image/jpm -# image/jpx -image/ktx ktx -# image/naplps -image/png png -image/prs.btif btif -# image/prs.pti -image/svg+xml svg svgz -# image/t38 -image/tiff tiff tif -# image/tiff-fx -image/vnd.adobe.photoshop psd -# image/vnd.cns.inf2 -image/vnd.dece.graphic uvi uvvi uvg uvvg -image/vnd.dvb.subtitle sub -image/vnd.djvu djvu djv -image/vnd.dwg dwg -image/vnd.dxf dxf -image/vnd.fastbidsheet fbs -image/vnd.fpx fpx -image/vnd.fst fst -image/vnd.fujixerox.edmics-mmr mmr -image/vnd.fujixerox.edmics-rlc rlc -# image/vnd.globalgraphics.pgb -# image/vnd.microsoft.icon -# image/vnd.mix -image/vnd.ms-modi mdi -image/vnd.net-fpx npx -# image/vnd.radiance -# image/vnd.sealed.png -# image/vnd.sealedmedia.softseal.gif -# image/vnd.sealedmedia.softseal.jpg -# image/vnd.svf -image/vnd.wap.wbmp wbmp -image/vnd.xiff xif -image/webp webp -image/x-cmu-raster ras -image/x-cmx cmx -image/x-freehand fh fhc fh4 fh5 fh7 -image/x-icon ico -image/x-pcx pcx -image/x-pict pic pct -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -# message/cpim -# message/delivery-status -# message/disposition-notification -# message/example -# message/external-body -# message/feedback-report -# message/global -# message/global-delivery-status -# message/global-disposition-notification -# message/global-headers -# message/http -# message/imdn+xml -# message/news -# message/partial -message/rfc822 eml mime -# message/s-http -# message/sip -# message/sipfrag -# message/tracking-status -# message/vnd.si.simp -# model/example -model/iges igs iges -model/mesh msh mesh silo -model/vnd.collada+xml dae -model/vnd.dwf dwf -# model/vnd.flatland.3dml -model/vnd.gdl gdl -# model/vnd.gs-gdl -# model/vnd.gs.gdl -model/vnd.gtw gtw -# model/vnd.moml+xml -model/vnd.mts mts -# model/vnd.parasolid.transmit.binary -# model/vnd.parasolid.transmit.text -model/vnd.vtu vtu -model/vrml wrl vrml -# multipart/alternative -# multipart/appledouble -# multipart/byteranges -# multipart/digest -# multipart/encrypted -# multipart/example -# multipart/form-data -# multipart/header-set -# multipart/mixed -# multipart/parallel -# multipart/related -# multipart/report -# multipart/signed -# multipart/voice-message -# text/1d-interleaved-parityfec -text/calendar ics ifb -text/css css -text/csv csv -# text/directory -# text/dns -# text/ecmascript -# text/enriched -# text/example -# text/fwdred -text/html html htm -# text/javascript -text/n3 n3 -# text/parityfec -text/plain txt text conf def list log in -# text/prs.fallenstein.rst -text/prs.lines.tag dsc -# text/vnd.radisys.msml-basic-layout -# text/red -# text/rfc822-headers -text/richtext rtx -# text/rtf -# text/rtp-enc-aescm128 -# text/rtx -text/sgml sgml sgm -# text/t140 -text/tab-separated-values tsv -text/troff t tr roff man me ms -text/turtle ttl -# text/ulpfec -text/uri-list uri uris urls -text/vcard vcard -# text/vnd.abc -text/vnd.curl curl -text/vnd.curl.dcurl dcurl -text/vnd.curl.scurl scurl -text/vnd.curl.mcurl mcurl -# text/vnd.dmclientscript -text/vnd.dvb.subtitle sub -# text/vnd.esmertec.theme-descriptor -text/vnd.fly fly -text/vnd.fmi.flexstor flx -text/vnd.graphviz gv -text/vnd.in3d.3dml 3dml -text/vnd.in3d.spot spot -# text/vnd.iptc.newsml -# text/vnd.iptc.nitf -# text/vnd.latex-z -# text/vnd.motorola.reflex -# text/vnd.ms-mediapackage -# text/vnd.net2phone.commcenter.command -# text/vnd.si.uricatalogue -text/vnd.sun.j2me.app-descriptor jad -# text/vnd.trolltech.linguist -# text/vnd.wap.si -# text/vnd.wap.sl -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-asm s asm -text/x-c c cc cxx cpp h hh dic -text/x-fortran f for f77 f90 -text/x-pascal p pas -text/x-java-source java -text/x-setext etx -text/x-uuencode uu -text/x-vcalendar vcs -text/x-vcard vcf -# text/xml -# text/xml-external-parsed-entity -# video/1d-interleaved-parityfec -video/3gpp 3gp -# video/3gpp-tt -video/3gpp2 3g2 -# video/bmpeg -# video/bt656 -# video/celb -# video/dv -# video/example -video/h261 h261 -video/h263 h263 -# video/h263-1998 -# video/h263-2000 -video/h264 h264 -# video/h264-rcdo -# video/h264-svc -video/jpeg jpgv -# video/jpeg2000 -video/jpm jpm jpgm -video/mj2 mj2 mjp2 -# video/mp1s -# video/mp2p -# video/mp2t -video/mp4 mp4 mp4v mpg4 -# video/mp4v-es -video/mpeg mpeg mpg mpe m1v m2v -# video/mpeg4-generic -# video/mpv -# video/nv -video/ogg ogv -# video/parityfec -# video/pointer -video/quicktime qt mov -# video/raw -# video/rtp-enc-aescm128 -# video/rtx -# video/smpte292m -# video/ulpfec -# video/vc1 -# video/vnd.cctv -video/vnd.dece.hd uvh uvvh -video/vnd.dece.mobile uvm uvvm -# video/vnd.dece.mp4 -video/vnd.dece.pd uvp uvvp -video/vnd.dece.sd uvs uvvs -video/vnd.dece.video uvv uvvv -# video/vnd.directv.mpeg -# video/vnd.directv.mpeg-tts -# video/vnd.dlna.mpeg-tts -video/vnd.dvb.file dvb -video/vnd.fvt fvt -# video/vnd.hns.video -# video/vnd.iptvforum.1dparityfec-1010 -# video/vnd.iptvforum.1dparityfec-2005 -# video/vnd.iptvforum.2dparityfec-1010 -# video/vnd.iptvforum.2dparityfec-2005 -# video/vnd.iptvforum.ttsavc -# video/vnd.iptvforum.ttsmpeg2 -# video/vnd.motorola.video -# video/vnd.motorola.videop -video/vnd.mpegurl mxu m4u -video/vnd.ms-playready.media.pyv pyv -# video/vnd.nokia.interleaved-multimedia -# video/vnd.nokia.videovoip -# video/vnd.objectvideo -# video/vnd.sealed.mpeg1 -# video/vnd.sealed.mpeg4 -# video/vnd.sealed.swf -# video/vnd.sealedmedia.softseal.mov -video/vnd.uvvu.mp4 uvu uvvu -video/vnd.vivo viv -video/webm webm -video/x-f4v f4v -video/x-fli fli -video/x-flv flv -video/x-m4v m4v -video/x-ms-asf asf asx -video/x-ms-wm wm -video/x-ms-wmv wmv -video/x-ms-wmx wmx -video/x-ms-wvx wvx -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/node.types b/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/node.types deleted file mode 100644 index b7fe8c0d316..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/node_modules/mime/types/node.types +++ /dev/null @@ -1,65 +0,0 @@ -# What: Google Chrome Extension -# Why: To allow apps to (work) be served with the right content type header. -# http://codereview.chromium.org/2830017 -# Added by: niftylettuce -application/x-chrome-extension crx - -# What: OTF Message Silencer -# Why: To silence the "Resource interpreted as font but transferred with MIME -# type font/otf" message that occurs in Google Chrome -# Added by: niftylettuce -font/opentype otf - -# What: HTC support -# Why: To properly render .htc files such as CSS3PIE -# Added by: niftylettuce -text/x-component htc - -# What: HTML5 application cache manifest -# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps -# per https://developer.mozilla.org/en/offline_resources_in_firefox -# Added by: louisremi -text/cache-manifest appcache manifest - -# What: node binary buffer format -# Why: semi-standard extension w/in the node community -# Added by: tootallnate -application/octet-stream buffer - -# What: The "protected" MP-4 formats used by iTunes. -# Why: Required for streaming music to browsers (?) -# Added by: broofa -application/mp4 m4p -audio/mp4 m4a - -# What: Music playlist format (http://en.wikipedia.org/wiki/M3U) -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -application/x-mpegURL m3u8 - -# What: Video format, Part of RFC1890 -# Why: See https://github.com/bentomas/node-mime/pull/6 -# Added by: mjrusso -video/MP2T ts - -# What: The FLAC lossless codec format -# Why: Streaming and serving FLAC audio -# Added by: jacobrask -audio/flac flac - -# What: EventSource mime type -# Why: mime type of Server-Sent Events stream -# http://www.w3.org/TR/eventsource/#text-event-stream -# Added by: francois2metz -text/event-stream event-stream - -# What: Mozilla App manifest mime type -# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests -# Added by: ednapiranha -application/x-web-app-manifest+json webapp - -# What: Matroska Mime Types -# Why: http://en.wikipedia.org/wiki/Matroska -# Added by: aduncan88 -video/x-matroska mkv -audio/x-matroska mka diff --git a/frontend/express/node_modules/express/node_modules/send/package.json b/frontend/express/node_modules/express/node_modules/send/package.json deleted file mode 100644 index 5e936f161b3..00000000000 --- a/frontend/express/node_modules/express/node_modules/send/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "send", - "version": "0.1.0", - "description": "Better streaming static file server with Range and conditional-GET support", - "keywords": [ - "static", - "file", - "server" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "dependencies": { - "debug": "*", - "mime": "1.2.6", - "fresh": "0.1.0", - "range-parser": "0.0.4" - }, - "devDependencies": { - "mocha": "*", - "should": "*", - "supertest": "0.0.1", - "connect": "2.x" - }, - "scripts": { - "test": "make test" - }, - "main": "index", - "readme": "\n# send\n\n Send is Connect's `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n $ npm install send\n\n## Examples\n\n Small:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n});\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require('http');\nvar send = require('send');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader('Location', req.url + '/');\n res.end('Redirecting to ' + req.url + '/');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname)\n .root('/www/example.com/public')\n .on('error', error)\n .on('directory', redirect)\n .pipe(res);\n});\n```\n\n## API\n\n### Events\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .root(dir)\n\n Serve files relative to `path`. Aliased as `.from(dir)`.\n\n### .index(path)\n\n By default send supports \"index.html\" files, to disable this\n invoke `.index(false)` or to supply a new index pass a string.\n\n### .maxage(ms)\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it's small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ make test\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "_id": "send@0.1.0", - "_from": "send@0.1.0" -} diff --git a/frontend/express/node_modules/express/package.json b/frontend/express/node_modules/express/package.json deleted file mode 100644 index 4b09f39c8f7..00000000000 --- a/frontend/express/node_modules/express/package.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "express", - "description": "Sinatra inspired web development framework", - "version": "3.2.6", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "contributors": [ - { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - { - "name": "Aaron Heckmann", - "email": "aaron.heckmann+github@gmail.com" - }, - { - "name": "Ciaran Jessup", - "email": "ciaranj@gmail.com" - }, - { - "name": "Guillermo Rauch", - "email": "rauchg@gmail.com" - } - ], - "dependencies": { - "connect": "2.7.11", - "commander": "0.6.1", - "range-parser": "0.0.4", - "mkdirp": "0.3.4", - "cookie": "0.1.0", - "buffer-crc32": "0.2.1", - "fresh": "0.1.0", - "methods": "0.0.1", - "send": "0.1.0", - "cookie-signature": "1.0.1", - "debug": "*" - }, - "devDependencies": { - "ejs": "*", - "mocha": "*", - "jade": "*", - "hjs": "*", - "stylus": "*", - "should": "*", - "connect-redis": "*", - "marked": "*", - "supertest": "0.6.0" - }, - "keywords": [ - "express", - "framework", - "sinatra", - "web", - "rest", - "restful", - "router", - "app", - "api" - ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/express" - }, - "main": "index", - "bin": { - "express": "./bin/express" - }, - "scripts": { - "prepublish": "npm prune", - "test": "make test" - }, - "engines": { - "node": "*" - }, - "readme": "![express logo](http://f.cl.ly/items/0V2S1n0K1i3y1c122g04/Screen%20Shot%202012-04-11%20at%209.59.42%20AM.png)\n\n Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [![Build Status](https://secure.travis-ci.org/visionmedia/express.png)](http://travis-ci.org/visionmedia/express) [![Dependency Status](https://gemnasium.com/visionmedia/express.png)](https://gemnasium.com/visionmedia/express)\n\n```js\nvar express = require('express');\nvar app = express();\n\napp.get('/', function(req, res){\n res.send('Hello World');\n});\n\napp.listen(3000);\n```\n\n## Installation\n\n $ npm install -g express\n\n## Quick Start\n\n The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:\n\n Create the app:\n\n $ npm install -g express\n $ express /tmp/foo && cd /tmp/foo\n\n Install dependencies:\n\n $ npm install\n\n Start the server:\n\n $ node app\n\n## Features\n\n * Built on [Connect](http://github.com/senchalabs/connect)\n * Robust routing\n * HTTP helpers (redirection, caching, etc)\n * View system supporting 14+ template engines\n * Content negotiation\n * Focus on high performance\n * Environment based configuration\n * Executable for generating applications quickly\n * High test coverage\n\n## Philosophy\n\n The Express philosophy is to provide small, robust tooling for HTTP servers. Making\n it a great solution for single page applications, web sites, hybrids, or public\n HTTP APIs.\n\n Built on Connect you can use _only_ what you need, and nothing more, applications\n can be as big or as small as you like, even a single file. Express does\n not force you to use any specific ORM or template engine. With support for over\n 14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js)\n you can quickly craft your perfect framework.\n\n## More Information\n\n * Join #express on freenode\n * [Google Group](http://groups.google.com/group/express-js) for discussion\n * Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates\n * Visit the [Wiki](http://github.com/visionmedia/express/wiki)\n * [РуÑÑкоÑÐ·Ñ‹Ñ‡Ð½Ð°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ](http://jsman.ru/express/)\n * Run express examples [online](https://runnable.com/express)\n\n## Viewing Examples\n\nClone the Express repo, then install the dev dependencies to install all the example / test suite deps:\n\n $ git clone git://github.com/visionmedia/express.git --depth 1\n $ cd express\n $ npm install\n\nthen run whichever tests you want:\n\n $ node examples/content-negotiation\n\n## Running Tests\n\nTo run the test suite first invoke the following command within the repo, installing the development dependencies:\n\n $ npm install\n\nthen run the tests:\n\n $ make test\n\n## Contributors\n\n```\nproject: express\ncommits: 3559\nactive : 468 days\nfiles : 237\nauthors:\n 1891\tTj Holowaychuk 53.1%\n 1285\tvisionmedia 36.1%\n 182\tTJ Holowaychuk 5.1%\n 54\tAaron Heckmann 1.5%\n 34\tcsausdev 1.0%\n 26\tciaranj 0.7%\n 21\tRobert Sköld 0.6%\n 6\tGuillermo Rauch 0.2%\n 3\tDav Glass 0.1%\n 3\tNick Poulden 0.1%\n 2\tRandy Merrill 0.1%\n 2\tBenny Wong 0.1%\n 2\tHunter Loftis 0.1%\n 2\tJake Gordon 0.1%\n 2\tBrian McKinney 0.1%\n 2\tRoman Shtylman 0.1%\n 2\tBen Weaver 0.1%\n 2\tDave Hoover 0.1%\n 2\tEivind Fjeldstad 0.1%\n 2\tDaniel Shaw 0.1%\n 1\tMatt Colyer 0.0%\n 1\tPau Ramon 0.0%\n 1\tPero Pejovic 0.0%\n 1\tPeter Rekdal Sunde 0.0%\n 1\tRaynos 0.0%\n 1\tTeng Siong Ong 0.0%\n 1\tViktor Kelemen 0.0%\n 1\tctide 0.0%\n 1\t8bitDesigner 0.0%\n 1\tisaacs 0.0%\n 1\tmgutz 0.0%\n 1\tpikeas 0.0%\n 1\tshuwatto 0.0%\n 1\ttstrimple 0.0%\n 1\tewoudj 0.0%\n 1\tAdam Sanderson 0.0%\n 1\tAndrii Kostenko 0.0%\n 1\tAndy Hiew 0.0%\n 1\tArpad Borsos 0.0%\n 1\tAshwin Purohit 0.0%\n 1\tBenjen 0.0%\n 1\tDarren Torpey 0.0%\n 1\tGreg Ritter 0.0%\n 1\tGregory Ritter 0.0%\n 1\tJames Herdman 0.0%\n 1\tJim Snodgrass 0.0%\n 1\tJoe McCann 0.0%\n 1\tJonathan Dumaine 0.0%\n 1\tJonathan Palardy 0.0%\n 1\tJonathan Zacsh 0.0%\n 1\tJustin Lilly 0.0%\n 1\tKen Sato 0.0%\n 1\tMaciej MaÅ‚ecki 0.0%\n 1\tMasahiro Hayashi 0.0%\n```\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2009-2012 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/express/issues" - }, - "_id": "express@3.2.6", - "_from": "express@3.2.6", - "dist": { - "shasum": "497d46002a811e34dd06a46b1f359d6f2c870356" - }, - "_resolved": "https://registry.npmjs.org/express/-/express-3.2.6.tgz" -} diff --git a/frontend/express/node_modules/express/test.js b/frontend/express/node_modules/express/test.js deleted file mode 100644 index 2b4b3577d24..00000000000 --- a/frontend/express/node_modules/express/test.js +++ /dev/null @@ -1,17 +0,0 @@ -var express = require('./'); -var app = express(); - -express.request.toJSON = function(){ - return { - method: this.method, - url: this.url, - header: this.headers - } -}; - -app.get('*', function(req, res){ - console.log(JSON.stringify(req)); - res.send(200); -}); - -app.listen(4000) diff --git a/frontend/express/node_modules/imagemagick/.npmignore b/frontend/express/node_modules/imagemagick/.npmignore deleted file mode 100644 index e852958e42c..00000000000 --- a/frontend/express/node_modules/imagemagick/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -**.DS_Store -*.jpg diff --git a/frontend/express/node_modules/imagemagick/README.md b/frontend/express/node_modules/imagemagick/README.md deleted file mode 100644 index 6400a51bf8f..00000000000 --- a/frontend/express/node_modules/imagemagick/README.md +++ /dev/null @@ -1,179 +0,0 @@ -# node-imagemagick - -[Imagemagick](http://www.imagemagick.org/) module for [Node](http://nodejs.org/). - -You can install this module using [npm](http://github.com/isaacs/npm): - - npm install imagemagick - -Requires imagemagick CLI tools to be installed. There are numerous ways to install them. For instance, if you're on OS X you can use [Homebrew](http://mxcl.github.com/homebrew/): `brew install imagemagick`. - -## Example - -```javascript -var im = require('imagemagick'); -im.readMetadata('kittens.jpg', function(err, metadata){ - if (err) throw err; - console.log('Shot at '+metadata.exif.dateTimeOriginal); -}) -// -> Shot at Tue, 06 Feb 2007 21:13:54 GMT -``` - -## API - -### convert.path - -Path to the `convert` program. Defaults to `"convert"`. - -### identify.path - -Path to the `identify` program. Defaults to `"identify"`. - -### identify(path, callback(err, features)) - -Identify file at `path` and return an object `features`. - -Example: - -```javascript -im.identify('kittens.jpg', function(err, features){ - if (err) throw err; - console.log(features); - // { format: 'JPEG', width: 3904, height: 2622, depth: 8 } -}); -``` - -### identify(args, callback(err, output)) - -Custom identification where `args` is an array of arguments. The result is returned as a raw string to `output`. - -Example: - -```javascript -im.identify(['-format', '%wx%h', 'kittens.jpg'], function(err, output){ - if (err) throw err; - console.log('dimension: '+output); - // dimension: 3904x2622 -}); -``` - -### readMetadata(path, callback(err, metadata)) - -Read metadata (i.e. exif) in `path` and return an object `metadata`. Modelled on top of `identify`. - -Example: - -```javascript -im.readMetadata('kittens.jpg', function(err, metadata){ - if (err) throw err; - console.log('Shot at '+metadata.exif.dateTimeOriginal); - // -> Shot at Tue, 06 Feb 2007 21:13:54 GMT -}); -``` - -### convert(args, callback(err, stdout, stderr)) - -Raw interface to `convert` passing arguments in the array `args`. - -Example: - -```javascript -im.convert(['kittens.jpg', '-resize', '25x120', 'kittens-small.jpg'], -function(err, stdout){ - if (err) throw err; - console.log('stdout:', stdout); -}); -``` - -### resize(options, callback(err, stdout, stderr)) - -Convenience function for resizing an image, modelled on top of `convert`. - -The `options` argument have the following default values: - -```javascript -{ - srcPath: undefined, - srcData: null, - srcFormat: null, - dstPath: undefined, - quality: 0.8, - format: 'jpg', - progressive: false, - width: 0, - height: 0, - strip: true, - filter: 'Lagrange', - sharpening: 0.2, - customArgs: [] -} -``` - -srcPath, dstPath and (at least one of) width and height are required. The rest is optional. - -Example: - -```javascript -im.resize({ - srcPath: 'kittens.jpg', - dstPath: 'kittens-small.jpg', - width: 256 -}, function(err, stdout, stderr){ - if (err) throw err; - console.log('resized kittens.jpg to fit within 256x256px'); -}); -``` - -Example with stdin/stdout: - -```javascript -var fs = require('fs'); -im.resize({ - srcData: fs.readFileSync('kittens.jpg', 'binary'), - width: 256 -}, function(err, stdout, stderr){ - if (err) throw err - fs.writeFileSync('kittens-resized.jpg', stdout, 'binary'); - console.log('resized kittens.jpg to fit within 256x256px') -}); -``` - -### crop(options, callback) ### -Convenience function for resizing and cropping an image. _crop_ uses the resize method, so _options_ and _callback_ are the same. _crop_ uses _options.srcPath_, so make sure you set it :) Using only _options.width_ or _options.height_ will create a square dimensioned image. Gravity can also be specified, it defaults to Center. Available gravity options are [NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast] - -Example: - -```javascript -im.crop({ - srcPath: path, - dstPath: 'cropped.jpg', - width: 800, - height: 600, - quality: 1, - gravity: "North" -}, function(err, stdout, stderr){ - // foo -}); -``` - -## License (MIT) - -Copyright (c) 2010-2012 Rasmus Andersson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/imagemagick/imagemagick.js b/frontend/express/node_modules/imagemagick/imagemagick.js deleted file mode 100644 index b846c0cfebf..00000000000 --- a/frontend/express/node_modules/imagemagick/imagemagick.js +++ /dev/null @@ -1,415 +0,0 @@ -var childproc = require('child_process'), - EventEmitter = require('events').EventEmitter; - - -function exec2(file, args /*, options, callback */) { - var options = { encoding: 'utf8' - , timeout: 0 - , maxBuffer: 500*1024 - , killSignal: 'SIGKILL' - , output: null - }; - - var callback = arguments[arguments.length-1]; - if ('function' != typeof callback) callback = null; - - if (typeof arguments[2] == 'object') { - var keys = Object.keys(options); - for (var i = 0; i < keys.length; i++) { - var k = keys[i]; - if (arguments[2][k] !== undefined) options[k] = arguments[2][k]; - } - } - - var child = childproc.spawn(file, args); - var killed = false; - var timedOut = false; - - var Wrapper = function(proc) { - this.proc = proc; - this.stderr = new Accumulator(); - proc.emitter = new EventEmitter(); - proc.on = proc.emitter.on.bind(proc.emitter); - this.out = proc.emitter.emit.bind(proc.emitter, 'data'); - this.err = this.stderr.out.bind(this.stderr); - this.errCurrent = this.stderr.current.bind(this.stderr); - }; - Wrapper.prototype.finish = function(err) { - this.proc.emitter.emit('end', err, this.errCurrent()); - }; - - var Accumulator = function(cb) { - this.stdout = {contents: ""}; - this.stderr = {contents: ""}; - this.callback = cb; - - var limitedWrite = function(stream) { - return function(chunk) { - stream.contents += chunk; - if (!killed && stream.contents.length > options.maxBuffer) { - child.kill(options.killSignal); - killed = true; - } - }; - }; - this.out = limitedWrite(this.stdout); - this.err = limitedWrite(this.stderr); - }; - Accumulator.prototype.current = function() { return this.stdout.contents; }; - Accumulator.prototype.errCurrent = function() { return this.stderr.contents; }; - Accumulator.prototype.finish = function(err) { this.callback(err, this.stdout.contents, this.stderr.contents); }; - - var std = callback ? new Accumulator(callback) : new Wrapper(child); - - var timeoutId; - if (options.timeout > 0) { - timeoutId = setTimeout(function () { - if (!killed) { - child.kill(options.killSignal); - timedOut = true; - killed = true; - timeoutId = null; - } - }, options.timeout); - } - - child.stdout.setEncoding(options.encoding); - child.stderr.setEncoding(options.encoding); - - child.stdout.addListener("data", function (chunk) { std.out(chunk, options.encoding); }); - child.stderr.addListener("data", function (chunk) { std.err(chunk, options.encoding); }); - - var version = process.versions.node.split('.'); - child.addListener(version[0] == 0 && version[1] < 7 ? "exit" : "close", function (code, signal) { - if (timeoutId) clearTimeout(timeoutId); - if (code === 0 && signal === null) { - std.finish(null); - } else { - var e = new Error("Command "+(timedOut ? "timed out" : "failed")+": " + std.errCurrent()); - e.timedOut = timedOut; - e.killed = killed; - e.code = code; - e.signal = signal; - std.finish(e); - } - }); - - return child; -}; - - -function parseIdentify(input) { - var lines = input.split("\n"), - prop = {}, - props = [prop], - prevIndent = 0, - indents = [indent], - currentLine, comps, indent, i; - - lines.shift(); //drop first line (Image: name.jpg) - - for (i in lines) { - currentLine = lines[i]; - indent = currentLine.search(/\S/); - if (indent >= 0) { - comps = currentLine.split(': '); - if (indent > prevIndent) indents.push(indent); - while (indent < prevIndent && props.length) { - indents.pop(); - prop = props.pop(); - prevIndent = indents[indents.length - 1]; - } - if (comps.length < 2) { - props.push(prop); - prop = prop[currentLine.split(':')[0].trim().toLowerCase()] = {}; - } else { - prop[comps[0].trim().toLowerCase()] = comps[1].trim() - } - prevIndent = indent; - } - } - return prop; -}; - -exports.identify = function(pathOrArgs, callback) { - var isCustom = Array.isArray(pathOrArgs), - isData, - args = isCustom ? ([]).concat(pathOrArgs) : ['-verbose', pathOrArgs]; - - if (typeof args[args.length-1] === 'object') { - isData = true; - pathOrArgs = args[args.length-1]; - args[args.length-1] = '-'; - if (!pathOrArgs.data) - throw new Error('first argument is missing the "data" member'); - } else if (typeof pathOrArgs === 'function') { - args[args.length-1] = '-'; - callback = pathOrArgs; - } - var proc = exec2(exports.identify.path, args, {timeout:120000}, function(err, stdout, stderr) { - var result, geometry; - if (!err) { - if (isCustom) { - result = stdout; - } else { - result = parseIdentify(stdout); - geometry = result['geometry'].split(/x/); - - result.format = result.format.match(/\S*/)[0] - result.width = parseInt(geometry[0]); - result.height = parseInt(geometry[1]); - result.depth = parseInt(result.depth); - if (result.quality !== undefined) result.quality = parseInt(result.quality) / 100; - } - } - callback(err, result); - }); - if (isData) { - if ('string' === typeof pathOrArgs.data) { - proc.stdin.setEncoding('binary'); - proc.stdin.write(pathOrArgs.data, 'binary'); - proc.stdin.end(); - } else { - proc.stdin.end(pathOrArgs.data); - } - } - return proc; -} -exports.identify.path = 'identify'; - -function ExifDate(value) { - // YYYY:MM:DD HH:MM:SS -> Date(YYYY-MM-DD HH:MM:SS +0000) - value = value.split(/ /); - return new Date(value[0].replace(/:/g, '-')+' '+ - value[1]+' +0000'); -} - -function exifKeyName(k) { - return k.replace(exifKeyName.RE, function(x){ - if (x.length === 1) return x.toLowerCase(); - else return x.substr(0,x.length-1).toLowerCase()+x.substr(x.length-1); - }); -} -exifKeyName.RE = /^[A-Z]+/; - -var exifFieldConverters = { - // Numbers - bitsPerSample:Number, compression:Number, exifImageLength:Number, - exifImageWidth:Number, exifOffset:Number, exposureProgram:Number, - flash:Number, imageLength:Number, imageWidth:Number, isoSpeedRatings:Number, - jpegInterchangeFormat:Number, jpegInterchangeFormatLength:Number, - lightSource:Number, meteringMode:Number, orientation:Number, - photometricInterpretation:Number, planarConfiguration:Number, - resolutionUnit:Number, rowsPerStrip:Number, samplesPerPixel:Number, - sensingMethod:Number, stripByteCounts:Number, subSecTime:Number, - subSecTimeDigitized:Number, subSecTimeOriginal:Number, customRendered:Number, - exposureMode:Number, focalLengthIn35mmFilm:Number, gainControl:Number, - saturation:Number, sharpness:Number, subjectDistanceRange:Number, - subSecTime:Number, subSecTimeDigitized:Number, subSecTimeOriginal:Number, - whiteBalance:Number, sceneCaptureType:Number, - - // Dates - dateTime:ExifDate, dateTimeDigitized:ExifDate, dateTimeOriginal:ExifDate -}; - -exports.readMetadata = function(path, callback) { - return exports.identify(['-format', '%[EXIF:*]', path], function(err, stdout) { - var meta = {}; - if (!err) { - stdout.split(/\n/).forEach(function(line){ - var eq_p = line.indexOf('='); - if (eq_p === -1) return; - var key = line.substr(0, eq_p).replace('/','-'), - value = line.substr(eq_p+1).trim(), - typekey = 'default'; - var p = key.indexOf(':'); - if (p !== -1) { - typekey = key.substr(0, p); - key = key.substr(p+1); - if (typekey === 'exif') { - key = exifKeyName(key); - var converter = exifFieldConverters[key]; - if (converter) value = converter(value); - } - } - if (!(typekey in meta)) meta[typekey] = {key:value}; - else meta[typekey][key] = value; - }) - } - callback(err, meta); - }); -} - -exports.convert = function(args, timeout, callback) { - var procopt = {encoding: 'binary'}; - if (typeof timeout === 'function') { - callback = timeout; - timeout = 0; - } else if (typeof timeout !== 'number') { - timeout = 0; - } - if (timeout && (timeout = parseInt(timeout)) > 0 && !isNaN(timeout)) - procopt.timeout = timeout; - return exec2(exports.convert.path, args, procopt, callback); -} -exports.convert.path = 'convert'; - -var resizeCall = function(t, callback) { - var proc = exports.convert(t.args, t.opt.timeout, callback); - if (t.opt.srcPath.match(/-$/)) { - if ('string' === typeof t.opt.srcData) { - proc.stdin.setEncoding('binary'); - proc.stdin.write(t.opt.srcData, 'binary'); - proc.stdin.end(); - } else { - proc.stdin.end(t.opt.srcData); - } - } - return proc; -} - -exports.resize = function(options, callback) { - var t = exports.resizeArgs(options); - return resizeCall(t, callback) -} - -exports.crop = function (options, callback) { - if (typeof options !== 'object') - throw new TypeError('First argument must be an object'); - if (!options.srcPath && !options.srcData) - throw new TypeError("No srcPath or data defined"); - if (!options.height && !options.width) - throw new TypeError("No width or height defined"); - - if (options.srcPath){ - var args = options.srcPath; - } else { - var args = { - data: options.srcData - }; - } - - exports.identify(args, function(err, meta) { - if (err) return callback && callback(err); - var t = exports.resizeArgs(options), - ignoreArg = false, - printNext = false, - args = []; - t.args.forEach(function (arg) { - if (printNext === true){ - console.log("arg", arg); - printNext = false; - } - // ignoreArg is set when resize flag was found - if (!ignoreArg && (arg != '-resize')) - args.push(arg); - // found resize flag! ignore the next argument - if (arg == '-resize'){ - console.log("resize arg"); - ignoreArg = true; - printNext = true; - } - if (arg === "-crop"){ - console.log("crop arg"); - printNext = true; - } - // found the argument after the resize flag; ignore it and set crop options - if ((arg != "-resize") && ignoreArg) { - var dSrc = meta.width / meta.height, - dDst = t.opt.width / t.opt.height, - resizeTo = (dSrc < dDst) ? ''+t.opt.width+'x' : 'x'+t.opt.height, - dGravity = options.gravity ? options.gravity : "Center"; - args = args.concat([ - '-resize', resizeTo, - '-gravity', dGravity, - '-crop', ''+t.opt.width + 'x' + t.opt.height + '+0+0', - '+repage' - ]); - ignoreArg = false; - } - }) - - t.args = args; - resizeCall(t, callback); - }) -} - -exports.resizeArgs = function(options) { - var opt = { - srcPath: null, - srcData: null, - srcFormat: null, - dstPath: null, - quality: 0.8, - format: 'jpg', - progressive: false, - colorspace: null, - width: 0, - height: 0, - strip: true, - filter: 'Lagrange', - sharpening: 0.2, - customArgs: [], - timeout: 0 - } - - // check options - if (typeof options !== 'object') - throw new Error('first argument must be an object'); - for (var k in opt) if (k in options) opt[k] = options[k]; - if (!opt.srcPath && !opt.srcData) - throw new Error('both srcPath and srcData are empty'); - - // normalize options - if (!opt.format) opt.format = 'jpg'; - if (!opt.srcPath) { - opt.srcPath = (opt.srcFormat ? opt.srcFormat +':-' : '-'); // stdin - } - if (!opt.dstPath) - opt.dstPath = (opt.format ? opt.format+':-' : '-'); // stdout - if (opt.width === 0 && opt.height === 0) - throw new Error('both width and height can not be 0 (zero)'); - - // build args - var args = [opt.srcPath]; - if (opt.sharpening > 0) { - args = args.concat([ - '-set', 'option:filter:blur', String(1.0-opt.sharpening)]); - } - if (opt.filter) { - args.push('-filter'); - args.push(opt.filter); - } - if (opt.strip) { - args.push('-strip'); - } - if (opt.width || opt.height) { - args.push('-resize'); - if (opt.height === 0) args.push(String(opt.width)); - else if (opt.width === 0) args.push('x'+String(opt.height)); - else args.push(String(opt.width)+'x'+String(opt.height)); - } - opt.format = opt.format.toLowerCase(); - var isJPEG = (opt.format === 'jpg' || opt.format === 'jpeg'); - if (isJPEG && opt.progressive) { - args.push('-interlace'); - args.push('plane'); - } - if (isJPEG || opt.format === 'png') { - args.push('-quality'); - args.push(Math.round(opt.quality * 100.0).toString()); - } - else if (opt.format === 'miff' || opt.format === 'mif') { - args.push('-quality'); - args.push(Math.round(opt.quality * 9.0).toString()); - } - if (opt.colorspace) { - args.push('-colorspace'); - args.push(opt.colorspace); - } - if (Array.isArray(opt.customArgs) && opt.customArgs.length) - args = args.concat(opt.customArgs); - args.push(opt.dstPath); - - return {opt:opt, args:args}; -} diff --git a/frontend/express/node_modules/imagemagick/package.json b/frontend/express/node_modules/imagemagick/package.json deleted file mode 100644 index a5127326fde..00000000000 --- a/frontend/express/node_modules/imagemagick/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "imagemagick", - "description": "A wrapper around the imagemagick cli", - "version": "0.1.3", - "author": { - "name": "Rasmus Andersson", - "email": "http://rsms.me/" - }, - "licenses": [ - "MIT" - ], - "repository": { - "type": "git", - "url": "http://github.com/rsms/node-imagemagick.git" - }, - "engine": [ - "node >=0.6" - ], - "main": "imagemagick", - "readme": "# node-imagemagick\n\n[Imagemagick](http://www.imagemagick.org/) module for [Node](http://nodejs.org/).\n\nYou can install this module using [npm](http://github.com/isaacs/npm):\n\n npm install imagemagick\n\nRequires imagemagick CLI tools to be installed. There are numerous ways to install them. For instance, if you're on OS X you can use [Homebrew](http://mxcl.github.com/homebrew/): `brew install imagemagick`.\n\n## Example\n\n```javascript\nvar im = require('imagemagick');\nim.readMetadata('kittens.jpg', function(err, metadata){\n if (err) throw err;\n console.log('Shot at '+metadata.exif.dateTimeOriginal);\n})\n// -> Shot at Tue, 06 Feb 2007 21:13:54 GMT\n```\n\n## API\n\n### convert.path\n\nPath to the `convert` program. Defaults to `\"convert\"`.\n\n### identify.path\n\nPath to the `identify` program. Defaults to `\"identify\"`.\n\n### identify(path, callback(err, features))\n\nIdentify file at `path` and return an object `features`.\n\nExample:\n\n```javascript\nim.identify('kittens.jpg', function(err, features){\n if (err) throw err;\n console.log(features);\n // { format: 'JPEG', width: 3904, height: 2622, depth: 8 }\n});\n```\n\n### identify(args, callback(err, output))\n\nCustom identification where `args` is an array of arguments. The result is returned as a raw string to `output`.\n\nExample:\n\n```javascript\nim.identify(['-format', '%wx%h', 'kittens.jpg'], function(err, output){\n if (err) throw err;\n console.log('dimension: '+output);\n // dimension: 3904x2622\n});\n```\n\n### readMetadata(path, callback(err, metadata))\n\nRead metadata (i.e. exif) in `path` and return an object `metadata`. Modelled on top of `identify`.\n\nExample:\n\n```javascript\nim.readMetadata('kittens.jpg', function(err, metadata){\n if (err) throw err;\n console.log('Shot at '+metadata.exif.dateTimeOriginal);\n // -> Shot at Tue, 06 Feb 2007 21:13:54 GMT\n});\n```\n\n### convert(args, callback(err, stdout, stderr))\n\nRaw interface to `convert` passing arguments in the array `args`.\n\nExample:\n\n```javascript\nim.convert(['kittens.jpg', '-resize', '25x120', 'kittens-small.jpg'], \nfunction(err, stdout){\n if (err) throw err;\n console.log('stdout:', stdout);\n});\n```\n\n### resize(options, callback(err, stdout, stderr))\n\nConvenience function for resizing an image, modelled on top of `convert`.\n\nThe `options` argument have the following default values:\n\n```javascript\n{\n srcPath: undefined,\n srcData: null,\n srcFormat: null,\n dstPath: undefined,\n quality: 0.8,\n format: 'jpg',\n progressive: false,\n width: 0,\n height: 0,\n strip: true,\n filter: 'Lagrange',\n sharpening: 0.2,\n customArgs: []\n}\n```\n\nsrcPath, dstPath and (at least one of) width and height are required. The rest is optional.\n\nExample:\n\n```javascript\nim.resize({\n srcPath: 'kittens.jpg',\n dstPath: 'kittens-small.jpg',\n width: 256\n}, function(err, stdout, stderr){\n if (err) throw err;\n console.log('resized kittens.jpg to fit within 256x256px');\n});\n```\n\nExample with stdin/stdout:\n\n```javascript\nvar fs = require('fs');\nim.resize({\n srcData: fs.readFileSync('kittens.jpg', 'binary'),\n width: 256\n}, function(err, stdout, stderr){\n if (err) throw err\n fs.writeFileSync('kittens-resized.jpg', stdout, 'binary');\n console.log('resized kittens.jpg to fit within 256x256px')\n});\n```\n\n### crop(options, callback) ###\nConvenience function for resizing and cropping an image. _crop_ uses the resize method, so _options_ and _callback_ are the same. _crop_ uses _options.srcPath_, so make sure you set it :) Using only _options.width_ or _options.height_ will create a square dimensioned image. Gravity can also be specified, it defaults to Center. Available gravity options are [NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast]\n\nExample:\n\n```javascript\nim.crop({\n srcPath: path,\n dstPath: 'cropped.jpg',\n width: 800,\n height: 600,\n quality: 1,\n gravity: \"North\"\n}, function(err, stdout, stderr){\n // foo\n});\n```\n\n## License (MIT)\n\nCopyright (c) 2010-2012 Rasmus Andersson \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n", - "readmeFilename": "README.md", - "_id": "imagemagick@0.1.3", - "_from": "imagemagick" -} diff --git a/frontend/express/node_modules/imagemagick/test-crop.js b/frontend/express/node_modules/imagemagick/test-crop.js deleted file mode 100644 index a122a60d41c..00000000000 --- a/frontend/express/node_modules/imagemagick/test-crop.js +++ /dev/null @@ -1,35 +0,0 @@ -var fs = require('fs'), - im = require('./imagemagick'); - -var path = __dirname+'/sample-images/blue-bottle-coffee.jpg'; - -(function () { - var opt, timeStarted = new Date; - im.crop(opt = { - srcPath: path, - dstPath: 'cropped.jpg', - width: 200, - height: 90, - quality: 1 - }, function (err, stdout, stderr){ - if (err) return console.error(err.stack || err); - console.log('crop(',opt,') ->', stdout); - console.log('Real time spent: '+(new Date() - timeStarted) + ' ms'); - }); -})(); - -(function () { - var opt, timeStarted = new Date; - im.crop(opt = { - srcPath: path, - dstPath: 'cropped2.jpg', - width: 200, - height: 90, - gravity: "North", - quality: 1 - }, function (err, stdout, stderr){ - if (err) return console.error(err.stack || err); - console.log('crop(',opt,') ->', stdout); - console.log('Real time spent: '+(new Date() - timeStarted) + ' ms'); - }); -})(); diff --git a/frontend/express/node_modules/imagemagick/test.js b/frontend/express/node_modules/imagemagick/test.js deleted file mode 100644 index 2678c93318a..00000000000 --- a/frontend/express/node_modules/imagemagick/test.js +++ /dev/null @@ -1,52 +0,0 @@ -var fs = require('fs'), - im = require('./imagemagick'); - -var path = __dirname+'/sample-images/blue-bottle-coffee.jpg'; -var imdata = fs.readFileSync(path, 'binary'); - -im.identify(path, function (err, features){ - if (err) return console.error(err.stack || err); - console.log('identify(path) ->', features); -}) - -im.identify({data:imdata}, function (err, features){ - if (err) return console.error(err.stack || err); - console.log('identify({data:imdata}) ->', features); -}) - -im.readMetadata(path, function (err, metadata){ - if (err) return console.error(err.stack || err); - console.log('readMetadata(path) ->', metadata); -}) - -im.readMetadata({data:imdata}, function (err, metadata){ - if (err) return console.error(err.stack || err); - console.log('readMetadata({data:imdata} ->', metadata); -}) - -var timeStarted = new Date; -im.resize({ - srcPath: path, - dstPath: 'test-resized.jpg', - width: 256 -}, function (err, stdout, stderr){ - if (err) return console.error(err.stack || err); - console.log('resize(...) wrote "test-resized.jpg"'); - console.log('real time taken for convert: '+((new Date)-timeStarted)+' ms'); - im.identify(['-format', '%b', 'test-resized.jpg'], function (err, r){ - if (err) throw err; - console.log("identify(['-format', '%b', 'test-resized.jpg']) ->", r); - }) -}) - -timeStarted = new Date; -im.resize({ - srcData: imdata, - width: 256 -}, function (err, stdout, stderr){ - if (err) return console.error(err.stack || err); - console.log('real time taken for convert (with buffers): '+ - ((new Date)-timeStarted)+' ms'); - fs.writeFileSync('test-resized-io.jpg', stdout, 'binary'); - console.log('resize(...) wrote "test-resized.jpg" ('+stdout.length+' Bytes)'); -}) diff --git a/frontend/express/node_modules/mongodb/.npmignore b/frontend/express/node_modules/mongodb/.npmignore deleted file mode 100644 index ed901d90e73..00000000000 --- a/frontend/express/node_modules/mongodb/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -.git* -.buildinfo -.mongodb -docs/ -docs/sphinx-docs -data/ -dev/ -examples/ -test/ -.DS_Store - - diff --git a/frontend/express/node_modules/mongodb/.travis.yml b/frontend/express/node_modules/mongodb/.travis.yml deleted file mode 100644 index 0140117b64d..00000000000 --- a/frontend/express/node_modules/mongodb/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.10 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/CONTRIBUTING.md b/frontend/express/node_modules/mongodb/CONTRIBUTING.md deleted file mode 100644 index 2a1c52e2abd..00000000000 --- a/frontend/express/node_modules/mongodb/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -## Contributing to the driver - -### Bugfixes - -- Before starting to write code, look for existing [tickets](https://github.com/mongodb/node-mongodb-native/issues) or [create one](https://github.com/mongodb/node-mongodb-native/issues/new) for your specific issue. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch. -- Fork the [repo](https://github.com/mongodb/node-mongodb-native) _or_ for small documentation changes, navigate to the source on github and click the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. -- Follow the general coding style of the rest of the project: - - 2 space tabs - - no trailing whitespace - - comma last - - inline documentation for new methods, class members, etc - - 0 space between conditionals/functions, and their parenthesis and curly braces - - `if(..) {` - - `for(..) {` - - `while(..) {` - - `function(err) {` -- Write tests and make sure they pass (execute `make test` from the cmd line to run the test suite). - -### Documentation - -To contribute to the [API documentation](http://mongodb.github.com/node-mongodb-native/) just make your changes to the inline documentation of the appropriate [source code](https://github.com/mongodb/node-mongodb-native/tree/master/docs) in the master branch and submit a [pull request](https://help.github.com/articles/using-pull-requests/). You might also use the github [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. - -If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make generate_docs`. Make sure you have the python documentation framework sphinx installed `easy_install sphinx`. The docs are generated under `docs/build'. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes. \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/HISTORY b/frontend/express/node_modules/mongodb/HISTORY deleted file mode 100644 index d71e751856f..00000000000 --- a/frontend/express/node_modules/mongodb/HISTORY +++ /dev/null @@ -1,408 +0,0 @@ -0.9.9.2 2012-02-17 ------------------- -* Improved detection of Buffers using Buffer.isBuffer instead of instanceof. -* Added wrap error around db.dropDatabase to catch all errors (Issue #512) -* Added aggregate helper to collection, only for MongoDB >= 2.1 - -0.9.9.1 2012-02-15 ------------------- -* Better handling of safe when using some commands such as createIndex, ensureIndex, addUser, removeUser, createCollection. -* Mapreduce now throws error if out parameter is not specified. - -0.9.9 2012-02-13 ----------------- -* Added createFromTime method on ObjectID to allow for queries against _id more easily using the timestamp. -* Db.close(true) now makes connection unusable as it's been force closed by app. -* Fixed mapReduce and group functions to correctly send slaveOk on queries. -* Fixes for find method to correctly work with find(query, fields, callback) (Issue #506). -* A fix for connection error handling when using the SSL on MongoDB. - -0.9.8-7 2012-02-06 ------------------- -* Simplified findOne to use the find command instead of the custom code (Issue #498). -* BSON JS parser not also checks for _bsonType variable in case BSON object is in weird scope (Issue #495). - -0.9.8-6 2012-02-04 ------------------- -* Removed the check for replicaset change code as it will never work with node.js. - -0.9.8-5 2012-02-02 ------------------- -* Added geoNear command to Collection. -* Added geoHaystackSearch command to Collection. -* Added indexes command to collection to retrieve the indexes on a Collection. -* Added stats command to collection to retrieve the statistics on a Collection. -* Added listDatabases command to admin object to allow retrieval of all available dbs. -* Changed createCreateIndexCommand to work better with options. -* Fixed dereference method on Db class to correctly dereference Db reference objects. -* Moved connect object onto Db class(Db.connect) as well as keeping backward compatibility. -* Removed writeBuffer method from gridstore, write handles switching automatically now. -* Changed readBuffer to read on Gridstore, Gridstore now only supports Binary Buffers no Strings anymore. -* Moved Long class to bson directory. - -0.9.8-4 2012-01-28 ------------------- -* Added reIndex command to collection and db level. -* Added support for $returnKey, $maxScan, $min, $max, $showDiskLoc, $comment to cursor and find/findOne methods. -* Added dropDups and v option to createIndex and ensureIndex. -* Added isCapped method to Collection. -* Added indexExists method to Collection. -* Added findAndRemove method to Collection. -* Fixed bug for replicaset connection when no active servers in the set. -* Fixed bug for replicaset connections when errors occur during connection. -* Merged in patch for BSON Number handling from Lee Salzman, did some small fixes and added test coverage. - -0.9.8-3 2012-01-21 ------------------- -* Workaround for issue with Object.defineProperty (Issue #484) -* ObjectID generation with date does not set rest of fields to zero (Issue #482) - -0.9.8-2 2012-01-20 ------------------- -* Fixed a missing this in the ReplSetServers constructor. - -0.9.8-1 2012-01-17 ------------------- -* FindAndModify bug fix for duplicate errors (Issue #481) - -0.9.8 2012-01-17 ----------------- -* Replicasets now correctly adjusts to live changes in the replicaset configuration on the servers, reconnecting correctly. - - Set the interval for checking for changes setting the replicaSetCheckInterval property when creating the ReplSetServers instance or on db.serverConfig.replicaSetCheckInterval. (default 1000 miliseconds) -* Fixes formattedOrderClause in collection.js to accept a plain hash as a parameter (Issue #469) https://github.com/tedeh -* Removed duplicate code for formattedOrderClause and moved to utils module -* Pass in poolSize for ReplSetServers to set default poolSize for new replicaset members -* Bug fix for BSON JS deserializer. Isolating the eval functions in separate functions to avoid V8 deoptimizations -* Correct handling of illegal BSON messages during deserialization -* Fixed Infinite loop when reading GridFs file with no chunks (Issue #471) -* Correctly update existing user password when using addUser (Issue #470) - -0.9.7.3-5 2012-01-04 --------------------- -* Fix for RegExp serialization for 0.4.X where typeof /regexp/ == 'function' vs in 0.6.X typeof /regexp/ == 'object' -* Don't allow keepAlive and setNoDelay for 0.4.X as it throws errors - -0.9.7.3-4 2012-01-04 --------------------- -* Chased down potential memory leak on findAndModify, Issue #467 (node.js removeAllListeners leaves the key in the _events object, node.js bug on eventlistener?, leads to extremely slow memory leak on listener object) -* Sanity checks for GridFS performance with benchmark added - -0.9.7.3-3 2012-01-04 --------------------- -* Bug fixes for performance issues going form 0.9.6.X to 0.9.7.X on linux -* BSON bug fixes for performance - -0.9.7.3-2 2012-01-02 --------------------- -* Fixed up documentation to reflect the preferred way of instantiating bson types -* GC bug fix for JS bson parser to avoid stop-and-go GC collection - -0.9.7.3-1 2012-01-02 --------------------- -* Fix to make db.bson_serializer and db.bson_deserializer work as it did previously - -0.9.7.3 2011-12-30 --------------------- -* Moved BSON_BINARY_SUBTYPE_DEFAULT from BSON object to Binary object and removed the BSON_BINARY_ prefixes -* Removed Native BSON types, C++ parser uses JS types (faster due to cost of crossing the JS-C++ barrier for each call) -* Added build fix for 0.4.X branch of Node.js where GetOwnPropertyNames is not defined in v8 -* Fix for wire protocol parser for corner situation where the message is larger than the maximum socket buffer in node.js (Issue #464, #461, #447) -* Connection pool status set to connected on poolReady, isConnected returns false on anything but connected status (Issue #455) - -0.9.7.2-5 2011-12-22 --------------------- -* Brand spanking new Streaming Cursor support Issue #458 (https://github.com/christkv/node-mongodb-native/pull/458) thanks to Mr Aaron Heckmann - -0.9.7.2-4 2011-12-21 --------------------- -* Refactoring of callback code to work around performance regression on linux -* Fixed group function to correctly use the command mode as default - -0.9.7.2-3 2011-12-18 --------------------- -* Fixed error handling for findAndModify while still working for mongodb 1.8.6 (Issue #450). -* Allow for force send query to primary, pass option (read:'primary') on find command. - * ``find({a:1}, {read:'primary'}).toArray(function(err, items) {});`` - -0.9.7.2-2 2011-12-16 --------------------- -* Fixes infinite streamRecords QueryFailure fix when using Mongos (Issue #442) - -0.9.7.2-1 2011-12-16 --------------------- -* ~10% perf improvement for ObjectId#toHexString (Issue #448, https://github.com/aheckmann) -* Only using process.nextTick on errors emitted on callbacks not on all parsing, reduces number of ticks in the driver -* Changed parsing off bson messages to use process.nextTick to do bson parsing in batches if the message is over 10K as to yield more time to the event look increasing concurrency on big mongoreply messages with multiple documents - -0.9.7.2 2011-12-15 ------------------- -* Added SSL support for future version of mongodb (VERY VERY EXPERIMENTAL) - * pass in the ssl:true option to the server or replicaset server config to enable - * a bug either in mongodb or node.js does not allow for more than 1 connection pr db instance (poolSize:1). -* Added getTimestamp() method to objectID that returns a date object -* Added finalize function to collection.group - * function group (keys, condition, initial, reduce, finalize, command, callback) -* Reaper no longer using setTimeout to handle reaping. Triggering is done in the general flow leading to predictable behavior. - * reaperInterval, set interval for reaper (default 10000 miliseconds) - * reaperTimeout, set timeout for calls (default 30000 miliseconds) - * reaper, enable/disable reaper (default false) -* Work around for issues with findAndModify during high concurrency load, insure that the behavior is the same across the 1.8.X branch and 2.X branch of MongoDb -* Reworked multiple db's sharing same connection pool to behave correctly on error, timeout and close -* EnsureIndex command can be executed without a callback (Issue #438) -* Eval function no accepts options including nolock (Issue #432) - * eval(code, parameters, options, callback) (where options = {nolock:true}) - -0.9.7.1-4 2011-11-27 --------------------- -* Replaced install.sh with install.js to install correctly on all supported os's - -0.9.7.1-3 2011-11-27 --------------------- -* Fixes incorrect scope for ensureIndex error wrapping (Issue #419) https://github.com/ritch - -0.9.7.1-2 2011-11-27 --------------------- -* Set statistical selection strategy as default for secondary choice. - -0.9.7.1-1 2011-11-27 --------------------- -* Better handling of single server reconnect (fixes some bugs) -* Better test coverage of single server failure -* Correct handling of callbacks on replicaset servers when firewall dropping packets, correct reconnect - -0.9.7.1 2011-11-24 ------------------- -* Better handling of dead server for single server instances -* FindOne and find treats selector == null as {}, Issue #403 -* Possible to pass in a strategy for the replicaset to pick secondary reader node - * parameter strategy - * ping (default), pings the servers and picks the one with the lowest ping time - * statistical, measures each request and pick the one with the lowest mean and std deviation -* Set replicaset read preference replicaset.setReadPreference() - * Server.READ_PRIMARY (use primary server for reads) - * Server.READ_SECONDARY (from a secondary server (uses the strategy set)) - * tags, {object of tags} -* Added replay of commands issued to a closed connection when the connection is re-established -* Fix isConnected and close on unopened connections. Issue #409, fix by (https://github.com/sethml) -* Moved reaper to db.open instead of constructor (Issue #406) -* Allows passing through of socket connection settings to Server or ReplSetServer under the option socketOptions - * timeout = set seconds before connection times out (default 0) - * noDelay = Disables the Nagle algorithm (default true) - * keepAlive = Set if keepAlive is used (default 0, which means no keepAlive, set higher than 0 for keepAlive) - * encoding = ['ascii', 'utf8', or 'base64'] (default null) -* Fixes for handling of errors during shutdown off a socket connection -* Correctly applies socket options including timeout -* Cleanup of test management code to close connections correctly -* Handle parser errors better, closing down the connection and emitting an error -* Correctly emit errors from server.js only wrapping errors that are strings - -0.9.7 2011-11-10 ----------------- -* Added priority setting to replicaset manager -* Added correct handling of passive servers in replicaset -* Reworked socket code for simpler clearer handling -* Correct handling of connections in test helpers -* Added control of retries on failure - * control with parameters retryMiliSeconds and numberOfRetries when creating a db instance -* Added reaper that will timeout and cleanup queries that never return - * control with parameters reaperInterval and reaperTimeout when creating a db instance -* Refactored test helper classes for replicaset tests -* Allows raw (no bson parser mode for insert, update, remove, find and findOne) - * control raw mode passing in option raw:true on the commands - * will return buffers with the binary bson objects -* Fixed memory leak in cursor.toArray -* Fixed bug in command creation for mongodb server with wrong scope of call -* Added db(dbName) method to db.js to allow for reuse of connections against other databases -* Serialization of functions in an object is off by default, override with parameter - * serializeFunctions [true/false] on db level, collection level or individual insert/update/findAndModify -* Added Long.fromString to c++ class and fixed minor bug in the code (Test case for $gt operator on 64-bit integers, Issue #394) -* FindOne and find now share same code execution and will work in the same manner, Issue #399 -* Fix for tailable cursors, Issue #384 -* Fix for Cursor rewind broken, Issue #389 -* Allow Gridstore.exist to query using regexp, Issue #387, fix by (https://github.com/kaij) -* Updated documentation on https://github.com/christkv/node-mongodb-native -* Fixed toJSON methods across all objects for BSON, Binary return Base64 Encoded data - -0.9.6-22 2011-10-15 -------------------- -* Fixed bug in js bson parser that could cause wrong object size on serialization, Issue #370 -* Fixed bug in findAndModify that did not throw error on replicaset timeout, Issue #373 - -0.9.6-21 2011-10-05 -------------------- -* Reworked reconnect code to work correctly -* Handling errors in different parts of the code to ensure that it does not lock the connection -* Consistent error handling for Object.createFromHexString for JS and C++ - -0.9.6-20 2011-10-04 -------------------- -* Reworked bson.js parser to get rid off Array.shift() due to it allocating new memory for each call. Speedup varies between 5-15% depending on doc -* Reworked bson.cc to throw error when trying to serialize js bson types -* Added MinKey, MaxKey and Double support for JS and C++ parser -* Reworked socket handling code to emit errors on unparsable messages -* Added logger option for Db class, lets you pass in a function in the shape - { - log : function(message, object) {}, - error : function(errorMessage, errorObject) {}, - debug : function(debugMessage, object) {}, - } - - Usage is new Db(new Server(..), {logger: loggerInstance}) - -0.9.6-19 2011-09-29 -------------------- -* Fixing compatibility issues between C++ bson parser and js parser -* Added Symbol support to C++ parser -* Fixed socket handling bug for seldom misaligned message from mongodb -* Correctly handles serialization of functions using the C++ bson parser - -0.9.6-18 2011-09-22 -------------------- -* Fixed bug in waitForConnection that would lead to 100% cpu usage, Issue #352 - -0.9.6-17 2011-09-21 -------------------- -* Fixed broken exception test causing bamboo to hang -* Handling correctly command+lastError when both return results as in findAndModify, Issue #351 - -0.9.6-16 2011-09-14 -------------------- -* Fixing a bunch of issues with compatibility with MongoDB 2.0.X branch. Some fairly big changes in behavior from 1.8.X to 2.0.X on the server. -* Error Connection MongoDB V2.0.0 with Auth=true, Issue #348 - -0.9.6-15 2011-09-09 -------------------- -* Fixed issue where pools would not be correctly cleaned up after an error, Issue #345 -* Fixed authentication issue with secondary servers in Replicaset, Issue #334 -* Duplicate replica-set servers when omitting port, Issue #341 -* Fixing findAndModify to correctly work with Replicasets ensuring proper error handling, Issue #336 -* Merged in code from (https://github.com/aheckmann) that checks for global variable leaks - -0.9.6-14 2011-09-05 -------------------- -* Minor fixes for error handling in cursor streaming (https://github.com/sethml), Issue #332 -* Minor doc fixes -* Some more cursor sort tests added, Issue #333 -* Fixes to work with 0.5.X branch -* Fix Db not removing reconnect listener from serverConfig, (https://github.com/sbrekken), Issue #337 -* Removed node_events.h includes (https://github.com/jannehietamaki), Issue #339 -* Implement correct safe/strict mode for findAndModify. - -0.9.6-13 2011-08-24 -------------------- -* Db names correctly error checked for illegal characters - -0.9.6-12 2011-08-24 -------------------- -* Nasty bug in GridFS if you changed the default chunk size -* Fixed error handling bug in findOne - -0.9.6-11 2011-08-23 -------------------- -* Timeout option not correctly making it to the cursor, Issue #320, Fix from (https://github.com/year2013) -* Fixes for memory leaks when using buffers and C++ parser -* Fixes to make tests pass on 0.5.X -* Cleanup of bson.js to remove duplicated code paths -* Fix for errors occurring in ensureIndex, Issue #326 -* Removing require.paths to make tests work with the 0.5.X branch - -0.9.6-10 2011-08-11 -------------------- -* Specific type Double for capped collections (https://github.com/mbostock), Issue #312 -* Decorating Errors with all all object info from Mongo (https://github.com/laurie71), Issue #308 -* Implementing fixes for mongodb 1.9.1 and higher to make tests pass -* Admin validateCollection now takes an options argument for you to pass in full option -* Implemented keepGoing parameter for mongodb 1.9.1 or higher, Issue #310 -* Added test for read_secondary count issue, merged in fix from (https://github.com/year2013), Issue #317 - -0.9.6-9 -------- -* Bug fix for bson parsing the key '':'' correctly without crashing - -0.9.6-8 -------- -* Changed to using node.js crypto library MD5 digest -* Connect method support documented mongodb: syntax by (https://github.com/sethml) -* Support Symbol type for BSON, serializes to it's own type Symbol, Issue #302, #288 -* Code object without scope serializing to correct BSON type -* Lot's of fixes to avoid double callbacks (https://github.com/aheckmann) Issue #304 -* Long deserializes as Number for values in the range -2^53 to 2^53, Issue #305 (https://github.com/sethml) -* Fixed C++ parser to reflect JS parser handling of long deserialization -* Bson small optimizations - -0.9.6-7 2011-07-13 ------------------- -* JS Bson deserialization bug #287 - -0.9.6-6 2011-07-12 ------------------- -* FindAndModify not returning error message as other methods Issue #277 -* Added test coverage for $push, $pushAll and $inc atomic operations -* Correct Error handling for non 12/24 bit ids on Pure JS ObjectID class Issue #276 -* Fixed terrible deserialization bug in js bson code #285 -* Fix by andrewjstone to avoid throwing errors when this.primary not defined - -0.9.6-5 2011-07-06 ------------------- -* Rewritten BSON js parser now faster than the C parser on my core2duo laptop -* Added option full to indexInformation to get all index info Issue #265 -* Passing in ObjectID for new Gridstore works correctly Issue #272 - -0.9.6-4 2011-07-01 ------------------- -* Added test and bug fix for insert/update/remove without callback supplied - -0.9.6-3 2011-07-01 ------------------- -* Added simple grid class called Grid with put, get, delete methods -* Fixed writeBuffer/readBuffer methods on GridStore so they work correctly -* Automatic handling of buffers when using write method on GridStore -* GridStore now accepts a ObjectID instead of file name for write and read methods -* GridStore.list accepts id option to return of file ids instead of filenames -* GridStore close method returns document for the file allowing user to reference _id field - -0.9.6-2 2011-06-30 ------------------- -* Fixes for reconnect logic for server object (replays auth correctly) -* More testcases for auth -* Fixes in error handling for replicaset -* Fixed bug with safe parameter that would fail to execute safe when passing w or wtimeout -* Fixed slaveOk bug for findOne method -* Implemented auth support for replicaset and test cases -* Fixed error when not passing in rs_name - -0.9.6-1 2011-06-25 ------------------- -* Fixes for test to run properly using c++ bson parser -* Fixes for dbref in native parser (correctly handles ref without db component) -* Connection fixes for replicasets to avoid runtime conditions in cygwin (https://github.com/vincentcr) -* Fixes for timestamp in js bson parser (distinct timestamp type now) - -0.9.6 2011-06-21 ----------------- -* Worked around npm version handling bug -* Race condition fix for cygwin (https://github.com/vincentcr) - -0.9.5-1 2011-06-21 ------------------- -* Extracted Timestamp as separate class for bson js parser to avoid instanceof problems -* Fixed driver strict mode issue - -0.9.5 2011-06-20 ----------------- -* Replicaset support (failover and reading from secondary servers) -* Removed ServerPair and ServerCluster -* Added connection pool functionality -* Fixed serious bug in C++ bson parser where bytes > 127 would generate 2 byte sequences -* Allows for forcing the server to assign ObjectID's using the option {forceServerObjectId: true} - -0.6.8 ------ -* Removed multiple message concept from bson -* Changed db.open(db) to be db.open(err, db) - -0.1 2010-01-30 --------------- -* Initial release support of driver using native node.js interface -* Supports gridfs specification -* Supports admin functionality \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/Makefile b/frontend/express/node_modules/mongodb/Makefile deleted file mode 100644 index 59d2bfeb89e..00000000000 --- a/frontend/express/node_modules/mongodb/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit -DOX = node_modules/dox/bin/dox -name = all - -total: build_native - -test_functional: - node test/runner.js -t functional - -test_ssl: - node test/runner.js -t ssl - -test_replicaset: - node test/runner.js -t replicaset - -test_sharded: - node test/runner.js -t sharded - -test_auth: - node test/runner.js -t auth - -generate_docs: - $(NODE) dev/tools/build-docs.js - make --directory=./docs/sphinx-docs --file=Makefile html - -.PHONY: total diff --git a/frontend/express/node_modules/mongodb/Readme.md b/frontend/express/node_modules/mongodb/Readme.md deleted file mode 100644 index 306fde7bd0e..00000000000 --- a/frontend/express/node_modules/mongodb/Readme.md +++ /dev/null @@ -1,442 +0,0 @@ -Up to date documentation -======================== - -[Documentation](http://mongodb.github.com/node-mongodb-native/) - -Install -======= - -To install the most recent release from npm, run: - - npm install mongodb - -That may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version) - -To install the latest from the repository, run:: - - npm install path/to/node-mongodb-native - -Community -========= -Check out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver. - -Live Examples -============ - - -Introduction -============ - -This is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/. - -A simple example of inserting a document. - -```javascript - var client = new Db('test', new Server("127.0.0.1", 27017, {}), {w: 1}), - test = function (err, collection) { - collection.insert({a:2}, function(err, docs) { - - collection.count(function(err, count) { - test.assertEquals(1, count); - }); - - // Locate all the entries using find - collection.find().toArray(function(err, results) { - test.assertEquals(1, results.length); - test.assertTrue(results[0].a === 2); - - // Let's close the db - client.close(); - }); - }); - }; - - client.open(function(err, p_client) { - client.collection('test_insert', test); - }); -``` - -Data types -========== - -To store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code). - -In particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example: - -```javascript - // Get the objectID type - var ObjectID = require('mongodb').ObjectID; - - var idString = '4e4e1638c85e808431000003'; - collection.findOne({_id: new ObjectID(idString)}, console.log) // ok - collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined -``` - -Here are the constructors the non-Javascript BSON primitive types: - -```javascript - // Fetch the library - var mongo = require('mongodb'); - // Create new instances of BSON types - new mongo.Long(numberString) - new mongo.ObjectID(hexString) - new mongo.Timestamp() // the actual unique number is generated on insert. - new mongo.DBRef(collectionName, id, dbName) - new mongo.Binary(buffer) // takes a string or Buffer - new mongo.Code(code, [context]) - new mongo.Symbol(string) - new mongo.MinKey() - new mongo.MaxKey() - new mongo.Double(number) // Force double storage -``` - -The C/C++ bson parser/serializer --------------------------------- - -If you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below - -```javascript - // using native_parser: - var client = new Db('integration_tests_20', - new Server("127.0.0.1", 27017), - {native_parser:true}); -``` - -The C++ parser uses the js objects both for serialization and deserialization. - -GitHub information -================== - -The source code is available at http://github.com/mongodb/node-mongodb-native. -You can either clone the repository or download a tarball of the latest release. - -Once you have the source you can test the driver by running - - $ make test - -in the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass. - -Examples -======== - -For examples look in the examples/ directory. You can execute the examples using node. - - $ cd examples - $ node queries.js - -GridStore -========= - -The GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition. - -For more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) - -Replicasets -=========== -For more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md) - -Primary Key Factories ---------------------- - -Defining your own primary key factory allows you to generate your own series of id's -(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long "string". - -Simple example below - -```javascript - // Custom factory (need to provide a 12 byte array); - CustomPKFactory = function() {} - CustomPKFactory.prototype = new Object(); - CustomPKFactory.createPk = function() { - return new ObjectID("aaaaaaaaaaaa"); - } - - var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory}); - p_client.open(function(err, p_client) { - p_client.dropDatabase(function(err, done) { - p_client.createCollection('test_custom_key', function(err, collection) { - collection.insert({'a':1}, function(err, docs) { - collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) { - cursor.toArray(function(err, items) { - test.assertEquals(1, items.length); - - // Let's close the db - p_client.close(); - }); - }); - }); - }); - }); - }); -``` - -Strict mode ------------ - -Each database has an optional strict mode. If it is set then asking for a collection -that does not exist will return an Error object in the callback. Similarly if you -attempt to create a collection that already exists. Strict is provided for convenience. - -```javascript - var error_client = new Db('integration_tests_', new Server("127.0.0.1", 27017, {auto_reconnect: false}), {strict:true}); - test.assertEquals(true, error_client.strict); - - error_client.open(function(err, error_client) { - error_client.collection('does-not-exist', function(err, collection) { - test.assertTrue(err instanceof Error); - test.assertEquals("Collection does-not-exist does not exist. Currently in strict mode.", err.message); - }); - - error_client.createCollection('test_strict_access_collection', function(err, collection) { - error_client.collection('test_strict_access_collection', function(err, collection) { - test.assertTrue(collection instanceof Collection); - // Let's close the db - error_client.close(); - }); - }); - }); -``` - -Documentation -============= - -If this document doesn't answer your questions, see the source of -[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js) -or [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js), -or the documentation at MongoDB for query and update formats. - -Find ----- - -The find method is actually a factory method to create -Cursor objects. A Cursor lazily uses the connection the first time -you call `nextObject`, `each`, or `toArray`. - -The basic operation on a cursor is the `nextObject` method -that fetches the next matching document from the database. The convenience -methods `each` and `toArray` call `nextObject` until the cursor is exhausted. - -Signatures: - -```javascript - var cursor = collection.find(query, [fields], options); - cursor.sort(fields).limit(n).skip(m). - - cursor.nextObject(function(err, doc) {}); - cursor.each(function(err, doc) {}); - cursor.toArray(function(err, docs) {}); - - cursor.rewind() // reset the cursor to its initial state. -``` - -Useful chainable methods of cursor. These can optionally be options of `find` instead of method calls: - -* `.limit(n).skip(m)` to control paging. -* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes: - * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2. - * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above - * `.sort([['field1', 'desc'], 'field2'])` same as above - * `.sort('field1')` ascending by field1 - -Other options of `find`: - -* `fields` the fields to fetch (to avoid transferring the entire document) -* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors). -* `batchSize` The number of the subset of results to request the database -to return for every request. This should initially be greater than 1 otherwise -the database will automatically close the cursor. The batch size can be set to 1 -with `batchSize(n, function(err){})` after performing the initial query to the database. -* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint). -* `explain` turns this into an explain query. You can also call -`explain()` on any cursor to fetch the explanation. -* `snapshot` prevents documents that are updated while the query is active -from being returned multiple times. See more -[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database). -* `timeout` if false, asks MongoDb not to time out this cursor after an -inactivity period. - - -For information on how to create queries, see the -[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.find({}, {limit:10}).toArray(function(err, docs) { - console.dir(docs); - }); - }); -``` - -Insert ------- - -Signature: - -```javascript - collection.insert(docs, options, [callback]); -``` - -where `docs` can be a single document or an array of documents. - -Useful options: - -* `safe:true` Should always set if you have a callback. - -See also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.insert({hello: 'world'}, {safe:true}, - function(err, objects) { - if (err) console.warn(err.message); - if (err && err.message.indexOf('E11000 ') !== -1) { - // this _id was already inserted in the database - } - }); - }); -``` - -Note that there's no reason to pass a callback to the insert or update commands -unless you use the `safe:true` option. If you don't specify `safe:true`, then -your callback will be called immediately. - -Update; update and insert (upsert) ----------------------------------- - -The update operation will update the first document that matches your query -(or all documents that match if you use `multi:true`). -If `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated. - -See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for -the modifier (`$inc`, `$set`, `$push`, etc.) formats. - -Signature: - -```javascript - collection.update(criteria, objNew, options, [callback]); -``` - -Useful options: - -* `safe:true` Should always set if you have a callback. -* `multi:true` If set, all matching documents are updated, not just the first. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `update`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true}, - function(err) { - if (err) console.warn(err.message); - else console.log('successfully updated'); - }); - }); -``` - -Find and modify ---------------- - -`findAndModify` is like `update`, but it also gives the updated document to -your callback. But there are a few key differences between findAndModify and -update: - - 1. The signatures differ. - 2. You can only findAndModify a single item, not multiple items. - -Signature: - -```javascript - collection.findAndModify(query, sort, update, options, callback) -``` - -The sort parameter is used to specify which object to operate on, if more than -one document matches. It takes the same format as the cursor sort (see -Connection.find above). - -See the -[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) -for more details. - -Useful options: - -* `remove:true` set to a true to remove the object before returning -* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `findAndModify`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {}, - function(err, object) { - if (err) console.warn(err.message); - else console.dir(object); // undefined if no matching object exists. - }); - }); -``` - -Save ----- - -The `save` method is a shorthand for upsert if the document contains an -`_id`, or an insert if there is no `_id`. - -Sponsors -======== -Just as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB. - -If your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details. - -And I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing. - -Release Notes -============= - -See HISTORY - -Credits -======= - -1. [10gen](http://github.com/mongodb/mongo-ruby-driver/) -2. [Google Closure Library](http://code.google.com/closure/library/) -3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser) - -Contributors -============ - -Aaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy - -License -======= - - Copyright 2009 - 2012 Christian Amor Kvalheim. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/frontend/express/node_modules/mongodb/TODO b/frontend/express/node_modules/mongodb/TODO deleted file mode 100644 index 1ed86e8de1f..00000000000 --- a/frontend/express/node_modules/mongodb/TODO +++ /dev/null @@ -1,25 +0,0 @@ -TODO for jan 4 - 2011 -- Chase down potential memory leak in findAndModify -- Check compatibility for gridFS between python and js -- Ensure Gridfs speed is comparable to other solutions -- Map out python replicaset driver functionality - -ACCOMPLISHED jan 4 - 2011 -+ Chase down potential memory leak in findAndModify -+ Check compatibility for gridFS between python and js -+ Ensure Gridfs speed is comparable to other solutions - -0.9.7.4-dev -- Amortize documents (only deserialize when accessed) -- Mongo tests to handle special Mongos situations -- If a secondary server disappears don't kill the driver connection -- Check for new servers coming online (a new secondary server etc) -- http://api.mongodb.org/python/current/api/pymongo/index.html#pymongo.ReadPreference - ---------------------------------------------------------------------------------------------* Allow secondary read with no master -* Add lowest response time selection of read server for replicaset using a selectable strategy. First one being using the ping command response time -* Allow execution of multiple commands against the same server connection when having a connection pool -* Implement tag support for replicasets -* Change bson c++ parser to use js objects instead of native c++ objects -* Whole stack benchmark with profiling to locate where the driver spends time -* Change bson c++ parser to be stackless to look at performance difference \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/Makefile b/frontend/express/node_modules/mongodb/external-libs/bson/Makefile deleted file mode 100644 index ad877d4bd3c..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -test: - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/bson.cc b/frontend/express/node_modules/mongodb/external-libs/bson/bson.cc deleted file mode 100644 index decc28f1ac6..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/bson.cc +++ /dev/null @@ -1,2334 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bson.h" - -using namespace v8; -using namespace node; -using namespace std; - -// BSON DATA TYPES -const uint32_t BSON_DATA_NUMBER = 1; -const uint32_t BSON_DATA_STRING = 2; -const uint32_t BSON_DATA_OBJECT = 3; -const uint32_t BSON_DATA_ARRAY = 4; -const uint32_t BSON_DATA_BINARY = 5; -const uint32_t BSON_DATA_OID = 7; -const uint32_t BSON_DATA_BOOLEAN = 8; -const uint32_t BSON_DATA_DATE = 9; -const uint32_t BSON_DATA_NULL = 10; -const uint32_t BSON_DATA_REGEXP = 11; -const uint32_t BSON_DATA_CODE = 13; -const uint32_t BSON_DATA_SYMBOL = 14; -const uint32_t BSON_DATA_CODE_W_SCOPE = 15; -const uint32_t BSON_DATA_INT = 16; -const uint32_t BSON_DATA_TIMESTAMP = 17; -const uint32_t BSON_DATA_LONG = 18; -const uint32_t BSON_DATA_MIN_KEY = 0xff; -const uint32_t BSON_DATA_MAX_KEY = 0x7f; - -const int32_t BSON_INT32_MAX = (int32_t)2147483647L; -const int32_t BSON_INT32_MIN = (int32_t)(-1) * 2147483648L; - -const int64_t BSON_INT64_MAX = ((int64_t)1 << 63) - 1; -const int64_t BSON_INT64_MIN = (int64_t)-1 << 63; - -const int64_t JS_INT_MAX = (int64_t)1 << 53; -const int64_t JS_INT_MIN = (int64_t)-1 << 53; - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); - }; - -Persistent BSON::constructor_template; - -void BSON::Initialize(v8::Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - // Experimental - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize2", CalculateObjectSize2); - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize2", BSONSerialize2); - // NODE_SET_METHOD(constructor_template->GetFunction(), "serialize2", BSONSerialize2); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and assing it the existing context -Handle BSON::New(const Arguments &args) { - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - // Setup pre-allocated comparision objects - bson->_bsontypeString = Persistent::New(String::New("_bsontype")); - bson->_longLowString = Persistent::New(String::New("low_")); - bson->_longHighString = Persistent::New(String::New("high_")); - bson->_objectIDidString = Persistent::New(String::New("id")); - bson->_binaryPositionString = Persistent::New(String::New("position")); - bson->_binarySubTypeString = Persistent::New(String::New("sub_type")); - bson->_binaryBufferString = Persistent::New(String::New("buffer")); - bson->_doubleValueString = Persistent::New(String::New("value")); - bson->_symbolValueString = Persistent::New(String::New("value")); - bson->_dbRefRefString = Persistent::New(String::New("$ref")); - bson->_dbRefIdRefString = Persistent::New(String::New("$id")); - bson->_dbRefDbRefString = Persistent::New(String::New("$db")); - bson->_dbRefNamespaceString = Persistent::New(String::New("namespace")); - bson->_dbRefDbString = Persistent::New(String::New("db")); - bson->_dbRefOidString = Persistent::New(String::New("oid")); - - // total number of found classes - uint32_t numberOfClasses = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(String::New("Long"))) { - bson->longConstructor = Persistent::New(func); - bson->longString = Persistent::New(String::New("Long")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("ObjectID"))) { - bson->objectIDConstructor = Persistent::New(func); - bson->objectIDString = Persistent::New(String::New("ObjectID")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Binary"))) { - bson->binaryConstructor = Persistent::New(func); - bson->binaryString = Persistent::New(String::New("Binary")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Code"))) { - bson->codeConstructor = Persistent::New(func); - bson->codeString = Persistent::New(String::New("Code")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("DBRef"))) { - bson->dbrefConstructor = Persistent::New(func); - bson->dbrefString = Persistent::New(String::New("DBRef")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Symbol"))) { - bson->symbolConstructor = Persistent::New(func); - bson->symbolString = Persistent::New(String::New("Symbol")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Double"))) { - bson->doubleConstructor = Persistent::New(func); - bson->doubleString = Persistent::New(String::New("Double")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Timestamp"))) { - bson->timestampConstructor = Persistent::New(func); - bson->timestampString = Persistent::New(String::New("Timestamp")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MinKey"))) { - bson->minKeyConstructor = Persistent::New(func); - bson->minKeyString = Persistent::New(String::New("MinKey")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MaxKey"))) { - bson->maxKeyConstructor = Persistent::New(func); - bson->maxKeyString = Persistent::New(String::New("MaxKey")); - numberOfClasses = numberOfClasses + 1; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(numberOfClasses != 10) { - // Destroy object - delete(bson); - // Fire exception - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } else { - return VException("No types passed in"); - } - } else { - return VException("Argument passed in must be an array of types"); - } -} - -void BSON::write_int32(char *data, uint32_t value) { - // Write the int to the char* - memcpy(data, &value, 4); -} - -void BSON::write_double(char *data, double value) { - // Write the double to the char* - memcpy(data, &value, 8); -} - -void BSON::write_int64(char *data, int64_t value) { - // Write the int to the char* - memcpy(data, &value, 8); -} - -char *BSON::check_key(Local key) { - // Allocate space for they key string - char *key_str = (char *)malloc(key->Utf8Length() * sizeof(char) + 1); - // Error string - char *error_str = (char *)malloc(256 * sizeof(char)); - // Decode the key - ssize_t len = DecodeBytes(key, BINARY); - ssize_t written = DecodeWrite(key_str, len, key, BINARY); - *(key_str + key->Utf8Length()) = '\0'; - // Check if we have a valid key - if(key->Utf8Length() > 0 && *(key_str) == '$') { - // Create the string - sprintf(error_str, "key %s must not start with '$'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } else if(key->Utf8Length() > 0 && strchr(key_str, '.') != NULL) { - // Create the string - sprintf(error_str, "key %s must not contain '.'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } - // Free allocated space - free(key_str); - free(error_str); - // Return No check key error - return NULL; -} - -const char* BSON::ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : ""; -} - -Handle BSON::decodeDBref(BSON *bson, Local ref, Local oid, Local db) { - HandleScope scope; - Local argv[] = {ref, oid, db}; - Handle dbrefObj = bson->dbrefConstructor->NewInstance(3, argv); - return scope.Close(dbrefObj); -} - -Handle BSON::decodeCode(BSON *bson, char *code, Handle scope_object) { - HandleScope scope; - - Local argv[] = {String::New(code), scope_object->ToObject()}; - Handle codeObj = bson->codeConstructor->NewInstance(2, argv); - return scope.Close(codeObj); -} - -Handle BSON::decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data) { - HandleScope scope; - - // Create a buffer object that wraps the raw stream - Buffer *bufferObj = Buffer::New(data, number_of_bytes); - // Arguments to be passed to create the binary - Handle argv[] = {bufferObj->handle_, Uint32::New(sub_type)}; - // Return the buffer handle - Local bufferObjHandle = bson->binaryConstructor->NewInstance(2, argv); - // Close the scope - return scope.Close(bufferObjHandle); -} - -Handle BSON::decodeOid(BSON *bson, char *oid) { - HandleScope scope; - - // Encode the string (string - null termiating character) - Local bin_value = Encode(oid, 12, BINARY)->ToString(); - - // Return the id object - Local argv[] = {bin_value}; - Local oidObj = bson->objectIDConstructor->NewInstance(1, argv); - return scope.Close(oidObj); -} - -Handle BSON::decodeLong(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Decode 64bit value - int64_t value = 0; - memcpy(&value, (data + index), 8); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - int64_t finalValue = 0; - memcpy(&finalValue, (data + index), 8); - return scope.Close(Number::New(finalValue)); - } - - // Instantiate the js object and pass it back - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Local longObject = bson->longConstructor->NewInstance(2, argv); - return scope.Close(longObject); -} - -Handle BSON::decodeTimestamp(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Build timestamp - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Handle timestamp_obj = bson->timestampConstructor->NewInstance(2, argv); - return scope.Close(timestamp_obj); -} - -// Search for 0 terminated C string and return the string -char* BSON::extract_string(char *data, uint32_t offset) { - char *prt = strchr((data + offset), '\0'); - if(prt == NULL) return NULL; - // Figure out the length of the string - uint32_t length = (prt - data) - offset; - // Allocate memory for the new string - char *string_name = (char *)malloc((length * sizeof(char)) + 1); - // Copy the variable into the string_name - strncpy(string_name, (data + offset), length); - // Ensure the string is null terminated - *(string_name + length) = '\0'; - // Return the unpacked string - return string_name; -} - -// Decode a byte -uint16_t BSON::deserialize_int8(char *data, uint32_t offset) { - uint16_t value = 0; - value |= *(data + offset + 0); - return value; -} - -// Requires a 4 byte char array -uint32_t BSON::deserialize_int32(char* data, uint32_t offset) { - uint32_t value = 0; - memcpy(&value, (data + offset), 4); - return value; -} - -//------------------------------------------------------------------------------------------------ -// -// Experimental -// -//------------------------------------------------------------------------------------------------ -Handle BSON::CalculateObjectSize2(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() > 1) return VException("One argument required - [object]"); - // Calculate size of the object - uint32_t object_size = BSON::calculate_object_size2(args[0]); - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size2(Handle value) { - // Final object size - uint32_t object_size = (4 + 1); - uint32_t stackIndex = 0; - // Controls the flow - bool done = false; - bool finished = false; - bool isObject = false; - - // Define a local vector that keeps the stack - // vector > > stack;// = new vector > >(0); - - // My own stack max of 1024 objects deep - Local *stack[64]; - - // Current object we are processing - Local currentObject = value->ToObject(); - - // Current list of object keys - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local keys = currentObject->GetPropertyNames(); - #else - Local keys = currentObject->GetOwnPropertyNames(); - #endif - - // Contains pointer to keysIndex - uint32_t keysIndex = 0; - uint32_t keysLength = keys->Length(); - - // printf("=================================================================================\n"); - // printf("Start serializing\n"); - - while(!done) { - // If the index is bigger than the number of keys for the object - // we finished up the previous object and are ready for the next one - if(keysIndex >= keysLength) { - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - keys = currentObject->GetPropertyNames(); - #else - keys = currentObject->GetOwnPropertyNames(); - #endif - keysLength = keys->Length(); - } - - // Iterate over all the keys - while(keysIndex < keysLength) { - // Fetch the key name - Local name = keys->Get(keysIndex++)->ToString(); - // Fetch the object related to the key - Local value = currentObject->Get(name); - // Add size of the name, plus zero, plus type - object_size += name->Utf8Length() + 1 + 1; - - // If we have a string - if(value->IsString()) { - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } - // } else if(value->IsNumber()) { - // // Check if we have a float value or a long value - // Local number = value->ToNumber(); - // double d_number = number->NumberValue(); - // int64_t l_number = number->IntegerValue(); - // // Check if we have a double value and not a int64 - // double d_result = d_number - l_number; - // // If we have a value after subtracting the integer value we have a float - // if(d_result > 0 || d_result < 0) { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // object_size = name->Utf8Length() + 1 + object_size + 4 + 1; - // } else { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } - // } else if(value->IsObject()) { - // printf("------------- hello\n"); - // } - } - - // If we have finished all the keys - if(keysIndex == keysLength) { - finished = false; - } - - // Validate the stack - if(stackIndex == 0) { - // printf("======================================================================== 3\n"); - done = true; - } else if(finished || keysIndex == keysLength) { - // Pop off the stack - stackIndex = stackIndex - 1; - // Fetch the current object stack - // vector > currentObjectStored = stack.back(); - // stack.pop_back(); - // // Unroll the current object - // currentObject = currentObjectStored.back()->ToObject(); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keys = Local::Cast(currentObjectStored.back()->ToObject()); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keysIndex = currentObjectStored.back()->ToUint32()->Value(); - // currentObjectStored.pop_back(); - // // Check if we finished up - // if(keysIndex == keys->Length()) { - // finished = true; - // } - } - } - - return object_size; -} - -Handle BSON::BSONSerialize2(const Arguments &args) { - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() > 3) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - uint32_t object_size = BSON::calculate_object_size2(args[0]); - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() == 3 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - // Serialize the object - BSON::serialize2(serialized_object, 0, Null(), args[0], object_size, check_key); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - // Write the object size - BSON::write_int32((serialized_object), object_size); - - // If we have 3 arguments - if(args.Length() == 3) { - // Local asBuffer = args[2]->ToBoolean(); - Buffer *buffer = Buffer::New(serialized_object, object_size); - // Release the serialized string - free(serialized_object); - return scope.Close(buffer->handle_); - } else { - // Encode the string (string - null termiating character) - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - // Return the serialized content - return bin_value; - } -} - -uint32_t BSON::serialize2(char *serialized_object, uint32_t index, Handle name, Handle value, uint32_t objectSize, bool check_key) { - // Scope for method execution - HandleScope scope; - - // Final object size - uint32_t object_size = (4 + 1); - uint32_t stackIndex = 0; - // Controls the flow - bool done = false; - bool finished = false; - bool isObject = false; - - // Define a local vector that keeps the stack - // vector > > stack;// = new vector > >(0); - - // My own stack max of 1024 objects deep - Local *stack[64]; - - // Current object we are processing - Local currentObject = value->ToObject(); - // Current list of object keys - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local keys = currentObject->GetPropertyNames(); - #else - Local keys = currentObject->GetOwnPropertyNames(); - #endif - - // Contains pointer to keysIndex - uint32_t keysIndex = 0; - uint32_t keysLength = keys->Length(); - // Add pointer to start of new object - index = index + 4; - - // printf("=================================================================================\n"); - // printf("Start serializing\n"); - - while(!done) { - // If the index is bigger than the number of keys for the object - // we finished up the previous object and are ready for the next one - if(keysIndex >= keysLength) { - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - keys = currentObject->GetPropertyNames(); - #else - keys = currentObject->GetOwnPropertyNames(); - #endif - - keysLength = keys->Length(); - } - - // Iterate over all the keys - while(keysIndex < keysLength) { - // Fetch the key name - Local name = keys->Get(keysIndex++)->ToString(); - // Fetch the object related to the key - Local value = currentObject->Get(name); - - // If it's a string - if(value->IsString()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_STRING; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Write the actual string into the char array - Local str = value->ToString(); - // Let's fetch the int value - uint32_t utf8_length = str->Utf8Length(); - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - written = DecodeWrite((serialized_object + index), utf8_length, str, BINARY); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } - } - - // If we have finished all the keys - if(keysIndex == keysLength) { - finished = false; - } - - // Validate the stack - if(stackIndex == 0) { - // printf("======================================================================== 3\n"); - done = true; - // Set last byte to zero - *(serialized_object + objectSize - 1) = 0x00; - } else if(finished || keysIndex == keysLength) { - // printf("======================================================================== 4\n"); - // Pop off the stack - stackIndex = stackIndex - 1; - // Set last byte to zero - *(serialized_object + objectSize - 1) = 0x00; - - // Fetch the current object stack - // vector > currentObjectStored = stack.back(); - // stack.pop_back(); - // // Unroll the current object - // currentObject = currentObjectStored.back()->ToObject(); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keys = Local::Cast(currentObjectStored.back()->ToObject()); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keysIndex = currentObjectStored.back()->ToUint32()->Value(); - // currentObjectStored.pop_back(); - // // Check if we finished up - // if(keysIndex == keys->Length()) { - // finished = true; - // } - } - } - - return 0; -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -Handle BSON::BSONDeserialize(const Arguments &args) { - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - char *data; - uint32_t length; - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) { - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - uint32_t length = buffer->length(); - #else - data = Buffer::Data(obj); - uint32_t length = Buffer::Length(obj); - #endif - - // Validate that we have at least 5 bytes - if(length < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Deserialize the data - return BSON::deserialize(bson, data, length, 0, NULL); - } else { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Let's define the buffer size - data = (char *)malloc(len); - // Write the data to the buffer from the string object - ssize_t written = DecodeWrite(data, len, args[0], BINARY); - // Assert that we wrote the same number of bytes as we have length - assert(written == len); - // Get result - Handle result = BSON::deserialize(bson, data, len, 0, NULL); - // Free memory - free(data); - // Deserialize the content - return result; - } -} - -// Deserialize the stream -Handle BSON::deserialize(BSON *bson, char *data, uint32_t inDataLength, uint32_t startIndex, bool is_array_item) { - HandleScope scope; - // Holds references to the objects that are going to be returned - Local return_data = Object::New(); - Local return_array = Array::New(); - // The current index in the char data - uint32_t index = startIndex; - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // If we have an illegal message size - if(size < 0 || size > inDataLength) return VException("corrupt bson message"); - - // Data length - uint32_t dataLength = index + size; - - // Adjust the index to point to next piece - index = index + 4; - - // While we have data left let's decode - while(index < dataLength) { - // Read the first to bytes to indicate the type of object we are decoding - uint8_t type = BSON::deserialize_int8(data, index); - // Handles the internal size of the object - uint32_t insert_index = 0; - // Adjust index to skip type byte - index = index + 1; - - if(type == BSON_DATA_STRING) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), utf8_encoded_str); - } else { - return_data->ForceSet(String::New(string_name), utf8_encoded_str); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_INT) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - uint32_t value = 0; - memcpy(&value, (data + index), 4); - - // Adjust the index for the size of the value - index = index + 4; - // Add the element to the object - if(is_array_item) { - return_array->Set(Integer::New(insert_index), Integer::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Integer::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_TIMESTAMP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeTimestamp(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeTimestamp(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_LONG) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeLong(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeLong(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NUMBER) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - double value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Number::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Number::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MIN_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local minKey = bson->minKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), minKey); - } else { - return_data->ForceSet(String::New(string_name), minKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MAX_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local maxKey = bson->maxKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), maxKey); - } else { - return_data->ForceSet(String::New(string_name), maxKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NULL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Null()); - } else { - return_data->ForceSet(String::New(string_name), Null()); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_BOOLEAN) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the boolean value - char bool_value = *(data + index); - // Adjust the index for the size of the value - index = index + 1; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } else { - return_data->ForceSet(String::New(string_name), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_DATE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the value 64 bit integer - int64_t value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Date::New((double)value)); - } else { - return_data->ForceSet(String::New(string_name), Date::New((double)value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_REGEXP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Length variable - int32_t length_regexp = 0; - int32_t start_index = index; - char chr; - - // Locate end of the regexp expression \0 - while((chr = *(data + index + length_regexp)) != '\0') { - length_regexp = length_regexp + 1; - } - - // Contains the reg exp - char *reg_exp = (char *)malloc(length_regexp * sizeof(char) + 2); - // Copy the regexp from the data to the char * - memcpy(reg_exp, (data + index), (length_regexp + 1)); - // Adjust the index to skip the first part of the regular expression - index = index + length_regexp + 1; - - // Reset the length - int32_t options_length = 0; - // Locate the end of the options for the regexp terminated with a '\0' - while((chr = *(data + index + options_length)) != '\0') { - options_length = options_length + 1; - } - - // Contains the reg exp - char *options = (char *)malloc(options_length * sizeof(char) + 1); - // Copy the options from the data to the char * - memcpy(options, (data + index), (options_length + 1)); - // Adjust the index to skip the option part of the regular expression - index = index + options_length + 1; - // ARRRRGH Google does not expose regular expressions through the v8 api - // Have to use Script to instantiate the object (slower) - - // Generate the string for execution in the string context - int flag = 0; - - for(int i = 0; i < options_length; i++) { - // Multiline - if(*(options + i) == 'm') { - flag = flag | 4; - } else if(*(options + i) == 'i') { - flag = flag | 2; - } - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } else { - return_data->ForceSet(String::New(string_name), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } - - // Free memory - free(reg_exp); - free(options); - free(string_name); - } else if(type == BSON_DATA_OID) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // The id string - char *oid_string = (char *)malloc(12 * sizeof(char)); - // Copy the options from the data to the char * - memcpy(oid_string, (data + index), 12); - - // Adjust the index - index = index + 12; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeOid(bson, oid_string)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeOid(bson, oid_string)); - } - - // Free memory - free(oid_string); - free(string_name); - } else if(type == BSON_DATA_BINARY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the binary data size - uint32_t number_of_bytes = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Decode the subtype, ensure it's positive - uint32_t sub_type = (int)*(data + index) & 0xff; - // Adjust the index - index = index + 1; - // Copy the binary data into a buffer - char *buffer = (char *)malloc(number_of_bytes * sizeof(char) + 1); - memcpy(buffer, (data + index), number_of_bytes); - *(buffer + number_of_bytes) = '\0'; - - // Adjust the index - index = index + number_of_bytes; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } - // Free memory - free(buffer); - free(string_name); - } else if(type == BSON_DATA_SYMBOL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - - // Wrap up the string in a Symbol Object - Local argv[] = {utf8_encoded_str}; - Handle symbolObj = bson->symbolConstructor->NewInstance(1, argv); - - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), symbolObj); - } else { - return_data->ForceSet(String::New(string_name), symbolObj); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_CODE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - - // Define empty scope object - Handle scope_object = Object::New(); - - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - free(string_name); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(string_name); - } else if(type == BSON_DATA_CODE_W_SCOPE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Total number of bytes after array index - uint32_t total_code_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - // Adjust the index - index = index + string_size; - // Get the scope object (bson object) - uint32_t bson_object_size = total_code_size - string_size - 8; - // Allocate bson object buffer and copy out the content - char *bson_buffer = (char *)malloc(bson_object_size * sizeof(char)); - memcpy(bson_buffer, (data + index), bson_object_size); - // Adjust the index - index = index + bson_object_size; - // Parse the bson object - Handle scope_object = BSON::deserialize(bson, bson_buffer, inDataLength, 0, false); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Clean up memory allocation - free(string_name); - free(bson_buffer); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(bson_buffer); - free(string_name); - } else if(type == BSON_DATA_OBJECT) { - // If this is the top level object we need to skip the undecoding - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the object size - uint32_t bson_object_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, false); - // Adjust the index - index = index + bson_object_size; - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(string_name); - } else if(type == BSON_DATA_ARRAY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the size - uint32_t array_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, true); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - // Adjust the index for the next value - index = index + array_size; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - // Clean up memory allocation - free(string_name); - } - } - - // Check if we have a db reference - if(!is_array_item && return_data->Has(String::New("$ref")) && return_data->Has(String::New("$id"))) { - Handle dbrefValue = BSON::decodeDBref(bson, return_data->Get(String::New("$ref")), return_data->Get(String::New("$id")), return_data->Get(String::New("$db"))); - return scope.Close(dbrefValue); - } - - // Return the data object to javascript - if(is_array_item) { - return scope.Close(return_array); - } else { - return scope.Close(return_data); - } -} - -Handle BSON::BSONSerialize(const Arguments &args) { - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - if(args.Length() == 4) { - object_size = BSON::calculate_object_size(bson, args[0], args[3]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 3 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - // Check if we have a boolean value - bool serializeFunctions = false; - if(args.Length() == 4 && args[1]->IsBoolean()) { - serializeFunctions = args[3]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - // Write the object size - BSON::write_int32((serialized_object), object_size); - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) { - // Local asBuffer = args[2]->ToBoolean(); - Buffer *buffer = Buffer::New(serialized_object, object_size); - // Release the serialized string - free(serialized_object); - return scope.Close(buffer->handle_); - } else { - // Encode the string (string - null termiating character) - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - // Return the serialized content - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Object size - uint32_t object_size = 0; - // Check if we have our argument, calculate size of the object - if(args.Length() == 2) { - object_size = BSON::calculate_object_size(bson, args[0], args[1]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size(BSON *bson, Handle value, bool serializeFunctions) { - uint32_t object_size = 0; - - // If we have an object let's unwrap it and calculate the sub sections - if(value->IsString()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Calculate the size of each element - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Add the size of the string length - uint32_t label_length = strlen(length_str) + 1; - // Add the type definition size for each item - object_size = object_size + label_length + 1; - // Add size of the object - uint32_t object_length = BSON::calculate_object_size(bson, array->Get(Integer::New(i)), serializeFunctions); - object_size = object_size + object_length; - } - // Add the object size - object_size = object_size + 4 + 1; - // Free up memory - free(length_str); - } else if(value->IsFunction()) { - if(serializeFunctions) { - object_size += value->ToString()->Utf8Length() + 4 + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - object_size = object_size + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local positionObj = value->ToObject()->Get(String::New("position"))->ToUint32(); - // Adjust the object_size, binary content lengt + total size int32 + binary size int32 + subtype - object_size += positionObj->Value() + 4 + 1; - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Check if the scope has any parameters - // Let's calculate the size the code object adds adds - if(propertyNameLength > 0) { - object_size += function->Utf8Length() + 4 + BSON::calculate_object_size(bson, scope, serializeFunctions) + 4 + 1; - } else { - object_size += function->Utf8Length() + 4 + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - // Calculate size - object_size += BSON::calculate_object_size(bson, obj, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString) || bson->maxKeyString->Equals(constructorString)) { - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Get string - Local str = value->ToObject()->Get(String::New("value"))->ToString(); - // Get the utf8 length - uint32_t utf8_length = str->Utf8Length(); - // Check if we have a utf8 encoded string or not - if(utf8_length != str->Length()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += str->Utf8Length() + 1 + 4; - } else { - object_size += str->Length() + 1 + 4; - } - } else if(bson->doubleString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } - } else if(value->IsObject()) { - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Length of the property - uint32_t propertyLength = property_names->Length(); - - // Process all the properties on the object - for(uint32_t index = 0; index < propertyLength; index++) { - // Fetch the property name - Local property_name = property_names->Get(index)->ToString(); - - // Fetch the object for the property - Local property = object->Get(property_name); - // Get size of property (property + property name length + 1 for terminating 0) - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - object_size += BSON::calculate_object_size(bson, property, serializeFunctions) + property_name->Utf8Length() + 1 + 1; - } - } - - object_size = object_size + 4 + 1; - } - - return object_size; -} - -uint32_t BSON::serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions) { - // Scope for method execution - HandleScope scope; - - // If we have a name check that key is valid - if(!name->IsNull() && check_key) { - if(BSON::check_key(name->ToString()) != NULL) return -1; - } - - // If we have an object let's serialize it - if(value->IsString()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_STRING; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Write the actual string into the char array - Local str = value->ToString(); - // Let's fetch the int value - uint32_t utf8_length = str->Utf8Length(); - - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else if(value->IsNumber()) { - uint32_t first_pointer = index; - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_INT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - Local number = value->ToNumber(); - // Get the values - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // Smaller than 32 bit, write as 32 bit value - BSON::write_int32(serialized_object + index, value->ToInt32()->Value()); - // Adjust the size of the index - index = index + 4; - } else if(l_number <= JS_INT_MAX && l_number >= JS_INT_MIN) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else { - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust the size of the index - index = index + 8; - } - } else if(value->IsBoolean()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_BOOLEAN; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Save the boolean value - *(serialized_object + index) = value->BooleanValue() ? '\1' : '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsDate()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_DATE; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the Integer value - int64_t integer_value = value->IntegerValue(); - BSON::write_int64((serialized_object + index), integer_value); - // Adjust the index - index = index + 8; - } else if(value->IsNull() || value->IsUndefined()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_NULL; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_ARRAY; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - // Object size - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size of the object - BSON::write_int32((serialized_object + index), object_size); - // Adjust the index - index = index + 4; - // Write out all the elements - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Encode the values - index = BSON::serialize(bson, serialized_object, index, String::New(length_str), array->Get(Integer::New(i)), check_key, serializeFunctions); - // Write trailing '\0' for object - *(serialized_object + index) = '\0'; - } - - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - // Free up memory - free(length_str); - } else if(value->IsRegExp()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_REGEXP; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - len = DecodeBytes(regExp->GetSource(), UTF8); - written = DecodeWrite((serialized_object + index), len, regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // global - if((flags & (1 << 0)) != 0) { - *(serialized_object + index) = 's'; - index = index + 1; - } - - // ignorecase - if((flags & (1 << 1)) != 0) { - *(serialized_object + index) = 'i'; - index = index + 1; - } - - //multiline - if((flags & (1 << 2)) != 0) { - *(serialized_object + index) = 'm'; - index = index + 1; - } - - // Add null termiation for the string - *(serialized_object + index) = '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsFunction()) { - if(serializeFunctions) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_CODE; - - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Function String - Local function = value->ToString(); - - // Decode the function - len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - written = DecodeWrite((serialized_object + index), len, function, BINARY); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - uint32_t originalIndex = index; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_LONG; - // Object reference - Local longObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = longObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = longObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_TIMESTAMP; - // Object reference - Local timestampObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = timestampObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = timestampObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_OID; - // Convert to object - Local objectIDObject = value->ToObject(); - // Let's grab the id - Local idString = objectIDObject->Get(bson->_objectIDidString)->ToString(); - // Let's decode the raw chars from the string - len = DecodeBytes(idString, BINARY); - written = DecodeWrite((serialized_object + index), len, idString, BINARY); - // Adjust the index - index = index + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_BINARY; - - // Let's get the binary object - Local binaryObject = value->ToObject(); - - // Grab the size(position of the binary) - uint32_t position = value->ToObject()->Get(bson->_binaryPositionString)->ToUint32()->Value(); - // Grab the subtype - uint32_t subType = value->ToObject()->Get(bson->_binarySubTypeString)->ToUint32()->Value(); - // Grab the buffer object - Local bufferObj = value->ToObject()->Get(bson->_binaryBufferString)->ToObject(); - - // Buffer data pointers - char *data; - uint32_t length; - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(bufferObj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(bufferObj); - length = Buffer::Length(bufferObj); - #endif - - // Write the size of the buffer out - BSON::write_int32((serialized_object + index), position); - // Adjust index - index = index + 4; - // Write subtype - *(serialized_object + index) = (char)subType; - // Adjust index - index = index + 1; - // Write binary content - memcpy((serialized_object + index), data, position); - // Adjust index.rar">_ - index = index + position; - } else if(bson->doubleString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_NUMBER; - - // Unpack the double - Local doubleObject = value->ToObject(); - - // Fetch the double value - Local doubleValue = doubleObject->Get(bson->_doubleValueString)->ToNumber(); - // Write the double to the char array - BSON::write_double((serialized_object + index), doubleValue->NumberValue()); - // Adjust index for double - index = index + 8; - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_SYMBOL; - // Unpack symbol object - Local symbolObj = value->ToObject(); - - // Grab the actual string - Local str = symbolObj->Get(bson->_symbolValueString)->ToString(); - // Let's fetch the int value - uint32_t utf8_length = str->Utf8Length(); - - // If the Utf8 length is different from the string length then we - // have a UTF8 encoded string, otherwise write it as ascii - if(utf8_length != str->Length()) { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), str->Length() + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - written = DecodeWrite((serialized_object + index), str->Length(), str, BINARY); - // Add the null termination - *(serialized_object + index + str->Length()) = '\0'; - // Adjust the index - index = index + str->Length() + 1; - } - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Set the right type if we have a scope or not - if(propertyNameLength > 0) { - // Set basic data code object with scope object - *(serialized_object + originalIndex) = BSON_DATA_CODE_W_SCOPE; - - // Calculate the size of the whole object - uint32_t scopeSize = BSON::calculate_object_size(bson, scope, false); - // Decode the function length - ssize_t len = DecodeBytes(function, UTF8); - // Calculate total size - uint32_t size = 4 + len + 1 + 4 + scopeSize; - - // Write the total size - BSON::write_int32((serialized_object + index), size); - // Adjust the index - index = index + 4; - - // Write the function size - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, UTF8); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index with the length of the function - index = index + len + 1; - // Write the scope object - BSON::serialize(bson, (serialized_object + index), 0, Null(), scope, check_key, serializeFunctions); - // Adjust the index - index = index + scopeSize; - } else { - // Set basic data code object - *(serialized_object + originalIndex) = BSON_DATA_CODE; - // Decode the function - ssize_t len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, BINARY); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - - // Encode the variable - index = BSON::serialize(bson, serialized_object, originalIndex, name, obj, false, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_MIN_KEY; - } else if(bson->maxKeyString->StrictEquals(constructorString)) { - *(serialized_object + originalIndex) = BSON_DATA_MAX_KEY; - } - } else if(value->IsObject()) { - if(!name->IsNull()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_OBJECT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } - - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Calculate size of the total object - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size - BSON::write_int32((serialized_object + index), object_size); - // Adjust size - index = index + 4; - - // Process all the properties on the object - for(uint32_t i = 0; i < property_names->Length(); i++) { - // Fetch the property name - Local property_name = property_names->Get(i)->ToString(); - // Fetch the object for the property - Local property = object->Get(property_name); - // Write the next serialized object - // printf("========== !property->IsFunction() || (property->IsFunction() && serializeFunctions) = %d\n", !property->IsFunction() || (property->IsFunction() && serializeFunctions) == true ? 1 : 0); - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - ssize_t len = DecodeBytes(property_name, UTF8); - // char *data = new char[len]; - char *data = (char *)malloc(len + 1); - *(data + len) = '\0'; - ssize_t written = DecodeWrite(data, len, property_name, UTF8); - // Serialize the content - index = BSON::serialize(bson, serialized_object, index, property_name, property, check_key, serializeFunctions); - // Free up memory of data - free(data); - } - } - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - - // Null out reminding fields if we have a toplevel object and nested levels - if(name->IsNull()) { - for(uint32_t i = 0; i < (object_size - index); i++) { - *(serialized_object + index + i) = '\0'; - } - } - } - - return index; -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) { - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Define pointer to data - char *data; - uint32_t length; - // Unpack the object - Local obj = args[2]->ToObject(); - - // Unpack the buffer object and get pointers to structures - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - if(args.Length() == 5) { - object_size = BSON::calculate_object_size(bson, args[0], args[4]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Unpack the index variable - Local indexObject = args[3]->ToUint32(); - uint32_t index = indexObject->Value(); - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 4 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - bool serializeFunctions = false; - if(args.Length() == 5) { - serializeFunctions = args[4]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - for(int i = 0; i < object_size; i++) { - *(data + index + i) = *(serialized_object + i); - } - - return scope.Close(Uint32::New(index + object_size - 1)); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) { - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - char *data; - uint32_t length; - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->ToUint32()->Value(); - uint32_t index = args[1]->ToUint32()->Value(); - uint32_t resultIndex = args[4]->ToUint32()->Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - for(uint32_t i = 0; i < numberOfDocuments; i++) { - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // Get result - Handle result = BSON::deserialize(bson, data, size, index, NULL); - - // Add result to array - documents->Set(i + resultIndex, result); - - // Adjust the index for next pass - index = index + size; - } - - // Return new index of parsing - return scope.Close(Uint32::New(index)); -} - -// Exporting function -extern "C" void init(Handle target) { - HandleScope scope; - BSON::Initialize(target); -} - -// NODE_MODULE(bson, BSON::Initialize); -// NODE_MODULE(l, Long::Initialize); diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/bson.h b/frontend/express/node_modules/mongodb/external-libs/bson/bson.h deleted file mode 100644 index dcf21d17af6..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/bson.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef BSON_H_ -#define BSON_H_ - -#include -#include -#include - -using namespace v8; -using namespace node; - -class BSON : public ObjectWrap { - public: - BSON() : ObjectWrap() {} - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Experimental - static Handle CalculateObjectSize2(const Arguments &args); - static Handle BSONSerialize2(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - - private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - static uint32_t serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions); - - static char* extract_string(char *data, uint32_t offset); - static const char* ToCString(const v8::String::Utf8Value& value); - static uint32_t calculate_object_size(BSON *bson, Handle object, bool serializeFunctions); - - static void write_int32(char *data, uint32_t value); - static void write_int64(char *data, int64_t value); - static void write_double(char *data, double value); - static uint16_t deserialize_int8(char *data, uint32_t offset); - static uint32_t deserialize_int32(char* data, uint32_t offset); - static char *check_key(Local key); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparision objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - // Decode JS function - static Handle decodeLong(BSON *bson, char *data, uint32_t index); - static Handle decodeTimestamp(BSON *bson, char *data, uint32_t index); - static Handle decodeOid(BSON *bson, char *oid); - static Handle decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data); - static Handle decodeCode(BSON *bson, char *code, Handle scope); - static Handle decodeDBref(BSON *bson, Local ref, Local oid, Local db); - - // Experimental - static uint32_t calculate_object_size2(Handle object); - static uint32_t serialize2(char *serialized_object, uint32_t index, Handle name, Handle value, uint32_t object_size, bool check_key); -}; - -#endif // BSON_H_ diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/build/.wafpickle-7 b/frontend/express/node_modules/mongodb/external-libs/bson/build/.wafpickle-7 deleted file mode 100644 index 900bc211687..00000000000 Binary files a/frontend/express/node_modules/mongodb/external-libs/bson/build/.wafpickle-7 and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/index.js b/frontend/express/node_modules/mongodb/external-libs/bson/index.js deleted file mode 100644 index 2c66dee6cca..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/index.js +++ /dev/null @@ -1,20 +0,0 @@ -var bson = require('./bson'); -exports.BSON = bson.BSON; -exports.Long = require('../../lib/mongodb/bson/long').Long; -exports.ObjectID = require('../../lib/mongodb/bson/objectid').ObjectID; -exports.DBRef = require('../../lib/mongodb/bson/db_ref').DBRef; -exports.Code = require('../../lib/mongodb/bson/code').Code; -exports.Timestamp = require('../../lib/mongodb/bson/timestamp').Timestamp; -exports.Binary = require('../../lib/mongodb/bson/binary').Binary; -exports.Double = require('../../lib/mongodb/bson/double').Double; -exports.MaxKey = require('../../lib/mongodb/bson/max_key').MaxKey; -exports.MinKey = require('../../lib/mongodb/bson/min_key').MinKey; -exports.Symbol = require('../../lib/mongodb/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_bson.js b/frontend/express/node_modules/mongodb/external-libs/bson/test/test_bson.js deleted file mode 100644 index a3c096e0f8e..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_bson.js +++ /dev/null @@ -1,347 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp, - assert = require('assert'); - -sys.puts("=== EXECUTING TEST_BSON ==="); - -// Should fail due to illegal key -assert.throws(function() { new ObjectID('foo'); }) -assert.throws(function() { new ObjectID('foo'); }) - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Simple serialization and deserialization of edge value -var doc = {doc:0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// -// Assert correct toJSON -// -var a = Long.fromNumber(10); -assert.equal(10, a); - -var a = Long.fromNumber(9223372036854775807); -assert.equal(9223372036854775807, a); - -// Simple serialization and deserialization test for a Single String value -var doc = {doc:'Serialize'}; -var simple_string_serialized = bsonC.serialize(doc, true, false); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Nested doc -var doc = {a:{b:{c:1}}}; -var simple_string_serialized = bsonC.serialize(doc, false, true); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple integer serialization/deserialization test, including testing boundary conditions -var doc = {doc:-1}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization test for a Long value -var doc = {doc:Long.fromNumber(9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:Long.fromNumber(-9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a Float value -var doc = {doc:2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a null value -var doc = {doc:null}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:true}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a date value -var date = new Date(); -var doc = {doc:date}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:/abcd/mi}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -var doc = {doc:/abcd/}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a objectId value -var doc = {doc:new ObjectID()}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a Binary value -var binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - -var Binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { Binary.put(string.charAt(index)); } - -var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Binary}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - -// Simple serialization and deserialization for a Code value -var code = new Code('this.a > i', {'i': 1}); -var Code = new Code('this.a > i', {'i': 1}); -var simple_string_serialized_2 = bsonJS.serialize({doc:Code}, false, true); -var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - -// Simple serialization and deserialization for an Object -var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for an Array -var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for a DBRef -var oid = new ObjectID() -var oid2 = new ObjectID.createFromHexString(oid.toHexString()) -var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -// Ensure we have the same values for the dbref -var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object_c = bsonC.deserialize(simple_string_serialized); - -assert.equal(object_js.doc.namespace, object_c.doc.namespace); -assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); -assert.equal(object_js.doc.db, object_c.doc.db); - -// Serialized document -var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal('Patty', object.name) -assert.equal(34, object.age) -assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - -// Serialize utf8 -var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.equal(doc.name, object.name) -assert.equal(doc.name1, object.name1) -assert.equal(doc.name2, object.name2) - -// Serialize object with array -var doc = {b:[1, 2, 3]}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc, object) - -// Test equality of an object ID -var object_id = new ObjectID(); -var object_id_2 = new ObjectID(); -assert.ok(object_id.equals(object_id)); -assert.ok(!(object_id.equals(object_id_2))) - -// Test same serialization for Object ID -var object_id = new ObjectID(); -var object_id2 = ObjectID.createFromHexString(object_id.toString()) -var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - -assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object2 = bsonC.deserialize(simple_string_serialized); -assert.equal(object.doc.id, object2.doc.id) - -// JS Object -var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; -var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); - -// C++ Object -var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; -var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) -}; - -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); -} - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc._id.id, doc1._id.id) -assert.equal(doc._id.id, doc2._id.id) -assert.equal(doc1._id.id, doc2._id.id) - -var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.deepEqual(doc2, doc1) -assert.deepEqual(doc, doc2) -assert.deepEqual(doc, doc1) - -// Serialize function -var doc = { - _id: 'testid', - key1: function() {} -} - -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - -var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Should serialize to the same value -assert.equal(simple_string_serialized_2.toString('hex'), simple_string_serialized.toString('hex')) -var doc1 = bsonJS.deserialize(simple_string_serialized_2); -var doc2 = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc1, doc2) - -// Hex Id -var hexId = new ObjectID().toString(); -var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docJSBin = bsonJS.serialize(docJS, false, true, true); -var docCBin = bsonC.serialize(docC, false, true, true); -assert.equal(docCBin.toString('hex'), docJSBin.toString('hex')); - -// // Complex document serialization -// doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} -// var docJSBin = bsonJS.serialize(docJS, false, true, true); -// var docCBin = bsonC.serialize(docC, false, true, true); -// -// - -// // Force garbage collect -// global.gc(); - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_full_bson.js b/frontend/express/node_modules/mongodb/external-libs/bson/test/test_full_bson.js deleted file mode 100644 index 3efee430250..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_full_bson.js +++ /dev/null @@ -1,216 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - assert = require('assert'), - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - -sys.puts("=== EXECUTING TEST_FULL_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Should Correctly Deserialize object -var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(serialized_data); -assert.equal("a_1", object.name); -assert.equal(false, object.unique); -assert.equal(1, object.key.a); - -// Should Correctly Deserialize object with all types -var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} - -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal("hello", object.string); -assert.deepEqual([1, 2, 3], object.array); -assert.equal(1, object.hash.a); -assert.equal(2, object.hash.b); -assert.ok(object.date != null); -assert.ok(object.oid != null); -assert.ok(object.binary != null); -assert.equal(42, object.int); -assert.equal(33.3333, object.float); -assert.ok(object.regexp != null); -assert.equal(true, object.boolean); -assert.ok(object.where != null); -assert.ok(object.dbref != null); -assert.ok(object['null'] == null); - -// Should Serialize and Deserialze String -var test_string = {hello: 'world'} -var serialized_data = bsonC.serialize(test_string) -assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_number = {doc: 5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize null value -var test_null = {doc:null} -var serialized_data = bsonC.serialize(test_null) -var object = bsonC.deserialize(serialized_data); -assert.deepEqual(test_null, object); - -// Should Correctly Serialize and Deserialize undefined value -var test_undefined = {doc:undefined} -var serialized_data = bsonC.serialize(test_undefined) -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal(null, object.doc) - -// Should Correctly Serialize and Deserialize Number -var test_number = {doc: 5.5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_int = {doc: 42} -var serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -5600} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: 2147483647} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -2147483648} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Object -var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array with added on functions -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize A Boolean -var doc = {doc: true} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize a Date -var date = new Date() -//(2009, 11, 12, 12, 00, 30) -date.setUTCDate(12) -date.setUTCFullYear(2009) -date.setUTCMonth(11 - 1) -date.setUTCHours(12) -date.setUTCMinutes(0) -date.setUTCSeconds(30) -var doc = {doc: date} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// // Should Correctly Serialize and Deserialize Oid -var doc = {doc: new ObjectID()} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - -// Should Correctly encode Empty Hash -var test_code = {} -var serialized_data = bsonC.serialize(test_code) -assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Ordered Hash -var doc = {doc: {b:1, a:2, c:3, d:4}} -var serialized_data = bsonC.serialize(doc) -var decoded_hash = bsonC.deserialize(serialized_data).doc -var keys = [] -for(name in decoded_hash) keys.push(name) -assert.deepEqual(['b', 'a', 'c', 'd'], keys) - -// Should Correctly Serialize and Deserialize Regular Expression -// Serialize the regular expression -var doc = {doc: /foobar/mi} -var serialized_data = bsonC.serialize(doc) -var doc2 = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.toString(), doc2.doc.toString()) - -// Should Correctly Serialize and Deserialize a Binary object -var bin = new Binary() -var string = 'binstring' -for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) -} -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - -// Should Correctly Serialize and Deserialize a big Binary object -var data = fs.readFileSync("../../test/gridstore/test_gs_weird_bug.png", 'binary'); -var bin = new Binary() -bin.write(data) -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js b/frontend/express/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js deleted file mode 100644 index 5f43c4702b9..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js +++ /dev/null @@ -1,130 +0,0 @@ -var Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - assert = require('assert'); - -console.log("=== EXECUTING TEST_STACKLESS_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Number of iterations for the benchmark -var COUNT = 10000; -// var COUNT = 1; -// Sample simple doc -var doc = {key:"Hello world", key2:"šđžÄćŠÄŽČĆ", key3:'客家è¯', key4:'how are you doing dog!!'}; -// var doc = {}; -// for(var i = 0; i < 100; i++) { -// doc['string' + i] = "dumdyms fsdfdsfdsfdsfsdfdsfsdfsdfsdfsdfsdfsdfsdffsfsdfs"; -// } - -// // Calculate size -console.log(bsonC.calculateObjectSize2(doc)); -console.log(bsonJS.calculateObjectSize(doc)); -// assert.equal(bsonJS.calculateObjectSize(doc), bsonC.calculateObjectSize2(doc)); - -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// Benchmark calculateObjectSize -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- - -// Benchmark 1 JS BSON -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonJS.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 2 C++ BSON calculateObjectSize -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 3 C++ BSON calculateObjectSize2 -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize2(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize2(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// // Serialize the content -// var _serializedDoc1 = bsonJS.serialize(doc, true, false); -// var _serializedDoc2 = bsonC.serialize2(doc, true, false); -// console.dir(_serializedDoc1); -// console.dir(_serializedDoc2); -// assert.equal(_serializedDoc1.toString('hex'), _serializedDoc2.toString('hex')) -// -// -// // Benchmark 1 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// // var objectBSON = bsonC.serialize2(doc, true, false); -// var objectBSON = bsonJS.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 2 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize2(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 3 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); diff --git a/frontend/express/node_modules/mongodb/external-libs/bson/wscript b/frontend/express/node_modules/mongodb/external-libs/bson/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/mongodb/external-libs/bson/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/mongodb/index.js b/frontend/express/node_modules/mongodb/index.js deleted file mode 100644 index 4f59e9d9262..00000000000 --- a/frontend/express/node_modules/mongodb/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/mongodb'); diff --git a/frontend/express/node_modules/mongodb/install.js b/frontend/express/node_modules/mongodb/install.js deleted file mode 100644 index f9f2a5778eb..00000000000 --- a/frontend/express/node_modules/mongodb/install.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false'; -build_native = build_native == 'true' ? true : false; -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total']); - } else { - make = spawn('gmake', ['total']); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/frontend/express/node_modules/mongodb/leak.js b/frontend/express/node_modules/mongodb/leak.js deleted file mode 100644 index dbb87c6632e..00000000000 --- a/frontend/express/node_modules/mongodb/leak.js +++ /dev/null @@ -1,15 +0,0 @@ -require('v8-profiler'); - -// It is important to use named constructors (like the one below), otherwise -// the heap snapshots will not produce useful outputs for you. -function LeakingClass() { -} - -var leaks = []; -setInterval(function() { - for (var i = 0; i < 100; i++) { - leaks.push(new LeakingClass); - } - - console.error('Leaks: %d', leaks.length); -}, 1000); \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/admin.js b/frontend/express/node_modules/mongodb/lib/mongodb/admin.js deleted file mode 100644 index 6e9cd306cb4..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/admin.js +++ /dev/null @@ -1,339 +0,0 @@ -/*! - * Module dependencies. - */ -var Collection = require('./collection').Collection, - Cursor = require('./cursor').Cursor, - DbCommand = require('./commands/db_command').DbCommand, - utils = require('./utils'); - -/** - * Allows the user to access the admin functionality of MongoDB - * - * @class Represents the Admin methods of MongoDB. - * @param {Object} db Current db instance we wish to perform Admin operations on. - * @return {Function} Constructor for Admin type. - */ -function Admin(db) { - if(!(this instanceof Admin)) return new Admin(db); - this.db = db; -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.buildInfo = function(callback) { - this.serverInfo(callback); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured. - * @return {null} Returns no result - * @api private - */ -Admin.prototype.serverInfo = function(callback) { - this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Retrieve this db's server status. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.serverStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) { - callback(null, doc.documents[0]); - } else { - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - } - }); -}; - -/** - * Retrieve the current profiling Level for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingLevel = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({profile:-1}, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) { - var was = doc.was; - if(was == 0) return callback(null, "off"); - if(was == 1) return callback(null, "slow_only"); - if(was == 2) return callback(null, "all"); - return callback(new Error("Error: illegal profiling level value " + was), null); - } else { - err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - } - }); -}; - -/** - * Ping the MongoDB server and retrieve results - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.ping = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - - this.db.executeDbAdminCommand({ping: 1}, callback); -} - -/** - * Authenticate against MongoDB - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.authenticate = function(username, password, callback) { - this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Logout current authenticated user - * - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.logout = function(callback) { - this.db.logout({authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Add a user to the MongoDB server, if the user exists it will - * overwrite the current password - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.addUser = function(username, password, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - options.dbName = 'admin'; - // Add user - this.db.addUser(username, password, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Remove a user from the MongoDB server - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options.dbName = 'admin'; - - this.db.removeUser(username, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Set the current profiling level of MongoDB - * - * @param {String} level The new profiling level (off, slow_only, all) - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.setProfilingLevel = function(level, callback) { - var self = this; - var command = {}; - var profile = 0; - - if(level == "off") { - profile = 0; - } else if(level == "slow_only") { - profile = 1; - } else if(level == "all") { - profile = 2; - } else { - return callback(new Error("Error: illegal profiling level value " + level)); - } - - // Set up the profile number - command['profile'] = profile; - - this.db.executeDbAdminCommand(command, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) - return callback(null, level); - return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - }); -}; - -/** - * Retrive the current profiling information for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingInfo = function(callback) { - try { - new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) { - return callback(err, items); - }); - } catch (err) { - return callback(err, null); - } -}; - -/** - * Execute a db command against the Admin database - * - * @param {Object} command A command object `{ping:1}`. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.command = function(command, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Execute a command - this.db.executeDbAdminCommand(command, options, function(err, doc) { - // Ensure change before event loop executes - return callback != null ? callback(err, doc) : null; - }); -} - -/** - * Validate an existing collection - * - * @param {String} collectionName The name of the collection to validate. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.validateCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - var self = this; - var command = {validate: collectionName}; - var keys = Object.keys(options); - - // Decorate command with extra options - for(var i = 0; i < keys.length; i++) { - if(options.hasOwnProperty(keys[i])) { - command[keys[i]] = options[keys[i]]; - } - } - - this.db.executeDbCommand(command, function(err, doc) { - if(err != null) return callback(err, null); - doc = doc.documents[0]; - - if(doc.ok === 0) - return callback(new Error("Error with validate command"), null); - if(doc.result != null && doc.result.constructor != String) - return callback(new Error("Error with validation data"), null); - if(doc.result != null && doc.result.match(/exception|corrupt/) != null) - return callback(new Error("Error: invalid collection " + collectionName), null); - if(doc.valid != null && !doc.valid) - return callback(new Error("Error: invalid collection " + collectionName), null); - - return callback(null, doc); - }); -}; - -/** - * List the available databases - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.listDatabases = function(callback) { - // Execute the listAllDatabases command - this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Get ReplicaSet status - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.replSetGetStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) - return callback(null, doc.documents[0]); - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - }); -}; - -/** - * @ignore - */ -exports.Admin = Admin; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_cr.js b/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_cr.js deleted file mode 100644 index 51b09b1043e..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_cr.js +++ /dev/null @@ -1,53 +0,0 @@ -var DbCommand = require('../commands/db_command').DbCommand - , utils = require('../utils'); - -var authenticate = function(db, username, password, authdb, options, callback) { - var numberOfConnections = 0; - var errorObject = null; - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = db.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - // Execute all four - db._executeQueryCommand(DbCommand.createGetNonceCommand(db), options, function(err, result, connection) { - // Execute on all the connections - if(err == null) { - // Nonce used to make authentication request with md5 hash - var nonce = result.documents[0].nonce; - // Execute command - db._executeQueryCommand(DbCommand.createAuthenticationCommand(db, username, password, nonce, authdb), {connection:connection}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Ensure we save any error - if(err) { - errorObject = err; - } else if(result.documents[0].err != null || result.documents[0].errmsg != null){ - errorObject = utils.toError(result.documents[0]); - } - - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - - if(errorObject == null && result.documents[0].ok == 1) { - // We authenticated correctly save the credentials - db.serverConfig.auth.add('MONGODB-CR', db.databaseName, username, password, authdb); - // Return callback - internalCallback(errorObject, true); - } else { - internalCallback(errorObject, false); - } - } - }); - } - }); -} - -exports.authenticate = authenticate; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_gssapi.js b/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_gssapi.js deleted file mode 100644 index f41cd5d22da..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_gssapi.js +++ /dev/null @@ -1,148 +0,0 @@ -var DbCommand = require('../commands/db_command').DbCommand - , utils = require('../utils') - , format = require('util').format; - -// Kerberos class -var Kerberos = null; -var MongoAuthProcess = null; -// Try to grab the Kerberos class -try { - Kerberos = require('kerberos').Kerberos - // Authentication process for Mongo - MongoAuthProcess = require('kerberos').processes.MongoAuthProcess -} catch(err) {} - -var authenticate = function(db, username, password, authdb, options, callback) { - var numberOfConnections = 0; - var errorObject = null; - // We don't have the Kerberos library - if(Kerberos == null) return callback(new Error("Kerberos library is not installed")); - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = db.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - // Grab all the connections - var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections(); - var error = null; - // Authenticate all connections - for(var i = 0; i < numberOfConnections; i++) { - - // Start Auth process for a connection - GSSAPIInitialize(db, username, password, authdb, connections[i], function(err, result) { - // Adjust number of connections left to connect - numberOfConnections = numberOfConnections - 1; - // If we have an error save it - if(err) error = err; - - // We are done - if(numberOfConnections == 0) { - if(err) return callback(error, false); - // We authenticated correctly save the credentials - db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb); - // Return valid callback - return callback(null, true); - } - }); - } -} - -// -// Initialize step -var GSSAPIInitialize = function(db, username, password, authdb, connection, callback) { - // Create authenticator - var mongo_auth_process = new MongoAuthProcess(connection.socketOptions.host, connection.socketOptions.port); - - // Perform initialization - mongo_auth_process.init(username, password, function(err, context) { - if(err) return callback(err, false); - - // Perform the first step - mongo_auth_process.transition('', function(err, payload) { - if(err) return callback(err, false); - - // Call the next db step - MongoDBGSSAPIFirstStep(mongo_auth_process, payload, db, username, password, authdb, connection, callback); - }); - }); -} - -// -// Perform first step against mongodb -var MongoDBGSSAPIFirstStep = function(mongo_auth_process, payload, db, username, password, authdb, connection, callback) { - // Build the sasl start command - var command = { - saslStart: 1 - , mechanism: 'GSSAPI' - , payload: payload - , autoAuthorize: 1 - }; - - // Execute first sasl step - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err, false); - // Get the payload - doc = doc.documents[0]; - var db_payload = doc.payload; - - mongo_auth_process.transition(doc.payload, function(err, payload) { - if(err) return callback(err, false); - - // MongoDB API Second Step - MongoDBGSSAPISecondStep(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback); - }); - }); -} - -// -// Perform first step against mongodb -var MongoDBGSSAPISecondStep = function(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback) { - // Build Authentication command to send to MongoDB - var command = { - saslContinue: 1 - , conversationId: doc.conversationId - , payload: payload - }; - - // Execute the command - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err, false); - - // Get the result document - doc = doc.documents[0]; - - // Call next transition for kerberos - mongo_auth_process.transition(doc.payload, function(err, payload) { - if(err) return callback(err, false); - - // Call the last and third step - MongoDBGSSAPIThirdStep(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback); - }); - }); -} - -var MongoDBGSSAPIThirdStep = function(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback) { - // Build final command - var command = { - saslContinue: 1 - , conversationId: doc.conversationId - , payload: payload - }; - - // Let's finish the auth process against mongodb - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err, false); - - mongo_auth_process.transition(null, function(err, payload) { - if(err) return callback(err, false); - callback(null, true); - }); - }); -} - -exports.authenticate = authenticate; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_sspi.js b/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_sspi.js deleted file mode 100644 index 1990efd1f33..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/auth/mongodb_sspi.js +++ /dev/null @@ -1,134 +0,0 @@ -var DbCommand = require('../commands/db_command').DbCommand - , utils = require('../utils') - , format = require('util').format; - -// Kerberos class -var Kerberos = null; -var MongoAuthProcess = null; -// Try to grab the Kerberos class -try { - Kerberos = require('kerberos').Kerberos - // Authentication process for Mongo - MongoAuthProcess = require('kerberos').processes.MongoAuthProcess -} catch(err) {} - -var authenticate = function(db, username, password, authdb, options, callback) { - var numberOfConnections = 0; - var errorObject = null; - // We don't have the Kerberos library - if(Kerberos == null) return callback(new Error("Kerberos library is not installed")); - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = db.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - var connection = db.serverConfig.allRawConnections()[0]; - - // Grab all the connections - var connections = db.serverConfig.allRawConnections(); - var error = null; - - // Authenticate all connections - for(var i = 0; i < numberOfConnections; i++) { - // Start Auth process for a connection - SSIPAuthenticate(db, username, password, authdb, connections[i], function(err, result) { - // Adjust number of connections left to connect - numberOfConnections = numberOfConnections - 1; - // If we have an error save it - if(err) error = err; - - // We are done - if(numberOfConnections == 0) { - if(err) return callback(err, false); - // We authenticated correctly save the credentials - db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb); - // Return valid callback - return callback(null, true); - } - }); - } -} - -var SSIPAuthenticate = function(db, username, password, authdb, connection, callback) { - // -------------------------------------------------------------- - // Async Version - // -------------------------------------------------------------- - var command = { - saslStart: 1 - , mechanism: 'GSSAPI' - , payload: '' - , autoAuthorize: 1 - }; - - // Create authenticator - var mongo_auth_process = new MongoAuthProcess(connection.socketOptions.host, connection.socketOptions.port); - - // Execute first sasl step - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err); - doc = doc.documents[0]; - - mongo_auth_process.init(username, password, function(err) { - if(err) return callback(err); - - mongo_auth_process.transition(doc.payload, function(err, payload) { - if(err) return callback(err); - - // Perform the next step against mongod - var command = { - saslContinue: 1 - , conversationId: doc.conversationId - , payload: payload - }; - - // Execute the command - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err); - doc = doc.documents[0]; - - mongo_auth_process.transition(doc.payload, function(err, payload) { - if(err) return callback(err); - - // Perform the next step against mongod - var command = { - saslContinue: 1 - , conversationId: doc.conversationId - , payload: payload - }; - - // Execute the command - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err); - doc = doc.documents[0]; - - mongo_auth_process.transition(doc.payload, function(err, payload) { - // Perform the next step against mongod - var command = { - saslContinue: 1 - , conversationId: doc.conversationId - , payload: payload - }; - - // Execute the command - db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) { - if(err) return callback(err); - doc = doc.documents[0]; - - if(doc.done) return callback(null, true); - callback(new Error("Authentication failed"), false); - }); - }); - }); - }); - }); - }); - }); - }); -} - -exports.authenticate = authenticate; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary.js deleted file mode 100644 index 350be6b792d..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Module dependencies. - */ -var Buffer = require('buffer').Buffer; // TODO just use global Buffer -var bson = require('./bson'); - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? bson.BSON.BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - this.buffer = typeof buffer == 'string' ? new Buffer(buffer) : buffer; - this.position = buffer.length; - } else { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put (byte_value) { - if(this.buffer.length > this.position) { - this.buffer[this.position++] = byte_value.charCodeAt(0); - } else { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = byte_value.charCodeAt(0); - } -}; - -/** - * Writes. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = offset ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if (this.buffer.length < offset + string.length) { - var buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - // Assign the new buffer - this.buffer = buffer; - } - - if(Buffer.isBuffer(string)) { - string.copy(this.buffer, offset, 0, string.length); - } else { - this.buffer.write(string, 'binary', offset); - } - - this.position = offset + string.length; -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Return the buffer - return this.buffer.slice(position, position + length); -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 3; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 4; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_parser.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_parser.js deleted file mode 100644 index 1d6b07ce8a0..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_parser.js +++ /dev/null @@ -1,392 +0,0 @@ - -/** - * Module dependencies. - */ - -var sys = require('util'); - -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ - -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - sys.debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - sys.debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - sys.debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - sys.debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ - -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ - -exports.BinaryParser = BinaryParser; -BinaryParser.Buffer = BinaryParserBuffer; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_utils.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_utils.js deleted file mode 100644 index c52accdf724..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/binary_utils.js +++ /dev/null @@ -1,29 +0,0 @@ -exports.encodeInt = function(value) { - var buffer = new Buffer(4); - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = value & 0xff; - return buffer; -} - -exports.encodeIntInPlace = function(value, buffer, index) { - buffer[index + 3] = (value >> 24) & 0xff; - buffer[index + 2] = (value >> 16) & 0xff; - buffer[index + 1] = (value >> 8) & 0xff; - buffer[index] = value & 0xff; -} - -exports.encodeCString = function(string) { - var buf = new Buffer(string, 'utf8'); - return [buf, new Buffer([0])]; -} - -exports.decodeUInt32 = function(array, index) { - return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24; -} - -// Decode the int -exports.decodeUInt8 = function(array, index) { - return array[index]; -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/bson.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/bson.js deleted file mode 100644 index 53eec196ba4..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/bson.js +++ /dev/null @@ -1,1344 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var BinaryParser = require('./binary_parser').BinaryParser - , Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , debug = require('util').debug - , crypto = require('crypto') - , inspect = require('util').inspect - , inherits = require('util').inherits - , ieee754 = require('./float_parser'); - - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - switch(typeof value) { - case 'string': - return 1 + Buffer.byteLength(name, 'utf8') + 1 + 4 + Buffer.byteLength(value, 'utf8') + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (4 + 1); - } else { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (1); - case 'boolean': - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (12 + 1); - } else if(value instanceof Date) { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (8 + 1); - } else if(Buffer.isBuffer(value)) { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + 4 + 4 + Buffer.byteLength(value.code.toString(), 'utf8') + 1 + BSON.calculateObjectSize(value.scope); - } else { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + 4 + Buffer.byteLength(value.code.toString(), 'utf8') + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (value.position + 1 + 4 + 1); - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + (Buffer.byteLength(value.value, 'utf8') + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || toString.call(value) === '[object RegExp]') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + Buffer.byteLength(value.source, 'utf8') + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || toString.call(value) === '[object RegExp]') { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + Buffer.byteLength(value.source, 'utf8') + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + 4 + 4 + Buffer.byteLength(value.toString(), 'utf8') + 1 + BSON.calculateObjectSize(value.scope); - } else if(serializeFunctions) { - return (name != null ? (Buffer.byteLength(name) + 1) : 0) + 1 + 4 + Buffer.byteLength(value.toString(), 'utf8') + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - // console.log("packElement: " + name + " :: " + value) - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = Buffer.byteLength(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - buffer.write(value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write float - ieee754.writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write float - ieee754.writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write objectid - buffer.write(value.id, index, 'binary'); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Write float - ieee754.writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = Buffer.byteLength(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = Buffer.byteLength(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - // Write the data to the object - data.copy(buffer, index, 0, value.position); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Calculate size - size = Buffer.byteLength(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + Buffer.byteLength(value.source); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Serialize the object - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + Buffer.byteLength(value.source); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = Buffer.byteLength(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Encode the name - index = index + buffer.write(name, index, 'utf8') + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = Buffer.byteLength(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = new Buffer(BSON.calculateObjectSize(object, serializeFunctions)); - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = buffer.toString('utf8', index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 0 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - // Decode the oid - object[name] = new ObjectID(buffer.toString('binary', index, index + 12)); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = buffer.toString('utf8', index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = ieee754.readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = buffer.toString('utf8', index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = buffer.toString('utf8', index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/code.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/code.js deleted file mode 100644 index b2675385506..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/code.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/db_ref.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/db_ref.js deleted file mode 100644 index d44abb02423..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/db_ref.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/double.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/double.js deleted file mode 100644 index d77bc718670..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/double.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/float_parser.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/float_parser.js deleted file mode 100644 index 5d2af613b94..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/float_parser.js +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -exports.readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -exports.writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/long.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/long.js deleted file mode 100644 index a3c7e0763ab..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/long.js +++ /dev/null @@ -1,852 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/max_key.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/max_key.js deleted file mode 100644 index 20b4586cdd0..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/max_key.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/min_key.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/min_key.js deleted file mode 100644 index 265e563acb9..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/min_key.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/objectid.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/objectid.js deleted file mode 100644 index a78b2637dd1..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/objectid.js +++ /dev/null @@ -1,247 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser, - inspect = require('util').inspect, - debug = require('util').debug; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -function ObjectID(id) { - this._bsontype = 'ObjectID'; - - var self = this; - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters in hex format"); - // Generate id based on the input - if(id == null || typeof id == 'number') { - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else { - this.id = id; - } - - /** - * Returns the generation time in seconds that this ID was generated. - * - * @field generationTime - * @type {Number} - * @getter - * @setter - * @property return number of seconds in the timestamp part of the 12 byte id. - */ - Object.defineProperty(this, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - } - }); -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - return this.__id = hexString; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromHexString(time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - var objectID = new ObjectID(); - objectID.id = BinaryParser.encodeInt(time, 32, true, true) + BinaryParser.encodeInt(0, 64, true, true) - return objectID; -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(hexString != null && hexString.length != 24) throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters in hex format"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result); -}; - -/** - * Expose. - */ -exports.ObjectID = ObjectID; - diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/symbol.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/symbol.js deleted file mode 100644 index 67174157617..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/symbol.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/bson/timestamp.js b/frontend/express/node_modules/mongodb/lib/mongodb/bson/timestamp.js deleted file mode 100644 index db6003c03e1..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/bson/timestamp.js +++ /dev/null @@ -1,852 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/collection.js b/frontend/express/node_modules/mongodb/lib/mongodb/collection.js deleted file mode 100644 index 482ec7656ee..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/collection.js +++ /dev/null @@ -1,1763 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var InsertCommand = require('./commands/insert_command').InsertCommand - , QueryCommand = require('./commands/query_command').QueryCommand - , DeleteCommand = require('./commands/delete_command').DeleteCommand - , UpdateCommand = require('./commands/update_command').UpdateCommand - , DbCommand = require('./commands/db_command').DbCommand - , ObjectID = require('bson').ObjectID - , Code = require('bson').Code - , Cursor = require('./cursor').Cursor - , utils = require('./utils'); - -/** - * Precompiled regexes - * @ignore -**/ -const eErrorMessages = /No matching object found/; - -/** - * toString helper. - * @ignore - */ -var toString = Object.prototype.toString; - -/** - * Create a new Collection instance (INTERNAL TYPE) - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **slaveOk** {Boolean, default:false}, Allow reads from secondaries. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - * @class Represents a Collection - * @param {Object} db db instance. - * @param {String} collectionName collection name. - * @param {Object} [pkFactory] alternative primary key factory. - * @param {Object} [options] additional options for the collection. - * @return {Object} a collection instance. - */ -function Collection (db, collectionName, pkFactory, options) { - if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options); - - checkCollectionName(collectionName); - - this.db = db; - this.collectionName = collectionName; - this.internalHint = null; - this.opts = options != null && ('object' === typeof options) ? options : {}; - this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk; - this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions; - this.raw = options == null || options.raw == null ? db.raw : options.raw; - - this.readPreference = options == null || options.readPreference == null ? db.serverConfig.options.readPreference : options.readPreference; - this.readPreference = this.readPreference == null ? 'primary' : this.readPreference; - - this.pkFactory = pkFactory == null - ? ObjectID - : pkFactory; - - var self = this; -} - -/** - * Inserts a single document or a an array of documents into MongoDB. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Array|Object} docs - * @param {Object} [options] optional options for insert command - * @param {Function} [callback] optional callback for the function, must be provided when using a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.insert = function insert (docs, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - insertAll(self, Array.isArray(docs) ? docs : [docs], options, callback); - return this; -}; - -/** - * @ignore - */ -var checkCollectionName = function checkCollectionName (collectionName) { - if ('string' !== typeof collectionName) { - throw Error("collection name must be a String"); - } - - if (!collectionName || collectionName.indexOf('..') != -1) { - throw Error("collection names cannot be empty"); - } - - if (collectionName.indexOf('$') != -1 && - collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) { - throw Error("collection names must not contain '$'"); - } - - if (collectionName.match(/^\.|\.$/) != null) { - throw Error("collection names must not start or end with '.'"); - } -}; - -/** - * Removes documents specified by `selector` from the db. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **single** {Boolean, default:false}, removes the first document found. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [selector] optional select, no selector is equivalent to removing all documents. - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a remove with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.remove = function remove(selector, options, callback) { - if ('function' === typeof selector) { - callback = selector; - selector = options = {}; - } else if ('function' === typeof options) { - callback = options; - options = {}; - } - - // Ensure options - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Ensure we have at least an empty selector - selector = selector == null ? {} : selector; - // Set up flags for the command, if we have a single document remove - var flags = 0 | (options.single ? 1 : 0); - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Create a delete command - var deleteCommand = new DeleteCommand( - this.db - , dbName + "." + this.collectionName - , selector - , flags); - - var self = this; - var errorOptions = _getWriteConcern(self, options, callback); - // Execute the command, do not add a callback as it's async - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = true; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeRemoveCommand(deleteCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, error[0].n); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - var result = this.db._executeRemoveCommand(deleteCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * Renames the collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} newName the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback the callback accepting the result - * @return {null} - * @api public - */ -Collection.prototype.rename = function rename (newName, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - // Ensure the new name is valid - checkCollectionName(newName); - // Execute the command, return the new renamed collection if successful - self.db._executeQueryCommand(DbCommand.createRenameCollectionCommand(self.db, self.collectionName, newName, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - if(callback != null) { - // Set current object to point to the new name - self.collectionName = newName; - // Return the current collection - callback(null, self); - } - } else if(result.documents[0].errmsg != null) { - if(null != callback) { - if (null == err) { - err = utils.toError(result.documents[0]); - } - callback(err, null); - } - } - }); -}; - -/** - * @ignore - */ -var insertAll = function insertAll (self, docs, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Insert options (flags for insert) - var insertFlags = {}; - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['keepGoing'] != null) { - insertFlags['keepGoing'] = options['keepGoing']; - } - - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['continueOnError'] != null) { - insertFlags['continueOnError'] = options['continueOnError']; - } - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = self.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - insertFlags['serializeFunctions'] = options['serializeFunctions']; - } else { - insertFlags['serializeFunctions'] = self.serializeFunctions; - } - - // Pass in options - var insertCommand = new InsertCommand( - self.db - , dbName + "." + self.collectionName, true, insertFlags); - - // Add the documents and decorate them with id's if they have none - for(var index = 0, len = docs.length; index < len; ++index) { - var doc = docs[index]; - - // Add id to each document if it's not already defined - if (!(Buffer.isBuffer(doc)) && doc['_id'] == null && self.db.forceServerObjectId != true) { - doc['_id'] = self.pkFactory.createPk(); - } - - insertCommand.add(doc); - } - - // Collect errorOptions - var errorOptions = _getWriteConcern(self, options, callback); - // Default command options - var commandOptions = {}; - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - self.db._executeInsertCommand(insertCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if (err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, docs); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute the call without a write concern - var result = self.db._executeInsertCommand(insertCommand, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, docs); - } -}; - -/** - * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic - * operators and update instead for more efficient operations. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [doc] the document to save - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a safe save - * @return {null} - * @api public - */ -Collection.prototype.save = function save(doc, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Throw an error if attempting to perform a bulk operation - if(Array.isArray(doc)) throw new Error("doc parameter must be a single document"); - // Extract the id, if we have one we need to do a update command - var id = doc['_id']; - var commandOptions = _getWriteConcern(this, options, callback); - - if(id) { - commandOptions.upsert = true; - this.update({ _id: id }, doc, commandOptions, callback); - } else { - this.insert(doc, commandOptions, callback && function (err, docs) { - if (err) return callback(err, null); - - if (Array.isArray(docs)) { - callback(err, docs[0]); - } else { - callback(err, docs); - } - }); - } -}; - -/** - * Updates documents. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **multi** {Boolean, default:false}, update all documents matching the selector. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} selector the query to select the document/documents to be updated - * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted. - * @param {Object} [options] additional options during update. - * @param {Function} [callback] must be provided if you performing an update with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.update = function update(selector, document, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // If we are not providing a selector or document throw - if(selector == null || typeof selector != 'object') return callback(new Error("selector must be a valid JavaScript object")); - if(document == null || typeof document != 'object') return callback(new Error("document must be a valid JavaScript object")); - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - var updateCommand = new UpdateCommand( - this.db - , dbName + "." + this.collectionName - , selector - , document - , options); - - var self = this; - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeUpdateCommand(updateCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - // Perform the callback - callback(null, error[0].n, error[0]); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute update - var result = this.db._executeUpdateCommand(updateCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * The distinct command returns returns a list of distinct values for the given key across a collection. - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} key key to run distinct against. - * @param {Object} [query] option query to narrow the returned objects. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from distinct or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.distinct = function distinct(key, query, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - query = args.length ? args.shift() || {} : {}; - options = args.length ? args.shift() || {} : {}; - - var mapCommandHash = { - 'distinct': this.collectionName - , 'query': query - , 'key': key - }; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // Create the command - var cmd = DbCommand.createDbSlaveOkCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err) - return callback(err); - if(result.documents[0].ok != 1) - return callback(new Error(result.documents[0].errmsg)); - callback(null, result.documents[0].values); - }); -}; - -/** - * Count number of matching documents in the db to a query. - * - * Options - * - **skip** {Number}, The number of documents to skip for the count. - * - **limit** {Number}, The limit of documents to count. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object} [query] query to filter by before performing count. - * @param {Object} [options] additional options during count. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the count method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.count = function count (query, options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - query = args.length ? args.shift() || {} : {}; - options = args.length ? args.shift() || {} : {}; - var skip = options.skip; - var limit = options.limit; - - // Final query - var final_query = { - 'count': this.collectionName - , 'query': query - , 'fields': null - }; - - // Add limit and skip if defined - if(typeof skip == 'number') final_query.skip = skip; - if(typeof limit == 'number') final_query.limit = limit; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Set up query options - var queryOptions = QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - if (this.slaveOk || this.db.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - var queryCommand = new QueryCommand( - this.db - , this.db.databaseName + ".$cmd" - , queryOptions - , 0 - , -1 - , final_query - , null - ); - - var self = this; - this.db._executeQueryCommand(queryCommand, {read:readPreference}, function (err, result) { - result = result && result.documents; - if(!callback) return; - - if(err) return callback(err); - if (result[0].ok != 1 || result[0].errmsg) { - return callback(utils.toError(result[0])); - } - callback(null, result[0].n); - }); -}; - - -/** - * Drop the collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the drop method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.drop = function drop(callback) { - this.db.dropCollection(this.collectionName, callback); -}; - -/** - * Find and update a document. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **remove** {Boolean, default:false}, set to true to remove the object before returning. - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} doc - the fields/vals to be updated - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndModify method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndModify = function findAndModify (query, sort, doc, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() || [] : []; - doc = args.length ? args.shift() : null; - options = args.length ? args.shift() || {} : {}; - var self = this; - - var queryObject = { - 'findandmodify': this.collectionName - , 'query': query - , 'sort': utils.formattedOrderClause(sort) - }; - - queryObject.new = options.new ? 1 : 0; - queryObject.remove = options.remove ? 1 : 0; - queryObject.upsert = options.upsert ? 1 : 0; - - if (options.fields) { - queryObject.fields = options.fields; - } - - if (doc && !options.remove) { - queryObject.update = doc; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - // If we have j, w or something else do the getLast Error path - if(errorOptions != null - && typeof errorOptions == 'object' - && (errorOptions.w != 0 && errorOptions.w != 1 && errorOptions.safe != false)) { - // Commands to send - var commands = []; - // Add the find and modify command - commands.push(DbCommand.createDbCommand(this.db, queryObject, options)); - // If we have safe defined we need to return both call results - var chainedCommands = errorOptions != null ? true : false; - // Add error command if we have one - if(chainedCommands) { - commands.push(DbCommand.createGetLastErrorCommand(errorOptions, this.db)); - } - - // Fire commands and - this.db._executeQueryCommand(commands, {read:false}, function(err, result) { - if(err != null) return callback(err); - result = result && result.documents; - - if(result[0].err != null) { - return callback(utils.toError(result[0]), null); - } - - // Workaround due to 1.8.X returning an error on no matching object - // while 2.0.X does not not, making 2.0.X behaviour standard - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - return callback(null, result[0].value, result[0]); - }); - } else { - // Only run command and rely on getLastError command - var command = DbCommand.createDbCommand(this.db, queryObject, options) - // Execute command - this.db._executeQueryCommand(command, {read:false}, function(err, result) { - if(err != null) return callback(err); - - result = result && result.documents; - - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - // If we have an error return it - if(result[0].lastErrorObject && result[0].lastErrorObject.err != null) { - return callback(utils.toError(result[0].lastErrorObject), null); - } - - return callback(null, result[0].value, result[0]); - }); - } -} - -/** - * Find and remove a document - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndRemove method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndRemove = function(query, sort, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() || [] : []; - options = args.length ? args.shift() || {} : {}; - // Add the remove option - options['remove'] = true; - // Execute the callback - this.findAndModify(query, sort, null, options, callback); -} - -var testForFields = { - limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1 - , numberOfRetries: 1, awaitdata: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1 - , comment: 1, raw: 1, readPreference: 1, partial: 1, read: 1, dbName: 1 -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **tailableRetryInterval** {Number, default:100}, specify the miliseconds between getMores on tailable cursor. - * - **numberOfRetries** {Number, default:5}, specify the number of times to retry the tailable cursor. - * - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor. - * - **exhaust** {Boolean, default:false} have the server send all the documents at once as getMore packets, not recommended. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **numberOfRetries** {Number, default:5}, if using awaidata specifies the number of times to retry on timeout. - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object|ObjectID} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the find method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.find = function find () { - var options - , args = Array.prototype.slice.call(arguments, 0) - , has_callback = typeof args[args.length - 1] === 'function' - , has_weird_callback = typeof args[0] === 'function' - , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null) - , len = args.length - , selector = len >= 1 ? args[0] : {} - , fields = len >= 2 ? args[1] : undefined; - - if(len === 1 && has_weird_callback) { - // backwards compat for callback?, options case - selector = {}; - options = args[0]; - } - - if(len === 2 && !Array.isArray(fields)) { - var fieldKeys = Object.getOwnPropertyNames(fields); - var is_option = false; - - for(var i = 0; i < fieldKeys.length; i++) { - if(testForFields[fieldKeys[i]] != null) { - is_option = true; - break; - } - } - - if(is_option) { - options = fields; - fields = undefined; - } else { - options = {}; - } - } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) { - var newFields = {}; - // Rewrite the array - for(var i = 0; i < fields.length; i++) { - newFields[fields[i]] = 1; - } - // Set the fields - fields = newFields; - } - - if(3 === len) { - options = args[2]; - } - - // Ensure selector is not null - selector = selector == null ? {} : selector; - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Validate correctness of the field selector - var object = fields; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Check special case where we are using an objectId - if(selector instanceof ObjectID || (selector != null && selector._bsontype == 'ObjectID')) { - selector = {_id:selector}; - } - - // If it's a serialized fields field we need to just let it through - // user be warned it better be good - if(options && options.fields && !(Buffer.isBuffer(options.fields))) { - fields = {}; - - if(Array.isArray(options.fields)) { - if(!options.fields.length) { - fields['_id'] = 1; - } else { - for (var i = 0, l = options.fields.length; i < l; i++) { - fields[options.fields[i]] = 1; - } - } - } else { - fields = options.fields; - } - } - - if (!options) options = {}; - options.skip = len > 3 ? args[2] : options.skip ? options.skip : 0; - options.limit = len > 3 ? args[3] : options.limit ? options.limit : 0; - options.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw; - options.hint = options.hint != null ? normalizeHintField(options.hint) : this.internalHint; - options.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout; - // If we have overridden slaveOk otherwise use the default db setting - options.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk; - - // Set option - var o = options; - // Support read/readPreference - if(o["read"] != null) o["readPreference"] = o["read"]; - // Set the read preference - o.read = o["readPreference"] ? o.readPreference : this.readPreference; - // Adjust slave ok if read preference is secondary or secondary only - if(o.read == "secondary" || o.read == "secondaryOnly") options.slaveOk = true; - - // callback for backward compatibility - if(callback) { - // TODO refactor Cursor args - callback(null, new Cursor(this.db, this, selector, fields, o)); - } else { - return new Cursor(this.db, this, selector, fields, o); - } -}; - -/** - * Normalizes a `hint` argument. - * - * @param {String|Object|Array} hint - * @return {Object} - * @api private - */ -var normalizeHintField = function normalizeHintField(hint) { - var finalHint = null; - - if(typeof hint == 'string') { - finalHint = hint; - } else if(Array.isArray(hint)) { - finalHint = {}; - - hint.forEach(function(param) { - finalHint[param] = 1; - }); - } else if(hint != null && typeof hint == 'object') { - finalHint = {}; - for (var name in hint) { - finalHint[name] = hint[name]; - } - } - - return finalHint; -}; - -/** - * Finds a single document based on the query - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object|ObjectID} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findOne method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.findOne = function findOne () { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - var callback = args.pop(); - var cursor = this.find.apply(this, args).limit(-1).batchSize(1); - // Return the item - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the createIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.createIndex = function createIndex (fieldOrSpec, options, callback) { - // Clean up call - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Collect errorOptions - var errorOptions = _getWriteConcern(this, options, callback); - // Execute create index - this.db.createIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the ensureIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.ensureIndex = function ensureIndex (fieldOrSpec, options, callback) { - // Clean up call - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Execute create index - this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexInformation method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexInformation = function indexInformation (options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - // Call the index information - this.db.indexInformation(this.collectionName, options, callback); -}; - -/** - * Drops an index from this collection. - * - * @param {String} name - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropIndex = function dropIndex (name, callback) { - this.db.dropIndex(this.collectionName, name, callback); -}; - -/** - * Drops all indexes from this collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropAllIndexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropAllIndexes = function dropIndexes (callback) { - this.db.dropIndex(this.collectionName, '*', function (err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Drops all indexes from this collection. - * - * @deprecated - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndexes method or null if an error occured. - * @return {null} - * @api private - */ -Collection.prototype.dropIndexes = Collection.prototype.dropAllIndexes; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the reIndex method or null if an error occured. - * @return {null} - * @api public -**/ -Collection.prototype.reIndex = function(callback) { - this.db.reIndex(this.collectionName, callback); -} - -/** - * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection. - * - * Options - * - **out** {Object}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}* - * - **query** {Object}, query filter object. - * - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces. - * - **limit** {Number}, number of objects to return from collection. - * - **keeptemp** {Boolean, default:false}, keep temporary data. - * - **finalize** {Function | String}, finalize function. - * - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize. - * - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X. - * - **verbose** {Boolean, default:false}, provide statistics on job execution time. - * - **readPreference** {String, only for inline results}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Function|String} map the mapping function. - * @param {Function|String} reduce the reduce function. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the mapReduce method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.mapReduce = function mapReduce (map, reduce, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers) - if(null == options.out) { - throw new Error("the out option parameter must be defined, see mongodb docs for possible values"); - } - - if ('function' === typeof map) { - map = map.toString(); - } - - if ('function' === typeof reduce) { - reduce = reduce.toString(); - } - - if ('function' === typeof options.finalize) { - options.finalize = options.finalize.toString(); - } - - var mapCommandHash = { - mapreduce: this.collectionName - , map: map - , reduce: reduce - }; - - // Add any other options passed in - for (var name in options) { - if ('scope' == name) { - mapCommandHash[name] = processScope(options[name]); - } else { - mapCommandHash[name] = options[name]; - } - } - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // If we have a read preference and inline is not set as output fail hard - if(readPreference != false && options['out'] != 'inline') { - throw new Error("a readPreference can only be provided when performing an inline mapReduce"); - } - - // self - var self = this; - var cmd = DbCommand.createDbCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if (err) { - return callback(err); - } - - // - if (1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) { - return callback(utils.toError(result.documents[0])); - } - - // Create statistics value - var stats = {}; - if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis; - if(result.documents[0].counts) stats['counts'] = result.documents[0].counts; - if(result.documents[0].timing) stats['timing'] = result.documents[0].timing; - - // invoked with inline? - if(result.documents[0].results) { - return callback(null, result.documents[0].results, stats); - } - - // The returned collection - var collection = null; - - // If we have an object it's a different db - if(result.documents[0].result != null && typeof result.documents[0].result == 'object') { - var doc = result.documents[0].result; - collection = self.db.db(doc.db).collection(doc.collection); - } else { - // Create a collection object that wraps the result collection - collection = self.db.collection(result.documents[0].result) - } - - // If we wish for no verbosity - if(options['verbose'] == null || !options['verbose']) { - return callback(err, collection); - } - - // Return stats as third set of values - callback(err, collection, stats); - }); -}; - -/** - * Functions that are passed as scope args must - * be converted to Code instances. - * @ignore - */ -function processScope (scope) { - if (!utils.isObject(scope)) { - return scope; - } - - var keys = Object.keys(scope); - var i = keys.length; - var key; - - while (i--) { - key = keys[i]; - if ('function' == typeof scope[key]) { - scope[key] = new Code(String(scope[key])); - } - } - - return scope; -} - -/** - * Group function helper - * @ignore - */ -var groupFunction = function () { - var c = db[ns].find(condition); - var map = new Map(); - var reduce_function = reduce; - - while (c.hasNext()) { - var obj = c.next(); - var key = {}; - - for (var i = 0, len = keys.length; i < len; ++i) { - var k = keys[i]; - key[k] = obj[k]; - } - - var aggObj = map.get(key); - - if (aggObj == null) { - var newObj = Object.extend({}, key); - aggObj = Object.extend(newObj, initial); - map.put(key, aggObj); - } - - reduce_function(obj, aggObj); - } - - return { "result": map.values() }; -}.toString(); - -/** - * Run a group command across a collection - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by. - * @param {Object} condition an optional condition that must be true for a row to be considered. - * @param {Object} initial initial value of the aggregation counter object. - * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated - * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned. - * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the group method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.group = function group(keys, condition, initial, reduce, finalize, command, options, callback) { - var args = Array.prototype.slice.call(arguments, 3); - callback = args.pop(); - // Fetch all commands - reduce = args.length ? args.shift() : null; - finalize = args.length ? args.shift() : null; - command = args.length ? args.shift() : null; - options = args.length ? args.shift() || {} : {}; - - // Make sure we are backward compatible - if(!(typeof finalize == 'function')) { - command = finalize; - finalize = null; - } - - if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) { - keys = Object.keys(keys); - } - - if(typeof reduce === 'function') { - reduce = reduce.toString(); - } - - if(typeof finalize === 'function') { - finalize = finalize.toString(); - } - - // Set up the command as default - command = command == null ? true : command; - - // Execute using the command - if(command) { - var reduceFunction = reduce instanceof Code - ? reduce - : new Code(reduce); - - var selector = { - group: { - 'ns': this.collectionName - , '$reduce': reduceFunction - , 'cond': condition - , 'initial': initial - , 'out': "inline" - } - }; - - // if finalize is defined - if(finalize != null) selector.group['finalize'] = finalize; - // Set up group selector - if ('function' === typeof keys || keys instanceof Code) { - selector.group.$keyf = keys instanceof Code - ? keys - : new Code(keys); - } else { - var hash = {}; - keys.forEach(function (key) { - hash[key] = 1; - }); - selector.group.key = hash; - } - - var cmd = DbCommand.createDbSlaveOkCommand(this.db, selector); - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : this.readPreference; - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err != null) return callback(err); - - var document = result.documents[0]; - if (null == document.retval) { - return callback(new Error("group command failed: " + document.errmsg)); - } - - callback(null, document.retval); - }); - - } else { - // Create execution scope - var scope = reduce != null && reduce instanceof Code - ? reduce.scope - : {}; - - scope.ns = this.collectionName; - scope.keys = keys; - scope.condition = condition; - scope.initial = initial; - - // Pass in the function text to execute within mongodb. - var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';'); - - this.db.eval(new Code(groupfn, scope), function (err, results) { - if (err) return callback(err, null); - callback(null, results.result || results); - }); - } -}; - -/** - * Returns the options of the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the options method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.options = function options(callback) { - this.db.collectionsInfo(this.collectionName, function (err, cursor) { - if (err) return callback(err); - cursor.nextObject(function (err, document) { - callback(err, document && document.options || null); - }); - }); -}; - -/** - * Returns if the collection is a capped collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the isCapped method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.isCapped = function isCapped(callback) { - this.options(function(err, document) { - if(err != null) { - callback(err); - } else { - callback(null, document && document.capped); - } - }); -}; - -/** - * Checks if one or more indexes exist on the collection - * - * @param {String|Array} indexNames check if one or more indexes exist on the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexExists method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexExists = function indexExists(indexes, callback) { - this.indexInformation(function(err, indexInformation) { - // If we have an error return - if(err != null) return callback(err, null); - // Let's check for the index names - if(Array.isArray(indexes)) { - for(var i = 0; i < indexes.length; i++) { - if(indexInformation[indexes[i]] == null) { - return callback(null, false); - } - } - - // All keys found return true - return callback(null, true); - } else { - return callback(null, indexInformation[indexes] != null); - } - }); -} - -/** - * Execute the geoNear command to search for items in the collection - * - * Options - * - **num** {Number}, max number of results to return. - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions. - * - **query** {Object}, filter the results by a query. - * - **spherical** {Boolean, default:false}, perform query using a spherical model. - * - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X. - * - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoNear method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoNear = function geoNear(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() || {} : {}; - - // Build command object - var commandObject = { - geoNear:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['num'] != null) commandObject['num'] = options['num']; - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['distanceMultiplier'] != null) commandObject['distanceMultiplier'] = options['distanceMultiplier']; - if(options['query'] != null) commandObject['query'] = options['query']; - if(options['spherical'] != null) commandObject['spherical'] = options['spherical']; - if(options['uniqueDocs'] != null) commandObject['uniqueDocs'] = options['uniqueDocs']; - if(options['includeLocs'] != null) commandObject['includeLocs'] = options['includeLocs']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Execute a geo search using a geo haystack index on a collection. - * - * Options - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **search** {Object}, filter the results by a query. - * - **limit** {Number}, max number of results to return. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoHaystackSearch method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() || {} : {}; - - // Build command object - var commandObject = { - geoSearch:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['query'] != null) commandObject['search'] = options['query']; - if(options['search'] != null) commandObject['search'] = options['search']; - if(options['limit'] != null) commandObject['limit'] = options['limit']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Retrieve all the indexes on the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexes = function indexes(callback) { - // Return all the index information - this.db.indexInformation(this.collectionName, {full:true}, callback); -} - -/** - * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.1 - * - * Options - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Array} array containing all the aggregation framework commands for the execution. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the aggregate method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.aggregate = function(pipeline, options, callback) { - // * - **explain** {Boolean}, return the query plan for the aggregation pipeline instead of the results. 2.3, 2.4 - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - var self = this; - - // If we have any of the supported options in the options object - var opts = args[args.length - 1]; - options = opts.readPreference || opts.explain ? args.pop() : {} - - // Convert operations to an array - if(!Array.isArray(args[0])) { - pipeline = []; - // Push all the operations to the pipeline - for(var i = 0; i < args.length; i++) pipeline.push(args[i]); - } - - // Build the command - var command = { aggregate : this.collectionName, pipeline : pipeline}; - // Add all options - var keys = Object.keys(options); - // Add all options - for(var i = 0; i < keys.length; i++) { - command[keys[i]] = options[keys[i]]; - } - - // Execute the command - this.db.command(command, options, function(err, result) { - if(err) { - callback(err); - } else if(result['err'] || result['errmsg']) { - callback(utils.toError(result)); - } else if(typeof result == 'object' && result['serverPipeline']) { - callback(null, result); - } else { - callback(null, result.result); - } - }); -} - -/** - * Get all the collection statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the stats method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() || {} : {}; - - // Build command object - var commandObject = { - collStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * @ignore - */ -Object.defineProperty(Collection.prototype, "hint", { - enumerable: true - , get: function () { - return this.internalHint; - } - , set: function (v) { - this.internalHint = normalizeHintField(v); - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(self.opts.w != null || typeof self.opts.j == 'boolean' || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.opts); - } else if(typeof self.opts.safe == "boolean") { - finalOptions = {w: (self.opts.safe ? 1 : 0)}; - } else if(self.db.safe.w != null || typeof self.db.safe.j == 'boolean' || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.safe); - } else if(self.db.options.w != null || typeof self.db.options.j == 'boolean' || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.options); - } else if(typeof self.db.safe == "boolean") { - finalOptions = {w: (self.db.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Expose. - */ -exports.Collection = Collection; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/base_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/base_command.js deleted file mode 100644 index 955858283ce..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/base_command.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - Base object used for common functionality -**/ -var BaseCommand = exports.BaseCommand = function BaseCommand() { -}; - -var id = 1; -BaseCommand.prototype.getRequestId = function getRequestId() { - if (!this.requestId) this.requestId = id++; - return this.requestId; -}; - -BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {} - -BaseCommand.prototype.updateRequestId = function() { - this.requestId = id++; - return this.requestId; -}; - -// OpCodes -BaseCommand.OP_REPLY = 1; -BaseCommand.OP_MSG = 1000; -BaseCommand.OP_UPDATE = 2001; -BaseCommand.OP_INSERT = 2002; -BaseCommand.OP_GET_BY_OID = 2003; -BaseCommand.OP_QUERY = 2004; -BaseCommand.OP_GET_MORE = 2005; -BaseCommand.OP_DELETE = 2006; -BaseCommand.OP_KILL_CURSORS = 2007; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/db_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/db_command.js deleted file mode 100644 index f8751b5e6b1..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/db_command.js +++ /dev/null @@ -1,241 +0,0 @@ -var QueryCommand = require('./query_command').QueryCommand, - InsertCommand = require('./insert_command').InsertCommand, - inherits = require('util').inherits, - utils = require('../utils'), - crypto = require('crypto'); - -/** - Db Command -**/ -var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - QueryCommand.call(this); - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = dbInstance; - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(DbCommand, QueryCommand); - -// Constants -DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"; -DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes"; -DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile"; -DbCommand.SYSTEM_USER_COLLECTION = "system.users"; -DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd"; -DbCommand.SYSTEM_JS_COLLECTION = "system.js"; - -// New commands -DbCommand.NcreateIsMasterCommand = function(db, databaseName) { - return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -// Provide constructors for different db commands -DbCommand.createIsMasterCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -DbCommand.createCollectionInfoCommand = function(db, selector) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null); -}; - -DbCommand.createGetNonceCommand = function(db, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null); -}; - -DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) { - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var hash_password = md5.digest('hex'); - // Final key - md5 = crypto.createHash('md5'); - md5.update(nonce + username + hash_password); - var key = md5.digest('hex'); - // Creat selector - var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key}; - // Create db command - return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null); -}; - -DbCommand.createLogoutCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null); -}; - -DbCommand.createCreateCollectionCommand = function(db, collectionName, options) { - var selector = {'create':collectionName}; - // Modify the options to ensure correct behaviour - for(var name in options) { - if(options[name] != null && options[name].constructor != Function) selector[name] = options[name]; - } - // Execute the command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null); -}; - -DbCommand.createDropCollectionCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null); -}; - -DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName, options) { - var renameCollection = db.databaseName + "." + fromCollectionName; - var toCollection = db.databaseName + "." + toCollectionName; - var dropTarget = options && options.dropTarget ? options.dropTarget : false; - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget}, null); -}; - -DbCommand.createGetLastErrorCommand = function(options, db) { - - if (typeof db === 'undefined') { - db = options; - options = {}; - } - // Final command - var command = {'getlasterror':1}; - // If we have an options Object let's merge in the fields (fsync/wtimeout/w) - if('object' === typeof options) { - for(var name in options) { - command[name] = options[name] - } - } - - // Special case for w == 1, remove the w - if(1 == command.w) { - delete command.w; - } - - // Execute command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null); -}; - -DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand; - -DbCommand.createGetPreviousErrorsCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null); -}; - -DbCommand.createResetErrorHistoryCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null); -}; - -DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) { - var fieldHash = {}; - var indexes = []; - var keys; - - // Get all the fields accordingly - if('string' == typeof fieldOrSpec) { - // 'type' - indexes.push(fieldOrSpec + '_' + 1); - fieldHash[fieldOrSpec] = 1; - - } else if(utils.isArray(fieldOrSpec)) { - - fieldOrSpec.forEach(function(f) { - if('string' == typeof f) { - // [{location:'2d'}, 'type'] - indexes.push(f + '_' + 1); - fieldHash[f] = 1; - } else if(utils.isArray(f)) { - // [['location', '2d'],['type', 1]] - indexes.push(f[0] + '_' + (f[1] || 1)); - fieldHash[f[0]] = f[1] || 1; - } else if(utils.isObject(f)) { - // [{location:'2d'}, {type:1}] - keys = Object.keys(f); - keys.forEach(function(k) { - indexes.push(k + '_' + f[k]); - fieldHash[k] = f[k]; - }); - } else { - // undefined (ignore) - } - }); - - } else if(utils.isObject(fieldOrSpec)) { - // {location:'2d', type:1} - keys = Object.keys(fieldOrSpec); - keys.forEach(function(key) { - indexes.push(key + '_' + fieldOrSpec[key]); - fieldHash[key] = fieldOrSpec[key]; - }); - } - - // Generate the index name - var indexName = typeof options.name == 'string' - ? options.name - : indexes.join("_"); - - var selector = { - 'ns': db.databaseName + "." + collectionName, - 'key': fieldHash, - 'name': indexName - } - - // Ensure we have a correct finalUnique - var finalUnique = options == null || 'object' === typeof options - ? false - : options; - - // Set up options - options = options == null || typeof options == 'boolean' - ? {} - : options; - - // Add all the options - var keys = Object.keys(options); - for(var i = 0; i < keys.length; i++) { - selector[keys[i]] = options[keys[i]]; - } - - if(selector['unique'] == null) - selector['unique'] = finalUnique; - - var name = db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION; - var cmd = new InsertCommand(db, name, false); - return cmd.add(selector); -}; - -DbCommand.logoutCommand = function(db, command_hash, options) { - var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName; - return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -} - -DbCommand.createDropIndexCommand = function(db, collectionName, indexName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null); -}; - -DbCommand.createReIndexCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null); -}; - -DbCommand.createDropDatabaseCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null); -}; - -DbCommand.createDbCommand = function(db, command_hash, options, auth_db) { - var db_name = (auth_db ? auth_db : db.databaseName) + "." + DbCommand.SYSTEM_COMMAND_COLLECTION; - return new DbCommand(db, db_name, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options); -}; - -DbCommand.createAdminDbCommand = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -}; - -DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null); -}; - -DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options); -}; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/delete_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/delete_command.js deleted file mode 100644 index e6ae20ab6e6..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/delete_command.js +++ /dev/null @@ -1,114 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.flags = flags; - this.collectionName = collectionName; - this.selector = selector; - this.db = db; -}; - -inherits(DeleteCommand, BaseCommand); - -DeleteCommand.OP_DELETE = 2006; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 ZERO; // 0 - reserved for future use - mongo.BSON selector; // query object. See below for details. -} -*/ -DeleteCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff; - _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff; - _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff; - _command[_index] = DeleteCommand.OP_DELETE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(this.selector)) { - documentLength = this.selector.length; - // Copy the data into the current buffer - this.selector.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/get_more_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/get_more_command.js deleted file mode 100644 index d3aac02ef81..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/get_more_command.js +++ /dev/null @@ -1,83 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Get More Document Command -**/ -var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.numberToReturn = numberToReturn; - this.cursorId = cursorId; - this.db = db; -}; - -inherits(GetMoreCommand, BaseCommand); - -GetMoreCommand.OP_GET_MORE = 2005; - -GetMoreCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index++] = totalLengthOfCommand & 0xff; - _command[_index++] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 24) & 0xff; - - // Write the request ID - _command[_index++] = this.requestId & 0xff; - _command[_index++] = (this.requestId >> 8) & 0xff; - _command[_index++] = (this.requestId >> 16) & 0xff; - _command[_index++] = (this.requestId >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the op_code for the command - _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Number of documents to return - _command[_index++] = this.numberToReturn & 0xff; - _command[_index++] = (this.numberToReturn >> 8) & 0xff; - _command[_index++] = (this.numberToReturn >> 16) & 0xff; - _command[_index++] = (this.numberToReturn >> 24) & 0xff; - - // Encode the cursor id - var low_bits = this.cursorId.getLowBits(); - // Encode low bits - _command[_index++] = low_bits & 0xff; - _command[_index++] = (low_bits >> 8) & 0xff; - _command[_index++] = (low_bits >> 16) & 0xff; - _command[_index++] = (low_bits >> 24) & 0xff; - - var high_bits = this.cursorId.getHighBits(); - // Encode high bits - _command[_index++] = high_bits & 0xff; - _command[_index++] = (high_bits >> 8) & 0xff; - _command[_index++] = (high_bits >> 16) & 0xff; - _command[_index++] = (high_bits >> 24) & 0xff; - // Return command - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/insert_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/insert_command.js deleted file mode 100644 index d6a210017a5..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/insert_command.js +++ /dev/null @@ -1,147 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.documents = []; - this.checkKeys = checkKeys == null ? true : checkKeys; - this.db = db; - this.flags = 0; - this.serializeFunctions = false; - - // Ensure valid options hash - options = options == null ? {} : options; - - // Check if we have keepGoing set -> set flag if it's the case - if(options['keepGoing'] != null && options['keepGoing']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Check if we have keepGoing set -> set flag if it's the case - if(options['continueOnError'] != null && options['continueOnError']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(InsertCommand, BaseCommand); - -// OpCodes -InsertCommand.OP_INSERT = 2002; - -InsertCommand.prototype.add = function(document) { - if(Buffer.isBuffer(document)) { - var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24; - if(object_size != document.length) { - var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.documents.push(document); - return this; -}; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - BSON[] documents; // one or more documents to insert into the collection -} -*/ -InsertCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4); - // var docLength = 0 - for(var i = 0; i < this.documents.length; i++) { - if(Buffer.isBuffer(this.documents[i])) { - totalLengthOfCommand += this.documents[i].length; - } else { - // Calculate size of document - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true); - } - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff; - _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff; - _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff; - _command[_index] = InsertCommand.OP_INSERT & 0xff; - // Adjust index - _index = _index + 4; - // Write flags if any - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write all the bson documents to the buffer at the index offset - for(var i = 0; i < this.documents.length; i++) { - // Document binary length - var documentLength = 0 - var object = this.documents[i]; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - return _command; -}; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js deleted file mode 100644 index d8ccb0c3a64..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js +++ /dev/null @@ -1,98 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Insert Document Command -**/ -var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) { - BaseCommand.call(this); - - this.cursorIds = cursorIds; - this.db = db; -}; - -inherits(KillCursorCommand, BaseCommand); - -KillCursorCommand.OP_KILL_CURSORS = 2007; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - int32 numberOfCursorIDs; // number of cursorIDs in message - int64[] cursorIDs; // array of cursorIDs to close -} -*/ -KillCursorCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff; - _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff; - _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff; - _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Number of cursors to kill - var numberOfCursors = this.cursorIds.length; - _command[_index + 3] = (numberOfCursors >> 24) & 0xff; - _command[_index + 2] = (numberOfCursors >> 16) & 0xff; - _command[_index + 1] = (numberOfCursors >> 8) & 0xff; - _command[_index] = numberOfCursors & 0xff; - // Adjust index - _index = _index + 4; - - // Encode all the cursors - for(var i = 0; i < this.cursorIds.length; i++) { - // Encode the cursor id - var low_bits = this.cursorIds[i].getLowBits(); - // Encode low bits - _command[_index + 3] = (low_bits >> 24) & 0xff; - _command[_index + 2] = (low_bits >> 16) & 0xff; - _command[_index + 1] = (low_bits >> 8) & 0xff; - _command[_index] = low_bits & 0xff; - // Adjust index - _index = _index + 4; - - var high_bits = this.cursorIds[i].getHighBits(); - // Encode high bits - _command[_index + 3] = (high_bits >> 24) & 0xff; - _command[_index + 2] = (high_bits >> 16) & 0xff; - _command[_index + 1] = (high_bits >> 8) & 0xff; - _command[_index] = high_bits & 0xff; - // Adjust index - _index = _index + 4; - } - - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/query_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/query_command.js deleted file mode 100644 index 76829d9991f..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/query_command.js +++ /dev/null @@ -1,261 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = query, - object_size; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - object = returnFieldSelector; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Set up options - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - - // Ensure we have no null query - query = query == null ? {} : query; - // Wrap query in the $query parameter so we can add read preferences for mongos - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = db; - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(QueryCommand, BaseCommand); - -QueryCommand.OP_QUERY = 2004; - -/* - * Adds the read prefrence to the current command - */ -QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) { - // If we have readPreference set to true set to secondary prefered - if(readPreference == true) { - readPreference = 'secondaryPreferred'; - } else if(readPreference == 'false') { - readPreference = 'primary'; - } - - // Force the slave ok flag to be set if we are not using primary read preference - if(readPreference != false && readPreference != 'primary') { - this.queryOptions |= QueryCommand.OPTS_SLAVE; - } - - // Backward compatibility, ensure $query only set on read preference so 1.8.X works - if((readPreference != null || tags != null) && this.query['$query'] == null) { - this.query = {'$query': this.query}; - } - - // If we have no readPreference set and no tags, check if the slaveOk bit is set - if(readPreference == null && tags == null) { - // If we have a slaveOk bit set the read preference for MongoS - if(this.queryOptions & QueryCommand.OPTS_SLAVE) { - this.query['$readPreference'] = {mode: 'secondary'} - } else { - this.query['$readPreference'] = {mode: 'primary'} - } - } - - // Build read preference object - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - this.query['$readPreference'] = readPreference.toObject(); - } else if(readPreference != null) { - // Add the read preference - this.query['$readPreference'] = {mode: readPreference}; - - // If we have tags let's add them - if(tags != null) { - this.query['$readPreference']['tags'] = tags; - } - } -} - -/* -struct { - MsgHeader header; // standard message header - int32 opts; // query options. See below for details. - cstring fullCollectionName; // "dbname.collectionname" - int32 numberToSkip; // number of documents to skip when returning results - int32 numberToReturn; // number of documents to return in the first OP_REPLY - BSON query ; // query object. See below for details. - [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details. -} -*/ -QueryCommand.prototype.toBinary = function() { - // Total length of the command - var totalLengthOfCommand = 0; - // Calculate total length of the document - if(Buffer.isBuffer(this.query)) { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4); - } else { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4); - } - - // Calculate extra fields size - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true); - } - } else if(Buffer.isBuffer(this.returnFieldSelector)) { - totalLengthOfCommand += this.returnFieldSelector.length; - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff; - _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff; - _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff; - _command[_index] = QueryCommand.OP_QUERY & 0xff; - // Adjust index - _index = _index + 4; - - // Write the query options - _command[_index + 3] = (this.queryOptions >> 24) & 0xff; - _command[_index + 2] = (this.queryOptions >> 16) & 0xff; - _command[_index + 1] = (this.queryOptions >> 8) & 0xff; - _command[_index] = this.queryOptions & 0xff; - // Adjust index - _index = _index + 4; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the number of documents to skip - _command[_index + 3] = (this.numberToSkip >> 24) & 0xff; - _command[_index + 2] = (this.numberToSkip >> 16) & 0xff; - _command[_index + 1] = (this.numberToSkip >> 8) & 0xff; - _command[_index] = this.numberToSkip & 0xff; - // Adjust index - _index = _index + 4; - - // Write the number of documents to return - _command[_index + 3] = (this.numberToReturn >> 24) & 0xff; - _command[_index + 2] = (this.numberToReturn >> 16) & 0xff; - _command[_index + 1] = (this.numberToReturn >> 8) & 0xff; - _command[_index] = this.numberToReturn & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.query; - - // Serialize the selector - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Push field selector if available - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) { - // Document binary length - var documentLength = 0 - var object = this.returnFieldSelector; - - // Serialize the selector - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - // Return finished command - return _command; -}; - -// Constants -QueryCommand.OPTS_NONE = 0; -QueryCommand.OPTS_TAILABLE_CURSOR = 2; -QueryCommand.OPTS_SLAVE = 4; -QueryCommand.OPTS_OPLOG_REPLY = 8; -QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16; -QueryCommand.OPTS_AWAIT_DATA = 32; -QueryCommand.OPTS_EXHAUST = 64; -QueryCommand.OPTS_PARTIAL = 128; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/commands/update_command.js b/frontend/express/node_modules/mongodb/lib/mongodb/commands/update_command.js deleted file mode 100644 index 9829dea453d..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/commands/update_command.js +++ /dev/null @@ -1,174 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Update Document Command -**/ -var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) { - BaseCommand.call(this); - - var object = spec; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - var object = document; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.collectionName = collectionName; - this.spec = spec; - this.document = document; - this.db = db; - this.serializeFunctions = false; - - // Generate correct flags - var db_upsert = 0; - var db_multi_update = 0; - db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert; - db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update; - - // Flags - this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2); - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(UpdateCommand, BaseCommand); - -UpdateCommand.OP_UPDATE = 2001; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 flags; // bit vector. see below - BSON spec; // the query to select the document - BSON document; // the document data to update with or insert -} -*/ -UpdateCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) + - this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4); - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff; - _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff; - _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff; - _command[_index] = UpdateCommand.OP_UPDATE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the update flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.spec; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Document binary length - var documentLength = 0 - var object = this.document; - - // Serialize the document - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - return _command; -}; - -// Constants -UpdateCommand.DB_UPSERT = 0; -UpdateCommand.DB_MULTI_UPDATE = 1; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/base.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/base.js deleted file mode 100644 index 93b236ec23b..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/base.js +++ /dev/null @@ -1,465 +0,0 @@ -var EventEmitter = require('events').EventEmitter - , inherits = require('util').inherits - , mongodb_cr_authenticate = require('../auth/mongodb_cr.js').authenticate - , mongodb_gssapi_authenticate = require('../auth/mongodb_gssapi.js').authenticate - , mongodb_sspi_authenticate = require('../auth/mongodb_sspi.js').authenticate; - -var id = 0; - -/** - * Internal class for callback storage - * @ignore - */ -var CallbackStore = function() { - // Make class an event emitter - EventEmitter.call(this); - // Add a info about call variable - this._notReplied = {}; - this.id = id++; -} - -/** - * @ignore - */ -inherits(CallbackStore, EventEmitter); - -CallbackStore.prototype.notRepliedToIds = function() { - return Object.keys(this._notReplied); -} - -CallbackStore.prototype.callbackInfo = function(id) { - return this._notReplied[id]; -} - -/** - * Internal class for holding non-executed commands - * @ignore - */ -var NonExecutedOperationStore = function(config) { - this.config = config; - this.commands = { - read: [] - , write_reads: [] - , write: [] - }; -} - -NonExecutedOperationStore.prototype.write = function(op) { - this.commands.write.push(op); -} - -NonExecutedOperationStore.prototype.read_from_writer = function(op) { - this.commands.write_reads.push(op); -} - -NonExecutedOperationStore.prototype.read = function(op) { - this.commands.read.push(op); -} - -NonExecutedOperationStore.prototype.execute_queries = function(executeInsertCommand) { - var connection = this.config.checkoutReader(); - if(connection == null || connection instanceof Error) return; - - // Write out all the queries - while(this.commands.read.length > 0) { - // Get the next command - var command = this.commands.read.shift(); - // command['options'].connection = this.config.checkoutReader(); - command.options.connection = connection; - // Execute the next command - command.executeQueryCommand(command.db, command.db_command, command.options, command.callback); - } -} - -NonExecutedOperationStore.prototype.execute_writes = function() { - var connection = this.config.checkoutWriter(); - if(connection == null || connection instanceof Error) return; - - // Write out all the queries to the primary - while(this.commands.write_reads.length > 0) { - // Get the next command - var command = this.commands.write_reads.shift(); - command.options.connection = connection; - // Execute the next command - command.executeQueryCommand(command.db, command.db_command, command.options, command.callback); - } - - // Execute all write operations - while(this.commands.write.length > 0) { - // Get the next command - var command = this.commands.write.shift(); - // Set the connection - command.options.connection = connection; - // Execute the next command - command.executeInsertCommand(command.db, command.db_command, command.options, command.callback); - } -} - -/** - * Internal class for authentication storage - * @ignore - */ -var AuthStore = function() { - this._auths = []; -} - -AuthStore.prototype.add = function(authMechanism, dbName, username, password, authdbName) { - // Check for duplicates - if(!this.contains(dbName)) { - // Base config - var config = { - 'username':username - , 'password':password - , 'db': dbName - , 'authMechanism': authMechanism - }; - - // Add auth source if passed in - if(typeof authdbName == 'string') { - config['authdb'] = authdbName; - } - - // Push the config - this._auths.push(config); - } -} - -AuthStore.prototype.contains = function(dbName) { - for(var i = 0; i < this._auths.length; i++) { - if(this._auths[i].db == dbName) return true; - } - - return false; -} - -AuthStore.prototype.remove = function(dbName) { - var newAuths = []; - - // Filter out all the login details - for(var i = 0; i < this._auths.length; i++) { - if(this._auths[i].db != dbName) newAuths.push(this._auths[i]); - } - - // Set the filtered list - this._auths = newAuths; -} - -AuthStore.prototype.get = function(index) { - return this._auths[index]; -} - -AuthStore.prototype.length = function() { - return this._auths.length; -} - -AuthStore.prototype.toArray = function() { - return this._auths.slice(0); -} - -/** - * Internal class for storing db references - * @ignore - */ -var DbStore = function() { - this._dbs = []; -} - -DbStore.prototype.add = function(db) { - // this._dbs.push(db); - var found = false; - // Only add if it does not exist already - for(var i = 0; i < this._dbs.length; i++) { - if(db.databaseName == this._dbs[i].databaseName) found = true; - } - - if(!found) this._dbs.push(db); -} - -DbStore.prototype.reset = function() { - this._dbs = []; -} - -DbStore.prototype.emit = function(event, message, object, reset, filterDb) { - if(reset) { - while(this._dbs.length > 0) { - var db = this._dbs.shift(); - // Only emit if there is a listener - if(db.listeners(event).length > 0) { - if(filterDb == null || filterDb.databaseName !== db.databaseName - || filterDb.tag !== db.tag) { - db.emit(event, message, object); - } - } - } - } else { - for(var i = 0; i < this._dbs.length; i++) { - if(this._dbs[i].listeners(event).length > 0) { - if(filterDb == null || filterDb.databaseName !== this._dbs[i].databaseName - || filterDb.tag !== this._dbs[i].tag) { - this._dbs[i].emit(event, message, object); - } - } - } - } -} - -var Base = function Base() { - EventEmitter.call(this); - - // Callback store is part of connection specification - if(Base._callBackStore == null) { - Base._callBackStore = new CallbackStore(); - } - - // Create a new callback store - this._callBackStore = new CallbackStore(); - // All commands not being executed - this._commandsStore = new NonExecutedOperationStore(this); - // Create a new auth store - this.auth = new AuthStore(); - // Contains all the dbs attached to this server config - this._dbStore = new DbStore(); -} - -/** - * @ignore - */ -inherits(Base, EventEmitter); - -/** - * @ignore - */ -Base.prototype._apply_auths = function(db, callback) { - _apply_auths_serially(this, db, this.auth.toArray(), callback); -} - -var _apply_auths_serially = function(self, db, auths, callback) { - if(auths.length == 0) return callback(null, null); - // Get the first auth - var auth = auths.shift(); - var connections = self.allRawConnections(); - var connectionsLeft = connections.length; - - // Let's apply it to all raw connections - for(var i = 0; i < connections.length; i++) { - var options = {connection: connections[i]}; - - if(auth.authMechanism == 'GSSAPI') { - var connectionHandler = function(err, result) { - connectionsLeft = connectionsLeft - 1; - // If no more connections are left return - if(connectionsLeft == 0) { - return _apply_auths_serially(self, db, auths, callback); - } - } - - // We have the kerberos library, execute auth process - if(process.platform == 'win32') { - mongodb_sspi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback); - } else { - mongodb_gssapi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback); - } - } else if(auth.authMechanism == 'MONGODB-CR') { - mongodb_cr_authenticate(db, auth.username, auth.password, auth.authdb, options, callback); - } - } -} - -/** - * Fire all the errors - * @ignore - */ -Base.prototype.__executeAllCallbacksWithError = function(err) { - // Check all callbacks - var keys = Object.keys(this._callBackStore._notReplied); - // For each key check if it's a callback that needs to be returned - for(var j = 0; j < keys.length; j++) { - var info = this._callBackStore._notReplied[keys[j]]; - // Check if we have a chained command (findAndModify) - if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) { - var chained = info['chained']; - // Only callback once and the last one is the right one - var finalCallback = chained.pop(); - // Emit only the last event - this._callBackStore.emit(finalCallback, err, null); - - // Put back the final callback to ensure we don't call all commands in the chain - chained.push(finalCallback); - - // Remove all chained callbacks - for(var i = 0; i < chained.length; i++) { - delete this._callBackStore._notReplied[chained[i]]; - } - // Remove the key - delete this._callBackStore._notReplied[keys[j]]; - } else { - this._callBackStore.emit(keys[j], err, null); - // Remove the key - delete this._callBackStore._notReplied[keys[j]]; - } - } -} - -/** - * Fire all the errors - * @ignore - */ -Base.prototype.__executeAllServerSpecificErrorCallbacks = function(host, port, err) { - // Check all callbacks - var keys = Object.keys(this._callBackStore._notReplied); - // For each key check if it's a callback that needs to be returned - for(var j = 0; j < keys.length; j++) { - var info = this._callBackStore._notReplied[keys[j]]; - - if(info.connection) { - // Unpack the connection settings - var _host = info.connection.socketOptions.host; - var _port = info.connection.socketOptions.port; - // Check if we have a chained command (findAndModify) - if(info && info['chained'] - && Array.isArray(info['chained']) - && info['chained'].length > 0 - && _port == port && _host == host) { - var chained = info['chained']; - // Only callback once and the last one is the right one - var finalCallback = chained.pop(); - // Emit only the last event - this._callBackStore.emit(finalCallback, err, null); - - // Put back the final callback to ensure we don't call all commands in the chain - chained.push(finalCallback); - - // Remove all chained callbacks - for(var i = 0; i < chained.length; i++) { - delete this._callBackStore._notReplied[chained[i]]; - } - // Remove the key - delete this._callBackStore._notReplied[keys[j]]; - } else if(_port == port && _host == host) { - this._callBackStore.emit(keys[j], err, null); - // Remove the key - delete this._callBackStore._notReplied[keys[j]]; - } - } - } -} - -/** - * Register a handler - * @ignore - * @api private - */ -Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) { - // If we have an array of commands, chain them - var chained = Array.isArray(db_command); - - // Check if we have exhausted - if(typeof exhaust == 'function') { - callback = exhaust; - exhaust = false; - } - - // If they are chained we need to add a special handler situation - if(chained) { - // List off chained id's - var chainedIds = []; - // Add all id's - for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString()); - // Register all the commands together - for(var i = 0; i < db_command.length; i++) { - var command = db_command[i]; - // Add the callback to the store - this._callBackStore.once(command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection, exhaust:false}; - } - } else { - // Add the callback to the list of handlers - this._callBackStore.once(db_command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust}; - } -} - -/** - * Re-Register a handler, on the cursor id f.ex - * @ignore - * @api private - */ -Base.prototype._reRegisterHandler = function(newId, object, callback) { - // Add the callback to the list of handlers - this._callBackStore.once(newId, object.callback.listener); - // Add the information about the reply - this._callBackStore._notReplied[newId] = object.info; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._callHandler = function(id, document, err) { - // If there is a callback peform it - if(this._callBackStore.listeners(id).length >= 1) { - // Get info object - var info = this._callBackStore._notReplied[id]; - // Delete the current object - delete this._callBackStore._notReplied[id]; - // Emit to the callback of the object - this._callBackStore.emit(id, err, document, info.connection); - } -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._hasHandler = function(id) { - // If there is a callback peform it - return this._callBackStore.listeners(id).length >= 1; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._removeHandler = function(id) { - // Remove the information - if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id]; - // Remove the callback if it's registered - this._callBackStore.removeAllListeners(id); - // Force cleanup _events, node.js seems to set it as a null value - if(this._callBackStore._events != null) delete this._callBackStore._events[id]; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._findHandler = function(id) { - var info = this._callBackStore._notReplied[id]; - // Return the callback - return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null} -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) { - if(resetConnection) { - for(var i = 0; i < this._dbStore._dbs.length; i++) { - if(typeof this._dbStore._dbs[i].openCalled != 'undefined') - this._dbStore._dbs[i].openCalled = false; - } - } - - // Fire event - this._dbStore.emit(event, message, object, resetConnection, filterDb); -} - -exports.Base = Base; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection.js deleted file mode 100644 index 6753fd244e3..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection.js +++ /dev/null @@ -1,505 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - binaryutils = require('../utils'), - tls = require('tls'); - -var Connection = exports.Connection = function(id, socketOptions) { - // Set up event emitter - EventEmitter.call(this); - // Store all socket options - this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false}; - // Set keep alive default if not overriden - if(this.socketOptions.keepAlive == null && (process.platform !== "sunos" || process.platform !== "win32")) this.socketOptions.keepAlive = 100; - // Id for the connection - this.id = id; - // State of the connection - this.connected = false; - // Set if this is a domain socket - this.domainSocket = this.socketOptions.domainSocket; - - // - // Connection parsing state - // - this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE; - this.maxMessageSizeBytes = socketOptions.maxMessageSizeBytes ? socketOptions.maxMessageSizeBytes : Connection.DEFAULT_MAX_MESSAGE_SIZE; - // Contains the current message bytes - this.buffer = null; - // Contains the current message size - this.sizeOfMessage = 0; - // Contains the readIndex for the messaage - this.bytesRead = 0; - // Contains spill over bytes from additional messages - this.stubBuffer = 0; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]}; - - // Just keeps list of events we allow - resetHandlers(this, false); -} - -// Set max bson size -Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4; -// Set default to max bson to avoid overflow or bad guesses -Connection.DEFAULT_MAX_MESSAGE_SIZE = Connection.DEFAULT_MAX_BSON_SIZE; - -// Inherit event emitter so we can emit stuff wohoo -inherits(Connection, EventEmitter); - -Connection.prototype.start = function() { - var self = this; - - // If we have a normal connection - if(this.socketOptions.ssl) { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Check if the driver should validate the certificate - var validate_certificates = this.socketOptions.sslValidate == true ? true : false; - - // Create options for the tls connection - var tls_options = { - socket: this.connection - , rejectUnauthorized: false - } - - // If we wish to validate the certificate we have provided a ca store - if(validate_certificates) { - tls_options.ca = this.socketOptions.sslCA; - } - - // If we have a certificate to present - if(this.socketOptions.sslCert) { - tls_options.cert = this.socketOptions.sslCert; - tls_options.key = this.socketOptions.sslKey; - } - - // If the driver has been provided a private key password - if(this.socketOptions.sslPass) { - tls_options.passphrase = this.socketOptions.sslPass; - } - - // Contains the cleartext stream - var cleartext = null; - // Attempt to establish a TLS connection to the server - try { - cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() { - // If we have a ssl certificate validation error return an error - if(cleartext.authorizationError && validate_certificates) { - // Emit an error - return self.emit("error", cleartext.authorizationError, self, {ssl:true}); - } - - // Connect to the server - connectHandler(self)(); - }) - } catch(err) { - return self.emit("error", "SSL connection failed", self, {ssl:true}); - } - - // Save the output stream - this.writeSteam = cleartext; - - // Set up data handler for the clear stream - cleartext.on("data", createDataHandler(this)); - // Do any handling of end event of the stream - cleartext.on("end", endHandler(this)); - cleartext.on("error", errorHandler(this)); - - // Handle any errors - this.connection.on("error", errorHandler(this)); - // Handle timeout - this.connection.on("timeout", timeoutHandler(this)); - // Handle drain event - this.connection.on("drain", drainHandler(this)); - // Handle the close event - this.connection.on("close", closeHandler(this)); - } else { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Set up write stream - this.writeSteam = this.connection; - // Add handlers - this.connection.on("error", errorHandler(this)); - // Add all handlers to the socket to manage it - this.connection.on("connect", connectHandler(this)); - // this.connection.on("end", endHandler(this)); - this.connection.on("data", createDataHandler(this)); - this.connection.on("timeout", timeoutHandler(this)); - this.connection.on("drain", drainHandler(this)); - this.connection.on("close", closeHandler(this)); - } -} - -// Check if the sockets are live -Connection.prototype.isConnected = function() { - return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable; -} - -// Write the data out to the socket -Connection.prototype.write = function(command, callback) { - try { - // If we have a list off commands to be executed on the same socket - if(Array.isArray(command)) { - for(var i = 0; i < command.length; i++) { - var binaryCommand = command[i].toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]}); - - var r = this.writeSteam.write(binaryCommand); - } - } else { - var binaryCommand = command.toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command}); - - var r = this.writeSteam.write(binaryCommand); - } - } catch (err) { - if(typeof callback === 'function') callback(err); - } -} - -// Force the closure of the connection -Connection.prototype.close = function() { - // clear out all the listeners - resetHandlers(this, true); - // Add a dummy error listener to catch any weird last moment errors (and ignore them) - this.connection.on("error", function() {}) - // destroy connection - this.connection.destroy(); - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("closed connection", this.connection); - } -} - -// Reset all handlers -var resetHandlers = function(self, clearListeners) { - self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]}; - - // If we want to clear all the listeners - if(clearListeners && self.connection != null) { - var keys = Object.keys(self.eventHandlers); - // Remove all listeners - for(var i = 0; i < keys.length; i++) { - self.connection.removeAllListeners(keys[i]); - } - } -} - -// -// Handlers -// - -// Connect handler -var connectHandler = function(self) { - return function(data) { - // Set connected - self.connected = true; - // Now that we are connected set the socket timeout - self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout); - // Emit the connect event with no error - self.emit("connect", null, self); - } -} - -var createDataHandler = exports.Connection.createDataHandler = function(self) { - // We need to handle the parsing of the data - // and emit the messages when there is a complete one - return function(data) { - // Parse until we are done with the data - while(data.length > 0) { - // If we still have bytes to read on the current message - if(self.bytesRead > 0 && self.sizeOfMessage > 0) { - // Calculate the amount of remaining bytes - var remainingBytesToRead = self.sizeOfMessage - self.bytesRead; - // Check if the current chunk contains the rest of the message - if(remainingBytesToRead > data.length) { - // Copy the new data into the exiting buffer (should have been allocated when we know the message size) - data.copy(self.buffer, self.bytesRead); - // Adjust the number of bytes read so it point to the correct index in the buffer - self.bytesRead = self.bytesRead + data.length; - - // Reset state of buffer - data = new Buffer(0); - } else { - // Copy the missing part of the data into our current buffer - data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead); - // Slice the overflow into a new buffer that we will then re-parse - data = data.slice(remainingBytesToRead); - - // Emit current complete message - try { - var emitBuffer = self.buffer; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Emit the buffer - self.emit("message", emitBuffer, self); - } catch(err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } - } else { - // Stub buffer is kept in case we don't get enough bytes to determine the - // size of the message (< 4 bytes) - if(self.stubBuffer != null && self.stubBuffer.length > 0) { - - // If we have enough bytes to determine the message size let's do it - if(self.stubBuffer.length + data.length > 4) { - // Prepad the data - var newData = new Buffer(self.stubBuffer.length + data.length); - self.stubBuffer.copy(newData, 0); - data.copy(newData, self.stubBuffer.length); - // Reassign for parsing - data = newData; - - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - - } else { - - // Add the the bytes to the stub buffer - var newStubBuffer = new Buffer(self.stubBuffer.length + data.length); - // Copy existing stub buffer - self.stubBuffer.copy(newStubBuffer, 0); - // Copy missing part of the data - data.copy(newStubBuffer, self.stubBuffer.length); - // Exit parsing loop - data = new Buffer(0); - } - } else { - if(data.length > 4) { - // Retrieve the message size - var sizeOfMessage = binaryutils.decodeUInt32(data, 0); - // If we have a negative sizeOfMessage emit error and return - if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{ - sizeOfMessage: sizeOfMessage, - bytesRead: self.bytesRead, - stubBuffer: self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - return; - } - - // Ensure that the size of message is larger than 0 and less than the max allowed - if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) { - self.buffer = new Buffer(sizeOfMessage); - // Copy all the data into the buffer - data.copy(self.buffer, 0); - // Update bytes read - self.bytesRead = data.length; - // Update sizeOfMessage - self.sizeOfMessage = sizeOfMessage; - // Ensure stub buffer is null - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) { - try { - var emitBuffer = data; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:0, - buffer:null, - stubBuffer:null}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - - // Clear out the state of the parser - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else { - try { - var emitBuffer = data.slice(0, sizeOfMessage); - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Copy rest of message - data = data.slice(sizeOfMessage); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - - } - } else { - // Create a buffer that contains the space for the non-complete message - self.stubBuffer = new Buffer(data.length) - // Copy the data to the stub buffer - data.copy(self.stubBuffer, 0); - // Exit parsing loop - data = new Buffer(0); - } - } - } - } - } -} - -var endHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit end event - self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var timeoutHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit timeout event - self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self); - } -} - -var drainHandler = function(self) { - return function() { - } -} - -var errorHandler = function(self) { - return function(err) { - self.connection.destroy(); - // Set connected to false - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var closeHandler = function(self) { - return function(hadError) { - // If we have an error during the connection phase - if(hadError && !self.connected) { - // Set disconnected - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } else { - // Set disconnected - self.connected = false; - // Emit close - self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } - } -} - -// Some basic defaults -Connection.DEFAULT_PORT = 27017; - - - - - - - diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_pool.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_pool.js deleted file mode 100644 index 94cf75434a7..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_pool.js +++ /dev/null @@ -1,294 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - timers = require('timers'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - MongoReply = require("../responses/mongo_reply").MongoReply, - Connection = require("./connection").Connection; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) { - if(typeof host !== 'string') { - throw new Error("host must be specified [" + host + "]"); - } - - // Set up event emitter - EventEmitter.call(this); - - // Keep all options for the socket in a specific collection allowing the user to specify the - // Wished upon socket connection parameters - this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {}; - this.socketOptions.host = host; - this.socketOptions.port = port; - this.socketOptions.domainSocket = false; - this.bson = bson; - // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc) - this.poolSize = poolSize; - this.minPoolSize = Math.floor(this.poolSize / 2) + 1; - - // Check if the host is a socket - if(host.match(/^\//)) { - this.socketOptions.domainSocket = true; - } else if(typeof port === 'string') { - try { - port = parseInt(port, 10); - } catch(err) { - new Error("port must be specified or valid integer[" + port + "]"); - } - } else if(typeof port !== 'number') { - throw new Error("port must be specified [" + port + "]"); - } - - // Set default settings for the socket options - utils.setIntegerParameter(this.socketOptions, 'timeout', 0); - // Delay before writing out the data to the server - utils.setBooleanParameter(this.socketOptions, 'noDelay', true); - // Delay before writing out the data to the server - utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0); - // Set the encoding of the data read, default is binary == null - utils.setStringParameter(this.socketOptions, 'encoding', null); - // Allows you to set a throttling bufferSize if you need to stop overflows - utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0); - - // Internal structures - this.openConnections = []; - // Assign connection id's - this.connectionId = 0; - - // Current index for selection of pool connection - this.currentConnectionIndex = 0; - // The pool state - this._poolState = 'disconnected'; - // timeout control - this._timeout = false; - // Time to wait between connections for the pool - this._timeToWait = 10; -} - -inherits(ConnectionPool, EventEmitter); - -ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) { - if(maxBsonSize == null){ - maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxBsonSize = maxBsonSize; - } -} - -ConnectionPool.prototype.setMaxMessageSizeBytes = function(maxMessageSizeBytes) { - if(maxMessageSizeBytes == null){ - maxMessageSizeBytes = Connection.DEFAULT_MAX_MESSAGE_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxMessageSizeBytes = maxMessageSizeBytes; - } -} - -// Start a function -var _connect = function(_self) { - // return new function() { - // Create a new connection instance - var connection = new Connection(_self.connectionId++, _self.socketOptions); - // Set logger on pool - connection.logger = _self.logger; - // Connect handler - connection.on("connect", function(err, connection) { - // Add connection to list of open connections - _self.openConnections.push(connection); - // If the number of open connections is equal to the poolSize signal ready pool - if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') { - // Set connected - _self._poolState = 'connected'; - // Emit pool ready - _self.emit("poolReady"); - } else if(_self.openConnections.length < _self.poolSize) { - // Wait a little bit of time to let the close event happen if the server closes the connection - // so we don't leave hanging connections around - if(typeof _self._timeToWait == 'number') { - setTimeout(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }, _self._timeToWait); - } else { - processor(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }); - } - } - }); - - var numberOfErrors = 0 - - // Error handler - connection.on("error", function(err, connection, error_options) { - numberOfErrors++; - // If we are already disconnected ignore the event - if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) { - _self.emit("error", err, connection, error_options); - } - - // Close the connection - connection.close(); - // Set pool as disconnected - _self._poolState = 'disconnected'; - // Stop the pool - _self.stop(); - }); - - // Close handler - connection.on("close", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) { - _self.emit("close"); - } - - // Set disconnected - _self._poolState = 'disconnected'; - // Stop - _self.stop(); - }); - - // Timeout handler - connection.on("timeout", function(err, connection) { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) { - _self.emit("timeout", err); - } - - // Close the connection - connection.close(); - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - // Parse error, needs a complete shutdown of the pool - connection.on("parseError", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) { - _self.emit("parseError", new Error("parseError occured")); - } - - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - connection.on("message", function(message) { - _self.emit("message", message); - }); - - // Start connection in the next tick - connection.start(); - // }(); -} - - -// Start method, will throw error if no listeners are available -// Pass in an instance of the listener that contains the api for -// finding callbacks for a given message etc. -ConnectionPool.prototype.start = function() { - var markerDate = new Date().getTime(); - var self = this; - - if(this.listeners("poolReady").length == 0) { - throw "pool must have at least one listener ready that responds to the [poolReady] event"; - } - - // Set pool state to connecting - this._poolState = 'connecting'; - this._timeout = false; - - _connect(self); -} - -// Restart a connection pool (on a close the pool might be in a wrong state) -ConnectionPool.prototype.restart = function() { - // Close all connections - this.stop(false); - // Now restart the pool - this.start(); -} - -// Stop the connections in the pool -ConnectionPool.prototype.stop = function(removeListeners) { - removeListeners = removeListeners == null ? true : removeListeners; - // Set disconnected - this._poolState = 'disconnected'; - - // Clear all listeners if specified - if(removeListeners) { - this.removeAllEventListeners(); - } - - // Close all connections - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].close(); - } - - // Clean up - this.openConnections = []; -} - -// Check the status of the connection -ConnectionPool.prototype.isConnected = function() { - // return this._poolState === 'connected'; - return this.openConnections.length > 0 && this.openConnections[0].isConnected(); -} - -// Checkout a connection from the pool for usage, or grab a specific pool instance -ConnectionPool.prototype.checkoutConnection = function(id) { - var index = (this.currentConnectionIndex++ % (this.openConnections.length)); - var connection = this.openConnections[index]; - return connection; -} - -ConnectionPool.prototype.getAllConnections = function() { - return this.openConnections; -} - -// Remove all non-needed event listeners -ConnectionPool.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("connect"); - this.removeAllListeners("end"); - this.removeAllListeners("parseError"); - this.removeAllListeners("message"); - this.removeAllListeners("poolReady"); -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_utils.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_utils.js deleted file mode 100644 index 591092495a8..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/connection_utils.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.setIntegerParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) { - throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setBooleanParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "boolean") { - throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setStringParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "string") { - throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/mongos.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/mongos.js deleted file mode 100644 index 61a5bb17e8f..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/mongos.js +++ /dev/null @@ -1,470 +0,0 @@ -var ReadPreference = require('./read_preference').ReadPreference - , Base = require('./base').Base - , Server = require('./server').Server - , inherits = require('util').inherits; - -/** - * Mongos constructor provides a connection to a mongos proxy including failover to additional servers - * - * Options - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - * @class Represents a Mongos connection with failover to backup proxies - * @param {Array} list of mongos server objects - * @param {Object} [options] additional options for the mongos connection - */ -var Mongos = function Mongos(servers, options) { - // Set up basic - if(!(this instanceof Mongos)) - return new Mongos(servers, options); - - // Set up event emitter - Base.call(this); - - // Throw error on wrong setup - if(servers == null || !Array.isArray(servers) || servers.length == 0) - throw new Error("At least one mongos proxy must be in the array"); - - // Ensure we have at least an empty options object - this.options = options == null ? {} : options; - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - this._haInProgress = false; - // How often are we checking for new servers in the replicaset - this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 1000 : this.options['haInterval']; - // Save all the server connections - this.servers = servers; - // Servers we need to attempt reconnect with - this.downServers = []; - // Emit open setup - this.emitOpen = this.options.emitOpen || true; - // Just contains the current lowest ping time and server - this.lowestPingTimeServer = null; - this.lowestPingTime = 0; - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - - // Add options to servers - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - server._callBackStore = this._callBackStore; - server.auto_reconnect = false; - // Default empty socket options object - var socketOptions = {host: server.host, port: server.port}; - // If a socket option object exists clone it - if(this.socketOptions != null) { - var keys = Object.keys(this.socketOptions); - for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]]; - } - - // Set socket options - server.socketOptions = socketOptions; - } -} - -/** - * @ignore - */ -inherits(Mongos, Base); - -/** - * @ignore - */ -Mongos.prototype.isMongos = function() { - return true; -} - -/** - * @ignore - */ -Mongos.prototype.connect = function(db, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - - // Keep reference to parent - this.db = db; - // Set server state to connecting - this._serverState = 'connecting'; - // Number of total servers that need to initialized (known servers) - this._numberOfServersLeftToInitialize = this.servers.length; - // Connect handler - var connectHandler = function(_server) { - return function(err, result) { - self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1; - - if(self._numberOfServersLeftToInitialize == 0) { - // Start ha function if it exists - if(self.haEnabled) { - // Setup the ha process - if(self._replicasetTimeoutId != null) clearInterval(self._replicasetTimeoutId); - self._replicasetTimeoutId = setInterval(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - - // Set the mongos to connected - self._serverState = "connected"; - - // Emit the open event - if(self.emitOpen) - self.db.emit("open", null, self.db); - - // Callback - callback(null, self.db); - } - } - }; - - // Error handler - var errorOrCloseHandler = function(_server) { - return function(err, result) { - var validServers = []; - // Execute all the callbacks with errors - self.__executeAllCallbacksWithError(err); - // Check if we have the server - var found = false; - // Save the down server if it does not already exists - for(var i = 0; i < self.downServers.length; i++) { - if(self.downServers[i].host == _server.host && self.downServers[i].port == _server.port) { - found = true; - break; - } - } - - if(!found) - self.downServers.push(_server); - - // Remove the current server from the list - for(var i = 0; i < self.servers.length; i++) { - if(!(self.servers[i].host == _server.host && self.servers[i].port == _server.port) && self.servers[i].isConnected()) { - validServers.push(self.servers[i]); - } - } - - // Set current list of servers - self.servers = validServers; - - // Emit close across all the attached db instances - if(self.servers.length == 0) { - self._dbStore.emit("close", new Error("mongos disconnected, no valid proxies contactable over tcp"), null, true); - } - } - } - - // Mongo function - this.mongosCheckFunction = function() { - if(self._haInProgress) return; - // If all servers are down we are done - if(self.servers.length == 0) return; - - // Check that at least one server is available - var alldown = true; - for(var i = 0; i < self.servers.length; i++) { - if(self.servers[i].isConnected()) { - alldown = false; - break; - } - } - - // All servers are down - if(alldown) return; - - // Set as not waiting for check event - self._haInProgress = true; - // Check downed servers - if(self.downServers.length > 0) { - var numberOfServersLeft = self.downServers.length; - - // Iterate over all the downed servers - for(var i = 0; i < self.downServers.length; i++) { - // Pop a downed server - var downServer = self.downServers.pop(); - - // Set up the connection options for a Mongos - var options = { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: downServer.poolSize, - socketOptions: { - connectTimeoutMS: self._connectTimeoutMS, - socketTimeoutMS: self._socketTimeoutMS - } - } - - // Create a new server object - var newServer = new Server(downServer.host, downServer.port, options); - // Setup the connection function - var connectFunction = function(_db, _server, _options, _callback) { - return function() { - // Attempt to connect - _server.connect(_db, _options, function(err, result) { - numberOfServersLeft = numberOfServersLeft - 1; - - if(err) { - return _callback(err, _server); - } else { - // Set the new server settings - _server._callBackStore = self._callBackStore; - - // Add server event handlers - _server.on("close", errorOrCloseHandler(_server)); - _server.on("timeout", errorOrCloseHandler(_server)); - _server.on("error", errorOrCloseHandler(_server)); - - // Get a read connection - var _connection = _server.checkoutReader(); - // Get the start time - var startTime = new Date().getTime(); - - // Execute ping command to mark each server with the expected times - self.db.command({ping:1} - , {failFast:true, connection:_connection}, function(err, result) { - // Get the start time - var endTime = new Date().getTime(); - // Mark the server with the ping time - _server.runtimeStats['pingMs'] = endTime - startTime; - // Sort the servers on runtime so the first server always is the closest one - self.servers.sort(function(a, b) { - return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs']; - }); - - // Callback - return _callback(null, _server); - }); - } - }); - } - } - - // Attempt to connect to the database - connectFunction(self.db, newServer, options, function(err, _server) { - // If we have an error - if(err) { - self.downServers.push(_server); - } - - // Connection function - var connectionFunction = function(_auth, _connection, _callback) { - var pending = _auth.length(); - - for(var j = 0; j < pending; j++) { - // Get the auth object - var _auth = _auth.get(j); - // Unpack the parameter - var username = _auth.username; - var password = _auth.password; - var options = { - authMechanism: _auth.authMechanism - , authSource: _auth.authdb - , connection: _connection - }; - - // Hold any error - var _error = null; - // Authenticate against the credentials - self.db.authenticate(username, password, options, function(err, result) { - _error = err != null ? err : _error; - // Adjust the pending authentication - pending = pending - 1; - // Finished up - if(pending == 0) _callback(_error ? _error : null, _error ? false : true); - }); - } - } - - // Run auths against the connections - if(self.auth.length() > 0) { - var connections = _server.allRawConnections(); - var pendingAuthConn = connections.length; - - // No connections we are done - if(connections.length == 0) { - // Set ha done - if(numberOfServersLeft == 0) { - self._haInProgress = false; - } - } - - // Final error object - var finalError = null; - // Go over all the connections - for(var j = 0; j < connections.length; j++) { - - // Execute against all the connections - connectionFunction(self.auth, connections[j], function(err, result) { - // Pending authentication - pendingAuthConn = pendingAuthConn - 1 ; - - // Save error if any - finalError = err ? err : finalError; - - // If we are done let's finish up - if(pendingAuthConn == 0) { - // Set ha done - if(numberOfServersLeft == 0) { - self._haInProgress = false; - } - - if(finalError) { - return self.downServers.push(_server); - } - - // Push to list of valid server - self.servers.push(_server); - } - }); - } - } else { - self.servers.push(_server); - // Set ha done - if(numberOfServersLeft == 0) { - self._haInProgress = false; - } - } - })(); - } - } else { - self._haInProgress = false; - } - } - - // Connect all the server instances - for(var i = 0; i < this.servers.length; i++) { - // Get the connection - var server = this.servers[i]; - server.mongosInstance = this; - // Add server event handlers - server.on("close", errorOrCloseHandler(server)); - server.on("timeout", errorOrCloseHandler(server)); - server.on("error", errorOrCloseHandler(server)); - - // Configuration - var options = { - slaveOk: true, - poolSize: server.poolSize, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - returnIsMasterResults: true - } - - // Connect the instance - server.connect(self.db, options, connectHandler(server)); - } -} - -/** - * @ignore - * Just return the currently picked active connection - */ -Mongos.prototype.allServerInstances = function() { - return this.servers; -} - -/** - * Always ourselves - * @ignore - */ -Mongos.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Mongos.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - // Add all connections - for(var i = 0; i < this.servers.length; i++) { - allConnections = allConnections.concat(this.servers[i].allRawConnections()); - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -Mongos.prototype.isConnected = function() { - return this._serverState == "connected"; -} - -/** - * @ignore - */ -Mongos.prototype.canWrite = Mongos.prototype.isConnected; - -/** - * @ignore - */ -Mongos.prototype.canRead = Mongos.prototype.isConnected; - -/** - * @ignore - */ -Mongos.prototype.isDestroyed = function() { - return this._serverState == 'destroyed'; -} - -/** - * @ignore - */ -Mongos.prototype.checkoutWriter = function() { - if(this.servers.length == 0) return null; - return this.servers[0].checkoutWriter(); -} - -/** - * @ignore - */ -Mongos.prototype.checkoutReader = function(read) { - // If we have a read preference object unpack it - if(read != null && typeof read == 'object' && read['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode); - } else if(!ReadPreference.isValid(read)) { - throw new Error("Illegal readPreference mode specified, " + read); - } - - if(this.servers.length == 0) return null; - return this.servers[0].checkoutWriter(); -} - -/** - * @ignore - */ -Mongos.prototype.close = function(callback) { - var self = this; - // Set server status as disconnected - this._serverState = 'destroyed'; - // Number of connections to close - var numberOfConnectionsToClose = self.servers.length; - // If we have a ha process running kill it - if(self._replicasetTimeoutId != null) clearInterval(self._replicasetTimeoutId); - self._replicasetTimeoutId = null; - // Close all proxy connections - for(var i = 0; i < self.servers.length; i++) { - self.servers[i].close(function(err, result) { - numberOfConnectionsToClose = numberOfConnectionsToClose - 1; - // Callback if we have one defined - if(numberOfConnectionsToClose == 0 && typeof callback == 'function') { - callback(null); - } - }); - } -} - -/** - * @ignore - * Return the used state - */ -Mongos.prototype._isUsed = function() { - return this._used; -} - -exports.Mongos = Mongos; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/read_preference.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/read_preference.js deleted file mode 100644 index 6845171a347..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/read_preference.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * A class representation of the Read Preference. - * - * Read Preferences - * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.). - * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary. - * - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error. - * - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary. - * - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection. - * - * @class Represents a Read Preference. - * @param {String} the read preference type - * @param {Object} tags - * @return {ReadPreference} - */ -var ReadPreference = function(mode, tags) { - if(!(this instanceof ReadPreference)) - return new ReadPreference(mode, tags); - this._type = 'ReadPreference'; - this.mode = mode; - this.tags = tags; -} - -/** - * @ignore - */ -ReadPreference.isValid = function(_mode) { - return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED - || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED - || _mode == ReadPreference.NEAREST - || _mode == true || _mode == false); -} - -/** - * @ignore - */ -ReadPreference.prototype.isValid = function(mode) { - var _mode = typeof mode == 'string' ? mode : this.mode; - return ReadPreference.isValid(_mode); -} - -/** - * @ignore - */ -ReadPreference.prototype.toObject = function() { - var object = {mode:this.mode}; - - if(this.tags != null) { - object['tags'] = this.tags; - } - - return object; -} - -/** - * @ignore - */ -ReadPreference.PRIMARY = 'primary'; -ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred'; -ReadPreference.SECONDARY = 'secondary'; -ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred'; -ReadPreference.NEAREST = 'nearest' - -/** - * @ignore - */ -exports.ReadPreference = ReadPreference; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/ha.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/ha.js deleted file mode 100644 index c899712df32..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/ha.js +++ /dev/null @@ -1,392 +0,0 @@ -var DbCommand = require('../../commands/db_command').DbCommand - , format = require('util').format; - -var HighAvailabilityProcess = function(replset, options) { - this.replset = replset; - this.options = options; - this.server = null; - this.state = HighAvailabilityProcess.INIT; - this.selectedIndex = 0; -} - -HighAvailabilityProcess.INIT = 'init'; -HighAvailabilityProcess.RUNNING = 'running'; -HighAvailabilityProcess.STOPPED = 'stopped'; - -HighAvailabilityProcess.prototype.start = function() { - var self = this; - if(this.replset._state - && Object.keys(this.replset._state.addresses).length == 0) { - if(this.server) this.server.close(); - this.state = HighAvailabilityProcess.STOPPED; - return; - } - - if(this.server) this.server.close(); - // Start the running - this._haProcessInProcess = false; - this.state = HighAvailabilityProcess.RUNNING; - - // Get all possible reader servers - var candidate_servers = this.replset._state.getAllReadServers(); - if(candidate_servers.length == 0) { - return; - } - - // Select a candidate server for the connection - var server = candidate_servers[this.selectedIndex % candidate_servers.length]; - this.selectedIndex = this.selectedIndex + 1; - - // Unpack connection options - var connectTimeoutMS = self.options.connectTimeoutMS || 10000; - var socketTimeoutMS = self.options.socketTimeoutMS || 30000; - - // Just ensure we don't have a full cycle dependency - var Db = require('../../db').Db - var Server = require('../server').Server; - - // Set up a new server instance - var newServer = new Server(server.host, server.port, { - auto_reconnect: false - , returnIsMasterResults: true - , poolSize: 1 - , socketOptions: { - connectTimeoutMS: connectTimeoutMS, - socketTimeoutMS: socketTimeoutMS, - keepAlive: 100 - } - , ssl: this.options.ssl - , sslValidate: this.options.sslValidate - , sslCA: this.options.sslCA - , sslCert: this.options.sslCert - , sslKey: this.options.sslKey - , sslPass: this.options.sslPass - }); - - // Create new dummy db for app - self.db = new Db('local', newServer, {w:1}); - - // Set up the event listeners - newServer.once("error", _handle(this, newServer)); - newServer.once("close", _handle(this, newServer)); - newServer.once("timeout", _handle(this, newServer)); - newServer.name = format("%s:%s", server.host, server.port); - - // Let's attempt a connection over here - newServer.connect(self.db, function(err, result, _server) { - if(self.state == HighAvailabilityProcess.STOPPED) { - _server.close(); - } - - if(err) { - // Close the server - _server.close(); - // Check if we can even do HA (is there anything running) - if(Object.keys(self.replset._state.addresses).length == 0) { - return; - } - - // Let's boot the ha timeout settings - setTimeout(function() { - self.start(); - }, self.options.haInterval); - } else { - self.server = _server; - // Let's boot the ha timeout settings - setTimeout(_timeoutHandle(self), self.options.haInterval); - } - }); -} - -HighAvailabilityProcess.prototype.stop = function() { - this.state = HighAvailabilityProcess.STOPPED; - if(this.server) this.server.close(); -} - -var _timeoutHandle = function(self) { - return function() { - if(self.state == HighAvailabilityProcess.STOPPED) { - // Stop all server instances - for(var name in self.replset._state.addresses) { - self.replset._state.addresses[name].close(); - delete self.replset._state.addresses[name]; - } - - // Finished pinging - return; - } - - // If the server is connected - if(self.server.isConnected() && !self._haProcessInProcess) { - // Start HA process - self._haProcessInProcess = true; - // Execute is master command - self.db._executeQueryCommand(DbCommand.createIsMasterCommand(self.db), - {failFast:true, connection: self.server.checkoutReader()} - , function(err, res) { - if(err) { - self.server.close(); - return setTimeout(_timeoutHandle(self), self.options.haInterval); - } - - // Master document - var master = res.documents[0]; - var hosts = master.hosts || []; - var reconnect_servers = []; - var state = self.replset._state; - - // For all the hosts let's check that we have connections - for(var i = 0; i < hosts.length; i++) { - var host = hosts[i]; - - // Check if we need to reconnect to a server - if(state.addresses[host] == null) { - reconnect_servers.push(host); - } else if(state.addresses[host] && !state.addresses[host].isConnected()) { - state.addresses[host].close(); - reconnect_servers.push(host); - } - - if((master.primary && state.master == null) - || (master.primary && state.master.name != master.primary)) { - - // Locate the primary and set it - if(state.addresses[master.primary]) { - if(state.master) state.master.close(); - delete state.secondaries[master.primary]; - state.master = state.addresses[master.primary]; - } - - // Set up the changes - if(state.master != null && state.master.isMasterDoc != null) { - state.master.isMasterDoc.ismaster = true; - state.master.isMasterDoc.secondary = false; - } else if(state.master != null) { - state.master.isMasterDoc = master; - state.master.isMasterDoc.ismaster = true; - state.master.isMasterDoc.secondary = false; - } - - // Execute any waiting writes - self.replset._commandsStore.execute_writes(); - } - } - - // Let's reconnect to any server needed - if(reconnect_servers.length > 0) { - _reconnect_servers(self, reconnect_servers); - } else { - self._haProcessInProcess = false - return setTimeout(_timeoutHandle(self), self.options.haInterval); - } - }); - } else if(!self.server.isConnected()) { - setTimeout(function() { - return self.start(); - }, self.options.haInterval); - } else { - setTimeout(_timeoutHandle(self), self.options.haInterval); - } - } -} - -var _reconnect_servers = function(self, reconnect_servers) { - if(reconnect_servers.length == 0) { - self._haProcessInProcess = false - return setTimeout(_timeoutHandle(self), self.options.haInterval); - } - - // Unpack connection options - var connectTimeoutMS = self.options.connectTimeoutMS || 10000; - var socketTimeoutMS = self.options.socketTimeoutMS || 30000; - - // Server class - var Db = require('../../db').Db - var Server = require('../server').Server; - // Get the host - var host = reconnect_servers.shift(); - // Split it up - var _host = host.split(":")[0]; - var _port = parseInt(host.split(":")[1], 10); - - // Set up a new server instance - var newServer = new Server(_host, _port, { - auto_reconnect: false - , returnIsMasterResults: true - , poolSize: self.options.poolSize - , socketOptions: { - connectTimeoutMS: connectTimeoutMS, - socketTimeoutMS: socketTimeoutMS - } - , ssl: self.options.ssl - , sslValidate: self.options.sslValidate - , sslCA: self.options.sslCA - , sslCert: self.options.sslCert - , sslKey: self.options.sslKey - , sslPass: self.options.sslPass - }); - - // Create new dummy db for app - var db = new Db('local', newServer, {w:1}); - var state = self.replset._state; - - // Set up the event listeners - newServer.once("error", _repl_set_handler("error", self.replset, newServer)); - newServer.once("close", _repl_set_handler("close", self.replset, newServer)); - newServer.once("timeout", _repl_set_handler("timeout", self.replset, newServer)); - - // Set shared state - newServer.name = host; - newServer._callBackStore = self.replset._callBackStore; - newServer.replicasetInstance = self.replset; - newServer.enableRecordQueryStats(self.replset.recordQueryStats); - - // Let's attempt a connection over here - newServer.connect(db, function(err, result, _server) { - if(self.state == HighAvailabilityProcess.STOPPED) { - _server.close(); - } - - // If we connected let's check what kind of server we have - if(!err) { - _apply_auths(self, db, _server, function(err, result) { - if(err) { - _server.close(); - // Process the next server - return setTimeout(function() { - _reconnect_servers(self, reconnect_servers); - }, self.options.haInterval); - } - var doc = _server.isMasterDoc; - // Fire error on any unknown callbacks for this server - self.replset.__executeAllServerSpecificErrorCallbacks(_server.socketOptions.host, _server.socketOptions.port, err); - - if(doc.ismaster) { - if(state.secondaries[doc.me]) { - delete state.secondaries[doc.me]; - } - - // Override any server in list of addresses - state.addresses[doc.me] = _server; - // Set server as master - state.master = _server; - // Execute any waiting writes - self.replset._commandsStore.execute_writes(); - } else if(doc.secondary) { - state.secondaries[doc.me] = _server; - // Override any server in list of addresses - state.addresses[doc.me] = _server; - // Execute any waiting reads - self.replset._commandsStore.execute_queries(); - } else { - _server.close(); - } - - // Set any tags on the instance server - _server.name = doc.me; - _server.tags = doc.tags; - // Process the next server - setTimeout(function() { - _reconnect_servers(self, reconnect_servers); - }, self.options.haInterval); - }); - } else { - _server.close(); - self.replset.__executeAllServerSpecificErrorCallbacks(_server.socketOptions.host, _server.socketOptions.port, err); - - setTimeout(function() { - _reconnect_servers(self, reconnect_servers); - }, self.options.haInterval); - } - }); -} - -var _apply_auths = function(self, _db, _server, _callback) { - if(self.replset.auth.length() == 0) return _callback(null); - // Apply any authentication needed - if(self.replset.auth.length() > 0) { - var pending = self.replset.auth.length(); - var connections = _server.allRawConnections(); - var pendingAuthConn = connections.length; - - // Connection function - var connectionFunction = function(_auth, _connection, __callback) { - var pending = _auth.length(); - - for(var j = 0; j < pending; j++) { - // Get the auth object - var _auth = _auth.get(j); - // Unpack the parameter - var username = _auth.username; - var password = _auth.password; - var options = { - authMechanism: _auth.authMechanism - , authSource: _auth.authdb - , connection: _connection - }; - - // Hold any error - var _error = null; - - // Authenticate against the credentials - _db.authenticate(username, password, options, function(err, result) { - _error = err != null ? err : _error; - // Adjust the pending authentication - pending = pending - 1; - // Finished up - if(pending == 0) __callback(_error ? _error : null, _error ? false : true); - }); - } - } - - // Final error object - var finalError = null; - // Iterate over all the connections - for(var i = 0; i < connections.length; i++) { - connectionFunction(self.replset.auth, connections[i], function(err, result) { - // Pending authentication - pendingAuthConn = pendingAuthConn - 1 ; - - // Save error if any - finalError = err ? err : finalError; - - // If we are done let's finish up - if(pendingAuthConn == 0) { - _callback(null); - } - }); - } - } -} - -var _handle = function(self, server) { - return function(err) { - server.close(); - } -} - -var _repl_set_handler = function(event, self, server) { - var ReplSet = require('./repl_set').ReplSet; - - return function(err, doc) { - server.close(); - - // The event happened to a primary - // Remove it from play - if(self._state.isPrimary(server)) { - self._state.master == null; - self._serverState = ReplSet.REPLSET_READ_ONLY; - } else if(self._state.isSecondary(server)) { - delete self._state.secondaries[server.name]; - } - - // Unpack variables - var host = server.socketOptions.host; - var port = server.socketOptions.port; - - // Fire error on any unknown callbacks - self.__executeAllServerSpecificErrorCallbacks(host, port, err); - } -} - -exports.HighAvailabilityProcess = HighAvailabilityProcess; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js deleted file mode 100644 index a5658e3b0cf..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js +++ /dev/null @@ -1,126 +0,0 @@ -var PingStrategy = require('./strategies/ping_strategy').PingStrategy - , StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy - , ReadPreference = require('../read_preference').ReadPreference; - -var Options = function(options) { - options = options || {}; - this._options = options; - this.ha = options.ha || true; - this.haInterval = options.haInterval || 2000; - this.reconnectWait = options.reconnectWait || 1000; - this.retries = options.retries || 30; - this.rs_name = options.rs_name; - this.socketOptions = options.socketOptions || {}; - this.readPreference = options.readPreference; - this.readSecondary = options.read_secondary; - this.poolSize = options.poolSize == null ? 5 : options.poolSize; - this.strategy = options.strategy || 'ping'; - this.secondaryAcceptableLatencyMS = options.secondaryAcceptableLatencyMS || 15; - this.connectArbiter = options.connectArbiter || false; - this.connectWithNoPrimary = options.connectWithNoPrimary || false; - this.logger = options.logger; - this.ssl = options.ssl || false; - this.sslValidate = options.sslValidate || false; - this.sslCA = options.sslCA; - this.sslCert = options.sslCert; - this.sslKey = options.sslKey; - this.sslPass = options.sslPass; - this.emitOpen = options.emitOpen || true; -} - -Options.prototype.init = function() { - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Make sure strategy is one of the two allowed - if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical' && this.strategy != 'none')) - throw new Error("Only ping or statistical strategies allowed"); - - if(this.strategy == null) this.strategy = 'ping'; - - // Set logger if strategy exists - if(this.strategyInstance) this.strategyInstance.logger = this.logger; - - // Unpack read Preference - var readPreference = this.readPreference; - // Validate correctness of Read preferences - if(readPreference != null) { - if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED - && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED - && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("Illegal readPreference mode specified, " + readPreference); - } - - this.readPreference = readPreference; - } else { - this.readPreference = null; - } - - // Ensure read_secondary is set correctly - if(this.readSecondary != null) - this.readSecondary = this.readPreference == ReadPreference.PRIMARY - || this.readPreference == false - || this.readPreference == null ? false : true; - - // Ensure correct slave set - if(this.readSecondary) this.slaveOk = true; - - // Set up logger if any set - this.logger = this.logger != null - && (typeof this.logger.debug == 'function') - && (typeof this.logger.error == 'function') - && (typeof this.logger.debug == 'function') - ? this.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Connection timeout - this.connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - - // Socket connection timeout - this.socketTimeoutMS = this.socketOptions.socketTimeoutMS - ? this.socketOptions.socketTimeoutMS - : 30000; -} - -Options.prototype.decorateAndClean = function(servers, callBackStore) { - var self = this; - - // var de duplicate list - var uniqueServers = {}; - // De-duplicate any servers in the seed list - for(var i = 0; i < servers.length; i++) { - var server = servers[i]; - // If server does not exist set it - if(uniqueServers[server.host + ":" + server.port] == null) { - uniqueServers[server.host + ":" + server.port] = server; - } - } - - // Let's set the deduplicated list of servers - var finalServers = []; - // Add the servers - for(var key in uniqueServers) { - finalServers.push(uniqueServers[key]); - } - - finalServers.forEach(function(server) { - // Ensure no server has reconnect on - server.options.auto_reconnect = false; - // Set up ssl options - server.ssl = self.ssl; - server.sslValidate = self.sslValidate; - server.sslCA = self.sslCA; - server.sslCert = self.sslCert; - server.sslKey = self.sslKey; - server.sslPass = self.sslPass; - server.poolSize = self.poolSize; - // Set callback store - server._callBackStore = callBackStore; - }); - - return finalServers; -} - -exports.Options = Options; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js deleted file mode 100644 index 47b9e82bc6e..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js +++ /dev/null @@ -1,763 +0,0 @@ -var ReadPreference = require('../read_preference').ReadPreference - , DbCommand = require('../../commands/db_command').DbCommand - , inherits = require('util').inherits - , format = require('util').format - , timers = require('timers') - , Server = require('../server').Server - , utils = require('../../utils') - , PingStrategy = require('./strategies/ping_strategy').PingStrategy - , StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy - , Options = require('./options').Options - , ReplSetState = require('./repl_set_state').ReplSetState - , HighAvailabilityProcess = require('./ha').HighAvailabilityProcess - , Base = require('../base').Base; - -const STATE_STARTING_PHASE_1 = 0; -const STATE_PRIMARY = 1; -const STATE_SECONDARY = 2; -const STATE_RECOVERING = 3; -const STATE_FATAL_ERROR = 4; -const STATE_STARTING_PHASE_2 = 5; -const STATE_UNKNOWN = 6; -const STATE_ARBITER = 7; -const STATE_DOWN = 8; -const STATE_ROLLBACK = 9; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * ReplSet constructor provides replicaset functionality - * - * Options - * - **ha** {Boolean, default:true}, turn on high availability. - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect. - * - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect. - * - **rs_name** {String}, the name of the replicaset to connect to. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strategy** {String, default:'ping'}, selection strategy for reads choose between (ping, statistical and none, default is ping) - * - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms) - * - **connectWithNoPrimary** {Boolean, default:false}, sets if the driver should connect even if no primary is available - * - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - * @class Represents a Replicaset Configuration - * @param {Array} list of server objects participating in the replicaset. - * @param {Object} [options] additional options for the replicaset connection. - */ -var ReplSet = exports.ReplSet = function(servers, options) { - // Set up basic - if(!(this instanceof ReplSet)) - return new ReplSet(servers, options); - - // Set up event emitter - Base.call(this); - - // Ensure we have a list of servers - if(!Array.isArray(servers)) throw Error("The parameter must be an array of servers and contain at least one server"); - // Ensure no Mongos's - for(var i = 0; i < servers.length; i++) { - if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server"); - } - - // Save the options - this.options = new Options(options); - // Ensure basic validation of options - this.options.init(); - - // Server state - this._serverState = ReplSet.REPLSET_DISCONNECTED; - // Add high availability process - this._haProcess = new HighAvailabilityProcess(this, this.options); - - - // Let's iterate over all the provided server objects and decorate them - this.servers = this.options.decorateAndClean(servers, this._callBackStore); - // Throw error if no seed servers - if(this.servers.length == 0) throw new Error("No valid seed servers in the array"); - - // Let's set up our strategy object for picking secondaries - if(this.options.strategy == 'ping') { - // Create a new instance - this.strategyInstance = new PingStrategy(this, this.options.secondaryAcceptableLatencyMS); - } else if(this.options.strategy == 'statistical') { - // Set strategy as statistical - this.strategyInstance = new StatisticsStrategy(this); - // Add enable query information - this.enableRecordQueryStats(true); - } - - this.emitOpen = this.options.emitOpen || true; - // Set up a clean state - this._state = new ReplSetState(); - // Ensure up the server callbacks - for(var i = 0; i < this.servers.length; i++) { - this.servers[i]._callBackStore = this._callBackStore; - this.servers[i].name = format("%s:%s", this.servers[i].host, this.servers[i].port) - this.servers[i].replicasetInstance = this; - this.servers[i].options.auto_reconnect = false; - this.servers[i].inheritReplSetOptionsFrom(this); - } -} - -/** - * @ignore - */ -inherits(ReplSet, Base); - -// Replicaset states -ReplSet.REPLSET_CONNECTING = 'connecting'; -ReplSet.REPLSET_DISCONNECTED = 'disconnected'; -ReplSet.REPLSET_CONNECTED = 'connected'; -ReplSet.REPLSET_RECONNECTING = 'reconnecting'; -ReplSet.REPLSET_DESTROYED = 'destroyed'; -ReplSet.REPLSET_READ_ONLY = 'readonly'; - -ReplSet.prototype.isAutoReconnect = function() { - return true; -} - -ReplSet.prototype.canWrite = function() { - return this._state.master && this._state.master.isConnected(); -} - -ReplSet.prototype.canRead = function(read) { - if((read == ReadPreference.PRIMARY - || read == null || read == false) && (this._state.master == null || !this._state.master.isConnected())) return false; - return Object.keys(this._state.secondaries).length > 0; -} - -/** - * @ignore - */ -ReplSet.prototype.enableRecordQueryStats = function(enable) { - // Set the global enable record query stats - this.recordQueryStats = enable; - - // Enable all the servers - for(var i = 0; i < this.servers.length; i++) { - this.servers[i].enableRecordQueryStats(enable); - } -} - -/** - * @ignore - */ -ReplSet.prototype.setReadPreference = function(preference) { - this.options.readPreference = preference; -} - -ReplSet.prototype.connect = function(parent, options, callback) { - if(this._serverState != ReplSet.REPLSET_DISCONNECTED) - return callback(new Error("in process of connection")); - - // If no callback throw - if(!(typeof callback == 'function')) - throw new Error("cannot call ReplSet.prototype.connect with no callback function"); - - var self = this; - // Save db reference - this.options.db = parent; - // Set replicaset as connecting - this._serverState = ReplSet.REPLSET_CONNECTING - // Copy all the servers to our list of seeds - var candidateServers = this.servers.slice(0); - // Pop the first server - var server = candidateServers.pop(); - server.name = format("%s:%s", server.host, server.port); - // Set up the options - var opts = { - returnIsMasterResults: true, - eventReceiver: server - } - - // Register some event listeners - this.once("fullsetup", function(err, db, replset) { - // Set state to connected - self._serverState = ReplSet.REPLSET_CONNECTED; - // Stop any process running - if(self._haProcess) self._haProcess.stop(); - // Start the HA process - self._haProcess.start(); - - // Emit fullsetup - processor(function() { - if(self.emitOpen) - parent.emit("open", null, self.options.db, self); - - parent.emit("fullsetup", null, self.options.db, self); - }); - - // If we have a strategy defined start it - if(self.strategyInstance) { - self.strategyInstance.start(); - } - - // Finishing up the call - callback(err, db, replset); - }); - - // Errors - this.once("connectionError", function(err, result) { - callback(err, result); - }); - - // Attempt to connect to the server - server.connect(this.options.db, opts, _connectHandler(this, candidateServers, server)); -} - -ReplSet.prototype.close = function(callback) { - var self = this; - // Set as destroyed - this._serverState = ReplSet.REPLSET_DESTROYED; - // Stop the ha - this._haProcess.stop(); - - // If we have a strategy stop it - if(this.strategyInstance) { - this.strategyInstance.stop(); - } - - // Kill all servers available - for(var name in this._state.addresses) { - this._state.addresses[name].close(); - } - - // Clean out the state - this._state = new ReplSetState(); - - // Emit close event - processor(function() { - self._emitAcrossAllDbInstances(self, null, "close", null, null, true) - }); - - // Callback - if(typeof callback == 'function') - return callback(null, null); -} - -/** - * Creates a new server for the `replset` based on `host`. - * - * @param {String} host - host:port pair (localhost:27017) - * @param {ReplSet} replset - the ReplSet instance - * @return {Server} - * @ignore - */ -var createServer = function(self, host, options) { - // copy existing socket options to new server - var socketOptions = {} - if(options.socketOptions) { - var keys = Object.keys(options.socketOptions); - for(var k = 0; k < keys.length; k++) { - socketOptions[keys[k]] = options.socketOptions[keys[k]]; - } - } - - var parts = host.split(/:/); - if(1 === parts.length) { - parts[1] = Connection.DEFAULT_PORT; - } - - socketOptions.host = parts[0]; - socketOptions.port = parseInt(parts[1], 10); - - var serverOptions = { - readPreference: options.readPreference, - socketOptions: socketOptions, - // poolSize: options.poolSize, - poolSize: 1, - logger: options.logger, - auto_reconnect: false, - ssl: options.ssl, - sslValidate: options.sslValidate, - sslCA: options.sslCA, - sslCert: options.sslCert, - sslKey: options.sslKey, - sslPass: options.sslPass - } - - var server = new Server(socketOptions.host, socketOptions.port, serverOptions); - // Set up shared state - server._callBackStore = self._callBackStore; - server.replicasetInstance = self; - server.enableRecordQueryStats(self.recordQueryStats); - // Set up event handlers - server.on("close", _handler("close", self, server)); - server.on("error", _handler("error", self, server)); - server.on("timeout", _handler("timeout", self, server)); - return server; -} - -var _handler = function(event, self, server) { - return function(err, doc) { - // The event happened to a primary - // Remove it from play - if(self._state.isPrimary(server)) { - var current_master = self._state.master; - self._state.master = null; - self._serverState = ReplSet.REPLSET_READ_ONLY; - - if(current_master != null) { - // Unpack variables - var host = current_master.socketOptions.host; - var port = current_master.socketOptions.port; - - // Fire error on any unknown callbacks - self.__executeAllServerSpecificErrorCallbacks(host, port, err); - } - } else if(self._state.isSecondary(server)) { - delete self._state.secondaries[server.name]; - } - - // If there is no more connections left and the setting is not destroyed - // set to disconnected - if(Object.keys(self._state.addresses).length == 0 - && self._serverState != ReplSet.REPLSET_DESTROYED) { - self._serverState = ReplSet.REPLSET_DISCONNECTED; - - // Emit close across all the attached db instances - self._dbStore.emit("close", new Error("replicaset disconnected, no valid servers contactable over tcp"), null, true); - } - - // Unpack variables - var host = server.socketOptions.host; - var port = server.socketOptions.port; - - // Fire error on any unknown callbacks - self.__executeAllServerSpecificErrorCallbacks(host, port, err); - } -} - -var locateNewServers = function(self, state, candidateServers, ismaster) { - // Retrieve the host - var hosts = ismaster.hosts; - // In candidate servers - var inCandidateServers = function(name, candidateServers) { - for(var i = 0; i < candidateServers.length; i++) { - if(candidateServers[i].name == name) return true; - } - - return false; - } - - // New servers - var newServers = []; - if(Array.isArray(hosts)) { - // Let's go over all the hosts - for(var i = 0; i < hosts.length; i++) { - if(!state.contains(hosts[i]) - && !inCandidateServers(hosts[i], candidateServers)) { - newServers.push(createServer(self, hosts[i], self.options)); - } - } - } - - // Return list of possible new servers - return newServers; -} - -var _connectHandler = function(self, candidateServers, instanceServer) { - return function(err, doc) { - // If we have an error add to the list - if(err) self._state.errors[instanceServer.name] = instanceServer; - - // No error let's analyse the ismaster command - if(!err) { - var ismaster = doc.documents[0] - // console.dir(ismaster) - // If no replicaset name exists set the current one - if(self.options.rs_name == null) { - self.options.rs_name = ismaster.setName; - } - - // If we have a member that is not part of the set let's finish up - if(typeof ismaster.setName == 'string' && ismaster.setName != self.options.rs_name) { - return self.emit("connectionError", new Error("Replicaset name " + ismaster.setName + " does not match specified name " + self.options.rs_name)); - } - - // Add the error handlers - instanceServer.on("close", _handler("close", self, instanceServer)); - instanceServer.on("error", _handler("error", self, instanceServer)); - instanceServer.on("timeout", _handler("timeout", self, instanceServer)); - - // Set any tags on the instance server - instanceServer.name = ismaster.me; - instanceServer.tags = ismaster.tags; - - // Add the server to the list - self._state.addServer(instanceServer, ismaster); - - // Check if we have more servers to add (only check when done with initial set) - if(candidateServers.length == 0) { - // Get additional new servers that are not currently in set - var new_servers = locateNewServers(self, self._state, candidateServers, ismaster); - - // If we have new servers join them - if(new_servers.length > 0) { - candidateServers = candidateServers.concat(new_servers); - } - } - } - - // If the candidate server list is empty and no valid servers - if(candidateServers.length == 0 && - !self._state.hasValidServers()) { - return self.emit("connectionError", new Error("No valid replicaset instance servers found")); - } else if(candidateServers.length == 0) { - if(!self.options.connectWithNoPrimary && (self._state.master == null || !self._state.master.isConnected())) { - return self.emit("connectionError", new Error("No primary found in set")); - } - return self.emit("fullsetup", null, self.options.db, self); - } - - // Let's connect the next server - var nextServer = candidateServers.pop(); - - // Set up the options - var opts = { - returnIsMasterResults: true, - eventReceiver: nextServer - } - - // Attempt to connect to the server - nextServer.connect(self.options.db, opts, _connectHandler(self, candidateServers, nextServer)); - } -} - -ReplSet.prototype.isDestroyed = function() { - return this._serverState == ReplSet.REPLSET_DESTROYED; -} - -ReplSet.prototype.isConnected = function(read) { - var isConnected = false; - - if(read == null || read == ReadPreference.PRIMARY || read == false) - isConnected = this._state.master != null && this._state.master.isConnected(); - - if((read == ReadPreference.PRIMARY_PREFERRED || read == ReadPreference.SECONDARY_PREFERRED || read == ReadPreference.NEAREST) - && ((this._state.master != null && this._state.master.isConnected()) - || (this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0))) { - isConnected = true; - } else if(read == ReadPreference.SECONDARY) { - isConnected = this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0; - } - - // No valid connection return false - return isConnected; -} - -ReplSet.prototype.isMongos = function() { - return false; -} - -ReplSet.prototype.checkoutWriter = function() { - if(this._state.master) return this._state.master.checkoutWriter(); - return new Error("no writer connection available"); -} - -ReplSet.prototype.allRawConnections = function() { - var connections = []; - - for(var name in this._state.addresses) { - connections = connections.concat(this._state.addresses[name].allRawConnections()); - } - - return connections; -} - -/** - * @ignore - */ -ReplSet.prototype.allServerInstances = function() { - var self = this; - // If no state yet return empty - if(!self._state) return []; - // Close all the servers (concatenate entire list of servers first for ease) - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // Return complete list of all servers - return allServers; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutReader = function(readPreference, tags) { - var connection = null; - - // If we have a read preference object unpack it - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + readPreference.mode); - // Set the tag - tags = readPreference.tags; - readPreference = readPreference.mode; - } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') { - return new Error("read preferences must be either a string or an instance of ReadPreference"); - } - - // Set up our read Preference, allowing us to override the readPreference - var finalReadPreference = readPreference != null ? readPreference : this.options.readPreference; - - // Ensure we unpack a reference - if(finalReadPreference != null && typeof finalReadPreference == 'object' && finalReadPreference['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!finalReadPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + finalReadPreference.mode); - // Set the tag - tags = finalReadPreference.tags; - readPreference = finalReadPreference.mode; - } - - // Finalize the read preference setup - finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference; - finalReadPreference = finalReadPreference == null ? ReadPreference.PRIMARY : finalReadPreference; - - // If we are reading from a primary - if(finalReadPreference == 'primary') { - // If we provide a tags set send an error - if(typeof tags == 'object' && tags != null) { - return new Error("PRIMARY cannot be combined with tags"); - } - - // If we provide a tags set send an error - if(this._state.master == null) { - return new Error("No replica set primary available for query with ReadPreference PRIMARY"); - } - - // Checkout a writer - return this.checkoutWriter(); - } - - // If we have specified to read from a secondary server grab a random one and read - // from it, otherwise just pass the primary connection - if((this.options.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - // Only pick from secondaries - var _secondaries = []; - for(var key in this._state.secondaries) { - _secondaries.push(this._state.secondaries[key]); - } - - if(finalReadPreference == ReadPreference.SECONDARY) { - // Check out the nearest from only the secondaries - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - } else { - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null || connection instanceof Error) { - return new Error("No replica set members available for query"); - } - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) { - // Check if there is a primary available and return that if possible - connection = this.checkoutWriter(); - // If no connection available checkout a secondary - if(connection == null || connection instanceof Error) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } - } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null || connection instanceof Error) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null || connection instanceof Error) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } - } - } - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) { - return new Error("A strategy for calculating nearness must be enabled such as ping or statistical"); - } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) { - if(tags != null && typeof tags == 'object') { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } else { - return new Error("No replica set secondary available for query with ReadPreference SECONDARY"); - } - } else { - connection = this.checkoutWriter(); - } - - // Return the connection - return connection; -} - -/** - * @ignore - */ -var _pickFromTags = function(self, tags) { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Match all the servers that match the provdided tags - var keys = Object.keys(self._state.secondaries); - var candidateServers = []; - - for(var i = 0; i < keys.length; i++) { - var server = self._state.secondaries[keys[i]]; - // If we have tags match - if(server.tags != null) { - var matching = true; - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - candidateServers.push(server); - } - } - } - - // If we have a candidate server return - if(candidateServers.length > 0) { - if(self.strategyInstance) return self.strategyInstance.checkoutConnection(tags, candidateServers); - // Set instance to return - return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader(); - } - } - - // No connection found - return null; -} - -/** - * Pick a secondary using round robin - * - * @ignore - */ -function _roundRobin (replset, tags) { - var keys = Object.keys(replset._state.secondaries); - var key = keys[replset._currentServerChoice++ % keys.length]; - - var conn = null != replset._state.secondaries[key] - ? replset._state.secondaries[key].checkoutReader() - : null; - - // If connection is null fallback to first available secondary - if (null == conn) { - conn = pickFirstConnectedSecondary(replset, tags); - } - - return conn; -} - -/** - * @ignore - */ -var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) { - var keys = Object.keys(self._state.secondaries); - var connection; - - // Find first available reader if any - for(var i = 0; i < keys.length; i++) { - connection = self._state.secondaries[keys[i]].checkoutReader(); - if(connection) return connection; - } - - // If we still have a null, read from primary if it's not secondary only - if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) { - connection = self._state.master.checkoutReader(); - if(connection) return connection; - } - - var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED - ? 'secondary' - : self._readPreference; - - return new Error("No replica set member available for query with ReadPreference " - + preferenceName + " and tags " + JSON.stringify(tags)); -} - -/** - * Get list of secondaries - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true - , get: function() { - return utils.objectToArray(this._state.secondaries); - } -}); - -/** - * Get list of secondaries - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true - , get: function() { - return utils.objectToArray(this._state.arbiters); - } -}); - diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set_state.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set_state.js deleted file mode 100644 index 6f9e143277c..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set_state.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Interval state object constructor - * - * @ignore - */ -var ReplSetState = function ReplSetState () { - this.errorMessages = []; - this.secondaries = {}; - this.addresses = {}; - this.arbiters = {}; - this.passives = {}; - this.members = []; - this.errors = {}; - this.setName = null; - this.master = null; -} - -ReplSetState.prototype.hasValidServers = function() { - var validServers = []; - if(this.master && this.master.isConnected()) return true; - - if(this.secondaries) { - var keys = Object.keys(this.secondaries) - for(var i = 0; i < keys.length; i++) { - if(this.secondaries[keys[i]].isConnected()) - return true; - } - } - - return false; -} - -ReplSetState.prototype.getAllReadServers = function() { - var candidate_servers = []; - for(var name in this.addresses) { - candidate_servers.push(this.addresses[name]); - } - - // Return all possible read candidates - return candidate_servers; -} - -ReplSetState.prototype.addServer = function(server, master) { - server.name = master.me; - - if(master.ismaster) { - this.master = server; - this.addresses[server.name] = server; - } else if(master.secondary) { - this.secondaries[server.name] = server; - this.addresses[server.name] = server; - } else if(master.arbiters) { - this.arbiters[server.name] = server; - this.addresses[server.name] = server; - } -} - -ReplSetState.prototype.contains = function(host) { - return this.addresses[host] != null; -} - -ReplSetState.prototype.isPrimary = function(server) { - return this.master && this.master.name == server.name; -} - -ReplSetState.prototype.isSecondary = function(server) { - return this.secondaries[server.name] != null; -} - -exports.ReplSetState = ReplSetState; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/ping_strategy.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/ping_strategy.js deleted file mode 100644 index d1baaae62a9..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/ping_strategy.js +++ /dev/null @@ -1,297 +0,0 @@ -var Server = require("../../server").Server - , format = require('util').format; - -// The ping strategy uses pings each server and records the -// elapsed time for the server so it can pick a server based on lowest -// return time for the db command {ping:true} -var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) { - this.replicaset = replicaset; - this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS; - this.state = 'disconnected'; - this.pingInterval = 5000; - // Class instance - this.Db = require("../../../db").Db; - // Active db connections - this.dbs = {}; - // Logger api - this.Logger = null; -} - -// Starts any needed code -PingStrategy.prototype.start = function(callback) { - // already running? - if ('connected' == this.state) return; - - this.state = 'connected'; - - // Start ping server - this._pingServer(callback); -} - -// Stops and kills any processes running -PingStrategy.prototype.stop = function(callback) { - // Stop the ping process - this.state = 'disconnected'; - - // Stop all the server instances - for(var key in this.dbs) { - this.dbs[key].close(); - } - - // optional callback - callback && callback(null, null); -} - -PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - var self = this; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // Sort by ping time - finalCandidates.sort(function(a, b) { - return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs']; - }); - - if(0 === finalCandidates.length) - return new Error("No replica set members available for query"); - - // find lowest server with a ping time - var lowest = finalCandidates.filter(function (server) { - return undefined != server.runtimeStats.pingMs; - })[0]; - - if(!lowest) { - lowest = finalCandidates[0]; - } - - // convert to integer - var lowestPing = lowest.runtimeStats.pingMs | 0; - - // determine acceptable latency - var acceptable = lowestPing + this.secondaryAcceptableLatencyMS; - - // remove any server responding slower than acceptable - var len = finalCandidates.length; - while(len--) { - if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) { - finalCandidates.splice(len, 1); - } - } - - if(self.logger && self.logger.debug) { - self.logger.debug("Ping strategy selection order for tags", tags); - finalCandidates.forEach(function(c) { - self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null); - }) - } - - // If no candidates available return an error - if(finalCandidates.length == 0) - return new Error("No replica set members available for query"); - - // Pick a random acceptable server - var connection = finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); - if(self.logger && self.logger.debug) { - if(connection) - self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port); - } - - return connection; -} - -PingStrategy.prototype._pingServer = function(callback) { - var self = this; - - // Ping server function - var pingFunction = function() { - // Our state changed to disconnected or destroyed return - if(self.state == 'disconnected' || self.state == 'destroyed') return; - // If the replicaset is destroyed return - if(self.replicaset.isDestroyed() || self.replicaset._serverState == 'disconnected') return - - // Create a list of all servers we can send the ismaster command to - var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : []; - - // Secondary keys - var keys = Object.keys(self.replicaset._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self.replicaset._state.secondaries[keys[i]]); - } - - // Number of server entries - var numberOfEntries = allServers.length; - - // We got keys - for(var i = 0; i < allServers.length; i++) { - - // We got a server instance - var server = allServers[i]; - - // Create a new server object, avoid using internal connections as they might - // be in an illegal state - new function(serverInstance) { - var _db = self.dbs[serverInstance.host + ":" + serverInstance.port]; - // If we have a db - if(_db != null) { - // Startup time of the command - var startTime = Date.now(); - - // Execute ping command in own scope - var _ping = function(__db, __serverInstance) { - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }; - // Ping - _ping(_db, serverInstance); - } else { - var connectTimeoutMS = self.replicaset.options.socketOptions - ? self.replicaset.options.socketOptions.connectTimeoutMS : 0 - - // Create a new master connection - var _server = new Server(serverInstance.host, serverInstance.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: connectTimeoutMS }, - ssl: self.replicaset.ssl, - sslValidate: self.replicaset.sslValidate, - sslCA: self.replicaset.sslCA, - sslCert: self.replicaset.sslCert, - sslKey: self.replicaset.sslKey, - sslPass: self.replicaset.sslPass - }); - - // Create Db instance - var _db = new self.Db('local', _server, { safe: true }); - _db.on("close", function() { - delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port]; - }) - - var _ping = function(__db, __serverInstance) { - if(self.state == 'disconnected') { - self.stop(); - return; - } - - __db.open(function(err, db) { - if(self.state == 'disconnected' && __db != null) { - return __db.close(); - } - - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - // Save instance - self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db; - - // Startup time of the command - var startTime = Date.now(); - - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }); - }; - - _ping(_db, serverInstance); - } - - function done() { - // Adjust the number of checks - numberOfEntries--; - - // If we are done with all results coming back trigger ping again - if(0 === numberOfEntries && 'connected' == self.state) { - setTimeout(pingFunction, self.pingInterval); - } - } - }(server); - } - } - - // Start pingFunction - pingFunction(); - - callback && callback(null); -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/statistics_strategy.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/statistics_strategy.js deleted file mode 100644 index f9b8c46433c..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/statistics_strategy.js +++ /dev/null @@ -1,80 +0,0 @@ -// The Statistics strategy uses the measure of each end-start time for each -// query executed against the db to calculate the mean, variance and standard deviation -// and pick the server which the lowest mean and deviation -var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) { - this.replicaset = replicaset; - // Logger api - this.Logger = null; -} - -// Starts any needed code -StatisticsStrategy.prototype.start = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.stop = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // If no candidates available return an error - if(finalCandidates.length == 0) return new Error("No replica set members available for query"); - // Pick a random server - return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set_servers.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set_servers.js deleted file mode 100644 index 28662821e94..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/repl_set_servers.js +++ /dev/null @@ -1,968 +0,0 @@ -var Connection = require('./connection').Connection, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - debug = require('util').debug, - SimpleEmitter = require('./simple_emitter').SimpleEmitter, - inherits = require('util').inherits, - inspect = require('util').inspect, - Server = require('./server').Server, - format = require('util').format, - PingStrategy = require('./strategies/ping_strategy').PingStrategy, - StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy; - -const STATE_STARTING_PHASE_1 = 0; -const STATE_PRIMARY = 1; -const STATE_SECONDARY = 2; -const STATE_RECOVERING = 3; -const STATE_FATAL_ERROR = 4; -const STATE_STARTING_PHASE_2 = 5; -const STATE_UNKNOWN = 6; -const STATE_ARBITER = 7; -const STATE_DOWN = 8; -const STATE_ROLLBACK = 9; - -/** -* ReplSetServers constructor provides master-slave functionality -* -* @param serverArr{Array of type Server} -* @return constructor of ServerCluster -* -*/ -var ReplSetServers = exports.ReplSetServers = function(servers, options) { - var self = this; - // Contains the master server entry - this.options = options == null ? {} : options; - this.reconnectWait = this.options["reconnectWait"] != null ? this.options["reconnectWait"] : 1000; - this.retries = this.options["retries"] != null ? this.options["retries"] : 30; - this.replicaSet = this.options["rs_name"]; - - // Are we allowing reads from secondaries ? - this.readSecondary = this.options["read_secondary"]; - this.slaveOk = true; - this.closedConnectionCount = 0; - this._used = false; - - // Default poolSize for new server instances - this.poolSize = this.options.poolSize == null ? 1 : this.options.poolSize; - - // Set up ssl connections - this.ssl = this.options.ssl == null ? false : this.options.ssl; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // Read preference - this._readPreference = null; - // Do we record server stats or not - this.recordQueryStats = false; - - // Get the readPreference - var readPreference = this.options['readPreference']; - // Read preference setting - if(readPreference != null) { - if(readPreference != Server.READ_PRIMARY && readPreference != Server.READ_SECONDARY_ONLY - && readPreference != Server.READ_SECONDARY) { - throw new Error("Illegal readPreference mode specified, " + readPreference); - } - - // Set read Preference - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Strategy for picking a secondary - this.strategy = this.options['strategy'] == null ? 'statistical' : this.options['strategy']; - // Make sure strategy is one of the two allowed - if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical')) throw new Error("Only ping or statistical strategies allowed"); - // Let's set up our strategy object for picking secodaries - if(this.strategy == 'ping') { - // Create a new instance - this.strategyInstance = new PingStrategy(this); - } else if(this.strategy == 'statistical') { - // Set strategy as statistical - this.strategyInstance = new StatisticsStrategy(this); - // Add enable query information - this.enableRecordQueryStats(true); - } - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.debug == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Ensure all the instances are of type server and auto_reconnect is false - if(!Array.isArray(servers) || servers.length == 0) { - throw Error("The parameter must be an array of servers and contain at least one server"); - } else if(Array.isArray(servers) || servers.length > 0) { - var count = 0; - servers.forEach(function(server) { - if(server instanceof Server) count = count + 1; - // Ensure no server has reconnect on - server.options.auto_reconnect = false; - }); - - if(count < servers.length) { - throw Error("All server entries must be of type Server"); - } else { - this.servers = servers; - } - } - - // Auto Reconnect property - Object.defineProperty(this, "autoReconnect", { enumerable: true - , get: function () { - return true; - } - }); - - // Get Read Preference method - Object.defineProperty(this, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return Server.READ_SECONDARY; - } else if(this._readPreference == null && !this.readSecondary) { - return Server.READ_PRIMARY; - } else { - return this._readPreference; - } - } - }); - - // Db Instances - Object.defineProperty(this, "dbInstances", {enumerable:true - , get: function() { - var servers = this.allServerInstances(); - return servers[0].dbInstances; - } - }) - - // Auto Reconnect property - Object.defineProperty(this, "host", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.host; - } - }); - - Object.defineProperty(this, "port", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.port; - } - }); - - Object.defineProperty(this, "read", { enumerable: true - , get: function () { - return this.secondaries.length > 0 ? this.secondaries[0] : null; - } - }); - - // Get list of secondaries - Object.defineProperty(this, "secondaries", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.secondaries); - var array = new Array(keys.length); - // Convert secondaries to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.secondaries[keys[i]]; - } - return array; - } - }); - - // Get list of all secondaries including passives - Object.defineProperty(this, "allSecondaries", {enumerable: true - , get: function() { - return this.secondaries.concat(this.passives); - } - }); - - // Get list of arbiters - Object.defineProperty(this, "arbiters", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.arbiters); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.arbiters[keys[i]]; - } - return array; - } - }); - - // Get list of passives - Object.defineProperty(this, "passives", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.passives); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.passives[keys[i]]; - } - return array; - } - }); - - // Master connection property - Object.defineProperty(this, "primary", { enumerable: true - , get: function () { - return this._state != null ? this._state.master : null; - } - }); -}; - -inherits(ReplSetServers, SimpleEmitter); - -// Allow setting the read preference at the replicaset level -ReplSetServers.prototype.setReadPreference = function(preference) { - // Set read preference - this._readPreference = preference; - // Ensure slaveOk is correct for secodnaries read preference and tags - if((this._readPreference == Server.READ_SECONDARY || this._readPreference == Server.READ_SECONDARY_ONLY) - || (this._readPreference != null && typeof this._readPreference == 'object')) { - this.slaveOk = true; - } -} - -// Return the used state -ReplSetServers.prototype._isUsed = function() { - return this._used; -} - -ReplSetServers.prototype.setTarget = function(target) { - this.target = target; -}; - -ReplSetServers.prototype.isConnected = function() { - // Return the state of the replicaset server - return this.primary != null && this._state.master != null && this._state.master.isConnected(); -} - -Server.prototype.isSetMember = function() { - return false; -} - -ReplSetServers.prototype.isPrimary = function(config) { - return this.readSecondary && this.secondaries.length > 0 ? false : true; -} - -ReplSetServers.prototype.isReadPrimary = ReplSetServers.prototype.isPrimary; - -// Clean up dead connections -var cleanupConnections = ReplSetServers.cleanupConnections = function(connections, addresses, byTags) { - // Ensure we don't have entries in our set with dead connections - var keys = Object.keys(connections); - for(var i = 0; i < keys.length; i++) { - var server = connections[keys[i]]; - // If it's not connected remove it from the list - if(!server.isConnected()) { - // Remove from connections and addresses - delete connections[keys[i]]; - delete addresses[keys[i]]; - // Clean up tags if needed - if(server.tags != null && typeof server.tags === 'object') { - cleanupTags(server, byTags); - } - } - } -} - -var cleanupTags = ReplSetServers._cleanupTags = function(server, byTags) { - var serverTagKeys = Object.keys(server.tags); - // Iterate over all server tags and remove any instances for that tag that matches the current - // server - for(var i = 0; i < serverTagKeys.length; i++) { - // Fetch the value for the tag key - var value = server.tags[serverTagKeys[i]]; - - // If we got an instance of the server - if(byTags[serverTagKeys[i]] != null - && byTags[serverTagKeys[i]][value] != null - && Array.isArray(byTags[serverTagKeys[i]][value])) { - // List of clean servers - var cleanInstances = []; - // We got instances for the particular tag set - var instances = byTags[serverTagKeys[i]][value]; - for(var j = 0; j < instances.length; j++) { - var serverInstance = instances[j]; - // If we did not find an instance add it to the clean instances - if((serverInstance.host + ":" + serverInstance.port) !== (server.host + ":" + server.port)) { - cleanInstances.push(serverInstance); - } - } - - // Update the byTags list - byTags[serverTagKeys[i]][value] = cleanInstances; - } - } -} - -ReplSetServers.prototype.allServerInstances = function() { - var self = this; - // Close all the servers (concatenate entire list of servers first for ease) - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // Arbiter keys - var keys = Object.keys(self._state.arbiters); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.arbiters[keys[i]]); - } - - // Passive keys - var keys = Object.keys(self._state.passives); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.passives[keys[i]]); - } - - // Return complete list of all servers - return allServers; -} - -// Ensure no callback is left hanging when we have an error -var __executeAllCallbacksWithError = function(dbInstance, error) { - var keys = Object.keys(dbInstance._callBackStore._notReplied); - // Iterate over all callbacks - for(var i = 0; i < keys.length; i++) { - // Delete info object - delete dbInstance._callBackStore._notReplied[keys[i]]; - // Emit the error - dbInstance._callBackStore.emit(keys[i], error); - } -} - -ReplSetServers.prototype.connect = function(parent, options, callback) { - var self = this; - var dateStamp = new Date().getTime(); - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Keep reference to parent - this.db = parent; - // Set server state to connecting - this._serverState = 'connecting'; - // Reference to the instance - var replSetSelf = this; - var serverConnections = this.servers; - // Ensure parent can do a slave query if it's set - parent.slaveOk = this.slaveOk ? this.slaveOk : parent.slaveOk; - // Number of total servers that need to initialized (known servers) - var numberOfServersLeftToInitialize = serverConnections.length; - - // Clean up state - replSetSelf._state = {'master':null, 'secondaries':{}, 'arbiters':{}, 'passives':{}, 'errors':{}, 'addresses':{}, 'byTags':{}, 'setName':null, 'errorMessages':[], 'members':[]}; - - // Create a connection handler - var connectionHandler = function(instanceServer) { - return function(err, result) { - // Don't attempt to connect if we are done - // if(replSetSelf._serverState === 'disconnected') return; - // Remove a server from the list of intialized servers we need to perform - numberOfServersLeftToInitialize = numberOfServersLeftToInitialize - 1; - // Add enable query information - instanceServer.enableRecordQueryStats(replSetSelf.recordQueryStats); - - if(err == null && result.documents[0].hosts != null) { - // Fetch the isMaster command result - var document = result.documents[0]; - // Break out the results - var setName = document.setName; - var isMaster = document.ismaster; - var secondary = document.secondary; - var passive = document.passive; - var arbiterOnly = document.arbiterOnly; - var hosts = Array.isArray(document.hosts) ? document.hosts : []; - var arbiters = Array.isArray(document.arbiters) ? document.arbiters : []; - var passives = Array.isArray(document.passives) ? document.passives : []; - var tags = document.tags ? document.tags : {}; - var primary = document.primary; - var me = document.me; - - // Only add server to our internal list if it's a master, secondary or arbiter - if(isMaster == true || secondary == true || arbiterOnly == true) { - // Handle a closed connection - var closeHandler = function(err, server) { - var closeServers = function() { - // Set the state to disconnected - parent._state = 'disconnected'; - // Shut down the replicaset for now and Fire off all the callbacks sitting with no reply - if(replSetSelf._serverState == 'connected') { - // Close the replicaset - replSetSelf.close(function() { - __executeAllCallbacksWithError(parent, err); - // Ensure single callback only - if(callback != null) { - // Single callback only - var internalCallback = callback; - callback = null; - // Return the error - internalCallback(err, null); - } else { - // If the parent has listeners trigger an event - if(parent.listeners("close").length > 0) { - parent.emit("close", err); - } - } - }); - } - } - - // Check if this is the primary server, then disconnect otherwise keep going - if(replSetSelf._state.master != null) { - var primaryAddress = format("%s:%s", replSetSelf._state.master.host, replSetSelf._state.master.port); - var errorServerAddress = format("%s:%s", server.host, server.port); - - // Only shut down the set if we have a primary server error - if(primaryAddress == errorServerAddress) { - closeServers(); - } else { - // Remove from the list of servers - delete replSetSelf._state.addresses[errorServerAddress]; - // Locate one of the lists and remove - if(replSetSelf._state.secondaries[errorServerAddress] != null) { - delete replSetSelf._state.secondaries[errorServerAddress]; - } else if(replSetSelf._state.arbiters[errorServerAddress] != null) { - delete replSetSelf._state.arbiters[errorServerAddress]; - } else if(replSetSelf._state.passives[errorServerAddress] != null) { - delete replSetSelf._state.passives[errorServerAddress]; - } - - // Check if we are reading from Secondary only - if(replSetSelf._readPreference == Server.READ_SECONDARY_ONLY && Object.keys(replSetSelf._state.secondaries).length == 0) { - closeServers(); - } - } - } else { - closeServers(); - } - } - - // Handle a connection timeout - var timeoutHandler = function(err, server) { - var closeServers = function() { - // Set the state to disconnected - parent._state = 'disconnected'; - // Shut down the replicaset for now and Fire off all the callbacks sitting with no reply - if(replSetSelf._serverState == 'connected') { - // Close the replicaset - replSetSelf.close(function() { - __executeAllCallbacksWithError(parent, err); - // Ensure single callback only - if(callback != null) { - // Single callback only - var internalCallback = callback; - callback = null; - // Return the error - internalCallback(new Error("connection timed out"), null); - } else { - // If the parent has listeners trigger an event - if(parent.listeners("error").length > 0) { - parent.emit("timeout", new Error("connection timed out")); - } - } - }); - } - } - - // Check if this is the primary server, then disconnect otherwise keep going - if(replSetSelf._state.master != null) { - var primaryAddress = format("%s:%s", replSetSelf._state.master.host, replSetSelf._state.master.port); - var errorServerAddress = format("%s:%s", server.host, server.port); - - // Only shut down the set if we have a primary server error - if(primaryAddress == errorServerAddress) { - closeServers(); - } else { - // Remove from the list of servers - delete replSetSelf._state.addresses[errorServerAddress]; - // Locate one of the lists and remove - if(replSetSelf._state.secondaries[errorServerAddress] != null) { - delete replSetSelf._state.secondaries[errorServerAddress]; - } else if(replSetSelf._state.arbiters[errorServerAddress] != null) { - delete replSetSelf._state.arbiters[errorServerAddress]; - } else if(replSetSelf._state.passives[errorServerAddress] != null) { - delete replSetSelf._state.passives[errorServerAddress]; - } - - // Check if we are reading from Secondary only - if(replSetSelf._readPreference == Server.READ_SECONDARY_ONLY && Object.keys(replSetSelf._state.secondaries).length == 0) { - closeServers(); - } - } - } else { - closeServers(); - } - } - - // Handle an error - var errorHandler = function(err, server) { - var closeServers = function() { - // Set the state to disconnected - parent._state = 'disconnected'; - // Shut down the replicaset for now and Fire off all the callbacks sitting with no reply - if(replSetSelf._serverState == 'connected') { - // Close the replicaset - replSetSelf.close(function() { - __executeAllCallbacksWithError(parent, err); - // Ensure single callback only - if(callback != null) { - // Single callback only - var internalCallback = callback; - callback = null; - // Return the error - internalCallback(err, null); - } else { - // If the parent has listeners trigger an event - if(parent.listeners("error").length > 0) { - parent.emit("error", err); - } - } - }); - } - } - - // Check if this is the primary server, then disconnect otherwise keep going - if(replSetSelf._state.master != null) { - var primaryAddress = format("%s:%s", replSetSelf._state.master.host, replSetSelf._state.master.port); - var errorServerAddress = format("%s:%s", server.host, server.port); - - // Only shut down the set if we have a primary server error - if(primaryAddress == errorServerAddress) { - closeServers(); - } else { - // Remove from the list of servers - delete replSetSelf._state.addresses[errorServerAddress]; - // Locate one of the lists and remove - if(replSetSelf._state.secondaries[errorServerAddress] != null) { - delete replSetSelf._state.secondaries[errorServerAddress]; - } else if(replSetSelf._state.arbiters[errorServerAddress] != null) { - delete replSetSelf._state.arbiters[errorServerAddress]; - } else if(replSetSelf._state.passives[errorServerAddress] != null) { - delete replSetSelf._state.passives[errorServerAddress]; - } - - // Check if we are reading from Secondary only - if(replSetSelf._readPreference == Server.READ_SECONDARY_ONLY && Object.keys(replSetSelf._state.secondaries).length == 0) { - closeServers(); - } - } - } else { - closeServers(); - } - } - - // Ensure we don't have duplicate handlers - instanceServer.removeAllListeners("close"); - instanceServer.removeAllListeners("error"); - instanceServer.removeAllListeners("timeout"); - - // Add error handler to the instance of the server - instanceServer.on("close", closeHandler); - // Add error handler to the instance of the server - instanceServer.on("error", errorHandler); - // instanceServer.on("timeout", errorHandler); - instanceServer.on("timeout", timeoutHandler); - // Add tag info - instanceServer.tags = tags; - - // For each tag in tags let's add the instance Server to the list for that tag - if(tags != null && typeof tags === 'object') { - var tagKeys = Object.keys(tags); - // For each tag file in the server add it to byTags - for(var i = 0; i < tagKeys.length; i++) { - var value = tags[tagKeys[i]]; - // Check if we have a top level tag object - if(replSetSelf._state.byTags[tagKeys[i]] == null) replSetSelf._state.byTags[tagKeys[i]] = {}; - // For the value check if we have an array of server instances - if(!Array.isArray(replSetSelf._state.byTags[tagKeys[i]][value])) replSetSelf._state.byTags[tagKeys[i]][value] = []; - // Check that the instance is not already registered there - var valueArray = replSetSelf._state.byTags[tagKeys[i]][value]; - var found = false; - - // Iterate over all values - for(var j = 0; j < valueArray.length; j++) { - if(valueArray[j].host == instanceServer.host && valueArray[j].port == instanceServer.port) { - found = true; - break; - } - } - - // If it was not found push the instance server to the list - if(!found) valueArray.push(instanceServer); - } - } - - // Remove from error list - delete replSetSelf._state.errors[me]; - - // Add our server to the list of finished servers - replSetSelf._state.addresses[me] = instanceServer; - - // Assign the set name - if(replSetSelf.replicaSet == null) { - replSetSelf._state.setName = setName; - } else if(replSetSelf.replicaSet != setName && replSetSelf._serverState != 'disconnected') { - replSetSelf._state.errorMessages.push(new Error("configured mongodb replicaset does not match provided replicaset [" + setName + "] != [" + replSetSelf.replicaSet + "]")); - // Set done - replSetSelf._serverState = 'disconnected'; - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Return error message ignoring rest of calls - return internalCallback(replSetSelf._state.errorMessages[0], parent); - } - - // Let's add the server to our list of server types - if(secondary == true && (passive == false || passive == null)) { - replSetSelf._state.secondaries[me] = instanceServer; - } else if(arbiterOnly == true) { - replSetSelf._state.arbiters[me] = instanceServer; - } else if(secondary == true && passive == true) { - replSetSelf._state.passives[me] = instanceServer; - } else if(isMaster == true) { - replSetSelf._state.master = instanceServer; - } else if(isMaster == false && primary != null && replSetSelf._state.addresses[primary]) { - replSetSelf._state.master = replSetSelf._state.addresses[primary]; - } - - // Let's go throught all the "possible" servers in the replicaset - var candidateServers = hosts.concat(arbiters).concat(passives); - - // If we have new servers let's add them - for(var i = 0; i < candidateServers.length; i++) { - // Fetch the server string - var candidateServerString = candidateServers[i]; - // Add the server if it's not defined - if(replSetSelf._state.addresses[candidateServerString] == null) { - // Split the server string - var parts = candidateServerString.split(/:/); - if(parts.length == 1) { - parts = [parts[0], Connection.DEFAULT_PORT]; - } - - // Default empty socket options object - var socketOptions = {}; - // If a socket option object exists clone it - if(replSetSelf.socketOptions != null) { - var keys = Object.keys(replSetSelf.socketOptions); - for(var i = 0; i < keys.length;i++) socketOptions[keys[i]] = replSetSelf.socketOptions[keys[i]]; - } - - // Add host information to socket options - socketOptions['host'] = parts[0]; - socketOptions['port'] = parseInt(parts[1]); - - // Create a new server instance - var newServer = new Server(parts[0], parseInt(parts[1]), {auto_reconnect:false, 'socketOptions':socketOptions - , logger:replSetSelf.logger, ssl:replSetSelf.ssl, poolSize:replSetSelf.poolSize}); - // Set the replicaset instance - newServer.replicasetInstance = replSetSelf; - - // Add handlers - newServer.on("close", closeHandler); - newServer.on("timeout", timeoutHandler); - newServer.on("error", errorHandler); - - // Add server to list, ensuring we don't get a cascade of request to the same server - replSetSelf._state.addresses[candidateServerString] = newServer; - - // Add a new server to the total number of servers that need to initialized before we are done - numberOfServersLeftToInitialize = numberOfServersLeftToInitialize + 1; - - // Let's set up a new server instance - newServer.connect(parent, {returnIsMasterResults: true, eventReceiver:newServer}, connectionHandler(newServer)); - } - } - } else { - // Remove the instance from out list of servers - delete replSetSelf._state.addresses[me]; - } - } - - // If done finish up - if((numberOfServersLeftToInitialize == 0) && replSetSelf._serverState === 'connecting' && replSetSelf._state.errorMessages.length == 0) { - // Set db as connected - replSetSelf._serverState = 'connected'; - // If we don't expect a master let's call back, otherwise we need a master before - // the connection is successful - if(replSetSelf.masterNotNeeded || replSetSelf._state.master != null) { - // If we have a read strategy boot it - if(replSetSelf.strategyInstance != null) { - // Ensure we have a proper replicaset defined - replSetSelf.strategyInstance.replicaset = replSetSelf; - // Start strategy - replSetSelf.strategyInstance.start(function(err) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(null, parent); - }) - } else { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(null, parent); - } - } else if(replSetSelf.readSecondary == true && Object.keys(replSetSelf._state.secondaries).length > 0) { - // If we have a read strategy boot it - if(replSetSelf.strategyInstance != null) { - // Ensure we have a proper replicaset defined - replSetSelf.strategyInstance.replicaset = replSetSelf; - // Start strategy - replSetSelf.strategyInstance.start(function(err) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(null, parent); - }) - } else { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(null, parent); - } - } else if(replSetSelf.readSecondary == true && Object.keys(replSetSelf._state.secondaries).length == 0) { - replSetSelf._serverState = 'disconnected'; - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Force close all server instances - replSetSelf.close(); - // Perform callback - internalCallback(new Error("no secondary server found"), null); - } else if(typeof callback === 'function'){ - replSetSelf._serverState = 'disconnected'; - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Force close all server instances - replSetSelf.close(); - // Perform callback - internalCallback(new Error("no primary server found"), null); - } - } else if((numberOfServersLeftToInitialize == 0) && replSetSelf._state.errorMessages.length > 0 && replSetSelf._serverState != 'disconnected') { - // Set done - replSetSelf._serverState = 'disconnected'; - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Force close all server instances - replSetSelf.close(); - // Callback to signal we are done - internalCallback(replSetSelf._state.errorMessages[0], null); - } - } - } - - // Ensure we have all registered servers in our set - for(var i = 0; i < serverConnections.length; i++) { - replSetSelf._state.addresses[serverConnections[i].host + ':' + serverConnections[i].port] = serverConnections[i]; - } - - // Initialize all the connections - for(var i = 0; i < serverConnections.length; i++) { - // Set up the logger for the server connection - serverConnections[i].logger = replSetSelf.logger; - // Default empty socket options object - var socketOptions = {}; - // If a socket option object exists clone it - if(this.socketOptions != null && typeof this.socketOptions === 'object') { - var keys = Object.keys(this.socketOptions); - for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = this.socketOptions[keys[j]]; - } - - // If ssl is specified - if(replSetSelf.ssl) serverConnections[i].ssl = true; - - // Add host information to socket options - socketOptions['host'] = serverConnections[i].host; - socketOptions['port'] = serverConnections[i].port; - - // Set the socket options - serverConnections[i].socketOptions = socketOptions; - // Set the replicaset instance - serverConnections[i].replicasetInstance = replSetSelf; - // Connect to server - serverConnections[i].connect(parent, {returnIsMasterResults: true, eventReceiver:serverConnections[i]}, connectionHandler(serverConnections[i])); - } - - // Check if we have an error in the inital set of servers and callback with error - if(replSetSelf._state.errorMessages.length > 0 && typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(replSetSelf._state.errorMessages[0], null); - } -} - -ReplSetServers.prototype.checkoutWriter = function() { - // Establish connection - var connection = this._state.master != null ? this._state.master.checkoutWriter() : null; - // Return the connection - return connection; -} - -ReplSetServers.prototype.checkoutReader = function() { - var connection = null; - // If we have specified to read from a secondary server grab a random one and read - // from it, otherwise just pass the primary connection - if((this.readSecondary == true || this._readPreference == Server.READ_SECONDARY || this._readPreference == Server.READ_SECONDARY_ONLY) && Object.keys(this._state.secondaries).length > 0) { - // Checkout a secondary server from the passed in set of servers - if(this.strategyInstance != null) { - connection = this.strategyInstance.checkoutSecondary(); - } else { - // Pick a random key - var keys = Object.keys(this._state.secondaries); - var key = keys[Math.floor(Math.random() * keys.length)]; - connection = this._state.secondaries[key].checkoutReader(); - } - } else if(this._readPreference == Server.READ_SECONDARY_ONLY && Object.keys(this._state.secondaries).length == 0) { - connection = null; - } else if(this._readPreference != null && typeof this._readPreference === 'object') { - // Get all tag keys (used to try to find a server that is valid) - var keys = Object.keys(this._readPreference); - // final instance server - var instanceServer = null; - // for each key look for an avilable instance - for(var i = 0; i < keys.length; i++) { - // Grab subkey value - var value = this._readPreference[keys[i]]; - - // Check if we have any servers for the tag, if we do pick a random one - if(this._state.byTags[keys[i]] != null - && this._state.byTags[keys[i]][value] != null - && Array.isArray(this._state.byTags[keys[i]][value]) - && this._state.byTags[keys[i]][value].length > 0) { - // Let's grab an available server from the list using a random pick - var serverInstances = this._state.byTags[keys[i]][value]; - // Set instance to return - instanceServer = serverInstances[Math.floor(Math.random() * serverInstances.length)]; - break; - } - } - - // Return the instance of the server - connection = instanceServer != null ? instanceServer.checkoutReader() : this.checkoutWriter(); - } else { - connection = this.checkoutWriter(); - } - // Return the connection - return connection; -} - -ReplSetServers.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - // Get connection object - var allMasterConnections = this._state.master.connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(allMasterConnections); - - // If we have read secondary let's add all secondary servers - if(this.readSecondary && Object.keys(this._state.secondaries).length > 0) { - // Get all the keys - var keys = Object.keys(this._state.secondaries); - // For each of the secondaries grab the connections - for(var i = 0; i < keys.length; i++) { - // Get connection object - var secondaryPoolConnections = this._state.secondaries[keys[i]].connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(secondaryPoolConnections); - } - } - - // Return all the conections - return allConnections; -} - -ReplSetServers.prototype.enableRecordQueryStats = function(enable) { - // Set the global enable record query stats - this.recordQueryStats = enable; - // Ensure all existing servers already have the flag set, even if the - // connections are up already or we have not connected yet - if(this._state != null && this._state.addresses != null) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances and set the enableRecordQueryStats flag - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].enableRecordQueryStats(enable); - } - } else if(Array.isArray(this.servers)) { - for(var i = 0; i < this.servers.length; i++) { - this.servers[i].enableRecordQueryStats(enable); - } - } -} - -ReplSetServers.prototype.disconnect = function(callback) { - this.close(callback); -} - -ReplSetServers.prototype.close = function(callback) { - var self = this; - // Set server status as disconnected - this._serverState = 'disconnected'; - // Get all the server instances and close them - var allServers = []; - // Make sure we have servers - if(this._state['addresses'] != null) { - var keys = Object.keys(this._state.addresses); - for(var i = 0; i < keys.length; i++) { - allServers.push(this._state.addresses[keys[i]]); - } - } - - // Let's process all the closing - var numberOfServersToClose = allServers.length; - - // Remove all the listeners - self.removeAllListeners(); - - // Special case where there are no servers - if(allServers.length == 0 && typeof callback === 'function') return callback(null, null); - - // Close the servers - for(var i = 0; i < allServers.length; i++) { - var server = allServers[i]; - if(server.isConnected()) { - // Close each server - server.close(function() { - numberOfServersToClose = numberOfServersToClose - 1; - // Clear out state if we are done - if(numberOfServersToClose == 0) { - // Clear out state - self._state = {'master':null, 'secondaries':{}, 'arbiters':{}, 'passives':{}, 'errors':{}, 'addresses':{}, 'byTags':{}, 'setName':null, 'errorMessages':[], 'members':[]}; - } - - // If we are finished perform the call back - if(numberOfServersToClose == 0 && typeof callback === 'function') { - callback(null); - } - }) - } else { - numberOfServersToClose = numberOfServersToClose - 1; - // If we have no more servers perform the callback - if(numberOfServersToClose == 0 && typeof callback === 'function') { - callback(null); - } - } - } -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/server.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/server.js deleted file mode 100644 index 546bf23ea70..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/server.js +++ /dev/null @@ -1,985 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - ConnectionPool = require('./connection_pool').ConnectionPool, - EventEmitter = require('events').EventEmitter, - Base = require('./base').Base, - utils = require('../utils'), - timers = require('timers'), - inherits = require('util').inherits; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Class representing a single MongoDB Server connection - * - * Options - * - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST) - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **auto_reconnect** {Boolean, default:false}, reconnect on error. - * - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big - * - * @class Represents a Server connection. - * @param {String} host the server host - * @param {Number} port the server port - * @param {Object} [options] optional options for insert command - */ -function Server(host, port, options) { - // Set up Server instance - if(!(this instanceof Server)) return new Server(host, port, options); - - // Set up event emitter - Base.call(this); - - // Ensure correct values - if(port != null && typeof port == 'object') { - options = port; - port = Connection.DEFAULT_PORT; - } - - var self = this; - this.host = host; - this.port = port; - this.options = options == null ? {} : options; - this.internalConnection; - this.internalMaster = false; - this.connected = false; - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false; - this._used = false; - this.replicasetInstance = null; - - // Emit open setup - this.emitOpen = this.options.emitOpen || true; - // Set ssl as connection method - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Get the readPreference - var readPreference = this.options['readPreference']; - // If readPreference is an object get the mode string - var validateReadPreference = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - // Read preference setting - if(validateReadPreference != null) { - if(validateReadPreference != ReadPreference.PRIMARY && validateReadPreference != ReadPreference.SECONDARY && validateReadPreference != ReadPreference.NEAREST - && validateReadPreference != ReadPreference.SECONDARY_PREFERRED && validateReadPreference != ReadPreference.PRIMARY_PREFERRED) { - throw new Error("Illegal readPreference mode specified, " + validateReadPreference); - } - - // Set read Preference - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Contains the isMaster information returned from the server - this.isMasterDoc; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck; - - // Set ssl up if it's defined - if(this.ssl) { - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // Contains state information about server connection - this._state = {'runtimeStats': {'queryStats':new RunningStats()}}; - // Do we record server stats or not - this.recordQueryStats = false; -}; - -/** - * @ignore - */ -inherits(Server, Base); - -// -// Deprecated, USE ReadPreferences class -// -Server.READ_PRIMARY = ReadPreference.PRIMARY; -Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED; -Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY; - -/** - * Always ourselves - * @ignore - */ -Server.prototype.setReadPreference = function(readPreference) { - this._readPreference = readPreference; -} - -/** - * @ignore - */ -Server.prototype.isMongos = function() { - return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false; -} - -/** - * @ignore - */ -Server.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -Server.prototype.close = function(callback) { - // Set server status as disconnected - this._serverState = 'destroyed'; - // Remove all local listeners - this.removeAllListeners(); - - if(this.connectionPool != null) { - // Remove all the listeners on the pool so it does not fire messages all over the place - this.connectionPool.removeAllEventListeners(); - // Close the connection if it's open - this.connectionPool.stop(true); - } - - // Emit close event - if(this.db && !this.isSetMember()) { - var self = this; - processor(function() { - self._emitAcrossAllDbInstances(self, null, "close", null, null, true) - }) - } - - // Peform callback if present - if(typeof callback === 'function') callback(null); -}; - -Server.prototype.isDestroyed = function() { - return this._serverState == 'destroyed'; -} - -/** - * @ignore - */ -Server.prototype.isConnected = function() { - return this.connectionPool.isConnected(); -} - -/** - * @ignore - */ -Server.prototype.canWrite = Server.prototype.isConnected; -Server.prototype.canRead = Server.prototype.isConnected; - -Server.prototype.isAutoReconnect = function() { - if(this.isSetMember()) return false; - return this.options.auto_reconnect != null ? this.options.auto_reconnect : true; -} - -/** - * @ignore - */ -Server.prototype.allServerInstances = function() { - return [this]; -} - -/** - * @ignore - */ -Server.prototype.isSetMember = function() { - return this.replicasetInstance != null || this.mongosInstance != null; -} - -/** - * Assigns a replica set to this `server`. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.assignReplicaSet = function (replset) { - this.replicasetInstance = replset; - this.inheritReplSetOptionsFrom(replset); - this.enableRecordQueryStats(replset.recordQueryStats); -} - -/** - * Takes needed options from `replset` and overwrites - * our own options. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.inheritReplSetOptionsFrom = function (replset) { - this.socketOptions = {}; - this.socketOptions.connectTimeoutMS = replset.options.socketOptions.connectTimeoutMS || 30000; - - if(replset.options.ssl) { - // Set ssl on - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = replset.options.sslValidate == null ? false : replset.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(replset.options.sslCA) ? replset.options.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = replset.options.sslCert; - // Set certificate to present - this.socketOptions.sslKey = replset.options.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = replset.options.sslPass; - } - - // If a socket option object exists clone it - if(utils.isObject(replset.options.socketOptions)) { - var keys = Object.keys(replset.options.socketOptions); - for(var i = 0; i < keys.length; i++) - this.socketOptions[keys[i]] = replset.options.socketOptions[keys[i]]; - } -} - -/** - * Opens this server connection. - * - * @ignore - */ -Server.prototype.connect = function(dbInstance, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - // Save the options - this.options = options; - - // Currently needed to work around problems with multiple connections in a pool with ssl - // TODO fix if possible - if(this.ssl == true) { - // Set up socket options for ssl - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Let's connect - var server = this; - // Let's us override the main receiver of events - var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this; - // Save reference to dbInstance - this.db = dbInstance; // `db` property matches ReplSet and Mongos - this.dbInstances = [dbInstance]; - - // Force connection pool if there is one - if(server.connectionPool) server.connectionPool.stop(); - // Set server state to connecting - this._serverState = 'connecting'; - - if(server.connectionPool != null) { - // Remove all the listeners on the pool so it does not fire messages all over the place - this.connectionPool.removeAllEventListeners(); - // Close the connection if it's open - this.connectionPool.stop(true); - } - - this.connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions); - var connectionPool = this.connectionPool; - // If ssl is not enabled don't wait between the pool connections - if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null; - // Set logger on pool - connectionPool.logger = this.logger; - connectionPool.bson = dbInstance.bson; - - // Set basic parameters passed in - var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults; - - // Create a default connect handler, overriden when using replicasets - var connectCallback = function(_server) { - return function(err, reply) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Assign the server - _server = _server != null ? _server : server; - - // If something close down the connection and removed the callback before - // proxy killed connection etc, ignore the erorr as close event was isssued - if(err != null && internalCallback == null) return; - // Internal callback - if(err != null) return internalCallback(err, null, _server); - _server.master = reply.documents[0].ismaster == 1 ? true : false; - _server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize); - _server.connectionPool.setMaxMessageSizeBytes(reply.documents[0].maxMessageSizeBytes); - // Set server state to connEcted - _server._serverState = 'connected'; - // Set server as connected - _server.connected = true; - // Save document returned so we can query it - _server.isMasterDoc = reply.documents[0]; - - if(self.emitOpen) - _server._emitAcrossAllDbInstances(_server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null); - - // If we have it set to returnIsMasterResults - if(returnIsMasterResults) { - internalCallback(null, reply, _server); - } else { - internalCallback(null, dbInstance, _server); - } - } - }; - - // Let's us override the main connect callback - var connectHandler = options.connectHandler == null ? connectCallback(server) : options.connectHandler; - - // Set up on connect method - connectionPool.on("poolReady", function() { - // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks) - var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName); - // Check out a reader from the pool - var connection = connectionPool.checkoutConnection(); - // Register handler for messages - server._registerHandler(db_command, false, connection, connectHandler); - // Write the command out - connection.write(db_command); - }) - - // Set up item connection - connectionPool.on("message", function(message) { - // Attempt to parse the message - try { - // Create a new mongo reply - var mongoReply = new MongoReply() - // Parse the header - mongoReply.parseHeader(message, connectionPool.bson) - - // If message size is not the same as the buffer size - // something went terribly wrong somewhere - if(mongoReply.messageLength != message.length) { - // Emit the error - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server); - // Remove all listeners - server.removeAllListeners(); - } else { - var startDate = new Date().getTime(); - - // Callback instance - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - - // The command executed another request, log the handler again under that request id - if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0" - && callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) { - server._reRegisterHandler(mongoReply.requestId, callbackInfo); - } - - // Only execute callback if we have a caller - // chained is for findAndModify as it does not respect write concerns - if(callbackInfo && callbackInfo.callback && callbackInfo.info && Array.isArray(callbackInfo.info.chained)) { - // Check if callback has already been fired (missing chain command) - var chained = callbackInfo.info.chained; - var numberOfFoundCallbacks = 0; - for(var i = 0; i < chained.length; i++) { - if(server._hasHandler(chained[i])) numberOfFoundCallbacks++; - } - - // If we have already fired then clean up rest of chain and move on - if(numberOfFoundCallbacks != chained.length) { - for(var i = 0; i < chained.length; i++) { - server._removeHandler(chained[i]); - } - - // Just return from function - return; - } - - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Fetch the callback - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - // If we have an error let's execute the callback and clean up all other - // chained commands - var firstResult = mongoReply && mongoReply.documents; - - // Check for an error, if we have one let's trigger the callback and clean up - // The chained callbacks - if(firstResult[0].err != null || firstResult[0].errmsg != null) { - // Cleanup the remaining callback - if(Array.isArray(callbackInfo.info.chained)) { - for(var i = 0; i < callbackInfo.info.chained.length; i++) { - if(callbackInfo.info.chained[i] != mongoReply.responseTo) - server._removeHandler(callbackInfo.info.chained[i]); - } - } - // Trigger the callback for the error - server._callHandler(mongoReply.responseTo, mongoReply, null); - } else { - var chainedIds = callbackInfo.info.chained; - - if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) { - // Cleanup all other chained calls - chainedIds.pop(); - // Remove listeners - for(var i = 0; i < chainedIds.length; i++) server._removeHandler(chainedIds[i]); - // Call the handler - server._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null); - } else{ - // Add the results to all the results - for(var i = 0; i < chainedIds.length; i++) { - var handler = server._findHandler(chainedIds[i]); - // Check if we have an object, if it's the case take the current object commands and - // and add this one - if(handler.info != null) { - handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : []; - handler.info.results.push(mongoReply); - } - } - } - } - }); - } else if(callbackInfo && callbackInfo.callback && callbackInfo.info) { - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Let's record the stats info if it's enabled - if(server.recordQueryStats == true && server._state['runtimeStats'] != null - && server._state.runtimeStats['queryStats'] instanceof RunningStats) { - // Add data point to the running statistics object - server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start); - } - - server._callHandler(mongoReply.responseTo, mongoReply, null); - }); - } - } - } catch (err) { - // Throw error in next tick - processor(function() { - throw err; - }) - } - }); - - // Handle timeout - connectionPool.on("timeout", function(err) { - // If pool connection is already closed - if(server._serverState === 'disconnected' - || server._serverState === 'destroyed') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(err, null, server); - } else if(server.isSetMember()) { - if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server); - } else { - if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(err); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true); - } - }); - - // Handle errors - connectionPool.on("error", function(message, connection, error_options) { - // If pool connection is already closed - if(server._serverState === 'disconnected' - || server._serverState === 'destroyed') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Error message - var error_message = new Error(message && message.err ? message.err : message); - // Error message coming from ssl - if(error_options && error_options.ssl) error_message.ssl = true; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(error_message, null, server); - } else if(server.isSetMember()) { - if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server); - } else { - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(error_message); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true); - } - - // If we have autoConnect enabled let's fire up an attempt to reconnect - if(server.isAutoReconnect() - && !server.isSetMember() - && (server._serverState != 'destroyed') - && !server._reconnectInProgreess) { - - // Set the number of retries - server._reconnect_retries = server.db.numberOfRetries; - // Attempt reconnect - server._reconnectInProgreess = true; - setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds); - } - }); - - // Handle close events - connectionPool.on("close", function() { - // If pool connection is already closed - if(server._serverState === 'disconnected' - || server._serverState === 'destroyed') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback == 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server); - } else { - if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed")); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true); - } - - // If we have autoConnect enabled let's fire up an attempt to reconnect - if(server.isAutoReconnect() - && !server.isSetMember() - && (server._serverState != 'destroyed') - && !server._reconnectInProgreess) { - - // Set the number of retries - server._reconnect_retries = server.db.numberOfRetries; - // Attempt reconnect - server._reconnectInProgreess = true; - setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds); - } - }); - - /** - * @ignore - */ - var __attemptReconnect = function(server) { - return function() { - // Attempt reconnect - server.connect(server.db, server.options, function(err, result) { - server._reconnect_retries = server._reconnect_retries - 1; - - if(err) { - // Retry - if(server._reconnect_retries == 0 || server._serverState == 'destroyed') { - server._serverState = 'connected'; - server._reconnectInProgreess = false - // Fire all callback errors - return server.__executeAllCallbacksWithError(new Error("failed to reconnect to server")); - } else { - return setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds); - } - } else { - // Set as authenticating (isConnected will be false) - server._serverState = 'authenticating'; - // Apply any auths, we don't try to catch any errors here - // as there are nowhere to simply propagate them to - self._apply_auths(server.db, function(err, result) { - server._serverState = 'connected'; - server._reconnectInProgreess = false; - server._commandsStore.execute_queries(); - server._commandsStore.execute_writes(); - }); - } - }); - } - } - - // If we have a parser error we are in an unknown state, close everything and emit - // error - connectionPool.on("parseError", function(message) { - // If pool connection is already closed - if(server._serverState === 'disconnected' - || server._serverState === 'destroyed') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - server._emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - }); - - // Boot up connection poole, pass in a locator of callbacks - connectionPool.start(); -} - -/** - * @ignore - */ -Server.prototype.allRawConnections = function() { - return this.connectionPool.getAllConnections(); -} - -/** - * Check if a writer can be provided - * @ignore - */ -var canCheckoutWriter = function(self, read) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } if(self.isMasterDoc['secondary'] == true) { - return new Error("Cannot write to a secondary"); - } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutWriter = function(read) { - if(read == true) return this.connectionPool.checkoutConnection(); - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutWriter(this, read); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * Check if a reader can be provided - * @ignore - */ -var canCheckoutReader = function(self) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } else if(self._readPreference != null) { - // If the read preference is Primary and the instance is not a master return an error - if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) { - return new Error("Read preference is Server.PRIMARY and server is not master"); - } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutReader = function(read) { - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutReader(this); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * @ignore - */ -Server.prototype.enableRecordQueryStats = function(enable) { - this.recordQueryStats = enable; -} - -/** - * Internal statistics object used for calculating average and standard devitation on - * running queries - * @ignore - */ -var RunningStats = function() { - var self = this; - this.m_n = 0; - this.m_oldM = 0.0; - this.m_oldS = 0.0; - this.m_newM = 0.0; - this.m_newS = 0.0; - - // Define getters - Object.defineProperty(this, "numDataValues", { enumerable: true - , get: function () { return this.m_n; } - }); - - Object.defineProperty(this, "mean", { enumerable: true - , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; } - }); - - Object.defineProperty(this, "variance", { enumerable: true - , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); } - }); - - Object.defineProperty(this, "standardDeviation", { enumerable: true - , get: function () { return Math.sqrt(this.variance); } - }); - - Object.defineProperty(this, "sScore", { enumerable: true - , get: function () { - var bottom = this.mean + this.standardDeviation; - if(bottom == 0) return 0; - return ((2 * this.mean * this.standardDeviation)/(bottom)); - } - }); -} - -/** - * @ignore - */ -RunningStats.prototype.push = function(x) { - // Update the number of samples - this.m_n = this.m_n + 1; - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if(this.m_n == 1) { - this.m_oldM = this.m_newM = x; - this.m_oldS = 0.0; - } else { - this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n; - this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM); - - // set up for next iteration - this.m_oldM = this.m_newM; - this.m_oldS = this.m_newS; - } -} - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true - , get: function () { - return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect']; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "connection", { enumerable: true - , get: function () { - return this.internalConnection; - } - , set: function(connection) { - this.internalConnection = connection; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "master", { enumerable: true - , get: function () { - return this.internalMaster; - } - , set: function(value) { - this.internalMaster = value; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "primary", { enumerable: true - , get: function () { - return this; - } -}); - -/** - * Getter for query Stats - * @ignore - */ -Object.defineProperty(Server.prototype, "queryStats", { enumerable: true - , get: function () { - return this._state.runtimeStats.queryStats; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true - , get: function () { - return this._state.runtimeStats; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(Server.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return Server.READ_SECONDARY; - } else if(this._readPreference == null && !this.readSecondary) { - return Server.READ_PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * @ignore - */ -exports.Server = Server; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/simple_emitter.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/simple_emitter.js deleted file mode 100644 index 6782cbc30bc..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/simple_emitter.js +++ /dev/null @@ -1,48 +0,0 @@ -var SimpleEmitter = exports.SimpleEmitter = function() {} -// -// My own simple synchronous emit support, We don't need the overhead of the built in flexible node.js -// event emitter as we are looking for as low latency as possible. -// -SimpleEmitter.prototype.on = function(event, callback) { - if(this.eventHandlers[event] == null) throw "Event handler only accepts values of " + Object.keys(this.eventHandlers); - // Just add callback to our event handler (avoiding the cost of the node.js event handler) - this.eventHandlers[event].push(callback); -} - -SimpleEmitter.prototype.emit = function(event, err, object) { - if(this.eventHandlers[event] == null) throw "Event handler only accepts values of " + Object.keys(this.eventHandlers); - // Fire off all the callbacks - var callbacks = this.eventHandlers[event]; - // Attemp to emit - try { - // Perform a callback on all the registered callback handlers - for(var i = 0; i < callbacks.length; i++) { - callbacks[i](err, object); - } - } catch (err) { - this.emit("error", err); - } -} - -SimpleEmitter.prototype.listeners = function(event) { - return this.eventHandlers[event]; -} - -SimpleEmitter.prototype.overrideListeners = function(event, listeners) { - this.eventHandlers[event] = listeners; -} - -SimpleEmitter.prototype.removeListeners = function(event) { - if(this.eventHandlers[event] == null) throw "Event handler only accepts values of " + Object.keys(this.eventHandlers); - // Throw away all handlers - this.eventHandlers[event] = []; -} - -SimpleEmitter.prototype.removeAllListeners = function() { - // Fetch all the keys of handlers - var keys = Object.keys(this.eventHandlers); - // Remove all handlers - for(var i = 0; i < keys.length; i++) { - this.eventHandlers[keys[i]] = []; - } -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js deleted file mode 100644 index 6bb36cff276..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js +++ /dev/null @@ -1,125 +0,0 @@ -var Server = require("../server").Server; - -// The ping strategy uses pings each server and records the -// elapsed time for the server so it can pick a server based on lowest -// return time for the db command {ping:true} -var PingStrategy = exports.PingStrategy = function(replicaset) { - this.replicaset = replicaset; - this.state = 'disconnected'; - // Class instance - this.Db = require("../../db").Db; -} - -// Starts any needed code -PingStrategy.prototype.start = function(callback) { - this.state = 'connected'; - // Start ping server - this._pingServer(callback); -} - -// Stops and kills any processes running -PingStrategy.prototype.stop = function(callback) { - // Stop the ping process - this.state = 'disconnected'; - // Call the callback - callback(null, null); -} - -PingStrategy.prototype.checkoutSecondary = function() { - // Get all secondary server keys - var keys = Object.keys(this.replicaset._state.secondaries); - // Contains the picked instance - var minimumPingMs = null; - var selectedInstance = null; - // Pick server key by the lowest ping time - for(var i = 0; i < keys.length; i++) { - // Fetch a server - var server = this.replicaset._state.secondaries[keys[i]]; - // If we don't have a ping time use it - if(server.runtimeStats['pingMs'] == null) { - // Set to 0 ms for the start - server.runtimeStats['pingMs'] = 0; - // Pick server - selectedInstance = server; - break; - } else { - // If the next server's ping time is less than the current one choose than one - if(minimumPingMs == null || server.runtimeStats['pingMs'] < minimumPingMs) { - minimumPingMs = server.runtimeStats['pingMs']; - selectedInstance = server; - } - } - } - - // Return the selected instance - return selectedInstance != null ? selectedInstance.checkoutReader() : null; -} - -PingStrategy.prototype._pingServer = function(callback) { - var self = this; - - // Ping server function - var pingFunction = function() { - if(self.state == 'disconnected') return; - var addresses = self.replicaset._state != null && self.replicaset._state.addresses != null ? self.replicaset._state.addresses : null; - // Grab all servers - var serverKeys = Object.keys(addresses); - // Number of server entries - var numberOfEntries = serverKeys.length; - // We got keys - for(var i = 0; i < serverKeys.length; i++) { - // We got a server instance - var server = addresses[serverKeys[i]]; - // Create a new server object, avoid using internal connections as they might - // be in an illegal state - new function(serverInstance) { - var server = new Server(serverInstance.host, serverInstance.port, {poolSize:1, timeout:500}); - var db = new self.Db(self.replicaset.db.databaseName, server); - // Add error listener - db.on("error", function(err) { - // Adjust the number of checks - numberOfEntries = numberOfEntries - 1; - // Close connection - db.close(); - // If we are done with all results coming back trigger ping again - if(numberOfEntries == 0 && self.state == 'connected') { - setTimeout(pingFunction, 1000); - } - }) - - // Open the db instance - db.open(function(err, p_db) { - if(err != null) { - db.close(); - } else { - // Startup time of the command - var startTime = new Date().getTime(); - // Execute ping on this connection - p_db.executeDbCommand({ping:1}, function(err, result) { - // Adjust the number of checks - numberOfEntries = numberOfEntries - 1; - // Get end time of the command - var endTime = new Date().getTime(); - // Store the ping time in the server instance state variable, if there is one - if(serverInstance != null && serverInstance.runtimeStats != null && serverInstance.isConnected()) { - serverInstance.runtimeStats['pingMs'] = (endTime - startTime); - } - - // Close server - p_db.close(); - // If we are done with all results coming back trigger ping again - if(numberOfEntries == 0 && self.state == 'connected') { - setTimeout(pingFunction, 1000); - } - }) - } - }) - }(server); - } - } - - // Start pingFunction - setTimeout(pingFunction, 1000); - // Do the callback - callback(null); -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js deleted file mode 100644 index 0c8b1c0832f..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js +++ /dev/null @@ -1,40 +0,0 @@ -// The Statistics strategy uses the measure of each end-start time for each -// query executed against the db to calculate the mean, variance and standard deviation -// and pick the server which the lowest mean and deviation -var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) { - this.replicaset = replicaset; -} - -// Starts any needed code -StatisticsStrategy.prototype.start = function(callback) { - callback(null, null); -} - -StatisticsStrategy.prototype.stop = function(callback) { - // Remove reference to replicaset - this.replicaset = null; - // Perform callback - callback(null, null); -} - -StatisticsStrategy.prototype.checkoutSecondary = function() { - // Get all secondary server keys - var keys = Object.keys(this.replicaset._state.secondaries); - // Contains the picked instance - var minimumSscore = null; - var selectedInstance = null; - - // Pick server key by the lowest ping time - for(var i = 0; i < keys.length; i++) { - // Fetch a server - var server = this.replicaset._state.secondaries[keys[i]]; - // Pick server by lowest Sscore - if(minimumSscore == null || (server.queryStats.sScore < minimumSscore)) { - minimumSscore = server.queryStats.sScore; - selectedInstance = server; - } - } - - // Return the selected instance - return selectedInstance != null ? selectedInstance.checkoutReader() : null; -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/connection/url_parser.js b/frontend/express/node_modules/mongodb/lib/mongodb/connection/url_parser.js deleted file mode 100644 index 9adf5263e1d..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/connection/url_parser.js +++ /dev/null @@ -1,241 +0,0 @@ -var fs = require('fs'), - ReadPreference = require('./read_preference').ReadPreference; - -exports.parse = function(url, options) { - // Ensure we have a default options object if none set - options = options || {}; - // Variables - var connection_part = ''; - var auth_part = ''; - var query_string_part = ''; - var dbName = 'admin'; - - // Must start with mongodb - if(url.indexOf("mongodb://") != 0) - throw Error("URL must be in the format mongodb://user:pass@host:port/dbname"); - // If we have a ? mark cut the query elements off - if(url.indexOf("?") != -1) { - query_string_part = url.substr(url.indexOf("?") + 1); - connection_part = url.substring("mongodb://".length, url.indexOf("?")) - } else { - connection_part = url.substring("mongodb://".length); - } - - // Check if we have auth params - if(connection_part.indexOf("@") != -1) { - auth_part = connection_part.split("@")[0]; - connection_part = connection_part.split("@")[1]; - } - - // Check if the connection string has a db - if(connection_part.indexOf(".sock") != -1) { - if(connection_part.indexOf(".sock/") != -1) { - dbName = connection_part.split(".sock/")[1]; - connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length); - } - } else if(connection_part.indexOf("/") != -1) { - dbName = connection_part.split("/")[1]; - connection_part = connection_part.split("/")[0]; - } - - // Result object - var object = {}; - - // Pick apart the authentication part of the string - var authPart = auth_part || ''; - var auth = authPart.split(':', 2); - if(options['uri_decode_auth']){ - auth[0] = decodeURIComponent(auth[0]); - if(auth[1]){ - auth[1] = decodeURIComponent(auth[1]); - } - } - - // Add auth to final object if we have 2 elements - if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]}; - - // Variables used for temporary storage - var hostPart; - var urlOptions; - var servers; - var serverOptions = {socketOptions: {}}; - var dbOptions = {read_preference_tags: []}; - var replSetServersOptions = {socketOptions: {}}; - // Add server options to final object - object.server_options = serverOptions; - object.db_options = dbOptions; - object.rs_options = replSetServersOptions; - object.mongos_options = {}; - - // Let's check if we are using a domain socket - if(url.match(/\.sock/)) { - // Split out the socket part - var domainSocket = url.substring( - url.indexOf("mongodb://") + "mongodb://".length - , url.lastIndexOf(".sock") + ".sock".length); - // Clean out any auth stuff if any - if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1]; - servers = [{domain_socket: domainSocket}]; - } else { - // Split up the db - hostPart = connection_part; - // Parse all server results - servers = hostPart.split(',').map(function(h) { - var hostPort = h.split(':', 2); - var _host = hostPort[0] || 'localhost'; - var _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017; - // Check for localhost?safe=true style case - if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0]; - - // Return the mapped object - return {host: _host, port: _port}; - }); - } - - // Get the db name - object.dbName = dbName || 'admin'; - // Split up all the options - urlOptions = (query_string_part || '').split(/[&;]/); - // Ugh, we have to figure out which options go to which constructor manually. - urlOptions.forEach(function(opt) { - if(!opt) return; - var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1]; - // Options implementations - switch(name) { - case 'slaveOk': - case 'slave_ok': - serverOptions.slave_ok = (value == 'true'); - break; - case 'maxPoolSize': - case 'poolSize': - serverOptions.poolSize = parseInt(value, 10); - replSetServersOptions.poolSize = parseInt(value, 10); - break; - case 'autoReconnect': - case 'auto_reconnect': - serverOptions.auto_reconnect = (value == 'true'); - break; - case 'minPoolSize': - throw new Error("minPoolSize not supported"); - case 'maxIdleTimeMS': - throw new Error("maxIdleTimeMS not supported"); - case 'waitQueueMultiple': - throw new Error("waitQueueMultiple not supported"); - case 'waitQueueTimeoutMS': - throw new Error("waitQueueTimeoutMS not supported"); - case 'uuidRepresentation': - throw new Error("uuidRepresentation not supported"); - case 'ssl': - if(value == 'prefer') { - serverOptions.ssl = value; - replSetServersOptions.ssl = value; - break; - } - serverOptions.ssl = (value == 'true'); - replSetServersOptions.ssl = (value == 'true'); - break; - case 'replicaSet': - case 'rs_name': - replSetServersOptions.rs_name = value; - break; - case 'reconnectWait': - replSetServersOptions.reconnectWait = parseInt(value, 10); - break; - case 'retries': - replSetServersOptions.retries = parseInt(value, 10); - break; - case 'readSecondary': - case 'read_secondary': - replSetServersOptions.read_secondary = (value == 'true'); - break; - case 'fsync': - dbOptions.fsync = (value == 'true'); - break; - case 'journal': - dbOptions.journal = (value == 'true'); - break; - case 'safe': - dbOptions.safe = (value == 'true'); - break; - case 'nativeParser': - case 'native_parser': - dbOptions.native_parser = (value == 'true'); - break; - case 'connectTimeoutMS': - serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - break; - case 'socketTimeoutMS': - serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - break; - case 'w': - dbOptions.w = parseInt(value, 10); - break; - case 'authSource': - dbOptions.authSource = value; - break; - case 'authMechanism': - if(value == 'GSSAPI') { - // If no password provided decode only the principal - if(object.auth == null) { - var urlDecodeAuthPart = decodeURIComponent(authPart); - if(urlDecodeAuthPart.indexOf("@") == -1) throw new Error("GSSAPI requires a provided principal"); - object.auth = {user: urlDecodeAuthPart, password: null}; - } else { - object.auth.user = decodeURIComponent(object.auth.user); - } - } - // Only support GSSAPI or MONGODB-CR for now - if(value != 'GSSAPI' && value != 'MONGODB-CR') throw new Error("only GSSAPI or MONGODB-CR is supported by authMechanism"); - dbOptions.authMechanism = value; - break; - case 'wtimeoutMS': - dbOptions.wtimeoutMS = parseInt(value, 10); - break; - case 'readPreference': - if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest"); - dbOptions.read_preference = value; - break; - case 'readPreferenceTags': - // Contains the tag object - var tagObject = {}; - if(value == null || value == '') { - dbOptions.read_preference_tags.push(tagObject); - break; - } - - // Split up the tags - var tags = value.split(/\,/); - for(var i = 0; i < tags.length; i++) { - var parts = tags[i].trim().split(/\:/); - tagObject[parts[0]] = parts[1]; - } - - // Set the preferences tags - dbOptions.read_preference_tags.push(tagObject); - break; - default: - break; - } - }); - - // No tags: should be null (not []) - if(dbOptions.read_preference_tags.length === 0) { - dbOptions.read_preference_tags = null; - } - - // Validate if there are an invalid write concern combinations - if((dbOptions.w == -1 || dbOptions.w == 0) && ( - dbOptions.journal == true - || dbOptions.fsync == true - || dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync") - - // If no read preference set it to primary - if(!dbOptions.read_preference) dbOptions.read_preference = 'primary'; - - // Add servers to result - object.servers = servers; - // Returned parsed object - return object; -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/cursor.js b/frontend/express/node_modules/mongodb/lib/mongodb/cursor.js deleted file mode 100644 index 5eab489192d..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/cursor.js +++ /dev/null @@ -1,938 +0,0 @@ -var QueryCommand = require('./commands/query_command').QueryCommand, - GetMoreCommand = require('./commands/get_more_command').GetMoreCommand, - KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand, - Long = require('bson').Long, - ReadPreference = require('./connection/read_preference').ReadPreference, - CursorStream = require('./cursorstream'), - timers = require('timers'), - utils = require('./utils'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Constructor for a cursor object that handles all the operations on query result - * using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly, - * but use find to acquire a cursor. (INTERNAL TYPE) - * - * Options - * - **skip** {Number} skip number of documents to skip. - * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **hint** {Object}, hint force the query to use a specific index. - * - **explain** {Boolean}, explain return the explaination of the query. - * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned. - * - **timeout** {Boolean}, timeout allow the query to timeout. - * - **tailable** {Boolean}, tailable allow the cursor to be tailable. - * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor. - * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database. - * - **raw** {Boolean}, raw return all query documents as raw buffers (default false). - * - **read** {Boolean}, read specify override of read from source (primary/secondary). - * - **returnKey** {Boolean}, returnKey only return the index key. - * - **maxScan** {Number}, maxScan limit the number of items to scan. - * - **min** {Number}, min set index bounds. - * - **max** {Number}, max set index bounds. - * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results. - * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler. - * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout. - * - **dbName** {String}, dbName override the default dbName. - * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor. - * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets. - * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos. - * - * @class Represents a Cursor. - * @param {Db} db the database object to work with. - * @param {Collection} collection the collection to query. - * @param {Object} selector the query selector. - * @param {Object} fields an object containing what fields to include or exclude from objects returned. - * @param {Object} [options] additional options for the collection. -*/ -function Cursor(db, collection, selector, fields, options) { - this.db = db; - this.collection = collection; - this.selector = selector; - this.fields = fields; - options = !options ? {} : options; - - this.skipValue = options.skip == null ? 0 : options.skip; - this.limitValue = options.limit == null ? 0 : options.limit; - this.sortValue = options.sort; - this.hint = options.hint; - this.explainValue = options.explain; - this.snapshot = options.snapshot; - this.timeout = options.timeout == null ? true : options.timeout; - this.tailable = options.tailable; - this.awaitdata = options.awaitdata; - this.numberOfRetries = options.numberOfRetries == null ? 5 : options.numberOfRetries; - this.currentNumberOfRetries = this.numberOfRetries; - this.batchSizeValue = options.batchSize == null ? 0 : options.batchSize; - this.raw = options.raw == null ? false : options.raw; - this.read = options.read == null ? ReadPreference.PRIMARY : options.read; - this.returnKey = options.returnKey; - this.maxScan = options.maxScan; - this.min = options.min; - this.max = options.max; - this.showDiskLoc = options.showDiskLoc; - this.comment = options.comment; - this.tailableRetryInterval = options.tailableRetryInterval || 100; - this.exhaust = options.exhaust || false; - this.partial = options.partial || false; - this.slaveOk = options.slaveOk || false; - - this.totalNumberOfRecords = 0; - this.items = []; - this.cursorId = Long.fromInt(0); - - // This name - this.dbName = options.dbName; - - // State variables for the cursor - this.state = Cursor.INIT; - // Keep track of the current query run - this.queryRun = false; - this.getMoreTimer = false; - - // If we are using a specific db execute against it - if(this.dbName != null) { - this.collectionName = this.dbName + "." + this.collection.collectionName; - } else { - this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName; - } -}; - -/** - * Resets this cursor to its initial state. All settings like the query string, - * tailable, batchSizeValue, skipValue and limits are preserved. - * - * @return {Cursor} returns itself with rewind applied. - * @api public - */ -Cursor.prototype.rewind = function() { - var self = this; - - if (self.state != Cursor.INIT) { - if (self.state != Cursor.CLOSED) { - self.close(function() {}); - } - - self.numberOfReturned = 0; - self.totalNumberOfRecords = 0; - self.items = []; - self.cursorId = Long.fromInt(0); - self.state = Cursor.INIT; - self.queryRun = false; - } - - return self; -}; - - -/** - * Returns an array of documents. The caller is responsible for making sure that there - * is enough memory to store the results. Note that the array only contain partial - * results when this cursor had been previouly accessed. In that case, - * cursor.rewind() can be used to reset the cursor. - * - * @param {Function} callback This will be called after executing this method successfully. The first parameter will contain the Error object if an error occured, or null otherwise. The second parameter will contain an array of BSON deserialized objects as a result of the query. - * @return {null} - * @api public - */ -Cursor.prototype.toArray = function(callback) { - var self = this; - - if(!callback) { - throw new Error('callback is mandatory'); - } - - if(this.tailable) { - callback(new Error("Tailable cursor cannot be converted to array"), null); - } else if(this.state != Cursor.CLOSED) { - // return toArrayExhaust(self, callback); - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return toArrayExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - self.nextObject({noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err), null); - if(self.cursorId.toString() == "0") { - self.state = Cursor.CLOSED; - return callback(null, self.items); - } - - // Let's issue getMores until we have no more records waiting - getAllByGetMore(self, function(err, done) { - self.state = Cursor.CLOSED; - if(err) return callback(utils.toError(err), null); - // Let's release the internal list - var items = self.items; - self.items = null; - // Return all the items - callback(null, items); - }); - }) - - } else { - callback(new Error("Cursor is closed"), null); - } -} - -var toArrayExhaust = function(self, callback) { - var items = []; - - self.each(function(err, item) { - if(err != null) { - return callback(utils.toError(err), null); - } - - if(item != null && Array.isArray(items)) { - items.push(item); - } else { - var resultItems = items; - items = null; - self.items = []; - callback(null, resultItems); - } - }); -} - -var getAllByGetMore = function(self, callback) { - getMore(self, {noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err)); - if(result == null) return callback(null, null); - if(self.cursorId.toString() == "0") return callback(null, null); - getAllByGetMore(self, callback); - }) -} - -/** - * Iterates over all the documents for this cursor. As with **{cursor.toArray}**, - * not all of the elements will be iterated if this cursor had been previouly accessed. - * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike - * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements - * at any given time if batch size is specified. Otherwise, the caller is responsible - * for making sure that the entire result can fit the memory. - * - * @param {Function} callback this will be called for while iterating every document of the query result. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the document. - * @return {null} - * @api public - */ -Cursor.prototype.each = function(callback) { - var self = this; - var fn; - - if (!callback) { - throw new Error('callback is mandatory'); - } - - if(this.state != Cursor.CLOSED) { - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return eachExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - if(this.items.length > 0) { - // Trampoline all the entries - while(fn = loop(self, callback)) fn(self, callback); - // Call each again - self.each(callback); - } else { - self.nextObject(function(err, item) { - - if(err) { - self.state = Cursor.CLOSED; - return callback(utils.toError(err), item); - } - - if(item == null) return callback(null, null); - callback(null, item); - self.each(callback); - }) - } - } else { - callback(new Error("Cursor is closed"), null); - } -} - -// Special for exhaust command as we don't initiate the actual result sets -// the server just sends them as they arrive meaning we need to get the IO event -// loop happen so we can receive more data from the socket or we return to early -// after the first fetch and loose all the incoming getMore's automatically issued -// from the server. -var eachExhaust = function(self, callback) { - //FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2) - processor(function(){ - // Fetch the next object until there is no more objects - self.nextObject(function(err, item) { - if(err != null) return callback(err, null); - if(item != null) { - callback(null, item); - eachExhaust(self, callback); - } else { - // Close the cursor if done - self.state = Cursor.CLOSED; - callback(err, null); - } - }); - }); -} - -// Trampoline emptying the number of retrieved items -// without incurring a nextTick operation -var loop = function(self, callback) { - // No more items we are done - if(self.items.length == 0) return; - // Get the next document - var doc = self.items.shift(); - // Callback - callback(null, doc); - // Loop - return loop; -} - -/** - * Determines how many result the query for this cursor will return - * - * @param {Boolean} applySkipLimit if set to true will apply the skip and limits set on the cursor. Defaults to false. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the number of results or null if an error occured. - * @return {null} - * @api public - */ -Cursor.prototype.count = function(applySkipLimit, callback) { - if(typeof applySkipLimit == 'function') { - callback = applySkipLimit; - applySkipLimit = false; - } - - var options = {}; - if(applySkipLimit) { - if(typeof this.skipValue == 'number') options.skip = this.skipValue; - if(typeof this.limitValue == 'number') options.limit = this.limitValue; - } - - // Call count command - this.collection.count(this.selector, options, callback); -}; - -/** - * Sets the sort parameter of this cursor to the given value. - * - * This method has the following method signatures: - * (keyOrList, callback) - * (keyOrList, direction, callback) - * - * @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction]. - * @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive. - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.sort = function(keyOrList, direction, callback) { - callback = callback || function(){}; - if(typeof direction === "function") { callback = direction; direction = null; } - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support sorting"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - var order = keyOrList; - - if(direction != null) { - order = [[keyOrList, direction]]; - } - - this.sortValue = order; - callback(null, this); - } - return this; -}; - -/** - * Sets the limit parameter of this cursor to the given value. - * - * @param {Number} limit the new limit. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.limit = function(limit, callback) { - if(this.tailable) { - if(callback) { - callback(new Error("Tailable cursor doesn't support limit"), null); - } else { - throw new Error("Tailable cursor doesn't support limit"); - } - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback) { - callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else { - if(limit != null && limit.constructor != Number) { - if(callback) { - callback(new Error("limit requires an integer"), null); - } else { - throw new Error("limit requires an integer"); - } - } else { - this.limitValue = limit; - if(callback) return callback(null, this); - } - } - - return this; -}; - -/** - * Sets the read preference for the cursor - * - * @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.setReadPreference = function(readPreference, tags, callback) { - if(typeof tags == 'function') callback = tags; - - var _mode = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - - if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback == null) throw new Error("Cannot change read preference on executed query or closed cursor"); - callback(new Error("Cannot change read preference on executed query or closed cursor")); - } else if(_mode != null && _mode != 'primary' - && _mode != 'secondaryOnly' && _mode != 'secondary' - && _mode != 'nearest' && _mode != 'primaryPreferred' && _mode != 'secondaryPreferred') { - if(callback == null) throw new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported"); - callback(new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported")); - } else { - this.read = readPreference; - if(callback != null) callback(null, this); - } - - return this; -} - -/** - * Sets the skip parameter of this cursor to the given value. - * - * @param {Number} skip the new skip value. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.skip = function(skip, callback) { - callback = callback || function(){}; - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support skip"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - if(skip != null && skip.constructor != Number) { - callback(new Error("skip requires an integer"), null); - } else { - this.skipValue = skip; - callback(null, this); - } - } - - return this; -}; - -/** - * Sets the batch size parameter of this cursor to the given value. - * - * @param {Number} batchSize the new batch size. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.batchSize = function(batchSize, callback) { - if(this.state == Cursor.CLOSED) { - if(callback != null) { - return callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else if(batchSize != null && batchSize.constructor != Number) { - if(callback != null) { - return callback(new Error("batchSize requires an integer"), null); - } else { - throw new Error("batchSize requires an integer"); - } - } else { - this.batchSizeValue = batchSize; - if(callback != null) return callback(null, this); - } - - return this; -}; - -/** - * The limit used for the getMore command - * - * @return {Number} The number of records to request per batch. - * @ignore - * @api private - */ -var limitRequest = function(self) { - var requestedLimit = self.limitValue; - var absLimitValue = Math.abs(self.limitValue); - var absBatchValue = Math.abs(self.batchSizeValue); - - if(absLimitValue > 0) { - if (absBatchValue > 0) { - requestedLimit = Math.min(absLimitValue, absBatchValue); - } - } else { - requestedLimit = self.batchSizeValue; - } - - return requestedLimit; -}; - - -/** - * Generates a QueryCommand object using the parameters of this cursor. - * - * @return {QueryCommand} The command object - * @ignore - * @api private - */ -var generateQueryCommand = function(self) { - // Unpack the options - var queryOptions = QueryCommand.OPTS_NONE; - if(!self.timeout) { - queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - } - - if(self.tailable != null) { - queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR; - self.skipValue = self.limitValue = 0; - - // if awaitdata is set - if(self.awaitdata != null) { - queryOptions |= QueryCommand.OPTS_AWAIT_DATA; - } - } - - if(self.exhaust) { - queryOptions |= QueryCommand.OPTS_EXHAUST; - } - - // Unpack the read preference to set slave ok correctly - var read = self.read instanceof ReadPreference ? self.read.mode : self.read; - - // if(self.read == 'secondary') - if(read == ReadPreference.PRIMARY_PREFERRED - || read == ReadPreference.SECONDARY - || read == ReadPreference.SECONDARY_PREFERRED - || read == ReadPreference.NEAREST) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - // Override slaveOk from the user - if(self.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - if(self.partial) { - queryOptions |= QueryCommand.OPTS_PARTIAL; - } - - // limitValue of -1 is a special case used by Db#eval - var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self); - - // Check if we need a special selector - if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null - || self.returnKey != null || self.maxScan != null || self.min != null || self.max != null - || self.showDiskLoc != null || self.comment != null) { - - // Build special selector - var specialSelector = {'$query':self.selector}; - if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue); - if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint; - if(self.snapshot != null) specialSelector['$snapshot'] = true; - if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey; - if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan; - if(self.min != null) specialSelector['$min'] = self.min; - if(self.max != null) specialSelector['$max'] = self.max; - if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc; - if(self.comment != null) specialSelector['$comment'] = self.comment; - // If we have explain set only return a single document with automatic cursor close - if(self.explainValue != null) { - numberToReturn = (-1)*Math.abs(numberToReturn); - specialSelector['$explain'] = true; - } - - // Return the query - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields); - } else { - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields); - } -}; - -/** - * @return {Object} Returns an object containing the sort value of this cursor with - * the proper formatting that can be used internally in this cursor. - * @ignore - * @api private - */ -Cursor.prototype.formattedOrderClause = function() { - return utils.formattedOrderClause(this.sortValue); -}; - -/** - * Converts the value of the sort direction into its equivalent numerical value. - * - * @param sortDirection {String|number} Range of acceptable values: - * 'ascending', 'descending', 'asc', 'desc', 1, -1 - * - * @return {number} The equivalent numerical value - * @throws Error if the given sortDirection is invalid - * @ignore - * @api private - */ -Cursor.prototype.formatSortValue = function(sortDirection) { - return utils.formatSortValue(sortDirection); -}; - -/** - * Gets the next document from the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @api public - */ -Cursor.prototype.nextObject = function(options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.INIT) { - var cmd; - try { - cmd = generateQueryCommand(self); - } catch (err) { - return callback(err, null); - } - - var queryOptions = {exhaust: self.exhaust, raw:self.raw, read:self.read, connection:self.connection}; - // Execute command - var commandHandler = function(err, result) { - // If on reconnect, the command got given a different connection, switch - // the whole cursor to it. - self.connection = queryOptions.connection; - self.state = Cursor.OPEN; - if(err != null && result == null) return callback(utils.toError(err), null); - - if(err == null && (result == null || result.documents == null)) { - return self.close(function() {callback(null, null);}); - } - - if(err == null && result && result.documents[0] && result.documents[0]['$err']) { - return self.close(function() {callback(utils.toError(result.documents[0]['$err']), null);}); - } - - self.queryRun = true; - self.state = Cursor.OPEN; // Adjust the state of the cursor - self.cursorId = result.cursorId; - self.totalNumberOfRecords = result.numberReturned; - - // Add the new documents to the list of items, using forloop to avoid - // new array allocations and copying - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // If we have noReturn set just return (not modifying the internal item list) - // used for toArray - if(options.noReturn) { - return callback(null, true); - } - - // Ignore callbacks until the cursor is dead for exhausted - if(self.exhaust && result.cursorId.toString() == "0") { - self.nextObject(callback); - } else if(self.exhaust == false || self.exhaust == null) { - self.nextObject(callback); - } - }; - - // If we have no connection set on this cursor check one out - if(self.connection == null) { - try { - // self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read); - self.connection = self.db.serverConfig.checkoutReader(this.read); - } catch(err) { - return callback(utils.toError(err), null); - } - } - - // Execute the command - self.db._executeQueryCommand(cmd, queryOptions, commandHandler); - // Set the command handler to null - commandHandler = null; - } else if(self.items.length) { - callback(null, self.items.shift()); - } else if(self.cursorId.greaterThan(Long.fromInt(0))) { - getMore(self, callback); - } else { - // Force cursor to stay open - return self.close(function() {callback(null, null);}); - } -} - -/** - * Gets more results from the database if any. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @ignore - * @api private - */ -var getMore = function(self, options, callback) { - var limit = 0; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.GET_MORE) return callback(null, null); - - // Set get more in progress - self.state = Cursor.GET_MORE; - - // Set options - if (!self.tailable && self.limitValue > 0) { - limit = self.limitValue - self.totalNumberOfRecords; - if (limit < 1) { - self.close(function() {callback(null, null);}); - return; - } - } - - try { - var getMoreCommand = new GetMoreCommand( - self.db - , self.collectionName - , limitRequest(self) - , self.cursorId - ); - - // Set up options - var command_options = {read: self.read, raw: self.raw, connection:self.connection }; - - // Execute the command - self.db._executeQueryCommand(getMoreCommand, command_options, function(err, result) { - var cbValue; - - // Get more done - self.state = Cursor.OPEN; - - if(err != null) { - return callback(utils.toError(err), null); - } - - try { - var isDead = 1 === result.responseFlag && result.cursorId.isZero(); - - self.cursorId = result.cursorId; - self.totalNumberOfRecords += result.numberReturned; - - // Determine if there's more documents to fetch - if(result.numberReturned > 0) { - if (self.limitValue > 0) { - var excessResult = self.totalNumberOfRecords - self.limitValue; - - if (excessResult > 0) { - result.documents.splice(-1 * excessResult, excessResult); - } - } - - // Reset the tries for awaitdata if we are using it - self.currentNumberOfRetries = self.numberOfRetries; - // Get the documents - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // Don's shift a document out as we need it for toArray - if(options.noReturn) { - cbValue = true; - } else { - cbValue = self.items.shift(); - } - } else if(self.tailable && !isDead && self.awaitdata) { - // Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used - self.currentNumberOfRetries = self.currentNumberOfRetries - 1; - if(self.currentNumberOfRetries == 0) { - self.close(function() { - callback(new Error("tailable cursor timed out"), null); - }); - } else { - getMore(self, callback); - } - } else if(self.tailable && !isDead) { - self.getMoreTimer = setTimeout(function() { getMore(self, callback); }, self.tailableRetryInterval); - } else { - self.close(function() {callback(null, null); }); - } - - result = null; - } catch(err) { - callback(utils.toError(err), null); - } - if (cbValue != null) callback(null, cbValue); - }); - - getMoreCommand = null; - } catch(err) { - // Get more done - self.state = Cursor.OPEN; - - var handleClose = function() { - callback(utils.toError(err), null); - }; - - self.close(handleClose); - handleClose = null; - } -} - -/** - * Gets a detailed information about how the query is performed on this cursor and how - * long it took the database to process it. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details. - * @api public - */ -Cursor.prototype.explain = function(callback) { - var limit = (-1)*Math.abs(this.limitValue); - - // Create a new cursor and fetch the plan - var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, { - skip: this.skipValue - , limit:limit - , sort: this.sortValue - , hint: this.hint - , explain: true - , snapshot: this.snapshot - , timeout: this.timeout - , tailable: this.tailable - , batchSize: this.batchSizeValue - , slaveOk: this.slaveOk - , raw: this.raw - , read: this.read - , returnKey: this.returnKey - , maxScan: this.maxScan - , min: this.min - , max: this.max - , showDiskLoc: this.showDiskLoc - , comment: this.comment - , awaitdata: this.awaitdata - , numberOfRetries: this.numberOfRetries - , dbName: this.dbName - }); - - // Fetch the explaination document - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - // close the cursor - cursor.close(function(err, result) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); - }); -}; - -/** - * Returns a Node ReadStream interface for this cursor. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * @return {CursorStream} returns a stream object. - * @api public - */ -Cursor.prototype.stream = function stream(options) { - return new CursorStream(this, options); -} - -/** - * Close the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor. - * @return {null} - * @api public - */ -Cursor.prototype.close = function(callback) { - var self = this - this.getMoreTimer && clearTimeout(this.getMoreTimer); - // Close the cursor if not needed - if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) { - try { - var command = new KillCursorCommand(this.db, [this.cursorId]); - // Added an empty callback to ensure we don't throw any null exceptions - this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function() {}); - } catch(err) {} - } - - // Null out the connection - self.connection = null; - // Reset cursor id - this.cursorId = Long.fromInt(0); - // Set to closed status - this.state = Cursor.CLOSED; - - if(callback) { - callback(null, self); - self.items = []; - } - - return this; -}; - -/** - * Check if the cursor is closed or open. - * - * @return {Boolean} returns the state of the cursor. - * @api public - */ -Cursor.prototype.isClosed = function() { - return this.state == Cursor.CLOSED ? true : false; -}; - -/** - * Init state - * - * @classconstant INIT - **/ -Cursor.INIT = 0; - -/** - * Cursor open - * - * @classconstant OPEN - **/ -Cursor.OPEN = 1; - -/** - * Cursor closed - * - * @classconstant CLOSED - **/ -Cursor.CLOSED = 2; - -/** - * Cursor performing a get more - * - * @classconstant OPEN - **/ -Cursor.GET_MORE = 3; - -/** - * @ignore - * @api private - */ -exports.Cursor = Cursor; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/cursorstream.js b/frontend/express/node_modules/mongodb/lib/mongodb/cursorstream.js deleted file mode 100644 index 27520913e2b..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/cursorstream.js +++ /dev/null @@ -1,164 +0,0 @@ -var timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Module dependecies. - */ -var Stream = require('stream').Stream; - -/** - * CursorStream - * - * Returns a stream interface for the **cursor**. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - **close** {function() {}} the end event triggers when there is no more documents available. - * - * @class Represents a CursorStream. - * @param {Cursor} cursor a cursor object that the stream wraps. - * @return {Stream} - */ -function CursorStream(cursor, options) { - if(!(this instanceof CursorStream)) return new CursorStream(cursor); - options = options ? options : {}; - - Stream.call(this); - - this.readable = true; - this.paused = false; - this._cursor = cursor; - this._destroyed = null; - this.options = options; - - // give time to hook up events - var self = this; - process.nextTick(function() { - self._init(); - }); -} - -/** - * Inherit from Stream - * @ignore - * @api private - */ -CursorStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -CursorStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -CursorStream.prototype.paused; - -/** - * Initialize the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._init = function () { - if (this._destroyed) return; - this._next(); -} - -/** - * Pull the next document from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._next = function () { - if(this.paused || this._destroyed) return; - - var self = this; - // Get the next object - processor(function() { - if(self.paused || self._destroyed) return; - - self._cursor.nextObject(function (err, doc) { - self._onNextObject(err, doc); - }); - }); -} - -/** - * Handle each document as its returned from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._onNextObject = function (err, doc) { - if(err) return this.destroy(err); - - // when doc is null we hit the end of the cursor - if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) { - this.emit('end') - return this.destroy(); - } else if(doc) { - var data = typeof this.options.transform == 'function' ? this.options.transform(doc) : doc; - this.emit('data', data); - this._next(); - } -} - -/** - * Pauses the stream. - * - * @api public - */ -CursorStream.prototype.pause = function () { - this.paused = true; -} - -/** - * Resumes the stream. - * - * @api public - */ -CursorStream.prototype.resume = function () { - var self = this; - - // Don't do anything if we are not paused - if(!this.paused) return; - if(!this._cursor.state == 3) return; - - process.nextTick(function() { - self.paused = false; - // Only trigger more fetching if the cursor is open - self._next(); - }) -} - -/** - * Destroys the stream, closing the underlying - * cursor. No more events will be emitted. - * - * @api public - */ -CursorStream.prototype.destroy = function (err) { - if (this._destroyed) return; - this._destroyed = true; - this.readable = false; - - this._cursor.close(); - - if(err) { - this.emit('error', err); - } - - this.emit('close'); -} - -// TODO - maybe implement the raw option to pass binary? -//CursorStream.prototype.setEncoding = function () { -//} - -module.exports = exports = CursorStream; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/db.js b/frontend/express/node_modules/mongodb/lib/mongodb/db.js deleted file mode 100644 index 58621a5d6dc..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/db.js +++ /dev/null @@ -1,1938 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var QueryCommand = require('./commands/query_command').QueryCommand - , DbCommand = require('./commands/db_command').DbCommand - , MongoReply = require('./responses/mongo_reply').MongoReply - , Admin = require('./admin').Admin - , Collection = require('./collection').Collection - , Server = require('./connection/server').Server - , ReplSet = require('./connection/repl_set/repl_set').ReplSet - , ReadPreference = require('./connection/read_preference').ReadPreference - , Mongos = require('./connection/mongos').Mongos - , Cursor = require('./cursor').Cursor - , EventEmitter = require('events').EventEmitter - , inherits = require('util').inherits - , crypto = require('crypto') - , timers = require('timers') - , utils = require('./utils') - , mongodb_cr_authenticate = require('./auth/mongodb_cr.js').authenticate - , mongodb_gssapi_authenticate = require('./auth/mongodb_gssapi.js').authenticate - , mongodb_sspi_authenticate = require('./auth/mongodb_sspi.js').authenticate; - -var hasKerberos = false; -// Check if we have a the kerberos library -try { - require('kerberos'); - hasKerberos = true; -} catch(err) {} - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Create a new Db instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **slaveOk** {Number, default:null}, force setting of SlaveOk flag on queries (only use when explicitly connecting to a secondary server). - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a Db - * @param {String} databaseName name of the database. - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function Db(databaseName, serverConfig, options) { - if(!(this instanceof Db)) return new Db(databaseName, serverConfig, options); - EventEmitter.call(this); - - var self = this; - this.databaseName = databaseName; - this.serverConfig = serverConfig; - this.options = options == null ? {} : options; - // State to check against if the user force closed db - this._applicationClosed = false; - // Fetch the override flag if any - var overrideUsedFlag = this.options['override_used_flag'] == null ? false : this.options['override_used_flag']; - - // Verify that nobody is using this config - if(!overrideUsedFlag && this.serverConfig != null && typeof this.serverConfig == 'object' && this.serverConfig._isUsed && this.serverConfig._isUsed()) { - throw new Error("A Server or ReplSet instance cannot be shared across multiple Db instances"); - } else if(!overrideUsedFlag && typeof this.serverConfig == 'object'){ - // Set being used - this.serverConfig._used = true; - } - - // Allow slaveOk override - this.slaveOk = this.options["slave_ok"] == null ? false : this.options["slave_ok"]; - this.slaveOk = this.options["slaveOk"] == null ? this.slaveOk : this.options["slaveOk"]; - - // Ensure we have a valid db name - validateDatabaseName(databaseName); - - // Contains all the connections for the db - try { - this.native_parser = this.options.native_parser; - // The bson lib - var bsonLib = this.bsonLib = this.options.native_parser ? require('bson').BSONNative : require('bson').BSONPure; - // Fetch the serializer object - var BSON = bsonLib.BSON; - // Create a new instance - this.bson = new BSON([bsonLib.Long, bsonLib.ObjectID, bsonLib.Binary, bsonLib.Code, bsonLib.DBRef, bsonLib.Symbol, bsonLib.Double, bsonLib.Timestamp, bsonLib.MaxKey, bsonLib.MinKey]); - // Backward compatibility to access types - this.bson_deserializer = bsonLib; - this.bson_serializer = bsonLib; - } catch (err) { - // If we tried to instantiate the native driver - var msg = "Native bson parser not compiled, please compile " - + "or avoid using native_parser=true"; - throw Error(msg); - } - - // Internal state of the server - this._state = 'disconnected'; - - this.pkFactory = this.options.pk == null ? bsonLib.ObjectID : this.options.pk; - this.forceServerObjectId = this.options.forceServerObjectId != null ? this.options.forceServerObjectId : false; - - // Added safe - this.safe = this.options.safe == null ? false : this.options.safe; - - // If we have not specified a "safe mode" we just print a warning to the console - if(this.options.safe == null && this.options.w == null && this.options.journal == null && this.options.fsync == null) { - console.log("========================================================================================"); - console.log("= Please ensure that you set the default write concern for the database by setting ="); - console.log("= one of the options ="); - console.log("= ="); - console.log("= w: (value of > -1 or the string 'majority'), where < 1 means ="); - console.log("= no write acknowlegement ="); - console.log("= journal: true/false, wait for flush to journal before acknowlegement ="); - console.log("= fsync: true/false, wait for flush to file system before acknowlegement ="); - console.log("= ="); - console.log("= For backward compatibility safe is still supported and ="); - console.log("= allows values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}] ="); - console.log("= the default value is false which means the driver receives does not ="); - console.log("= return the information of the success/error of the insert/update/remove ="); - console.log("= ="); - console.log("= ex: new Db(new Server('localhost', 27017), {safe:false}) ="); - console.log("= ="); - console.log("= http://www.mongodb.org/display/DOCS/getLastError+Command ="); - console.log("= ="); - console.log("= The default of no acknowlegement will change in the very near future ="); - console.log("= ="); - console.log("= This message will disappear when the default safe is set on the driver Db ="); - console.log("========================================================================================"); - } - - // Internal states variables - this.notReplied ={}; - this.isInitializing = true; - this.openCalled = false; - - // Command queue, keeps a list of incoming commands that need to be executed once the connection is up - this.commands = []; - - // Set up logger - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Associate the logger with the server config - this.serverConfig.logger = this.logger; - if(this.serverConfig.strategyInstance) this.serverConfig.strategyInstance.logger = this.logger; - this.tag = new Date().getTime(); - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[]}; - - // Controls serialization options - this.serializeFunctions = this.options.serializeFunctions != null ? this.options.serializeFunctions : false; - - // Raw mode - this.raw = this.options.raw != null ? this.options.raw : false; - - // Record query stats - this.recordQueryStats = this.options.recordQueryStats != null ? this.options.recordQueryStats : false; - - // If we have server stats let's make sure the driver objects have it enabled - if(this.recordQueryStats == true) { - this.serverConfig.enableRecordQueryStats(true); - } - - // Retry information - this.retryMiliSeconds = this.options.retryMiliSeconds != null ? this.options.retryMiliSeconds : 1000; - this.numberOfRetries = this.options.numberOfRetries != null ? this.options.numberOfRetries : 60; - - // Set default read preference if any - this.readPreference = this.options.readPreference; - - // Ensure we keep a reference to this db - this.serverConfig._dbStore.add(this); -}; - -/** - * @ignore - */ -function validateDatabaseName(databaseName) { - if(typeof databaseName !== 'string') throw new Error("database name must be a string"); - if(databaseName.length === 0) throw new Error("database name cannot be the empty string"); - - var invalidChars = [" ", ".", "$", "/", "\\"]; - for(var i = 0; i < invalidChars.length; i++) { - if(databaseName.indexOf(invalidChars[i]) != -1) throw new Error("database names cannot contain the character '" + invalidChars[i] + "'"); - } -} - -/** - * @ignore - */ -inherits(Db, EventEmitter); - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the index information or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.open = function(callback) { - var self = this; - - // Check that the user has not called this twice - if(this.openCalled) { - // Close db - this.close(); - // Throw error - throw new Error("db object already connecting, open cannot be called multiple times"); - } - - // If we have a specified read preference - if(this.readPreference != null) this.serverConfig.setReadPreference(this.readPreference); - - // Set that db has been opened - this.openCalled = true; - - // Set the status of the server - self._state = 'connecting'; - - // Set up connections - if(self.serverConfig instanceof Server || self.serverConfig instanceof ReplSet || self.serverConfig instanceof Mongos) { - // Ensure we have the original options passed in for the server config - var connect_options = {}; - for(var name in self.serverConfig.options) { - connect_options[name] = self.serverConfig.options[name] - } - connect_options.firstCall = true; - - // Attempt to connect - self.serverConfig.connect(self, connect_options, function(err, result) { - if(err != null) { - // Set that db has been closed - self.openCalled = false; - // Return error from connection - return callback(err, null); - } - // Set the status of the server - self._state = 'connected'; - // If we have queued up commands execute a command to trigger replays - if(self.commands.length > 0) _execute_queued_command(self); - // Callback - return callback(null, self); - }); - } else { - return callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null); - } -}; - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -Db.prototype.db = function(dbName) { - // Copy the options and add out internal override of the not shared flag - var options = {}; - for(var key in this.options) { - options[key] = this.options[key]; - } - - // Add override flag - options['override_used_flag'] = true; - // Create a new db instance - var newDbInstance = new Db(dbName, this.serverConfig, options); - // Add the instance to the list of approved db instances - var allServerInstances = this.serverConfig.allServerInstances(); - // Add ourselves to all server callback instances - for(var i = 0; i < allServerInstances.length; i++) { - // var server = allServerInstances[i]; - // server.dbInstances.push(newDbInstance); - this.serverConfig._dbStore.add(newDbInstance); - } - // Return new db object - return newDbInstance; -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Boolean} [forceClose] connection can never be reused. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.close = function(forceClose, callback) { - var self = this; - // Ensure we force close all connections - this._applicationClosed = false; - - if(typeof forceClose == 'function') { - callback = forceClose; - } else if(typeof forceClose == 'boolean') { - this._applicationClosed = forceClose; - } - - this.serverConfig.close(function(err, result) { - // You can reuse the db as everything is shut down - self.openCalled = false; - // If we have a callback call it - if(callback) callback(err, result); - }); -}; - -/** - * Access the Admin database - * - * @param {Function} [callback] returns the results. - * @return {Admin} the admin db object. - * @api public - */ -Db.prototype.admin = function(callback) { - if(callback == null) return new Admin(this); - callback(null, new Admin(this)); -}; - -/** - * Returns a cursor to all the collection information. - * - * @param {String} [collectionName] the collection name we wish to retrieve the information from. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the options or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionsInfo = function(collectionName, callback) { - if(callback == null && typeof collectionName == 'function') { callback = collectionName; collectionName = null; } - // Create selector - var selector = {}; - // If we are limiting the access to a specific collection name - if(collectionName != null) selector.name = this.databaseName + "." + collectionName; - - // Return Cursor - // callback for backward compatibility - if(callback) { - callback(null, new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector)); - } else { - return new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector); - } -}; - -/** - * Get the list of all collection names for the specified db - * - * Options - * - **namesOnly** {String, default:false}, Return only the full collection namespace. - * - * @param {String} [collectionName] the collection name we wish to filter by. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection names or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionNames = function(collectionName, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - collectionName = args.length ? args.shift() : null; - options = args.length ? args.shift() || {} : {}; - - // Ensure no breaking behavior - if(collectionName != null && typeof collectionName == 'object') { - options = collectionName; - collectionName = null; - } - - // Let's make our own callback to reuse the existing collections info method - self.collectionsInfo(collectionName, function(err, cursor) { - if(err != null) return callback(err, null); - - cursor.toArray(function(err, documents) { - if(err != null) return callback(err, null); - - // List of result documents that have been filtered - var filtered_documents = documents.filter(function(document) { - return !(document.name.indexOf(self.databaseName) == -1 || document.name.indexOf('$') != -1); - }); - - // If we are returning only the names - if(options.namesOnly) { - filtered_documents = filtered_documents.map(function(document) { return document.name }); - } - - // Return filtered items - callback(null, filtered_documents); - }); - }); -}; - -/** - * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you can - * can use it without a callback in the following way. var collection = db.collection('mycollection'); - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws an error if the collection does not exist - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collection = function(collectionName, options, callback) { - var self = this; - if(typeof options === "function") { callback = options; options = {}; } - // Execute safe - - if(options && (options.strict)) { - self.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - if(collections.length == 0) { - return callback(new Error("Collection " + collectionName + " does not exist. Currently in safe mode."), null); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - }); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - if(callback == null) { - throw err; - } else { - return callback(err, null); - } - } - - // If we have no callback return collection object - return callback == null ? collection : callback(null, collection); - } -}; - -/** - * Fetch all collections for the current db. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collections or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collections = function(callback) { - var self = this; - // Let's get the collection names - self.collectionNames(function(err, documents) { - if(err != null) return callback(err, null); - var collections = []; - documents.forEach(function(document) { - collections.push(new Collection(self, document.name.replace(self.databaseName + ".", ''), self.pkFactory)); - }); - // Return the collection objects - callback(null, collections); - }); -}; - -/** - * Evaluate javascript on the server - * - * Options - * - **nolock** {Boolean, default:false}, Tell MongoDB not to block on the evaulation of the javascript. - * - * @param {Code} code javascript to execute on server. - * @param {Object|Array} [parameters] the parameters for the call. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from eval or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.eval = function(code, parameters, options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - parameters = args.length ? args.shift() : parameters; - options = args.length ? args.shift() || {} : {}; - - var finalCode = code; - var finalParameters = []; - // If not a code object translate to one - if(!(finalCode instanceof this.bsonLib.Code)) { - finalCode = new this.bsonLib.Code(finalCode); - } - - // Ensure the parameters are correct - if(parameters != null && parameters.constructor != Array && typeof parameters !== 'function') { - finalParameters = [parameters]; - } else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') { - finalParameters = parameters; - } - - // Create execution selector - var selector = {'$eval':finalCode, 'args':finalParameters}; - // Check if the nolock parameter is passed in - if(options['nolock']) { - selector['nolock'] = options['nolock']; - } - - // Set primary read preference - options.readPreference = ReadPreference.PRIMARY; - - // Execute the eval - this.collection(DbCommand.SYSTEM_COMMAND_COLLECTION).findOne(selector, options, function(err, result) { - if(err) return callback(err); - - if(result && result.ok == 1) { - callback(null, result.retval); - } else if(result) { - callback(new Error("eval failed: " + result.errmsg), null); return; - } else { - callback(err, result); - } - }); -}; - -/** - * Dereference a dbref, against a db - * - * @param {DBRef} dbRef db reference object we wish to resolve. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dereference or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dereference = function(dbRef, callback) { - var db = this; - // If we have a db reference then let's get the db first - if(dbRef.db != null) db = this.db(dbRef.db); - // Fetch the collection and find the reference - var collection = db.collection(dbRef.namespace); - collection.findOne({'_id':dbRef.oid}, function(err, result) { - callback(err, result); - }); -}; - -/** - * Logout user from server, fire off on all connections and remove all auth info - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.logout = function(options, callback) { - var self = this; - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - // Number of connections we need to logout from - var numberOfConnections = this.serverConfig.allRawConnections().length; - - // Let's generate the logout command object - var logoutCommand = DbCommand.logoutCommand(self, {logout:1}, options); - self._executeQueryCommand(logoutCommand, {onAll:true}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - - // Remove the db from auths - self.serverConfig.auth.remove(self.databaseName); - - // Handle any errors - if(err == null && result.documents[0].ok == 1) { - internalCallback(null, true); - } else { - err != null ? internalCallback(err, false) : internalCallback(new Error(result.documents[0].errmsg), false); - } - } - }); -} - -/** - * Authenticate a user against the server. - * authMechanism - * Options - * - **authSource** {String}, The database that the credentials are for, - * different from the name of the current DB, for example admin - * - **authMechanism** {String, default:MONGODB-CR}, The authentication mechanism to use, GSSAPI or MONGODB-CR - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authentication or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.authenticate = function(username, password, options, callback) { - var self = this; - - if(typeof callback === 'undefined') { - callback = options; - options = {}; - } - - // Set default mechanism - if(!options.authMechanism) { - options.authMechanism = 'MONGODB-CR'; - } else if(options.authMechanism != 'GSSAPI' && options.authMechanism != 'MONGODB-CR') { - return callback(new Error("only GSSAPI or MONGODB-CR is supported by authMechanism")); - } - - // the default db to authenticate against is 'this' - // if authententicate is called from a retry context, it may be another one, like admin - var authdb = options.authdb ? options.authdb : self.databaseName; - authdb = options.authSource ? options.authSource : authdb; - - // Callback - var _callback = function(err, result) { - if(self.listeners("authenticated").length > 9) { - self.emit("authenticated", err, result); - } - - // Return to caller - callback(err, result); - } - - // If classic auth delegate to auth command - if(options.authMechanism == 'MONGODB-CR') { - mongodb_cr_authenticate(self, username, password, authdb, options, _callback); - } else if(options.authMechanism == 'GSSAPI') { - // - // Kerberos library is not installed, throw and error - if(hasKerberos == false) { - console.log("========================================================================================"); - console.log("= Please make sure that you install the Kerberos library to use GSSAPI ="); - console.log("= ="); - console.log("= npm install -g kerberos ="); - console.log("= ="); - console.log("= The Kerberos package is not installed by default for simplicities sake ="); - console.log("= and needs to be global install ="); - console.log("========================================================================================"); - throw new Error("Kerberos library not installed"); - } - - if(process.platform == 'win32') { - mongodb_sspi_authenticate(self, username, password, authdb, options, _callback); - } else { - // We have the kerberos library, execute auth process - mongodb_gssapi_authenticate(self, username, password, authdb, options, _callback); - } - } -}; - -/** - * Add a user to the database. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.addUser = function(username, password, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - errorOptions.w = errorOptions.w == null ? 1 : errorOptions.w; - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var userPassword = md5.digest('hex'); - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - // Check if we are inserting the first user - collection.count({}, function(err, count) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Check if the user exists and update i - collection.find({user: username}, {dbName: options['dbName']}).toArray(function(err, documents) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Add command keys - var commandOptions = errorOptions; - commandOptions.dbName = options['dbName']; - commandOptions.upsert = true; - - // We have a user, let's update the password or upsert if not - collection.update({user: username},{$set: {user: username, pwd: userPassword}}, commandOptions, function(err, results) { - if(count == 0 && err) { - callback(null, [{user:username, pwd:userPassword}]); - } else if(err) { - callback(err, null) - } else { - callback(null, [{user:username, pwd:userPassword}]); - } - }); - }); - }); -}; - -/** - * Remove a user from a database - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - collection.findOne({user: username}, {dbName: options['dbName']}, function(err, user) { - if(user != null) { - // Add command keys - var commandOptions = safe; - commandOptions.dbName = options['dbName']; - - collection.remove({user: username}, commandOptions, function(err, result) { - callback(err, true); - }); - } else { - callback(err, false); - } - }); -}; - -/** - * Creates a collection on a server pre-allocating space, need to create f.ex capped collections. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **capped** {Boolean, default:false}, create a capped collection. - * - **size** {Number}, the size of the capped collection in bytes. - * - **max** {Number}, the maximum number of documents in the capped collection. - * - **autoIndexId** {Boolean, default:true}, create an index on the _id field of the document, True by default on MongoDB 2.2 or higher off for version < 2.2. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws an error if collection already exists - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : null; - var self = this; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Check if we have the name - this.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - var found = false; - collections.forEach(function(collection) { - if(collection.name == self.databaseName + "." + collectionName) found = true; - }); - - // If the collection exists either throw an exception (if db in safe mode) or return the existing collection - if(found && options && options.strict) { - return callback(new Error("Collection " + collectionName + " already exists. Currently in safe mode."), null); - } else if(found){ - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - - // Create a new collection and return it - self._executeQueryCommand(DbCommand.createCreateCollectionCommand(self, collectionName, options), {read:false, safe:safe}, function(err, result) { - var document = result.documents[0]; - // If we have no error let's return the collection - if(err == null && document.ok == 1) { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } else { - if (null == err) err = utils.toError(document); - callback(err, null); - } - }); - }); -}; - -/** - * Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server. - * - * @param {Object} selector the command hash to send to the server, ex: {ping:1}. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} - * @api public - */ -Db.prototype.command = function(selector, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - // Set up the options - var cursor = new Cursor(this - , new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, { - limit: -1, timeout: QueryCommand.OPTS_NO_CURSOR_TIMEOUT, dbName: options['dbName'] - }); - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Ensure only commands who support read Prefrences are exeuted otherwise override and use Primary - if(readPreference != false) { - if(selector['group'] || selector['aggregate'] || selector['collStats'] || selector['dbStats'] - || selector['count'] || selector['distinct'] || selector['geoNear'] || selector['geoSearch'] || selector['geoWalk'] - || (selector['mapreduce'] && selector.out == 'inline')) { - // Set the read preference - cursor.setReadPreference(readPreference); - } else { - cursor.setReadPreference(ReadPreference.PRIMARY); - } - } - - // Return the next object - cursor.nextObject(callback); -}; - -/** - * Drop a collection from the database, removing it permanently. New accesses will create a new collection. - * - * @param {String} collectionName the name of the collection we wish to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropCollection = function(collectionName, callback) { - var self = this; - callback || (callback = function(){}); - - // Drop the collection - this._executeQueryCommand(DbCommand.createDropCollectionCommand(this, collectionName), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, true); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Rename a collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} fromCollection the name of the current collection we wish to rename. - * @param {String} toCollection the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from renameCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - callback || (callback = function(){}); - // Execute the command, return the new renamed collection if successful - this._executeQueryCommand(DbCommand.createRenameCollectionCommand(this, fromCollection, toCollection, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, new Collection(self, toCollection, self.pkFactory)); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Return last error message for the given connection, note options can be combined. - * - * Options - * - **fsync** {Boolean, default:false}, option forces the database to fsync all files before returning. - * - **j** {Boolean, default:false}, awaits the journal commit before returning, > MongoDB 2.0. - * - **w** {Number}, until a write operation has been replicated to N servers. - * - **wtimeout** {Number}, number of miliseconds to wait before timing out. - * - * Connection Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Object} [connectionOptions] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from lastError or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.lastError = function(options, connectionOptions, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - connectionOptions = args.length ? args.shift() || {} : {}; - - this._executeQueryCommand(DbCommand.createGetLastErrorCommand(options, this), connectionOptions, function(err, error) { - callback(err, error && error.documents); - }); -}; - -/** - * Legacy method calls. - * - * @ignore - * @api private - */ -Db.prototype.error = Db.prototype.lastError; -Db.prototype.lastStatus = Db.prototype.lastError; - -/** - * Return all errors up to the last time db reset_error_history was called. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from previousErrors or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.previousErrors = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - this._executeQueryCommand(DbCommand.createGetPreviousErrorsCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Runs a command on the database. - * @ignore - * @api private - */ -Db.prototype.executeDbCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, command_hash, options), options, callback); -}; - -/** - * Runs a command on the database as admin. - * @ignore - * @api private - */ -Db.prototype.executeDbAdminCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createAdminDbCommand(this, command_hash), options, callback); -}; - -/** - * Resets the error history of the mongo instance. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from resetErrorHistory or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.resetErrorHistory = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - this._executeQueryCommand(DbCommand.createResetErrorHistoryCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - // Default command options - var commandOptions = {}; - - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute insert command - this._executeInsertCommand(command, commandOptions, function(err, result) { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute insert command - var result = this._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, null); - } -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ensureIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Make sure we don't try to do a write concern without a callback - if(_hasWriteConcern(errorOptions) && callback == null) - throw new Error("Cannot use a writeConcern without a provided callback"); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - var index_name = command.documents[0].name; - - // Default command options - var commandOptions = {}; - // Check if the index allready exists - this.indexInformation(collectionName, function(err, collectionInfo) { - if(err != null) return callback(err, null); - - if(!collectionInfo[index_name]) { - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - if(typeof callback === 'function' - && commandOptions.w < 1 && !commandOptions.fsync && !commandOptions.journal) { - commandOptions.w = 1; - } - - self._executeInsertCommand(command, commandOptions, function(err, result) { - // Only callback if we have one specified - if(typeof callback === 'function') { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - } - }); - } else { - // Execute insert command - var result = self._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, index_name); - } - } else { - if(typeof callback === 'function') return callback(null, index_name); - } - }); -}; - -/** - * Returns the information available on allocated cursors. - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from cursorInfo or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.cursorInfo = function(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() || {} : {}; - - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, {'cursorInfo':1}), options, function(err, result) { - callback(err, result.documents[0]); - }); -}; - -/** - * Drop an index on a collection. - * - * @param {String} collectionName the name of the collection where the command will drop an index. - * @param {String} indexName name of the index to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropIndex = function(collectionName, indexName, callback) { - this._executeQueryCommand(DbCommand.createDropIndexCommand(this, collectionName, indexName), callback); -}; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {String} collectionName the name of the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from reIndex or null if an error occured. - * @api public -**/ -Db.prototype.reIndex = function(collectionName, callback) { - this._executeQueryCommand(DbCommand.createReIndexCommand(this, collectionName), function(err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} collectionName the name of the collection. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from indexInformation or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.indexInformation = function(collectionName, options, callback) { - if(typeof callback === 'undefined') { - if(typeof options === 'undefined') { - callback = collectionName; - collectionName = null; - } else { - callback = options; - } - options = {}; - } - - // If we specified full information - var full = options['full'] == null ? false : options['full']; - // Build selector for the indexes - var selector = collectionName != null ? {ns: (this.databaseName + "." + collectionName)} : {}; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : ReadPreference.PRIMARY; - - // Iterate through all the fields of the index - this.collection(DbCommand.SYSTEM_INDEX_COLLECTION, function(err, collection) { - // Perform the find for the collection - collection.find(selector).setReadPreference(readPreference).toArray(function(err, indexes) { - if(err != null) return callback(err, null); - // Contains all the information - var info = {}; - - // if full defined just return all the indexes directly - if(full) return callback(null, indexes); - - // Process all the indexes - for(var i = 0; i < indexes.length; i++) { - var index = indexes[i]; - // Let's unpack the object - info[index.name] = []; - for(var name in index.key) { - info[index.name].push([name, index.key[name]]); - } - } - - // Return all the indexes - callback(null, info); - }); - }); -}; - -/** - * Drop a database. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropDatabase or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropDatabase = function(callback) { - var self = this; - - this._executeQueryCommand(DbCommand.createDropDatabaseCommand(this), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - callback(null, true); - } else { - if(err) { - callback(err, false); - } else { - callback(utils.toError(result.documents[0]), false); - } - } - }); -}; - -/** - * Get all the db statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from stats or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() || {} : {}; - - // Build command object - var commandObject = { - dbStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.command(commandObject, options, callback); -} - -/** - * @ignore - */ -var __executeQueryCommand = function(self, db_command, options, callback) { - // Options unpacking - var read = options['read'] != null ? options['read'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var onAll = options['onAll'] != null ? options['onAll'] : false; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - - // Correct read preference to default primary if set to false, null or primary - if(!(typeof read == 'object') && read._type == 'ReadPreference') { - read = (read == null || read == 'primary' || read == false) ? ReadPreference.PRIMARY : read; - if(!ReadPreference.isValid(read)) return callback(new Error("Illegal readPreference mode specified, " + read)); - } else if(typeof read == 'object' && read._type == 'ReadPreference') { - if(!read.isValid()) return callback(new Error("Illegal readPreference mode specified, " + read.mode)); - } - - // If we have a read preference set and we are a mongos pass the read preference on to the mongos instance, - if(self.serverConfig.isMongos() && read != null && read != false) { - db_command.setMongosReadPreference(read); - } - - // If we got a callback object - if(typeof callback === 'function' && !onAll) { - // Override connection if we passed in a specific connection - var connection = specifiedConnection != null ? specifiedConnection : null; - - if(connection instanceof Error) return callback(connection, null); - - // Fetch either a reader or writer dependent on the specified read option if no connection - // was passed in - if(connection == null) { - // connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - connection = self.serverConfig.checkoutReader(read); - } - - // Ensure we have a valid connection - /*if(connection == null && self.serverConfig.isAutoReconnect()) { - return self.serverConfig._commandsStore.read_from_writer( - { type: 'query' - , db_command: db_command - , options: options - , callback: callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } else */if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error || connection['message'] != null) { - return callback(connection); - } - - // Exhaust Option - var exhaust = options.exhaust || false; - - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, exhaust, callback); - - // Ensure the connection is valid - if(!connection.isConnected()) { - if(read == ReadPreference.PRIMARY - || read == ReadPreference.PRIMARY_PREFERRED - || (read != null && typeof read == 'object' && read.mode) - || read == null) { - - // Save the command - self.serverConfig._commandsStore.read_from_writer( - { type: 'query' - , db_command: db_command - , options: options - , callback: callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } else { - self.serverConfig._commandsStore.read( - { type: 'query' - , db_command: db_command - , options: options - , callback: callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } - } - - // Write the message out and handle any errors if there are any - connection.write(db_command, function(err) { - if(err != null) { - // Call the handler with an error - if(Array.isArray(db_command)) - self.serverConfig._callHandler(db_command[0].getRequestId(), null, err); - else - self.serverConfig._callHandler(db_command.getRequestId(), null, err); - } - }); - } else if(typeof callback === 'function' && onAll) { - var connections = self.serverConfig.allRawConnections(); - var numberOfEntries = connections.length; - // Go through all the connections - for(var i = 0; i < connections.length; i++) { - // Fetch a connection - var connection = connections[i]; - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, callback); - - // Write the message out - connection.write(db_command, function(err) { - // Adjust the number of entries we need to process - numberOfEntries = numberOfEntries - 1; - // Remove listener - if(err != null) { - // Clean up listener and return error - self.serverConfig._removeHandler(db_command.getRequestId()); - } - - // No more entries to process callback with the error - if(numberOfEntries <= 0) { - callback(err); - } - }); - - // Update the db_command request id - db_command.updateRequestId(); - } - } else { - // Fetch either a reader or writer dependent on the specified read option - // var connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - var connection = self.serverConfig.checkoutReader(read); - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - // Ensure we have a valid connection - if(connection == null || connection instanceof Error || connection['message'] != null) return null; - // Write the message out - connection.write(db_command, function(err) { - if(err != null) { - // Emit the error - self.emit("error", err); - } - }); - } -} - -/** - * Execute db query command (not safe) - * @ignore - * @api private - */ -Db.prototype._executeQueryCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - - // fast fail option used for HA, no retry - var failFast = options['failFast'] != null - ? options['failFast'] - : false; - - // Check if the user force closed the command - if(this._applicationClosed) { - var err = new Error("db closed by application"); - if('function' == typeof callback) { - return callback(err, null); - } else { - throw err; - } - } - - if(this.serverConfig.isDestroyed()) return callback(new Error("Connection was destroyed by application")); - - // Get the configuration - var config = this.serverConfig; - var read = options.read; - - if(!config.canRead(read) && !config.canWrite() && config.isAutoReconnect()) { - if(read == ReadPreference.PRIMARY - || read == ReadPreference.PRIMARY_PREFERRED - || (read != null && typeof read == 'object' && read.mode) - || read == null) { - - // Save the command - self.serverConfig._commandsStore.read_from_writer( - { type: 'query' - , db_command: db_command - , options: options - , callback: callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } else { - self.serverConfig._commandsStore.read( - { type: 'query' - , db_command: db_command - , options: options - , callback: callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } - } else if(!config.canRead(read) && !config.canWrite() && !config.isAutoReconnect()) { - return callback(new Error("no open connections"), null); - } else { - // Execute the command - __executeQueryCommand(self, db_command, options, function (err, result, conn) { - if(callback) callback(err, result, conn); - }); - } -}; - -/** - * @ignore - */ -var __executeInsertCommand = function(self, db_command, options, callback) { - // Always checkout a writer for this kind of operations - var connection = self.serverConfig.checkoutWriter(); - // Get safe mode - var safe = options['safe'] != null ? options['safe'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - - // Ensure we have a valid connection - if(typeof callback === 'function') { - // Ensure we have a valid connection - /*if(connection == null && self.serverConfig.isAutoReconnect()) { - return self.serverConfig._commandsStore.write( - { type:'insert' - , 'db_command':db_command - , 'options':options - , 'callback':callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } else*/ if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - var errorOptions = _getWriteConcern(self, options, callback); - if(errorOptions.w > 0 || errorOptions.w == 'majority' || errorOptions.j || errorOptions.journal || errorOptions.fsync) { - // db command is now an array of commands (original command + lastError) - db_command = [db_command, DbCommand.createGetLastErrorCommand(safe, self)]; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command[1], raw, connection, callback); - } - } - - // If we have no callback and there is no connection - if(connection == null) return null; - if(connection instanceof Error && typeof callback == 'function') return callback(connection, null); - if(connection instanceof Error) return null; - if(connection == null && typeof callback == 'function') return callback(new Error("no primary server found"), null); - - // Ensure we truly are connected - if(!connection.isConnected()) { - return self.serverConfig._commandsStore.write( - { type:'insert' - , 'db_command':db_command - , 'options':options - , 'callback':callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } - - // Write the message out - connection.write(db_command, function(err) { - // Return the callback if it's not a safe operation and the callback is defined - if(typeof callback === 'function' && (safe == null || safe == false)) { - // Perform the callback - callback(err, null); - } else if(typeof callback === 'function') { - // Call the handler with an error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, err); - } else if(typeof callback == 'function' && safe && safe.w == -1) { - // Call the handler with no error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, null); - } else if(!safe || safe.w == -1) { - self.emit("error", err); - } - }); -} - -/** - * Execute an insert Command - * @ignore - * @api private - */ -Db.prototype._executeInsertCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if(callback == null && typeof options === 'function') { - callback = options; - options = {}; - } - - // Ensure options are not null - options = options == null ? {} : options; - - // Check if the user force closed the command - if(this._applicationClosed) { - if(typeof callback == 'function') { - return callback(new Error("db closed by application"), null); - } else { - throw new Error("db closed by application"); - } - } - - if(this.serverConfig.isDestroyed()) return callback(new Error("Connection was destroyed by application")); - - // Get config - var config = self.serverConfig; - // Check if we are connected - if(!config.canWrite() && config.isAutoReconnect()) { - self.serverConfig._commandsStore.write( - { type:'insert' - , 'db_command':db_command - , 'options':options - , 'callback':callback - , db: self - , executeQueryCommand: __executeQueryCommand - , executeInsertCommand: __executeInsertCommand - } - ); - } else if(!config.canWrite() && !config.isAutoReconnect()) { - return callback(new Error("no open connections"), null); - } else { - // Execute write command - __executeInsertCommand(self, db_command, options, callback); - } -} - -/** - * Update command is the same - * @ignore - * @api private - */ -Db.prototype._executeUpdateCommand = Db.prototype._executeInsertCommand; -/** - * Remove command is the same - * @ignore - * @api private - */ -Db.prototype._executeRemoveCommand = Db.prototype._executeInsertCommand; - -/** - * Wrap a Mongo error document into an Error instance. - * Deprecated. Use utils.toError instead. - * - * @ignore - * @api private - * @deprecated - */ -Db.prototype.wrap = utils.toError; - -/** - * Default URL - * - * @classconstant DEFAULT_URL - **/ -Db.DEFAULT_URL = 'mongodb://localhost:27017/default'; - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the db instance or null if an error occured. - * @return {null} - * @api public - */ -Db.connect = function(url, options, callback) { - // Ensure correct mapping of the callback - if(typeof options == 'function') { - callback = options; - options = {}; - } - - // Ensure same behavior as previous version w:0 - if(url.indexOf("safe") == -1 - && url.indexOf("w") == -1 - && url.indexOf("journal") == -1 && url.indexOf("j") == -1 - && url.indexOf("fsync") == -1) options.w = 0; - - // Avoid circular require problem - var MongoClient = require('./mongo_client.js').MongoClient; - // Attempt to connect - MongoClient.connect.call(MongoClient, url, options, callback); -} - -/** - * State of the db connection - * @ignore - */ -Object.defineProperty(Db.prototype, "state", { enumerable: true - , get: function () { - return this.serverConfig._serverState; - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(self.options.w != null || typeof self.options.j == 'boolean' || typeof self.options.journal == 'boolean' || typeof self.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.options); - } else if(self.safe.w != null || typeof self.safe.j == 'boolean' || typeof self.safe.journal == 'boolean' || typeof self.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.safe); - } else if(typeof self.safe == "boolean") { - finalOptions = {w: (self.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Legacy support - * - * @ignore - * @api private - */ -exports.connect = Db.connect; -exports.Db = Db; - -/** - * Remove all listeners to the db instance. - * @ignore - * @api private - */ -Db.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("parseError"); - this.removeAllListeners("poolReady"); - this.removeAllListeners("message"); -} diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/chunk.js b/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/chunk.js deleted file mode 100644 index 572d144653c..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/chunk.js +++ /dev/null @@ -1,213 +0,0 @@ -var Binary = require('bson').Binary, - ObjectID = require('bson').ObjectID; - -/** - * Class for representing a single chunk in GridFS. - * - * @class - * - * @param file {GridStore} The {@link GridStore} object holding this chunk. - * @param mongoObject {object} The mongo object representation of this chunk. - * - * @throws Error when the type of data field for {@link mongoObject} is not - * supported. Currently supported types for data field are instances of - * {@link String}, {@link Array}, {@link Binary} and {@link Binary} - * from the bson module - * - * @see Chunk#buildMongoObject - */ -var Chunk = exports.Chunk = function(file, mongoObject) { - if(!(this instanceof Chunk)) return new Chunk(file, mongoObject); - - this.file = file; - var self = this; - var mongoObjectFinal = mongoObject == null ? {} : mongoObject; - - this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id; - this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n; - this.data = new Binary(); - - if(mongoObjectFinal.data == null) { - } else if(typeof mongoObjectFinal.data == "string") { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data, 'binary', 0); - this.data = new Binary(buffer); - } else if(Array.isArray(mongoObjectFinal.data)) { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data.join(''), 'binary', 0); - this.data = new Binary(buffer); - } else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") { - this.data = mongoObjectFinal.data; - } else if(Buffer.isBuffer(mongoObjectFinal.data)) { - } else { - throw Error("Illegal chunk format"); - } - // Update position - this.internalPosition = 0; -}; - -/** - * Writes a data to this object and advance the read/write head. - * - * @param data {string} the data to write - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.write = function(data, callback) { - this.data.write(data, this.internalPosition); - this.internalPosition = this.data.length(); - if(callback != null) return callback(null, this); - return this; -}; - -/** - * Reads data and advances the read/write head. - * - * @param length {number} The length of data to read. - * - * @return {string} The data read if the given length will not exceed the end of - * the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.read = function(length) { - // Default to full read if no index defined - length = length == null || length == 0 ? this.length() : length; - - if(this.length() - this.internalPosition + 1 >= length) { - var data = this.data.read(this.internalPosition, length); - this.internalPosition = this.internalPosition + length; - return data; - } else { - return ''; - } -}; - -Chunk.prototype.readSlice = function(length) { - if ((this.length() - this.internalPosition) >= length) { - var data = null; - if (this.data.buffer != null) { //Pure BSON - data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length); - } else { //Native BSON - data = new Buffer(length); - length = this.data.readInto(data, this.internalPosition); - } - this.internalPosition = this.internalPosition + length; - return data; - } else { - return null; - } -}; - -/** - * Checks if the read/write head is at the end. - * - * @return {boolean} Whether the read/write head has reached the end of this - * chunk. - */ -Chunk.prototype.eof = function() { - return this.internalPosition == this.length() ? true : false; -}; - -/** - * Reads one character from the data of this chunk and advances the read/write - * head. - * - * @return {string} a single character data read if the the read/write head is - * not at the end of the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.getc = function() { - return this.read(1); -}; - -/** - * Clears the contents of the data in this chunk and resets the read/write head - * to the initial position. - */ -Chunk.prototype.rewind = function() { - this.internalPosition = 0; - this.data = new Binary(); -}; - -/** - * Saves this chunk to the database. Also overwrites existing entries having the - * same id as this chunk. - * - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.save = function(callback) { - var self = this; - - self.file.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) { - if(err) return callback(err); - - if(self.data.length() > 0) { - self.buildMongoObject(function(mongoObject) { - collection.insert(mongoObject, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - } else { - callback(null, self); - } - }); - }); -}; - -/** - * Creates a mongoDB object representation of this chunk. - * - * @param callback {function(Object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this chunk
    - *          'files_id' : , // {number} foreign key to the file collection
    - *          'n' : , // {number} chunk number
    - *          'data' : , // {bson#Binary} the chunk data itself
    - *        }
    - *        
    - * - * @see MongoDB GridFS Chunk Object Structure - */ -Chunk.prototype.buildMongoObject = function(callback) { - var mongoObject = {'_id': this.objectId, - 'files_id': this.file.fileId, - 'n': this.chunkNumber, - 'data': this.data}; - callback(mongoObject); -}; - -/** - * @return {number} the length of the data - */ -Chunk.prototype.length = function() { - return this.data.length(); -}; - -/** - * The position of the read/write head - * @name position - * @lends Chunk# - * @field - */ -Object.defineProperty(Chunk.prototype, "position", { enumerable: true - , get: function () { - return this.internalPosition; - } - , set: function(value) { - this.internalPosition = value; - } -}); - -/** - * The default chunk size - * @constant - */ -Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/grid.js b/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/grid.js deleted file mode 100644 index aa695b723cd..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/grid.js +++ /dev/null @@ -1,103 +0,0 @@ -var GridStore = require('./gridstore').GridStore, - ObjectID = require('bson').ObjectID; - -/** - * A class representation of a simple Grid interface. - * - * @class Represents the Grid. - * @param {Db} db A database instance to interact with. - * @param {String} [fsName] optional different root collection for GridFS. - * @return {Grid} - */ -function Grid(db, fsName) { - - if(!(this instanceof Grid)) return new Grid(db, fsName); - - this.db = db; - this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName; -} - -/** - * Puts binary data to the grid - * - * Options - * - **_id** {Any}, unique id for this file - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @param {Buffer} data buffer with Binary Data. - * @param {Object} [options] the options for the files. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.put = function(data, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // If root is not defined add our default one - options['root'] = options['root'] == null ? this.fsName : options['root']; - - // Return if we don't have a buffer object as data - if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null); - // Get filename if we are using it - var filename = options['filename'] || null; - // Get id if we are using it - var id = options['_id'] || null; - // Create gridstore - var gridStore = new GridStore(this.db, id, filename, "w", options); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - gridStore.write(data, function(err, result) { - if(err) return callback(err, null); - - gridStore.close(function(err, result) { - if(err) return callback(err, null); - callback(null, result); - }) - }) - }) -} - -/** - * Get binary data to the grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.get = function(id, callback) { - // Create gridstore - var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName}); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - // Return the data - gridStore.read(function(err, data) { - return callback(err, data) - }); - }) -} - -/** - * Delete file from grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.delete = function(id, callback) { - // Create gridstore - GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) { - if(err) return callback(err, false); - return callback(null, true); - }); -} - -exports.Grid = Grid; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js b/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js deleted file mode 100644 index 0699e321448..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js +++ /dev/null @@ -1,1482 +0,0 @@ -/** - * @fileOverview GridFS is a tool for MongoDB to store files to the database. - * Because of the restrictions of the object size the database can hold, a - * facility to split a file into several chunks is needed. The {@link GridStore} - * class offers a simplified api to interact with files while managing the - * chunks of split files behind the scenes. More information about GridFS can be - * found here. - */ -var Chunk = require('./chunk').Chunk, - DbCommand = require('../commands/db_command').DbCommand, - ObjectID = require('bson').ObjectID, - Buffer = require('buffer').Buffer, - fs = require('fs'), - timers = require('timers'), - util = require('util'), - inherits = util.inherits, - ReadStream = require('./readstream').ReadStream, - Stream = require('stream'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var REFERENCE_BY_FILENAME = 0, - REFERENCE_BY_ID = 1; - -/** - * A class representation of a file stored in GridFS. - * - * Modes - * - **"r"** - read only. This is the default mode. - * - **"w"** - write in truncate mode. Existing data will be overwriten. - * - **w+"** - write in edit mode. - * - * Options - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @class Represents the GridStore. - * @param {Db} db A database instance to interact with. - * @param {Any} [id] optional unique id for this file - * @param {String} [filename] optional filename for this file, no unique constrain on the field - * @param {String} mode set the mode for this file. - * @param {Object} options optional properties to specify. - * @return {GridStore} - */ -var GridStore = function GridStore(db, id, filename, mode, options) { - if(!(this instanceof GridStore)) return new GridStore(db, id, filename, mode, options); - - var self = this; - this.db = db; - - // Call stream constructor - if(typeof Stream == 'function') { - Stream.call(this); - } else { - // 0.4.X backward compatibility fix - Stream.Stream.call(this); - } - - // Handle options - if(typeof options === 'undefined') options = {}; - // Handle mode - if(typeof mode === 'undefined') { - mode = filename; - filename = undefined; - } else if(typeof mode == 'object') { - options = mode; - mode = filename; - filename = undefined; - } - - if(id instanceof ObjectID) { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } else if(typeof filename == 'undefined') { - this.referenceBy = REFERENCE_BY_FILENAME; - this.filename = id; - if (mode.indexOf('w') != null) { - this.fileId = new ObjectID(); - } - } else { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } - - // Set up the rest - this.mode = mode == null ? "r" : mode; - this.options = options == null ? {} : options; - this.root = this.options['root'] == null ? exports.GridStore.DEFAULT_ROOT_COLLECTION : this.options['root']; - this.position = 0; - // Set default chunk size - this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize']; -} - -/** - * Code for the streaming capabilities of the gridstore object - * Most code from Aaron heckmanns project https://github.com/aheckmann/gridfs-stream - * Modified to work on the gridstore object itself - * @ignore - */ -if(typeof Stream == 'function') { - GridStore.prototype = { __proto__: Stream.prototype } -} else { - // Node 0.4.X compatibility code - GridStore.prototype = { __proto__: Stream.Stream.prototype } -} - -// Move pipe to _pipe -GridStore.prototype._pipe = GridStore.prototype.pipe; - -/** - * Opens the file from the database and initialize this object. Also creates a - * new one if file does not exist. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an **{Error}** object and the second parameter will be null if an error occured. Otherwise, the first parameter will be null and the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.open = function(callback) { - if( this.mode != "w" && this.mode != "w+" && this.mode != "r"){ - callback(new Error("Illegal mode " + this.mode), null); - return; - } - - var self = this; - - if((self.mode == "w" || self.mode == "w+") && self.db.serverConfig.primary != null) { - // Get files collection - self.collection(function(err, collection) { - if(err) return callback(err); - - // Put index on filename - collection.ensureIndex([['filename', 1]], function(err, index) { - if(err) return callback(err); - - // Get chunk collection - self.chunkCollection(function(err, chunkCollection) { - if(err) return callback(err); - - // Ensure index on chunk collection - chunkCollection.ensureIndex([['files_id', 1], ['n', 1]], function(err, index) { - if(err) return callback(err); - _open(self, callback); - }); - }); - }); - }); - } else { - // Open the gridstore - _open(self, callback); - } -}; - -/** - * Hidding the _open function - * @ignore - * @api private - */ -var _open = function(self, callback) { - self.collection(function(err, collection) { - if(err!==null) { - callback(new Error("at collection: "+err), null); - return; - } - - // Create the query - var query = self.referenceBy == REFERENCE_BY_ID ? {_id:self.fileId} : {filename:self.filename}; - query = null == self.fileId && this.filename == null ? null : query; - - // Fetch the chunks - if(query != null) { - collection.find(query, function(err, cursor) { - if(err) return error(err); - - // Fetch the file - cursor.nextObject(function(err, doc) { - if(err) return error(err); - - // Check if the collection for the files exists otherwise prepare the new one - if(doc != null) { - self.fileId = doc._id; - self.filename = doc.filename; - self.contentType = doc.contentType; - self.internalChunkSize = doc.chunkSize; - self.uploadDate = doc.uploadDate; - self.aliases = doc.aliases; - self.length = doc.length; - self.metadata = doc.metadata; - self.internalMd5 = doc.md5; - } else if (self.mode != 'r') { - self.fileId = self.fileId == null ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - } else { - self.length = 0; - var txtId = self.fileId instanceof ObjectID ? self.fileId.toHexString() : self.fileId; - return error(new Error((self.referenceBy == REFERENCE_BY_ID ? txtId : self.filename) + " does not exist", self)); - } - - // Process the mode of the object - if(self.mode == "r") { - nthChunk(self, 0, function(err, chunk) { - if(err) return error(err); - self.currentChunk = chunk; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - }); - } else { - // Write only mode - self.fileId = null == self.fileId ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - - self.chunkCollection(function(err, collection2) { - if(err) return error(err); - - // No file exists set up write mode - if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - } - }); - - // only pass error to callback once - function error (err) { - if(error.err) return; - callback(error.err = err); - } -}; - -/** - * Stores a file from the file system to the GridFS database. - * - * @param {String|Buffer|FileHandle} file the file to store. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.writeFile = function (file, callback) { - var self = this; - if (typeof file === 'string') { - fs.open(file, 'r', 0666, function (err, fd) { - if(err) return callback(err); - self.writeFile(fd, callback); - }); - return; - } - - self.open(function (err, self) { - if(err) return callback(err, self); - - fs.fstat(file, function (err, stats) { - if(err) return callback(err, self); - - var offset = 0; - var index = 0; - var numberOfChunksLeft = Math.min(stats.size / self.chunkSize); - - // Write a chunk - var writeChunk = function() { - fs.read(file, self.chunkSize, offset, 'binary', function(err, data, bytesRead) { - if(err) return callback(err, self); - - offset = offset + bytesRead; - - // Create a new chunk for the data - var chunk = new Chunk(self, {n:index++}); - chunk.write(data, function(err, chunk) { - if(err) return callback(err, self); - - chunk.save(function(err, result) { - if(err) return callback(err, self); - - self.position = self.position + data.length; - - // Point to current chunk - self.currentChunk = chunk; - - if(offset >= stats.size) { - fs.close(file); - self.close(function(err, result) { - if(err) return callback(err, self); - return callback(null, self); - }); - } else { - return processor(writeChunk); - } - }); - }); - }); - } - - // Process the first write - processor(writeChunk); - }); - }); -}; - -/** - * Writes some data. This method will work properly only if initialized with mode - * "w" or "w+". - * - * @param string {string} The data to write. - * @param close {boolean=false} opt_argument Closes this file after writing if - * true. - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - * - * @ignore - * @api private - */ -var writeBuffer = function(self, buffer, close, callback) { - if(typeof close === "function") { callback = close; close = null; } - var finalClose = (close == null) ? false : close; - - if(self.mode[0] != "w") { - callback(new Error((self.referenceBy == REFERENCE_BY_ID ? self.toHexString() : self.filename) + " not opened for writing"), null); - } else { - if(self.currentChunk.position + buffer.length >= self.chunkSize) { - // Write out the current Chunk and then keep writing until we have less data left than a chunkSize left - // to a new chunk (recursively) - var previousChunkNumber = self.currentChunk.chunkNumber; - var leftOverDataSize = self.chunkSize - self.currentChunk.position; - var firstChunkData = buffer.slice(0, leftOverDataSize); - var leftOverData = buffer.slice(leftOverDataSize); - // A list of chunks to write out - var chunksToWrite = [self.currentChunk.write(firstChunkData)]; - // If we have more data left than the chunk size let's keep writing new chunks - while(leftOverData.length >= self.chunkSize) { - // Create a new chunk and write to it - var newChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - var firstChunkData = leftOverData.slice(0, self.chunkSize); - leftOverData = leftOverData.slice(self.chunkSize); - // Update chunk number - previousChunkNumber = previousChunkNumber + 1; - // Write data - newChunk.write(firstChunkData); - // Push chunk to save list - chunksToWrite.push(newChunk); - } - - // Set current chunk with remaining data - self.currentChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - // If we have left over data write it - if(leftOverData.length > 0) self.currentChunk.write(leftOverData); - - // Update the position for the gridstore - self.position = self.position + buffer.length; - // Total number of chunks to write - var numberOfChunksToWrite = chunksToWrite.length; - // Write out all the chunks and then return - for(var i = 0; i < chunksToWrite.length; i++) { - var chunk = chunksToWrite[i]; - chunk.save(function(err, result) { - if(err) return callback(err); - - numberOfChunksToWrite = numberOfChunksToWrite - 1; - - if(numberOfChunksToWrite <= 0) { - return callback(null, self); - } - }) - } - } else { - // Update the position for the gridstore - self.position = self.position + buffer.length; - // We have less data than the chunk size just write it and callback - self.currentChunk.write(buffer); - callback(null, self); - } - } -}; - -/** - * Creates a mongoDB object representation of this object. - * - * @param callback {function(object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this file
    - *          'filename' : , // {string} name for this file
    - *          'contentType' : , // {string} mime type for this file
    - *          'length' : , // {number} size of this file?
    - *          'chunksize' : , // {number} chunk size used by this file
    - *          'uploadDate' : , // {Date}
    - *          'aliases' : , // {array of string}
    - *          'metadata' : , // {string}
    - *        }
    - *        
    - * - * @ignore - * @api private - */ -var buildMongoObject = function(self, callback) { - // // Keeps the final chunk number - // var chunkNumber = 0; - // var previousChunkSize = 0; - // // Get the correct chunk Number, if we have an empty chunk return the previous chunk number - // if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) { - // chunkNumber = self.currentChunk.chunkNumber - 1; - // } else { - // chunkNumber = self.currentChunk.chunkNumber; - // previousChunkSize = self.currentChunk.position; - // } - - // // Calcuate the length - // var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0; - var mongoObject = { - '_id': self.fileId, - 'filename': self.filename, - 'contentType': self.contentType, - 'length': self.position ? self.position : 0, - 'chunkSize': self.chunkSize, - 'uploadDate': self.uploadDate, - 'aliases': self.aliases, - 'metadata': self.metadata - }; - - var md5Command = {filemd5:self.fileId, root:self.root}; - self.db.command(md5Command, function(err, results) { - mongoObject.md5 = results.md5; - callback(mongoObject); - }); -}; - -/** - * Saves this file to the database. This will overwrite the old entry if it - * already exists. This will work properly only if mode was initialized to - * "w" or "w+". - * - * @param {Function} callback this will be called after executing this method. Passes an **{Error}** object to the first parameter and null to the second if an error occured. Otherwise, passes null to the first and a reference to this object to the second. - * @return {null} - * @api public - */ -GridStore.prototype.close = function(callback) { - var self = this; - - if(self.mode[0] == "w") { - if(self.currentChunk != null && self.currentChunk.position > 0) { - self.currentChunk.save(function(err, chunk) { - if(err && typeof callback == 'function') return callback(err); - - self.collection(function(err, files) { - if(err && typeof callback == 'function') return callback(err); - - // Build the mongo object - if(self.uploadDate != null) { - files.remove({'_id':self.fileId}, {safe:true}, function(err, collection) { - if(err && typeof callback == 'function') return callback(err); - - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - if(typeof callback == 'function') - callback(err, mongoObject); - }); - }); - }); - } else { - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - if(typeof callback == 'function') - callback(err, mongoObject); - }); - }); - } - }); - }); - } else { - self.collection(function(err, files) { - if(err && typeof callback == 'function') return callback(err); - - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - if(typeof callback == 'function') - callback(err, mongoObject); - }); - }); - }); - } - } else if(self.mode[0] == "r") { - if(typeof callback == 'function') - callback(null, null); - } else { - if(typeof callback == 'function') - callback(new Error("Illegal mode " + self.mode), null); - } -}; - -/** - * Gets the nth chunk of this file. - * - * @param chunkNumber {number} The nth chunk to retrieve. - * @param callback {function(*, Chunk|object)} This will be called after - * executing this method. null will be passed to the first parameter while - * a new {@link Chunk} instance will be passed to the second parameter if - * the chunk was found or an empty object {} if not. - * - * @ignore - * @api private - */ -var nthChunk = function(self, chunkNumber, callback) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.find({'files_id':self.fileId, 'n':chunkNumber}, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, chunk) { - if(err) return callback(err); - - var finalChunk = chunk == null ? {} : chunk; - callback(null, new Chunk(self, finalChunk)); - }); - }); - }); -}; - -/** - * - * @ignore - * @api private - */ -GridStore.prototype._nthChunk = function(chunkNumber, callback) { - nthChunk(this, chunkNumber, callback); -} - -/** - * @return {Number} The last chunk number of this file. - * - * @ignore - * @api private - */ -var lastChunkNumber = function(self) { - return Math.floor(self.length/self.chunkSize); -}; - -/** - * Retrieve this file's chunks collection. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.chunkCollection = function(callback) { - this.db.collection((this.root + ".chunks"), callback); -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param callback {function(*, boolean)} This will be called after this method - * executes. Passes null to the first and true to the second argument. - * - * @ignore - * @api private - */ -var deleteChunks = function(self, callback) { - if(self.fileId != null) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err, false); - collection.remove({'files_id':self.fileId}, {safe:true}, function(err, result) { - if(err) return callback(err, false); - callback(null, true); - }); - }); - } else { - callback(null, true); - } -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param {Function} callback this will be called after this method executes. Passes null to the first and true to the second argument. - * @return {null} - * @api public - */ -GridStore.prototype.unlink = function(callback) { - var self = this; - deleteChunks(this, function(err) { - if(err!==null) { - err.message = "at deleteChunks: " + err.message; - return callback(err); - } - - self.collection(function(err, collection) { - if(err!==null) { - err.message = "at collection: " + err.message; - return callback(err); - } - - collection.remove({'_id':self.fileId}, {safe:true}, function(err) { - callback(err, self); - }); - }); - }); -}; - -/** - * Retrieves the file collection associated with this object. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.collection = function(callback) { - this.db.collection(this.root + ".files", callback); -}; - -/** - * Reads the data of this file. - * - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Function} callback This will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.prototype.readlines = function(separator, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - separator = args.length ? args.shift() : "\n"; - - this.read(function(err, data) { - if(err) return callback(err); - - var items = data.toString().split(separator); - items = items.length > 0 ? items.splice(0, items.length - 1) : []; - for(var i = 0; i < items.length; i++) { - items[i] = items[i] + separator; - } - - callback(null, items); - }); -}; - -/** - * Deletes all the chunks of this file in the database if mode was set to "w" or - * "w+" and resets the read/write head to the initial position. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.rewind = function(callback) { - var self = this; - - if(this.currentChunk.chunkNumber != 0) { - if(this.mode[0] == "w") { - deleteChunks(self, function(err, gridStore) { - if(err) return callback(err); - self.currentChunk = new Chunk(self, {'n': 0}); - self.position = 0; - callback(null, self); - }); - } else { - self.currentChunk(0, function(err, chunk) { - if(err) return callback(err); - self.currentChunk = chunk; - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - }); - } - } else { - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - } -}; - -/** - * Retrieves the contents of this file and advances the read/write head. Works with Buffers only. - * - * There are 3 signatures for this method: - * - * (callback) - * (length, callback) - * (length, buffer, callback) - * - * @param {Number} [length] the number of characters to read. Reads all the characters from the read/write head to the EOF if not specified. - * @param {String|Buffer} [buffer] a string to hold temporary data. This is used for storing the string data read so far when recursively calling this method. - * @param {Function} callback this will be called after this method is executed. null will be passed to the first parameter and a string containing the contents of the buffer concatenated with the contents read from this file will be passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.read = function(length, buffer, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - length = args.length ? args.shift() : null; - buffer = args.length ? args.shift() : null; - - // The data is a c-terminated string and thus the length - 1 - var finalLength = length == null ? self.length - self.position : length; - var finalBuffer = buffer == null ? new Buffer(finalLength) : buffer; - // Add a index to buffer to keep track of writing position or apply current index - finalBuffer._index = buffer != null && buffer._index != null ? buffer._index : 0; - - if((self.currentChunk.length() - self.currentChunk.position + finalBuffer._index) >= finalLength) { - var slice = self.currentChunk.readSlice(finalLength - finalBuffer._index); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update internal position - self.position = self.position + finalBuffer.length; - // Check if we don't have a file at all - if(finalLength == 0 && finalBuffer.length == 0) return callback(new Error("File does not exist"), null); - // Else return data - callback(null, finalBuffer); - } else { - var slice = self.currentChunk.readSlice(self.currentChunk.length() - self.currentChunk.position); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update index position - finalBuffer._index += slice.length; - - // Load next chunk and read more - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) return callback(err); - - if(chunk.length() > 0) { - self.currentChunk = chunk; - self.read(length, finalBuffer, callback); - } else { - if (finalBuffer._index > 0) { - callback(null, finalBuffer) - } else { - callback(new Error("no chunks found for file, possibly corrupt"), null); - } - } - }); - } -} - -/** - * Retrieves the position of the read/write head of this file. - * - * @param {Function} callback This gets called after this method terminates. null is passed to the first parameter and the position is passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.tell = function(callback) { - callback(null, this.position); -}; - -/** - * Moves the read/write head to a new location. - * - * There are 3 signatures for this method - * - * Seek Location Modes - * - **GridStore.IO_SEEK_SET**, **(default)** set the position from the start of the file. - * - **GridStore.IO_SEEK_CUR**, set the position from the current position in the file. - * - **GridStore.IO_SEEK_END**, set the position from the end of the file. - * - * @param {Number} [position] the position to seek to - * @param {Number} [seekLocation] seek mode. Use one of the Seek Location modes. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.seek = function(position, seekLocation, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - seekLocation = args.length ? args.shift() : null; - - var seekLocationFinal = seekLocation == null ? exports.GridStore.IO_SEEK_SET : seekLocation; - var finalPosition = position; - var targetPosition = 0; - - // Calculate the position - if(seekLocationFinal == exports.GridStore.IO_SEEK_CUR) { - targetPosition = self.position + finalPosition; - } else if(seekLocationFinal == exports.GridStore.IO_SEEK_END) { - targetPosition = self.length + finalPosition; - } else { - targetPosition = finalPosition; - } - - // Get the chunk - var newChunkNumber = Math.floor(targetPosition/self.chunkSize); - if(newChunkNumber != self.currentChunk.chunkNumber) { - var seekChunk = function() { - nthChunk(self, newChunkNumber, function(err, chunk) { - self.currentChunk = chunk; - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(err, self); - }); - }; - - if(self.mode[0] == 'w') { - self.currentChunk.save(function(err) { - if(err) return callback(err); - seekChunk(); - }); - } else { - seekChunk(); - } - } else { - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(null, self); - } -}; - -/** - * Verify if the file is at EOF. - * - * @return {Boolean} true if the read/write head is at the end of this file. - * @api public - */ -GridStore.prototype.eof = function() { - return this.position == this.length ? true : false; -}; - -/** - * Retrieves a single character from this file. - * - * @param {Function} callback this gets called after this method is executed. Passes null to the first parameter and the character read to the second or null to the second if the read/write head is at the end of the file. - * @return {null} - * @api public - */ -GridStore.prototype.getc = function(callback) { - var self = this; - - if(self.eof()) { - callback(null, null); - } else if(self.currentChunk.eof()) { - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - self.currentChunk = chunk; - self.position = self.position + 1; - callback(err, self.currentChunk.getc()); - }); - } else { - self.position = self.position + 1; - callback(null, self.currentChunk.getc()); - } -}; - -/** - * Writes a string to the file with a newline character appended at the end if - * the given string does not have one. - * - * @param {String} string the string to write. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.puts = function(string, callback) { - var finalString = string.match(/\n$/) == null ? string + "\n" : string; - this.write(finalString, callback); -}; - -/** - * Returns read stream based on this GridStore file - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @param {Boolean} autoclose if true current GridStore will be closed when EOF and 'close' event will be fired - * @return {null} - * @api public - */ -GridStore.prototype.stream = function(autoclose) { - return new ReadStream(autoclose, this); -}; - -/** -* The collection to be used for holding the files and chunks collection. -* -* @classconstant DEFAULT_ROOT_COLLECTION -**/ -GridStore.DEFAULT_ROOT_COLLECTION = 'fs'; - -/** -* Default file mime type -* -* @classconstant DEFAULT_CONTENT_TYPE -**/ -GridStore.DEFAULT_CONTENT_TYPE = 'binary/octet-stream'; - -/** -* Seek mode where the given length is absolute. -* -* @classconstant IO_SEEK_SET -**/ -GridStore.IO_SEEK_SET = 0; - -/** -* Seek mode where the given length is an offset to the current read/write head. -* -* @classconstant IO_SEEK_CUR -**/ -GridStore.IO_SEEK_CUR = 1; - -/** -* Seek mode where the given length is an offset to the end of the file. -* -* @classconstant IO_SEEK_END -**/ -GridStore.IO_SEEK_END = 2; - -/** - * Checks if a file exists in the database. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file to look for. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes true to the second if the file exists and false otherwise. - * @return {null} - * @api public - */ -GridStore.exist = function(db, fileIdObject, rootCollection, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - - // Fetch collection - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - db.collection(rootCollectionFinal + ".files", function(err, collection) { - if(err) return callback(err); - - // Build query - var query = (typeof fileIdObject == 'string' || Object.prototype.toString.call(fileIdObject) == '[object RegExp]' ) - ? {'filename':fileIdObject} - : {'_id':fileIdObject}; // Attempt to locate file - - collection.find(query, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, item) { - if(err) return callback(err); - callback(null, item == null ? false : true); - }); - }); - }); -}; - -/** - * Gets the list of files stored in the GridFS. - * - * @param {Db} db the database to query. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes an array of strings containing the names of the files. - * @return {null} - * @api public - */ -GridStore.list = function(db, rootCollection, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure we have correct values - if(rootCollection != null && typeof rootCollection == 'object') { - options = rootCollection; - rootCollection = null; - } - - // Check if we are returning by id not filename - var byId = options['id'] != null ? options['id'] : false; - // Fetch item - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - var items = []; - db.collection((rootCollectionFinal + ".files"), function(err, collection) { - if(err) return callback(err); - - collection.find(function(err, cursor) { - if(err) return callback(err); - - cursor.each(function(err, item) { - if(item != null) { - items.push(byId ? item._id : item.filename); - } else { - callback(err, items); - } - }); - }); - }); -}; - -/** - * Reads the contents of a file. - * - * This method has the following signatures - * - * (db, name, callback) - * (db, name, length, callback) - * (db, name, length, offset, callback) - * (db, name, length, offset, options, callback) - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {Number} [length] the size of data to read. - * @param {Number} [offset] the offset from the head of the file of which to start reading from. - * @param {Object} [options] the options for the file. - * @param {Function} callback this will be called after this method executes. A string with an error message will be passed to the first parameter when the length and offset combination exceeds the length of the file while an Error object will be passed if other forms of error occured, otherwise, a string is passed. The second parameter will contain the data read if successful or null if an error occured. - * @return {null} - * @api public - */ -GridStore.read = function(db, name, length, offset, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - length = args.length ? args.shift() : null; - offset = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - // Make sure we are not reading out of bounds - if(offset && offset >= gridStore.length) return callback("offset larger than size of file", null); - if(length && length > gridStore.length) return callback("length is larger than the size of the file", null); - if(offset && length && (offset + length) > gridStore.length) return callback("offset and length is larger than the size of the file", null); - - if(offset != null) { - gridStore.seek(offset, function(err, gridStore) { - if(err) return callback(err); - gridStore.read(length, callback); - }); - } else { - gridStore.read(length, callback); - } - }); -}; - -/** - * Reads the data of this file. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Object} [options] file options. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.readlines = function(db, name, separator, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - separator = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - var finalSeperator = separator == null ? "\n" : separator; - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - gridStore.readlines(finalSeperator, callback); - }); -}; - -/** - * Deletes the chunks and metadata information of a file from GridFS. - * - * @param {Db} db the database to interact with. - * @param {String|Array} names the name/names of the files to delete. - * @param {Object} [options] the options for the files. - * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.unlink = function(db, names, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : null; - - if(names.constructor == Array) { - var tc = 0; - for(var i = 0; i < names.length; i++) { - ++tc; - self.unlink(db, names[i], function(result) { - if(--tc == 0) { - callback(null, self); - } - }); - } - } else { - new GridStore(db, names, "w", options).open(function(err, gridStore) { - if(err) return callback(err); - deleteChunks(gridStore, function(err, result) { - if(err) return callback(err); - gridStore.collection(function(err, collection) { - if(err) return callback(err); - collection.remove({'_id':gridStore.fileId}, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - }); - }); - } -}; - -/** - * Returns the current chunksize of the file. - * - * @field chunkSize - * @type {Number} - * @getter - * @setter - * @property return number of bytes in the current chunkSize. - */ -Object.defineProperty(GridStore.prototype, "chunkSize", { enumerable: true - , get: function () { - return this.internalChunkSize; - } - , set: function(value) { - if(!(this.mode[0] == "w" && this.position == 0 && this.uploadDate == null)) { - this.internalChunkSize = this.internalChunkSize; - } else { - this.internalChunkSize = value; - } - } -}); - -/** - * The md5 checksum for this file. - * - * @field md5 - * @type {Number} - * @getter - * @setter - * @property return this files md5 checksum. - */ -Object.defineProperty(GridStore.prototype, "md5", { enumerable: true - , get: function () { - return this.internalMd5; - } -}); - -/** - * GridStore Streaming methods - * Handles the correct return of the writeable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "writable", { enumerable: true - , get: function () { - if(this._writeable == null) { - this._writeable = this.mode != null && this.mode.indexOf("w") != -1; - } - // Return the _writeable - return this._writeable; - } - , set: function(value) { - this._writeable = value; - } -}); - -/** - * Handles the correct return of the readable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "readable", { enumerable: true - , get: function () { - if(this._readable == null) { - this._readable = this.mode != null && this.mode.indexOf("r") != -1; - } - return this._readable; - } - , set: function(value) { - this._readable = value; - } -}); - -GridStore.prototype.paused; - -/** - * Handles the correct setting of encoding for the stream - * @ignore - */ -GridStore.prototype.setEncoding = fs.ReadStream.prototype.setEncoding; - -/** - * Handles the end events - * @ignore - */ -GridStore.prototype.end = function end(data) { - var self = this; - // allow queued data to write before closing - if(!this.writable) return; - this.writable = false; - - if(data) { - this._q.push(data); - } - - this.on('drain', function () { - self.close(function (err) { - if (err) return _error(self, err); - self.emit('close'); - }); - }); - - _flush(self); -} - -/** - * Handles the normal writes to gridstore - * @ignore - */ -var _writeNormal = function(self, data, close, callback) { - // If we have a buffer write it using the writeBuffer method - if(Buffer.isBuffer(data)) { - return writeBuffer(self, data, close, callback); - } else { - // Wrap the string in a buffer and write - return writeBuffer(self, new Buffer(data, 'binary'), close, callback); - } -} - -/** - * Writes some data. This method will work properly only if initialized with mode "w" or "w+". - * - * @param {String|Buffer} data the data to write. - * @param {Boolean} [close] closes this file after writing if set to true. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.write = function write(data, close, callback) { - // If it's a normal write delegate the call - if(typeof close == 'function' || typeof callback == 'function') { - return _writeNormal(this, data, close, callback); - } - - // Otherwise it's a stream write - var self = this; - if (!this.writable) { - throw new Error('GridWriteStream is not writable'); - } - - // queue data until we open. - if (!this._opened) { - // Set up a queue to save data until gridstore object is ready - this._q = []; - _openStream(self); - this._q.push(data); - return false; - } - - // Push data to queue - this._q.push(data); - _flush(this); - // Return write successful - return true; -} - -/** - * Handles the destroy part of a stream - * @ignore - */ -GridStore.prototype.destroy = function destroy() { - // close and do not emit any more events. queued data is not sent. - if(!this.writable) return; - this.readable = false; - if(this.writable) { - this.writable = false; - this._q.length = 0; - this.emit('close'); - } -} - -/** - * Handles the destroySoon part of a stream - * @ignore - */ -GridStore.prototype.destroySoon = function destroySoon() { - // as soon as write queue is drained, destroy. - // may call destroy immediately if no data is queued. - if(!this._q.length) { - return this.destroy(); - } - this._destroying = true; -} - -/** - * Handles the pipe part of the stream - * @ignore - */ -GridStore.prototype.pipe = function(destination, options) { - var self = this; - // Open the gridstore - this.open(function(err, result) { - if(err) _errorRead(self, err); - if(!self.readable) return; - // Set up the pipe - self._pipe(destination, options); - // Emit the stream is open - self.emit('open'); - // Read from the stream - _read(self); - }) -} - -/** - * Internal module methods - * @ignore - */ -var _read = function _read(self) { - if (!self.readable || self.paused || self.reading) { - return; - } - - self.reading = true; - var stream = self._stream = self.stream(); - stream.paused = self.paused; - - stream.on('data', function (data) { - if (self._decoder) { - var str = self._decoder.write(data); - if (str.length) self.emit('data', str); - } else { - self.emit('data', data); - } - }); - - stream.on('end', function (data) { - self.emit('end', data); - }); - - stream.on('error', function (data) { - _errorRead(self, data); - }); - - stream.on('close', function (data) { - self.emit('close', data); - }); - - self.pause = function () { - // native doesn't always pause. - // bypass its pause() method to hack it - self.paused = stream.paused = true; - } - - self.resume = function () { - if(!self.paused) return; - - self.paused = false; - stream.resume(); - self.readable = stream.readable; - } - - self.destroy = function () { - self.readable = false; - stream.destroy(); - } -} - -/** - * pause - * @ignore - */ -GridStore.prototype.pause = function pause () { - // Overridden when the GridStore opens. - this.paused = true; -} - -/** - * resume - * @ignore - */ -GridStore.prototype.resume = function resume () { - // Overridden when the GridStore opens. - this.paused = false; -} - -/** - * Internal module methods - * @ignore - */ -var _flush = function _flush(self, _force) { - if (!self._opened) return; - if (!_force && self._flushing) return; - self._flushing = true; - - // write the entire q to gridfs - if (!self._q.length) { - self._flushing = false; - self.emit('drain'); - - if(self._destroying) { - self.destroy(); - } - return; - } - - self.write(self._q.shift(), function (err, store) { - if (err) return _error(self, err); - self.emit('progress', store.position); - _flush(self, true); - }); -} - -var _openStream = function _openStream (self) { - if(self._opening == true) return; - self._opening = true; - - // Open the store - self.open(function (err, gridstore) { - if (err) return _error(self, err); - self._opened = true; - self.emit('open'); - _flush(self); - }); -} - -var _error = function _error(self, err) { - self.destroy(); - self.emit('error', err); -} - -var _errorRead = function _errorRead (self, err) { - self.readable = false; - self.emit('error', err); -} - -/** - * @ignore - * @api private - */ -exports.GridStore = GridStore; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/readstream.js b/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/readstream.js deleted file mode 100644 index 8ff99731ea0..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/gridfs/readstream.js +++ /dev/null @@ -1,193 +0,0 @@ -var Stream = require('stream').Stream, - timers = require('timers'), - util = require('util'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * ReadStream - * - * Returns a stream interface for the **file**. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @class Represents a GridFS File Stream. - * @param {Boolean} autoclose automatically close file when the stream reaches the end. - * @param {GridStore} cursor a cursor object that the stream wraps. - * @return {ReadStream} - */ -function ReadStream(autoclose, gstore) { - if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore); - Stream.call(this); - - this.autoclose = !!autoclose; - this.gstore = gstore; - - this.finalLength = gstore.length - gstore.position; - this.completedLength = 0; - this.currentChunkNumber = gstore.currentChunk.chunkNumber; - - this.paused = false; - this.readable = true; - this.pendingChunk = null; - this.executing = false; - - // Calculate the number of chunks - this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize); - - // This seek start position inside the current chunk - this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize); - - var self = this; - processor(function() { - self._execute(); - }); -}; - -/** - * Inherit from Stream - * @ignore - * @api private - */ -ReadStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -ReadStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -ReadStream.prototype.paused; - -/** - * @ignore - * @api private - */ -ReadStream.prototype._execute = function() { - if(this.paused === true || this.readable === false) { - return; - } - - var gstore = this.gstore; - var self = this; - // Set that we are executing - this.executing = true; - - var last = false; - var toRead = 0; - - if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) { - self.executing = false; - last = true; - } - - // Data setup - var data = null; - - // Read a slice (with seek set if none) - if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition); - this.seekStartPosition = 0; - } else { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length()); - } - - // Return the data - if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) { - self.currentChunkNumber = self.currentChunkNumber + 1; - self.completedLength += data.length; - self.pendingChunk = null; - self.emit("data", data); - } - - if(last === true) { - self.readable = false; - self.emit("end"); - - if(self.autoclose === true) { - if(gstore.mode[0] == "w") { - gstore.close(function(err, doc) { - if (err) { - self.emit("error", err); - return; - } - self.readable = false; - self.emit("close", doc); - }); - } else { - self.readable = false; - self.emit("close"); - } - } - } else { - gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) { - self.readable = false; - self.emit("error", err); - self.executing = false; - return; - } - - self.pendingChunk = chunk; - if(self.paused === true) { - self.executing = false; - return; - } - - gstore.currentChunk = self.pendingChunk; - self._execute(); - }); - } -}; - -/** - * Pauses this stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.pause = function() { - if(!this.executing) { - this.paused = true; - } -}; - -/** - * Destroys the stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.destroy = function() { - this.readable = false; - // Emit close event - this.emit("close"); -}; - -/** - * Resumes this stream. - * - * @ignore - * @api public - */ -ReadStream.prototype.resume = function() { - if(this.paused === false || !this.readable) { - return; - } - - this.paused = false; - var self = this; - processor(function() { - self._execute(); - }); -}; - -exports.ReadStream = ReadStream; diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/index.js b/frontend/express/node_modules/mongodb/lib/mongodb/index.js deleted file mode 100644 index b2fdadf84a0..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/index.js +++ /dev/null @@ -1,66 +0,0 @@ -try { - exports.BSONPure = require('bson').BSONPure; - exports.BSONNative = require('bson').BSONNative; -} catch(err) { - // do nothing -} - -[ 'commands/base_command' - , 'admin' - , 'collection' - , 'connection/read_preference' - , 'connection/connection' - , 'connection/server' - , 'connection/mongos' - , 'connection/repl_set/repl_set' - , 'mongo_client' - , 'cursor' - , 'db' - , 'mongo_client' - , 'gridfs/grid' - , 'gridfs/chunk' - , 'gridfs/gridstore'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// backwards compat -exports.ReplSetServers = exports.ReplSet; -// Add BSON Classes -exports.Binary = require('bson').Binary; -exports.Code = require('bson').Code; -exports.DBRef = require('bson').DBRef; -exports.Double = require('bson').Double; -exports.Long = require('bson').Long; -exports.MinKey = require('bson').MinKey; -exports.MaxKey = require('bson').MaxKey; -exports.ObjectID = require('bson').ObjectID; -exports.Symbol = require('bson').Symbol; -exports.Timestamp = require('bson').Timestamp; -// Add BSON Parser -exports.BSON = require('bson').BSONPure.BSON; - -// Get the Db object -var Db = require('./db').Db; -// Set up the connect function -var connect = Db.connect; -var obj = connect; -// Map all values to the exports value -for(var name in exports) { - obj[name] = exports[name]; -} - -// Add the pure and native backward compatible functions -exports.pure = exports.native = function() { - return obj; -} - -// Map all values to the exports value -for(var name in exports) { - connect[name] = exports[name]; -} - -// Set our exports to be the connect function -module.exports = connect; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/mongo_client.js b/frontend/express/node_modules/mongodb/lib/mongodb/mongo_client.js deleted file mode 100644 index 1593fd7eabd..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/mongo_client.js +++ /dev/null @@ -1,369 +0,0 @@ -var Db = require('./db').Db - , Server = require('./connection/server').Server - , Mongos = require('./connection/mongos').Mongos - , ReplSet = require('./connection/repl_set/repl_set').ReplSet - , ReadPreference = require('./connection/read_preference').ReadPreference - , inherits = require('util').inherits - , EventEmitter = require('events').EventEmitter - , parse = require('./connection/url_parser').parse; - -/** - * Create a new MongoClient instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a MongoClient - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function MongoClient(serverConfig, options) { - if(serverConfig != null) { - options = options == null ? {} : options; - // If no write concern is set set the default to w:1 - if(options != null && !options.journal && !options.w && !options.fsync) { - options.w = 1; - } - - // The internal db instance we are wrapping - this._db = new Db('test', serverConfig, options); - } -} - -/** - * @ignore - */ -inherits(MongoClient, EventEmitter); - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.connect = function(url, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - MongoClient.connect(url, options, function(err, db) { - if(err) return callback(err, db); - // Emit open and perform callback - self.emit("open", err, db); - callback(err, db); - }); -} - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the connected mongoclient or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.open = function(callback) { - // Self reference - var self = this; - // Open the db - this._db.open(function(err, db) { - if(err) return callback(err, null); - - // Emit open event - self.emit("open", err, db); - // Callback - callback(null, self); - }) -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the close method or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.close = function(callback) { - this._db.close(callback); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -MongoClient.prototype.db = function(dbName) { - return this._db.db(dbName); -} - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.connect = function(url, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = typeof args[args.length - 1] == 'function' ? args.pop() : null; - options = args.length ? args.shift() : null; - options = options || {}; - - // Set default empty server options - var serverOptions = options.server || {}; - var mongosOptions = options.mongos || {}; - var replSetServersOptions = options.replSet || options.replSetServers || {}; - var dbOptions = options.db || {}; - - // If callback is null throw an exception - if(callback == null) throw new Error("no callback function provided"); - - // Parse the string - var object = parse(url, options); - // Merge in any options for db in options object - if(dbOptions) { - for(var name in dbOptions) object.db_options[name] = dbOptions[name]; - } - - // Added the url to the options - object.db_options.url = url; - - // Merge in any options for server in options object - if(serverOptions) { - for(var name in serverOptions) object.server_options[name] = serverOptions[name]; - } - - // Merge in any replicaset server options - if(replSetServersOptions) { - for(var name in replSetServersOptions) object.rs_options[name] = replSetServersOptions[name]; - } - - // Merge in any replicaset server options - if(mongosOptions) { - for(var name in mongosOptions) object.mongos_options[name] = mongosOptions[name]; - } - - // We need to ensure that the list of servers are only either direct members or mongos - // they cannot be a mix of monogs and mongod's - var totalNumberOfServers = object.servers.length; - var totalNumberOfMongosServers = 0; - var totalNumberOfMongodServers = 0; - var serverConfig = null; - var errorServers = {}; - - // Failure modes - if(object.servers.length == 0) throw new Error("connection string must contain at least one seed host"); - - // If we have no db setting for the native parser try to set the c++ one first - object.db_options.native_parser = _setNativeParser(object.db_options); - // If no auto_reconnect is set, set it to true as default for single servers - if(typeof object.server_options.auto_reconnect != 'boolean') { - object.server_options.auto_reconnect = true; - } - - // If we have more than a server, it could be replicaset or mongos list - // need to verify that it's one or the other and fail if it's a mix - // Connect to all servers and run ismaster - for(var i = 0; i < object.servers.length; i++) { - // Set up socket options - var _server_options = {poolSize:1, socketOptions:{connectTimeoutMS:1000}, auto_reconnect:false}; - - // Ensure we have ssl setup for the servers - if(object.rs_options.ssl) { - _server_options.ssl = object.rs_options.ssl; - _server_options.sslValidate = object.rs_options.sslValidate; - _server_options.sslCA = object.rs_options.sslCA; - _server_options.sslCert = object.rs_options.sslCert; - _server_options.sslKey = object.rs_options.sslKey; - _server_options.sslPass = object.rs_options.sslPass; - } else if(object.server_options.ssl) { - _server_options.ssl = object.server_options.ssl; - _server_options.sslValidate = object.server_options.sslValidate; - _server_options.sslCA = object.server_options.sslCA; - _server_options.sslCert = object.server_options.sslCert; - _server_options.sslKey = object.server_options.sslKey; - _server_options.sslPass = object.server_options.sslPass; - } - - // Set up the Server object - var _server = object.servers[i].domain_socket - ? new Server(object.servers[i].domain_socket, _server_options) - : new Server(object.servers[i].host, object.servers[i].port, _server_options); - - var connectFunction = function(__server) { - // Attempt connect - new Db(object.dbName, __server, {safe:false, native_parser:false}).open(function(err, db) { - // Update number of servers - totalNumberOfServers = totalNumberOfServers - 1; - // If no error do the correct checks - if(!err) { - // Close the connection - db.close(true); - var isMasterDoc = db.serverConfig.isMasterDoc; - // Check what type of server we have - if(isMasterDoc.setName) totalNumberOfMongodServers++; - if(isMasterDoc.msg && isMasterDoc.msg == "isdbgrid") totalNumberOfMongosServers++; - } else { - errorServers[__server.host + ":" + __server.port] = __server; - } - - if(totalNumberOfServers == 0) { - // If we have a mix of mongod and mongos, throw an error - if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) - return callback(new Error("cannot combine a list of replicaset seeds and mongos seeds")); - - if(totalNumberOfMongodServers == 0 && object.servers.length == 1) { - var obj = object.servers[0]; - serverConfig = obj.domain_socket ? - new Server(obj.domain_socket, object.server_options) - : new Server(obj.host, obj.port, object.server_options); - } else if(totalNumberOfMongodServers > 0 || totalNumberOfMongosServers > 0) { - var finalServers = object.servers - .filter(function(serverObj) { - return errorServers[serverObj.host + ":" + serverObj.port] == null; - }) - .map(function(serverObj) { - return new Server(serverObj.host, serverObj.port, object.server_options); - }); - // Clean out any error servers - errorServers = {}; - // Set up the final configuration - if(totalNumberOfMongodServers > 0) { - serverConfig = new ReplSet(finalServers, object.rs_options); - } else { - serverConfig = new Mongos(finalServers, object.mongos_options); - } - } - - if(serverConfig == null) return callback(new Error("Could not locate any valid servers in initial seed list")); - // Ensure no firing off open event before we are ready - serverConfig.emitOpen = false; - // Set up all options etc and connect to the database - _finishConnecting(serverConfig, object, options, callback) - } - }); - } - - // Wrap the context of the call - connectFunction(_server); - } -} - -var _setNativeParser = function(db_options) { - if(typeof db_options.native_parser == 'boolean') return db_options.native_parser; - - try { - require('bson').BSONNative.BSON; - return true; - } catch(err) { - return false; - } -} - -var _finishConnecting = function(serverConfig, object, options, callback) { - // Safe settings - var safe = {}; - // Build the safe parameter if needed - if(object.db_options.journal) safe.j = object.db_options.journal; - if(object.db_options.w) safe.w = object.db_options.w; - if(object.db_options.fsync) safe.fsync = object.db_options.fsync; - if(object.db_options.wtimeoutMS) safe.wtimeout = object.db_options.wtimeoutMS; - - // If we have a read Preference set - if(object.db_options.read_preference) { - var readPreference = new ReadPreference(object.db_options.read_preference); - // If we have the tags set up - if(object.db_options.read_preference_tags) - readPreference = new ReadPreference(object.db_options.read_preference, object.db_options.read_preference_tags); - // Add the read preference - object.db_options.readPreference = readPreference; - } - - // No safe mode if no keys - if(Object.keys(safe).length == 0) safe = false; - - // Add the safe object - object.db_options.safe = safe; - - // Set up the db options - var db = new Db(object.dbName, serverConfig, object.db_options); - // Open the db - db.open(function(err, db){ - if(err) return callback(err, null); - - if(db.options !== null && !db.options.safe && !db.options.journal - && !db.options.w && !db.options.fsync && typeof db.options.w != 'number' - && (db.options.safe == false && object.db_options.url.indexOf("safe=") == -1)) { - db.options.w = 1; - } - - if(err == null && object.auth){ - // What db to authenticate against - var authentication_db = db; - if(object.db_options && object.db_options.authSource) { - authentication_db = db.db(object.db_options.authSource); - } - - // Build options object - var options = {}; - if(object.db_options.authMechanism) options.authMechanism = object.db_options.authMechanism; - - // Authenticate - authentication_db.authenticate(object.auth.user, object.auth.password, options, function(err, success){ - if(success){ - callback(null, db); - } else { - if(db) db.close(); - callback(err ? err : new Error('Could not authenticate user ' + auth[0]), null); - } - }); - } else { - callback(err, db); - } - }); -} - - -exports.MongoClient = MongoClient; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js b/frontend/express/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js deleted file mode 100644 index b27b81232d7..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js +++ /dev/null @@ -1,144 +0,0 @@ -var Long = require('bson').Long - , timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - Reply message from mongo db -**/ -var MongoReply = exports.MongoReply = function() { - this.documents = []; - this.index = 0; -}; - -MongoReply.prototype.parseHeader = function(binary_reply, bson) { - // Unpack the standard header first - this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the request id for this reply - this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the id of the request that triggered the response - this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // Skip op-code field - this.index = this.index + 4 + 4; - // Unpack the reply message - this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the cursor id (a 64 bit long integer) - var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - this.cursorId = new Long(low_bits, high_bits); - // Unpack the starting from - this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the number of objects returned - this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; -} - -MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) { - raw = raw == null ? false : raw; - // Just set a doc limit for deserializing - var docLimitSize = 1024*20; - - // If our message length is very long, let's switch to process.nextTick for messages - if(this.messageLength > docLimitSize) { - var batchSize = this.numberReturned; - this.documents = new Array(this.numberReturned); - - // Just walk down until we get a positive number >= 1 - for(var i = 50; i > 0; i--) { - if((this.numberReturned/i) >= 1) { - batchSize = i; - break; - } - } - - // Actual main creator of the processFunction setting internal state to control the flow - var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) { - var object_index = 0; - // Internal loop process that will use nextTick to ensure we yield some time - var processFunction = function() { - // Adjust batchSize if we have less results left than batchsize - if((_numberReturned - object_index) < _batchSize) { - _batchSize = _numberReturned - object_index; - } - - // If raw just process the entries - if(raw) { - // Iterate over the batch - for(var i = 0; i < _batchSize; i++) { - // Are we done ? - if(object_index <= _numberReturned) { - // Read the size of the bson object - var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - _self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize); - // Adjust binary index to point to next block of binary bson data - _self.index = _self.index + bsonObjectSize; - // Update number of docs parsed - object_index = object_index + 1; - } - } - } else { - try { - // Parse documents - _self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index); - // Adjust index - object_index = object_index + _batchSize; - } catch (err) { - return callback(err); - } - } - - // If we have more documents process NextTick - if(object_index < _numberReturned) { - processor(processFunction); - } else { - callback(null); - } - } - - // Return the process function - return processFunction; - }(this, binary_reply, batchSize, this.numberReturned)(); - } else { - try { - // Let's unpack all the bson documents, deserialize them and store them - for(var object_index = 0; object_index < this.numberReturned; object_index++) { - // Read the size of the bson object - var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - if(raw) { - // Deserialize the object and add to the documents array - this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize)); - } else { - // Deserialize the object and add to the documents array - this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize))); - } - // Adjust binary index to point to next block of binary bson data - this.index = this.index + bsonObjectSize; - } - } catch(err) { - return callback(err); - } - - // No error return - callback(null); - } -} - -MongoReply.prototype.is_error = function(){ - if(this.documents.length == 1) { - return this.documents[0].ok == 1 ? false : true; - } - return false; -}; - -MongoReply.prototype.error_message = function() { - return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/lib/mongodb/utils.js b/frontend/express/node_modules/mongodb/lib/mongodb/utils.js deleted file mode 100644 index 087789d7cae..00000000000 --- a/frontend/express/node_modules/mongodb/lib/mongodb/utils.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Sort functions, Normalize and prepare sort parameters - */ -var formatSortValue = exports.formatSortValue = function(sortDirection) { - var value = ("" + sortDirection).toLowerCase(); - - switch (value) { - case 'ascending': - case 'asc': - case '1': - return 1; - case 'descending': - case 'desc': - case '-1': - return -1; - default: - throw new Error("Illegal sort clause, must be of the form " - + "[['field1', '(ascending|descending)'], " - + "['field2', '(ascending|descending)']]"); - } -}; - -var formattedOrderClause = exports.formattedOrderClause = function(sortValue) { - var orderBy = {}; - - if (Array.isArray(sortValue)) { - for(var i = 0; i < sortValue.length; i++) { - if(sortValue[i].constructor == String) { - orderBy[sortValue[i]] = 1; - } else { - orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]); - } - } - } else if(Object.prototype.toString.call(sortValue) === '[object Object]') { - orderBy = sortValue; - } else if (sortValue.constructor == String) { - orderBy[sortValue] = 1; - } else { - throw new Error("Illegal sort clause, must be of the form " + - "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"); - } - - return orderBy; -}; - -exports.encodeInt = function(value) { - var buffer = new Buffer(4); - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = value & 0xff; - return buffer; -} - -exports.encodeIntInPlace = function(value, buffer, index) { - buffer[index + 3] = (value >> 24) & 0xff; - buffer[index + 2] = (value >> 16) & 0xff; - buffer[index + 1] = (value >> 8) & 0xff; - buffer[index] = value & 0xff; -} - -exports.encodeCString = function(string) { - var buf = new Buffer(string, 'utf8'); - return [buf, new Buffer([0])]; -} - -exports.decodeUInt32 = function(array, index) { - return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24; -} - -// Decode the int -exports.decodeUInt8 = function(array, index) { - return array[index]; -} - -/** - * Context insensitive type checks - */ - -var toString = Object.prototype.toString; - -exports.isObject = function (arg) { - return '[object Object]' == toString.call(arg) -} - -exports.isArray = function (arg) { - return Array.isArray(arg) || - 'object' == typeof arg && '[object Array]' == toString.call(arg) -} - -exports.isDate = function (arg) { - return 'object' == typeof arg && '[object Date]' == toString.call(arg) -} - -exports.isRegExp = function (arg) { - return 'object' == typeof arg && '[object RegExp]' == toString.call(arg) -} - -/** - * Wrap a Mongo error document in an Error instance - * @ignore - * @api private - */ -exports.toError = function(error) { - if (error instanceof Error) return error; - - var msg = error.err || error.errmsg || error; - var e = new Error(msg); - e.name = 'MongoError'; - - // Get all object keys - var keys = typeof error == 'object' - ? Object.keys(error) - : []; - - for(var i = 0; i < keys.length; i++) { - e[keys[i]] = error[keys[i]]; - } - - return e; -} - -/** - * Convert a single level object to an array - * @ignore - * @api private - */ -exports.objectToArray = function(object) { - var list = []; - - for(var name in object) { - list.push(object[name]) - } - - return list; -} - diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/.travis.yml b/frontend/express/node_modules/mongodb/node_modules/bson/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/Makefile b/frontend/express/node_modules/mongodb/node_modules/bson/Makefile deleted file mode 100644 index 77ce4e04085..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit - -all: clean node_gyp - -test: clean node_gyp - npm test - -node_gyp: clean - node-gyp configure build - -clean: - node-gyp clean - -browserify: - node_modules/.bin/onejs build browser_build/package.json browser_build/bson.js - -.PHONY: all diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/README.md b/frontend/express/node_modules/mongodb/node_modules/bson/README.md deleted file mode 100644 index 1a6fc2bafb0..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/README.md +++ /dev/null @@ -1,45 +0,0 @@ -Javascript + C++ BSON parser -============================ - -This BSON parser is primarily meant for usage with the `mongodb` node.js driver. However thanks to such wonderful tools at `onejs` we are able to package up a BSON parser that will work in the browser aswell. The current build is located in the `browser_build/bson.js` file. - -A simple example on how to use it - - - - - - - - - It's got two simple methods to use in your application. - - * BSON.serialize(object, checkKeys, asBuffer, serializeFunctions) - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)** - * @return {TypedArray/Array} returns a TypedArray or Array depending on what your browser supports - - * BSON.deserialize(buffer, options, isArray) - * Options - * **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * @param {TypedArray/Array} a TypedArray/Array containing the BSON data - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/binding.gyp b/frontend/express/node_modules/mongodb/node_modules/bson/binding.gyp deleted file mode 100644 index 42445d325d7..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/binding.gyp +++ /dev/null @@ -1,17 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'bson', - 'sources': [ 'ext/bson.cc' ], - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/bson.js b/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/bson.js deleted file mode 100644 index 7132496117d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/bson.js +++ /dev/null @@ -1,4815 +0,0 @@ -var bson = (function(){ - - var pkgmap = {}, - global = {}, - nativeRequire = typeof require != 'undefined' && require, - lib, ties, main, async; - - function exports(){ return main(); }; - - exports.main = exports; - exports.module = module; - exports.packages = pkgmap; - exports.pkg = pkg; - exports.require = function require(uri){ return pkgmap.main.index.require(uri); }; - - - ties = {}; - - aliases = {}; - - - return exports; - -function join() { - return normalize(Array.prototype.join.call(arguments, "/")); -}; - -function normalize(path) { - var ret = [], parts = path.split('/'), cur, prev; - - var i = 0, l = parts.length-1; - for (; i <= l; i++) { - cur = parts[i]; - - if (cur === "." && prev !== undefined) continue; - - if (cur === ".." && ret.length && prev !== ".." && prev !== "." && prev !== undefined) { - ret.pop(); - prev = ret.slice(-1)[0]; - } else { - if (prev === ".") ret.pop(); - ret.push(cur); - prev = cur; - } - } - - return ret.join("/"); -}; - -function dirname(path) { - return path && path.substr(0, path.lastIndexOf("/")) || "."; -}; - -function findModule(workingModule, uri){ - var moduleId = join(dirname(workingModule.id), uri).replace(/\.js$/, ''), - moduleIndexId = join(moduleId, 'index'), - pkg = workingModule.pkg, - module; - - var i = pkg.modules.length, - id; - - while(i-->0){ - id = pkg.modules[i].id; - if(id==moduleId || id == moduleIndexId){ - module = pkg.modules[i]; - break; - } - } - - return module; -} - -function newRequire(callingModule){ - function require(uri){ - var module, pkg; - - if(/^\./.test(uri)){ - module = findModule(callingModule, uri); - } else if ( ties && ties.hasOwnProperty( uri ) ) { - return ties[uri]; - } else if ( aliases && aliases.hasOwnProperty( uri ) ) { - return require(aliases[uri]); - } else { - pkg = pkgmap[uri]; - - if(!pkg && nativeRequire){ - try { - pkg = nativeRequire(uri); - } catch (nativeRequireError) {} - - if(pkg) return pkg; - } - - if(!pkg){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module = pkg.index; - } - - if(!module){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module.parent = callingModule; - return module.call(); - }; - - - return require; -} - - -function module(parent, id, wrapper){ - var mod = { pkg: parent, id: id, wrapper: wrapper }, - cached = false; - - mod.exports = {}; - mod.require = newRequire(mod); - - mod.call = function(){ - if(cached) { - return mod.exports; - } - - cached = true; - - global.require = mod.require; - - mod.wrapper(mod, mod.exports, global, global.require); - return mod.exports; - }; - - if(parent.mainModuleId == mod.id){ - parent.index = mod; - parent.parents.length === 0 && ( main = mod.call ); - } - - parent.modules.push(mod); -} - -function pkg(/* [ parentId ...], wrapper */){ - var wrapper = arguments[ arguments.length - 1 ], - parents = Array.prototype.slice.call(arguments, 0, arguments.length - 1), - ctx = wrapper(parents); - - - pkgmap[ctx.name] = ctx; - - arguments.length == 1 && ( pkgmap.main = ctx ); - - return function(modules){ - var id; - for(id in modules){ - module(ctx, id, modules[id]); - } - }; -} - - -}(this)); - -bson.pkg(function(parents){ - - return { - 'name' : 'bson', - 'mainModuleId' : 'bson', - 'modules' : [], - 'parents' : parents - }; - -})({ 'binary': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - - -}, - - - -'binary_parser': function(module, exports, global, require, undefined){ - /** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; - -}, - - - -'bson': function(module, exports, global, require, undefined){ - var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; - -}, - - - -'code': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; -}, - - - -'db_ref': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; -}, - - - -'double': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; -}, - - - -'float_parser': function(module, exports, global, require, undefined){ - // Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; -}, - - - -'index': function(module, exports, global, require, undefined){ - try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -}, - - - -'long': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; -}, - - - -'max_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; -}, - - - -'min_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; -}, - - - -'objectid': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; -}, - - - -'symbol': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; -}, - - - -'timestamp': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; -}, - - }); - - -if(typeof module != 'undefined' && module.exports ){ - module.exports = bson; - - if( !module.parent ){ - bson(); - } -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/package.json b/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/package.json deleted file mode 100644 index 3ebb58761c5..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/browser_build/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ "name" : "bson" -, "description" : "A bson parser for node.js and the browser" -, "main": "../lib/bson/bson" -, "directories" : { "lib" : "../lib/bson" } -, "engines" : { "node" : ">=0.6.0" } -, "licenses" : [ { "type" : "Apache License, Version 2.0" - , "url" : "http://www.apache.org/licenses/LICENSE-2.0" } ] -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Makefile b/frontend/express/node_modules/mongodb/node_modules/bson/build/Makefile deleted file mode 100644 index a96572cb2eb..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/Makefile +++ /dev/null @@ -1,333 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bson.target.mk)))),) - include bson.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/home/b/Desktop/countly/frontend/express/node_modules/mongodb/node_modules/bson/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/root/.node-gyp/0.10.11/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/root/.node-gyp/0.10.11" "-Dmodule_root_dir=/home/b/Desktop/countly/frontend/express/node_modules/mongodb/node_modules/bson" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../root/.node-gyp/0.10.11/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d deleted file mode 100644 index 866c155bc23..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bson.node := rm -rf "Release/bson.node" && cp -af "Release/obj.target/bson.node" "Release/bson.node" diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d deleted file mode 100644 index a7317de71b7..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/bson.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m32 -Wl,-soname=bson.node -o Release/obj.target/bson.node -Wl,--start-group Release/obj.target/bson/ext/bson.o -Wl,--end-group diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d deleted file mode 100644 index 5cdc93f8392..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d +++ /dev/null @@ -1,28 +0,0 @@ -cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/root/.node-gyp/0.10.11/src -I/root/.node-gyp/0.10.11/deps/uv/include -I/root/.node-gyp/0.10.11/deps/v8/include -Wall -Wextra -Wno-unused-parameter -pthread -m32 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-tree-sink -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc -Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \ - /root/.node-gyp/0.10.11/deps/v8/include/v8.h \ - /root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/src/node_version.h \ - /root/.node-gyp/0.10.11/src/node_buffer.h ../ext/bson.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h -../ext/bson.cc: -/root/.node-gyp/0.10.11/deps/v8/include/v8.h: -/root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/src/node_version.h: -/root/.node-gyp/0.10.11/src/node_buffer.h: -../ext/bson.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/bson.node b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o b/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o deleted file mode 100644 index a2bfc494436..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/binding.Makefile b/frontend/express/node_modules/mongodb/node_modules/bson/build/binding.Makefile deleted file mode 100644 index 90bf8247b39..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) bson diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/bson.target.mk b/frontend/express/node_modules/mongodb/node_modules/bson/build/bson.target.mk deleted file mode 100644 index 5359f669c3e..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/bson.target.mk +++ /dev/null @@ -1,126 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bson -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti - -INCS_Debug := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-tree-sink - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti - -INCS_Release := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/ext/bson.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m32 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m32 - -LIBS := - -$(obj).target/bson.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/bson.node: LIBS := $(LIBS) -$(obj).target/bson.node: TOOLSET := $(TOOLSET) -$(obj).target/bson.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/bson.node -# Add target alias -.PHONY: bson -bson: $(builddir)/bson.node - -# Copy this to the executable output path. -$(builddir)/bson.node: TOOLSET := $(TOOLSET) -$(builddir)/bson.node: $(obj).target/bson.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/bson.node -# Short alias for building this executable. -.PHONY: bson.node -bson.node: $(obj).target/bson.node $(builddir)/bson.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bson.node - diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build/config.gypi b/frontend/express/node_modules/mongodb/node_modules/bson/build/config.gypi deleted file mode 100644 index 69c52b6eb0f..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build/config.gypi +++ /dev/null @@ -1,114 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 44, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/root/.node-gyp/0.10.11", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "pre": "", - "sign_git_tag": "", - "always_auth": "", - "user_agent": "node/v0.10.11 linux ia32", - "bin_links": "true", - "description": "true", - "fetch_retries": "2", - "init_version": "0.0.0", - "user": "", - "force": "", - "ignore": "", - "cache_min": "10", - "editor": "vi", - "rollback": "true", - "cache_max": "null", - "userconfig": "/root/.npmrc", - "coverage": "", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/root/tmp", - "userignorefile": "/root/.npmignore", - "yes": "", - "depth": "null", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/root/.npm", - "npaturl": "http://npat.npmjs.org/", - "searchsort": "name", - "version": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.11", - "tag": "latest", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/root/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "group": "", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "json": "" - } -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/build_browser.js b/frontend/express/node_modules/mongodb/node_modules/bson/build_browser.js deleted file mode 100644 index bb802384453..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/build_browser.js +++ /dev/null @@ -1,7 +0,0 @@ -require('one'); - -one('./package.json') - .tie('bson', BSON) - // .exclude('buffer') - .tie('buffer', {}) - .save('./browser_build/bson.js') \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/Makefile b/frontend/express/node_modules/mongodb/node_modules/bson/ext/Makefile deleted file mode 100644 index 435999ee960..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/ext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.cc b/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.cc deleted file mode 100644 index 8a2ec8b7e7a..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.cc +++ /dev/null @@ -1,1006 +0,0 @@ -//=========================================================================== - -#include -#include -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -// this and the above block must be around the v8.h header otherwise -// v8 is not happy -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __sun - #include -#endif - -#include "bson.h" - -using namespace v8; -using namespace node; - -//=========================================================================== - -void DataStream::WriteObjectId(const Handle& object, const Handle& key) -{ - uint16_t buffer[12]; - object->Get(key)->ToString()->Write(buffer, 0, 12); - for(uint32_t i = 0; i < 12; ++i) - { - *p++ = (char) buffer[i]; - } -} - -void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...) -{ - va_list args; - va_start(args, format); - char* string = (char*) malloc(allocationSize); - vsprintf(string, format, args); - va_end(args); - - throw string; -} - -void DataStream::CheckKey(const Local& keyName) -{ - size_t keyLength = keyName->Utf8Length(); - if(keyLength == 0) return; - - char* keyStringBuffer = (char*) alloca(keyLength+1); - keyName->WriteUtf8(keyStringBuffer); - - if(keyStringBuffer[0] == '$') - { - ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer); - } - - if(strchr(keyStringBuffer, '.') != NULL) - { - ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer); - } -} - -template void BSONSerializer::SerializeDocument(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - Local object = bson->GetSerializeObject(value); - - // Get the object property names - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local propertyNames = object->GetPropertyNames(); - #else - Local propertyNames = object->GetOwnPropertyNames(); - #endif - - // Length of the property - int propertyLength = propertyNames->Length(); - for(int i = 0; i < propertyLength; ++i) - { - const Local& propertyName = propertyNames->Get(i)->ToString(); - if(checkKeys) this->CheckKey(propertyName); - - const Local& propertyValue = object->Get(propertyName); - - if(serializeFunctions || !propertyValue->IsFunction()) - { - void* typeLocation = this->BeginWriteType(); - this->WriteString(propertyName); - SerializeValue(typeLocation, propertyValue); - } - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -template void BSONSerializer::SerializeArray(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - - Local array = Local::Cast(value->ToObject()); - uint32_t arrayLength = array->Length(); - - for(uint32_t i = 0; i < arrayLength; ++i) - { - void* typeLocation = this->BeginWriteType(); - this->WriteUInt32String(i); - SerializeValue(typeLocation, array->Get(i)); - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes. -// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths) -// and ensures that there is always consistency between bytes counted and bytes written by design. -template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value) -{ - if(value->IsNumber()) - { - double doubleValue = value->NumberValue(); - int intValue = (int) doubleValue; - if(intValue == doubleValue) - { - this->CommitType(typeLocation, BSON_TYPE_INT); - this->WriteInt32(intValue); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(doubleValue); - } - } - else if(value->IsString()) - { - this->CommitType(typeLocation, BSON_TYPE_STRING); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsBoolean()) - { - this->CommitType(typeLocation, BSON_TYPE_BOOLEAN); - this->WriteBool(value); - } - else if(value->IsArray()) - { - this->CommitType(typeLocation, BSON_TYPE_ARRAY); - SerializeArray(value); - } - else if(value->IsDate()) - { - this->CommitType(typeLocation, BSON_TYPE_DATE); - this->WriteInt64(value); - } - else if(value->IsRegExp()) - { - this->CommitType(typeLocation, BSON_TYPE_REGEXP); - const Handle& regExp = Handle::Cast(value); - - this->WriteString(regExp->GetSource()); - - int flags = regExp->GetFlags(); - if(flags & RegExp::kGlobal) this->WriteByte('s'); - if(flags & RegExp::kIgnoreCase) this->WriteByte('i'); - if(flags & RegExp::kMultiline) this->WriteByte('m'); - this->WriteByte(0); - } - else if(value->IsFunction()) - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsObject()) - { - const Local& object = value->ToObject(); - if(object->Has(bson->_bsontypeString)) - { - const Local& constructorString = object->GetConstructorName(); - if(bson->longString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_LONG); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->timestampString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->objectIDString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OID); - this->WriteObjectId(object, bson->_objectIDidString); - } - else if(bson->binaryString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value(); - Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject(); - - this->WriteInt32(length); - this->WriteByte(object, bson->_binarySubTypeString); // write subtype - // If type 0x02 write the array length aswell - if(object->Get(bson->_binarySubTypeString)->Int32Value() == 0x02) { - this->WriteInt32(length); - } - // Write the actual data - this->WriteData(Buffer::Data(bufferObj), length); - } - else if(bson->doubleString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(object, bson->_doubleValueString); - } - else if(bson->symbolString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_SYMBOL); - this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString()); - } - else if(bson->codeString->StrictEquals(constructorString)) - { - const Local& function = object->Get(bson->_codeCodeString)->ToString(); - const Local& scope = object->Get(bson->_codeScopeString)->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - if(propertyNameLength > 0) - { - this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE); - void* codeWidthScopeSize = this->BeginWriteSize(); - this->WriteLengthPrefixedString(function->ToString()); - SerializeDocument(scope); - this->CommitSize(codeWidthScopeSize); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(function->ToString()); - } - } - else if(bson->dbrefString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - - void* dbRefSize = this->BeginWriteSize(); - - void* refType = this->BeginWriteType(); - this->WriteData("$ref", 5); - SerializeValue(refType, object->Get(bson->_dbRefNamespaceString)); - - void* idType = this->BeginWriteType(); - this->WriteData("$id", 4); - SerializeValue(idType, object->Get(bson->_dbRefOidString)); - - const Local& refDbValue = object->Get(bson->_dbRefDbString); - if(!refDbValue->IsUndefined()) - { - void* dbType = this->BeginWriteType(); - this->WriteData("$db", 4); - SerializeValue(dbType, refDbValue); - } - - this->WriteByte(0); - this->CommitSize(dbRefSize); - } - else if(bson->minKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MIN_KEY); - } - else if(bson->maxKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MAX_KEY); - } - } - else if(Buffer::HasInstance(value)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(value->ToObject()); - uint32_t length = object->length(); - #else - uint32_t length = Buffer::Length(value->ToObject()); - #endif - - this->WriteInt32(length); - this->WriteByte(0); - this->WriteData(Buffer::Data(value->ToObject()), length); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - SerializeDocument(value); - } - } - else if(value->IsNull() || value->IsUndefined()) - { - this->CommitType(typeLocation, BSON_TYPE_NULL); - } -} - -// Data points to start of element list, length is length of entire document including '\0' but excluding initial size -BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length) -: bson(aBson), - pStart(data), - p(data), - pEnd(data + length - 1) -{ - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length) -: bson(parentSerializer.bson), - pStart(parentSerializer.p), - p(parentSerializer.p), - pEnd(parentSerializer.p + length - 1) -{ - parentSerializer.p += length; - if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds"); - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -Local BSONDeserializer::ReadCString() -{ - char* start = p; - while(*p++) { } - return String::New(start, (int32_t) (p-start-1) ); -} - -int32_t BSONDeserializer::ReadRegexOptions() -{ - int32_t options = 0; - for(;;) - { - switch(*p++) - { - case '\0': return options; - case 's': options |= RegExp::kGlobal; break; - case 'i': options |= RegExp::kIgnoreCase; break; - case 'm': options |= RegExp::kMultiline; break; - } - } -} - -uint32_t BSONDeserializer::ReadIntegerString() -{ - uint32_t value = 0; - while(*p) - { - if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array"); - value = value * 10 + *p++ - '0'; - } - ++p; - return value; -} - -Local BSONDeserializer::ReadString() -{ - uint32_t length = ReadUInt32(); - char* start = p; - p += length; - return String::New(start, length-1); -} - -Local BSONDeserializer::ReadObjectId() -{ - uint16_t objectId[12]; - for(size_t i = 0; i < 12; ++i) - { - objectId[i] = *reinterpret_cast(p++); - } - return String::New(objectId, 12); -} - -Handle BSONDeserializer::DeserializeDocument() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeDocumentInternal(); -} - -Handle BSONDeserializer::DeserializeDocumentInternal() -{ - Local returnObject = Object::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - const Local& name = ReadCString(); - const Handle& value = DeserializeValue(type); - returnObject->ForceSet(name, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes"); - - // From JavaScript: - // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - if(returnObject->Has(bson->_dbRefIdRefString)) - { - Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) }; - return bson->dbrefConstructor->NewInstance(3, argv); - } - else - { - return returnObject; - } -} - -Handle BSONDeserializer::DeserializeArray() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeArrayInternal(); -} - -Handle BSONDeserializer::DeserializeArrayInternal() -{ - Local returnArray = Array::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - uint32_t index = ReadIntegerString(); - const Handle& value = DeserializeValue(type); - returnArray->Set(index, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes"); - - return returnArray; -} - -Handle BSONDeserializer::DeserializeValue(BsonType type) -{ - switch(type) - { - case BSON_TYPE_STRING: - return ReadString(); - - case BSON_TYPE_INT: - return Integer::New(ReadInt32()); - - case BSON_TYPE_NUMBER: - return Number::New(ReadDouble()); - - case BSON_TYPE_NULL: - return Null(); - - case BSON_TYPE_UNDEFINED: - return Undefined(); - - case BSON_TYPE_TIMESTAMP: - { - int32_t lowBits = ReadInt32(); - int32_t highBits = ReadInt32(); - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->timestampConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_BOOLEAN: - return (ReadByte() != 0) ? True() : False(); - - case BSON_TYPE_REGEXP: - { - const Local& regex = ReadCString(); - int32_t options = ReadRegexOptions(); - return RegExp::New(regex, (RegExp::Flags) options); - } - - case BSON_TYPE_CODE: - { - const Local& code = ReadString(); - const Local& scope = Object::New(); - Local argv[] = { code, scope }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_CODE_W_SCOPE: - { - ReadUInt32(); - const Local& code = ReadString(); - const Handle& scope = DeserializeDocument(); - Local argv[] = { code, scope->ToObject() }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_OID: - { - Local argv[] = { ReadObjectId() }; - return bson->objectIDConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_BINARY: - { - uint32_t length = ReadUInt32(); - uint32_t subType = ReadByte(); - if(subType == 0x02) { - length = ReadInt32(); - } - - Buffer* buffer = Buffer::New(p, length); - p += length; - - Handle argv[] = { buffer->handle_, Uint32::New(subType) }; - return bson->binaryConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_LONG: - { - // Read 32 bit integers - int32_t lowBits = (int32_t) ReadInt32(); - int32_t highBits = (int32_t) ReadInt32(); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - // Adjust the pointer and read as 64 bit value - p -= 8; - // Read the 64 bit value - int64_t finalValue = (int64_t) ReadInt64(); - return Number::New(finalValue); - } - - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->longConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_DATE: - return Date::New((double) ReadInt64()); - - case BSON_TYPE_ARRAY: - return DeserializeArray(); - - case BSON_TYPE_OBJECT: - return DeserializeDocument(); - - case BSON_TYPE_SYMBOL: - { - const Local& string = ReadString(); - Local argv[] = { string }; - return bson->symbolConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_MIN_KEY: - return bson->minKeyConstructor->NewInstance(); - - case BSON_TYPE_MAX_KEY: - return bson->maxKeyConstructor->NewInstance(); - - default: - ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type); - } - - return v8::Null(); -} - - -static Handle VException(const char *msg) -{ - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Persistent BSON::constructor_template; - -BSON::BSON() : ObjectWrap() -{ - // Setup pre-allocated comparision objects - _bsontypeString = Persistent::New(String::New("_bsontype")); - _longLowString = Persistent::New(String::New("low_")); - _longHighString = Persistent::New(String::New("high_")); - _objectIDidString = Persistent::New(String::New("id")); - _binaryPositionString = Persistent::New(String::New("position")); - _binarySubTypeString = Persistent::New(String::New("sub_type")); - _binaryBufferString = Persistent::New(String::New("buffer")); - _doubleValueString = Persistent::New(String::New("value")); - _symbolValueString = Persistent::New(String::New("value")); - _dbRefRefString = Persistent::New(String::New("$ref")); - _dbRefIdRefString = Persistent::New(String::New("$id")); - _dbRefDbRefString = Persistent::New(String::New("$db")); - _dbRefNamespaceString = Persistent::New(String::New("namespace")); - _dbRefDbString = Persistent::New(String::New("db")); - _dbRefOidString = Persistent::New(String::New("oid")); - _codeCodeString = Persistent::New(String::New("code")); - _codeScopeString = Persistent::New(String::New("scope")); - _toBSONString = Persistent::New(String::New("toBSON")); - - longString = Persistent::New(String::New("Long")); - objectIDString = Persistent::New(String::New("ObjectID")); - binaryString = Persistent::New(String::New("Binary")); - codeString = Persistent::New(String::New("Code")); - dbrefString = Persistent::New(String::New("DBRef")); - symbolString = Persistent::New(String::New("Symbol")); - doubleString = Persistent::New(String::New("Double")); - timestampString = Persistent::New(String::New("Timestamp")); - minKeyString = Persistent::New(String::New("MinKey")); - maxKeyString = Persistent::New(String::New("MaxKey")); -} - -void BSON::Initialize(v8::Handle target) -{ - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and passing it the existing context -Handle BSON::New(const Arguments &args) -{ - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) - { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) - { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - uint32_t foundClassesMask = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(bson->longString)) { - bson->longConstructor = Persistent::New(func); - foundClassesMask |= 1; - } else if(functionName->StrictEquals(bson->objectIDString)) { - bson->objectIDConstructor = Persistent::New(func); - foundClassesMask |= 2; - } else if(functionName->StrictEquals(bson->binaryString)) { - bson->binaryConstructor = Persistent::New(func); - foundClassesMask |= 4; - } else if(functionName->StrictEquals(bson->codeString)) { - bson->codeConstructor = Persistent::New(func); - foundClassesMask |= 8; - } else if(functionName->StrictEquals(bson->dbrefString)) { - bson->dbrefConstructor = Persistent::New(func); - foundClassesMask |= 0x10; - } else if(functionName->StrictEquals(bson->symbolString)) { - bson->symbolConstructor = Persistent::New(func); - foundClassesMask |= 0x20; - } else if(functionName->StrictEquals(bson->doubleString)) { - bson->doubleConstructor = Persistent::New(func); - foundClassesMask |= 0x40; - } else if(functionName->StrictEquals(bson->timestampString)) { - bson->timestampConstructor = Persistent::New(func); - foundClassesMask |= 0x80; - } else if(functionName->StrictEquals(bson->minKeyString)) { - bson->minKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x100; - } else if(functionName->StrictEquals(bson->maxKeyString)) { - bson->maxKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x200; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(foundClassesMask != 0x3ff) { - delete bson; - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } - else - { - return VException("No types passed in"); - } - } - else - { - return VException("Argument passed in must be an array of types"); - } -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ - -Handle BSON::BSONDeserialize(const Arguments &args) -{ - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) - { -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Validate that we have at least 5 bytes - if(length < 5) return VException("corrupt bson message < 5 bytes long"); - - try - { - BSONDeserializer deserializer(bson, data, length); - return deserializer.DeserializeDocument(); - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - } - else - { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) return VException("corrupt bson message < 5 bytes long"); - - // Let's define the buffer size - char* data = (char *)malloc(len); - DecodeWrite(data, len, args[0], BINARY); - - try - { - BSONDeserializer deserializer(bson, data, len); - Handle result = deserializer.DeserializeDocument(); - free(data); - return result; - - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - free(data); - return error; - } - } -} - -Local BSON::GetSerializeObject(const Handle& argValue) -{ - Local object = argValue->ToObject(); - if(object->Has(_toBSONString)) - { - const Local& toBSON = object->Get(_toBSONString); - if(!toBSON->IsFunction()) ThrowAllocatedStringException(64, "toBSON is not a function"); - - Local result = Local::Cast(toBSON)->Call(object, 0, NULL); - if(!result->IsObject()) ThrowAllocatedStringException(64, "toBSON function did not return an object"); - return result->ToObject(); - } - else - { - return object; - } -} - -Handle BSON::BSONSerialize(const Arguments &args) -{ - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - bool serializeFunctions = (args.Length() >= 4) && args[3]->BooleanValue(); - - char *serialized_object = NULL; - size_t object_size; - try - { - Local object = bson->GetSerializeObject(args[0]); - - BSONSerializer counter(bson, false, serializeFunctions); - counter.SerializeDocument(object); - object_size = counter.GetSerializeSize(); - - // Allocate the memory needed for the serialization - serialized_object = (char *)malloc(object_size); - - // Check if we have a boolean value - bool checkKeys = args.Length() >= 3 && args[1]->IsBoolean() && args[1]->BooleanValue(); - BSONSerializer data(bson, checkKeys, serializeFunctions, serialized_object); - data.SerializeDocument(object); - } - catch(char *err_msg) - { - free(serialized_object); - Handle error = VException(err_msg); - free(err_msg); - return error; - } - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) - { - Buffer *buffer = Buffer::New(serialized_object, object_size); - free(serialized_object); - return scope.Close(buffer->handle_); - } - else - { - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - free(serialized_object); - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) -{ - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - bool serializeFunctions = (args.Length() >= 2) && args[1]->BooleanValue(); - BSONSerializer countSerializer(bson, false, serializeFunctions); - countSerializer.SerializeDocument(args[0]); - - // Return the object size - return scope.Close(Uint32::New((uint32_t) countSerializer.GetSerializeSize())); -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) -{ - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, ->, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - uint32_t index; - size_t object_size; - - try - { - BSON *bson = ObjectWrap::Unwrap(args.This()); - - Local obj = args[2]->ToObject(); - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); - - index = args[3]->Uint32Value(); - bool checkKeys = args.Length() >= 4 && args[1]->IsBoolean() && args[1]->BooleanValue(); - bool serializeFunctions = (args.Length() == 5) && args[4]->BooleanValue(); - - BSONSerializer dataSerializer(bson, checkKeys, serializeFunctions, data+index); - dataSerializer.SerializeDocument(bson->GetSerializeObject(args[0])); - object_size = dataSerializer.GetSerializeSize(); - - if(object_size + index > length) return VException("Serious error - overflowed buffer!!"); - } - catch(char *exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - return scope.Close(Uint32::New((uint32_t) (index + object_size - 1))); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) -{ - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) return VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) - { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->Uint32Value(); - uint32_t index = args[1]->Uint32Value(); - uint32_t resultIndex = args[4]->Uint32Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - BSONDeserializer deserializer(bson, data+index, length-index); - for(uint32_t i = 0; i < numberOfDocuments; i++) - { - try - { - documents->Set(i + resultIndex, deserializer.DeserializeDocument()); - } - catch (char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - } - - // Return new index of parsing - return scope.Close(Uint32::New((uint32_t) (index + deserializer.GetSerializeSize()))); -} - -// Exporting function -extern "C" void init(Handle target) -{ - HandleScope scope; - BSON::Initialize(target); -} - -NODE_MODULE(bson, BSON::Initialize); diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.h b/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.h deleted file mode 100644 index 00f273b4022..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/ext/bson.h +++ /dev/null @@ -1,277 +0,0 @@ -//=========================================================================== - -#ifndef BSON_H_ -#define BSON_H_ - -//=========================================================================== - -#ifdef __arm__ -#define USE_MISALIGNED_MEMORY_ACCESS 0 -#else -#define USE_MISALIGNED_MEMORY_ACCESS 1 -#endif - -#include -#include -#include - -using namespace v8; -using namespace node; - -//=========================================================================== - -enum BsonType -{ - BSON_TYPE_NUMBER = 1, - BSON_TYPE_STRING = 2, - BSON_TYPE_OBJECT = 3, - BSON_TYPE_ARRAY = 4, - BSON_TYPE_BINARY = 5, - BSON_TYPE_UNDEFINED = 6, - BSON_TYPE_OID = 7, - BSON_TYPE_BOOLEAN = 8, - BSON_TYPE_DATE = 9, - BSON_TYPE_NULL = 10, - BSON_TYPE_REGEXP = 11, - BSON_TYPE_CODE = 13, - BSON_TYPE_SYMBOL = 14, - BSON_TYPE_CODE_W_SCOPE = 15, - BSON_TYPE_INT = 16, - BSON_TYPE_TIMESTAMP = 17, - BSON_TYPE_LONG = 18, - BSON_TYPE_MAX_KEY = 0x7f, - BSON_TYPE_MIN_KEY = 0xff -}; - -//=========================================================================== - -template class BSONSerializer; - -class BSON : public ObjectWrap { -public: - BSON(); - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - -private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparison objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - Persistent _codeCodeString; - Persistent _codeScopeString; - Persistent _toBSONString; - - Local GetSerializeObject(const Handle& object); - - template friend class BSONSerializer; - friend class BSONDeserializer; -}; - -//=========================================================================== - -class CountStream -{ -public: - CountStream() : count(0) { } - - void WriteByte(int value) { ++count; } - void WriteByte(const Handle&, const Handle&) { ++count; } - void WriteBool(const Handle& value) { ++count; } - void WriteInt32(int32_t value) { count += 4; } - void WriteInt32(const Handle& value) { count += 4; } - void WriteInt32(const Handle& object, const Handle& key) { count += 4; } - void WriteInt64(int64_t value) { count += 8; } - void WriteInt64(const Handle& value) { count += 8; } - void WriteDouble(double value) { count += 8; } - void WriteDouble(const Handle& value) { count += 8; } - void WriteDouble(const Handle&, const Handle&) { count += 8; } - void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { count += value->Utf8Length()+5; } - void WriteObjectId(const Handle& object, const Handle& key) { count += 12; } - void WriteString(const Local& value) { count += value->Utf8Length() + 1; } // This returns the number of bytes exclusive of the NULL terminator - void WriteData(const char* data, size_t length) { count += length; } - - void* BeginWriteType() { ++count; return NULL; } - void CommitType(void*, BsonType) { } - void* BeginWriteSize() { count += 4; return NULL; } - void CommitSize(void*) { } - - size_t GetSerializeSize() const { return count; } - - // Do nothing. CheckKey is implemented for DataStream - void CheckKey(const Local&) { } - -private: - size_t count; -}; - -class DataStream -{ -public: - DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { } - - void WriteByte(int value) { *p++ = value; } - void WriteByte(const Handle& object, const Handle& key) { *p++ = object->Get(key)->Int32Value(); } -#if USE_MISALIGNED_MEMORY_ACCESS - void WriteInt32(int32_t value) { *reinterpret_cast(p) = value; p += 4; } - void WriteInt64(int64_t value) { *reinterpret_cast(p) = value; p += 8; } - void WriteDouble(double value) { *reinterpret_cast(p) = value; p += 8; } -#else - void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; } - void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; } - void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; } -#endif - void WriteBool(const Handle& value) { WriteByte(value->BooleanValue() ? 1 : 0); } - void WriteInt32(const Handle& value) { WriteInt32(value->Int32Value()); } - void WriteInt32(const Handle& object, const Handle& key) { WriteInt32(object->Get(key)); } - void WriteInt64(const Handle& value) { WriteInt64(value->IntegerValue()); } - void WriteDouble(const Handle& value) { WriteDouble(value->NumberValue()); } - void WriteDouble(const Handle& object, const Handle& key) { WriteDouble(object->Get(key)); } - void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); } - void WriteObjectId(const Handle& object, const Handle& key); - void WriteString(const Local& value) { p += value->WriteUtf8(p); } // This returns the number of bytes inclusive of the NULL terminator. - void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; } - - void* BeginWriteType() { void* returnValue = p; p++; return returnValue; } - void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast(beginPoint) = value; } - void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; } - -#if USE_MISALIGNED_MEMORY_ACCESS - void CommitSize(void* beginPoint) { *reinterpret_cast(beginPoint) = (int32_t) (p - (char*) beginPoint); } -#else - void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); } -#endif - - size_t GetSerializeSize() const { return p - destinationBuffer; } - - void CheckKey(const Local& keyName); - -protected: - char *const destinationBuffer; // base, never changes - char* p; // cursor into buffer -}; - -template class BSONSerializer : public T -{ -private: - typedef T Inherited; - -public: - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - - void SerializeDocument(const Handle& value); - void SerializeArray(const Handle& value); - void SerializeValue(void* typeLocation, const Handle& value); - -private: - bool checkKeys; - bool serializeFunctions; - BSON* bson; -}; - -//=========================================================================== - -class BSONDeserializer -{ -public: - BSONDeserializer(BSON* aBson, char* data, size_t length); - BSONDeserializer(BSONDeserializer& parentSerializer, size_t length); - - Handle DeserializeDocument(); - - bool HasMoreData() const { return p < pEnd; } - Local ReadCString(); - uint32_t ReadIntegerString(); - int32_t ReadRegexOptions(); - Local ReadString(); - Local ReadObjectId(); - - unsigned char ReadByte() { return *reinterpret_cast(p++); } -#if USE_MISALIGNED_MEMORY_ACCESS - int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast(p); p += 8; return returnValue; } - double ReadDouble() { double returnValue = *reinterpret_cast(p); p += 8; return returnValue; } -#else - int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } - double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } -#endif - - size_t GetSerializeSize() const { return p - pStart; } - -private: - Handle DeserializeArray(); - Handle DeserializeValue(BsonType type); - Handle DeserializeDocumentInternal(); - Handle DeserializeArrayInternal(); - - BSON* bson; - char* const pStart; - char* p; - char* const pEnd; -}; - -//=========================================================================== - -#endif // BSON_H_ - -//=========================================================================== diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/index.js b/frontend/express/node_modules/mongodb/node_modules/bson/ext/index.js deleted file mode 100644 index 85e243cc2e1..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/ext/index.js +++ /dev/null @@ -1,30 +0,0 @@ -var bson = null; - -// Load the precompiled win32 binary -if(process.platform == "win32" && process.arch == "x64") { - bson = require('./win32/x64/bson'); -} else if(process.platform == "win32" && process.arch == "ia32") { - bson = require('./win32/ia32/bson'); -} else { - bson = require('../build/Release/bson'); -} - -exports.BSON = bson.BSON; -exports.Long = require('../lib/bson/long').Long; -exports.ObjectID = require('../lib/bson/objectid').ObjectID; -exports.DBRef = require('../lib/bson/db_ref').DBRef; -exports.Code = require('../lib/bson/code').Code; -exports.Timestamp = require('../lib/bson/timestamp').Timestamp; -exports.Binary = require('../lib/bson/binary').Binary; -exports.Double = require('../lib/bson/double').Double; -exports.MaxKey = require('../lib/bson/max_key').MaxKey; -exports.MinKey = require('../lib/bson/min_key').MinKey; -exports.Symbol = require('../lib/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node b/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node deleted file mode 100644 index b27819bb1a8..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node b/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node deleted file mode 100644 index a544c8ed638..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/ext/wscript b/frontend/express/node_modules/mongodb/node_modules/bson/ext/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/ext/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary.js deleted file mode 100644 index 82d4d04c10b..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary.js +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js deleted file mode 100644 index d2fc811f416..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/bson.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/bson.js deleted file mode 100644 index 7da82492be1..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/bson.js +++ /dev/null @@ -1,1519 +0,0 @@ -var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/code.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/code.js deleted file mode 100644 index 69b56a3ff51..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/code.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js deleted file mode 100644 index 56b651029bd..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/double.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/double.js deleted file mode 100644 index ae5146378f0..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/double.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js deleted file mode 100644 index 6fca3924f6c..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/index.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/index.js deleted file mode 100644 index 950fcad343d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/index.js +++ /dev/null @@ -1,74 +0,0 @@ -try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/long.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/long.js deleted file mode 100644 index f8f37a6b865..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/long.js +++ /dev/null @@ -1,854 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js deleted file mode 100644 index 0825408d0c9..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js deleted file mode 100644 index 230c2e64a1d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js deleted file mode 100644 index 183bbc3c939..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation date (accurate up to the second) that this ID was generated. -* -* @return {Date} the generation date -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js deleted file mode 100644 index 8e2838d1783..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js b/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js deleted file mode 100644 index c650d1536c8..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/package.json b/frontend/express/node_modules/mongodb/node_modules/bson/package.json deleted file mode 100644 index e9eb5f1638c..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "bson", - "description": "A bson parser for node.js and the browser", - "keywords": [ - "mongodb", - "bson", - "parser" - ], - "version": "0.1.9", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [], - "repository": { - "type": "git", - "url": "git://github.com/mongodb/js-bson.git" - }, - "bugs": { - "url": "https://github.com/mongodb/js-bson/issues" - }, - "devDependencies": { - "nodeunit": "0.7.3", - "gleak": "0.2.3", - "one": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/bson/index", - "directories": { - "lib": "./lib/bson" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "nodeunit ./test/node && TEST_NATIVE=TRUE nodeunit ./test/node" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Javascript + C++ BSON parser\n============================\n\nThis BSON parser is primarily meant for usage with the `mongodb` node.js driver. However thanks to such wonderful tools at `onejs` we are able to package up a BSON parser that will work in the browser aswell. The current build is located in the `browser_build/bson.js` file.\n\nA simple example on how to use it\n\n \n \n \n \n \n \n\n It's got two simple methods to use in your application.\n\n * BSON.serialize(object, checkKeys, asBuffer, serializeFunctions)\n * @param {Object} object the Javascript object to serialize.\n * @param {Boolean} checkKeys the serializer will check if keys are valid.\n * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**.\n * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**\n * @return {TypedArray/Array} returns a TypedArray or Array depending on what your browser supports\n \n * BSON.deserialize(buffer, options, isArray)\n * Options\n * **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.\n * **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.\n * **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.\n * @param {TypedArray/Array} a TypedArray/Array containing the BSON data\n * @param {Object} [options] additional options used for the deserialization.\n * @param {Boolean} [isArray] ignore used for recursive parsing.\n * @return {Object} returns the deserialized Javascript Object.\n", - "readmeFilename": "README.md", - "_id": "bson@0.1.9", - "_from": "bson@0.1.9" -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/gleak.js b/frontend/express/node_modules/mongodb/node_modules/bson/tools/gleak.js deleted file mode 100644 index c707cfcb56c..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/tools/gleak.js +++ /dev/null @@ -1,21 +0,0 @@ - -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE b/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE deleted file mode 100644 index 7c435baaec8..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js b/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js deleted file mode 100644 index 73834010f60..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js +++ /dev/null @@ -1,190 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css b/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css deleted file mode 100644 index 6583fe7c66d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js b/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js deleted file mode 100644 index c3d2dc7d2d3..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png b/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png deleted file mode 100644 index 218f3b43713..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/README.md b/frontend/express/node_modules/mongodb/node_modules/kerberos/README.md deleted file mode 100644 index 7428b0d0ef4..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/README.md +++ /dev/null @@ -1,4 +0,0 @@ -kerberos -======== - -Kerberos library for node.js \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/binding.gyp b/frontend/express/node_modules/mongodb/node_modules/kerberos/binding.gyp deleted file mode 100644 index 027a70f2084..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/binding.gyp +++ /dev/null @@ -1,41 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'kerberos', - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'sources': [ 'lib/kerberos.cc', 'lib/worker.cc', 'lib/kerberosgss.c', 'lib/base64.c', 'lib/kerberos_context.cc' ], - 'defines': [ - '__MACOSX_CORE__' - ], - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - }, - "link_settings": { - "libraries": [ - "-lkrb5" - ] - } - }], - ['OS=="win"', { - 'sources': [ - 'lib/win32/kerberos.cc', - 'lib/win32/base64.c', - 'lib/win32/worker.cc', - 'lib/win32/kerberos_sspi.c', - 'lib/win32/wrappers/security_buffer.cc', - 'lib/win32/wrappers/security_buffer_descriptor.cc', - 'lib/win32/wrappers/security_context.cc', - 'lib/win32/wrappers/security_credentials.cc' - ], - "link_settings": { - "libraries": [ - ] - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Makefile b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Makefile deleted file mode 100644 index 9525fc3d1be..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Makefile +++ /dev/null @@ -1,333 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,kerberos.target.mk)))),) - include kerberos.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/home/b/Desktop/countly/frontend/express/node_modules/mongodb/node_modules/kerberos/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/root/.node-gyp/0.10.11/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/root/.node-gyp/0.10.11" "-Dmodule_root_dir=/home/b/Desktop/countly/frontend/express/node_modules/mongodb/node_modules/kerberos" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../root/.node-gyp/0.10.11/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/kerberos.node.d b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/kerberos.node.d deleted file mode 100644 index 0bc32060740..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/kerberos.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/kerberos.node := rm -rf "Release/kerberos.node" && cp -af "Release/obj.target/kerberos.node" "Release/kerberos.node" diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/obj.target/kerberos.node.d b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/obj.target/kerberos.node.d deleted file mode 100644 index ba6dec80cb6..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/.deps/Release/obj.target/kerberos.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/kerberos.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m32 -Wl,-soname=kerberos.node -o Release/obj.target/kerberos.node -Wl,--start-group -Wl,--end-group diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/kerberos.node b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/kerberos.node deleted file mode 100644 index 6a37aa74271..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/kerberos.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/obj.target/kerberos.node b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/obj.target/kerberos.node deleted file mode 100644 index 6a37aa74271..00000000000 Binary files a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/Release/obj.target/kerberos.node and /dev/null differ diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/binding.Makefile b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/binding.Makefile deleted file mode 100644 index d0d9c64a79c..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) kerberos diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/config.gypi b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/config.gypi deleted file mode 100644 index 69c52b6eb0f..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/config.gypi +++ /dev/null @@ -1,114 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 44, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/root/.node-gyp/0.10.11", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "pre": "", - "sign_git_tag": "", - "always_auth": "", - "user_agent": "node/v0.10.11 linux ia32", - "bin_links": "true", - "description": "true", - "fetch_retries": "2", - "init_version": "0.0.0", - "user": "", - "force": "", - "ignore": "", - "cache_min": "10", - "editor": "vi", - "rollback": "true", - "cache_max": "null", - "userconfig": "/root/.npmrc", - "coverage": "", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/root/tmp", - "userignorefile": "/root/.npmignore", - "yes": "", - "depth": "null", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/root/.npm", - "npaturl": "http://npat.npmjs.org/", - "searchsort": "name", - "version": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.11", - "tag": "latest", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/root/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "group": "", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "json": "" - } -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/kerberos.target.mk b/frontend/express/node_modules/mongodb/node_modules/kerberos/build/kerberos.target.mk deleted file mode 100644 index d2ce49b9228..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/build/kerberos.target.mk +++ /dev/null @@ -1,42 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := kerberos -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m32 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m32 - -LIBS := - -$(obj).target/kerberos.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/kerberos.node: LIBS := $(LIBS) -$(obj).target/kerberos.node: TOOLSET := $(TOOLSET) -$(obj).target/kerberos.node: FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/kerberos.node -# Add target alias -.PHONY: kerberos -kerberos: $(builddir)/kerberos.node - -# Copy this to the executable output path. -$(builddir)/kerberos.node: TOOLSET := $(TOOLSET) -$(builddir)/kerberos.node: $(obj).target/kerberos.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/kerberos.node -# Short alias for building this executable. -.PHONY: kerberos.node -kerberos.node: $(obj).target/kerberos.node $(builddir)/kerberos.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/kerberos.node - diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/index.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/index.js deleted file mode 100644 index b8c853276a6..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/index.js +++ /dev/null @@ -1,6 +0,0 @@ -// Get the Kerberos library -module.exports = require('./lib/kerberos'); -// Set up the auth processes -module.exports['processes'] = { - MongoAuthProcess: require('./lib/auth_processes/mongodb').MongoAuthProcess -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/auth_processes/mongodb.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/auth_processes/mongodb.js deleted file mode 100644 index afc30b7454e..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/auth_processes/mongodb.js +++ /dev/null @@ -1,278 +0,0 @@ -var format = require('util').format; - -var MongoAuthProcess = function(host, port) { - // Check what system we are on - if(process.platform == 'win32') { - this._processor = new Win32MongoProcessor(host, port); - } else { - this._processor = new UnixMongoProcessor(host, port); - } -} - -MongoAuthProcess.prototype.init = function(username, password, callback) { - this._processor.init(username, password, callback); -} - -MongoAuthProcess.prototype.transition = function(payload, callback) { - this._processor.transition(payload, callback); -} - -/******************************************************************* - * - * Win32 SSIP Processor for MongoDB - * - *******************************************************************/ -var Win32MongoProcessor = function(host, port) { - this.host = host; - this.port = port - // SSIP classes - this.ssip = require("../kerberos").SSIP; - // Set up first transition - this._transition = Win32MongoProcessor.first_transition(this); - // Set up target - this.target = format("mongodb/%s", host); - // Number of retries - this.retries = 10; -} - -Win32MongoProcessor.prototype.init = function(username, password, callback) { - var self = this; - // Save the values used later - this.username = username; - this.password = password; - // Aquire credentials - this.ssip.SecurityCredentials.aquire_kerberos(username, password, function(err, security_credentials) { - if(err) return callback(err); - // Save credentials - self.security_credentials = security_credentials; - // Callback with success - callback(null); - }); -} - -Win32MongoProcessor.prototype.transition = function(payload, callback) { - if(this._transition == null) return callback(new Error("Transition finished")); - this._transition(payload, callback); -} - -Win32MongoProcessor.first_transition = function(self) { - return function(payload, callback) { - self.ssip.SecurityContext.initialize( - self.security_credentials, - self.target, - payload, function(err, security_context) { - if(err) return callback(err); - - // If no context try again until we have no more retries - if(!security_context.hasContext) { - if(self.retries == 0) return callback(new Error("Failed to initialize security context")); - // Update the number of retries - self.retries = self.retries - 1; - // Set next transition - return self.transition(payload, callback); - } - - // Set next transition - self._transition = Win32MongoProcessor.second_transition(self); - self.security_context = security_context; - // Return the payload - callback(null, security_context.payload); - }); - } -} - -Win32MongoProcessor.second_transition = function(self) { - return function(payload, callback) { - // Perform a step - self.security_context.initialize(self.target, payload, function(err, security_context) { - if(err) return callback(err); - - // If no context try again until we have no more retries - if(!security_context.hasContext) { - if(self.retries == 0) return callback(new Error("Failed to initialize security context")); - // Update the number of retries - self.retries = self.retries - 1; - // Set next transition - self._transition = Win32MongoProcessor.first_transition(self); - // Retry - return self.transition(payload, callback); - } - - // Set next transition - self._transition = Win32MongoProcessor.third_transition(self); - // Return the payload - callback(null, security_context.payload); - }); - } -} - -Win32MongoProcessor.third_transition = function(self) { - return function(payload, callback) { - var messageLength = 0; - // Get the raw bytes - var encryptedBytes = new Buffer(payload, 'base64'); - var encryptedMessage = new Buffer(messageLength); - // Copy first byte - encryptedBytes.copy(encryptedMessage, 0, 0, messageLength); - // Set up trailer - var securityTrailerLength = encryptedBytes.length - messageLength; - var securityTrailer = new Buffer(securityTrailerLength); - // Copy the bytes - encryptedBytes.copy(securityTrailer, 0, messageLength, securityTrailerLength); - - // Types used - var SecurityBuffer = self.ssip.SecurityBuffer; - var SecurityBufferDescriptor = self.ssip.SecurityBufferDescriptor; - - // Set up security buffers - var buffers = [ - new SecurityBuffer(SecurityBuffer.DATA, encryptedBytes) - , new SecurityBuffer(SecurityBuffer.STREAM, securityTrailer) - ]; - - // Set up the descriptor - var descriptor = new SecurityBufferDescriptor(buffers); - - // Decrypt the data - self.security_context.decryptMessage(descriptor, function(err, security_context) { - if(err) return callback(err); - - var length = 4; - if(self.username != null) { - length += self.username.length; - } - - var bytesReceivedFromServer = new Buffer(length); - bytesReceivedFromServer[0] = 0x01; // NO_PROTECTION - bytesReceivedFromServer[1] = 0x00; // NO_PROTECTION - bytesReceivedFromServer[2] = 0x00; // NO_PROTECTION - bytesReceivedFromServer[3] = 0x00; // NO_PROTECTION - - if(self.username != null) { - var authorization_id_bytes = new Buffer(self.username, 'utf8'); - authorization_id_bytes.copy(bytesReceivedFromServer, 4, 0); - } - - self.security_context.queryContextAttributes(0x00, function(err, sizes) { - if(err) return callback(err); - - var buffers = [ - new SecurityBuffer(SecurityBuffer.TOKEN, new Buffer(sizes.securityTrailer)) - , new SecurityBuffer(SecurityBuffer.DATA, bytesReceivedFromServer) - , new SecurityBuffer(SecurityBuffer.PADDING, new Buffer(sizes.blockSize)) - ] - - var descriptor = new SecurityBufferDescriptor(buffers); - - self.security_context.encryptMessage(descriptor, 0x80000001, function(err, security_context) { - if(err) return callback(err); - callback(null, security_context.payload); - }); - }); - }); - } -} - -/******************************************************************* - * - * UNIX MIT Kerberos processor - * - *******************************************************************/ -var UnixMongoProcessor = function(host, port) { - this.host = host; - this.port = port - // SSIP classes - this.Kerberos = require("../kerberos").Kerberos; - this.kerberos = new this.Kerberos(); - // Set up first transition - this._transition = UnixMongoProcessor.first_transition(this); - // Set up target - this.target = format("mongodb@%s", host); - // Number of retries - this.retries = 10; -} - -UnixMongoProcessor.prototype.init = function(username, password, callback) { - var self = this; - this.username = username; - this.password = password; - // Call client initiate - this.kerberos.authGSSClientInit( - self.target - , this.Kerberos.GSS_C_MUTUAL_FLAG, function(err, context) { - self.context = context; - // Return the context - callback(null, context); - }); -} - -UnixMongoProcessor.prototype.transition = function(payload, callback) { - if(this._transition == null) return callback(new Error("Transition finished")); - this._transition(payload, callback); -} - -UnixMongoProcessor.first_transition = function(self) { - return function(payload, callback) { - self.kerberos.authGSSClientStep(self.context, '', function(err, result) { - if(err) return callback(err); - // Set up the next step - self._transition = UnixMongoProcessor.second_transition(self); - // Return the payload - callback(null, self.context.response); - }) - } -} - -UnixMongoProcessor.second_transition = function(self) { - return function(payload, callback) { - self.kerberos.authGSSClientStep(self.context, payload, function(err, result) { - if(err && self.retries == 0) return callback(err); - // Attempt to re-establish a context - if(err) { - // Adjust the number of retries - self.retries = self.retries - 1; - // Call same step again - return self.transition(payload, callback); - } - - // Set up the next step - self._transition = UnixMongoProcessor.third_transition(self); - // Return the payload - callback(null, self.context.response || ''); - }); - } -} - -UnixMongoProcessor.third_transition = function(self) { - return function(payload, callback) { - // GSS Client Unwrap - self.kerberos.authGSSClientUnwrap(self.context, payload, function(err, result) { - if(err) return callback(err, false); - - // Wrap the response - self.kerberos.authGSSClientWrap(self.context, self.context.response, self.username, function(err, result) { - if(err) return callback(err, false); - // Set up the next step - self._transition = UnixMongoProcessor.fourth_transition(self); - // Return the payload - callback(null, self.context.response); - }); - }); - } -} - -UnixMongoProcessor.fourth_transition = function(self) { - return function(payload, callback) { - // Clean up context - self.kerberos.authGSSClientClean(self.context, function(err, result) { - if(err) return callback(err, false); - // Set the transition to null - self._transition = null; - // Callback with valid authentication - callback(null, true); - }); - } -} - -// Set the process -exports.MongoAuthProcess = MongoAuthProcess; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.c b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.c deleted file mode 100644 index 4232106b98c..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -#include "base64.h" - -#include -#include - -// base64 tables -static char basis_64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static signed char index_64[128] = -{ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; -#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) - -// base64_encode : base64 encode -// -// value : data to encode -// vlen : length of data -// (result) : new char[] - c-str of result -char *base64_encode(const unsigned char *value, int vlen) -{ - char *result = (char *)malloc((vlen * 4) / 3 + 5); - char *out = result; - while (vlen >= 3) - { - *out++ = basis_64[value[0] >> 2]; - *out++ = basis_64[((value[0] << 4) & 0x30) | (value[1] >> 4)]; - *out++ = basis_64[((value[1] << 2) & 0x3C) | (value[2] >> 6)]; - *out++ = basis_64[value[2] & 0x3F]; - value += 3; - vlen -= 3; - } - if (vlen > 0) - { - *out++ = basis_64[value[0] >> 2]; - unsigned char oval = (value[0] << 4) & 0x30; - if (vlen > 1) oval |= value[1] >> 4; - *out++ = basis_64[oval]; - *out++ = (vlen < 2) ? '=' : basis_64[(value[1] << 2) & 0x3C]; - *out++ = '='; - } - *out = '\0'; - - return result; -} - -// base64_decode : base64 decode -// -// value : c-str to decode -// rlen : length of decoded result -// (result) : new unsigned char[] - decoded result -unsigned char *base64_decode(const char *value, int *rlen) -{ - *rlen = 0; - int c1, c2, c3, c4; - - int vlen = strlen(value); - unsigned char *result =(unsigned char *)malloc((vlen * 3) / 4 + 1); - unsigned char *out = result; - - while (1) - { - if (value[0]==0) - return result; - c1 = value[0]; - if (CHAR64(c1) == -1) - goto base64_decode_error;; - c2 = value[1]; - if (CHAR64(c2) == -1) - goto base64_decode_error;; - c3 = value[2]; - if ((c3 != '=') && (CHAR64(c3) == -1)) - goto base64_decode_error;; - c4 = value[3]; - if ((c4 != '=') && (CHAR64(c4) == -1)) - goto base64_decode_error;; - - value += 4; - *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4); - *rlen += 1; - if (c3 != '=') - { - *out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2); - *rlen += 1; - if (c4 != '=') - { - *out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4); - *rlen += 1; - } - } - } - -base64_decode_error: - *result = 0; - *rlen = 0; - return result; -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.h deleted file mode 100644 index f0e1f061623..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/base64.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -char *base64_encode(const unsigned char *value, int vlen); -unsigned char *base64_decode(const char *value, int *rlen); diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.cc deleted file mode 100644 index 08eda82b2a8..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.cc +++ /dev/null @@ -1,563 +0,0 @@ -#include "kerberos.h" -#include -#include "worker.h" -#include "kerberos_context.h" - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) -#endif - -Persistent Kerberos::constructor_template; - -// Call structs -typedef struct AuthGSSClientCall { - uint32_t flags; - char *uri; -} AuthGSSClientCall; - -typedef struct AuthGSSClientStepCall { - KerberosContext *context; - char *challenge; -} AuthGSSClientStepCall; - -typedef struct AuthGSSClientUnwrapCall { - KerberosContext *context; - char *challenge; -} AuthGSSClientUnwrapCall; - -typedef struct AuthGSSClientWrapCall { - KerberosContext *context; - char *challenge; - char *user_name; -} AuthGSSClientWrapCall; - -typedef struct AuthGSSClientCleanCall { - KerberosContext *context; -} AuthGSSClientCleanCall; - -// VException object (causes throw in calling code) -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Kerberos::Kerberos() : ObjectWrap() { -} - -void Kerberos::Initialize(v8::Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(Kerberos::New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Kerberos")); - - // Set up method for the Kerberos instance - NODE_SET_PROTOTYPE_METHOD(constructor_template, "authGSSClientInit", AuthGSSClientInit); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "authGSSClientStep", AuthGSSClientStep); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "authGSSClientUnwrap", AuthGSSClientUnwrap); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "authGSSClientWrap", AuthGSSClientWrap); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "authGSSClientClean", AuthGSSClientClean); - - // Set the symbol - target->ForceSet(String::NewSymbol("Kerberos"), constructor_template->GetFunction()); -} - -Handle Kerberos::New(const Arguments &args) { - // Create a Kerberos instance - Kerberos *kerberos = new Kerberos(); - // Return the kerberos object - kerberos->Wrap(args.This()); - return args.This(); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientInit -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authGSSClientInit(Worker *worker) { - gss_client_state *state; - gss_client_response *response; - - // Allocate state - state = (gss_client_state *)malloc(sizeof(gss_client_state)); - - // Unpack the parameter data struct - AuthGSSClientCall *call = (AuthGSSClientCall *)worker->parameters; - // Start the kerberos client - response = authenticate_gss_client_init(call->uri, call->flags, state); - - // Release the parameter struct memory - free(call->uri); - free(call); - - // If we have an error mark worker as having had an error - if(response->return_code == AUTH_GSS_ERROR) { - worker->error = TRUE; - worker->error_code = response->return_code; - worker->error_message = response->message; - } else { - worker->return_value = state; - } - - // Free structure - free(response); -} - -static Handle _map_authGSSClientInit(Worker *worker) { - HandleScope scope; - - KerberosContext *context = KerberosContext::New(); - context->state = (gss_client_state *)worker->return_value; - // Persistent _context = Persistent::New(context->handle_); - return scope.Close(context->handle_); -} - -// Initialize method -Handle Kerberos::AuthGSSClientInit(const Arguments &args) { - HandleScope scope; - - // Ensure valid call - if(args.Length() != 3) return VException("Requires a service string uri, integer flags and a callback function"); - if(args.Length() == 3 && !args[0]->IsString() && !args[1]->IsInt32() && !args[2]->IsFunction()) - return VException("Requires a service string uri, integer flags and a callback function"); - - Local service = args[0]->ToString(); - // Convert uri string to c-string - char *service_str = (char *)calloc(service->Utf8Length() + 1, sizeof(char)); - // Write v8 string to c-string - service->WriteUtf8(service_str); - - // Allocate a structure - AuthGSSClientCall *call = (AuthGSSClientCall *)calloc(1, sizeof(AuthGSSClientCall)); - call->flags =args[1]->ToInt32()->Uint32Value(); - call->uri = service_str; - - // Unpack the callback - Local callback = Local::Cast(args[2]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authGSSClientInit; - worker->mapper = _map_authGSSClientInit; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Kerberos::Process, (uv_after_work_cb)Kerberos::After); - // Return no value as it's callback based - return scope.Close(Undefined()); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientStep -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authGSSClientStep(Worker *worker) { - gss_client_state *state; - gss_client_response *response; - char *challenge; - - // Unpack the parameter data struct - AuthGSSClientStepCall *call = (AuthGSSClientStepCall *)worker->parameters; - // Get the state - state = call->context->state; - challenge = call->challenge; - - // Check what kind of challenge we have - if(call->challenge == NULL) { - challenge = (char *)""; - } - - // Perform authentication step - response = authenticate_gss_client_step(state, challenge); - - // If we have an error mark worker as having had an error - if(response->return_code == AUTH_GSS_ERROR) { - worker->error = TRUE; - worker->error_code = response->return_code; - worker->error_message = response->message; - } else { - worker->return_code = response->return_code; - } - - // Free up structure - if(call->challenge != NULL) free(call->challenge); - free(call); - free(response); -} - -static Handle _map_authGSSClientStep(Worker *worker) { - HandleScope scope; - // Return the return code - return scope.Close(Int32::New(worker->return_code)); -} - -// Initialize method -Handle Kerberos::AuthGSSClientStep(const Arguments &args) { - HandleScope scope; - - // Ensure valid call - if(args.Length() != 2 && args.Length() != 3) return VException("Requires a GSS context, optional challenge string and callback function"); - if(args.Length() == 2 && !KerberosContext::HasInstance(args[0])) return VException("Requires a GSS context, optional challenge string and callback function"); - if(args.Length() == 3 && !KerberosContext::HasInstance(args[0]) && !args[1]->IsString()) return VException("Requires a GSS context, optional challenge string and callback function"); - - // Challenge string - char *challenge_str = NULL; - // Let's unpack the parameters - Local object = args[0]->ToObject(); - KerberosContext *kerberos_context = KerberosContext::Unwrap(object); - - // If we have a challenge string - if(args.Length() == 3) { - // Unpack the challenge string - Local challenge = args[1]->ToString(); - // Convert uri string to c-string - challenge_str = (char *)calloc(challenge->Utf8Length() + 1, sizeof(char)); - // Write v8 string to c-string - challenge->WriteUtf8(challenge_str); - } - - // Allocate a structure - AuthGSSClientStepCall *call = (AuthGSSClientStepCall *)calloc(1, sizeof(AuthGSSClientCall)); - call->context = kerberos_context; - call->challenge = challenge_str; - - // Unpack the callback - Local callback = Local::Cast(args[2]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authGSSClientStep; - worker->mapper = _map_authGSSClientStep; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Kerberos::Process, (uv_after_work_cb)Kerberos::After); - - // Return no value as it's callback based - return scope.Close(Undefined()); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientUnwrap -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authGSSClientUnwrap(Worker *worker) { - gss_client_response *response; - char *challenge; - - // Unpack the parameter data struct - AuthGSSClientUnwrapCall *call = (AuthGSSClientUnwrapCall *)worker->parameters; - challenge = call->challenge; - - // Check what kind of challenge we have - if(call->challenge == NULL) { - challenge = (char *)""; - } - - // Perform authentication step - response = authenticate_gss_client_unwrap(call->context->state, challenge); - - // If we have an error mark worker as having had an error - if(response->return_code == AUTH_GSS_ERROR) { - worker->error = TRUE; - worker->error_code = response->return_code; - worker->error_message = response->message; - } else { - worker->return_code = response->return_code; - } - - // Free up structure - if(call->challenge != NULL) free(call->challenge); - free(call); - free(response); -} - -static Handle _map_authGSSClientUnwrap(Worker *worker) { - HandleScope scope; - // Return the return code - return scope.Close(Int32::New(worker->return_code)); -} - -// Initialize method -Handle Kerberos::AuthGSSClientUnwrap(const Arguments &args) { - HandleScope scope; - - // Ensure valid call - if(args.Length() != 2 && args.Length() != 3) return VException("Requires a GSS context, optional challenge string and callback function"); - if(args.Length() == 2 && !KerberosContext::HasInstance(args[0]) && !args[1]->IsFunction()) return VException("Requires a GSS context, optional challenge string and callback function"); - if(args.Length() == 3 && !KerberosContext::HasInstance(args[0]) && !args[1]->IsString() && !args[2]->IsFunction()) return VException("Requires a GSS context, optional challenge string and callback function"); - - // Challenge string - char *challenge_str = NULL; - // Let's unpack the parameters - Local object = args[0]->ToObject(); - KerberosContext *kerberos_context = KerberosContext::Unwrap(object); - - // If we have a challenge string - if(args.Length() == 3) { - // Unpack the challenge string - Local challenge = args[1]->ToString(); - // Convert uri string to c-string - challenge_str = (char *)calloc(challenge->Utf8Length() + 1, sizeof(char)); - // Write v8 string to c-string - challenge->WriteUtf8(challenge_str); - } - - // Allocate a structure - AuthGSSClientUnwrapCall *call = (AuthGSSClientUnwrapCall *)calloc(1, sizeof(AuthGSSClientUnwrapCall)); - call->context = kerberos_context; - call->challenge = challenge_str; - - // Unpack the callback - Local callback = args.Length() == 3 ? Local::Cast(args[2]) : Local::Cast(args[1]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authGSSClientUnwrap; - worker->mapper = _map_authGSSClientUnwrap; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Kerberos::Process, (uv_after_work_cb)Kerberos::After); - - // Return no value as it's callback based - return scope.Close(Undefined()); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientWrap -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authGSSClientWrap(Worker *worker) { - gss_client_response *response; - char *user_name = NULL; - - // Unpack the parameter data struct - AuthGSSClientWrapCall *call = (AuthGSSClientWrapCall *)worker->parameters; - user_name = call->user_name; - - // Check what kind of challenge we have - if(call->user_name == NULL) { - user_name = (char *)""; - } - - // Perform authentication step - response = authenticate_gss_client_wrap(call->context->state, call->challenge, user_name); - - // If we have an error mark worker as having had an error - if(response->return_code == AUTH_GSS_ERROR) { - worker->error = TRUE; - worker->error_code = response->return_code; - worker->error_message = response->message; - } else { - worker->return_code = response->return_code; - } - - // Free up structure - if(call->challenge != NULL) free(call->challenge); - if(call->user_name != NULL) free(call->user_name); - free(call); - free(response); -} - -static Handle _map_authGSSClientWrap(Worker *worker) { - HandleScope scope; - // Return the return code - return scope.Close(Int32::New(worker->return_code)); -} - -// Initialize method -Handle Kerberos::AuthGSSClientWrap(const Arguments &args) { - HandleScope scope; - - // Ensure valid call - if(args.Length() != 3 && args.Length() != 4) return VException("Requires a GSS context, the result from the authGSSClientResponse after authGSSClientUnwrap, optional user name and callback function"); - if(args.Length() == 3 && !KerberosContext::HasInstance(args[0]) && !args[1]->IsString() && !args[2]->IsFunction()) return VException("Requires a GSS context, the result from the authGSSClientResponse after authGSSClientUnwrap, optional user name and callback function"); - if(args.Length() == 4 && !KerberosContext::HasInstance(args[0]) && !args[1]->IsString() && !args[2]->IsString() && !args[2]->IsFunction()) return VException("Requires a GSS context, the result from the authGSSClientResponse after authGSSClientUnwrap, optional user name and callback function"); - - // Challenge string - char *challenge_str = NULL; - char *user_name_str = NULL; - - // Let's unpack the kerberos context - Local object = args[0]->ToObject(); - KerberosContext *kerberos_context = KerberosContext::Unwrap(object); - - // Unpack the challenge string - Local challenge = args[1]->ToString(); - // Convert uri string to c-string - challenge_str = (char *)calloc(challenge->Utf8Length() + 1, sizeof(char)); - // Write v8 string to c-string - challenge->WriteUtf8(challenge_str); - - // If we have a user string - if(args.Length() == 4) { - // Unpack user name - Local user_name = args[2]->ToString(); - // Convert uri string to c-string - user_name_str = (char *)calloc(user_name->Utf8Length() + 1, sizeof(char)); - // Write v8 string to c-string - user_name->WriteUtf8(user_name_str); - } - - // Allocate a structure - AuthGSSClientWrapCall *call = (AuthGSSClientWrapCall *)calloc(1, sizeof(AuthGSSClientWrapCall)); - call->context = kerberos_context; - call->challenge = challenge_str; - call->user_name = user_name_str; - - // Unpack the callback - Local callback = args.Length() == 4 ? Local::Cast(args[3]) : Local::Cast(args[2]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authGSSClientWrap; - worker->mapper = _map_authGSSClientWrap; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Kerberos::Process, (uv_after_work_cb)Kerberos::After); - - // Return no value as it's callback based - return scope.Close(Undefined()); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientWrap -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authGSSClientClean(Worker *worker) { - gss_client_response *response; - - // Unpack the parameter data struct - AuthGSSClientCleanCall *call = (AuthGSSClientCleanCall *)worker->parameters; - - // Perform authentication step - response = authenticate_gss_client_clean(call->context->state); - - // If we have an error mark worker as having had an error - if(response->return_code == AUTH_GSS_ERROR) { - worker->error = TRUE; - worker->error_code = response->return_code; - worker->error_message = response->message; - } else { - worker->return_code = response->return_code; - } - - // Free up structure - free(call); - free(response); -} - -static Handle _map_authGSSClientClean(Worker *worker) { - HandleScope scope; - // Return the return code - return scope.Close(Int32::New(worker->return_code)); -} - -// Initialize method -Handle Kerberos::AuthGSSClientClean(const Arguments &args) { - HandleScope scope; - - // // Ensure valid call - if(args.Length() != 2) return VException("Requires a GSS context and callback function"); - if(!KerberosContext::HasInstance(args[0]) && !args[1]->IsFunction()) return VException("Requires a GSS context and callback function"); - - // Let's unpack the kerberos context - Local object = args[0]->ToObject(); - KerberosContext *kerberos_context = KerberosContext::Unwrap(object); - - // Allocate a structure - AuthGSSClientCleanCall *call = (AuthGSSClientCleanCall *)calloc(1, sizeof(AuthGSSClientCleanCall)); - call->context = kerberos_context; - - // Unpack the callback - Local callback = Local::Cast(args[1]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authGSSClientClean; - worker->mapper = _map_authGSSClientClean; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Kerberos::Process, (uv_after_work_cb)Kerberos::After); - - // Return no value as it's callback based - return scope.Close(Undefined()); -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// UV Lib callbacks -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void Kerberos::Process(uv_work_t* work_req) { - // Grab the worker - Worker *worker = static_cast(work_req->data); - // Execute the worker code - worker->execute(worker); -} - -void Kerberos::After(uv_work_t* work_req) { - // Grab the scope of the call from Node - v8::HandleScope scope; - - // Get the worker reference - Worker *worker = static_cast(work_req->data); - - // If we have an error - if(worker->error) { - v8::Local err = v8::Exception::Error(v8::String::New(worker->error_message)); - Local obj = err->ToObject(); - obj->Set(NODE_PSYMBOL("code"), Int32::New(worker->error_code)); - v8::Local args[2] = { err, v8::Local::New(v8::Null()) }; - // Execute the error - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } else { - // // Map the data - v8::Handle result = worker->mapper(worker); - // Set up the callback with a null first - v8::Handle args[2] = { v8::Local::New(v8::Null()), result}; - // Wrap the callback function call in a TryCatch so that we can call - // node's FatalException afterwards. This makes it possible to catch - // the exception from JavaScript land using the - // process.on('uncaughtException') event. - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } - - // Clean up the memory - worker->callback.Dispose(); - delete worker; -} - -// Exporting function -extern "C" void init(Handle target) { - HandleScope scope; - Kerberos::Initialize(target); - KerberosContext::Initialize(target); -} - -NODE_MODULE(kerberos, init); diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.h deleted file mode 100644 index f0fbcdc8cf3..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef KERBEROS_H -#define KERBEROS_H - -#include -#include -#include - -#include -#include -#include - -extern "C" { - #include "kerberosgss.h" -} - -using namespace v8; -using namespace node; - -class Kerberos : public ObjectWrap { - -public: - Kerberos(); - ~Kerberos() {}; - - // Constructor used for creating new Kerberos objects from C++ - static Persistent constructor_template; - - // Initialize function for the object - static void Initialize(Handle target); - - // Method available - static Handle AuthGSSClientInit(const Arguments &args); - static Handle AuthGSSClientStep(const Arguments &args); - static Handle AuthGSSClientUnwrap(const Arguments &args); - static Handle AuthGSSClientWrap(const Arguments &args); - static Handle AuthGSSClientClean(const Arguments &args); - -private: - static Handle New(const Arguments &args); - - // Handles the uv calls - static void Process(uv_work_t* work_req); - // Called after work is done - static void After(uv_work_t* work_req); -}; - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.js deleted file mode 100644 index b1a701ba002..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos.js +++ /dev/null @@ -1,91 +0,0 @@ -var kerberos = require('../build/Release/kerberos') - , KerberosNative = kerberos.Kerberos; - -var Kerberos = function() { - this._native_kerberos = new KerberosNative(); -} - -Kerberos.prototype.authGSSClientInit = function(uri, flags, callback) { - return this._native_kerberos.authGSSClientInit(uri, flags, callback); -} - -Kerberos.prototype.authGSSClientStep = function(context, challenge, callback) { - if(typeof challenge == 'function') { - callback = challenge; - challenge = ''; - } - - return this._native_kerberos.authGSSClientStep(context, challenge, callback); -} - -Kerberos.prototype.authGSSClientUnwrap = function(context, challenge, callback) { - if(typeof challenge == 'function') { - callback = challenge; - challenge = ''; - } - - return this._native_kerberos.authGSSClientUnwrap(context, challenge, callback); -} - -Kerberos.prototype.authGSSClientWrap = function(context, challenge, user_name, callback) { - if(typeof user_name == 'function') { - callback = user_name; - user_name = ''; - } - - return this._native_kerberos.authGSSClientWrap(context, challenge, user_name, callback); -} - -Kerberos.prototype.authGSSClientClean = function(context, callback) { - return this._native_kerberos.authGSSClientClean(context, callback); -} - -Kerberos.prototype.acquireAlternateCredentials = function(user_name, password, domain) { - return this._native_kerberos.acquireAlternateCredentials(user_name, password, domain); -} - -Kerberos.prototype.prepareOutboundPackage = function(principal, inputdata) { - return this._native_kerberos.prepareOutboundPackage(principal, inputdata); -} - -Kerberos.prototype.decryptMessage = function(challenge) { - return this._native_kerberos.decryptMessage(challenge); -} - -Kerberos.prototype.encryptMessage = function(challenge) { - return this._native_kerberos.encryptMessage(challenge); -} - -Kerberos.prototype.queryContextAttribute = function(attribute) { - if(typeof attribute != 'number' && attribute != 0x00) throw new Error("Attribute not supported"); - return this._native_kerberos.queryContextAttribute(attribute); -} - -// Some useful result codes -Kerberos.AUTH_GSS_CONTINUE = 0; -Kerberos.AUTH_GSS_COMPLETE = 1; - -// Some useful gss flags -Kerberos.GSS_C_DELEG_FLAG = 1; -Kerberos.GSS_C_MUTUAL_FLAG = 2; -Kerberos.GSS_C_REPLAY_FLAG = 4; -Kerberos.GSS_C_SEQUENCE_FLAG = 8; -Kerberos.GSS_C_CONF_FLAG = 16; -Kerberos.GSS_C_INTEG_FLAG = 32; -Kerberos.GSS_C_ANON_FLAG = 64; -Kerberos.GSS_C_PROT_READY_FLAG = 128; -Kerberos.GSS_C_TRANS_FLAG = 256; - -// Export Kerberos class -exports.Kerberos = Kerberos; - -// If we have SSPI (windows) -if(kerberos.SecurityCredentials) { - // Put all SSPI classes in it's own namespace - exports.SSIP = { - SecurityCredentials: require('./win32/wrappers/security_credentials').SecurityCredentials - , SecurityContext: require('./win32/wrappers/security_context').SecurityContext - , SecurityBuffer: require('./win32/wrappers/security_buffer').SecurityBuffer - , SecurityBufferDescriptor: require('./win32/wrappers/security_buffer_descriptor').SecurityBufferDescriptor - } -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.cc deleted file mode 100644 index 7a5f4eb8d8d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.cc +++ /dev/null @@ -1,74 +0,0 @@ -#include "kerberos_context.h" - -Persistent KerberosContext::constructor_template; - -KerberosContext::KerberosContext() : ObjectWrap() { -} - -KerberosContext::~KerberosContext() { -} - -KerberosContext* KerberosContext::New() { - HandleScope scope; - - Local obj = constructor_template->GetFunction()->NewInstance(); - KerberosContext *kerberos_context = ObjectWrap::Unwrap(obj); - - return kerberos_context; -} - -Handle KerberosContext::New(const Arguments &args) { - HandleScope scope; - // Create code object - KerberosContext *kerberos_context = new KerberosContext(); - // Wrap it - kerberos_context->Wrap(args.This()); - // Return the object - return args.This(); -} - -static Persistent response_symbol; - -void KerberosContext::Initialize(Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("KerberosContext")); - - // Property symbols - response_symbol = NODE_PSYMBOL("response"); - - // Getter for the response - constructor_template->InstanceTemplate()->SetAccessor(response_symbol, ResponseGetter); - - // Set up the Symbol for the Class on the Module - target->Set(String::NewSymbol("KerberosContext"), constructor_template->GetFunction()); -} - -// -// Response Setter / Getter -Handle KerberosContext::ResponseGetter(Local property, const AccessorInfo& info) { - HandleScope scope; - gss_client_state *state; - - // Unpack the object - KerberosContext *context = ObjectWrap::Unwrap(info.Holder()); - // Let's grab the response - state = context->state; - // No state no response - if(state == NULL || state->response == NULL) return scope.Close(Null()); - // Return the response - return scope.Close(String::New(state->response)); -} - - - - - - - - - diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.h deleted file mode 100644 index 1b62cba9bfb..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberos_context.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef KERBEROS_CONTEXT_H -#define KERBEROS_CONTEXT_H - -#include -#include -#include - -#include -#include -#include - -extern "C" { - #include "kerberosgss.h" -} - -using namespace v8; -using namespace node; - -class KerberosContext : public ObjectWrap { - -public: - KerberosContext(); - ~KerberosContext(); - - static inline bool HasInstance(Handle val) { - if (!val->IsObject()) return false; - Local obj = val->ToObject(); - return constructor_template->HasInstance(obj); - }; - - // Constructor used for creating new Kerberos objects from C++ - static Persistent constructor_template; - - // Initialize function for the object - static void Initialize(Handle target); - - // Public constructor - static KerberosContext* New(); - - // Handle to the kerberos context - gss_client_state *state; - -private: - static Handle New(const Arguments &args); - - static Handle ResponseGetter(Local property, const AccessorInfo& info); -}; -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.c b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.c deleted file mode 100644 index ddf8c4ad089..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.c +++ /dev/null @@ -1,668 +0,0 @@ -/** - * Copyright (c) 2006-2010 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -#include "kerberosgss.h" - -#include "base64.h" - -#include -#include -#include -#include - -static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min); - -/*extern PyObject *GssException_class; -extern PyObject *KrbException_class; - -char* server_principal_details(const char* service, const char* hostname) -{ - char match[1024]; - int match_len = 0; - char* result = NULL; - - int code; - krb5_context kcontext; - krb5_keytab kt = NULL; - krb5_kt_cursor cursor = NULL; - krb5_keytab_entry entry; - char* pname = NULL; - - // Generate the principal prefix we want to match - snprintf(match, 1024, "%s/%s@", service, hostname); - match_len = strlen(match); - - code = krb5_init_context(&kcontext); - if (code) - { - PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))", - "Cannot initialize Kerberos5 context", code)); - return NULL; - } - - if ((code = krb5_kt_default(kcontext, &kt))) - { - PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))", - "Cannot get default keytab", code)); - goto end; - } - - if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) - { - PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))", - "Cannot get sequence cursor from keytab", code)); - goto end; - } - - while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) - { - if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) - { - PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))", - "Cannot parse principal name from keytab", code)); - goto end; - } - - if (strncmp(pname, match, match_len) == 0) - { - result = malloc(strlen(pname) + 1); - strcpy(result, pname); - krb5_free_unparsed_name(kcontext, pname); - krb5_free_keytab_entry_contents(kcontext, &entry); - break; - } - - krb5_free_unparsed_name(kcontext, pname); - krb5_free_keytab_entry_contents(kcontext, &entry); - } - - if (result == NULL) - { - PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))", - "Principal not found in keytab", -1)); - } - -end: - if (cursor) - krb5_kt_end_seq_get(kcontext, kt, &cursor); - if (kt) - krb5_kt_close(kcontext, kt); - krb5_free_context(kcontext); - - return result; -} -*/ -gss_client_response *authenticate_gss_client_init(const char* service, long int gss_flags, gss_client_state* state) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER; - gss_client_response *response = NULL; - int ret = AUTH_GSS_COMPLETE; - - state->server_name = GSS_C_NO_NAME; - state->context = GSS_C_NO_CONTEXT; - state->gss_flags = gss_flags; - state->username = NULL; - state->response = NULL; - - // Import server name first - name_token.length = strlen(service); - name_token.value = (char *)service; - - maj_stat = gss_import_name(&min_stat, &name_token, gss_krb5_nt_service_name, &state->server_name); - - if (GSS_ERROR(maj_stat)) { - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } - -end: - if(response == NULL) { - response = calloc(1, sizeof(gss_client_response)); - response->return_code = ret; - } - - return response; -} - -gss_client_response *authenticate_gss_client_clean(gss_client_state *state) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - int ret = AUTH_GSS_COMPLETE; - gss_client_response *response = NULL; - - if(state->context != GSS_C_NO_CONTEXT) - maj_stat = gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER); - - if(state->server_name != GSS_C_NO_NAME) - maj_stat = gss_release_name(&min_stat, &state->server_name); - - if(state->username != NULL) { - free(state->username); - state->username = NULL; - } - - if (state->response != NULL) { - free(state->response); - state->response = NULL; - } - - if(response == NULL) { - response = calloc(1, sizeof(gss_client_response)); - response->return_code = ret; - } - - return response; -} - -gss_client_response *authenticate_gss_client_step(gss_client_state* state, const char* challenge) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - int ret = AUTH_GSS_CONTINUE; - gss_client_response *response = NULL; - - // Always clear out the old response - if (state->response != NULL) { - free(state->response); - state->response = NULL; - } - - // If there is a challenge (data from the server) we need to give it to GSS - if (challenge && *challenge) { - int len; - input_token.value = base64_decode(challenge, &len); - input_token.length = len; - } - - // Do GSSAPI step - maj_stat = gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &state->context, - state->server_name, - GSS_C_NO_OID, - (OM_uint32)state->gss_flags, - 0, - GSS_C_NO_CHANNEL_BINDINGS, - &input_token, - NULL, - &output_token, - NULL, - NULL); - - if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) { - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } - - ret = (maj_stat == GSS_S_COMPLETE) ? AUTH_GSS_COMPLETE : AUTH_GSS_CONTINUE; - // Grab the client response to send back to the server - if(output_token.length) { - state->response = base64_encode((const unsigned char *)output_token.value, output_token.length); - maj_stat = gss_release_buffer(&min_stat, &output_token); - } - - // Try to get the user name if we have completed all GSS operations - if (ret == AUTH_GSS_COMPLETE) { - gss_name_t gssuser = GSS_C_NO_NAME; - maj_stat = gss_inquire_context(&min_stat, state->context, &gssuser, NULL, NULL, NULL, NULL, NULL, NULL); - - if(GSS_ERROR(maj_stat)) { - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } - - gss_buffer_desc name_token; - name_token.length = 0; - maj_stat = gss_display_name(&min_stat, gssuser, &name_token, NULL); - - if(GSS_ERROR(maj_stat)) { - if(name_token.value) - gss_release_buffer(&min_stat, &name_token); - gss_release_name(&min_stat, &gssuser); - - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } else { - state->username = (char *)malloc(name_token.length + 1); - strncpy(state->username, (char*) name_token.value, name_token.length); - state->username[name_token.length] = 0; - gss_release_buffer(&min_stat, &name_token); - gss_release_name(&min_stat, &gssuser); - } - } - -end: - if(output_token.value) - gss_release_buffer(&min_stat, &output_token); - if(input_token.value) - free(input_token.value); - - if(response == NULL) { - response = calloc(1, sizeof(gss_client_response)); - response->return_code = ret; - } - - // Return the response - return response; -} - -gss_client_response *authenticate_gss_client_unwrap(gss_client_state *state, const char *challenge) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_client_response *response = NULL; - int ret = AUTH_GSS_CONTINUE; - - // Always clear out the old response - if(state->response != NULL) { - free(state->response); - state->response = NULL; - } - - // If there is a challenge (data from the server) we need to give it to GSS - if(challenge && *challenge) { - int len; - input_token.value = base64_decode(challenge, &len); - input_token.length = len; - } - - // Do GSSAPI step - maj_stat = gss_unwrap(&min_stat, - state->context, - &input_token, - &output_token, - NULL, - NULL); - - if(maj_stat != GSS_S_COMPLETE) { - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } else { - ret = AUTH_GSS_COMPLETE; - } - - // Grab the client response - if(output_token.length) { - state->response = base64_encode((const unsigned char *)output_token.value, output_token.length); - maj_stat = gss_release_buffer(&min_stat, &output_token); - } -end: - if(output_token.value) - gss_release_buffer(&min_stat, &output_token); - if(input_token.value) - free(input_token.value); - - if(response == NULL) { - response = calloc(1, sizeof(gss_client_response)); - response->return_code = ret; - } - - // Return the response - return response; -} - -gss_client_response *authenticate_gss_client_wrap(gss_client_state* state, const char* challenge, const char* user) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - int ret = AUTH_GSS_CONTINUE; - gss_client_response *response = NULL; - char buf[4096], server_conf_flags; - unsigned long buf_size; - - // Always clear out the old response - if(state->response != NULL) { - free(state->response); - state->response = NULL; - } - - if(challenge && *challenge) { - int len; - input_token.value = base64_decode(challenge, &len); - input_token.length = len; - } - - if(user) { - // get bufsize - server_conf_flags = ((char*) input_token.value)[0]; - ((char*) input_token.value)[0] = 0; - buf_size = ntohl(*((long *) input_token.value)); - free(input_token.value); -#ifdef PRINTFS - printf("User: %s, %c%c%c\n", user, - server_conf_flags & GSS_AUTH_P_NONE ? 'N' : '-', - server_conf_flags & GSS_AUTH_P_INTEGRITY ? 'I' : '-', - server_conf_flags & GSS_AUTH_P_PRIVACY ? 'P' : '-'); - printf("Maximum GSS token size is %ld\n", buf_size); -#endif - - // agree to terms (hack!) - buf_size = htonl(buf_size); // not relevant without integrity/privacy - memcpy(buf, &buf_size, 4); - buf[0] = GSS_AUTH_P_NONE; - // server decides if principal can log in as user - strncpy(buf + 4, user, sizeof(buf) - 4); - input_token.value = buf; - input_token.length = 4 + strlen(user); - } - - // Do GSSAPI wrap - maj_stat = gss_wrap(&min_stat, - state->context, - 0, - GSS_C_QOP_DEFAULT, - &input_token, - NULL, - &output_token); - - if (maj_stat != GSS_S_COMPLETE) { - response = gss_error(maj_stat, min_stat); - response->return_code = AUTH_GSS_ERROR; - goto end; - } else - ret = AUTH_GSS_COMPLETE; - // Grab the client response to send back to the server - if (output_token.length) { - state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);; - maj_stat = gss_release_buffer(&min_stat, &output_token); - } -end: - if (output_token.value) - gss_release_buffer(&min_stat, &output_token); - - if(response == NULL) { - response = calloc(1, sizeof(gss_client_response)); - response->return_code = ret; - } - - // Return the response - return response; -} - -int authenticate_gss_server_init(const char *service, gss_server_state *state) -{ - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER; - int ret = AUTH_GSS_COMPLETE; - - state->context = GSS_C_NO_CONTEXT; - state->server_name = GSS_C_NO_NAME; - state->client_name = GSS_C_NO_NAME; - state->server_creds = GSS_C_NO_CREDENTIAL; - state->client_creds = GSS_C_NO_CREDENTIAL; - state->username = NULL; - state->targetname = NULL; - state->response = NULL; - - // Server name may be empty which means we aren't going to create our own creds - size_t service_len = strlen(service); - if (service_len != 0) - { - // Import server name first - name_token.length = strlen(service); - name_token.value = (char *)service; - - maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name); - - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - - // Get credentials - maj_stat = gss_acquire_cred(&min_stat, state->server_name, GSS_C_INDEFINITE, - GSS_C_NO_OID_SET, GSS_C_ACCEPT, &state->server_creds, NULL, NULL); - - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - } - -end: - return ret; -} - -int authenticate_gss_server_clean(gss_server_state *state) -{ - OM_uint32 maj_stat; - OM_uint32 min_stat; - int ret = AUTH_GSS_COMPLETE; - - if (state->context != GSS_C_NO_CONTEXT) - maj_stat = gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER); - if (state->server_name != GSS_C_NO_NAME) - maj_stat = gss_release_name(&min_stat, &state->server_name); - if (state->client_name != GSS_C_NO_NAME) - maj_stat = gss_release_name(&min_stat, &state->client_name); - if (state->server_creds != GSS_C_NO_CREDENTIAL) - maj_stat = gss_release_cred(&min_stat, &state->server_creds); - if (state->client_creds != GSS_C_NO_CREDENTIAL) - maj_stat = gss_release_cred(&min_stat, &state->client_creds); - if (state->username != NULL) - { - free(state->username); - state->username = NULL; - } - if (state->targetname != NULL) - { - free(state->targetname); - state->targetname = NULL; - } - if (state->response != NULL) - { - free(state->response); - state->response = NULL; - } - - return ret; -} - -/*int authenticate_gss_server_step(gss_server_state *state, const char *challenge) -{ - OM_uint32 maj_stat; - OM_uint32 min_stat; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - int ret = AUTH_GSS_CONTINUE; - - // Always clear out the old response - if (state->response != NULL) - { - free(state->response); - state->response = NULL; - } - - // If there is a challenge (data from the server) we need to give it to GSS - if (challenge && *challenge) - { - int len; - input_token.value = base64_decode(challenge, &len); - input_token.length = len; - } - else - { - PyErr_SetString(KrbException_class, "No challenge parameter in request from client"); - ret = AUTH_GSS_ERROR; - goto end; - } - - maj_stat = gss_accept_sec_context(&min_stat, - &state->context, - state->server_creds, - &input_token, - GSS_C_NO_CHANNEL_BINDINGS, - &state->client_name, - NULL, - &output_token, - NULL, - NULL, - &state->client_creds); - - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - - // Grab the server response to send back to the client - if (output_token.length) - { - state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);; - maj_stat = gss_release_buffer(&min_stat, &output_token); - } - - // Get the user name - maj_stat = gss_display_name(&min_stat, state->client_name, &output_token, NULL); - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - state->username = (char *)malloc(output_token.length + 1); - strncpy(state->username, (char*) output_token.value, output_token.length); - state->username[output_token.length] = 0; - - // Get the target name if no server creds were supplied - if (state->server_creds == GSS_C_NO_CREDENTIAL) - { - gss_name_t target_name = GSS_C_NO_NAME; - maj_stat = gss_inquire_context(&min_stat, state->context, NULL, &target_name, NULL, NULL, NULL, NULL, NULL); - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - maj_stat = gss_display_name(&min_stat, target_name, &output_token, NULL); - if (GSS_ERROR(maj_stat)) - { - set_gss_error(maj_stat, min_stat); - ret = AUTH_GSS_ERROR; - goto end; - } - state->targetname = (char *)malloc(output_token.length + 1); - strncpy(state->targetname, (char*) output_token.value, output_token.length); - state->targetname[output_token.length] = 0; - } - - ret = AUTH_GSS_COMPLETE; - -end: - if (output_token.length) - gss_release_buffer(&min_stat, &output_token); - if (input_token.value) - free(input_token.value); - return ret; -} -*/ - -static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min) { - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string; - char buf_maj[512]; - char buf_min[512]; - - do { - maj_stat = gss_display_status (&min_stat, - err_maj, - GSS_C_GSS_CODE, - GSS_C_NO_OID, - &msg_ctx, - &status_string); - if(GSS_ERROR(maj_stat)) - break; - - strncpy(buf_maj, (char*) status_string.value, sizeof(buf_maj)); - gss_release_buffer(&min_stat, &status_string); - - maj_stat = gss_display_status (&min_stat, - err_min, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status_string); - if (!GSS_ERROR(maj_stat)) { - - strncpy(buf_min, (char*) status_string.value , sizeof(buf_min)); - gss_release_buffer(&min_stat, &status_string); - } - } while (!GSS_ERROR(maj_stat) && msg_ctx != 0); -} - -gss_client_response *gss_error(OM_uint32 err_maj, OM_uint32 err_min) { - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string; - char *buf_maj = calloc(512, sizeof(char)); - char *buf_min = calloc(512, sizeof(char)); - char *message = NULL; - gss_client_response *response = calloc(1, sizeof(gss_client_response)); - - do { - maj_stat = gss_display_status (&min_stat, - err_maj, - GSS_C_GSS_CODE, - GSS_C_NO_OID, - &msg_ctx, - &status_string); - if(GSS_ERROR(maj_stat)) - break; - - strncpy(buf_maj, (char*) status_string.value, 512); - gss_release_buffer(&min_stat, &status_string); - - maj_stat = gss_display_status (&min_stat, - err_min, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status_string); - if(!GSS_ERROR(maj_stat)) { - strncpy(buf_min, (char*) status_string.value , 512); - gss_release_buffer(&min_stat, &status_string); - } - } while (!GSS_ERROR(maj_stat) && msg_ctx != 0); - - // Join the strings - message = calloc(1024, sizeof(1)); - // Join the two messages - sprintf(message, "%s, %s", buf_maj, buf_min); - // Free data - free(buf_min); - free(buf_maj); - // Set the message - response->message = message; - // Return the message - return response; -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.h deleted file mode 100644 index 58ac0b714d2..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/kerberosgss.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2006-2009 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ -#ifndef KERBEROS_GSS_H -#define KERBEROS_GSS_H - -#include -#include -#include - -#define krb5_get_err_text(context,code) error_message(code) - -#define AUTH_GSS_ERROR -1 -#define AUTH_GSS_COMPLETE 1 -#define AUTH_GSS_CONTINUE 0 - -#define GSS_AUTH_P_NONE 1 -#define GSS_AUTH_P_INTEGRITY 2 -#define GSS_AUTH_P_PRIVACY 4 - -typedef struct { - int return_code; - char *message; -} gss_client_response; - -typedef struct { - gss_ctx_id_t context; - gss_name_t server_name; - long int gss_flags; - char* username; - char* response; -} gss_client_state; - -typedef struct { - gss_ctx_id_t context; - gss_name_t server_name; - gss_name_t client_name; - gss_cred_id_t server_creds; - gss_cred_id_t client_creds; - char* username; - char* targetname; - char* response; -} gss_server_state; - -// char* server_principal_details(const char* service, const char* hostname); - -gss_client_response *authenticate_gss_client_init(const char* service, long int gss_flags, gss_client_state* state); -gss_client_response *authenticate_gss_client_clean(gss_client_state *state); -gss_client_response *authenticate_gss_client_step(gss_client_state *state, const char *challenge); -gss_client_response *authenticate_gss_client_unwrap(gss_client_state* state, const char* challenge); -gss_client_response *authenticate_gss_client_wrap(gss_client_state* state, const char* challenge, const char* user); - -int authenticate_gss_server_init(const char* service, gss_server_state* state); -int authenticate_gss_server_clean(gss_server_state *state); -// int authenticate_gss_server_step(gss_server_state *state, const char *challenge); - -gss_client_response *gss_error(OM_uint32 err_maj, OM_uint32 err_min); -#endif diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/sspi.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/sspi.js deleted file mode 100644 index d9120fba331..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/sspi.js +++ /dev/null @@ -1,15 +0,0 @@ -// Load the native SSPI classes -var kerberos = require('../build/Release/kerberos') - , Kerberos = kerberos.Kerberos - , SecurityBuffer = require('./win32/wrappers/security_buffer').SecurityBuffer - , SecurityBufferDescriptor = require('./win32/wrappers/security_buffer_descriptor').SecurityBufferDescriptor - , SecurityCredentials = require('./win32/wrappers/security_credentials').SecurityCredentials - , SecurityContext = require('./win32/wrappers/security_context').SecurityContext; -var SSPI = function() { -} - -exports.SSPI = SSPI; -exports.SecurityBuffer = SecurityBuffer; -exports.SecurityBufferDescriptor = SecurityBufferDescriptor; -exports.SecurityCredentials = SecurityCredentials; -exports.SecurityContext = SecurityContext; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.c b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.c deleted file mode 100644 index 502a021c800..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.c +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -#include "base64.h" - -#include -#include - -// base64 tables -static char basis_64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static signed char index_64[128] = -{ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; -#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) - -// base64_encode : base64 encode -// -// value : data to encode -// vlen : length of data -// (result) : new char[] - c-str of result -char *base64_encode(const unsigned char *value, int vlen) -{ - char *result = (char *)malloc((vlen * 4) / 3 + 5); - char *out = result; - unsigned char oval; - - while (vlen >= 3) - { - *out++ = basis_64[value[0] >> 2]; - *out++ = basis_64[((value[0] << 4) & 0x30) | (value[1] >> 4)]; - *out++ = basis_64[((value[1] << 2) & 0x3C) | (value[2] >> 6)]; - *out++ = basis_64[value[2] & 0x3F]; - value += 3; - vlen -= 3; - } - if (vlen > 0) - { - *out++ = basis_64[value[0] >> 2]; - oval = (value[0] << 4) & 0x30; - if (vlen > 1) oval |= value[1] >> 4; - *out++ = basis_64[oval]; - *out++ = (vlen < 2) ? '=' : basis_64[(value[1] << 2) & 0x3C]; - *out++ = '='; - } - *out = '\0'; - - return result; -} - -// base64_decode : base64 decode -// -// value : c-str to decode -// rlen : length of decoded result -// (result) : new unsigned char[] - decoded result -unsigned char *base64_decode(const char *value, int *rlen) -{ - int c1, c2, c3, c4; - int vlen = (int)strlen(value); - unsigned char *result =(unsigned char *)malloc((vlen * 3) / 4 + 1); - unsigned char *out = result; - *rlen = 0; - - while (1) - { - if (value[0]==0) - return result; - c1 = value[0]; - if (CHAR64(c1) == -1) - goto base64_decode_error;; - c2 = value[1]; - if (CHAR64(c2) == -1) - goto base64_decode_error;; - c3 = value[2]; - if ((c3 != '=') && (CHAR64(c3) == -1)) - goto base64_decode_error;; - c4 = value[3]; - if ((c4 != '=') && (CHAR64(c4) == -1)) - goto base64_decode_error;; - - value += 4; - *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4); - *rlen += 1; - if (c3 != '=') - { - *out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2); - *rlen += 1; - if (c4 != '=') - { - *out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4); - *rlen += 1; - } - } - } - -base64_decode_error: - *result = 0; - *rlen = 0; - return result; -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.h deleted file mode 100644 index f0e1f061623..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/base64.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2006-2008 Apple Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - **/ - -char *base64_encode(const unsigned char *value, int vlen); -unsigned char *base64_decode(const char *value, int *rlen); diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.cc deleted file mode 100644 index 7fd521b8a01..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.cc +++ /dev/null @@ -1,53 +0,0 @@ -#include "kerberos.h" -#include -#include -#include "base64.h" -#include "wrappers/security_buffer.h" -#include "wrappers/security_buffer_descriptor.h" -#include "wrappers/security_context.h" -#include "wrappers/security_credentials.h" - -Persistent Kerberos::constructor_template; - -// VException object (causes throw in calling code) -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Kerberos::Kerberos() : ObjectWrap() { -} - -void Kerberos::Initialize(v8::Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(Kerberos::New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Kerberos")); - // Set the symbol - target->ForceSet(String::NewSymbol("Kerberos"), constructor_template->GetFunction()); -} - -Handle Kerberos::New(const Arguments &args) { - // Load the security.dll library - load_library(); - // Create a Kerberos instance - Kerberos *kerberos = new Kerberos(); - // Return the kerberos object - kerberos->Wrap(args.This()); - return args.This(); -} - -// Exporting function -extern "C" void init(Handle target) { - HandleScope scope; - Kerberos::Initialize(target); - SecurityContext::Initialize(target); - SecurityBuffer::Initialize(target); - SecurityBufferDescriptor::Initialize(target); - SecurityCredentials::Initialize(target); -} - -NODE_MODULE(kerberos, init); diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.h deleted file mode 100644 index 8443e78ab1d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef KERBEROS_H -#define KERBEROS_H - -#include -#include -#include - -extern "C" { - #include "kerberos_sspi.h" - #include "base64.h" -} - -using namespace v8; -using namespace node; - -class Kerberos : public ObjectWrap { - -public: - Kerberos(); - ~Kerberos() {}; - - // Constructor used for creating new Kerberos objects from C++ - static Persistent constructor_template; - - // Initialize function for the object - static void Initialize(Handle target); - - // Method available - static Handle AcquireAlternateCredentials(const Arguments &args); - static Handle PrepareOutboundPackage(const Arguments &args); - static Handle DecryptMessage(const Arguments &args); - static Handle EncryptMessage(const Arguments &args); - static Handle QueryContextAttributes(const Arguments &args); - -private: - static Handle New(const Arguments &args); - - // Pointer to context object - SEC_WINNT_AUTH_IDENTITY m_Identity; - // credentials - CredHandle m_Credentials; - // Expiry time for ticket - TimeStamp Expiration; - // package info - SecPkgInfo m_PkgInfo; - // context - CtxtHandle m_Context; - // Do we have a context - bool m_HaveContext; - // Attributes - DWORD CtxtAttr; - - // Handles the uv calls - static void Process(uv_work_t* work_req); - // Called after work is done - static void After(uv_work_t* work_req); -}; - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.c b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.c deleted file mode 100644 index d75c9ab0a6d..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "kerberos_sspi.h" -#include -#include - -static HINSTANCE _sspi_security_dll = NULL; -static HINSTANCE _sspi_secur32_dll = NULL; - -/** - * Encrypt A Message - */ -SECURITY_STATUS SEC_ENTRY _sspi_EncryptMessage(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo) { - // Create function pointer instance - encryptMessage_fn pfn_encryptMessage = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - - // Map function to library method - pfn_encryptMessage = (encryptMessage_fn)GetProcAddress(_sspi_security_dll, "EncryptMessage"); - // Check if the we managed to map function pointer - if(!pfn_encryptMessage) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Call the function - return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo); -} - -/** - * Acquire Credentials - */ -SECURITY_STATUS SEC_ENTRY _sspi_AcquireCredentialsHandle( - LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, - void * pvLogonId, void * pAuthData, SEC_GET_KEY_FN pGetKeyFn, void * pvGetKeyArgument, - PCredHandle phCredential, PTimeStamp ptsExpiry -) { - SECURITY_STATUS status; - // Create function pointer instance - acquireCredentialsHandle_fn pfn_acquireCredentialsHandle = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - - // Map function - #ifdef _UNICODE - pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn)GetProcAddress(_sspi_security_dll, "AcquireCredentialsHandleW"); - #else - pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn)GetProcAddress(_sspi_security_dll, "AcquireCredentialsHandleA"); - #endif - - // Check if the we managed to map function pointer - if(!pfn_acquireCredentialsHandle) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Status - status = (*pfn_acquireCredentialsHandle)(pszPrincipal, pszPackage, fCredentialUse, - pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry - ); - - // Call the function - return status; -} - -/** - * Delete Security Context - */ -SECURITY_STATUS SEC_ENTRY _sspi_DeleteSecurityContext(PCtxtHandle phContext) { - // Create function pointer instance - deleteSecurityContext_fn pfn_deleteSecurityContext = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - // Map function - pfn_deleteSecurityContext = (deleteSecurityContext_fn)GetProcAddress(_sspi_security_dll, "DeleteSecurityContext"); - - // Check if the we managed to map function pointer - if(!pfn_deleteSecurityContext) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Call the function - return (*pfn_deleteSecurityContext)(phContext); -} - -/** - * Decrypt Message - */ -SECURITY_STATUS SEC_ENTRY _sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long pfQOP) { - // Create function pointer instance - decryptMessage_fn pfn_decryptMessage = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - // Map function - pfn_decryptMessage = (decryptMessage_fn)GetProcAddress(_sspi_security_dll, "DecryptMessage"); - - // Check if the we managed to map function pointer - if(!pfn_decryptMessage) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Call the function - return (*pfn_decryptMessage)(phContext, pMessage, MessageSeqNo, pfQOP); -} - -/** - * Initialize Security Context - */ -SECURITY_STATUS SEC_ENTRY _sspi_initializeSecurityContext( - PCredHandle phCredential, PCtxtHandle phContext, - LPSTR pszTargetName, unsigned long fContextReq, - unsigned long Reserved1, unsigned long TargetDataRep, - PSecBufferDesc pInput, unsigned long Reserved2, - PCtxtHandle phNewContext, PSecBufferDesc pOutput, - unsigned long * pfContextAttr, PTimeStamp ptsExpiry -) { - SECURITY_STATUS status; - // Create function pointer instance - initializeSecurityContext_fn pfn_initializeSecurityContext = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - - // Map function - #ifdef _UNICODE - pfn_initializeSecurityContext = (initializeSecurityContext_fn)GetProcAddress(_sspi_security_dll, "InitializeSecurityContextW"); - #else - pfn_initializeSecurityContext = (initializeSecurityContext_fn)GetProcAddress(_sspi_security_dll, "InitializeSecurityContextA"); - #endif - - // Check if the we managed to map function pointer - if(!pfn_initializeSecurityContext) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Execute intialize context - status = (*pfn_initializeSecurityContext)( - phCredential, phContext, pszTargetName, fContextReq, - Reserved1, TargetDataRep, pInput, Reserved2, - phNewContext, pOutput, pfContextAttr, ptsExpiry - ); - - // Call the function - return status; -} -/** - * Query Context Attributes - */ -SECURITY_STATUS SEC_ENTRY _sspi_QueryContextAttributes( - PCtxtHandle phContext, unsigned long ulAttribute, void * pBuffer -) { - // Create function pointer instance - queryContextAttributes_fn pfn_queryContextAttributes = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return -1; - - #ifdef _UNICODE - pfn_queryContextAttributes = (queryContextAttributes_fn)GetProcAddress(_sspi_security_dll, "QueryContextAttributesW"); - #else - pfn_queryContextAttributes = (queryContextAttributes_fn)GetProcAddress(_sspi_security_dll, "QueryContextAttributesA"); - #endif - - // Check if the we managed to map function pointer - if(!pfn_queryContextAttributes) { - printf("GetProcAddress failed.\n"); - return -2; - } - - // Call the function - return (*pfn_queryContextAttributes)( - phContext, ulAttribute, pBuffer - ); -} - -/** - * InitSecurityInterface - */ -PSecurityFunctionTable _ssip_InitSecurityInterface() { - INIT_SECURITY_INTERFACE InitSecurityInterface; - PSecurityFunctionTable pSecurityInterface = NULL; - - // Return error if library not loaded - if(_sspi_security_dll == NULL) return NULL; - - #ifdef _UNICODE - // Get the address of the InitSecurityInterface function. - InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress ( - _sspi_secur32_dll, - TEXT("InitSecurityInterfaceW")); - #else - // Get the address of the InitSecurityInterface function. - InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress ( - _sspi_secur32_dll, - TEXT("InitSecurityInterfaceA")); - #endif - - if(!InitSecurityInterface) { - printf (TEXT("Failed in getting the function address, Error: %x"), GetLastError ()); - return NULL; - } - - // Use InitSecurityInterface to get the function table. - pSecurityInterface = (*InitSecurityInterface)(); - - if(!pSecurityInterface) { - printf (TEXT("Failed in getting the function table, Error: %x"), GetLastError ()); - return NULL; - } - - return pSecurityInterface; -} - -/** - * Load security.dll dynamically - */ -int load_library() { - DWORD err; - // Load the library - _sspi_security_dll = LoadLibrary("security.dll"); - - // Check if the library loaded - if(_sspi_security_dll == NULL) { - err = GetLastError(); - return err; - } - - // Load the library - _sspi_secur32_dll = LoadLibrary("secur32.dll"); - - // Check if the library loaded - if(_sspi_secur32_dll == NULL) { - err = GetLastError(); - return err; - } - - return 0; -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.h deleted file mode 100644 index a3008dc53f8..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/kerberos_sspi.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef SSPI_C_H -#define SSPI_C_H - -#define SECURITY_WIN32 1 - -#include -#include - -/** - * Encrypt A Message - */ -SECURITY_STATUS SEC_ENTRY _sspi_EncryptMessage(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo); - -typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); - -/** - * Acquire Credentials - */ -SECURITY_STATUS SEC_ENTRY _sspi_AcquireCredentialsHandle( - LPSTR pszPrincipal, // Name of principal - LPSTR pszPackage, // Name of package - unsigned long fCredentialUse, // Flags indicating use - void * pvLogonId, // Pointer to logon ID - void * pAuthData, // Package specific data - SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func - void * pvGetKeyArgument, // Value to pass to GetKey() - PCredHandle phCredential, // (out) Cred Handle - PTimeStamp ptsExpiry // (out) Lifetime (optional) -); - -typedef DWORD (WINAPI *acquireCredentialsHandle_fn)( - LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, - void * pvLogonId, void * pAuthData, SEC_GET_KEY_FN pGetKeyFn, void * pvGetKeyArgument, - PCredHandle phCredential, PTimeStamp ptsExpiry - ); - -/** - * Delete Security Context - */ -SECURITY_STATUS SEC_ENTRY _sspi_DeleteSecurityContext( - PCtxtHandle phContext // Context to delete -); - -typedef DWORD (WINAPI *deleteSecurityContext_fn)(PCtxtHandle phContext); - -/** - * Decrypt Message - */ -SECURITY_STATUS SEC_ENTRY _sspi_DecryptMessage( - PCtxtHandle phContext, - PSecBufferDesc pMessage, - unsigned long MessageSeqNo, - unsigned long pfQOP -); - -typedef DWORD (WINAPI *decryptMessage_fn)( - PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long pfQOP); - -/** - * Initialize Security Context - */ -SECURITY_STATUS SEC_ENTRY _sspi_initializeSecurityContext( - PCredHandle phCredential, // Cred to base context - PCtxtHandle phContext, // Existing context (OPT) - LPSTR pszTargetName, // Name of target - unsigned long fContextReq, // Context Requirements - unsigned long Reserved1, // Reserved, MBZ - unsigned long TargetDataRep, // Data rep of target - PSecBufferDesc pInput, // Input Buffers - unsigned long Reserved2, // Reserved, MBZ - PCtxtHandle phNewContext, // (out) New Context handle - PSecBufferDesc pOutput, // (inout) Output Buffers - unsigned long * pfContextAttr, // (out) Context attrs - PTimeStamp ptsExpiry // (out) Life span (OPT) -); - -typedef DWORD (WINAPI *initializeSecurityContext_fn)( - PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq, - unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, - PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long * pfContextAttr, PTimeStamp ptsExpiry); - -/** - * Query Context Attributes - */ -SECURITY_STATUS SEC_ENTRY _sspi_QueryContextAttributes( - PCtxtHandle phContext, // Context to query - unsigned long ulAttribute, // Attribute to query - void * pBuffer // Buffer for attributes -); - -typedef DWORD (WINAPI *queryContextAttributes_fn)( - PCtxtHandle phContext, unsigned long ulAttribute, void * pBuffer); - -/** - * InitSecurityInterface - */ -PSecurityFunctionTable _ssip_InitSecurityInterface(); - -typedef DWORD (WINAPI *initSecurityInterface_fn) (); - -/** - * Load security.dll dynamically - */ -int load_library(); - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.cc deleted file mode 100644 index e7a472f6785..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.cc +++ /dev/null @@ -1,7 +0,0 @@ -#include "worker.h" - -Worker::Worker() { -} - -Worker::~Worker() { -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.h deleted file mode 100644 index f73a4a76855..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/worker.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef WORKER_H_ -#define WORKER_H_ - -#include -#include -#include - -using namespace node; -using namespace v8; - -class Worker { - public: - Worker(); - virtual ~Worker(); - - // libuv's request struct. - uv_work_t request; - // Callback - v8::Persistent callback; - // Parameters - void *parameters; - // Results - void *return_value; - // Did we raise an error - bool error; - // The error message - char *error_message; - // Error code if not message - int error_code; - // Any return code - int return_code; - // Method we are going to fire - void (*execute)(Worker *worker); - Handle (*mapper)(Worker *worker); -}; - -#endif // WORKER_H_ diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc deleted file mode 100644 index e583336fed1..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "security_buffer.h" - -using namespace node; - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -}; - -Persistent SecurityBuffer::constructor_template; - -SecurityBuffer::SecurityBuffer(uint32_t security_type, size_t size) : ObjectWrap() { - this->size = size; - this->data = calloc(size, sizeof(char)); - this->security_type = security_type; - // Set up the data in the sec_buffer - this->sec_buffer.BufferType = security_type; - this->sec_buffer.cbBuffer = (unsigned long)size; - this->sec_buffer.pvBuffer = this->data; -} - -SecurityBuffer::SecurityBuffer(uint32_t security_type, size_t size, void *data) : ObjectWrap() { - this->size = size; - this->data = data; - this->security_type = security_type; - // Set up the data in the sec_buffer - this->sec_buffer.BufferType = security_type; - this->sec_buffer.cbBuffer = (unsigned long)size; - this->sec_buffer.pvBuffer = this->data; -} - -SecurityBuffer::~SecurityBuffer() { - free(this->data); -} - -Handle SecurityBuffer::New(const Arguments &args) { - HandleScope scope; - SecurityBuffer *security_obj; - - if(args.Length() != 2) - return VException("Two parameters needed integer buffer type and [32 bit integer/Buffer] required"); - - if(!args[0]->IsInt32()) - return VException("Two parameters needed integer buffer type and [32 bit integer/Buffer] required"); - - if(!args[1]->IsInt32() && !Buffer::HasInstance(args[1])) - return VException("Two parameters needed integer buffer type and [32 bit integer/Buffer] required"); - - // Unpack buffer type - uint32_t buffer_type = args[0]->ToUint32()->Value(); - - // If we have an integer - if(args[1]->IsInt32()) { - security_obj = new SecurityBuffer(buffer_type, args[1]->ToUint32()->Value()); - } else { - // Get the length of the Buffer - size_t length = Buffer::Length(args[1]->ToObject()); - // Allocate space for the internal void data pointer - void *data = calloc(length, sizeof(char)); - // Write the data to out of V8 heap space - memcpy(data, Buffer::Data(args[1]->ToObject()), length); - // Create new SecurityBuffer - security_obj = new SecurityBuffer(buffer_type, length, data); - } - - // Wrap it - security_obj->Wrap(args.This()); - // Return the object - return args.This(); -} - -Handle SecurityBuffer::ToBuffer(const Arguments &args) { - HandleScope scope; - - // Unpack the Security Buffer object - SecurityBuffer *security_obj = ObjectWrap::Unwrap(args.This()); - // Create a Buffer - Buffer *buffer = Buffer::New((char *)security_obj->data, (size_t)security_obj->size); - - // Return the buffer - return scope.Close(buffer->handle_); -} - -void SecurityBuffer::Initialize(Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("SecurityBuffer")); - - // Set up method for the Kerberos instance - NODE_SET_PROTOTYPE_METHOD(constructor_template, "toBuffer", ToBuffer); - - // Set up class - target->Set(String::NewSymbol("SecurityBuffer"), constructor_template->GetFunction()); -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.h deleted file mode 100644 index d6a567510c6..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef SECURITY_BUFFER_H -#define SECURITY_BUFFER_H - -#include -#include -#include - -#define SECURITY_WIN32 1 - -#include -#include - -using namespace v8; -using namespace node; - -class SecurityBuffer : public ObjectWrap { - public: - SecurityBuffer(uint32_t security_type, size_t size); - SecurityBuffer(uint32_t security_type, size_t size, void *data); - ~SecurityBuffer(); - - // Internal values - void *data; - size_t size; - uint32_t security_type; - SecBuffer sec_buffer; - - // Has instance check - static inline bool HasInstance(Handle val) { - if (!val->IsObject()) return false; - Local obj = val->ToObject(); - return constructor_template->HasInstance(obj); - }; - - // Functions available from V8 - static void Initialize(Handle target); - static Handle ToBuffer(const Arguments &args); - - // Constructor used for creating new Long objects from C++ - static Persistent constructor_template; - - private: - static Handle New(const Arguments &args); -}; - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.js deleted file mode 100644 index 4996163c92f..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer.js +++ /dev/null @@ -1,12 +0,0 @@ -var SecurityBufferNative = require('../../../build/Release/kerberos').SecurityBuffer; - -// Add some attributes -SecurityBufferNative.VERSION = 0; -SecurityBufferNative.EMPTY = 0; -SecurityBufferNative.DATA = 1; -SecurityBufferNative.TOKEN = 2; -SecurityBufferNative.PADDING = 9; -SecurityBufferNative.STREAM = 10; - -// Export the modified class -exports.SecurityBuffer = SecurityBufferNative; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.cc deleted file mode 100644 index 3bda0b768fb..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.cc +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SECURITY_WIN32 1 - -#include "security_buffer_descriptor.h" -#include "security_buffer.h" - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -}; - -Persistent SecurityBufferDescriptor::constructor_template; - -SecurityBufferDescriptor::SecurityBufferDescriptor() : ObjectWrap() { -} - -SecurityBufferDescriptor::SecurityBufferDescriptor(Persistent arrayObject) : ObjectWrap() { - SecurityBuffer *security_obj = NULL; - // Safe reference to array - this->arrayObject = arrayObject; - - // Unpack the array and ensure we have a valid descriptor - this->secBufferDesc.cBuffers = arrayObject->Length(); - this->secBufferDesc.ulVersion = SECBUFFER_VERSION; - - if(arrayObject->Length() == 1) { - // Unwrap the buffer - security_obj = ObjectWrap::Unwrap(arrayObject->Get(0)->ToObject()); - // Assign the buffer - this->secBufferDesc.pBuffers = &security_obj->sec_buffer; - } else { - this->secBufferDesc.pBuffers = new SecBuffer[arrayObject->Length()]; - this->secBufferDesc.cBuffers = arrayObject->Length(); - - // Assign the buffers - for(uint32_t i = 0; i < arrayObject->Length(); i++) { - security_obj = ObjectWrap::Unwrap(arrayObject->Get(i)->ToObject()); - this->secBufferDesc.pBuffers[i].BufferType = security_obj->sec_buffer.BufferType; - this->secBufferDesc.pBuffers[i].pvBuffer = security_obj->sec_buffer.pvBuffer; - this->secBufferDesc.pBuffers[i].cbBuffer = security_obj->sec_buffer.cbBuffer; - } - } -} - -SecurityBufferDescriptor::~SecurityBufferDescriptor() { -} - -size_t SecurityBufferDescriptor::bufferSize() { - SecurityBuffer *security_obj = NULL; - - if(this->secBufferDesc.cBuffers == 1) { - security_obj = ObjectWrap::Unwrap(arrayObject->Get(0)->ToObject()); - return security_obj->size; - } else { - int bytesToAllocate = 0; - - for(unsigned int i = 0; i < this->secBufferDesc.cBuffers; i++) { - bytesToAllocate += this->secBufferDesc.pBuffers[i].cbBuffer; - } - - // Return total size - return bytesToAllocate; - } -} - -char *SecurityBufferDescriptor::toBuffer() { - SecurityBuffer *security_obj = NULL; - char *data = NULL; - - if(this->secBufferDesc.cBuffers == 1) { - security_obj = ObjectWrap::Unwrap(arrayObject->Get(0)->ToObject()); - data = (char *)malloc(security_obj->size * sizeof(char)); - memcpy(data, security_obj->data, security_obj->size); - } else { - size_t bytesToAllocate = this->bufferSize(); - char *data = (char *)calloc(bytesToAllocate, sizeof(char)); - int offset = 0; - - for(unsigned int i = 0; i < this->secBufferDesc.cBuffers; i++) { - memcpy((data + offset), this->secBufferDesc.pBuffers[i].pvBuffer, this->secBufferDesc.pBuffers[i].cbBuffer); - offset +=this->secBufferDesc.pBuffers[i].cbBuffer; - } - - // Return the data - return data; - } - - return data; -} - -Handle SecurityBufferDescriptor::New(const Arguments &args) { - HandleScope scope; - SecurityBufferDescriptor *security_obj; - Persistent arrayObject; - - if(args.Length() != 1) - return VException("There must be 1 argument passed in where the first argument is a [int32 or an Array of SecurityBuffers]"); - - if(!args[0]->IsInt32() && !args[0]->IsArray()) - return VException("There must be 1 argument passed in where the first argument is a [int32 or an Array of SecurityBuffers]"); - - if(args[0]->IsArray()) { - Handle array = Handle::Cast(args[0]); - // Iterate over all items and ensure we the right type - for(uint32_t i = 0; i < array->Length(); i++) { - if(!SecurityBuffer::HasInstance(array->Get(i))) { - return VException("There must be 1 argument passed in where the first argument is a [int32 or an Array of SecurityBuffers]"); - } - } - } - - // We have a single integer - if(args[0]->IsInt32()) { - // Create new SecurityBuffer instance - Local argv[] = {Int32::New(0x02), args[0]}; - Handle security_buffer = SecurityBuffer::constructor_template->GetFunction()->NewInstance(2, argv); - // Create a new array - Local array = Array::New(1); - // Set the first value - array->Set(0, security_buffer); - // Create persistent handle - arrayObject = Persistent::New(array); - // Create descriptor - security_obj = new SecurityBufferDescriptor(arrayObject); - } else { - arrayObject = Persistent::New(Handle::Cast(args[0])); - security_obj = new SecurityBufferDescriptor(arrayObject); - } - - // Wrap it - security_obj->Wrap(args.This()); - // Return the object - return args.This(); -} - -Handle SecurityBufferDescriptor::ToBuffer(const Arguments &args) { - HandleScope scope; - - // Unpack the Security Buffer object - SecurityBufferDescriptor *security_obj = ObjectWrap::Unwrap(args.This()); - - // Get the buffer - char *buffer_data = security_obj->toBuffer(); - size_t buffer_size = security_obj->bufferSize(); - - // Create a Buffer - Buffer *buffer = Buffer::New(buffer_data, buffer_size); - - // Return the buffer - return scope.Close(buffer->handle_); -} - -void SecurityBufferDescriptor::Initialize(Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("SecurityBufferDescriptor")); - - // Set up method for the Kerberos instance - NODE_SET_PROTOTYPE_METHOD(constructor_template, "toBuffer", ToBuffer); - - target->Set(String::NewSymbol("SecurityBufferDescriptor"), constructor_template->GetFunction()); -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.h deleted file mode 100644 index 858863259e5..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef SECURITY_BUFFER_DESCRIPTOR_H -#define SECURITY_BUFFER_DESCRIPTOR_H - -#include -#include -#include - -#include -#include - -using namespace v8; -using namespace node; - -class SecurityBufferDescriptor : public ObjectWrap { - public: - Persistent arrayObject; - SecBufferDesc secBufferDesc; - - SecurityBufferDescriptor(); - SecurityBufferDescriptor(Persistent arrayObject); - ~SecurityBufferDescriptor(); - - // Has instance check - static inline bool HasInstance(Handle val) { - if (!val->IsObject()) return false; - Local obj = val->ToObject(); - return constructor_template->HasInstance(obj); - }; - - char *toBuffer(); - size_t bufferSize(); - - // Functions available from V8 - static void Initialize(Handle target); - static Handle ToBuffer(const Arguments &args); - - // Constructor used for creating new Long objects from C++ - static Persistent constructor_template; - - private: - static Handle New(const Arguments &args); -}; - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.js deleted file mode 100644 index 9421392ea56..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_buffer_descriptor.js +++ /dev/null @@ -1,3 +0,0 @@ -var SecurityBufferDescriptorNative = require('../../../build/Release/kerberos').SecurityBufferDescriptor; -// Export the modified class -exports.SecurityBufferDescriptor = SecurityBufferDescriptorNative; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.cc deleted file mode 100644 index 8c3691a7ea6..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.cc +++ /dev/null @@ -1,1211 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "security_context.h" -#include "security_buffer_descriptor.h" - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) -#endif - -static LPSTR DisplaySECError(DWORD ErrCode); - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -}; - -static Handle VExceptionErrNo(const char *msg, const int errorNumber) { - HandleScope scope; - - Local err = Exception::Error(String::New(msg)); - Local obj = err->ToObject(); - obj->Set(NODE_PSYMBOL("code"), Int32::New(errorNumber)); - return ThrowException(err); -}; - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// UV Lib callbacks -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void Process(uv_work_t* work_req) { - // Grab the worker - Worker *worker = static_cast(work_req->data); - // Execute the worker code - worker->execute(worker); -} - -static void After(uv_work_t* work_req) { - // Grab the scope of the call from Node - v8::HandleScope scope; - - // Get the worker reference - Worker *worker = static_cast(work_req->data); - - // If we have an error - if(worker->error) { - v8::Local err = v8::Exception::Error(v8::String::New(worker->error_message)); - Local obj = err->ToObject(); - obj->Set(NODE_PSYMBOL("code"), Int32::New(worker->error_code)); - v8::Local args[2] = { err, v8::Local::New(v8::Null()) }; - // Execute the error - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } else { - // // Map the data - v8::Handle result = worker->mapper(worker); - // Set up the callback with a null first - v8::Handle args[2] = { v8::Local::New(v8::Null()), result}; - // Wrap the callback function call in a TryCatch so that we can call - // node's FatalException afterwards. This makes it possible to catch - // the exception from JavaScript land using the - // process.on('uncaughtException') event. - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } - - // Clean up the memory - worker->callback.Dispose(); - free(worker->parameters); - delete worker; -} - -Persistent SecurityContext::constructor_template; - -SecurityContext::SecurityContext() : ObjectWrap() { -} - -SecurityContext::~SecurityContext() { - if(this->hasContext) { - _sspi_DeleteSecurityContext(&this->m_Context); - } -} - -Handle SecurityContext::New(const Arguments &args) { - HandleScope scope; - - PSecurityFunctionTable pSecurityInterface = NULL; - DWORD dwNumOfPkgs; - SECURITY_STATUS status; - - // Create code object - SecurityContext *security_obj = new SecurityContext(); - // Get security table interface - pSecurityInterface = _ssip_InitSecurityInterface(); - // Call the security interface - status = (*pSecurityInterface->EnumerateSecurityPackages)( - &dwNumOfPkgs, - &security_obj->m_PkgInfo); - if(status != SEC_E_OK) { - printf(TEXT("Failed in retrieving security packages, Error: %x"), GetLastError()); - return VException("Failed in retrieving security packages"); - } - - // Wrap it - security_obj->Wrap(args.This()); - // Return the object - return args.This(); -} - -Handle SecurityContext::InitializeContextSync(const Arguments &args) { - HandleScope scope; - char *service_principal_name_str = NULL, *input_str = NULL, *decoded_input_str = NULL; - BYTE *out_bound_data_str = NULL; - int decoded_input_str_length = NULL; - // Store reference to security credentials - SecurityCredentials *security_credentials = NULL; - // Status of operation - SECURITY_STATUS status; - - // We need 3 parameters - if(args.Length() != 3) - return VException("Initialize must be called with either [credential:SecurityCredential, servicePrincipalName:string, input:string]"); - - // First parameter must be an instance of SecurityCredentials - if(!SecurityCredentials::HasInstance(args[0])) - return VException("First parameter for Initialize must be an instance of SecurityCredentials"); - - // Second parameter must be a string - if(!args[1]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Third parameter must be a base64 encoded string - if(!args[2]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Let's unpack the values - Local service_principal_name = args[1]->ToString(); - service_principal_name_str = (char *)calloc(service_principal_name->Utf8Length() + 1, sizeof(char)); - service_principal_name->WriteUtf8(service_principal_name_str); - - // Unpack the user name - Local input = args[2]->ToString(); - - if(input->Utf8Length() > 0) { - input_str = (char *)calloc(input->Utf8Length() + 1, sizeof(char)); - input->WriteUtf8(input_str); - - // Now let's get the base64 decoded string - decoded_input_str = (char *)base64_decode(input_str, &decoded_input_str_length); - } - - // Unpack the Security credentials - security_credentials = ObjectWrap::Unwrap(args[0]->ToObject()); - - // Create Security context instance - Local security_context_value = constructor_template->GetFunction()->NewInstance(); - // Unwrap the security context - SecurityContext *security_context = ObjectWrap::Unwrap(security_context_value); - // Add a reference to the security_credentials - security_context->security_credentials = security_credentials; - - // Structures used for c calls - SecBufferDesc ibd, obd; - SecBuffer ib, ob; - - // - // Prepare data structure for returned data from SSPI - ob.BufferType = SECBUFFER_TOKEN; - ob.cbBuffer = security_context->m_PkgInfo->cbMaxToken; - // Allocate space for return data - out_bound_data_str = new BYTE[ob.cbBuffer + sizeof(DWORD)]; - ob.pvBuffer = out_bound_data_str; - // prepare buffer description - obd.cBuffers = 1; - obd.ulVersion = SECBUFFER_VERSION; - obd.pBuffers = &ob; - - // - // Prepare the data we are passing to the SSPI method - if(input->Utf8Length() > 0) { - ib.BufferType = SECBUFFER_TOKEN; - ib.cbBuffer = decoded_input_str_length; - ib.pvBuffer = decoded_input_str; - // prepare buffer description - ibd.cBuffers = 1; - ibd.ulVersion = SECBUFFER_VERSION; - ibd.pBuffers = &ib; - } - - // Perform initialization step - status = _sspi_initializeSecurityContext( - &security_credentials->m_Credentials - , NULL - , const_cast(service_principal_name_str) - , 0x02 // MUTUAL - , 0 - , 0 // Network - , input->Utf8Length() > 0 ? &ibd : NULL - , 0 - , &security_context->m_Context - , &obd - , &security_context->CtxtAttr - , &security_context->Expiration - ); - - // If we have a ok or continue let's prepare the result - if(status == SEC_E_OK - || status == SEC_I_COMPLETE_NEEDED - || status == SEC_I_CONTINUE_NEEDED - || status == SEC_I_COMPLETE_AND_CONTINUE - ) { - security_context->hasContext = true; - security_context->payload = base64_encode((const unsigned char *)ob.pvBuffer, ob.cbBuffer); - } else { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - - // Return security context - return scope.Close(security_context_value); -} - -// -// Async InitializeContext -// -typedef struct SecurityContextStaticInitializeCall { - char *service_principal_name_str; - char *decoded_input_str; - int decoded_input_str_length; - SecurityContext *context; -} SecurityContextStaticInitializeCall; - -static void _initializeContext(Worker *worker) { - // Status of operation - SECURITY_STATUS status; - BYTE *out_bound_data_str = NULL; - SecurityContextStaticInitializeCall *call = (SecurityContextStaticInitializeCall *)worker->parameters; - - // Structures used for c calls - SecBufferDesc ibd, obd; - SecBuffer ib, ob; - - // - // Prepare data structure for returned data from SSPI - ob.BufferType = SECBUFFER_TOKEN; - ob.cbBuffer = call->context->m_PkgInfo->cbMaxToken; - // Allocate space for return data - out_bound_data_str = new BYTE[ob.cbBuffer + sizeof(DWORD)]; - ob.pvBuffer = out_bound_data_str; - // prepare buffer description - obd.cBuffers = 1; - obd.ulVersion = SECBUFFER_VERSION; - obd.pBuffers = &ob; - - // - // Prepare the data we are passing to the SSPI method - if(call->decoded_input_str_length > 0) { - ib.BufferType = SECBUFFER_TOKEN; - ib.cbBuffer = call->decoded_input_str_length; - ib.pvBuffer = call->decoded_input_str; - // prepare buffer description - ibd.cBuffers = 1; - ibd.ulVersion = SECBUFFER_VERSION; - ibd.pBuffers = &ib; - } - - // Perform initialization step - status = _sspi_initializeSecurityContext( - &call->context->security_credentials->m_Credentials - , NULL - , const_cast(call->service_principal_name_str) - , 0x02 // MUTUAL - , 0 - , 0 // Network - , call->decoded_input_str_length > 0 ? &ibd : NULL - , 0 - , &call->context->m_Context - , &obd - , &call->context->CtxtAttr - , &call->context->Expiration - ); - - // If we have a ok or continue let's prepare the result - if(status == SEC_E_OK - || status == SEC_I_COMPLETE_NEEDED - || status == SEC_I_CONTINUE_NEEDED - || status == SEC_I_COMPLETE_AND_CONTINUE - ) { - call->context->hasContext = true; - call->context->payload = base64_encode((const unsigned char *)ob.pvBuffer, ob.cbBuffer); - - // Set the context - worker->return_code = status; - worker->return_value = call->context; - } else { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } - - // Clean up data - if(call->decoded_input_str != NULL) free(call->decoded_input_str); - if(call->service_principal_name_str != NULL) free(call->service_principal_name_str); -} - -static Handle _map_initializeContext(Worker *worker) { - HandleScope scope; - - // Unwrap the security context - SecurityContext *context = (SecurityContext *)worker->return_value; - // Return the value - return scope.Close(context->handle_); -} - -Handle SecurityContext::InitializeContext(const Arguments &args) { - HandleScope scope; - char *service_principal_name_str = NULL, *input_str = NULL, *decoded_input_str = NULL; - int decoded_input_str_length = NULL; - // Store reference to security credentials - SecurityCredentials *security_credentials = NULL; - - // We need 3 parameters - if(args.Length() != 4) - return VException("Initialize must be called with [credential:SecurityCredential, servicePrincipalName:string, input:string, callback:function]"); - - // First parameter must be an instance of SecurityCredentials - if(!SecurityCredentials::HasInstance(args[0])) - return VException("First parameter for Initialize must be an instance of SecurityCredentials"); - - // Second parameter must be a string - if(!args[1]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Third parameter must be a base64 encoded string - if(!args[2]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Third parameter must be a callback - if(!args[3]->IsFunction()) - return VException("Third parameter for Initialize must be a callback function"); - - // Let's unpack the values - Local service_principal_name = args[1]->ToString(); - service_principal_name_str = (char *)calloc(service_principal_name->Utf8Length() + 1, sizeof(char)); - service_principal_name->WriteUtf8(service_principal_name_str); - - // Unpack the user name - Local input = args[2]->ToString(); - - if(input->Utf8Length() > 0) { - input_str = (char *)calloc(input->Utf8Length() + 1, sizeof(char)); - input->WriteUtf8(input_str); - - // Now let's get the base64 decoded string - decoded_input_str = (char *)base64_decode(input_str, &decoded_input_str_length); - // Free original allocation - free(input_str); - } - - // Unpack the Security credentials - security_credentials = ObjectWrap::Unwrap(args[0]->ToObject()); - // Create Security context instance - Local security_context_value = constructor_template->GetFunction()->NewInstance(); - // Unwrap the security context - SecurityContext *security_context = ObjectWrap::Unwrap(security_context_value); - // Add a reference to the security_credentials - security_context->security_credentials = security_credentials; - - // Build the call function - SecurityContextStaticInitializeCall *call = (SecurityContextStaticInitializeCall *)calloc(1, sizeof(SecurityContextStaticInitializeCall)); - call->context = security_context; - call->decoded_input_str = decoded_input_str; - call->decoded_input_str_length = decoded_input_str_length; - call->service_principal_name_str = service_principal_name_str; - - // Callback - Local callback = Local::Cast(args[3]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _initializeContext; - worker->mapper = _map_initializeContext; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Process, (uv_after_work_cb)After); - - // Return no value - return scope.Close(Undefined()); -} - -Handle SecurityContext::PayloadGetter(Local property, const AccessorInfo& info) { - HandleScope scope; - // Unpack the context object - SecurityContext *context = ObjectWrap::Unwrap(info.Holder()); - // Return the low bits - return scope.Close(String::New(context->payload)); -} - -Handle SecurityContext::HasContextGetter(Local property, const AccessorInfo& info) { - HandleScope scope; - // Unpack the context object - SecurityContext *context = ObjectWrap::Unwrap(info.Holder()); - // Return the low bits - return scope.Close(Boolean::New(context->hasContext)); -} - -// -// Async InitializeContextStep -// -typedef struct SecurityContextStepStaticInitializeCall { - char *service_principal_name_str; - char *decoded_input_str; - int decoded_input_str_length; - SecurityContext *context; -} SecurityContextStepStaticInitializeCall; - -static void _initializeContextStep(Worker *worker) { - // Outbound data array - BYTE *out_bound_data_str = NULL; - // Status of operation - SECURITY_STATUS status; - // Unpack data - SecurityContextStepStaticInitializeCall *call = (SecurityContextStepStaticInitializeCall *)worker->parameters; - SecurityContext *context = call->context; - // Structures used for c calls - SecBufferDesc ibd, obd; - SecBuffer ib, ob; - - // - // Prepare data structure for returned data from SSPI - ob.BufferType = SECBUFFER_TOKEN; - ob.cbBuffer = context->m_PkgInfo->cbMaxToken; - // Allocate space for return data - out_bound_data_str = new BYTE[ob.cbBuffer + sizeof(DWORD)]; - ob.pvBuffer = out_bound_data_str; - // prepare buffer description - obd.cBuffers = 1; - obd.ulVersion = SECBUFFER_VERSION; - obd.pBuffers = &ob; - - // - // Prepare the data we are passing to the SSPI method - if(call->decoded_input_str_length > 0) { - ib.BufferType = SECBUFFER_TOKEN; - ib.cbBuffer = call->decoded_input_str_length; - ib.pvBuffer = call->decoded_input_str; - // prepare buffer description - ibd.cBuffers = 1; - ibd.ulVersion = SECBUFFER_VERSION; - ibd.pBuffers = &ib; - } - - // Perform initialization step - status = _sspi_initializeSecurityContext( - &context->security_credentials->m_Credentials - , context->hasContext == true ? &context->m_Context : NULL - , const_cast(call->service_principal_name_str) - , 0x02 // MUTUAL - , 0 - , 0 // Network - , call->decoded_input_str_length ? &ibd : NULL - , 0 - , &context->m_Context - , &obd - , &context->CtxtAttr - , &context->Expiration - ); - - // If we have a ok or continue let's prepare the result - if(status == SEC_E_OK - || status == SEC_I_COMPLETE_NEEDED - || status == SEC_I_CONTINUE_NEEDED - || status == SEC_I_COMPLETE_AND_CONTINUE - ) { - // Set the new payload - if(context->payload != NULL) free(context->payload); - context->payload = base64_encode((const unsigned char *)ob.pvBuffer, ob.cbBuffer); - worker->return_code = status; - worker->return_value = context; - } else { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } - - // Clean up data - if(call->decoded_input_str != NULL) free(call->decoded_input_str); - if(call->service_principal_name_str != NULL) free(call->service_principal_name_str); -} - -static Handle _map_initializeContextStep(Worker *worker) { - HandleScope scope; - // Unwrap the security context - SecurityContext *context = (SecurityContext *)worker->return_value; - // Return the value - return scope.Close(context->handle_); -} - -Handle SecurityContext::InitalizeStep(const Arguments &args) { - HandleScope scope; - - char *service_principal_name_str = NULL, *input_str = NULL, *decoded_input_str = NULL; - int decoded_input_str_length = NULL; - - // We need 3 parameters - if(args.Length() != 3) - return VException("Initialize must be called with [servicePrincipalName:string, input:string, callback:function]"); - - // Second parameter must be a string - if(!args[0]->IsString()) - return VException("First parameter for Initialize must be a string"); - - // Third parameter must be a base64 encoded string - if(!args[1]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Third parameter must be a base64 encoded string - if(!args[2]->IsFunction()) - return VException("Third parameter for Initialize must be a callback function"); - - // Let's unpack the values - Local service_principal_name = args[0]->ToString(); - service_principal_name_str = (char *)calloc(service_principal_name->Utf8Length() + 1, sizeof(char)); - service_principal_name->WriteUtf8(service_principal_name_str); - - // Unpack the user name - Local input = args[1]->ToString(); - - if(input->Utf8Length() > 0) { - input_str = (char *)calloc(input->Utf8Length() + 1, sizeof(char)); - input->WriteUtf8(input_str); - // Now let's get the base64 decoded string - decoded_input_str = (char *)base64_decode(input_str, &decoded_input_str_length); - // Free input string - free(input_str); - } - - // Unwrap the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - - // Create call structure - SecurityContextStepStaticInitializeCall *call = (SecurityContextStepStaticInitializeCall *)calloc(1, sizeof(SecurityContextStepStaticInitializeCall)); - call->context = security_context; - call->decoded_input_str = decoded_input_str; - call->decoded_input_str_length = decoded_input_str_length; - call->service_principal_name_str = service_principal_name_str; - - // Callback - Local callback = Local::Cast(args[2]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _initializeContextStep; - worker->mapper = _map_initializeContextStep; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Process, (uv_after_work_cb)After); - - // Return undefined - return scope.Close(Undefined()); -} - -Handle SecurityContext::InitalizeStepSync(const Arguments &args) { - HandleScope scope; - - char *service_principal_name_str = NULL, *input_str = NULL, *decoded_input_str = NULL; - BYTE *out_bound_data_str = NULL; - int decoded_input_str_length = NULL; - // Status of operation - SECURITY_STATUS status; - - // We need 3 parameters - if(args.Length() != 2) - return VException("Initialize must be called with [servicePrincipalName:string, input:string]"); - - // Second parameter must be a string - if(!args[0]->IsString()) - return VException("First parameter for Initialize must be a string"); - - // Third parameter must be a base64 encoded string - if(!args[1]->IsString()) - return VException("Second parameter for Initialize must be a string"); - - // Let's unpack the values - Local service_principal_name = args[0]->ToString(); - service_principal_name_str = (char *)calloc(service_principal_name->Utf8Length() + 1, sizeof(char)); - service_principal_name->WriteUtf8(service_principal_name_str); - - // Unpack the user name - Local input = args[1]->ToString(); - - if(input->Utf8Length() > 0) { - input_str = (char *)calloc(input->Utf8Length() + 1, sizeof(char)); - input->WriteUtf8(input_str); - // Now let's get the base64 decoded string - decoded_input_str = (char *)base64_decode(input_str, &decoded_input_str_length); - } - - // Unpack the long object - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - SecurityCredentials *security_credentials = security_context->security_credentials; - - // Structures used for c calls - SecBufferDesc ibd, obd; - SecBuffer ib, ob; - - // - // Prepare data structure for returned data from SSPI - ob.BufferType = SECBUFFER_TOKEN; - ob.cbBuffer = security_context->m_PkgInfo->cbMaxToken; - // Allocate space for return data - out_bound_data_str = new BYTE[ob.cbBuffer + sizeof(DWORD)]; - ob.pvBuffer = out_bound_data_str; - // prepare buffer description - obd.cBuffers = 1; - obd.ulVersion = SECBUFFER_VERSION; - obd.pBuffers = &ob; - - // - // Prepare the data we are passing to the SSPI method - if(input->Utf8Length() > 0) { - ib.BufferType = SECBUFFER_TOKEN; - ib.cbBuffer = decoded_input_str_length; - ib.pvBuffer = decoded_input_str; - // prepare buffer description - ibd.cBuffers = 1; - ibd.ulVersion = SECBUFFER_VERSION; - ibd.pBuffers = &ib; - } - - // Perform initialization step - status = _sspi_initializeSecurityContext( - &security_credentials->m_Credentials - , security_context->hasContext == true ? &security_context->m_Context : NULL - , const_cast(service_principal_name_str) - , 0x02 // MUTUAL - , 0 - , 0 // Network - , input->Utf8Length() > 0 ? &ibd : NULL - , 0 - , &security_context->m_Context - , &obd - , &security_context->CtxtAttr - , &security_context->Expiration - ); - - // If we have a ok or continue let's prepare the result - if(status == SEC_E_OK - || status == SEC_I_COMPLETE_NEEDED - || status == SEC_I_CONTINUE_NEEDED - || status == SEC_I_COMPLETE_AND_CONTINUE - ) { - // Set the new payload - if(security_context->payload != NULL) free(security_context->payload); - security_context->payload = base64_encode((const unsigned char *)ob.pvBuffer, ob.cbBuffer); - } else { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - - return scope.Close(Null()); -} - -// -// Async EncryptMessage -// -typedef struct SecurityContextEncryptMessageCall { - SecurityContext *context; - SecurityBufferDescriptor *descriptor; - unsigned long flags; -} SecurityContextEncryptMessageCall; - -static void _encryptMessage(Worker *worker) { - SECURITY_STATUS status; - // Unpack call - SecurityContextEncryptMessageCall *call = (SecurityContextEncryptMessageCall *)worker->parameters; - // Unpack the security context - SecurityContext *context = call->context; - SecurityBufferDescriptor *descriptor = call->descriptor; - - // Let's execute encryption - status = _sspi_EncryptMessage( - &context->m_Context - , call->flags - , &descriptor->secBufferDesc - , 0 - ); - - // We've got ok - if(status == SEC_E_OK) { - int bytesToAllocate = (int)descriptor->bufferSize(); - // Free up existing payload - if(context->payload != NULL) free(context->payload); - // Save the payload - context->payload = base64_encode((unsigned char *)descriptor->toBuffer(), bytesToAllocate); - // Set result - worker->return_code = status; - worker->return_value = context; - } else { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } -} - -static Handle _map_encryptMessage(Worker *worker) { - HandleScope scope; - // Unwrap the security context - SecurityContext *context = (SecurityContext *)worker->return_value; - // Return the value - return scope.Close(context->handle_); -} - -Handle SecurityContext::EncryptMessage(const Arguments &args) { - HandleScope scope; - - if(args.Length() != 3) - return VException("EncryptMessage takes an instance of SecurityBufferDescriptor, an integer flag and a callback function"); - if(!SecurityBufferDescriptor::HasInstance(args[0])) - return VException("EncryptMessage takes an instance of SecurityBufferDescriptor, an integer flag and a callback function"); - if(!args[1]->IsUint32()) - return VException("EncryptMessage takes an instance of SecurityBufferDescriptor, an integer flag and a callback function"); - if(!args[2]->IsFunction()) - return VException("EncryptMessage takes an instance of SecurityBufferDescriptor, an integer flag and a callback function"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - - // Unpack the descriptor - SecurityBufferDescriptor *descriptor = ObjectWrap::Unwrap(args[0]->ToObject()); - - // Create call structure - SecurityContextEncryptMessageCall *call = (SecurityContextEncryptMessageCall *)calloc(1, sizeof(SecurityContextEncryptMessageCall)); - call->context = security_context; - call->descriptor = descriptor; - call->flags = (unsigned long)args[1]->ToInteger()->Value(); - - // Callback - Local callback = Local::Cast(args[2]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _encryptMessage; - worker->mapper = _map_encryptMessage; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Process, (uv_after_work_cb)After); - - // Return undefined - return scope.Close(Undefined()); -} - -Handle SecurityContext::EncryptMessageSync(const Arguments &args) { - HandleScope scope; - SECURITY_STATUS status; - - if(args.Length() != 2) - return VException("EncryptMessageSync takes an instance of SecurityBufferDescriptor and an integer flag"); - if(!SecurityBufferDescriptor::HasInstance(args[0])) - return VException("EncryptMessageSync takes an instance of SecurityBufferDescriptor and an integer flag"); - if(!args[1]->IsUint32()) - return VException("EncryptMessageSync takes an instance of SecurityBufferDescriptor and an integer flag"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - - // Unpack the descriptor - SecurityBufferDescriptor *descriptor = ObjectWrap::Unwrap(args[0]->ToObject()); - - // Let's execute encryption - status = _sspi_EncryptMessage( - &security_context->m_Context - , (unsigned long)args[1]->ToInteger()->Value() - , &descriptor->secBufferDesc - , 0 - ); - - // We've got ok - if(status == SEC_E_OK) { - int bytesToAllocate = (int)descriptor->bufferSize(); - // Free up existing payload - if(security_context->payload != NULL) free(security_context->payload); - // Save the payload - security_context->payload = base64_encode((unsigned char *)descriptor->toBuffer(), bytesToAllocate); - } else { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - - return scope.Close(Null()); -} - -// -// Async DecryptMessage -// -typedef struct SecurityContextDecryptMessageCall { - SecurityContext *context; - SecurityBufferDescriptor *descriptor; -} SecurityContextDecryptMessageCall; - -static void _decryptMessage(Worker *worker) { - unsigned long quality = 0; - SECURITY_STATUS status; - - // Unpack parameters - SecurityContextDecryptMessageCall *call = (SecurityContextDecryptMessageCall *)worker->parameters; - SecurityContext *context = call->context; - SecurityBufferDescriptor *descriptor = call->descriptor; - - // Let's execute encryption - status = _sspi_DecryptMessage( - &context->m_Context - , &descriptor->secBufferDesc - , 0 - , (unsigned long)&quality - ); - - // We've got ok - if(status == SEC_E_OK) { - int bytesToAllocate = (int)descriptor->bufferSize(); - // Free up existing payload - if(context->payload != NULL) free(context->payload); - // Save the payload - context->payload = base64_encode((unsigned char *)descriptor->toBuffer(), bytesToAllocate); - // Set return values - worker->return_code = status; - worker->return_value = context; - } else { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } -} - -static Handle _map_decryptMessage(Worker *worker) { - HandleScope scope; - // Unwrap the security context - SecurityContext *context = (SecurityContext *)worker->return_value; - // Return the value - return scope.Close(context->handle_); -} - -Handle SecurityContext::DecryptMessage(const Arguments &args) { - HandleScope scope; - - if(args.Length() != 2) - return VException("DecryptMessage takes an instance of SecurityBufferDescriptor and a callback function"); - if(!SecurityBufferDescriptor::HasInstance(args[0])) - return VException("DecryptMessage takes an instance of SecurityBufferDescriptor and a callback function"); - if(!args[1]->IsFunction()) - return VException("DecryptMessage takes an instance of SecurityBufferDescriptor and a callback function"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - // Unpack the descriptor - SecurityBufferDescriptor *descriptor = ObjectWrap::Unwrap(args[0]->ToObject()); - // Create call structure - SecurityContextDecryptMessageCall *call = (SecurityContextDecryptMessageCall *)calloc(1, sizeof(SecurityContextDecryptMessageCall)); - call->context = security_context; - call->descriptor = descriptor; - - // Callback - Local callback = Local::Cast(args[1]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _decryptMessage; - worker->mapper = _map_decryptMessage; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Process, (uv_after_work_cb)After); - - // Return undefined - return scope.Close(Undefined()); -} - -Handle SecurityContext::DecryptMessageSync(const Arguments &args) { - HandleScope scope; - unsigned long quality = 0; - SECURITY_STATUS status; - - if(args.Length() != 1) - return VException("DecryptMessageSync takes an instance of SecurityBufferDescriptor"); - if(!SecurityBufferDescriptor::HasInstance(args[0])) - return VException("DecryptMessageSync takes an instance of SecurityBufferDescriptor"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - - // Unpack the descriptor - SecurityBufferDescriptor *descriptor = ObjectWrap::Unwrap(args[0]->ToObject()); - - // Let's execute encryption - status = _sspi_DecryptMessage( - &security_context->m_Context - , &descriptor->secBufferDesc - , 0 - , (unsigned long)&quality - ); - - // We've got ok - if(status == SEC_E_OK) { - int bytesToAllocate = (int)descriptor->bufferSize(); - // Free up existing payload - if(security_context->payload != NULL) free(security_context->payload); - // Save the payload - security_context->payload = base64_encode((unsigned char *)descriptor->toBuffer(), bytesToAllocate); - } else { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - - return scope.Close(Null()); -} - -// -// Async QueryContextAttributes -// -typedef struct SecurityContextQueryContextAttributesCall { - SecurityContext *context; - uint32_t attribute; -} SecurityContextQueryContextAttributesCall; - -static void _queryContextAttributes(Worker *worker) { - SECURITY_STATUS status; - - // Cast to data structure - SecurityContextQueryContextAttributesCall *call = (SecurityContextQueryContextAttributesCall *)worker->parameters; - - // Allocate some space - SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)calloc(1, sizeof(SecPkgContext_Sizes)); - // Let's grab the query context attribute - status = _sspi_QueryContextAttributes( - &call->context->m_Context, - call->attribute, - sizes - ); - - if(status == SEC_E_OK) { - worker->return_code = status; - worker->return_value = sizes; - } else { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } -} - -static Handle _map_queryContextAttributes(Worker *worker) { - HandleScope scope; - - // Cast to data structure - SecurityContextQueryContextAttributesCall *call = (SecurityContextQueryContextAttributesCall *)worker->parameters; - // Unpack the attribute - uint32_t attribute = call->attribute; - - // Convert data - if(attribute == SECPKG_ATTR_SIZES) { - SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)worker->return_value; - // Create object - Local value = Object::New(); - value->Set(String::New("maxToken"), Integer::New(sizes->cbMaxToken)); - value->Set(String::New("maxSignature"), Integer::New(sizes->cbMaxSignature)); - value->Set(String::New("blockSize"), Integer::New(sizes->cbBlockSize)); - value->Set(String::New("securityTrailer"), Integer::New(sizes->cbSecurityTrailer)); - return scope.Close(value); - } - - // Return the value - return scope.Close(Null()); -} - -Handle SecurityContext::QueryContextAttributes(const Arguments &args) { - HandleScope scope; - - if(args.Length() != 2) - return VException("QueryContextAttributesSync method takes a an integer Attribute specifier and a callback function"); - if(!args[0]->IsInt32()) - return VException("QueryContextAttributes method takes a an integer Attribute specifier and a callback function"); - if(!args[1]->IsFunction()) - return VException("QueryContextAttributes method takes a an integer Attribute specifier and a callback function"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - - // Unpack the int value - uint32_t attribute = args[0]->ToInt32()->Value(); - - // Check that we have a supported attribute - if(attribute != SECPKG_ATTR_SIZES) - return VException("QueryContextAttributes only supports the SECPKG_ATTR_SIZES attribute"); - - // Create call structure - SecurityContextQueryContextAttributesCall *call = (SecurityContextQueryContextAttributesCall *)calloc(1, sizeof(SecurityContextQueryContextAttributesCall)); - call->attribute = attribute; - call->context = security_context; - - // Callback - Local callback = Local::Cast(args[1]); - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _queryContextAttributes; - worker->mapper = _map_queryContextAttributes; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, Process, (uv_after_work_cb)After); - - // Return undefined - return scope.Close(Undefined()); -} - -Handle SecurityContext::QueryContextAttributesSync(const Arguments &args) { - HandleScope scope; - SECURITY_STATUS status; - - if(args.Length() != 1) - return VException("QueryContextAttributesSync method takes a an integer Attribute specifier"); - if(!args[0]->IsInt32()) - return VException("QueryContextAttributesSync method takes a an integer Attribute specifier"); - - // Unpack the security context - SecurityContext *security_context = ObjectWrap::Unwrap(args.This()); - uint32_t attribute = args[0]->ToInt32()->Value(); - - if(attribute != SECPKG_ATTR_SIZES) - return VException("QueryContextAttributes only supports the SECPKG_ATTR_SIZES attribute"); - - // Check what attribute we are asking for - if(attribute == SECPKG_ATTR_SIZES) { - SecPkgContext_Sizes sizes; - - // Let's grab the query context attribute - status = _sspi_QueryContextAttributes( - &security_context->m_Context, - attribute, - &sizes - ); - - if(status == SEC_E_OK) { - Local value = Object::New(); - value->Set(String::New("maxToken"), Integer::New(sizes.cbMaxToken)); - value->Set(String::New("maxSignature"), Integer::New(sizes.cbMaxSignature)); - value->Set(String::New("blockSize"), Integer::New(sizes.cbBlockSize)); - value->Set(String::New("securityTrailer"), Integer::New(sizes.cbSecurityTrailer)); - return scope.Close(value); - } else { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - } - - return scope.Close(Null()); -} - -void SecurityContext::Initialize(Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("SecurityContext")); - - // Class methods - NODE_SET_METHOD(constructor_template, "initializeSync", InitializeContextSync); - NODE_SET_METHOD(constructor_template, "initialize", InitializeContext); - - // Set up method for the instance - NODE_SET_PROTOTYPE_METHOD(constructor_template, "initializeSync", InitalizeStepSync); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "initialize", InitalizeStep); - - NODE_SET_PROTOTYPE_METHOD(constructor_template, "decryptMessageSync", DecryptMessageSync); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "decryptMessage", DecryptMessage); - - NODE_SET_PROTOTYPE_METHOD(constructor_template, "queryContextAttributesSync", QueryContextAttributesSync); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "queryContextAttributes", QueryContextAttributes); - - NODE_SET_PROTOTYPE_METHOD(constructor_template, "encryptMessageSync", EncryptMessageSync); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "encryptMessage", EncryptMessage); - - // Getters for correct serialization of the object - constructor_template->InstanceTemplate()->SetAccessor(String::NewSymbol("payload"), PayloadGetter); - // Getters for correct serialization of the object - constructor_template->InstanceTemplate()->SetAccessor(String::NewSymbol("hasContext"), HasContextGetter); - - // Set template class name - target->Set(String::NewSymbol("SecurityContext"), constructor_template->GetFunction()); -} - -static LPSTR DisplaySECError(DWORD ErrCode) { - LPSTR pszName = NULL; // WinError.h - - switch(ErrCode) { - case SEC_E_BUFFER_TOO_SMALL: - pszName = "SEC_E_BUFFER_TOO_SMALL - The message buffer is too small. Used with the Digest SSP."; - break; - - case SEC_E_CRYPTO_SYSTEM_INVALID: - pszName = "SEC_E_CRYPTO_SYSTEM_INVALID - The cipher chosen for the security context is not supported. Used with the Digest SSP."; - break; - case SEC_E_INCOMPLETE_MESSAGE: - pszName = "SEC_E_INCOMPLETE_MESSAGE - The data in the input buffer is incomplete. The application needs to read more data from the server and call DecryptMessageSync (General) again."; - break; - - case SEC_E_INVALID_HANDLE: - pszName = "SEC_E_INVALID_HANDLE - A context handle that is not valid was specified in the phContext parameter. Used with the Digest and Schannel SSPs."; - break; - - case SEC_E_INVALID_TOKEN: - pszName = "SEC_E_INVALID_TOKEN - The buffers are of the wrong type or no buffer of type SECBUFFER_DATA was found. Used with the Schannel SSP."; - break; - - case SEC_E_MESSAGE_ALTERED: - pszName = "SEC_E_MESSAGE_ALTERED - The message has been altered. Used with the Digest and Schannel SSPs."; - break; - - case SEC_E_OUT_OF_SEQUENCE: - pszName = "SEC_E_OUT_OF_SEQUENCE - The message was not received in the correct sequence."; - break; - - case SEC_E_QOP_NOT_SUPPORTED: - pszName = "SEC_E_QOP_NOT_SUPPORTED - Neither confidentiality nor integrity are supported by the security context. Used with the Digest SSP."; - break; - - case SEC_I_CONTEXT_EXPIRED: - pszName = "SEC_I_CONTEXT_EXPIRED - The message sender has finished using the connection and has initiated a shutdown."; - break; - - case SEC_I_RENEGOTIATE: - pszName = "SEC_I_RENEGOTIATE - The remote party requires a new handshake sequence or the application has just initiated a shutdown."; - break; - - case SEC_E_ENCRYPT_FAILURE: - pszName = "SEC_E_ENCRYPT_FAILURE - The specified data could not be encrypted."; - break; - - case SEC_E_DECRYPT_FAILURE: - pszName = "SEC_E_DECRYPT_FAILURE - The specified data could not be decrypted."; - break; - case -1: - pszName = "Failed to load security.dll library"; - break; - } - - return pszName; -} - diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.h deleted file mode 100644 index b0059e39eb4..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef SECURITY_CONTEXT_H -#define SECURITY_CONTEXT_H - -#include -#include -#include - -#define SECURITY_WIN32 1 - -#include -#include -#include "security_credentials.h" -#include "../worker.h" - -extern "C" { - #include "../kerberos_sspi.h" - #include "../base64.h" -} - -using namespace v8; -using namespace node; - -class SecurityContext : public ObjectWrap { - public: - SecurityContext(); - ~SecurityContext(); - - // Security info package - PSecPkgInfo m_PkgInfo; - // Do we have a context - bool hasContext; - // Reference to security credentials - SecurityCredentials *security_credentials; - // Security context - CtxtHandle m_Context; - // Attributes - DWORD CtxtAttr; - // Expiry time for ticket - TimeStamp Expiration; - // Payload - char *payload; - - // Has instance check - static inline bool HasInstance(Handle val) { - if (!val->IsObject()) return false; - Local obj = val->ToObject(); - return constructor_template->HasInstance(obj); - }; - - // Functions available from V8 - static void Initialize(Handle target); - - static Handle InitializeContext(const Arguments &args); - static Handle InitializeContextSync(const Arguments &args); - - static Handle InitalizeStep(const Arguments &args); - static Handle InitalizeStepSync(const Arguments &args); - - static Handle DecryptMessage(const Arguments &args); - static Handle DecryptMessageSync(const Arguments &args); - - static Handle QueryContextAttributesSync(const Arguments &args); - static Handle QueryContextAttributes(const Arguments &args); - - static Handle EncryptMessageSync(const Arguments &args); - static Handle EncryptMessage(const Arguments &args); - - // Payload getter - static Handle PayloadGetter(Local property, const AccessorInfo& info); - // hasContext getter - static Handle HasContextGetter(Local property, const AccessorInfo& info); - - // Constructor used for creating new Long objects from C++ - static Persistent constructor_template; - - private: - // Create a new instance - static Handle New(const Arguments &args); - // // Handles the uv calls - // static void Process(uv_work_t* work_req); - // // Called after work is done - // static void After(uv_work_t* work_req); -}; - -#endif diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.js deleted file mode 100644 index ef04e9274e7..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_context.js +++ /dev/null @@ -1,3 +0,0 @@ -var SecurityContextNative = require('../../../build/Release/kerberos').SecurityContext; -// Export the modified class -exports.SecurityContext = SecurityContextNative; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.cc deleted file mode 100644 index 14c1cdc5070..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.cc +++ /dev/null @@ -1,468 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "security_credentials.h" - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) -#endif - -static LPSTR DisplaySECError(DWORD ErrCode); - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -}; - -static Handle VExceptionErrNo(const char *msg, const int errorNumber) { - HandleScope scope; - - Local err = Exception::Error(String::New(msg)); - Local obj = err->ToObject(); - obj->Set(NODE_PSYMBOL("code"), Int32::New(errorNumber)); - return ThrowException(err); -}; - -Persistent SecurityCredentials::constructor_template; - -SecurityCredentials::SecurityCredentials() : ObjectWrap() { -} - -SecurityCredentials::~SecurityCredentials() { -} - -Handle SecurityCredentials::New(const Arguments &args) { - HandleScope scope; - - // Create security credentials instance - SecurityCredentials *security_credentials = new SecurityCredentials(); - // Wrap it - security_credentials->Wrap(args.This()); - // Return the object - return args.This(); -} - -Handle SecurityCredentials::AquireSync(const Arguments &args) { - HandleScope scope; - char *package_str = NULL, *username_str = NULL, *password_str = NULL, *domain_str = NULL; - // Status of operation - SECURITY_STATUS status; - - // Unpack the variables - if(args.Length() != 2 && args.Length() != 3 && args.Length() != 4) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string]]"); - - if(!args[0]->IsString()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string]]"); - - if(!args[1]->IsString()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string]]"); - - if(args.Length() == 3 && !args[2]->IsString()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string]]"); - - if(args.Length() == 4 && (!args[3]->IsString() && !args[3]->IsUndefined() && !args[3]->IsNull())) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string]]"); - - // Unpack the package - Local package = args[0]->ToString(); - package_str = (char *)calloc(package->Utf8Length() + 1, sizeof(char)); - package->WriteUtf8(package_str); - - // Unpack the user name - Local username = args[1]->ToString(); - username_str = (char *)calloc(username->Utf8Length() + 1, sizeof(char)); - username->WriteUtf8(username_str); - - // If we have a password - if(args.Length() == 3 || args.Length() == 4) { - Local password = args[2]->ToString(); - password_str = (char *)calloc(password->Utf8Length() + 1, sizeof(char)); - password->WriteUtf8(password_str); - } - - // If we have a domain - if(args.Length() == 4 && args[3]->IsString()) { - Local domain = args[3]->ToString(); - domain_str = (char *)calloc(domain->Utf8Length() + 1, sizeof(char)); - domain->WriteUtf8(domain_str); - } - - // Create Security instance - Local security_credentials_value = constructor_template->GetFunction()->NewInstance(); - - // Unwrap the credentials - SecurityCredentials *security_credentials = ObjectWrap::Unwrap(security_credentials_value); - - // If we have domain string - if(domain_str != NULL) { - security_credentials->m_Identity.Domain = USTR(_tcsdup(domain_str)); - security_credentials->m_Identity.DomainLength = (unsigned long)_tcslen(domain_str); - } else { - security_credentials->m_Identity.Domain = NULL; - security_credentials->m_Identity.DomainLength = 0; - } - - // Set up the user - security_credentials->m_Identity.User = USTR(_tcsdup(username_str)); - security_credentials->m_Identity.UserLength = (unsigned long)_tcslen(username_str); - - // If we have a password string - if(password_str != NULL) { - // Set up the password - security_credentials->m_Identity.Password = USTR(_tcsdup(password_str)); - security_credentials->m_Identity.PasswordLength = (unsigned long)_tcslen(password_str); - } - - #ifdef _UNICODE - security_credentials->m_Identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - #else - security_credentials->m_Identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; - #endif - - // Attempt to acquire credentials - status = _sspi_AcquireCredentialsHandle( - NULL, - package_str, - SECPKG_CRED_OUTBOUND, - NULL, - password_str != NULL ? &security_credentials->m_Identity : NULL, - NULL, NULL, - &security_credentials->m_Credentials, - &security_credentials->Expiration - ); - - // We have an error - if(status != SEC_E_OK) { - LPSTR err_message = DisplaySECError(status); - - if(err_message != NULL) { - return VExceptionErrNo(err_message, status); - } else { - return VExceptionErrNo("Unknown error", status); - } - } - - // Make object persistent - Persistent persistent = Persistent::New(security_credentials_value); - // Return the object - return scope.Close(persistent); -} - -// Call structs -typedef struct SecurityCredentialCall { - char *package_str; - char *username_str; - char *password_str; - char *domain_str; - SecurityCredentials *credentials; -} SecurityCredentialCall; - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// authGSSClientInit -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -static void _authSSPIAquire(Worker *worker) { - // Status of operation - SECURITY_STATUS status; - - // Unpack data - SecurityCredentialCall *call = (SecurityCredentialCall *)worker->parameters; - - // Unwrap the credentials - SecurityCredentials *security_credentials = (SecurityCredentials *)call->credentials; - - // If we have domain string - if(call->domain_str != NULL) { - security_credentials->m_Identity.Domain = USTR(_tcsdup(call->domain_str)); - security_credentials->m_Identity.DomainLength = (unsigned long)_tcslen(call->domain_str); - } else { - security_credentials->m_Identity.Domain = NULL; - security_credentials->m_Identity.DomainLength = 0; - } - - // Set up the user - security_credentials->m_Identity.User = USTR(_tcsdup(call->username_str)); - security_credentials->m_Identity.UserLength = (unsigned long)_tcslen(call->username_str); - - // If we have a password string - if(call->password_str != NULL) { - // Set up the password - security_credentials->m_Identity.Password = USTR(_tcsdup(call->password_str)); - security_credentials->m_Identity.PasswordLength = (unsigned long)_tcslen(call->password_str); - } - - #ifdef _UNICODE - security_credentials->m_Identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - #else - security_credentials->m_Identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; - #endif - - // Attempt to acquire credentials - status = _sspi_AcquireCredentialsHandle( - NULL, - call->package_str, - SECPKG_CRED_OUTBOUND, - NULL, - call->password_str != NULL ? &security_credentials->m_Identity : NULL, - NULL, NULL, - &security_credentials->m_Credentials, - &security_credentials->Expiration - ); - - // We have an error - if(status != SEC_E_OK) { - worker->error = TRUE; - worker->error_code = status; - worker->error_message = DisplaySECError(status); - } else { - worker->return_code = status; - worker->return_value = security_credentials; - } - - // Free up parameter structure - if(call->package_str != NULL) free(call->package_str); - if(call->domain_str != NULL) free(call->domain_str); - if(call->password_str != NULL) free(call->password_str); - if(call->username_str != NULL) free(call->username_str); - free(call); -} - -static Handle _map_authSSPIAquire(Worker *worker) { - HandleScope scope; - - // Unpack the credentials - SecurityCredentials *security_credentials = (SecurityCredentials *)worker->return_value; - // Make object persistent - Persistent persistent = Persistent::New(security_credentials->handle_); - // Return the object - return scope.Close(persistent); -} - -Handle SecurityCredentials::Aquire(const Arguments &args) { - HandleScope scope; - char *package_str = NULL, *username_str = NULL, *password_str = NULL, *domain_str = NULL; - // Unpack the variables - if(args.Length() != 2 && args.Length() != 3 && args.Length() != 4 && args.Length() != 5) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - if(!args[0]->IsString()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - if(!args[1]->IsString()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - if(args.Length() == 3 && (!args[2]->IsString() && !args[2]->IsFunction())) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - if(args.Length() == 4 && (!args[3]->IsString() && !args[3]->IsUndefined() && !args[3]->IsNull()) && !args[3]->IsFunction()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - if(args.Length() == 5 && !args[4]->IsFunction()) - return VException("Aquire must be called with either [package:string, username:string, [password:string, domain:string], callback:function]"); - - Local callback; - - // Figure out which parameter is the callback - if(args.Length() == 5) { - callback = Local::Cast(args[4]); - } else if(args.Length() == 4) { - callback = Local::Cast(args[3]); - } else if(args.Length() == 3) { - callback = Local::Cast(args[2]); - } - - // Unpack the package - Local package = args[0]->ToString(); - package_str = (char *)calloc(package->Utf8Length() + 1, sizeof(char)); - package->WriteUtf8(package_str); - - // Unpack the user name - Local username = args[1]->ToString(); - username_str = (char *)calloc(username->Utf8Length() + 1, sizeof(char)); - username->WriteUtf8(username_str); - - // If we have a password - if(args.Length() == 3 || args.Length() == 4 || args.Length() == 5) { - Local password = args[2]->ToString(); - password_str = (char *)calloc(password->Utf8Length() + 1, sizeof(char)); - password->WriteUtf8(password_str); - } - - // If we have a domain - if((args.Length() == 4 || args.Length() == 5) && args[3]->IsString()) { - Local domain = args[3]->ToString(); - domain_str = (char *)calloc(domain->Utf8Length() + 1, sizeof(char)); - domain->WriteUtf8(domain_str); - } - - // Create reference object - Local security_credentials_value = constructor_template->GetFunction()->NewInstance(); - // Unwrap object - SecurityCredentials *security_credentials = ObjectWrap::Unwrap(security_credentials_value); - - // Allocate call structure - SecurityCredentialCall *call = (SecurityCredentialCall *)calloc(1, sizeof(SecurityCredentialCall)); - call->domain_str = domain_str; - call->package_str = package_str; - call->password_str = password_str; - call->username_str = username_str; - call->credentials = security_credentials; - - // Let's allocate some space - Worker *worker = new Worker(); - worker->error = false; - worker->request.data = worker; - worker->callback = Persistent::New(callback); - worker->parameters = call; - worker->execute = _authSSPIAquire; - worker->mapper = _map_authSSPIAquire; - - // Schedule the worker with lib_uv - uv_queue_work(uv_default_loop(), &worker->request, SecurityCredentials::Process, (uv_after_work_cb)SecurityCredentials::After); - - // Return the undefined value - return scope.Close(Undefined()); -} - -void SecurityCredentials::Initialize(Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("SecurityCredentials")); - - // Class methods - NODE_SET_METHOD(constructor_template, "aquireSync", AquireSync); - NODE_SET_METHOD(constructor_template, "aquire", Aquire); - - // Set the class on the target module - target->Set(String::NewSymbol("SecurityCredentials"), constructor_template->GetFunction()); - - // Attempt to load the security.dll library - load_library(); -} - -static LPSTR DisplaySECError(DWORD ErrCode) { - LPSTR pszName = NULL; // WinError.h - - switch(ErrCode) { - case SEC_E_BUFFER_TOO_SMALL: - pszName = "SEC_E_BUFFER_TOO_SMALL - The message buffer is too small. Used with the Digest SSP."; - break; - - case SEC_E_CRYPTO_SYSTEM_INVALID: - pszName = "SEC_E_CRYPTO_SYSTEM_INVALID - The cipher chosen for the security context is not supported. Used with the Digest SSP."; - break; - case SEC_E_INCOMPLETE_MESSAGE: - pszName = "SEC_E_INCOMPLETE_MESSAGE - The data in the input buffer is incomplete. The application needs to read more data from the server and call DecryptMessage (General) again."; - break; - - case SEC_E_INVALID_HANDLE: - pszName = "SEC_E_INVALID_HANDLE - A context handle that is not valid was specified in the phContext parameter. Used with the Digest and Schannel SSPs."; - break; - - case SEC_E_INVALID_TOKEN: - pszName = "SEC_E_INVALID_TOKEN - The buffers are of the wrong type or no buffer of type SECBUFFER_DATA was found. Used with the Schannel SSP."; - break; - - case SEC_E_MESSAGE_ALTERED: - pszName = "SEC_E_MESSAGE_ALTERED - The message has been altered. Used with the Digest and Schannel SSPs."; - break; - - case SEC_E_OUT_OF_SEQUENCE: - pszName = "SEC_E_OUT_OF_SEQUENCE - The message was not received in the correct sequence."; - break; - - case SEC_E_QOP_NOT_SUPPORTED: - pszName = "SEC_E_QOP_NOT_SUPPORTED - Neither confidentiality nor integrity are supported by the security context. Used with the Digest SSP."; - break; - - case SEC_I_CONTEXT_EXPIRED: - pszName = "SEC_I_CONTEXT_EXPIRED - The message sender has finished using the connection and has initiated a shutdown."; - break; - - case SEC_I_RENEGOTIATE: - pszName = "SEC_I_RENEGOTIATE - The remote party requires a new handshake sequence or the application has just initiated a shutdown."; - break; - - case SEC_E_ENCRYPT_FAILURE: - pszName = "SEC_E_ENCRYPT_FAILURE - The specified data could not be encrypted."; - break; - - case SEC_E_DECRYPT_FAILURE: - pszName = "SEC_E_DECRYPT_FAILURE - The specified data could not be decrypted."; - break; - case -1: - pszName = "Failed to load security.dll library"; - break; - - } - - return pszName; -} - -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// UV Lib callbacks -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -void SecurityCredentials::Process(uv_work_t* work_req) { - // Grab the worker - Worker *worker = static_cast(work_req->data); - // Execute the worker code - worker->execute(worker); -} - -void SecurityCredentials::After(uv_work_t* work_req) { - // Grab the scope of the call from Node - v8::HandleScope scope; - - // Get the worker reference - Worker *worker = static_cast(work_req->data); - - // If we have an error - if(worker->error) { - v8::Local err = v8::Exception::Error(v8::String::New(worker->error_message)); - Local obj = err->ToObject(); - obj->Set(NODE_PSYMBOL("code"), Int32::New(worker->error_code)); - v8::Local args[2] = { err, v8::Local::New(v8::Null()) }; - // Execute the error - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } else { - // // Map the data - v8::Handle result = worker->mapper(worker); - // Set up the callback with a null first - v8::Handle args[2] = { v8::Local::New(v8::Null()), result}; - // Wrap the callback function call in a TryCatch so that we can call - // node's FatalException afterwards. This makes it possible to catch - // the exception from JavaScript land using the - // process.on('uncaughtException') event. - v8::TryCatch try_catch; - // Call the callback - worker->callback->Call(v8::Context::GetCurrent()->Global(), ARRAY_SIZE(args), args); - // If we have an exception handle it as a fatalexception - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } - - // Clean up the memory - worker->callback.Dispose(); - delete worker; -} - diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.h deleted file mode 100644 index 10b3edaa3bd..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef SECURITY_CREDENTIALS_H -#define SECURITY_CREDENTIALS_H - -#include -#include -#include - -#define SECURITY_WIN32 1 - -#include -#include -#include -#include "../worker.h" -#include - -extern "C" { - #include "../kerberos_sspi.h" -} - -// SEC_WINNT_AUTH_IDENTITY makes it unusually hard -// to compile for both Unicode and ansi, so I use this macro: -#ifdef _UNICODE -#define USTR(str) (str) -#else -#define USTR(str) ((unsigned char*)(str)) -#endif - -using namespace v8; -using namespace node; - -class SecurityCredentials : public ObjectWrap { - public: - SecurityCredentials(); - ~SecurityCredentials(); - - // Pointer to context object - SEC_WINNT_AUTH_IDENTITY m_Identity; - // credentials - CredHandle m_Credentials; - // Expiry time for ticket - TimeStamp Expiration; - - // Has instance check - static inline bool HasInstance(Handle val) { - if (!val->IsObject()) return false; - Local obj = val->ToObject(); - return constructor_template->HasInstance(obj); - }; - - // Functions available from V8 - static void Initialize(Handle target); - static Handle AquireSync(const Arguments &args); - static Handle Aquire(const Arguments &args); - - // Constructor used for creating new Long objects from C++ - static Persistent constructor_template; - - private: - // Create a new instance - static Handle New(const Arguments &args); - // Handles the uv calls - static void Process(uv_work_t* work_req); - // Called after work is done - static void After(uv_work_t* work_req); -}; - -#endif \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.js deleted file mode 100644 index 4215c92740f..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/win32/wrappers/security_credentials.js +++ /dev/null @@ -1,22 +0,0 @@ -var SecurityCredentialsNative = require('../../../build/Release/kerberos').SecurityCredentials; - -// Add simple kebros helper -SecurityCredentialsNative.aquire_kerberos = function(username, password, domain, callback) { - if(typeof password == 'function') { - callback = password; - password = null; - } else if(typeof domain == 'function') { - callback = domain; - domain = null; - } - - // We are going to use the async version - if(typeof callback == 'function') { - return SecurityCredentialsNative.aquire('Kerberos', username, password, domain, callback); - } else { - return SecurityCredentialsNative.aquireSync('Kerberos', username, password, domain); - } -} - -// Export the modified class -exports.SecurityCredentials = SecurityCredentialsNative; \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.cc b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.cc deleted file mode 100644 index e7a472f6785..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.cc +++ /dev/null @@ -1,7 +0,0 @@ -#include "worker.h" - -Worker::Worker() { -} - -Worker::~Worker() { -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.h b/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.h deleted file mode 100644 index c5f86f5219a..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/lib/worker.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef WORKER_H_ -#define WORKER_H_ - -#include -#include -#include - -using namespace node; -using namespace v8; - -class Worker { - public: - Worker(); - virtual ~Worker(); - - // libuv's request struct. - uv_work_t request; - // Callback - v8::Persistent callback; - // // Arguments - // v8::Persistent arguments; - // Parameters - void *parameters; - // Results - void *return_value; - // Did we raise an error - bool error; - // The error message - char *error_message; - // Error code if not message - int error_code; - // Any return code - int return_code; - // Method we are going to fire - void (*execute)(Worker *worker); - Handle (*mapper)(Worker *worker); -}; - -#endif // WORKER_H_ diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/package.json b/frontend/express/node_modules/mongodb/node_modules/kerberos/package.json deleted file mode 100644 index 46e144bfbee..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "kerberos", - "version": "0.0.2", - "description": "Kerberos library for Node.js", - "main": "index.js", - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "nodeunit ./test" - }, - "repository": { - "type": "git", - "url": "https://github.com/christkv/kerberos.git" - }, - "keywords": [ - "kerberos", - "security", - "authentication" - ], - "devDependencies": { - "nodeunit": "latest" - }, - "author": { - "name": "Christian Amor Kvalheim" - }, - "license": "Apache 2.0", - "readmeFilename": "README.md", - "gitHead": "bb01d4fe322e022999aca19da564e7d9db59a8ed", - "readme": "kerberos\n========\n\nKerberos library for node.js", - "bugs": { - "url": "https://github.com/christkv/kerberos/issues" - }, - "_id": "kerberos@0.0.2", - "_from": "kerberos@latest" -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_tests.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_tests.js deleted file mode 100644 index a06c5fdfe27..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_tests.js +++ /dev/null @@ -1,34 +0,0 @@ -exports.setUp = function(callback) { - callback(); -} - -exports.tearDown = function(callback) { - callback(); -} - -exports['Simple initialize of Kerberos object'] = function(test) { - var Kerberos = require('../lib/kerberos.js').Kerberos; - var kerberos = new Kerberos(); - // console.dir(kerberos) - - // Initiate kerberos client - kerberos.authGSSClientInit('mongodb@kdc.10gen.me', Kerberos.GSS_C_MUTUAL_FLAG, function(err, context) { - console.log("===================================== authGSSClientInit") - test.equal(null, err); - test.ok(context != null && typeof context == 'object'); - // console.log("===================================== authGSSClientInit") - console.dir(err) - console.dir(context) - // console.dir(typeof result) - - // Perform the first step - kerberos.authGSSClientStep(context, function(err, result) { - console.log("===================================== authGSSClientStep") - console.dir(err) - console.dir(result) - console.dir(context) - - test.done(); - }); - }); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_win32_test.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_win32_test.js deleted file mode 100644 index d2f7046380a..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/kerberos_win32_test.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.setUp = function(callback) { - callback(); -} - -exports.tearDown = function(callback) { - callback(); -} - -exports['Simple initialize of Kerberos win32 object'] = function(test) { - var KerberosNative = require('../build/Release/kerberos').Kerberos; - // console.dir(KerberosNative) - var kerberos = new KerberosNative(); - console.log("=========================================== 0") - console.dir(kerberos.acquireAlternateCredentials("dev1@10GEN.ME", "a")); - console.log("=========================================== 1") - console.dir(kerberos.prepareOutboundPackage("mongodb/kdc.10gen.com")); - console.log("=========================================== 2") - test.done(); -} diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_descriptor_tests.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_descriptor_tests.js deleted file mode 100644 index 3531b6bc2c3..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_descriptor_tests.js +++ /dev/null @@ -1,41 +0,0 @@ -exports.setUp = function(callback) { - callback(); -} - -exports.tearDown = function(callback) { - callback(); -} - -exports['Initialize a security Buffer Descriptor'] = function(test) { - var SecurityBufferDescriptor = require('../../lib/sspi.js').SecurityBufferDescriptor - SecurityBuffer = require('../../lib/sspi.js').SecurityBuffer; - - // Create descriptor with single Buffer - var securityDescriptor = new SecurityBufferDescriptor(100); - try { - // Fail to work due to no valid Security Buffer - securityDescriptor = new SecurityBufferDescriptor(["hello"]); - test.ok(false); - } catch(err){} - - // Should Correctly construct SecurityBuffer - var buffer = new SecurityBuffer(SecurityBuffer.DATA, 100); - securityDescriptor = new SecurityBufferDescriptor([buffer]); - // Should correctly return a buffer - var result = securityDescriptor.toBuffer(); - test.equal(100, result.length); - - // Should Correctly construct SecurityBuffer - var buffer = new SecurityBuffer(SecurityBuffer.DATA, new Buffer("hello world")); - securityDescriptor = new SecurityBufferDescriptor([buffer]); - var result = securityDescriptor.toBuffer(); - test.equal("hello world", result.toString()); - - // Test passing in more than one Buffer - var buffer = new SecurityBuffer(SecurityBuffer.DATA, new Buffer("hello world")); - var buffer2 = new SecurityBuffer(SecurityBuffer.STREAM, new Buffer("adam and eve")); - securityDescriptor = new SecurityBufferDescriptor([buffer, buffer2]); - var result = securityDescriptor.toBuffer(); - test.equal("hello worldadam and eve", result.toString()); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_tests.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_tests.js deleted file mode 100644 index b52b9598b05..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_buffer_tests.js +++ /dev/null @@ -1,22 +0,0 @@ -exports.setUp = function(callback) { - callback(); -} - -exports.tearDown = function(callback) { - callback(); -} - -exports['Initialize a security Buffer'] = function(test) { - var SecurityBuffer = require('../../lib/sspi.js').SecurityBuffer; - // Create empty buffer - var securityBuffer = new SecurityBuffer(SecurityBuffer.DATA, 100); - var buffer = securityBuffer.toBuffer(); - test.equal(100, buffer.length); - - // Access data passed in - var allocated_buffer = new Buffer(256); - securityBuffer = new SecurityBuffer(SecurityBuffer.DATA, allocated_buffer); - buffer = securityBuffer.toBuffer(); - test.deepEqual(allocated_buffer, buffer); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_credentials_tests.js b/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_credentials_tests.js deleted file mode 100644 index 7758180070e..00000000000 --- a/frontend/express/node_modules/mongodb/node_modules/kerberos/test/win32/security_credentials_tests.js +++ /dev/null @@ -1,55 +0,0 @@ -exports.setUp = function(callback) { - callback(); -} - -exports.tearDown = function(callback) { - callback(); -} - -exports['Initialize a set of security credentials'] = function(test) { - var SecurityCredentials = require('../../lib/sspi.js').SecurityCredentials; - - // Aquire some credentials - try { - var credentials = SecurityCredentials.aquire('Kerberos', 'dev1@10GEN.ME', 'a'); - } catch(err) { - console.dir(err) - test.ok(false); - } - - - - // console.dir(SecurityCredentials); - - // var SecurityBufferDescriptor = require('../../lib/sspi.js').SecurityBufferDescriptor - // SecurityBuffer = require('../../lib/sspi.js').SecurityBuffer; - - // // Create descriptor with single Buffer - // var securityDescriptor = new SecurityBufferDescriptor(100); - // try { - // // Fail to work due to no valid Security Buffer - // securityDescriptor = new SecurityBufferDescriptor(["hello"]); - // test.ok(false); - // } catch(err){} - - // // Should Correctly construct SecurityBuffer - // var buffer = new SecurityBuffer(SecurityBuffer.DATA, 100); - // securityDescriptor = new SecurityBufferDescriptor([buffer]); - // // Should correctly return a buffer - // var result = securityDescriptor.toBuffer(); - // test.equal(100, result.length); - - // // Should Correctly construct SecurityBuffer - // var buffer = new SecurityBuffer(SecurityBuffer.DATA, new Buffer("hello world")); - // securityDescriptor = new SecurityBufferDescriptor([buffer]); - // var result = securityDescriptor.toBuffer(); - // test.equal("hello world", result.toString()); - - // // Test passing in more than one Buffer - // var buffer = new SecurityBuffer(SecurityBuffer.DATA, new Buffer("hello world")); - // var buffer2 = new SecurityBuffer(SecurityBuffer.STREAM, new Buffer("adam and eve")); - // securityDescriptor = new SecurityBufferDescriptor([buffer, buffer2]); - // var result = securityDescriptor.toBuffer(); - // test.equal("hello worldadam and eve", result.toString()); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/package.json b/frontend/express/node_modules/mongodb/package.json deleted file mode 100644 index db302df06f9..00000000000 --- a/frontend/express/node_modules/mongodb/package.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "name": "mongodb", - "description": "A node.js driver for MongoDB", - "keywords": [ - "mongodb", - "mongo", - "driver", - "db" - ], - "version": "1.3.9", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [ - { - "name": "Aaron Heckmann" - }, - { - "name": "Christoph Pojer" - }, - { - "name": "Pau Ramon Revilla" - }, - { - "name": "Nathan White" - }, - { - "name": "Emmerman" - }, - { - "name": "Seth LaForge" - }, - { - "name": "Boris Filipov" - }, - { - "name": "Stefan Schärmeli" - }, - { - "name": "Tedde Lundgren" - }, - { - "name": "renctan" - }, - { - "name": "Sergey Ukustov" - }, - { - "name": "Ciaran Jessup" - }, - { - "name": "kuno" - }, - { - "name": "srimonti" - }, - { - "name": "Erik Abele" - }, - { - "name": "Pratik Daga" - }, - { - "name": "Slobodan Utvic" - }, - { - "name": "Kristina Chodorow" - }, - { - "name": "Yonathan Randolph" - }, - { - "name": "Brian Noguchi" - }, - { - "name": "Sam Epstein" - }, - { - "name": "James Harrison Fisher" - }, - { - "name": "Vladimir Dronnikov" - }, - { - "name": "Ben Hockey" - }, - { - "name": "Henrik Johansson" - }, - { - "name": "Simon Weare" - }, - { - "name": "Alex Gorbatchev" - }, - { - "name": "Shimon Doodkin" - }, - { - "name": "Kyle Mueller" - }, - { - "name": "Eran Hammer-Lahav" - }, - { - "name": "Marcin Ciszak" - }, - { - "name": "François de Metz" - }, - { - "name": "Vinay Pulim" - }, - { - "name": "nstielau" - }, - { - "name": "Adam Wiggins" - }, - { - "name": "entrinzikyl" - }, - { - "name": "Jeremy Selier" - }, - { - "name": "Ian Millington" - }, - { - "name": "Public Keating" - }, - { - "name": "andrewjstone" - }, - { - "name": "Christopher Stott" - }, - { - "name": "Corey Jewett" - }, - { - "name": "brettkiefer" - }, - { - "name": "Rob Holland" - }, - { - "name": "Senmiao Liu" - }, - { - "name": "heroic" - }, - { - "name": "gitfy" - }, - { - "name": "Andrew Stone" - }, - { - "name": "John Le Drew" - }, - { - "name": "Lucasfilm Singapore" - }, - { - "name": "Roman Shtylman" - }, - { - "name": "Matt Self" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/mongodb/node-mongodb-native.git" - }, - "bugs": { - "url": "http://github.com/mongodb/node-mongodb-native/issues" - }, - "dependencies": { - "bson": "0.1.9", - "kerberos": "latest" - }, - "devDependencies": { - "dox": "0.2.0", - "uglify-js": "1.2.5", - "ejs": "0.6.1", - "request": "2.12.0", - "nodeunit": "0.7.4", - "markdown": "0.3.1", - "gleak": "0.2.3", - "step": "0.0.5", - "async": "0.1.22", - "integra": "latest", - "optimist": "latest" - }, - "optionalDependencies": { - "kerberos": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/mongodb/index", - "homepage": "http://mongodb.github.com/node-mongodb-native/", - "directories": { - "lib": "./lib/mongodb" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "test": "make test_functional" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Up to date documentation\n========================\n\n[Documentation](http://mongodb.github.com/node-mongodb-native/)\n\nInstall\n=======\n\nTo install the most recent release from npm, run:\n\n npm install mongodb\n\nThat may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version)\n\nTo install the latest from the repository, run::\n\n npm install path/to/node-mongodb-native\n\nCommunity\n=========\nCheck out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver.\n\nLive Examples\n============\n\n\nIntroduction\n============\n\nThis is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/.\n\nA simple example of inserting a document.\n\n```javascript\n var client = new Db('test', new Server(\"127.0.0.1\", 27017, {}), {w: 1}),\n test = function (err, collection) {\n collection.insert({a:2}, function(err, docs) {\n\n collection.count(function(err, count) {\n test.assertEquals(1, count);\n });\n\n // Locate all the entries using find\n collection.find().toArray(function(err, results) {\n test.assertEquals(1, results.length);\n test.assertTrue(results[0].a === 2);\n\n // Let's close the db\n client.close();\n });\n });\n };\n\n client.open(function(err, p_client) {\n client.collection('test_insert', test);\n });\n```\n\nData types\n==========\n\nTo store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code).\n\nIn particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example:\n\n```javascript\n // Get the objectID type\n var ObjectID = require('mongodb').ObjectID;\n\n var idString = '4e4e1638c85e808431000003';\n collection.findOne({_id: new ObjectID(idString)}, console.log) // ok\n collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined\n```\n\nHere are the constructors the non-Javascript BSON primitive types:\n\n```javascript\n // Fetch the library\n var mongo = require('mongodb');\n // Create new instances of BSON types\n new mongo.Long(numberString)\n new mongo.ObjectID(hexString)\n new mongo.Timestamp() // the actual unique number is generated on insert.\n new mongo.DBRef(collectionName, id, dbName)\n new mongo.Binary(buffer) // takes a string or Buffer\n new mongo.Code(code, [context])\n new mongo.Symbol(string)\n new mongo.MinKey()\n new mongo.MaxKey()\n new mongo.Double(number)\t// Force double storage\n```\n\nThe C/C++ bson parser/serializer\n--------------------------------\n\nIf you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below\n\n```javascript\n // using native_parser:\n var client = new Db('integration_tests_20',\n new Server(\"127.0.0.1\", 27017),\n {native_parser:true});\n```\n\nThe C++ parser uses the js objects both for serialization and deserialization.\n\nGitHub information\n==================\n\nThe source code is available at http://github.com/mongodb/node-mongodb-native.\nYou can either clone the repository or download a tarball of the latest release.\n\nOnce you have the source you can test the driver by running\n\n $ make test\n\nin the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass.\n\nExamples\n========\n\nFor examples look in the examples/ directory. You can execute the examples using node.\n\n $ cd examples\n $ node queries.js\n\nGridStore\n=========\n\nThe GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition.\n\nFor more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)\n\nReplicasets\n===========\nFor more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md)\n\nPrimary Key Factories\n---------------------\n\nDefining your own primary key factory allows you to generate your own series of id's\n(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long \"string\".\n\nSimple example below\n\n```javascript\n // Custom factory (need to provide a 12 byte array);\n CustomPKFactory = function() {}\n CustomPKFactory.prototype = new Object();\n CustomPKFactory.createPk = function() {\n return new ObjectID(\"aaaaaaaaaaaa\");\n }\n\n var p_client = new Db('integration_tests_20', new Server(\"127.0.0.1\", 27017, {}), {'pk':CustomPKFactory});\n p_client.open(function(err, p_client) {\n p_client.dropDatabase(function(err, done) {\n p_client.createCollection('test_custom_key', function(err, collection) {\n collection.insert({'a':1}, function(err, docs) {\n collection.find({'_id':new ObjectID(\"aaaaaaaaaaaa\")}, function(err, cursor) {\n cursor.toArray(function(err, items) {\n test.assertEquals(1, items.length);\n\n // Let's close the db\n p_client.close();\n });\n });\n });\n });\n });\n });\n```\n\nStrict mode\n-----------\n\nEach database has an optional strict mode. If it is set then asking for a collection\nthat does not exist will return an Error object in the callback. Similarly if you\nattempt to create a collection that already exists. Strict is provided for convenience.\n\n```javascript\n var error_client = new Db('integration_tests_', new Server(\"127.0.0.1\", 27017, {auto_reconnect: false}), {strict:true});\n test.assertEquals(true, error_client.strict);\n\n error_client.open(function(err, error_client) {\n error_client.collection('does-not-exist', function(err, collection) {\n test.assertTrue(err instanceof Error);\n test.assertEquals(\"Collection does-not-exist does not exist. Currently in strict mode.\", err.message);\n });\n\n error_client.createCollection('test_strict_access_collection', function(err, collection) {\n error_client.collection('test_strict_access_collection', function(err, collection) {\n test.assertTrue(collection instanceof Collection);\n // Let's close the db\n error_client.close();\n });\n });\n });\n```\n\nDocumentation\n=============\n\nIf this document doesn't answer your questions, see the source of\n[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js)\nor [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js),\nor the documentation at MongoDB for query and update formats.\n\nFind\n----\n\nThe find method is actually a factory method to create\nCursor objects. A Cursor lazily uses the connection the first time\nyou call `nextObject`, `each`, or `toArray`.\n\nThe basic operation on a cursor is the `nextObject` method\nthat fetches the next matching document from the database. The convenience\nmethods `each` and `toArray` call `nextObject` until the cursor is exhausted.\n\nSignatures:\n\n```javascript\n var cursor = collection.find(query, [fields], options);\n cursor.sort(fields).limit(n).skip(m).\n\n cursor.nextObject(function(err, doc) {});\n cursor.each(function(err, doc) {});\n cursor.toArray(function(err, docs) {});\n\n cursor.rewind() // reset the cursor to its initial state.\n```\n\nUseful chainable methods of cursor. These can optionally be options of `find` instead of method calls:\n\n* `.limit(n).skip(m)` to control paging.\n* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes:\n * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2.\n * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above\n * `.sort([['field1', 'desc'], 'field2'])` same as above\n * `.sort('field1')` ascending by field1\n\nOther options of `find`:\n\n* `fields` the fields to fetch (to avoid transferring the entire document)\n* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors).\n* `batchSize` The number of the subset of results to request the database\nto return for every request. This should initially be greater than 1 otherwise\nthe database will automatically close the cursor. The batch size can be set to 1\nwith `batchSize(n, function(err){})` after performing the initial query to the database.\n* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint).\n* `explain` turns this into an explain query. You can also call\n`explain()` on any cursor to fetch the explanation.\n* `snapshot` prevents documents that are updated while the query is active\nfrom being returned multiple times. See more\n[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database).\n* `timeout` if false, asks MongoDb not to time out this cursor after an\ninactivity period.\n\n\nFor information on how to create queries, see the\n[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.find({}, {limit:10}).toArray(function(err, docs) {\n console.dir(docs);\n });\n });\n```\n\nInsert\n------\n\nSignature:\n\n```javascript\n collection.insert(docs, options, [callback]);\n```\n\nwhere `docs` can be a single document or an array of documents.\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n\nSee also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.insert({hello: 'world'}, {safe:true},\n function(err, objects) {\n if (err) console.warn(err.message);\n if (err && err.message.indexOf('E11000 ') !== -1) {\n // this _id was already inserted in the database\n }\n });\n });\n```\n\nNote that there's no reason to pass a callback to the insert or update commands\nunless you use the `safe:true` option. If you don't specify `safe:true`, then\nyour callback will be called immediately.\n\nUpdate; update and insert (upsert)\n----------------------------------\n\nThe update operation will update the first document that matches your query\n(or all documents that match if you use `multi:true`).\nIf `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated.\n\nSee the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for\nthe modifier (`$inc`, `$set`, `$push`, etc.) formats.\n\nSignature:\n\n```javascript\n collection.update(criteria, objNew, options, [callback]);\n```\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n* `multi:true` If set, all matching documents are updated, not just the first.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `update`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true},\n function(err) {\n if (err) console.warn(err.message);\n else console.log('successfully updated');\n });\n });\n```\n\nFind and modify\n---------------\n\n`findAndModify` is like `update`, but it also gives the updated document to\nyour callback. But there are a few key differences between findAndModify and\nupdate:\n\n 1. The signatures differ.\n 2. You can only findAndModify a single item, not multiple items.\n\nSignature:\n\n```javascript\n collection.findAndModify(query, sort, update, options, callback)\n```\n\nThe sort parameter is used to specify which object to operate on, if more than\none document matches. It takes the same format as the cursor sort (see\nConnection.find above).\n\nSee the\n[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command)\nfor more details.\n\nUseful options:\n\n* `remove:true` set to a true to remove the object before returning\n* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `findAndModify`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {},\n function(err, object) {\n if (err) console.warn(err.message);\n else console.dir(object); // undefined if no matching object exists.\n });\n });\n```\n\nSave\n----\n\nThe `save` method is a shorthand for upsert if the document contains an\n`_id`, or an insert if there is no `_id`.\n\nSponsors\n========\nJust as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB.\n\nIf your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details.\n\nAnd I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing.\n\nRelease Notes\n=============\n\nSee HISTORY\n\nCredits\n=======\n\n1. [10gen](http://github.com/mongodb/mongo-ruby-driver/)\n2. [Google Closure Library](http://code.google.com/closure/library/)\n3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser)\n\nContributors\n============\n\nAaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy\n\nLicense\n=======\n\n Copyright 2009 - 2012 Christian Amor Kvalheim.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n", - "readmeFilename": "Readme.md", - "_id": "mongodb@1.3.9", - "_from": "mongodb@1.3.9", - "dist": { - "shasum": "34a8ac4d7fcb81d39b4fa7aa596187f03ee36f93" - }, - "_resolved": "https://registry.npmjs.org/mongodb/-/mongodb-1.3.9.tgz" -} diff --git a/frontend/express/node_modules/mongodb/t.js b/frontend/express/node_modules/mongodb/t.js deleted file mode 100644 index dbb87c6632e..00000000000 --- a/frontend/express/node_modules/mongodb/t.js +++ /dev/null @@ -1,15 +0,0 @@ -require('v8-profiler'); - -// It is important to use named constructors (like the one below), otherwise -// the heap snapshots will not produce useful outputs for you. -function LeakingClass() { -} - -var leaks = []; -setInterval(function() { - for (var i = 0; i < 100; i++) { - leaks.push(new LeakingClass); - } - - console.error('Leaks: %d', leaks.length); -}, 1000); \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/test.js b/frontend/express/node_modules/mongodb/test.js deleted file mode 100644 index 8ec16cc95f7..00000000000 --- a/frontend/express/node_modules/mongodb/test.js +++ /dev/null @@ -1,55 +0,0 @@ -var mongodb = require('./lib/mongodb') - , Db = mongodb.Db - , Server = mongodb.Server - , ReplSet = mongodb.ReplSet - , MongoClient = mongodb.MongoClient; - -// Replica set -var replSet = new ReplSet( [ - new Server('localhost', 31000), // Primary - new Server('localhost', 31001), // Secondary - new Server('localhost', 31002), // Secondary - // new Server('ChristianK-MacBook-Pro.local', 31000), // Primary - // new Server('ChristianK-MacBook-Pro.local', 31001), // Secondary - // new Server('ChristianK-MacBook-Pro.local', 31002), // Secondary - ], - { rs_name: 'testReplSet', read_secondary: true } -); - - -// MongoClient.connect("mongodb://localhost:31000,localhost:31001,localhost:31002", function(err, db) { -// console.log("=========================== logged on") -// if (err) console.error(err); -// db.close(); -// }) -var db = new Db('test', replSet, { native_parser: true, w: 1 }); - -// Opening -db.open(function (err, _db) { - console.log("=========================== logged on") - if (err) console.error(err); - - _db.close(); -}); - -// var dns = require('dns'); - -// dns.lookup('ChristianK-MacBook-Pro.local', function (err, addresses) { -// if (err) throw err; - -// console.log('addresses: ' + JSON.stringify(addresses)); - -// dns.reverse('192.168.1.138', function (err, domains) { -// console.dir(err) -// }); - - // addresses.forEach(function (a) { - // dns.reverse(a, function (err, domains) { - // if (err) { - // throw err; - // } - - // console.log('reverse for ' + a + ': ' + JSON.stringify(domains)); - // }); - // }); -// }); \ No newline at end of file diff --git a/frontend/express/node_modules/mongodb/test2.js b/frontend/express/node_modules/mongodb/test2.js deleted file mode 100644 index a8d74d19272..00000000000 --- a/frontend/express/node_modules/mongodb/test2.js +++ /dev/null @@ -1,37 +0,0 @@ -var mongoDB = require("./lib/mongodb") - -// keep the programming running for a while -setTimeout(function(){ - console.log("end of program") -},12*60*60*1000) - -mongoDB.MongoClient.connect("mongodb://localhost/test", {server:{auto_reconnect:true}}, function(err, db) { - if (err) {console.log("error connecting. " + err.message); return } - var testCollection=db.collection("test") - - testCollection.remove({},function(err){ - if (err) { console.log("error removing. " + err.message); return } - - testCollection.insert([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}, function(err, result){ - if (err) { console.log("error inserting. " + err.message); return } - - console.log("shut down the db server") - setTimeout(function(){ - console.log("starting first find...") - db.collection("test").findOne({a:1},function(err,result){ - console.log("first find return - never gets here") - }) - - console.log("start the db server back up") - setTimeout(function(){ - console.log("starting second find...") - db.collection("test").findOne({a:1},function(err,result){ - console.log("second find return - never gets here") - db.close() - }) - },5000) - - },5000) - }) - }) -}) \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/.jshintrc b/frontend/express/node_modules/mongoskin/.jshintrc deleted file mode 100644 index bbe0a3e8a05..00000000000 --- a/frontend/express/node_modules/mongoskin/.jshintrc +++ /dev/null @@ -1,43 +0,0 @@ -{ - "predef": [ - "phantom", - "module", - "require", - "__dirname", - "process", - "console", - "it", - "describe", - "before", - "beforeEach", - "after", - "should", - "rewire", - "$" - ], - - "browser": true, - "node" : true, - "es5": true, - "bitwise": true, - "curly": true, - "eqeqeq": true, - "forin": false, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonew": true, - "plusplus": false, - "undef": true, - "strict": true, - "trailing": false, - "globalstrict": true, - "nonstandard": true, - "white": false, - "indent": 2, - "expr": true, - "multistr": true, - "onevar": false -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/.npmignore b/frontend/express/node_modules/mongoskin/.npmignore deleted file mode 100644 index cbd931a5c04..00000000000 --- a/frontend/express/node_modules/mongoskin/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -data/ -deps/ -coverage.html -lib-cov -test/ -test_results.md diff --git a/frontend/express/node_modules/mongoskin/.travis.yml b/frontend/express/node_modules/mongoskin/.travis.yml deleted file mode 100644 index f0afa7e8376..00000000000 --- a/frontend/express/node_modules/mongoskin/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 -services: - - mongodb diff --git a/frontend/express/node_modules/mongoskin/AUTHORS b/frontend/express/node_modules/mongoskin/AUTHORS deleted file mode 100644 index 99e04c19eb9..00000000000 --- a/frontend/express/node_modules/mongoskin/AUTHORS +++ /dev/null @@ -1,16 +0,0 @@ -# Total 12 contributors. -# Ordered by date of first contribution. -# Auto-generated (http://github.com/dtrejo/node-authors) on Tue Aug 14 2012 02:58:57 GMT+0800 (CST). - -Gui Lin (https://github.com/guileen) -François de Metz (https://github.com/francois2metz) -fengmk2 (http://fengmk2.github.com) -Quang Van (https://github.com/quangv) -Matt Perpick (https://github.com/clutchski) -humanchimp (https://github.com/humanchimp) -Joe Faber (https://github.com/jlfaber) -Harvey McQueen (https://github.com/hmcqueen) -Paul Gebheim (https://github.com/paulirish) -Aneil Mallavarapu (https://github.com/amallavarapu) -wmertens (https://github.com/wmertens) -Rakshit Menpara (https://github.com/deltasquare4) diff --git a/frontend/express/node_modules/mongoskin/History.md b/frontend/express/node_modules/mongoskin/History.md deleted file mode 100644 index 25af581994a..00000000000 --- a/frontend/express/node_modules/mongoskin/History.md +++ /dev/null @@ -1,61 +0,0 @@ - -0.5.0 / 2012-12-29 -================== - - * fixed unsafe mode warnning log - * Merge pull request #84 from kingpearl/master - * MongoDB 1.2.x support - * Merge pull request #73 from jockster/master - * Merge pull request #75 from voke/patch-1 - * Fix typo - * fixed bind() test cases; - * Minor error in readme. Now updated - * Updated readme according to issue #72 - -0.3.4 / 2011-03-24 - * fix global leaks - -0.3.3 / 2011-03-15 -================== - * Add rootCollection option to SkinGridStore.exist - -0.3.2 / 2011-03-01 -================== - * exports all classes of node-mongodb-native - -0.3.1 / 2011-02-26 -================== - * bug fix #33 - -0.3.0 / 2011-01-19 -================== - * add ReplSet support - * bug fix - -0.2.3 / 2011-01-03 -================== - * add db.toObjectID - * fix #25 for node-mongodb-native update - -0.2.2 / 2011-12-02 -================== - * add bind support for embeded collections, e.g. db.bind('system.js') - * add method `toId` to SkinDB - * add property `ObjectID`, `bson_serializer` to SkinDB. - * SkinCollection.prototype.id is now deprecated. - -0.2.1 / 2011-11-18 -================== - * add ObjectId support for XXXXById - -0.2.0 / 2011-11-06 -================== - * add SkinDB.gridfs - -0.1.3 / 2011-05-24 -================== - * add SkinCollection.removeById - -0.1.2 / 2011-04-30 -================== - * add mongoskin.router diff --git a/frontend/express/node_modules/mongoskin/LICENSE b/frontend/express/node_modules/mongoskin/LICENSE deleted file mode 100644 index e91ac035ea1..00000000000 --- a/frontend/express/node_modules/mongoskin/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/Makefile b/frontend/express/node_modules/mongoskin/Makefile deleted file mode 100644 index 94d697ebfc6..00000000000 --- a/frontend/express/node_modules/mongoskin/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -TESTS = test/ -TESTTIMEOUT = 60000 -REPORTER = spec -MOCHA_OPTS = -PROJECT_DIR = $(shell pwd) -MONGOSKIN_REPLICASET = false -JSCOVERAGE = ./node_modules/jscover/bin/jscover -SUPPORT_VERSIONS := \ - 1.0.0 1.0.1 1.0.2 \ - 1.1.0-beta 1.1.1 1.1.2 1.1.3 1.1.4 - -test: - @npm install - @if ! test -d deps/mongodb; then \ - git clone git://github.com/mongodb/node-mongodb-native.git deps/mongodb; \ - fi - @cd deps/mongodb && npm install && git pull && cd ../.. - @NODE_ENV=test MONGOSKIN_REPLICASET=$(MONGOSKIN_REPLICASET) \ - ./node_modules/mocha/bin/mocha --recursive \ - --reporter $(REPORTER) --timeout $(TESTTIMEOUT) \ - $(MOCHA_OPTS) $(TESTS) - -test-debug: - @$(MAKE) test MOCHA_OPTS="--debug-brk" - -test-replicaset: - @$(MAKE) test MONGOSKIN_REPLICASET=true - -lib-cov: - @rm -rf $@ - @$(JSCOVERAGE) lib $@ - -test-cov: lib-cov - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=dot - @MONGOSKIN_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html - @$(MAKE) test REPORTER=markdown > test_results.md - -test-version: - @for version in $(SUPPORT_VERSIONS); do \ - echo "test with mongodb@$$version"; \ - npm install mongodb@$$version --loglevel=warn; \ - $(MAKE) test REPORTER=dot; \ - done - -.PHONY: test-replicaset test-version test-cov test lib-cov diff --git a/frontend/express/node_modules/mongoskin/Readme.md b/frontend/express/node_modules/mongoskin/Readme.md deleted file mode 100644 index ba39ce97b91..00000000000 --- a/frontend/express/node_modules/mongoskin/Readme.md +++ /dev/null @@ -1,724 +0,0 @@ -# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin) - -![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png) - -This project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native). -The api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first. - -## Test - -* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md) -* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html) - -## Test pass [mongodb] versions - -* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` - when connection open error. -* 1.0.x -* 1.1.x -* 1.2.x - -```bash -$ make test -``` - - - -# Mongoskin document - -* [Nodejs mongodb drivers comparation](#comparation) -* [Install](#install) -* [Quick Start](#quickstart) - * [Connect easier](#quickstart-1) - * [Server options and BSON options](#quickstart-2) - * [Similar API with node-mongodb-native](#quickstart-3) - * [Cursor easier](#quickstart-4) - * [MVC helper](#quickstart-5) -* [Documentation](#documentation) - * [Module](#module) - * [SkinServer](#skinserver) - * [SkinDb](#skindb) - * [SkinCollection](#skincollection) - * [Additional methods](#additional-collection-op) - * [Collection operation](#inherit-collection-op) - * [Indexes](#inherit-indexes) - * [Querying](#inherit-query) - * [Aggregation](#inherit-aggregation) - * [Inserting](#inherit-inserting) - * [Updating](#inherit-updating) - * [Removing](#inherit-removing) - * [SkinCursor](#skincursor) - - - -Nodejs Mongodb Driver Comparison -======== - -node-mongodb-native --------- - -One of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build -on top of it, including mongoskin. Unfortunately, it has an awkward interface with too many -callbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model. - -See [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs) - -mongoose --------- - -Mongoose provides an ORM way to hold Collection instance as Model, - you should define schema first. But why mongodb need schema? - Some guys like me, want to write code from application layer but not database layer, - and we can use any fields without define it before. - - Mongoose provide a DAL that you can do validation, and write your middlewares. - But some guys like me would like to validate manually, I think it is the tao of mongodb. - - If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice. - -mongoskin --------- - -Mongoskin is an easy to use driver of mongodb for nodejs, - it is similar with mongo shell, powerful like node-mongodb-native, - and support additional javascript method binding, which make it can act as a Model(in document way). - -It will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native), - and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29). - -If you need validation, you can use [node-iform](https://github.com/guileen/node-iform). - -[Back to index](#index) - - - -Install -======== - -```bash -$ npm install mongoskin -``` - -[Back to index](#index) - - - - -Quick Start -======== - - **Is mongoskin synchronized?** - -Nope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29). -**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native) - - - -Connect easier --------- -You can connect to mongodb easier now. - -```js -var mongo = require('mongoskin'); -mongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) { - console.dir(items); -}) -``` - - - -Server options and BSON options --------- -You can also set `auto_reconnect` options querystring. -And native_parser options will automatically set if native_parser is available. - -```js -var mongo = require('mongoskin'); -var db = mongo.db('localhost:27017/test?auto_reconnect'); -``` - - - -Similar API with node-mongodb-native --------- -You can do everything that node-mongodb-native can do. - -```js -db.createCollection(...); -db.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {}); -db.collection('posts').hint = 'slug'; -db.collection('posts').findOne({slug: 'whats-up'}, function (err, post) { - // do something -}); -``` - - - -Cursor easier --------- - -```js -db.collection('posts').find().toArray(function (err, posts) { - // do something -}); -``` - - - -MVC helper --------- - -You can bind **additional methods** for collection. -It is very useful if you want to use MVC patterns with nodejs and mongodb. -You can also invoke collection by properties after bind, -it could simplfy your `require`. - -To keep your code in line with DRY principles, it's possible to create your own -data layer by for example, setting up your own validators and/or default values -inside the MVC methods as shown below in the config example - -```js -db.bind('posts', { - findTop10 : function (fn) { - this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn); - }, - removeTagWith : function (tag, fn) { - this.remove({tags:tag},fn); - } - } -}); - -db.bind('settings', { - - getAll: function(user, fn) { - - this.find({user: user}).toArray(function(err, settings) { - - // We want to set a default currency from within our app instead of storing it - // for every user - settings.currency = (typeof settings.currency !== "undefined") ? settings.currency : 'USD'; - - fn(err, settings); - - }); - } -}); - - -db.bind('comments'); - -db.collection('posts').removeTagWith('delete', function (err, replies) { - //do something -}); - -db.posts.findTop10(function (err, topPosts) { - //do something -}); - -db.comments.find().toArray(function (err, comments) { - //do something -}); -``` - -[Back to index](#index) - - - - -Documentation -======== - -for more information, see the source. - -[Back to index](#index) - - - - -Module --------- - -### MongoSkin Url format - -``` -[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]` -``` - -e.g. - -``` -localhost/blog -mongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect -127.0.0.1?auto_reconnect=false -``` - -### db(serverURL[s], dbOptions, replicasetOptions) - -Get or create instance of [SkinDb](#skindb). - -```js -var db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5'); -``` - -for ReplSet server - -```js -var db = mongoskin.db([ - '192.168.0.1:27017/?auto_reconnect=true', - '192.168.0.2:27017/?auto_reconnect=true', - '192.168.0.3:27017/?auto_reconnect=true' -], { - database: 'testdb', - safe: true -}, { - connectArbiter: false, - socketOptions: { - timeout: 2000 - } -}); -``` - -### router(select) - -select is `function(collectionName)` returns a database instance, means router collectionName to that database. - -```js -var db = mongo.router(function (coll_name) { - switch(coll_name) { - case 'user': - case 'message': - return mongo.db('192.168.1.3/auth_db'); - default: - return mongo.db('192.168.1.2/app_db'); - } -}); -db.bind('user', require('./shared-user-methods')); -var users = db.user; //auth_db.user -var messages = db.collection('message'); // auth_db.message -var products = db.collection('product'); //app_db.product -``` - -### classes extends frome node-mongodb-native - -* BSONPure -* BSONNative -* BinaryParser -* Binary -* Code -* DBRef -* Double -* MaxKey -* MinKey -* ObjectID -* Symbol -* Timestamp -* Long -* BaseCommand -* DbCommand -* DeleteCommand -* GetMoreCommand -* InsertCommand -* KillCursorCommand -* QueryCommand -* UpdateCommand -* MongoReply -* Admin -* Collection -* Connection -* Server -* ReplSetServers -* Cursor -* Db -* connect -* Grid -* Chunk -* GridStore -* native -* pure - - -[Back to index](#index) - - - -SkinServer --------- - -### SkinServer(server) - -Construct SkinServer from native Server instance. - -### db(dbname, username=null, password=null) - -Construct [SkinDb](#skindb) from SkinServer. - -[Back to index](#index) - - - -SkinDb --------- - -### SkinDb(db, username=null, password=null) - -Construct SkinDb. - -### open(callback) - -Connect to database, retrieval native -[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) -instance, callback is function(err, db). - -### collection(collectionName) - -Retrieval [SkinCollection](#skincollection) instance of specified collection name. - - - -### bind(collectionName) - -### bind(collectionName, SkinCollection) - -### bind(collectionName, extendObject1, extendObject2 ...) - -Bind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name). -You can also bind additional methods to the SkinCollection, it is useful when -you want to reuse a complex operation. This will also affect -db.collection(name) method. - -e.g. - -```js -db.bind('book', { - firstBook: function (fn) { - this.findOne(fn); - } -}); -db.book.firstBook(function (err, book) {}); -``` - -### all the methods from Db.prototype - -See [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information. - -[Back to index](#index) - - - -SkinCollection --------- - -See [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information. - - -### open(callback) - -Retrieval native -[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) -instance, callback is function(err, collection). - -### id(hex) - -Equivalent to - -```js -db.bson_serializer.ObjectID.createFromHexString(hex); -``` - -See [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548) - - - - -### Collection operation - -```js -checkCollectionName(collectionName) -options(callback) -rename(collectionName, callback) -drop(callback) -``` - - - -### Indexes - -```js -createIndex(fieldOrSpec, unique, callback) -ensureIndex(fieldOrSpec, unique, callback) -indexInformation(callback) -dropIndex(indexName, callback) -dropIndexes(callback) -``` - -See [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md) - - - -### Queries - -See [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md) - -#### findItems(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.toArray(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findEach(..., callback) - -Equivalent to - -```js -collection.find(..., function (err, cursor) { - cursor.each(callback); -}); -``` - -See [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) - -#### findById(id, ..., callback) - -Equivalent to - -```js -collection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417) - -#### find(...) - -If the last parameter is function, it is equivalent to native -[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348) -method, else it will return a future [SkinCursor](#skincursor). - -e.g. - -```js -// callback -db.book.find({}, function (err, cursor) {/* do something */}); -// future SkinCursor -db.book.find().toArray(function (err, books) {/* do something */}); -``` - -#### normalizeHintField(hint) - -#### find - -```js -/** - * Various argument possibilities - * 1 callback - * 2 selector, callback, - * 2 callback, options // really?! - * 3 selector, fields, callback - * 3 selector, options, callback - * 4,selector, fields, options, callback - * 5 selector, fields, skip, limit, callback - * 6 selector, fields, skip, limit, timeout, callback - * - * Available options: - * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize - */ -``` - -#### findAndModify(query, sort, update, options, callback) - -```js -/** - Fetch and update a collection - query: a filter for the query - sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate - update: an object describing the modifications to the documents selected by the query - options: - remove: set to a true to remove the object before returning - new: set to true if you want to return the modified object rather than the original. Ignored for remove. - upsert: true/false (perform upsert operation) -**/ -``` - -#### findOne(queryObject, options, callback) - - - -### Aggregation - -#### mapReduce(map, reduce, options, callback) - -e.g. - -```js -var map = function () { - emit(test(this.timestamp.getYear()), 1); -} - -var reduce = function (k, v){ - count = 0; - for (i = 0; i < v.length; i++) { - count += v[i]; - } - return count; -} -var options = {scope: {test: new client.bson_serializer.Code(t.toString())}}; -collection.mapReduce(map, reduce, options, function (err, collection) { - collection.find(function (err, cursor) { - cursor.toArray(function (err, results) { - test.equal(2, results[0].value) - finished_test({test_map_reduce_functions_scope:'ok'}); - }) -}) -``` - -#### group(keys, condition, initial, reduce, command, callback) - -e.g. - -```js -collection.group([], {}, {"count":0}, "function (obj, prev) { prev.count++; }", true, function(err, results) {}); -``` - -#### count(query, callback) -#### distinct(key, query, callback) - - - -### Inserting - -#### insert(docs, options, callback) - - - -### Updating - -#### save(doc, options, callback) - -```js -/** - Update a single document in this collection. - spec - a associcated array containing the fields that need to be present in - the document for the update to succeed - - document - an associated array with the fields to be updated or in the case of - a upsert operation the fields to be inserted. - - Options: - upsert - true/false (perform upsert operation) - multi - true/false (update all documents matching spec) - strict - true/false (perform check if the operation failed, required extra call to db) - Deprecated Options: - safe - true/false (perform check if the operation failed, required extra call to db) -**/ -``` - -#### update(spec, document, options, callback) - -#### updateById(_id, ..., callback) - -Equivalent to - -```js -collection.update({_id, ObjectID.createFromHexString(id)}, ..., callback); -``` - -See [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md) - - - -### Removing - -#### remove(selector, options, callback) - -#### removeById(_id, options, callback) - -[Back to index](#index) - - - -SkinCursor ---------- - -See [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1) -of node-mongodb-native for more information. - -All these methods will return the SkinCursor itself. - -```js -sort(keyOrList, [direction], [callback]) -limit(limit, [callback]) -skip(skip, [callback]) -batchSize(skip, [callback]) - -toArray(callback) -each(callback) -count(callback) -nextObject(callback) -getMore(callback) -explain(callback) -``` - -[Back to index](#index) - -## How to validate input? - -I wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) -base on [node-validator](https://github.com/chriso/node-validator) - -## Authors - -Below is the output from `git-summary`. - -``` - project: node-mongoskin - commits: 112 - active : 54 days - files : 39 - authors: - 49 Lin Gui 43.8% - 34 guilin æ¡‚æž— 30.4% - 9 fengmk2 8.0% - 5 guilin 4.5% - 2 François de Metz 1.8% - 2 Paul Gebheim 1.8% - 2 Gui Lin 1.8% - 1 humanchimp 0.9% - 1 Aneil Mallavarapu 0.9% - 1 wmertens 0.9% - 1 Harvey McQueen 0.9% - 1 Joe Faber 0.9% - 1 Matt Perpick 0.9% - 1 Quang Van 0.9% - 1 Rakshit Menpara 0.9% - 1 Wout Mertens 0.9% -``` - -## License - -(The MIT License) - -Copyright (c) 2011 - 2012 kissjs.org - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/mongoskin/docs/docco.css b/frontend/express/node_modules/mongoskin/docs/docco.css deleted file mode 100644 index 5aa0a8d73f7..00000000000 --- a/frontend/express/node_modules/mongoskin/docs/docco.css +++ /dev/null @@ -1,186 +0,0 @@ -/*--------------------- Layout and Typography ----------------------------*/ -body { - font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; - font-size: 15px; - line-height: 22px; - color: #252519; - margin: 0; padding: 0; -} -a { - color: #261a3b; -} - a:visited { - color: #261a3b; - } -p { - margin: 0 0 15px 0; -} -h1, h2, h3, h4, h5, h6 { - margin: 0px 0 15px 0; -} - h1 { - margin-top: 40px; - } -#container { - position: relative; -} -#background { - position: fixed; - top: 0; left: 525px; right: 0; bottom: 0; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - z-index: -1; -} -#jump_to, #jump_page { - background: white; - -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; - -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - font: 10px Arial; - text-transform: uppercase; - cursor: pointer; - text-align: right; -} -#jump_to, #jump_wrapper { - position: fixed; - right: 0; top: 0; - padding: 5px 10px; -} - #jump_wrapper { - padding: 0; - display: none; - } - #jump_to:hover #jump_wrapper { - display: block; - } - #jump_page { - padding: 5px 0 3px; - margin: 0 0 25px 25px; - } - #jump_page .source { - display: block; - padding: 5px 10px; - text-decoration: none; - border-top: 1px solid #eee; - } - #jump_page .source:hover { - background: #f5f5ff; - } - #jump_page .source:first-child { - } -table td { - border: 0; - outline: 0; -} - td.docs, th.docs { - max-width: 450px; - min-width: 450px; - min-height: 5px; - padding: 10px 25px 1px 50px; - overflow-x: hidden; - vertical-align: top; - text-align: left; - } - .docs pre { - margin: 15px 0 15px; - padding-left: 15px; - } - .docs p tt, .docs p code { - background: #f8f8ff; - border: 1px solid #dedede; - font-size: 12px; - padding: 0 0.2em; - } - .pilwrap { - position: relative; - } - .pilcrow { - font: 12px Arial; - text-decoration: none; - color: #454545; - position: absolute; - top: 3px; left: -20px; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; - } - td.docs:hover .pilcrow { - opacity: 1; - } - td.code, th.code { - padding: 14px 15px 16px 25px; - width: 100%; - vertical-align: top; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - } - pre, tt, code { - font-size: 12px; line-height: 18px; - font-family: Monaco, Consolas, "Lucida Console", monospace; - margin: 0; padding: 0; - } - - -/*---------------------- Syntax Highlighting -----------------------------*/ -td.linenos { background-color: #f0f0f0; padding-right: 10px; } -span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } -body .hll { background-color: #ffffcc } -body .c { color: #408080; font-style: italic } /* Comment */ -body .err { border: 1px solid #FF0000 } /* Error */ -body .k { color: #954121 } /* Keyword */ -body .o { color: #666666 } /* Operator */ -body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -body .cp { color: #BC7A00 } /* Comment.Preproc */ -body .c1 { color: #408080; font-style: italic } /* Comment.Single */ -body .cs { color: #408080; font-style: italic } /* Comment.Special */ -body .gd { color: #A00000 } /* Generic.Deleted */ -body .ge { font-style: italic } /* Generic.Emph */ -body .gr { color: #FF0000 } /* Generic.Error */ -body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -body .gi { color: #00A000 } /* Generic.Inserted */ -body .go { color: #808080 } /* Generic.Output */ -body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -body .gs { font-weight: bold } /* Generic.Strong */ -body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -body .gt { color: #0040D0 } /* Generic.Traceback */ -body .kc { color: #954121 } /* Keyword.Constant */ -body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ -body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ -body .kp { color: #954121 } /* Keyword.Pseudo */ -body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ -body .kt { color: #B00040 } /* Keyword.Type */ -body .m { color: #666666 } /* Literal.Number */ -body .s { color: #219161 } /* Literal.String */ -body .na { color: #7D9029 } /* Name.Attribute */ -body .nb { color: #954121 } /* Name.Builtin */ -body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -body .no { color: #880000 } /* Name.Constant */ -body .nd { color: #AA22FF } /* Name.Decorator */ -body .ni { color: #999999; font-weight: bold } /* Name.Entity */ -body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -body .nf { color: #0000FF } /* Name.Function */ -body .nl { color: #A0A000 } /* Name.Label */ -body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -body .nt { color: #954121; font-weight: bold } /* Name.Tag */ -body .nv { color: #19469D } /* Name.Variable */ -body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -body .w { color: #bbbbbb } /* Text.Whitespace */ -body .mf { color: #666666 } /* Literal.Number.Float */ -body .mh { color: #666666 } /* Literal.Number.Hex */ -body .mi { color: #666666 } /* Literal.Number.Integer */ -body .mo { color: #666666 } /* Literal.Number.Oct */ -body .sb { color: #219161 } /* Literal.String.Backtick */ -body .sc { color: #219161 } /* Literal.String.Char */ -body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ -body .s2 { color: #219161 } /* Literal.String.Double */ -body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -body .sh { color: #219161 } /* Literal.String.Heredoc */ -body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -body .sx { color: #954121 } /* Literal.String.Other */ -body .sr { color: #BB6688 } /* Literal.String.Regex */ -body .s1 { color: #219161 } /* Literal.String.Single */ -body .ss { color: #19469D } /* Literal.String.Symbol */ -body .bp { color: #954121 } /* Name.Builtin.Pseudo */ -body .vc { color: #19469D } /* Name.Variable.Class */ -body .vg { color: #19469D } /* Name.Variable.Global */ -body .vi { color: #19469D } /* Name.Variable.Instance */ -body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/examples/admin.js b/frontend/express/node_modules/mongoskin/examples/admin.js deleted file mode 100644 index f32eee53546..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/admin.js +++ /dev/null @@ -1,9 +0,0 @@ -var db = require('./config').db; - -db.admin.listDatabases(function(err, result){ - if(err) { - console.traceError(err); - } - console.log(result); - db.close(); -}) diff --git a/frontend/express/node_modules/mongoskin/examples/close.js b/frontend/express/node_modules/mongoskin/examples/close.js deleted file mode 100644 index 73fafaa1381..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/close.js +++ /dev/null @@ -1,15 +0,0 @@ -var db = require('./config').db; - -db.collection('test').findOne({}, function(err, data) { - if(!err) { - console.log('db has open'); - console.log(data); - } -}); - -process.on('SIGINT', function() { - console.log('Recieve SIGINT'); - db.close(function(){ - console.log('database has closed'); - }) -}) diff --git a/frontend/express/node_modules/mongoskin/examples/config.js b/frontend/express/node_modules/mongoskin/examples/config.js deleted file mode 100644 index 80c9184a9d7..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/config.js +++ /dev/null @@ -1,5 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -exports.db = mongoskin.db('localhost/test'); - -mongoskin.db('localhost', { database: 'test' }); diff --git a/frontend/express/node_modules/mongoskin/examples/generateId.js b/frontend/express/node_modules/mongoskin/examples/generateId.js deleted file mode 100644 index 6acb4bfe4df..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/generateId.js +++ /dev/null @@ -1,31 +0,0 @@ -var redis = require('redis').createClient() - , shorten = require('shorten')(redis) - , async = require('async') - , db = require('./config').db - ; - -db.bind('user'); - -function log(err) { - if(err) { - console.log(err.stack); - } -} - -function createUser(user, callback) { - - async.waterfall([ - function(fn) { - shorten.nextId('user', fn); - } - , function(uid, fn) { - user.uid = uid; - db.user.save(user, fn); - } - ], callback); - -} - -for(var i = 0; i<10; i++) { - createUser({name: 'user' + i}, log); -} diff --git a/frontend/express/node_modules/mongoskin/examples/gridfs.js b/frontend/express/node_modules/mongoskin/examples/gridfs.js deleted file mode 100644 index ce476a3bba0..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/gridfs.js +++ /dev/null @@ -1,13 +0,0 @@ -var db = require('./config').db; - -db.gridfs().open('test.txt', 'w', function(err, gs) { - gs.write('blablabla', function(err, reply) { - gs.close(function(err, reply){ - db.gridfs().open('test.txt', 'r' ,function(err, gs) { - gs.read(function(err, reply){ - console.log(reply.toString()); - }); - }); - }); - }); -}); diff --git a/frontend/express/node_modules/mongoskin/examples/insert.js b/frontend/express/node_modules/mongoskin/examples/insert.js deleted file mode 100644 index bba4c58007f..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/insert.js +++ /dev/null @@ -1,8 +0,0 @@ -var db = require('./config').db; - -db.collection('test').insert({foo: 'bar'}, function(err, result) { - console.log(result); - db.collection('test').drop(); - db.close(); - -}); diff --git a/frontend/express/node_modules/mongoskin/examples/replSetBenchmark.js b/frontend/express/node_modules/mongoskin/examples/replSetBenchmark.js deleted file mode 100644 index bacd59eb3d0..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/replSetBenchmark.js +++ /dev/null @@ -1,45 +0,0 @@ - -var mongo = require('../'); - -var conf = { - hosts: [ - '127.0.0.1:27110/?auto_reconnect', - '127.0.0.1:27111/?auto_reconnect' - ], - dataDB: 'test' -}; - -var db = exports.db = mongo.db(conf.hosts, { - database: conf.dataDB -}); - -var noop = function() {}; - -db.bind('user'); -// db.user.ensureIndex({ name: 1 }, { unique: true }, noop); -// db.user.ensureIndex({ enable: 1 }, noop); -// db.user.ensureIndex({ created_at: 1, enable: 1 }, noop); - -var counter = 0; -setInterval(function () { - db.user.findItems({ name: 'name_' + counter }, function (err, items) { - if (err) { - console.error('findItems user error', err); - } - if (items) { - console.log('total: %d users', items.length); - } - }); - db.user.insert({ - name: 'name_' + counter, - createtime: new Date() - }, function(err, user) { - if (err) { - console.error('insert user error', err); - } - if (user && user[0]) { - console.log('new: %d %s', counter, user[0]._id); - } - }); - counter++; -}, 10); diff --git a/frontend/express/node_modules/mongoskin/examples/replset.js b/frontend/express/node_modules/mongoskin/examples/replset.js deleted file mode 100644 index 4e3dc616ccf..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/replset.js +++ /dev/null @@ -1,10 +0,0 @@ -var mongoskin = require('../lib/mongoskin/'); - -var db = mongoskin.db(['127.0.0.1:27017'], { - database: 'test' -}); - -db.open(function(err, data) { - console.log(err && err.stack); - console.log(data); -}); diff --git a/frontend/express/node_modules/mongoskin/examples/update.js b/frontend/express/node_modules/mongoskin/examples/update.js deleted file mode 100644 index 080d84e3807..00000000000 --- a/frontend/express/node_modules/mongoskin/examples/update.js +++ /dev/null @@ -1,19 +0,0 @@ -var db = require('./config').db; -var articles = db.collection('articles'); -articles.insert({foo: 'bar', val: 'val1'}, function(err, result) { - - console.log(result); - articles.update({foo:'bar'}, {foo: 'bar', val:'val2'}, {strict: true}, function(err, result) { - - console.log(result); - articles.find({foo: 'bar'}).toArray(function(err, docs){ - - console.log(docs); - articles.drop(); - db.close(); - - }); - - }) - -}); diff --git a/frontend/express/node_modules/mongoskin/index.js b/frontend/express/node_modules/mongoskin/index.js deleted file mode 100644 index dd996affa95..00000000000 --- a/frontend/express/node_modules/mongoskin/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = process.env.MONGOSKIN_COV ? require('./lib-cov/mongoskin') : require('./lib/mongoskin'); \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/integration/integration_tests.js b/frontend/express/node_modules/mongoskin/integration/integration_tests.js deleted file mode 100644 index 7a34db70fa1..00000000000 --- a/frontend/express/node_modules/mongoskin/integration/integration_tests.js +++ /dev/null @@ -1,203 +0,0 @@ -GLOBAL.DEBUG = true; - -var assert = require('assert'), - mongo = require('../lib/mongoskin'); - -console.log('======== test MongoSkin.db ========'); -(function(){ - var username = 'testuser', - password = 'password'; - - db = mongo.db('localhost/test'); - db.open(function(err, db) { - assert.ok(!err); - assert.ok(db, err && err.stack); - db.addUser(username, password, function(err, result){ - var authdb = mongo.db(username + ':' + password +'@localhost/test'); - authdb.open(function(err, db){ - assert.ok(!err, err && err.stack); - }); - var faildb = mongo.db(username + ':wrongpassword@localhost/test'); - faildb.open(function(err, db){ - assert.ok(err, 'should not auth'); - assert.ok(!db, 'should not return db'); - }); - }); - }); -})(); - -(function(){ - db = mongo.db('db://admin:admin@localhost:27017/test?auto_reconnect'); - db.open(function(err, db){ - assert.ok(err instanceof Error); - }) -})(); - -var bindToBlog = { - first: function(fn) { - this.findOne(fn); - } -}; - -console.log('======== test MongoSkin.router ========'); -var testdb1 = mongo.db('localhost/test1'); -var testdb2 = mongo.db('localhost/test2'); -var router = mongo.router(function(name){ - switch(name){ - case 'user': - case 'message': - return testdb1; - default: - return testdb2; - } -}); -assert.equal(router.collection('user'), testdb1.collection('user'), 'user should router to testdb1'); -assert.equal(router.collection('message'), testdb1.collection('message'), 'message should router to testdb1'); -assert.equal(router.collection('others'), testdb2.collection('others'), 'others should router to testdb2'); -router.bind('user'); -router.bind('others'); -assert.equal(router.user, testdb1.user, 'user property should router to testdb1'); -assert.equal(router.others, testdb2.others, 'user property should router to testdb1'); - -console.log('======== test MongoSkin.bind ========'); -var db = mongo.db('localhost/test_mongoskin'); -db.bind('blog', bindToBlog); -db.bind('users'); -assert.equal(db.blog.first, bindToBlog.first); -assert.ok(db.users); - -console.log('======== test SkinDb bson ========'); -assert.ok(db.ObjectID.createFromHexString('a7b79d4dca9d730000000000')); - -console.log('======== test SkinDb.bind ========'); -db.bind('blog2', bindToBlog); -db.bind('user2'); -assert.equal(db.blog2.first, bindToBlog.first); -assert.ok(db.user2); - -console.log('======== test SkinDb.open ========'); -(function(){ - var db1, db2; - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db1 = db; - assert.equal(db1.state, 'connected'); - if (db2) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - - db.open(function(err, db) { - assert.ok(db, err && err.stack); - db2 = db; - assert.equal(db2.state, 'connected'); - if (db1) { - assert.equal(db1, db2, 'should alwayse be the same instance in db.open.'); - } - }); - -})() - -console.log('======== test normal method of SkinDb ========'); -db.createCollection('test_createCollection', function(err, collection) { - assert.equal(db.db.state, 'connected'); - assert.ok(collection, err && err.stack); -}); - - -console.log('======== test SkinDb.collection ========'); -assert.equal(db.blog, db.collection('blog')); - -console.log('======== test SkinCollection.open ========'); -var coll1, coll2; -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll1 = coll; - if (coll2) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -db.blog.open(function(err, coll) { - assert.ok(coll, err && err.stack); - coll2 = coll; - if (coll1) { - assert.equal(coll1, coll2, 'should be the same instance in collection.open'); - } -}); - -console.log('======== test normal method of SkinCollection ========'); -db.collection('test_normal').ensureIndex([['a',1]], function(err, replies){ - assert.ok(replies, err && err.stack); -}); - -console.log('======== test SkinCollection.drop ========'); -db.collection('test_find').drop(function(err, replies){ - assert.ok(!err, err && err.stack); -}); - -console.log('======== test SkinCollection.find ========'); -collection = db.collection('test_find'); -collection.insert([{a:1},{a:2},{a:3},{a:4}], function(err, replies){ - assert.ok(replies, err && err.stack); - console.log('======== test SkinCollection.findById ========'); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.equal(item.a, 1); - console.log('======== test SkinCollection.removeById ========'); - collection.removeById(replies[0]._id.toString(), function(err, reply){ - assert.ok(!err, err && err.stack); - collection.findById(replies[0]._id.toString(), function(err, item){ - assert.ok(!err); - assert.ok(!item); - }); - }); - }); -}); - - - collection.findItems(function(err, items){ - assert.ok(items, err && err.stack); - console.log('found '+ items.length + ' items'); - }); - collection.findEach(function(err, item){ - assert.ok(!err, err && err.stack); - }); - collection.find(function(err, cursor){ - assert.ok(cursor, err && err.stack); - }); - - console.log('======== test SkinCursor ========'); - collection.find().toArray(function(err, items){ - console.log('======== test find cursor toArray========'); - assert.ok(items, err && err.stack); - }); - collection.find().each(function(err, item){ - console.log('======== test find cursor each========'); - assert.ok(!err, err && err.stack); - }); - collection.find().sort({a:-1}).limit(2).skip(1).toArray(function(err, items){ - console.log('======== test cursor sort() limit() skip() ========'); - assert.ok(!err, err && err.stack); - console.dir(items); - }); - -console.log('======== deep future test ========'); -(function(){ - var db2 = mongo.db('localhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(!err, err && err.stack); - }) -})(); - -(function(){ - var db2 = mongo.db('unknownhost/test-mongoskin01'); - db2.collection('blog').find().toArray(function(err, items){ - assert.ok(err); - }) -})(); -/* -console.log('======== test SkinDb.close ========'); -db.close(); -assert.equal(db.db.state, 'notConnected'); -*/ - diff --git a/frontend/express/node_modules/mongoskin/integration/longlive.js b/frontend/express/node_modules/mongoskin/integration/longlive.js deleted file mode 100644 index 828f71a1bdb..00000000000 --- a/frontend/express/node_modules/mongoskin/integration/longlive.js +++ /dev/null @@ -1,28 +0,0 @@ -var mongo = require('../'); -var db = mongo.db('192.168.0.103/test'); -// var db = mongo.db('127.0.0.1/test'); -var myconsole = require('myconsole'); - -var foo = db.collection('foo'); - -setInterval(function() { - foo.insert({foo:'foo'}, function(err, result){ - if(err) return myconsole.error(err); - foo.count(function(err, count){ - if(err) return myconsole.error(err); - myconsole.log('count: %d', count); - foo.find().limit(10).toArray(function(err, arr) { - if(err) return myconsole.error(err); - myconsole.log('arr: %d', arr.length); - }) - }) - }) -}, 500); - -process.on('SIGINT', function(){ - myconsole.log('SIGINT') - foo.drop(function(err){ - if(err) myconsole.error(err); - process.exit(); - }) -}) diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/admin.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/admin.js deleted file mode 100644 index 035e2087d7b..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/admin.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - admin.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var Admin = require('mongodb').Admin; -var utils = require('./utils'); -var constant = require('./constant'); - -/** - * SkinAdmin - * - * @param {SkinDb} skinDb - * @constructor - * @api public - */ -var SkinAdmin = exports.SkinAdmin = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; - this.admin = null; -}; - -utils.inherits(SkinAdmin, utils.SkinObject); - -/** - * Retrieve mongodb.Admin instance. - * - * @param {Function(err, admin)} callback - * @return {SkinAdmin} this - * @api public - */ -SkinAdmin.prototype.open = function (callback) { - if (this.state === constant.STATE_OPEN) { - callback(null, this.admin); - return this; - } - this.emitter.once('open', callback); - if (this.state === constant.STATE_OPENNING) { - return this; - } - this.state = constant.STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.admin = null; - this.state = constant.STATE_CLOSE; - } else { - this.admin = new Admin(db); - this.state = constant.STATE_OPEN; - } - this.emitter.emit('open', err, this.admin); - }.bind(this)); - return this; -}; - -for (var key in Admin.prototype) { - var method = Admin.prototype[key]; - utils.bindSkin('SkinAdmin', SkinAdmin, 'admin', key, method); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/collection.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/collection.js deleted file mode 100644 index 20302026747..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/collection.js +++ /dev/null @@ -1,300 +0,0 @@ -/*! - * mongoskin - collection.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - bind these methods from Collection.prototype to Provider - - methods: - insert - checkCollectionName - remove - rename - save - update - distinct - count - drop - findAndModify - find - normalizeHintField - findOne - createIndex - ensureIndex - indexInformation - dropIndex - dropIndexes - mapReduce - group - options -*/ -var __slice = Array.prototype.slice; -var events = require('events'); -var Collection = require('mongodb').Collection; -var SkinCursor = require('./cursor').SkinCursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * Construct SkinCollection from SkinDb and collectionName - * use skinDb.collection('name') usually - * - * @param {SkinDb} skinDb - * @param {String} collectionName - * @param {Object} [options] collection options - * @constructor - * @api public - */ -var SkinCollection = exports.SkinCollection = function (skinDb, collectionName, options) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(50); - - this.options = options; - this.skinDb = skinDb; - this.ObjectID = this.skinDb.ObjectID; - this.collectionName = collectionName; - this.collection = null; - this.internalHint = null; - this.__defineGetter__('hint', function () { - return this.internalHint; - }); - this.__defineSetter__('hint', function (value) { - this.internalHint = value; - this.open(function (err, collection) { - collection.hint = value; - this.internalHint = collection.hint; - }.bind(this)); - }); -}; - -utils.inherits(SkinCollection, utils.SkinObject); - -for (var _name in Collection.prototype) { - var method = Collection.prototype[_name]; - utils.bindSkin('SkinCollection', SkinCollection, 'collection', _name, method); -} - -/* - * find is a special method, because it could return a SkinCursor instance - */ -SkinCollection.prototype._find = SkinCollection.prototype.find; - -/** - * Retrieve mongodb.Collection - * - * @param {Function(err, collection)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.collection); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinDb.open(function (err, db) { - if (err) { - this.state = STATE_CLOSE; - return this.emitter.emit('open', err, null); - } - db.collection(this.collectionName, this.options, function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - } else { - this.state = STATE_OPEN; - this.collection = collection; - if (this.hint) { - this.collection.hint = this.hit; - } - } - this.emitter.emit('open', err, collection); - }.bind(this)); - }.bind(this)); - break; - } - return this; -}; - -/** - * Close current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.close = function (callback) { - this.collection = null; - this.state = STATE_CLOSE; - return this; -}; - -/** - * Drop current collection. - * - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.drop = function (callback) { - this.skinDb.dropCollection(this.collectionName, callback); - this.close(); - return this; -}; - -/** - * same args as find, but use Array as callback result but not use Cursor - * - * findItems(args, function (err, items) {}); - * - * same as - * - * find(args).toArray(function (err, items) {}); - * - * or using `mongodb.collection.find()` - * - * find(args, function (err, cursor) { - * cursor.toArray(function (err, items) { - * }); - * }); - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, docs)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findItems = function (query, options, callback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.toArray(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * find and cursor.each(fn). - * - * @param {Object} [query] - * @param {Object} [options] - * @param {Function(err, item)} eachCallback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findEach = function (query, options, eachCallback) { - var args = __slice.call(arguments); - var fn = args[args.length - 1]; - args[args.length - 1] = function (err, cursor) { - if (err) { - return fn(err); - } - cursor.each(fn); - }; - this.find.apply(this, args); - return this; -}; - -/** - * @deprecated use `SkinDb.toId` instead - * - * @param {String} hex - * @return {ObjectID|String} - * @api public - */ -SkinCollection.prototype.id = function (hex) { - return this.skinDb.toId(hex); -}; - -/** - * Operate by object.`_id` - * - * @param {String} methodName - * @param {String|ObjectID|Number} id - * @param {Arguments|Array} args - * @return {SkinCollection} this - * @api private - */ -SkinCollection.prototype._operateById = function (methodName, id, args) { - args = __slice.call(args); - args[0] = {_id: this.skinDb.toId(id)}; - this[methodName].apply(this, args); - return this; -}; - -/** - * Find one object by _id. - * - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err, doc)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.findById = function (id, callback) { - return this._operateById('findOne', id, arguments); -}; - -/** - * Update doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Object} doc - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.updateById = function (id, doc, callback) { - return this._operateById('update', id, arguments); -}; - -/** - * Remove doc by _id. - * @param {String|ObjectID|Number} id, doc primary key `_id` - * @param {Function(err)} callback - * @return {SkinCollection} this - * @api public - */ -SkinCollection.prototype.removeById = function (id, callback) { - return this._operateById('remove', id, arguments); -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB. - * - * @param {Object} query - * @param {Object} options - * @param {Function(err, docs)} callback - * @return {SkinCursor|SkinCollection} if last argument is not a function, then returns a SkinCursor, - * otherise return this - * @api public - */ -SkinCollection.prototype.find = function (query, options, callback) { - var args = __slice.call(arguments); - if (args.length > 0 && typeof args[args.length - 1] === 'function') { - this._find.apply(this, args); - return this; - } else { - return new SkinCursor(null, this, args); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/constant.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/constant.js deleted file mode 100644 index b9fb90704ac..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/constant.js +++ /dev/null @@ -1,15 +0,0 @@ -/*! - * mongoskin - constant.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -exports.DEFAULT_PORT = 27017; - -exports.STATE_CLOSE = 0; -exports.STATE_OPENNING = 1; -exports.STATE_OPEN = 2; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/cursor.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/cursor.js deleted file mode 100644 index a879d80a473..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/cursor.js +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * mongoskin - cursor.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter; -var Cursor = require('mongodb').Cursor; -var utils = require('./utils'); -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -var SkinCursor = exports.SkinCursor = function (cursor, skinCollection, args) { - utils.SkinObject.call(this); - - this.cursor = cursor; - this.skinCollection = skinCollection; - this.args = args || []; - this.emitter = new EventEmitter(); - if (cursor) { - this.state = STATE_OPEN; - } -}; - -utils.inherits(SkinCursor, utils.SkinObject); - -/** - * Retrieve mongodb.Cursor instance. - * - * @param {Function(err, cursor)} callback - * @return {SkinCursor} this - * @api public - */ -SkinCursor.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback(null, this.cursor); - break; - case STATE_OPENNING: - this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this.skinCollection.open(function (err, collection) { - if (err) { - this.state = STATE_CLOSE; - this.emitter.emit('open', err); - return; - } - // copy args - var args = this.args.slice(); - args.push(function (err, cursor) { - if (cursor) { - this.state = STATE_OPEN; - this.cursor = cursor; - } - this.emitter.emit('open', err, cursor); - }.bind(this)); - collection.find.apply(collection, args); - }.bind(this)); - break; - } - return this; -}; - -[ - // callbacks - 'toArray', 'each', 'count', 'nextObject', 'getMore', 'explain', - // self return - 'sort', 'limit', 'skip', 'batchSize', - // unsupported - //'rewind', 'close' ,... -].forEach(function (name) { - var method = Cursor.prototype[name]; - utils.bindSkin('SkinCursor', SkinCursor, 'cursor', name, method); -}); diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/db.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/db.js deleted file mode 100644 index f954a52ff5b..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/db.js +++ /dev/null @@ -1,254 +0,0 @@ -/*! - * mongoskin - db.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var mongodb = require('mongodb'); -var utils = require('./utils'); -var SkinAdmin = require('./admin').SkinAdmin; -var SkinCollection = require('./collection').SkinCollection; -var SkinGridStore = require('./gridfs').SkinGridStore; -var Db = mongodb.Db; -var constant = require('./constant'); -var STATE_CLOSE = constant.STATE_CLOSE; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_OPEN = constant.STATE_OPEN; - -/** - * SkinDb - * - * @param {Db} dbconn, mongodb.Db instance - * @param {String} [username] - * @param {String} [password] - * @constructor - * @api public - */ -var SkinDb = exports.SkinDb = function (dbconn, username, password) { - utils.SkinObject.call(this); - this.emitter.setMaxListeners(100); - - this._dbconn = dbconn; - this.db = null; - this.username = username; - this.password = password; - this.admin = new SkinAdmin(this); - this._collections = {}; - this.bson_serializer = dbconn.bson_serializer; - this.ObjectID = mongodb.ObjectID /* 0.9.7-3-2 */ || dbconn.bson_serializer.ObjectID /* <= 0.9.7 */; -}; - -utils.inherits(SkinDb, utils.SkinObject); - -/** - * Convert to ObjectID. - * - * @param {String} hex - * @return {ObjectID} - */ -SkinDb.prototype.toObjectID = SkinDb.prototype.toId = function (hex) { - if (hex instanceof this.ObjectID) { - return hex; - } - if (!hex || hex.length !== 24) { - return hex; - } - return this.ObjectID.createFromHexString(hex); -}; - - -/** - * Open the database connection. - * - * @param {Function(err, nativeDb)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.open = function (callback) { - switch (this.state) { - case STATE_OPEN: - callback && callback(null, this.db); - break; - case STATE_OPENNING: - // if call 'open' method multi times before opened - callback && this.emitter.once('open', callback); - break; - // case STATE_CLOSE: - default: - var onDbOpen = function (err, db) { - if (!err && db) { - this.db = db; - this.state = STATE_OPEN; - } else { - db && db.close(); - // close the openning connection. - this._dbconn.close(); - this.db = null; - this.state = STATE_CLOSE; - } - this.emitter.emit('open', err, this.db); - }.bind(this); - callback && this.emitter.once('open', callback); - this.state = STATE_OPENNING; - this._dbconn.open(function (err, db) { - if (db && this.username) { - // do authenticate - db.authenticate(this.username, this.password, function (err) { - onDbOpen(err, db); - }); - } else { - onDbOpen(err, db); - } - }.bind(this)); - break; - } - return this; -}; - -/** - * Close the database connection. - * - * @param {Function(err)} [callback] - * @return {SkinDb} this - * @api public - */ -SkinDb.prototype.close = function (callback) { - if (this.state === STATE_CLOSE) { - callback && callback(); - } else if (this.state === STATE_OPEN) { - this.state = STATE_CLOSE; - this.db.close(callback); - } else if (this.state === STATE_OPENNING) { - var that = this; - this.emitter.once('open', function (err, db) { - that.state = STATE_CLOSE; - db ? db.close(callback) : callback && callback(err); - }); - } - return this; -}; - -/** - * Create or retrieval skin collection - * - * @param {String} name, the collection name. - * @param {Object} [options] collection options. - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.collection = function (name, options) { - var collection = this._collections[name]; - if (!collection) { - this._collections[name] = collection = new SkinCollection(this, name, options); - } - return collection; -}; - -/** - * gridfs - * - * @return {SkinGridStore} - * @api public - */ -SkinDb.prototype.gridfs = function () { - return this.skinGridStore || (this.skinGridStore = new SkinGridStore(this)); -}; - -/** - * bind additional method to SkinCollection - * - * 1. collectionName - * 2. collectionName, extends1, extends2,... extendsn - * 3. collectionName, SkinCollection - * - * @param {String} collectionName - * @param {Object|SkinCollection} [options] - * @return {SkinCollection} - * @api public - */ -SkinDb.prototype.bind = function (collectionName, options) { - var args = __slice.call(arguments); - var name = args[0]; - - if (typeof name !== 'string' || !name.trim()) { - throw new Error('Must provide collection name to bind.'); - } - if (args.length === 1) { - return this.bind(name, this.collection(name)); - } - if (args.length === 2 && args[1].constructor === SkinCollection) { - this._collections[name] = args[1]; - Object.defineProperty(this, name, { - value: args[1], - writable: false, - enumerable: true - }); - // support bind for system.js - var names = name.split('.'); - if (names.length > 1){ - var prev = this, next; - for (var i = 0; i < names.length - 1; i++) { - next = prev[names[i]]; - if (!next) { - next = {}; - Object.defineProperty(prev, names[i], { - value: next, - writable: false, - enumerable : true - }); - } - prev = next; - } - Object.defineProperty(prev, names[names.length - 1], { - value: args[1], - writable: false, - enumerable : true - }); - } - return args[1]; - } - - var isOptions = false; - var argsIndex = 1; - if (options && typeof options === 'object') { - isOptions = true; - argsIndex = 2; - for (var k in options) { - if (typeof options[k] === 'function') { - isOptions = false; - argsIndex = 1; - break; - } - } - } - var collection = this.collection(name, isOptions ? options : null); - for (var len = args.length; argsIndex < len; argsIndex++) { - var extend = args[argsIndex]; - if (typeof extend !== 'object') { - throw new Error('the args[' + argsIndex + '] should be object, but is `' + extend + '`'); - } - utils.extend(collection, extend); - } - return this.bind(name, collection); -}; - -var IGNORE_NAMES = [ - 'bind', 'open', 'close', 'collection', 'admin', 'state' -]; -// bind method of mongodb.Db to SkinDb -for (var key in Db.prototype) { - if (!key || key[0] === '_' || IGNORE_NAMES.indexOf(key) >= 0) { - continue; - } - var method = Db.prototype[key]; - utils.bindSkin('SkinDb', SkinDb, 'db', key, method); -} diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/gridfs.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/gridfs.js deleted file mode 100644 index 603e9e9a67c..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/gridfs.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * mongoskin - gridfs.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var GridStore = require('mongodb').GridStore; -var utils = require('./utils'); - -/** - * @param filename: filename or ObjectId - */ -var SkinGridStore = exports.SkinGridStore = function (skinDb) { - utils.SkinObject.call(this); - this.skinDb = skinDb; -}; - -utils.inherits(SkinGridStore, utils.SkinObject); - -/** - * @param id - * @param filename - * @param mode - * @param options - * @param callback - * callback(err, gridStoreObject) - */ -SkinGridStore.prototype.open = function (id, filename, mode, options, callback) { - var args = Array.prototype.slice.call(arguments); - callback = args.pop(); - this.skinDb.open(function (err, db) { - var gs = new GridStore(db, args[0], args[1], args[2], args[3]); - var props = { - length: gs.length, - contentType: gs.contentType, - uploadDate: gs.uploadDate, - metadata: gs.metadata, - chunkSize: gs.chunkSize - }; - - gs.open(function (error, reply) { - callback(error, reply, props); - }); - }); -}; - -/** - * @param filename: filename or ObjectId - */ -SkinGridStore.prototype.unlink = SkinGridStore.prototype.remove = function (filename, callback) { - this.skinDb.open(function (err, db) { - GridStore.unlink(db, filename, callback); - }); -}; - -SkinGridStore.prototype.exist = function (filename, rootCollection, callback) { - this.skinDb.open(function (err, db) { - GridStore.exist(db, filename, rootCollection, callback); - }); -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/index.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/index.js deleted file mode 100644 index db051fc3115..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/index.js +++ /dev/null @@ -1,200 +0,0 @@ -/*! - * mongoskin - index.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var url = require('url'); -var Router = require('./router').Router; -var mongo = require('mongodb'); -var SkinServer = require('./server').SkinServer; -var SkinDb =require('./db').SkinDb; -var Db = mongo.Db; -var Server = mongo.Server; -var ReplSetServers = mongo.ReplSetServers; -var BSONNative = mongo.BSONNative; -var constant = require('./constant'); -var DEFAULT_PORT = constant.DEFAULT_PORT; - -function toBool(value) { - return value !== undefined && value !== 'false' && value !== 'no' && value !== 'off'; -} - -/** - * parse the database url to config - * - * [*://]username:password@host[:port]/database?options - * - * @param {String} serverUrl - * @return {Object} config - * - {String} host - * - {Number} port, default is `DEFAULT_PORT`. - * - {String} [database], no database by default. - * - {Object} options - * - {Bool} auto_reconnect, default is `false`. - * - {Number} poolSize, default is `1`. - * - {String} [username], no username by default. - * - {String} [password], no password by default. - * @api private - */ -var parseUrl = function (serverUrl) { - serverUrl = /\w+:\/\//.test(serverUrl) ? serverUrl : 'db://' + serverUrl; - var uri = url.parse(serverUrl, true); - var config = {}; - var serverOptions = uri.query; - - config.host = uri.hostname; - config.port = parseInt(uri.port, 10) || DEFAULT_PORT; - if (uri.pathname) { - config.database = uri.pathname.replace(/\//g, ''); - } - config.options = {}; - config.options.auto_reconnect = toBool(serverOptions.auto_reconnect); - config.options.poolSize = parseInt(serverOptions.poolSize || 1, 10); - if (uri && uri.auth) { - var auth = uri.auth; - var separator = auth.indexOf(':'); - config.username = auth.substr(0, separator); - config.password = auth.substr(separator + 1); - } - return config; -}; - -/** - * constructor Server from url - * - * @param {String} serverUrl - * @return {Server} - * @api private - */ -var parseServer = function (serverUrl) { - var config = parseUrl(serverUrl); - return new Server(config.host, config.port, config.options); -}; - -/* - * exports mongo classes ObjectID Long Code DbRef ... to mongoskin - */ -for (var key in mongo) { - exports[key] = mongo[key]; -} - -/** - * constructor SkinDb from serverURL[s] - * - * ReplicaSet: mongoskin.db(serverURLs, dbOptions, replicasetOptions) - * - * ```js - * mongoskin.db([ - * '192.168.0.1:27017/', - * '192.168.0.2/?auto_reconnect', - * '192.168.0.3' - * ], {database: 'mydb'}, {connectArbiter: false, socketOptions: {timeout: 2000}}); - * ``` - * - * Single Server: mongoskin.db(dbURL, options) - * - * ```js - * mongoskin.db('192.168.0.1:27017/mydb'); - * // or - * mongoskin.db('192.168.0.1:27017', {database: 'mydb'}); - * // set the connection timeout to `2000ms` - * mongoskin.db('192.168.0.1:27017', {database: 'mydb', socketOptions: {timeout: 2000}}); - * ``` - * - * @param {String|Array} serverUrl or server urls. - * @param {Object} [dbOptions] - * - {Object} socketOptions: @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#socket-options - * - the other, @see http://mongodb.github.com/node-mongodb-native/markdown-docs/database.html#db-options - * @param {Object} [replicasetOptions], options for replicaset. - * The detail of this options, please - * @see https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/connection/repl_set.js#L27. - * @return {SkinDb} - * @api public - */ -exports.db = function (serverUrl, dbOptions, replicasetOptions) { - dbOptions = dbOptions || {}; - - var server, database, config; - - if (Array.isArray(serverUrl)) { - if (!dbOptions.database) { - throw new Error('Please provide a database in `dbOptions` to connect.'); - } - database = dbOptions.database; - - var len = serverUrl.length; - var servers = []; - for (var i = 0; i < len; i++) { - config = parseUrl(serverUrl[i]); - if (config.database || config.username) { - console.log('MONGOSKIN:WARN: database or username found in RepliSet server URL, ' + serverUrl[i]); - } - servers.push(new Server(config.host, config.port, config.options)); - } - server = new ReplSetServers(servers, replicasetOptions); - } else { - config = parseUrl(serverUrl); - database = dbOptions.database || config.database; - if (!database) { - throw new Error('Please provide a database to connect to.'); - } - var socketOptions = dbOptions.socketOptions; - if (socketOptions) { - delete dbOptions.socketOptions; - config.options.socketOptions = socketOptions; - } - server = new Server(config.host, config.port, config.options); - - if (dbOptions.username === undefined) { - dbOptions.username = config.username; - dbOptions.password = config.password; - } - } - - var skinServer = new SkinServer(server); - return skinServer.db(database, dbOptions); -}; - -/** - * select different db by collection name - * - * @param select `function(name)` returns SkinDb - * - * ```js - * var router = mongoskin.router(function (name) { - * swhich (name) { - * case 'user': - * case 'group': - * return authDb; - * default: - * return appDb; - * } - * }); - * router.collection('user') - * ``` - * - * @param {Function(name)} select - * @return {Router} - * @api public - */ -exports.router = function (select) { - return new Router(select); -}; - -/* - * export Skin classes from ./db ./collection ./cursor ./admin - */ -['server', 'db', 'collection', 'cursor', 'admin'].forEach(function (path) { - var module = require('./' + path); - for (var name in module) { - exports[name] = module[name]; - } -}); diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/router.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/router.js deleted file mode 100644 index 1e7bf301d98..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/router.js +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * mongoskin - router.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -/** - * Router - * - * @param {Function(name)} select - * @constructor - * @api public - */ -var Router = exports.Router = function (select) { - this._select = select; - this._collections = {}; -}; - -/** - * Bind custom methods - * - * @param {String} name, collection name. - * @param {Object} [options] - * @return {Router} this - * @api public - */ -Router.prototype.bind = function (name, options) { - var args = Array.prototype.slice.call(arguments); - var database = this._select(name); - var collection = database.bind.apply(database, args); - this._collections[name] = collection; - Object.defineProperty(this, name, { - value: collection, - writable: false, - enumerable: true - }); - return this; -}; - -Router.prototype.collection = function (name) { - return this._collections[name] || (this._collections[name] = this._select(name).collection(name)); -}; diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/server.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/server.js deleted file mode 100644 index 54baaf44dfd..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/server.js +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * mongoskin - server.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var mongodb = require('mongodb'); -var Db = mongodb.Db; -var Server = mongodb.Server; -var SkinDb = require('./db').SkinDb; - -/** - * Construct SkinServer with native Server - * - * @param {Server} server - * @constructor - * @api public - */ -var SkinServer = exports.SkinServer = function (server) { - this.server = server; - this._cache_ = {}; -}; - -/** - * Create SkinDb from a SkinServer - * - * @param {String} name database name - * @param {Object} [options] - * @return {SkinDb} - * @api public - */ -SkinServer.prototype.db = function (name, options) { - options = options || {}; - var username = options.username || ''; - var key = username + '@' + name; - var skinDb = this._cache_[key]; - if (!skinDb || skinDb.fail) { - var password = options.password; - if (!options.native_parser) { - options.native_parser = !! mongodb.BSONNative; - } - var db = new Db(name, this.server, options); - skinDb = new SkinDb(db, username, password); - this._cache_[key] = skinDb; - } - return skinDb; -}; diff --git a/frontend/express/node_modules/mongoskin/lib/mongoskin/utils.js b/frontend/express/node_modules/mongoskin/lib/mongoskin/utils.js deleted file mode 100644 index 9b98231e607..00000000000 --- a/frontend/express/node_modules/mongoskin/lib/mongoskin/utils.js +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * mongoskin - utils.js - * - * Copyright(c) 2011 - 2012 kissjs.org - * Copyright(c) 2012 fengmk2 - * MIT Licensed - */ - -"use strict"; - -/** - * Module dependencies. - */ - -var __slice = Array.prototype.slice; -var EventEmitter = require('events').EventEmitter; -var constant = require('./constant'); -var STATE_OPEN = constant.STATE_OPEN; -var STATE_OPENNING = constant.STATE_OPENNING; -var STATE_CLOSE = constant.STATE_CLOSE; - -exports.inherits = require('util').inherits; - -exports.error = function (err, args, name) { - var cb = args.pop(); - if (cb && typeof cb === 'function') { - cb(err); - } else { - console.error("Error occured with no callback to handle it while calling " + name, err); - } -}; - -/** - * SkinObject - * - * @constructor - * @api public - */ -exports.SkinObject = function () { - this.emitter = new EventEmitter(); - this.state = STATE_CLOSE; -}; - -/** - * Skin method binding. - * - * @param {String} objName - * @param {Function} obj - * @param {String} nativeObjName - * @param {String} methodName - * @param {Function} method - * @return {Function} - */ -exports.bindSkin = function (objName, obj, nativeObjName, methodName, method) { - if (typeof method !== 'function') { - return; - } - return obj.prototype[methodName] = function () { - var args = __slice.call(arguments); - if (this.state === STATE_OPEN) { - method.apply(this[nativeObjName], args); - return this; - } - this.open(function (err, nativeObj) { - if (err) { - exports.error(err, args, objName + '.' + methodName); - } else { - return method.apply(nativeObj, args); - } - }); - return this; - }; -}; - -exports.extend = function (destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; -}; - -exports.noop = function () {}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/logo.png b/frontend/express/node_modules/mongoskin/logo.png deleted file mode 100644 index c8de074af05..00000000000 Binary files a/frontend/express/node_modules/mongoskin/logo.png and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/.travis.yml b/frontend/express/node_modules/mongoskin/node_modules/mongodb/.travis.yml deleted file mode 100644 index 0140117b64d..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.10 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md b/frontend/express/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md deleted file mode 100644 index 2a1c52e2abd..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/CONTRIBUTING.md +++ /dev/null @@ -1,23 +0,0 @@ -## Contributing to the driver - -### Bugfixes - -- Before starting to write code, look for existing [tickets](https://github.com/mongodb/node-mongodb-native/issues) or [create one](https://github.com/mongodb/node-mongodb-native/issues/new) for your specific issue. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch. -- Fork the [repo](https://github.com/mongodb/node-mongodb-native) _or_ for small documentation changes, navigate to the source on github and click the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. -- Follow the general coding style of the rest of the project: - - 2 space tabs - - no trailing whitespace - - comma last - - inline documentation for new methods, class members, etc - - 0 space between conditionals/functions, and their parenthesis and curly braces - - `if(..) {` - - `for(..) {` - - `while(..) {` - - `function(err) {` -- Write tests and make sure they pass (execute `make test` from the cmd line to run the test suite). - -### Documentation - -To contribute to the [API documentation](http://mongodb.github.com/node-mongodb-native/) just make your changes to the inline documentation of the appropriate [source code](https://github.com/mongodb/node-mongodb-native/tree/master/docs) in the master branch and submit a [pull request](https://help.github.com/articles/using-pull-requests/). You might also use the github [Edit](https://github.com/blog/844-forking-with-the-edit-button) button. - -If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make generate_docs`. Make sure you have the python documentation framework sphinx installed `easy_install sphinx`. The docs are generated under `docs/build'. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes. \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/Makefile deleted file mode 100644 index 59d2bfeb89e..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit -DOX = node_modules/dox/bin/dox -name = all - -total: build_native - -test_functional: - node test/runner.js -t functional - -test_ssl: - node test/runner.js -t ssl - -test_replicaset: - node test/runner.js -t replicaset - -test_sharded: - node test/runner.js -t sharded - -test_auth: - node test/runner.js -t auth - -generate_docs: - $(NODE) dev/tools/build-docs.js - make --directory=./docs/sphinx-docs --file=Makefile html - -.PHONY: total diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/Readme.md b/frontend/express/node_modules/mongoskin/node_modules/mongodb/Readme.md deleted file mode 100644 index b81e719bfe4..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/Readme.md +++ /dev/null @@ -1,442 +0,0 @@ -Up to date documentation -======================== - -[Documentation](http://mongodb.github.com/node-mongodb-native/) - -Install -======= - -To install the most recent release from npm, run: - - npm install mongodb - -That may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version) - -To install the latest from the repository, run:: - - npm install path/to/node-mongodb-native - -Community -========= -Check out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver. - -Try it live -============ - - -Introduction -============ - -This is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/. - -A simple example of inserting a document. - -```javascript - var client = new Db('test', new Server("127.0.0.1", 27017, {}), {w: 1}), - test = function (err, collection) { - collection.insert({a:2}, function(err, docs) { - - collection.count(function(err, count) { - test.assertEquals(1, count); - }); - - // Locate all the entries using find - collection.find().toArray(function(err, results) { - test.assertEquals(1, results.length); - test.assertTrue(results[0].a === 2); - - // Let's close the db - client.close(); - }); - }); - }; - - client.open(function(err, p_client) { - client.collection('test_insert', test); - }); -``` - -Data types -========== - -To store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code). - -In particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example: - -```javascript - // Get the objectID type - var ObjectID = require('mongodb').ObjectID; - - var idString = '4e4e1638c85e808431000003'; - collection.findOne({_id: new ObjectID(idString)}, console.log) // ok - collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined -``` - -Here are the constructors the non-Javascript BSON primitive types: - -```javascript - // Fetch the library - var mongo = require('mongodb'); - // Create new instances of BSON types - new mongo.Long(numberString) - new mongo.ObjectID(hexString) - new mongo.Timestamp() // the actual unique number is generated on insert. - new mongo.DBRef(collectionName, id, dbName) - new mongo.Binary(buffer) // takes a string or Buffer - new mongo.Code(code, [context]) - new mongo.Symbol(string) - new mongo.MinKey() - new mongo.MaxKey() - new mongo.Double(number) // Force double storage -``` - -The C/C++ bson parser/serializer --------------------------------- - -If you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below - -```javascript - // using native_parser: - var client = new Db('integration_tests_20', - new Server("127.0.0.1", 27017), - {native_parser:true}); -``` - -The C++ parser uses the js objects both for serialization and deserialization. - -GitHub information -================== - -The source code is available at http://github.com/mongodb/node-mongodb-native. -You can either clone the repository or download a tarball of the latest release. - -Once you have the source you can test the driver by running - - $ make test - -in the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass. - -Examples -======== - -For examples look in the examples/ directory. You can execute the examples using node. - - $ cd examples - $ node queries.js - -GridStore -========= - -The GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition. - -For more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md) - -Replicasets -=========== -For more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md) - -Primary Key Factories ---------------------- - -Defining your own primary key factory allows you to generate your own series of id's -(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long "string". - -Simple example below - -```javascript - // Custom factory (need to provide a 12 byte array); - CustomPKFactory = function() {} - CustomPKFactory.prototype = new Object(); - CustomPKFactory.createPk = function() { - return new ObjectID("aaaaaaaaaaaa"); - } - - var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory}); - p_client.open(function(err, p_client) { - p_client.dropDatabase(function(err, done) { - p_client.createCollection('test_custom_key', function(err, collection) { - collection.insert({'a':1}, function(err, docs) { - collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) { - cursor.toArray(function(err, items) { - test.assertEquals(1, items.length); - - // Let's close the db - p_client.close(); - }); - }); - }); - }); - }); - }); -``` - -Strict mode ------------ - -Each database has an optional strict mode. If it is set then asking for a collection -that does not exist will return an Error object in the callback. Similarly if you -attempt to create a collection that already exists. Strict is provided for convenience. - -```javascript - var error_client = new Db('integration_tests_', new Server("127.0.0.1", 27017, {auto_reconnect: false}), {strict:true}); - test.assertEquals(true, error_client.strict); - - error_client.open(function(err, error_client) { - error_client.collection('does-not-exist', function(err, collection) { - test.assertTrue(err instanceof Error); - test.assertEquals("Collection does-not-exist does not exist. Currently in strict mode.", err.message); - }); - - error_client.createCollection('test_strict_access_collection', function(err, collection) { - error_client.collection('test_strict_access_collection', function(err, collection) { - test.assertTrue(collection instanceof Collection); - // Let's close the db - error_client.close(); - }); - }); - }); -``` - -Documentation -============= - -If this document doesn't answer your questions, see the source of -[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js) -or [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js), -or the documentation at MongoDB for query and update formats. - -Find ----- - -The find method is actually a factory method to create -Cursor objects. A Cursor lazily uses the connection the first time -you call `nextObject`, `each`, or `toArray`. - -The basic operation on a cursor is the `nextObject` method -that fetches the next matching document from the database. The convenience -methods `each` and `toArray` call `nextObject` until the cursor is exhausted. - -Signatures: - -```javascript - var cursor = collection.find(query, [fields], options); - cursor.sort(fields).limit(n).skip(m). - - cursor.nextObject(function(err, doc) {}); - cursor.each(function(err, doc) {}); - cursor.toArray(function(err, docs) {}); - - cursor.rewind() // reset the cursor to its initial state. -``` - -Useful chainable methods of cursor. These can optionally be options of `find` instead of method calls: - -* `.limit(n).skip(m)` to control paging. -* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes: - * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2. - * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above - * `.sort([['field1', 'desc'], 'field2'])` same as above - * `.sort('field1')` ascending by field1 - -Other options of `find`: - -* `fields` the fields to fetch (to avoid transferring the entire document) -* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors). -* `batchSize` The number of the subset of results to request the database -to return for every request. This should initially be greater than 1 otherwise -the database will automatically close the cursor. The batch size can be set to 1 -with `batchSize(n, function(err){})` after performing the initial query to the database. -* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint). -* `explain` turns this into an explain query. You can also call -`explain()` on any cursor to fetch the explanation. -* `snapshot` prevents documents that are updated while the query is active -from being returned multiple times. See more -[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database). -* `timeout` if false, asks MongoDb not to time out this cursor after an -inactivity period. - - -For information on how to create queries, see the -[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.find({}, {limit:10}).toArray(function(err, docs) { - console.dir(docs); - }); - }); -``` - -Insert ------- - -Signature: - -```javascript - collection.insert(docs, options, [callback]); -``` - -where `docs` can be a single document or an array of documents. - -Useful options: - -* `safe:true` Should always set if you have a callback. - -See also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting). - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.insert({hello: 'world'}, {safe:true}, - function(err, objects) { - if (err) console.warn(err.message); - if (err && err.message.indexOf('E11000 ') !== -1) { - // this _id was already inserted in the database - } - }); - }); -``` - -Note that there's no reason to pass a callback to the insert or update commands -unless you use the `safe:true` option. If you don't specify `safe:true`, then -your callback will be called immediately. - -Update; update and insert (upsert) ----------------------------------- - -The update operation will update the first document that matches your query -(or all documents that match if you use `multi:true`). -If `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated. - -See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for -the modifier (`$inc`, `$set`, `$push`, etc.) formats. - -Signature: - -```javascript - collection.update(criteria, objNew, options, [callback]); -``` - -Useful options: - -* `safe:true` Should always set if you have a callback. -* `multi:true` If set, all matching documents are updated, not just the first. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `update`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true}, - function(err) { - if (err) console.warn(err.message); - else console.log('successfully updated'); - }); - }); -``` - -Find and modify ---------------- - -`findAndModify` is like `update`, but it also gives the updated document to -your callback. But there are a few key differences between findAndModify and -update: - - 1. The signatures differ. - 2. You can only findAndModify a single item, not multiple items. - -Signature: - -```javascript - collection.findAndModify(query, sort, update, options, callback) -``` - -The sort parameter is used to specify which object to operate on, if more than -one document matches. It takes the same format as the cursor sort (see -Connection.find above). - -See the -[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) -for more details. - -Useful options: - -* `remove:true` set to a true to remove the object before returning -* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove. -* `upsert:true` Atomically inserts the document if no documents matched. - -Example for `findAndModify`: - -```javascript - var mongodb = require('mongodb'); - var server = new mongodb.Server("127.0.0.1", 27017, {}); - new mongodb.Db('test', server, {w: 1}).open(function (error, client) { - if (error) throw error; - var collection = new mongodb.Collection(client, 'test_collection'); - collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {}, - function(err, object) { - if (err) console.warn(err.message); - else console.dir(object); // undefined if no matching object exists. - }); - }); -``` - -Save ----- - -The `save` method is a shorthand for upsert if the document contains an -`_id`, or an insert if there is no `_id`. - -Sponsors -======== -Just as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB. - -If your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details. - -And I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing. - -Release Notes -============= - -See HISTORY - -Credits -======= - -1. [10gen](http://github.com/mongodb/mongo-ruby-driver/) -2. [Google Closure Library](http://code.google.com/closure/library/) -3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser) - -Contributors -============ - -Aaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy - -License -======= - - Copyright 2009 - 2012 Christian Amor Kvalheim. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile deleted file mode 100644 index ad877d4bd3c..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -test: - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - @$(NODE) --expose-gc test/test_bson.js - @$(NODE) --expose-gc test/test_full_bson.js - # @$(NODE) --expose-gc test/test_stackless_bson.js - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc deleted file mode 100644 index 8906eea9ac6..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.cc +++ /dev/null @@ -1,2165 +0,0 @@ -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bson.h" - -using namespace v8; -using namespace node; -using namespace std; - -// BSON DATA TYPES -const uint32_t BSON_DATA_NUMBER = 1; -const uint32_t BSON_DATA_STRING = 2; -const uint32_t BSON_DATA_OBJECT = 3; -const uint32_t BSON_DATA_ARRAY = 4; -const uint32_t BSON_DATA_BINARY = 5; -const uint32_t BSON_DATA_OID = 7; -const uint32_t BSON_DATA_BOOLEAN = 8; -const uint32_t BSON_DATA_DATE = 9; -const uint32_t BSON_DATA_NULL = 10; -const uint32_t BSON_DATA_REGEXP = 11; -const uint32_t BSON_DATA_CODE = 13; -const uint32_t BSON_DATA_SYMBOL = 14; -const uint32_t BSON_DATA_CODE_W_SCOPE = 15; -const uint32_t BSON_DATA_INT = 16; -const uint32_t BSON_DATA_TIMESTAMP = 17; -const uint32_t BSON_DATA_LONG = 18; -const uint32_t BSON_DATA_MIN_KEY = 0xff; -const uint32_t BSON_DATA_MAX_KEY = 0x7f; - -const int32_t BSON_INT32_MAX = (int32_t)2147483647L; -const int32_t BSON_INT32_MIN = (int32_t)(-1) * 2147483648L; - -const int64_t BSON_INT64_MAX = ((int64_t)1 << 63) - 1; -const int64_t BSON_INT64_MIN = (int64_t)-1 << 63; - -const int64_t JS_INT_MAX = (int64_t)1 << 53; -const int64_t JS_INT_MIN = (int64_t)-1 << 53; - -static Handle VException(const char *msg) { - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); - }; - -Persistent BSON::constructor_template; - -void BSON::Initialize(v8::Handle target) { - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - // Experimental - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize2", CalculateObjectSize2); - // NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize2", BSONSerialize2); - // NODE_SET_METHOD(constructor_template->GetFunction(), "serialize2", BSONSerialize2); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and assing it the existing context -Handle BSON::New(const Arguments &args) { - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - // Setup pre-allocated comparision objects - bson->_bsontypeString = Persistent::New(String::New("_bsontype")); - bson->_longLowString = Persistent::New(String::New("low_")); - bson->_longHighString = Persistent::New(String::New("high_")); - bson->_objectIDidString = Persistent::New(String::New("id")); - bson->_binaryPositionString = Persistent::New(String::New("position")); - bson->_binarySubTypeString = Persistent::New(String::New("sub_type")); - bson->_binaryBufferString = Persistent::New(String::New("buffer")); - bson->_doubleValueString = Persistent::New(String::New("value")); - bson->_symbolValueString = Persistent::New(String::New("value")); - bson->_dbRefRefString = Persistent::New(String::New("$ref")); - bson->_dbRefIdRefString = Persistent::New(String::New("$id")); - bson->_dbRefDbRefString = Persistent::New(String::New("$db")); - bson->_dbRefNamespaceString = Persistent::New(String::New("namespace")); - bson->_dbRefDbString = Persistent::New(String::New("db")); - bson->_dbRefOidString = Persistent::New(String::New("oid")); - - // total number of found classes - uint32_t numberOfClasses = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(String::New("Long"))) { - bson->longConstructor = Persistent::New(func); - bson->longString = Persistent::New(String::New("Long")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("ObjectID"))) { - bson->objectIDConstructor = Persistent::New(func); - bson->objectIDString = Persistent::New(String::New("ObjectID")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Binary"))) { - bson->binaryConstructor = Persistent::New(func); - bson->binaryString = Persistent::New(String::New("Binary")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Code"))) { - bson->codeConstructor = Persistent::New(func); - bson->codeString = Persistent::New(String::New("Code")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("DBRef"))) { - bson->dbrefConstructor = Persistent::New(func); - bson->dbrefString = Persistent::New(String::New("DBRef")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Symbol"))) { - bson->symbolConstructor = Persistent::New(func); - bson->symbolString = Persistent::New(String::New("Symbol")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Double"))) { - bson->doubleConstructor = Persistent::New(func); - bson->doubleString = Persistent::New(String::New("Double")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("Timestamp"))) { - bson->timestampConstructor = Persistent::New(func); - bson->timestampString = Persistent::New(String::New("Timestamp")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MinKey"))) { - bson->minKeyConstructor = Persistent::New(func); - bson->minKeyString = Persistent::New(String::New("MinKey")); - numberOfClasses = numberOfClasses + 1; - } else if(functionName->StrictEquals(String::New("MaxKey"))) { - bson->maxKeyConstructor = Persistent::New(func); - bson->maxKeyString = Persistent::New(String::New("MaxKey")); - numberOfClasses = numberOfClasses + 1; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(numberOfClasses != 10) { - // Destroy object - delete(bson); - // Fire exception - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } else { - return VException("No types passed in"); - } - } else { - return VException("Argument passed in must be an array of types"); - } -} - -void BSON::write_int32(char *data, uint32_t value) { - // Write the int to the char* - memcpy(data, &value, 4); -} - -void BSON::write_double(char *data, double value) { - // Write the double to the char* - memcpy(data, &value, 8); -} - -void BSON::write_int64(char *data, int64_t value) { - // Write the int to the char* - memcpy(data, &value, 8); -} - -char *BSON::check_key(Local key) { - // Allocate space for they key string - char *key_str = (char *)malloc(key->Utf8Length() * sizeof(char) + 1); - // Error string - char *error_str = (char *)malloc(256 * sizeof(char)); - // Decode the key - ssize_t len = DecodeBytes(key, BINARY); - DecodeWrite(key_str, len, key, BINARY); - *(key_str + key->Utf8Length()) = '\0'; - // Check if we have a valid key - if(key->Utf8Length() > 0 && *(key_str) == '$') { - // Create the string - sprintf(error_str, "key %s must not start with '$'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } else if(key->Utf8Length() > 0 && strchr(key_str, '.') != NULL) { - // Create the string - sprintf(error_str, "key %s must not contain '.'", key_str); - // Free up memory - free(key_str); - // Throw exception with string - throw error_str; - } - // Free allocated space - free(key_str); - free(error_str); - // Return No check key error - return NULL; -} - -const char* BSON::ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : ""; -} - -Handle BSON::decodeDBref(BSON *bson, Local ref, Local oid, Local db) { - HandleScope scope; - Local argv[] = {ref, oid, db}; - Handle dbrefObj = bson->dbrefConstructor->NewInstance(3, argv); - return scope.Close(dbrefObj); -} - -Handle BSON::decodeCode(BSON *bson, char *code, Handle scope_object) { - HandleScope scope; - - Local argv[] = {String::New(code), scope_object->ToObject()}; - Handle codeObj = bson->codeConstructor->NewInstance(2, argv); - return scope.Close(codeObj); -} - -Handle BSON::decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data) { - HandleScope scope; - - // Create a buffer object that wraps the raw stream - Buffer *bufferObj = Buffer::New(data, number_of_bytes); - // Arguments to be passed to create the binary - Handle argv[] = {bufferObj->handle_, Uint32::New(sub_type)}; - // Return the buffer handle - Local bufferObjHandle = bson->binaryConstructor->NewInstance(2, argv); - // Close the scope - return scope.Close(bufferObjHandle); -} - -Handle BSON::decodeOid(BSON *bson, char *oid) { - HandleScope scope; - - // Encode the string (string - null termiating character) - Local bin_value = Encode(oid, 12, BINARY)->ToString(); - - // Return the id object - Local argv[] = {bin_value}; - Local oidObj = bson->objectIDConstructor->NewInstance(1, argv); - return scope.Close(oidObj); -} - -Handle BSON::decodeLong(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Decode 64bit value - int64_t value = 0; - memcpy(&value, (data + index), 8); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - int64_t finalValue = 0; - memcpy(&finalValue, (data + index), 8); - return scope.Close(Number::New(finalValue)); - } - - // Instantiate the js object and pass it back - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Local longObject = bson->longConstructor->NewInstance(2, argv); - return scope.Close(longObject); -} - -Handle BSON::decodeTimestamp(BSON *bson, char *data, uint32_t index) { - HandleScope scope; - - // Decode the integer value - int32_t lowBits = 0; - int32_t highBits = 0; - memcpy(&lowBits, (data + index), 4); - memcpy(&highBits, (data + index + 4), 4); - - // Build timestamp - Local argv[] = {Int32::New(lowBits), Int32::New(highBits)}; - Handle timestamp_obj = bson->timestampConstructor->NewInstance(2, argv); - return scope.Close(timestamp_obj); -} - -// Search for 0 terminated C string and return the string -char* BSON::extract_string(char *data, uint32_t offset) { - char *prt = strchr((data + offset), '\0'); - if(prt == NULL) return NULL; - // Figure out the length of the string - uint32_t length = (prt - data) - offset; - // Allocate memory for the new string - char *string_name = (char *)malloc((length * sizeof(char)) + 1); - // Copy the variable into the string_name - strncpy(string_name, (data + offset), length); - // Ensure the string is null terminated - *(string_name + length) = '\0'; - // Return the unpacked string - return string_name; -} - -// Decode a byte -uint16_t BSON::deserialize_int8(char *data, uint32_t offset) { - uint16_t value = 0; - value |= *(data + offset + 0); - return value; -} - -// Requires a 4 byte char array -uint32_t BSON::deserialize_int32(char* data, uint32_t offset) { - uint32_t value = 0; - memcpy(&value, (data + offset), 4); - return value; -} - -//------------------------------------------------------------------------------------------------ -// -// Experimental -// -//------------------------------------------------------------------------------------------------ -Handle BSON::CalculateObjectSize2(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() > 1) return VException("One argument required - [object]"); - // Calculate size of the object - uint32_t object_size = BSON::calculate_object_size2(args[0]); - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size2(Handle value) { - // Final object size - uint32_t object_size = (4 + 1); - uint32_t stackIndex = 0; - // Controls the flow - bool done = false; - bool finished = false; - - // Current object we are processing - Local currentObject = value->ToObject(); - - // Current list of object keys - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local keys = currentObject->GetPropertyNames(); - #else - Local keys = currentObject->GetOwnPropertyNames(); - #endif - - // Contains pointer to keysIndex - uint32_t keysIndex = 0; - uint32_t keysLength = keys->Length(); - - // printf("=================================================================================\n"); - // printf("Start serializing\n"); - - while(!done) { - // If the index is bigger than the number of keys for the object - // we finished up the previous object and are ready for the next one - if(keysIndex >= keysLength) { - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - keys = currentObject->GetPropertyNames(); - #else - keys = currentObject->GetOwnPropertyNames(); - #endif - keysLength = keys->Length(); - } - - // Iterate over all the keys - while(keysIndex < keysLength) { - // Fetch the key name - Local name = keys->Get(keysIndex++)->ToString(); - // Fetch the object related to the key - Local value = currentObject->Get(name); - // Add size of the name, plus zero, plus type - object_size += name->Utf8Length() + 1 + 1; - - // If we have a string - if(value->IsString()) { - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } - // } else if(value->IsNumber()) { - // // Check if we have a float value or a long value - // Local number = value->ToNumber(); - // double d_number = number->NumberValue(); - // int64_t l_number = number->IntegerValue(); - // // Check if we have a double value and not a int64 - // double d_result = d_number - l_number; - // // If we have a value after subtracting the integer value we have a float - // if(d_result > 0 || d_result < 0) { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // object_size = name->Utf8Length() + 1 + object_size + 4 + 1; - // } else { - // object_size = name->Utf8Length() + 1 + object_size + 8 + 1; - // } - // } else if(value->IsObject()) { - // printf("------------- hello\n"); - // } - } - - // If we have finished all the keys - if(keysIndex == keysLength) { - finished = false; - } - - // Validate the stack - if(stackIndex == 0) { - // printf("======================================================================== 3\n"); - done = true; - } else if(finished || keysIndex == keysLength) { - // Pop off the stack - stackIndex = stackIndex - 1; - // Fetch the current object stack - // vector > currentObjectStored = stack.back(); - // stack.pop_back(); - // // Unroll the current object - // currentObject = currentObjectStored.back()->ToObject(); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keys = Local::Cast(currentObjectStored.back()->ToObject()); - // currentObjectStored.pop_back(); - // // Unroll the keysIndex - // keysIndex = currentObjectStored.back()->ToUint32()->Value(); - // currentObjectStored.pop_back(); - // // Check if we finished up - // if(keysIndex == keys->Length()) { - // finished = true; - // } - } - } - - return object_size; -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -Handle BSON::BSONDeserialize(const Arguments &args) { - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - char *data; - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) { - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - uint32_t length = buffer->length(); - #else - data = Buffer::Data(obj); - uint32_t length = Buffer::Length(obj); - #endif - - // Validate that we have at least 5 bytes - if(length < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Deserialize the data - return BSON::deserialize(bson, data, length, 0, NULL); - } else { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) { - return VException("corrupt bson message < 5 bytes long"); - } - - // Let's define the buffer size - data = (char *)malloc(len); - // Write the data to the buffer from the string object - ssize_t written = DecodeWrite(data, len, args[0], BINARY); - // Assert that we wrote the same number of bytes as we have length - assert(written == len); - // Get result - Handle result = BSON::deserialize(bson, data, len, 0, NULL); - // Free memory - free(data); - // Deserialize the content - return result; - } -} - -// Deserialize the stream -Handle BSON::deserialize(BSON *bson, char *data, uint32_t inDataLength, uint32_t startIndex, bool is_array_item) { - HandleScope scope; - // Holds references to the objects that are going to be returned - Local return_data = Object::New(); - Local return_array = Array::New(); - // The current index in the char data - uint32_t index = startIndex; - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // If we have an illegal message size - if(size > inDataLength) return VException("corrupt bson message"); - - // Data length - uint32_t dataLength = index + size; - - // Adjust the index to point to next piece - index = index + 4; - - // While we have data left let's decode - while(index < dataLength) { - // Read the first to bytes to indicate the type of object we are decoding - uint8_t type = BSON::deserialize_int8(data, index); - // Adjust index to skip type byte - index = index + 1; - - if(type == BSON_DATA_STRING) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), utf8_encoded_str); - } else { - return_data->ForceSet(String::New(string_name), utf8_encoded_str); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_INT) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - uint32_t value = 0; - memcpy(&value, (data + index), 4); - - // Adjust the index for the size of the value - index = index + 4; - // Add the element to the object - if(is_array_item) { - return_array->Set(Integer::New(insert_index), Integer::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Integer::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_TIMESTAMP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeTimestamp(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeTimestamp(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_LONG) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeLong(bson, data, index)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeLong(bson, data, index)); - } - - // Adjust the index for the size of the value - index = index + 8; - - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NUMBER) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the integer value - double value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Number::New(value)); - } else { - return_data->ForceSet(String::New(string_name), Number::New(value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MIN_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local minKey = bson->minKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), minKey); - } else { - return_data->ForceSet(String::New(string_name), minKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_MAX_KEY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Create new MinKey - Local maxKey = bson->maxKeyConstructor->NewInstance(); - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), maxKey); - } else { - return_data->ForceSet(String::New(string_name), maxKey); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_NULL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Null()); - } else { - return_data->ForceSet(String::New(string_name), Null()); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_BOOLEAN) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the boolean value - char bool_value = *(data + index); - // Adjust the index for the size of the value - index = index + 1; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } else { - return_data->ForceSet(String::New(string_name), bool_value == 1 ? Boolean::New(true) : Boolean::New(false)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_DATE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Decode the value 64 bit integer - int64_t value = 0; - memcpy(&value, (data + index), 8); - // Adjust the index for the size of the value - index = index + 8; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), Date::New((double)value)); - } else { - return_data->ForceSet(String::New(string_name), Date::New((double)value)); - } - // Free up the memory - free(string_name); - } else if(type == BSON_DATA_REGEXP) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Length variable - int32_t length_regexp = 0; - char chr; - - // Locate end of the regexp expression \0 - while((chr = *(data + index + length_regexp)) != '\0') { - length_regexp = length_regexp + 1; - } - - // Contains the reg exp - char *reg_exp = (char *)malloc(length_regexp * sizeof(char) + 2); - // Copy the regexp from the data to the char * - memcpy(reg_exp, (data + index), (length_regexp + 1)); - // Adjust the index to skip the first part of the regular expression - index = index + length_regexp + 1; - - // Reset the length - int32_t options_length = 0; - // Locate the end of the options for the regexp terminated with a '\0' - while((chr = *(data + index + options_length)) != '\0') { - options_length = options_length + 1; - } - - // Contains the reg exp - char *options = (char *)malloc(options_length * sizeof(char) + 1); - // Copy the options from the data to the char * - memcpy(options, (data + index), (options_length + 1)); - // Adjust the index to skip the option part of the regular expression - index = index + options_length + 1; - // ARRRRGH Google does not expose regular expressions through the v8 api - // Have to use Script to instantiate the object (slower) - - // Generate the string for execution in the string context - int flag = 0; - - for(int i = 0; i < options_length; i++) { - // Multiline - if(*(options + i) == 'm') { - flag = flag | 4; - } else if(*(options + i) == 'i') { - flag = flag | 2; - } - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } else { - return_data->ForceSet(String::New(string_name), RegExp::New(String::New(reg_exp), (v8::RegExp::Flags)flag)); - } - - // Free memory - free(reg_exp); - free(options); - free(string_name); - } else if(type == BSON_DATA_OID) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // The id string - char *oid_string = (char *)malloc(12 * sizeof(char)); - // Copy the options from the data to the char * - memcpy(oid_string, (data + index), 12); - - // Adjust the index - index = index + 12; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeOid(bson, oid_string)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeOid(bson, oid_string)); - } - - // Free memory - free(oid_string); - free(string_name); - } else if(type == BSON_DATA_BINARY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the binary data size - uint32_t number_of_bytes = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Decode the subtype, ensure it's positive - uint32_t sub_type = (int)*(data + index) & 0xff; - // Adjust the index - index = index + 1; - // Copy the binary data into a buffer - char *buffer = (char *)malloc(number_of_bytes * sizeof(char) + 1); - memcpy(buffer, (data + index), number_of_bytes); - *(buffer + number_of_bytes) = '\0'; - - // Adjust the index - index = index + number_of_bytes; - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } else { - return_data->ForceSet(String::New(string_name), BSON::decodeBinary(bson, sub_type, number_of_bytes, buffer)); - } - // Free memory - free(buffer); - free(string_name); - } else if(type == BSON_DATA_SYMBOL) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the length of the string (next 4 bytes) - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust index to point to start of string - index = index + 4; - // Decode the string and add zero terminating value at the end of the string - char *value = (char *)malloc((string_size * sizeof(char))); - strncpy(value, (data + index), string_size); - // Encode the string (string - null termiating character) - Local utf8_encoded_str = Encode(value, string_size - 1, UTF8)->ToString(); - - // Wrap up the string in a Symbol Object - Local argv[] = {utf8_encoded_str}; - Handle symbolObj = bson->symbolConstructor->NewInstance(1, argv); - - // Add the value to the data - if(is_array_item) { - return_array->Set(Number::New(insert_index), symbolObj); - } else { - return_data->ForceSet(String::New(string_name), symbolObj); - } - - // Adjust index - index = index + string_size; - // Free up the memory - free(value); - free(string_name); - } else if(type == BSON_DATA_CODE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - - // Define empty scope object - Handle scope_object = Object::New(); - - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - free(string_name); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(string_name); - } else if(type == BSON_DATA_CODE_W_SCOPE) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Total number of bytes after array index - uint32_t total_code_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string size - uint32_t string_size = BSON::deserialize_int32(data, index); - // Adjust the index - index = index + 4; - // Read the string - char *code = (char *)malloc(string_size * sizeof(char) + 1); - // Copy string + terminating 0 - memcpy(code, (data + index), string_size); - // Adjust the index - index = index + string_size; - // Get the scope object (bson object) - uint32_t bson_object_size = total_code_size - string_size - 8; - // Allocate bson object buffer and copy out the content - char *bson_buffer = (char *)malloc(bson_object_size * sizeof(char)); - memcpy(bson_buffer, (data + index), bson_object_size); - // Adjust the index - index = index + bson_object_size; - // Parse the bson object - Handle scope_object = BSON::deserialize(bson, bson_buffer, inDataLength, 0, false); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::decodeCode(bson, code, scope_object); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Clean up memory allocation - free(string_name); - free(bson_buffer); - free(code); - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(code); - free(bson_buffer); - free(string_name); - } else if(type == BSON_DATA_OBJECT) { - // If this is the top level object we need to skip the undecoding - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the object size - uint32_t bson_object_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, false); - // Adjust the index - index = index + bson_object_size; - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - - // Clean up memory allocation - free(string_name); - } else if(type == BSON_DATA_ARRAY) { - // Read the null terminated index String - char *string_name = BSON::extract_string(data, index); - if(string_name == NULL) return VException("Invalid C String found."); - // Let's create a new string - index = index + strlen(string_name) + 1; - // Handle array value if applicable - uint32_t insert_index = 0; - if(is_array_item) { - insert_index = atoi(string_name); - } - - // Get the size - uint32_t array_size = BSON::deserialize_int32(data, index); - // Define the try catch block - TryCatch try_catch; - - // Decode the code object - Handle obj = BSON::deserialize(bson, data + index, inDataLength, 0, true); - // If an error was thrown push it up the chain - if(try_catch.HasCaught()) { - // Rethrow exception - return try_catch.ReThrow(); - } - // Adjust the index for the next value - index = index + array_size; - // Add the element to the object - if(is_array_item) { - return_array->Set(Number::New(insert_index), obj); - } else { - return_data->ForceSet(String::New(string_name), obj); - } - // Clean up memory allocation - free(string_name); - } - } - - // Check if we have a db reference - if(!is_array_item && return_data->Has(String::New("$ref")) && return_data->Has(String::New("$id"))) { - Handle dbrefValue = BSON::decodeDBref(bson, return_data->Get(String::New("$ref")), return_data->Get(String::New("$id")), return_data->Get(String::New("$db"))); - return scope.Close(dbrefValue); - } - - // Return the data object to javascript - if(is_array_item) { - return scope.Close(return_array); - } else { - return scope.Close(return_data); - } -} - -Handle BSON::BSONSerialize(const Arguments &args) { - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - if(args.Length() == 4) { - object_size = BSON::calculate_object_size(bson, args[0], args[3]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 3 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - // Check if we have a boolean value - bool serializeFunctions = false; - if(args.Length() == 4 && args[1]->IsBoolean()) { - serializeFunctions = args[3]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - // Write the object size - BSON::write_int32((serialized_object), object_size); - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) { - // Local asBuffer = args[2]->ToBoolean(); - Buffer *buffer = Buffer::New(serialized_object, object_size); - // Release the serialized string - free(serialized_object); - return scope.Close(buffer->handle_); - } else { - // Encode the string (string - null termiating character) - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - // Return the serialized content - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) { - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Object size - uint32_t object_size = 0; - // Check if we have our argument, calculate size of the object - if(args.Length() >= 2) { - object_size = BSON::calculate_object_size(bson, args[0], args[1]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Return the object size - return scope.Close(Uint32::New(object_size)); -} - -uint32_t BSON::calculate_object_size(BSON *bson, Handle value, bool serializeFunctions) { - uint32_t object_size = 0; - - // If we have an object let's unwrap it and calculate the sub sections - if(value->IsString()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += value->ToString()->Utf8Length() + 1 + 4; - } else if(value->IsNumber()) { - // Check if we have a float value or a long value - Local number = value->ToNumber(); - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - object_size = object_size + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - object_size = object_size + 4; - } else { - object_size = object_size + 8; - } - } else if(value->IsBoolean()) { - object_size = object_size + 1; - } else if(value->IsDate()) { - object_size = object_size + 8; - } else if(value->IsRegExp()) { - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - ssize_t len = DecodeBytes(regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - - // global - if((flags & (1 << 0)) != 0) len++; - // ignorecase - if((flags & (1 << 1)) != 0) len++; - //multiline - if((flags & (1 << 2)) != 0) len++; - // if((flags & (1 << 2)) != 0) len++; - // Calculate the space needed for the regexp: size of string - 2 for the /'ses +2 for null termiations - object_size = object_size + len + 2; - } else if(value->IsNull() || value->IsUndefined()) { - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Calculate the size of each element - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Add the size of the string length - uint32_t label_length = strlen(length_str) + 1; - // Add the type definition size for each item - object_size = object_size + label_length + 1; - // Add size of the object - uint32_t object_length = BSON::calculate_object_size(bson, array->Get(Integer::New(i)), serializeFunctions); - object_size = object_size + object_length; - } - // Add the object size - object_size = object_size + 4 + 1; - // Free up memory - free(length_str); - } else if(value->IsFunction()) { - if(serializeFunctions) { - object_size += value->ToString()->Utf8Length() + 4 + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - object_size = object_size + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local positionObj = value->ToObject()->Get(String::New("position"))->ToUint32(); - // Adjust the object_size, binary content lengt + total size int32 + binary size int32 + subtype - object_size += positionObj->Value() + 4 + 1; - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Check if the scope has any parameters - // Let's calculate the size the code object adds adds - if(propertyNameLength > 0) { - object_size += function->Utf8Length() + 4 + BSON::calculate_object_size(bson, scope, serializeFunctions) + 4 + 1; - } else { - object_size += function->Utf8Length() + 4 + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - // Calculate size - object_size += BSON::calculate_object_size(bson, obj, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString) || bson->maxKeyString->Equals(constructorString)) { - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Get string - Local str = value->ToObject()->Get(String::New("value"))->ToString(); - // Get the utf8 length - int utf8_length = str->Utf8Length(); - // Check if we have a utf8 encoded string or not - if(utf8_length != str->Length()) { - // Let's calculate the size the string adds, length + type(1 byte) + size(4 bytes) - object_size += str->Utf8Length() + 1 + 4; - } else { - object_size += str->Length() + 1 + 4; - } - } else if(bson->doubleString->StrictEquals(constructorString)) { - object_size = object_size + 8; - } - } else if(value->IsObject()) { - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Length of the property - uint32_t propertyLength = property_names->Length(); - - // Process all the properties on the object - for(uint32_t index = 0; index < propertyLength; index++) { - // Fetch the property name - Local property_name = property_names->Get(index)->ToString(); - - // Fetch the object for the property - Local property = object->Get(property_name); - // Get size of property (property + property name length + 1 for terminating 0) - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - object_size += BSON::calculate_object_size(bson, property, serializeFunctions) + property_name->Utf8Length() + 1 + 1; - } - } - - object_size = object_size + 4 + 1; - } - - return object_size; -} - -uint32_t BSON::serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions) { - // Scope for method execution - HandleScope scope; - - // If we have a name check that key is valid - if(!name->IsNull() && check_key) { - if(BSON::check_key(name->ToString()) != NULL) return -1; - } - - // If we have an object let's serialize it - if(value->IsString()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_STRING; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Write the actual string into the char array - Local str = value->ToString(); - // Let's fetch the int value - uint32_t utf8_length = str->Utf8Length(); - - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else if(value->IsNumber()) { - uint32_t first_pointer = index; - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_INT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - Local number = value->ToNumber(); - // Get the values - double d_number = number->NumberValue(); - int64_t l_number = number->IntegerValue(); - - // Check if we have a double value and not a int64 - double d_result = d_number - l_number; - // If we have a value after subtracting the integer value we have a float - if(d_result > 0 || d_result < 0) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else if(l_number <= BSON_INT32_MAX && l_number >= BSON_INT32_MIN) { - // Smaller than 32 bit, write as 32 bit value - BSON::write_int32(serialized_object + index, value->ToInt32()->Value()); - // Adjust the size of the index - index = index + 4; - } else if(l_number <= JS_INT_MAX && l_number >= JS_INT_MIN) { - // Write the double to the char array - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust index for double - index = index + 8; - } else { - BSON::write_double((serialized_object + index), d_number); - // Adjust type to be double - *(serialized_object + first_pointer) = BSON_DATA_NUMBER; - // Adjust the size of the index - index = index + 8; - } - } else if(value->IsBoolean()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_BOOLEAN; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Save the boolean value - *(serialized_object + index) = value->BooleanValue() ? '\1' : '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsDate()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_DATE; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the Integer value - int64_t integer_value = value->IntegerValue(); - BSON::write_int64((serialized_object + index), integer_value); - // Adjust the index - index = index + 8; - } else if(value->IsNull() || value->IsUndefined()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_NULL; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } else if(value->IsArray()) { - // Cast to array - Local array = Local::Cast(value->ToObject()); - // Turn length into string to calculate the size of all the strings needed - char *length_str = (char *)malloc(256 * sizeof(char)); - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_ARRAY; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - // Object size - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size of the object - BSON::write_int32((serialized_object + index), object_size); - // Adjust the index - index = index + 4; - // Write out all the elements - for(uint32_t i = 0; i < array->Length(); i++) { - // Add "index" string size for each element - sprintf(length_str, "%d", i); - // Encode the values - index = BSON::serialize(bson, serialized_object, index, String::New(length_str), array->Get(Integer::New(i)), check_key, serializeFunctions); - // Write trailing '\0' for object - *(serialized_object + index) = '\0'; - } - - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - // Free up memory - free(length_str); - } else if(value->IsRegExp()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_REGEXP; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Fetch the string for the regexp - Handle regExp = Handle::Cast(value); - len = DecodeBytes(regExp->GetSource(), UTF8); - written = DecodeWrite((serialized_object + index), len, regExp->GetSource(), UTF8); - int flags = regExp->GetFlags(); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // global - if((flags & (1 << 0)) != 0) { - *(serialized_object + index) = 's'; - index = index + 1; - } - - // ignorecase - if((flags & (1 << 1)) != 0) { - *(serialized_object + index) = 'i'; - index = index + 1; - } - - //multiline - if((flags & (1 << 2)) != 0) { - *(serialized_object + index) = 'm'; - index = index + 1; - } - - // Add null termiation for the string - *(serialized_object + index) = '\0'; - // Adjust the index - index = index + 1; - } else if(value->IsFunction()) { - if(serializeFunctions) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_CODE; - - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - - // Function String - Local function = value->ToString(); - - // Decode the function - len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - written = DecodeWrite((serialized_object + index), len, function, BINARY); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(value->ToObject()->Has(bson->_bsontypeString)) { - // Handle holder - Local constructorString = value->ToObject()->GetConstructorName(); - uint32_t originalIndex = index; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - // Add null termiation for the string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - - // BSON type object, avoid non-needed checking unless we have a type - if(bson->longString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_LONG; - // Object reference - Local longObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = longObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = longObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->timestampString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_TIMESTAMP; - // Object reference - Local timestampObject = value->ToObject(); - - // Fetch the low and high bits - int32_t lowBits = timestampObject->Get(bson->_longLowString)->ToInt32()->Value(); - int32_t highBits = timestampObject->Get(bson->_longHighString)->ToInt32()->Value(); - - // Write the content to the char array - BSON::write_int32((serialized_object + index), lowBits); - BSON::write_int32((serialized_object + index + 4), highBits); - // Adjust the index - index = index + 8; - } else if(bson->objectIDString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_OID; - // Convert to object - Local objectIDObject = value->ToObject(); - // Let's grab the id - Local idString = objectIDObject->Get(bson->_objectIDidString)->ToString(); - // Let's decode the raw chars from the string - len = DecodeBytes(idString, BINARY); - written = DecodeWrite((serialized_object + index), len, idString, BINARY); - // Adjust the index - index = index + 12; - } else if(bson->binaryString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_BINARY; - - // Let's get the binary object - Local binaryObject = value->ToObject(); - - // Grab the size(position of the binary) - uint32_t position = value->ToObject()->Get(bson->_binaryPositionString)->ToUint32()->Value(); - // Grab the subtype - uint32_t subType = value->ToObject()->Get(bson->_binarySubTypeString)->ToUint32()->Value(); - // Grab the buffer object - Local bufferObj = value->ToObject()->Get(bson->_binaryBufferString)->ToObject(); - - // Buffer data pointers - char *data; - uint32_t length; - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(bufferObj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(bufferObj); - length = Buffer::Length(bufferObj); - #endif - - // Write the size of the buffer out - BSON::write_int32((serialized_object + index), position); - // Adjust index - index = index + 4; - // Write subtype - *(serialized_object + index) = (char)subType; - // Adjust index - index = index + 1; - // Write binary content - memcpy((serialized_object + index), data, position); - // Adjust index.rar">_ - index = index + position; - } else if(bson->doubleString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_NUMBER; - - // Unpack the double - Local doubleObject = value->ToObject(); - - // Fetch the double value - Local doubleValue = doubleObject->Get(bson->_doubleValueString)->ToNumber(); - // Write the double to the char array - BSON::write_double((serialized_object + index), doubleValue->NumberValue()); - // Adjust index for double - index = index + 8; - } else if(bson->symbolString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_SYMBOL; - // Unpack symbol object - Local symbolObj = value->ToObject(); - - // Grab the actual string - Local str = symbolObj->Get(bson->_symbolValueString)->ToString(); - // Let's fetch the int value - int utf8_length = str->Utf8Length(); - - // If the Utf8 length is different from the string length then we - // have a UTF8 encoded string, otherwise write it as ascii - if(utf8_length != str->Length()) { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), utf8_length + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - str->WriteUtf8((serialized_object + index), utf8_length); - // Add the null termination - *(serialized_object + index + utf8_length) = '\0'; - // Adjust the index - index = index + utf8_length + 1; - } else { - // Write the integer to the char * - BSON::write_int32((serialized_object + index), str->Length() + 1); - // Adjust the index - index = index + 4; - // Write string to char in utf8 format - written = DecodeWrite((serialized_object + index), str->Length(), str, BINARY); - // Add the null termination - *(serialized_object + index + str->Length()) = '\0'; - // Adjust the index - index = index + str->Length() + 1; - } - } else if(bson->codeString->StrictEquals(constructorString)) { - // Unpack the object and encode - Local obj = value->ToObject(); - // Get the function - Local function = obj->Get(String::New("code"))->ToString(); - // Get the scope object - Local scope = obj->Get(String::New("scope"))->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - // Set the right type if we have a scope or not - if(propertyNameLength > 0) { - // Set basic data code object with scope object - *(serialized_object + originalIndex) = BSON_DATA_CODE_W_SCOPE; - - // Calculate the size of the whole object - uint32_t scopeSize = BSON::calculate_object_size(bson, scope, false); - // Decode the function length - ssize_t len = DecodeBytes(function, UTF8); - // Calculate total size - uint32_t size = 4 + len + 1 + 4 + scopeSize; - - // Write the total size - BSON::write_int32((serialized_object + index), size); - // Adjust the index - index = index + 4; - - // Write the function size - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, UTF8); - assert(written == len); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index with the length of the function - index = index + len + 1; - // Write the scope object - BSON::serialize(bson, (serialized_object + index), 0, Null(), scope, check_key, serializeFunctions); - // Adjust the index - index = index + scopeSize; - } else { - // Set basic data code object - *(serialized_object + originalIndex) = BSON_DATA_CODE; - // Decode the function - ssize_t len = DecodeBytes(function, BINARY); - // Write the size of the code string + 0 byte end of cString - BSON::write_int32((serialized_object + index), len + 1); - // Adjust the index - index = index + 4; - - // Write the data into the serialization stream - ssize_t written = DecodeWrite((serialized_object + index), len, function, BINARY); - assert(written == len); - // Write \0 for string - *(serialized_object + index + len) = 0x00; - // Adjust the index - index = index + len + 1; - } - } else if(bson->dbrefString->StrictEquals(constructorString)) { - // Unpack the dbref - Local dbref = value->ToObject(); - // Create an object containing the right namespace variables - Local obj = Object::New(); - - // Build the new object - obj->Set(bson->_dbRefRefString, dbref->Get(bson->_dbRefNamespaceString)); - obj->Set(bson->_dbRefIdRefString, dbref->Get(bson->_dbRefOidString)); - if(!dbref->Get(bson->_dbRefDbString)->IsNull() && !dbref->Get(bson->_dbRefDbString)->IsUndefined()) obj->Set(bson->_dbRefDbRefString, dbref->Get(bson->_dbRefDbString)); - - // Encode the variable - index = BSON::serialize(bson, serialized_object, originalIndex, name, obj, false, serializeFunctions); - } else if(bson->minKeyString->StrictEquals(constructorString)) { - // Save the string at the offset provided - *(serialized_object + originalIndex) = BSON_DATA_MIN_KEY; - } else if(bson->maxKeyString->StrictEquals(constructorString)) { - *(serialized_object + originalIndex) = BSON_DATA_MAX_KEY; - } - } else if(value->IsObject()) { - if(!name->IsNull()) { - // Save the string at the offset provided - *(serialized_object + index) = BSON_DATA_OBJECT; - // Adjust writing position for the first byte - index = index + 1; - // Convert name to char* - ssize_t len = DecodeBytes(name, UTF8); - ssize_t written = DecodeWrite((serialized_object + index), len, name, UTF8); - assert(written == len); - // Add null termiation for the string - *(serialized_object + index + len) = '\0'; - // Adjust the index - index = index + len + 1; - } - - // Unwrap the object - Local object = value->ToObject(); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local property_names = object->GetPropertyNames(); - #else - Local property_names = object->GetOwnPropertyNames(); - #endif - - // Calculate size of the total object - uint32_t object_size = BSON::calculate_object_size(bson, value, serializeFunctions); - // Write the size - BSON::write_int32((serialized_object + index), object_size); - // Adjust size - index = index + 4; - - // Process all the properties on the object - for(uint32_t i = 0; i < property_names->Length(); i++) { - // Fetch the property name - Local property_name = property_names->Get(i)->ToString(); - // Fetch the object for the property - Local property = object->Get(property_name); - // Write the next serialized object - // printf("========== !property->IsFunction() || (property->IsFunction() && serializeFunctions) = %d\n", !property->IsFunction() || (property->IsFunction() && serializeFunctions) == true ? 1 : 0); - if(!property->IsFunction() || (property->IsFunction() && serializeFunctions)) { - // Convert name to char* - ssize_t len = DecodeBytes(property_name, UTF8); - // char *data = new char[len]; - char *data = (char *)malloc(len + 1); - *(data + len) = '\0'; - ssize_t written = DecodeWrite(data, len, property_name, UTF8); - assert(written == len); - // Serialize the content - index = BSON::serialize(bson, serialized_object, index, property_name, property, check_key, serializeFunctions); - // Free up memory of data - free(data); - } - } - // Pad the last item - *(serialized_object + index) = '\0'; - index = index + 1; - - // Null out reminding fields if we have a toplevel object and nested levels - if(name->IsNull()) { - for(uint32_t i = 0; i < (object_size - index); i++) { - *(serialized_object + index + i) = '\0'; - } - } - } - - return index; -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) { - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Define pointer to data - char *data; - uint32_t length; - // Unpack the object - Local obj = args[2]->ToObject(); - - // Unpack the buffer object and get pointers to structures - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - uint32_t object_size = 0; - // Calculate the total size of the document in binary form to ensure we only allocate memory once - if(args.Length() == 5) { - object_size = BSON::calculate_object_size(bson, args[0], args[4]->BooleanValue()); - } else { - object_size = BSON::calculate_object_size(bson, args[0], false); - } - - // Unpack the index variable - Local indexObject = args[3]->ToUint32(); - uint32_t index = indexObject->Value(); - - // Allocate the memory needed for the serializtion - char *serialized_object = (char *)malloc(object_size * sizeof(char)); - - // Catch any errors - try { - // Check if we have a boolean value - bool check_key = false; - if(args.Length() >= 4 && args[1]->IsBoolean()) { - check_key = args[1]->BooleanValue(); - } - - bool serializeFunctions = false; - if(args.Length() == 5) { - serializeFunctions = args[4]->BooleanValue(); - } - - // Serialize the object - BSON::serialize(bson, serialized_object, 0, Null(), args[0], check_key, serializeFunctions); - } catch(char *err_msg) { - // Free up serialized object space - free(serialized_object); - V8::AdjustAmountOfExternalAllocatedMemory(-object_size); - // Throw exception with the string - Handle error = VException(err_msg); - // free error message - free(err_msg); - // Return error - return error; - } - - for(uint32_t i = 0; i < object_size; i++) { - *(data + index + i) = *(serialized_object + i); - } - - return scope.Close(Uint32::New(index + object_size - 1)); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) { - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - char *data; - uint32_t length; - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->ToUint32()->Value(); - uint32_t index = args[1]->ToUint32()->Value(); - uint32_t resultIndex = args[4]->ToUint32()->Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - data = buffer->data(); - length = buffer->length(); - #else - data = Buffer::Data(obj); - length = Buffer::Length(obj); - #endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - for(uint32_t i = 0; i < numberOfDocuments; i++) { - // Decode the size of the BSON data structure - uint32_t size = BSON::deserialize_int32(data, index); - - // Get result - Handle result = BSON::deserialize(bson, data, size, index, NULL); - - // Add result to array - documents->Set(i + resultIndex, result); - - // Adjust the index for next pass - index = index + size; - } - - // Return new index of parsing - return scope.Close(Uint32::New(index)); -} - -// Exporting function -extern "C" void init(Handle target) { - HandleScope scope; - BSON::Initialize(target); -} - -// NODE_MODULE(bson, BSON::Initialize); -// NODE_MODULE(l, Long::Initialize); diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h deleted file mode 100644 index dcf21d17af6..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/bson.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef BSON_H_ -#define BSON_H_ - -#include -#include -#include - -using namespace v8; -using namespace node; - -class BSON : public ObjectWrap { - public: - BSON() : ObjectWrap() {} - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Experimental - static Handle CalculateObjectSize2(const Arguments &args); - static Handle BSONSerialize2(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - - private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - static uint32_t serialize(BSON *bson, char *serialized_object, uint32_t index, Handle name, Handle value, bool check_key, bool serializeFunctions); - - static char* extract_string(char *data, uint32_t offset); - static const char* ToCString(const v8::String::Utf8Value& value); - static uint32_t calculate_object_size(BSON *bson, Handle object, bool serializeFunctions); - - static void write_int32(char *data, uint32_t value); - static void write_int64(char *data, int64_t value); - static void write_double(char *data, double value); - static uint16_t deserialize_int8(char *data, uint32_t offset); - static uint32_t deserialize_int32(char* data, uint32_t offset); - static char *check_key(Local key); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparision objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - // Decode JS function - static Handle decodeLong(BSON *bson, char *data, uint32_t index); - static Handle decodeTimestamp(BSON *bson, char *data, uint32_t index); - static Handle decodeOid(BSON *bson, char *oid); - static Handle decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data); - static Handle decodeCode(BSON *bson, char *code, Handle scope); - static Handle decodeDBref(BSON *bson, Local ref, Local oid, Local db); - - // Experimental - static uint32_t calculate_object_size2(Handle object); - static uint32_t serialize2(char *serialized_object, uint32_t index, Handle name, Handle value, uint32_t object_size, bool check_key); -}; - -#endif // BSON_H_ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js deleted file mode 100644 index 2c66dee6cca..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/index.js +++ /dev/null @@ -1,20 +0,0 @@ -var bson = require('./bson'); -exports.BSON = bson.BSON; -exports.Long = require('../../lib/mongodb/bson/long').Long; -exports.ObjectID = require('../../lib/mongodb/bson/objectid').ObjectID; -exports.DBRef = require('../../lib/mongodb/bson/db_ref').DBRef; -exports.Code = require('../../lib/mongodb/bson/code').Code; -exports.Timestamp = require('../../lib/mongodb/bson/timestamp').Timestamp; -exports.Binary = require('../../lib/mongodb/bson/binary').Binary; -exports.Double = require('../../lib/mongodb/bson/double').Double; -exports.MaxKey = require('../../lib/mongodb/bson/max_key').MaxKey; -exports.MinKey = require('../../lib/mongodb/bson/min_key').MinKey; -exports.Symbol = require('../../lib/mongodb/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js deleted file mode 100644 index 706f1df8cc8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_bson.js +++ /dev/null @@ -1,349 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp, - assert = require('assert'); - -if(process.env['npm_package_config_native'] != null) return; - -sys.puts("=== EXECUTING TEST_BSON ==="); - -// Should fail due to illegal key -assert.throws(function() { new ObjectID('foo'); }) -assert.throws(function() { new ObjectID('foo'); }) - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Simple serialization and deserialization of edge value -var doc = {doc:0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-0x1ffffffffffffe}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// -// Assert correct toJSON -// -var a = Long.fromNumber(10); -assert.equal(10, a); - -var a = Long.fromNumber(9223372036854775807); -assert.equal(9223372036854775807, a); - -// Simple serialization and deserialization test for a Single String value -var doc = {doc:'Serialize'}; -var simple_string_serialized = bsonC.serialize(doc, true, false); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Nested doc -var doc = {a:{b:{c:1}}}; -var simple_string_serialized = bsonC.serialize(doc, false, true); - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple integer serialization/deserialization test, including testing boundary conditions -var doc = {doc:-1}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2147483648}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization test for a Long value -var doc = {doc:Long.fromNumber(9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:Long.fromNumber(-9223372036854775807)}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a Float value -var doc = {doc:2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -var doc = {doc:-2222.3333}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a null value -var doc = {doc:null}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:true}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a date value -var date = new Date(); -var doc = {doc:date}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - -// Simple serialization and deserialization for a boolean value -var doc = {doc:/abcd/mi}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -var doc = {doc:/abcd/}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); -assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a objectId value -var doc = {doc:new ObjectID()}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - -assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - -// Simple serialization and deserialization for a Binary value -var binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - -var Binary = new Binary(); -var string = 'binstring' -for(var index = 0; index < string.length; index++) { Binary.put(string.charAt(index)); } - -var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); -assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Binary}, false, true)); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - -// Simple serialization and deserialization for a Code value -var code = new Code('this.a > i', {'i': 1}); -var Code = new Code('this.a > i', {'i': 1}); -var simple_string_serialized_2 = bsonJS.serialize({doc:Code}, false, true); -var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2); -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - -// Simple serialization and deserialization for an Object -var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for an Array -var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); -var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - -// Simple serialization and deserialization for a DBRef -var oid = new ObjectID() -var oid2 = new ObjectID.createFromHexString(oid.toHexString()) -var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -// Ensure we have the same values for the dbref -var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object_c = bsonC.deserialize(simple_string_serialized); - -assert.equal(object_js.doc.namespace, object_c.doc.namespace); -assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); -assert.equal(object_js.doc.db, object_c.doc.db); - -// Serialized document -var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal('Patty', object.name) -assert.equal(34, object.age) -assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - -// Serialize utf8 -var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.equal(doc.name, object.name) -assert.equal(doc.name1, object.name1) -assert.equal(doc.name2, object.name2) - -// Serialize object with array -var doc = {b:[1, 2, 3]}; -var simple_string_serialized = bsonC.serialize(doc, false, true); -var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - -var object = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc, object) - -// Test equality of an object ID -var object_id = new ObjectID(); -var object_id_2 = new ObjectID(); -assert.ok(object_id.equals(object_id)); -assert.ok(!(object_id.equals(object_id_2))) - -// Test same serialization for Object ID -var object_id = new ObjectID(); -var object_id2 = ObjectID.createFromHexString(object_id.toString()) -var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); -var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - -assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); -assert.deepEqual(simple_string_serialized, simple_string_serialized_2) -var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); -var object2 = bsonC.deserialize(simple_string_serialized); -assert.equal(object.doc.id, object2.doc.id) - -// JS Object -var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; -var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); - -// C++ Object -var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; -var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; -var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) -}; - -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); -} - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc._id.id, doc1._id.id) -assert.equal(doc._id.id, doc2._id.id) -assert.equal(doc1._id.id, doc2._id.id) - -var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } -}; - -var simple_string_serialized = bsonJS.serialize(doc, false, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.deepEqual(doc2, doc1) -assert.deepEqual(doc, doc2) -assert.deepEqual(doc, doc1) - -// Serialize function -var doc = { - _id: 'testid', - key1: function() {} -} - -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Deserialize the string -var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); -var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); -assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - -var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; -var simple_string_serialized = bsonJS.serialize(doc, false, true, true); -var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - -// Should serialize to the same value -assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) -var doc1 = bsonJS.deserialize(simple_string_serialized_2); -var doc2 = bsonC.deserialize(simple_string_serialized); -assert.deepEqual(doc1, doc2) - -// Hex Id -var hexId = new ObjectID().toString(); -var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; -var docJSBin = bsonJS.serialize(docJS, false, true, true); -var docCBin = bsonC.serialize(docC, false, true, true); -assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - -// // Complex document serialization -// doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} -// var docJSBin = bsonJS.serialize(docJS, false, true, true); -// var docCBin = bsonC.serialize(docC, false, true, true); -// -// - -// // Force garbage collect -// global.gc(); - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js deleted file mode 100644 index 2a6506c7650..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_full_bson.js +++ /dev/null @@ -1,218 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - assert = require('assert'), - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - -if(process.env['npm_package_config_native'] != null) return; - -sys.puts("=== EXECUTING TEST_FULL_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Should Correctly Deserialize object -var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} -var object = bsonC.deserialize(serialized_data); -assert.equal("a_1", object.name); -assert.equal(false, object.unique); -assert.equal(1, object.key.a); - -// Should Correctly Deserialize object with all types -var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; -var serialized_data = ''; -// Convert to chars -for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); -} - -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal("hello", object.string); -assert.deepEqual([1, 2, 3], object.array); -assert.equal(1, object.hash.a); -assert.equal(2, object.hash.b); -assert.ok(object.date != null); -assert.ok(object.oid != null); -assert.ok(object.binary != null); -assert.equal(42, object.int); -assert.equal(33.3333, object.float); -assert.ok(object.regexp != null); -assert.equal(true, object.boolean); -assert.ok(object.where != null); -assert.ok(object.dbref != null); -assert.ok(object['null'] == null); - -// Should Serialize and Deserialze String -var test_string = {hello: 'world'} -var serialized_data = bsonC.serialize(test_string) -assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_number = {doc: 5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize null value -var test_null = {doc:null} -var serialized_data = bsonC.serialize(test_null) -var object = bsonC.deserialize(serialized_data); -assert.deepEqual(test_null, object); - -// Should Correctly Serialize and Deserialize undefined value -var test_undefined = {doc:undefined} -var serialized_data = bsonC.serialize(test_undefined) -var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); -assert.equal(null, object.doc) - -// Should Correctly Serialize and Deserialize Number -var test_number = {doc: 5.5} -var serialized_data = bsonC.serialize(test_number) -assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Integer -var test_int = {doc: 42} -var serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -5600} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: 2147483647} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -test_int = {doc: -2147483648} -serialized_data = bsonC.serialize(test_int) -assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Object -var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Array with added on functions -var doc = {doc: [1, 2, 'a', 'b']} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize A Boolean -var doc = {doc: true} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize a Date -var date = new Date() -//(2009, 11, 12, 12, 00, 30) -date.setUTCDate(12) -date.setUTCFullYear(2009) -date.setUTCMonth(11 - 1) -date.setUTCHours(12) -date.setUTCMinutes(0) -date.setUTCSeconds(30) -var doc = {doc: date} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - -// // Should Correctly Serialize and Deserialize Oid -var doc = {doc: new ObjectID()} -var serialized_data = bsonC.serialize(doc) -assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - -// Should Correctly encode Empty Hash -var test_code = {} -var serialized_data = bsonC.serialize(test_code) -assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - -// Should Correctly Serialize and Deserialize Ordered Hash -var doc = {doc: {b:1, a:2, c:3, d:4}} -var serialized_data = bsonC.serialize(doc) -var decoded_hash = bsonC.deserialize(serialized_data).doc -var keys = [] -for(name in decoded_hash) keys.push(name) -assert.deepEqual(['b', 'a', 'c', 'd'], keys) - -// Should Correctly Serialize and Deserialize Regular Expression -// Serialize the regular expression -var doc = {doc: /foobar/mi} -var serialized_data = bsonC.serialize(doc) -var doc2 = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.toString(), doc2.doc.toString()) - -// Should Correctly Serialize and Deserialize a Binary object -var bin = new Binary() -var string = 'binstring' -for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) -} -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - -// Should Correctly Serialize and Deserialize a big Binary object -var data = fs.readFileSync("../../test/gridstore/test_gs_weird_bug.png", 'binary'); -var bin = new Binary() -bin.write(data) -var doc = {doc: bin} -var serialized_data = bsonC.serialize(doc) -var deserialized_data = bsonC.deserialize(serialized_data); -assert.equal(doc.doc.value(), deserialized_data.doc.value()) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js deleted file mode 100644 index f271caceb82..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/test/test_stackless_bson.js +++ /dev/null @@ -1,132 +0,0 @@ -var Buffer = require('buffer').Buffer, - BSON = require('../bson').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../../lib/mongodb/bson/bson').BSON, - BinaryParser = require('../../../lib/mongodb/bson/binary_parser').BinaryParser, - Long = require('../../../lib/mongodb/bson/long').Long, - ObjectID = require('../../../lib/mongodb/bson/bson').ObjectID, - Binary = require('../../../lib/mongodb/bson/bson').Binary, - Code = require('../../../lib/mongodb/bson/bson').Code, - DBRef = require('../../../lib/mongodb/bson/bson').DBRef, - Symbol = require('../../../lib/mongodb/bson/bson').Symbol, - Double = require('../../../lib/mongodb/bson/bson').Double, - MaxKey = require('../../../lib/mongodb/bson/bson').MaxKey, - MinKey = require('../../../lib/mongodb/bson/bson').MinKey, - Timestamp = require('../../../lib/mongodb/bson/bson').Timestamp; - assert = require('assert'); - -if(process.env['npm_package_config_native'] != null) return; - -console.log("=== EXECUTING TEST_STACKLESS_BSON ==="); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -// Number of iterations for the benchmark -var COUNT = 10000; -// var COUNT = 1; -// Sample simple doc -var doc = {key:"Hello world", key2:"šđžÄćŠÄŽČĆ", key3:'客家è¯', key4:'how are you doing dog!!'}; -// var doc = {}; -// for(var i = 0; i < 100; i++) { -// doc['string' + i] = "dumdyms fsdfdsfdsfdsfsdfdsfsdfsdfsdfsdfsdfsdfsdffsfsdfs"; -// } - -// // Calculate size -console.log(bsonC.calculateObjectSize2(doc)); -console.log(bsonJS.calculateObjectSize(doc)); -// assert.equal(bsonJS.calculateObjectSize(doc), bsonC.calculateObjectSize2(doc)); - -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// Benchmark calculateObjectSize -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- - -// Benchmark 1 JS BSON -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonJS.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 2 C++ BSON calculateObjectSize -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// Benchmark 3 C++ BSON calculateObjectSize2 -console.log(COUNT + "x (objectBSON = bsonC.calculateObjectSize2(object))") -start = new Date - -for (j=COUNT; --j>=0; ) { - var objectBSON = bsonC.calculateObjectSize2(doc); -} - -end = new Date -var opsprsecond = COUNT / ((end - start)/1000); -console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); - -// // Serialize the content -// var _serializedDoc1 = bsonJS.serialize(doc, true, false); -// var _serializedDoc2 = bsonC.serialize2(doc, true, false); -// console.dir(_serializedDoc1); -// console.dir(_serializedDoc2); -// assert.equal(_serializedDoc1.toString('base64'), _serializedDoc2.toString('base64')) -// -// -// // Benchmark 1 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// // var objectBSON = bsonC.serialize2(doc, true, false); -// var objectBSON = bsonJS.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 2 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize2(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); -// -// // Benchmark 3 -// console.log(COUNT + "x (objectBSON = bsonC.serialize(object))") -// start = new Date -// -// for (j=COUNT; --j>=0; ) { -// var objectBSON = bsonC.serialize(doc, true, false); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectbsonC.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectbsonC.length)/1024)); diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript b/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/external-libs/bson/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/index.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/index.js deleted file mode 100644 index 4f59e9d9262..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/mongodb'); diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/install.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/install.js deleted file mode 100644 index f9f2a5778eb..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/install.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn, - exec = require('child_process').exec; - -process.stdout.write("================================================================================\n"); -process.stdout.write("= =\n"); -process.stdout.write("= To install with C++ bson parser do =\n"); -process.stdout.write("= =\n"); -process.stdout.write("================================================================================\n"); - -// Check if we want to build the native code -var build_native = process.env['npm_package_config_native'] != null ? process.env['npm_package_config_native'] : 'false'; -build_native = build_native == 'true' ? true : false; -// If we are building the native bson extension ensure we use gmake if available -if(build_native) { - // Check if we need to use gmake - exec('which gmake', function(err, stdout, stderr) { - // Set up spawn command - var make = null; - // No gmake build using make - if(err != null) { - make = spawn('make', ['total']); - } else { - make = spawn('gmake', ['total']); - } - - // Execute spawn - make.stdout.on('data', function(data) { - process.stdout.write(data); - }) - - make.stderr.on('data', function(data) { - process.stdout.write(data); - }) - - make.on('exit', function(code) { - process.stdout.write('child process exited with code ' + code + "\n"); - }) - }); -} - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js deleted file mode 100644 index 6e9cd306cb4..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/admin.js +++ /dev/null @@ -1,339 +0,0 @@ -/*! - * Module dependencies. - */ -var Collection = require('./collection').Collection, - Cursor = require('./cursor').Cursor, - DbCommand = require('./commands/db_command').DbCommand, - utils = require('./utils'); - -/** - * Allows the user to access the admin functionality of MongoDB - * - * @class Represents the Admin methods of MongoDB. - * @param {Object} db Current db instance we wish to perform Admin operations on. - * @return {Function} Constructor for Admin type. - */ -function Admin(db) { - if(!(this instanceof Admin)) return new Admin(db); - this.db = db; -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.buildInfo = function(callback) { - this.serverInfo(callback); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured. - * @return {null} Returns no result - * @api private - */ -Admin.prototype.serverInfo = function(callback) { - this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Retrieve this db's server status. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.serverStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) { - callback(null, doc.documents[0]); - } else { - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - } - }); -}; - -/** - * Retrieve the current profiling Level for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingLevel = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({profile:-1}, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) { - var was = doc.was; - if(was == 0) return callback(null, "off"); - if(was == 1) return callback(null, "slow_only"); - if(was == 2) return callback(null, "all"); - return callback(new Error("Error: illegal profiling level value " + was), null); - } else { - err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - } - }); -}; - -/** - * Ping the MongoDB server and retrieve results - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.ping = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - - this.db.executeDbAdminCommand({ping: 1}, callback); -} - -/** - * Authenticate against MongoDB - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.authenticate = function(username, password, callback) { - this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Logout current authenticated user - * - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.logout = function(callback) { - this.db.logout({authdb: 'admin'}, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Add a user to the MongoDB server, if the user exists it will - * overwrite the current password - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {String} password The password for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.addUser = function(username, password, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - options.dbName = 'admin'; - // Add user - this.db.addUser(username, password, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Remove a user from the MongoDB server - * - * Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username The user name for the authentication. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options.dbName = 'admin'; - - this.db.removeUser(username, options, function(err, doc) { - return callback(err, doc); - }) -} - -/** - * Set the current profiling level of MongoDB - * - * @param {String} level The new profiling level (off, slow_only, all) - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.setProfilingLevel = function(level, callback) { - var self = this; - var command = {}; - var profile = 0; - - if(level == "off") { - profile = 0; - } else if(level == "slow_only") { - profile = 1; - } else if(level == "all") { - profile = 2; - } else { - return callback(new Error("Error: illegal profiling level value " + level)); - } - - // Set up the profile number - command['profile'] = profile; - - this.db.executeDbAdminCommand(command, function(err, doc) { - doc = doc.documents[0]; - - if(err == null && doc.ok === 1) - return callback(null, level); - return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null); - }); -}; - -/** - * Retrive the current profiling information for MongoDB - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.profilingInfo = function(callback) { - try { - new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) { - return callback(err, items); - }); - } catch (err) { - return callback(err, null); - } -}; - -/** - * Execute a db command against the Admin database - * - * @param {Object} command A command object `{ping:1}`. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.command = function(command, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Execute a command - this.db.executeDbAdminCommand(command, options, function(err, doc) { - // Ensure change before event loop executes - return callback != null ? callback(err, doc) : null; - }); -} - -/** - * Validate an existing collection - * - * @param {String} collectionName The name of the collection to validate. - * @param {Object} [options] Optional parameters to the command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.validateCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - var self = this; - var command = {validate: collectionName}; - var keys = Object.keys(options); - - // Decorate command with extra options - for(var i = 0; i < keys.length; i++) { - if(options.hasOwnProperty(keys[i])) { - command[keys[i]] = options[keys[i]]; - } - } - - this.db.executeDbCommand(command, function(err, doc) { - if(err != null) return callback(err, null); - doc = doc.documents[0]; - - if(doc.ok === 0) - return callback(new Error("Error with validate command"), null); - if(doc.result != null && doc.result.constructor != String) - return callback(new Error("Error with validation data"), null); - if(doc.result != null && doc.result.match(/exception|corrupt/) != null) - return callback(new Error("Error: invalid collection " + collectionName), null); - if(doc.valid != null && !doc.valid) - return callback(new Error("Error: invalid collection " + collectionName), null); - - return callback(null, doc); - }); -}; - -/** - * List the available databases - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured. - * @return {null} Returns no result - * @api public - */ -Admin.prototype.listDatabases = function(callback) { - // Execute the listAllDatabases command - this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) { - if(err != null) return callback(err, null); - return callback(null, doc.documents[0]); - }); -} - -/** - * Get ReplicaSet status - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured. - * @return {null} - * @api public - */ -Admin.prototype.replSetGetStatus = function(callback) { - var self = this; - - this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) { - if(err == null && doc.documents[0].ok === 1) - return callback(null, doc.documents[0]); - if(err) return callback(err, false); - return callback(utils.toError(doc.documents[0]), false); - }); -}; - -/** - * @ignore - */ -exports.Admin = Admin; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js deleted file mode 100644 index 9c80d809291..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/collection.js +++ /dev/null @@ -1,1762 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var InsertCommand = require('./commands/insert_command').InsertCommand - , QueryCommand = require('./commands/query_command').QueryCommand - , DeleteCommand = require('./commands/delete_command').DeleteCommand - , UpdateCommand = require('./commands/update_command').UpdateCommand - , DbCommand = require('./commands/db_command').DbCommand - , ObjectID = require('bson').ObjectID - , Code = require('bson').Code - , Cursor = require('./cursor').Cursor - , utils = require('./utils'); - -/** - * Precompiled regexes - * @ignore -**/ -const eErrorMessages = /No matching object found/; - -/** - * toString helper. - * @ignore - */ -var toString = Object.prototype.toString; - -/** - * Create a new Collection instance (INTERNAL TYPE) - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **slaveOk** {Boolean, default:false}, Allow reads from secondaries. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - * @class Represents a Collection - * @param {Object} db db instance. - * @param {String} collectionName collection name. - * @param {Object} [pkFactory] alternative primary key factory. - * @param {Object} [options] additional options for the collection. - * @return {Object} a collection instance. - */ -function Collection (db, collectionName, pkFactory, options) { - if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options); - - checkCollectionName(collectionName); - - this.db = db; - this.collectionName = collectionName; - this.internalHint = null; - this.opts = options != null && ('object' === typeof options) ? options : {}; - this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk; - this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions; - this.raw = options == null || options.raw == null ? db.raw : options.raw; - - this.readPreference = options == null || options.readPreference == null ? db.serverConfig.readPreference : options.readPreference; - this.readPreference = this.readPreference == null ? 'primary' : this.readPreference; - - this.pkFactory = pkFactory == null - ? ObjectID - : pkFactory; - - var self = this; -} - -/** - * Inserts a single document or a an array of documents into MongoDB. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Array|Object} docs - * @param {Object} [options] optional options for insert command - * @param {Function} [callback] optional callback for the function, must be provided when using a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.insert = function insert (docs, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - insertAll(self, Array.isArray(docs) ? docs : [docs], options, callback); - return this; -}; - -/** - * @ignore - */ -var checkCollectionName = function checkCollectionName (collectionName) { - if ('string' !== typeof collectionName) { - throw Error("collection name must be a String"); - } - - if (!collectionName || collectionName.indexOf('..') != -1) { - throw Error("collection names cannot be empty"); - } - - if (collectionName.indexOf('$') != -1 && - collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) { - throw Error("collection names must not contain '$'"); - } - - if (collectionName.match(/^\.|\.$/) != null) { - throw Error("collection names must not start or end with '.'"); - } -}; - -/** - * Removes documents specified by `selector` from the db. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **single** {Boolean, default:false}, removes the first document found. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [selector] optional select, no selector is equivalent to removing all documents. - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a remove with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.remove = function remove(selector, options, callback) { - if ('function' === typeof selector) { - callback = selector; - selector = options = {}; - } else if ('function' === typeof options) { - callback = options; - options = {}; - } - - // Ensure options - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Ensure we have at least an empty selector - selector = selector == null ? {} : selector; - // Set up flags for the command, if we have a single document remove - var flags = 0 | (options.single ? 1 : 0); - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Create a delete command - var deleteCommand = new DeleteCommand( - this.db - , dbName + "." + this.collectionName - , selector - , flags); - - var self = this; - var errorOptions = _getWriteConcern(self, options, callback); - // Execute the command, do not add a callback as it's async - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = true; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeRemoveCommand(deleteCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, error[0].n); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - var result = this.db._executeRemoveCommand(deleteCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * Renames the collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} newName the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback the callback accepting the result - * @return {null} - * @api public - */ -Collection.prototype.rename = function rename (newName, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - // Ensure the new name is valid - checkCollectionName(newName); - // Execute the command, return the new renamed collection if successful - self.db._executeQueryCommand(DbCommand.createRenameCollectionCommand(self.db, self.collectionName, newName, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - if(callback != null) { - // Set current object to point to the new name - self.collectionName = newName; - // Return the current collection - callback(null, self); - } - } else if(result.documents[0].errmsg != null) { - if(null != callback) { - if (null == err) { - err = utils.toError(result.documents[0]); - } - callback(err, null); - } - } - }); -}; - -/** - * @ignore - */ -var insertAll = function insertAll (self, docs, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Insert options (flags for insert) - var insertFlags = {}; - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['keepGoing'] != null) { - insertFlags['keepGoing'] = options['keepGoing']; - } - - // If we have a mongodb version >= 1.9.1 support keepGoing attribute - if(options['continueOnError'] != null) { - insertFlags['continueOnError'] = options['continueOnError']; - } - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = self.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - insertFlags['serializeFunctions'] = options['serializeFunctions']; - } else { - insertFlags['serializeFunctions'] = self.serializeFunctions; - } - - // Pass in options - var insertCommand = new InsertCommand( - self.db - , dbName + "." + self.collectionName, true, insertFlags); - - // Add the documents and decorate them with id's if they have none - for(var index = 0, len = docs.length; index < len; ++index) { - var doc = docs[index]; - - // Add id to each document if it's not already defined - if (!(Buffer.isBuffer(doc)) && doc['_id'] == null && self.db.forceServerObjectId != true) { - doc['_id'] = self.pkFactory.createPk(); - } - - insertCommand.add(doc); - } - - // Collect errorOptions - var errorOptions = _getWriteConcern(self, options, callback); - // Default command options - var commandOptions = {}; - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - self.db._executeInsertCommand(insertCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if (err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - callback(null, docs); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute the call without a write concern - var result = self.db._executeInsertCommand(insertCommand, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, docs); - } -}; - -/** - * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic - * operators and update instead for more efficient operations. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} [doc] the document to save - * @param {Object} [options] additional options during remove. - * @param {Function} [callback] must be provided if you performing a safe save - * @return {null} - * @api public - */ -Collection.prototype.save = function save(doc, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - // Extract the id, if we have one we need to do a update command - var id = doc['_id']; - var commandOptions = _getWriteConcern(this, options, callback); - - if(id) { - commandOptions.upsert = true; - this.update({ _id: id }, doc, commandOptions, callback); - } else { - this.insert(doc, commandOptions, callback && function (err, docs) { - if (err) return callback(err, null); - - if (Array.isArray(docs)) { - callback(err, docs[0]); - } else { - callback(err, docs); - } - }); - } -}; - -/** - * Updates documents. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **multi** {Boolean, default:false}, update all documents matching the selector. - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} selector the query to select the document/documents to be updated - * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted. - * @param {Object} [options] additional options during update. - * @param {Function} [callback] must be provided if you performing an update with a writeconcern - * @return {null} - * @api public - */ -Collection.prototype.update = function update(selector, document, options, callback) { - if('function' === typeof options) callback = options, options = null; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // DbName - var dbName = options['dbName']; - // If no dbname defined use the db one - if(dbName == null) { - dbName = this.db.databaseName; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - var updateCommand = new UpdateCommand( - this.db - , dbName + "." + this.collectionName - , selector - , document - , options); - - var self = this; - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - // If safe is defined check for error message - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - var commandOptions = {read:false}; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection) - this.db._executeUpdateCommand(updateCommand, commandOptions, function (err, error) { - error = error && error.documents; - if(!callback) return; - - if(err) { - callback(err); - } else if(error[0].err || error[0].errmsg) { - callback(utils.toError(error[0])); - } else { - // Perform the callback - callback(null, error[0].n, error[0]); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute update - var result = this.db._executeUpdateCommand(updateCommand); - // If no callback just return - if (!callback) return; - // If error return error - if (result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(); - } -}; - -/** - * The distinct command returns returns a list of distinct values for the given key across a collection. - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} key key to run distinct against. - * @param {Object} [query] option query to narrow the returned objects. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from distinct or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.distinct = function distinct(key, query, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - - var mapCommandHash = { - 'distinct': this.collectionName - , 'query': query - , 'key': key - }; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // Create the command - var cmd = DbCommand.createDbSlaveOkCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err) - return callback(err); - if(result.documents[0].ok != 1) - return callback(new Error(result.documents[0].errmsg)); - callback(null, result.documents[0].values); - }); -}; - -/** - * Count number of matching documents in the db to a query. - * - * Options - * - **skip** {Number}, The number of documents to skip for the count. - * - **limit** {Number}, The limit of documents to count. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object} [query] query to filter by before performing count. - * @param {Object} [options] additional options during count. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the count method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.count = function count (query, options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - query = args.length ? args.shift() : {}; - options = args.length ? args.shift() : {}; - var skip = options.skip; - var limit = options.limit; - - // Final query - var final_query = { - 'count': this.collectionName - , 'query': query - , 'fields': null - }; - - // Add limit and skip if defined - if(typeof skip == 'number') final_query.skip = skip; - if(typeof limit == 'number') final_query.limit = limit; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Set up query options - var queryOptions = QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - if (this.slaveOk || this.db.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - var queryCommand = new QueryCommand( - this.db - , this.db.databaseName + ".$cmd" - , queryOptions - , 0 - , -1 - , final_query - , null - ); - - var self = this; - this.db._executeQueryCommand(queryCommand, {read:readPreference}, function (err, result) { - result = result && result.documents; - if(!callback) return; - - if(err) return callback(err); - if (result[0].ok != 1 || result[0].errmsg) { - return callback(utils.toError(result[0])); - } - callback(null, result[0].n); - }); -}; - - -/** - * Drop the collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the drop method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.drop = function drop(callback) { - this.db.dropCollection(this.collectionName, callback); -}; - -/** - * Find and update a document. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **remove** {Boolean, default:false}, set to true to remove the object before returning. - * - **upsert** {Boolean, default:false}, perform an upsert operation. - * - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} doc - the fields/vals to be updated - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndModify method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndModify = function findAndModify (query, sort, doc, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - doc = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - var self = this; - - var queryObject = { - 'findandmodify': this.collectionName - , 'query': query - , 'sort': utils.formattedOrderClause(sort) - }; - - queryObject.new = options.new ? 1 : 0; - queryObject.remove = options.remove ? 1 : 0; - queryObject.upsert = options.upsert ? 1 : 0; - - if (options.fields) { - queryObject.fields = options.fields; - } - - if (doc && !options.remove) { - queryObject.update = doc; - } - - // Either use override on the function, or go back to default on either the collection - // level or db - if(options['serializeFunctions'] != null) { - options['serializeFunctions'] = options['serializeFunctions']; - } else { - options['serializeFunctions'] = this.serializeFunctions; - } - - // Unpack the error options if any - var errorOptions = _getWriteConcern(this, options, callback); - - // If we have j, w or something else do the getLast Error path - if(errorOptions != null && typeof errorOptions == 'object') { - // Commands to send - var commands = []; - // Add the find and modify command - commands.push(DbCommand.createDbCommand(this.db, queryObject, options)); - // If we have safe defined we need to return both call results - var chainedCommands = errorOptions != null ? true : false; - // Add error command if we have one - if(chainedCommands) { - commands.push(DbCommand.createGetLastErrorCommand(errorOptions, this.db)); - } - - // Fire commands and - this.db._executeQueryCommand(commands, {read:false}, function(err, result) { - if(err != null) return callback(err); - result = result && result.documents; - - if(result[0].err != null) { - return callback(utils.toError(result[0]), null); - } - - // Workaround due to 1.8.X returning an error on no matching object - // while 2.0.X does not not, making 2.0.X behaviour standard - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - return callback(null, result[0].value, result[0]); - }); - } else { - // Only run command and rely on getLastError command - var command = DbCommand.createDbCommand(this.db, queryObject, options) - // Execute command - this.db._executeQueryCommand(command, {read:false}, function(err, result) { - if(err != null) return callback(err); - - result = result && result.documents; - - if(result[0].errmsg != null && !result[0].errmsg.match(eErrorMessages)) { - return callback(utils.toError(result[0]), null, result[0]); - } - - // If we have an error return it - if(result[0].lastErrorObject && result[0].lastErrorObject.err != null) { - return callback(utils.toError(result[0].lastErrorObject), null); - } - - return callback(null, result[0].value, result[0]); - }); - } -} - -/** - * Find and remove a document - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} query query object to locate the object to modify - * @param {Array} sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndRemove method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.findAndRemove = function(query, sort, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - sort = args.length ? args.shift() : []; - options = args.length ? args.shift() : {}; - // Add the remove option - options['remove'] = true; - // Execute the callback - this.findAndModify(query, sort, null, options, callback); -} - -var testForFields = { - limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1 - , numberOfRetries: 1, awaitdata: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1 - , comment: 1, raw: 1, readPreference: 1, numberOfRetries: 1, partial: 1, read: 1, dbName: 1 -}; - -/** - * Creates a cursor for a query that can be used to iterate over results from MongoDB - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **tailableRetryInterval** {Number, default:100}, specify the miliseconds between getMores on tailable cursor. - * - **numberOfRetries** {Number, default:5}, specify the number of times to retry the tailable cursor. - * - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor. - * - **exhaust** {Boolean, default:false} have the server send all the documents at once as getMore packets, not recommended. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **numberOfRetries** {Number, default:5}, if using awaidata specifies the number of times to retry on timeout. - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the find method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.find = function find () { - var options - , args = Array.prototype.slice.call(arguments, 0) - , has_callback = typeof args[args.length - 1] === 'function' - , has_weird_callback = typeof args[0] === 'function' - , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null) - , len = args.length - , selector = len >= 1 ? args[0] : {} - , fields = len >= 2 ? args[1] : undefined; - - if(len === 1 && has_weird_callback) { - // backwards compat for callback?, options case - selector = {}; - options = args[0]; - } - - if(len === 2 && !Array.isArray(fields)) { - var fieldKeys = Object.getOwnPropertyNames(fields); - var is_option = false; - - for(var i = 0; i < fieldKeys.length; i++) { - if(testForFields[fieldKeys[i]] != null) { - is_option = true; - break; - } - } - - if(is_option) { - options = fields; - fields = undefined; - } else { - options = {}; - } - } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) { - var newFields = {}; - // Rewrite the array - for(var i = 0; i < fields.length; i++) { - newFields[fields[i]] = 1; - } - // Set the fields - fields = newFields; - } - - if(3 === len) { - options = args[2]; - } - - // Ensure selector is not null - selector = selector == null ? {} : selector; - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Validate correctness of the field selector - var object = fields; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Check special case where we are using an objectId - if(selector instanceof ObjectID) { - selector = {_id:selector}; - } - - // If it's a serialized fields field we need to just let it through - // user be warned it better be good - if(options && options.fields && !(Buffer.isBuffer(options.fields))) { - fields = {}; - - if(Array.isArray(options.fields)) { - if(!options.fields.length) { - fields['_id'] = 1; - } else { - for (var i = 0, l = options.fields.length; i < l; i++) { - fields[options.fields[i]] = 1; - } - } - } else { - fields = options.fields; - } - } - - if (!options) options = {}; - options.skip = len > 3 ? args[2] : options.skip ? options.skip : 0; - options.limit = len > 3 ? args[3] : options.limit ? options.limit : 0; - options.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw; - options.hint = options.hint != null ? normalizeHintField(options.hint) : this.internalHint; - options.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout; - // If we have overridden slaveOk otherwise use the default db setting - options.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk; - - // Set option - var o = options; - // Support read/readPreference - if(o["read"] != null) o["readPreference"] = o["read"]; - // Set the read preference - o.read = o["readPreference"] ? o.readPreference : this.readPreference; - // Adjust slave ok if read preference is secondary or secondary only - if(o.read == "secondary" || o.read == "secondaryOnly") options.slaveOk = true; - - // callback for backward compatibility - if(callback) { - // TODO refactor Cursor args - callback(null, new Cursor(this.db, this, selector, fields, o)); - } else { - return new Cursor(this.db, this, selector, fields, o); - } -}; - -/** - * Normalizes a `hint` argument. - * - * @param {String|Object|Array} hint - * @return {Object} - * @api private - */ -var normalizeHintField = function normalizeHintField(hint) { - var finalHint = null; - - if (null != hint) { - switch (hint.constructor) { - case String: - finalHint = {}; - finalHint[hint] = 1; - break; - case Object: - finalHint = {}; - for (var name in hint) { - finalHint[name] = hint[name]; - } - break; - case Array: - finalHint = {}; - hint.forEach(function(param) { - finalHint[param] = 1; - }); - break; - } - } - - return finalHint; -}; - -/** - * Finds a single document based on the query - * - * Various argument possibilities - * - callback? - * - selector, callback?, - * - selector, fields, callback? - * - selector, options, callback? - * - selector, fields, options, callback? - * - selector, fields, skip, limit, callback? - * - selector, fields, skip, limit, timeout, callback? - * - * Options - * - **limit** {Number, default:0}, sets the limit of documents returned in the query. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1} - * - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination). - * - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} - * - **explain** {Boolean, default:false}, explain the query instead of returning the data. - * - **snapshot** {Boolean, default:false}, snapshot query. - * - **timeout** {Boolean, default:false}, specify if the cursor can timeout. - * - **tailable** {Boolean, default:false}, specify if the cursor is tailable. - * - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results. - * - **returnKey** {Boolean, default:false}, only return the index key. - * - **maxScan** {Number}, Limit the number of items to scan. - * - **min** {Number}, Set index bounds. - * - **max** {Number}, Set index bounds. - * - **showDiskLoc** {Boolean, default:false}, Show disk location of results. - * - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler. - * - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents. - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system - * - * @param {Object} query query object to locate the object to modify - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findOne method or null if an error occured. - * @return {Cursor} returns a cursor to the query - * @api public - */ -Collection.prototype.findOne = function findOne () { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - var callback = args.pop(); - var cursor = this.find.apply(this, args).limit(-1).batchSize(1); - // Return the item - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the createIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.createIndex = function createIndex (fieldOrSpec, options, callback) { - // Clean up call - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Collect errorOptions - var errorOptions = _getWriteConcern(this, options, callback); - // Execute create index - this.db.createIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the ensureIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.ensureIndex = function ensureIndex (fieldOrSpec, options, callback) { - // Clean up call - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Execute create index - this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexInformation method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexInformation = function indexInformation (options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // Call the index information - this.db.indexInformation(this.collectionName, options, callback); -}; - -/** - * Drops an index from this collection. - * - * @param {String} name - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndex method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropIndex = function dropIndex (name, callback) { - this.db.dropIndex(this.collectionName, name, callback); -}; - -/** - * Drops all indexes from this collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropAllIndexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.dropAllIndexes = function dropIndexes (callback) { - this.db.dropIndex(this.collectionName, '*', function (err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Drops all indexes from this collection. - * - * @deprecated - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndexes method or null if an error occured. - * @return {null} - * @api private - */ -Collection.prototype.dropIndexes = Collection.prototype.dropAllIndexes; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the reIndex method or null if an error occured. - * @return {null} - * @api public -**/ -Collection.prototype.reIndex = function(callback) { - this.db.reIndex(this.collectionName, callback); -} - -/** - * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection. - * - * Options - * - **out** {Object, default:*{inline:1}*}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}* - * - **query** {Object}, query filter object. - * - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces. - * - **limit** {Number}, number of objects to return from collection. - * - **keeptemp** {Boolean, default:false}, keep temporary data. - * - **finalize** {Function | String}, finalize function. - * - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize. - * - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X. - * - **verbose** {Boolean, default:false}, provide statistics on job execution time. - * - **readPreference** {String, only for inline results}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Function|String} map the mapping function. - * @param {Function|String} reduce the reduce function. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the mapReduce method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.mapReduce = function mapReduce (map, reduce, options, callback) { - if ('function' === typeof options) callback = options, options = {}; - // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers) - if(null == options.out) { - throw new Error("the out option parameter must be defined, see mongodb docs for possible values"); - } - - if ('function' === typeof map) { - map = map.toString(); - } - - if ('function' === typeof reduce) { - reduce = reduce.toString(); - } - - if ('function' === typeof options.finalize) { - options.finalize = options.finalize.toString(); - } - - var mapCommandHash = { - mapreduce: this.collectionName - , map: map - , reduce: reduce - }; - - // Add any other options passed in - for (var name in options) { - if ('scope' == name) { - mapCommandHash[name] = processScope(options[name]); - } else { - mapCommandHash[name] = options[name]; - } - } - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - // If we have a read preference and inline is not set as output fail hard - if(readPreference != false && options['out'] != 'inline') { - throw new Error("a readPreference can only be provided when performing an inline mapReduce"); - } - - // self - var self = this; - var cmd = DbCommand.createDbCommand(this.db, mapCommandHash); - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if (err) { - return callback(err); - } - - // - if (1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) { - return callback(utils.toError(result.documents[0])); - } - - // Create statistics value - var stats = {}; - if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis; - if(result.documents[0].counts) stats['counts'] = result.documents[0].counts; - if(result.documents[0].timing) stats['timing'] = result.documents[0].timing; - - // invoked with inline? - if(result.documents[0].results) { - return callback(null, result.documents[0].results, stats); - } - - // The returned collection - var collection = null; - - // If we have an object it's a different db - if(result.documents[0].result != null && typeof result.documents[0].result == 'object') { - var doc = result.documents[0].result; - collection = self.db.db(doc.db).collection(doc.collection); - } else { - // Create a collection object that wraps the result collection - collection = self.db.collection(result.documents[0].result) - } - - // If we wish for no verbosity - if(options['verbose'] == null || !options['verbose']) { - return callback(err, collection); - } - - // Return stats as third set of values - callback(err, collection, stats); - }); -}; - -/** - * Functions that are passed as scope args must - * be converted to Code instances. - * @ignore - */ -function processScope (scope) { - if (!utils.isObject(scope)) { - return scope; - } - - var keys = Object.keys(scope); - var i = keys.length; - var key; - - while (i--) { - key = keys[i]; - if ('function' == typeof scope[key]) { - scope[key] = new Code(String(scope[key])); - } - } - - return scope; -} - -/** - * Group function helper - * @ignore - */ -var groupFunction = function () { - var c = db[ns].find(condition); - var map = new Map(); - var reduce_function = reduce; - - while (c.hasNext()) { - var obj = c.next(); - var key = {}; - - for (var i = 0, len = keys.length; i < len; ++i) { - var k = keys[i]; - key[k] = obj[k]; - } - - var aggObj = map.get(key); - - if (aggObj == null) { - var newObj = Object.extend({}, key); - aggObj = Object.extend(newObj, initial); - map.put(key, aggObj); - } - - reduce_function(obj, aggObj); - } - - return { "result": map.values() }; -}.toString(); - -/** - * Run a group command across a collection - * - * Options - * - **readPreference** {String}, the preferred read preference (Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by. - * @param {Object} condition an optional condition that must be true for a row to be considered. - * @param {Object} initial initial value of the aggregation counter object. - * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated - * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned. - * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the group method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.group = function group(keys, condition, initial, reduce, finalize, command, options, callback) { - var args = Array.prototype.slice.call(arguments, 3); - callback = args.pop(); - // Fetch all commands - reduce = args.length ? args.shift() : null; - finalize = args.length ? args.shift() : null; - command = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Make sure we are backward compatible - if(!(typeof finalize == 'function')) { - command = finalize; - finalize = null; - } - - if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) { - keys = Object.keys(keys); - } - - if(typeof reduce === 'function') { - reduce = reduce.toString(); - } - - if(typeof finalize === 'function') { - finalize = finalize.toString(); - } - - // Set up the command as default - command = command == null ? true : command; - - // Execute using the command - if(command) { - var reduceFunction = reduce instanceof Code - ? reduce - : new Code(reduce); - - var selector = { - group: { - 'ns': this.collectionName - , '$reduce': reduceFunction - , 'cond': condition - , 'initial': initial - , 'out': "inline" - } - }; - - // if finalize is defined - if(finalize != null) selector.group['finalize'] = finalize; - // Set up group selector - if ('function' === typeof keys || keys instanceof Code) { - selector.group.$keyf = keys instanceof Code - ? keys - : new Code(keys); - } else { - var hash = {}; - keys.forEach(function (key) { - hash[key] = 1; - }); - selector.group.key = hash; - } - - var cmd = DbCommand.createDbSlaveOkCommand(this.db, selector); - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - this.db._executeQueryCommand(cmd, {read:readPreference}, function (err, result) { - if(err != null) return callback(err); - - var document = result.documents[0]; - if (null == document.retval) { - return callback(new Error("group command failed: " + document.errmsg)); - } - - callback(null, document.retval); - }); - - } else { - // Create execution scope - var scope = reduce != null && reduce instanceof Code - ? reduce.scope - : {}; - - scope.ns = this.collectionName; - scope.keys = keys; - scope.condition = condition; - scope.initial = initial; - - // Pass in the function text to execute within mongodb. - var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';'); - - this.db.eval(new Code(groupfn, scope), function (err, results) { - if (err) return callback(err, null); - callback(null, results.result || results); - }); - } -}; - -/** - * Returns the options of the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the options method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.options = function options(callback) { - this.db.collectionsInfo(this.collectionName, function (err, cursor) { - if (err) return callback(err); - cursor.nextObject(function (err, document) { - callback(err, document && document.options || null); - }); - }); -}; - -/** - * Returns if the collection is a capped collection - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the isCapped method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.isCapped = function isCapped(callback) { - this.options(function(err, document) { - if(err != null) { - callback(err); - } else { - callback(null, document && document.capped); - } - }); -}; - -/** - * Checks if one or more indexes exist on the collection - * - * @param {String|Array} indexNames check if one or more indexes exist on the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexExists method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexExists = function indexExists(indexes, callback) { - this.indexInformation(function(err, indexInformation) { - // If we have an error return - if(err != null) return callback(err, null); - // Let's check for the index names - if(Array.isArray(indexes)) { - for(var i = 0; i < indexes.length; i++) { - if(indexInformation[indexes[i]] == null) { - return callback(null, false); - } - } - - // All keys found return true - return callback(null, true); - } else { - return callback(null, indexInformation[indexes] != null); - } - }); -} - -/** - * Execute the geoNear command to search for items in the collection - * - * Options - * - **num** {Number}, max number of results to return. - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions. - * - **query** {Object}, filter the results by a query. - * - **spherical** {Boolean, default:false}, perform query using a spherical model. - * - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X. - * - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoNear method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoNear = function geoNear(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoNear:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['num'] != null) commandObject['num'] = options['num']; - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['distanceMultiplier'] != null) commandObject['distanceMultiplier'] = options['distanceMultiplier']; - if(options['query'] != null) commandObject['query'] = options['query']; - if(options['spherical'] != null) commandObject['spherical'] = options['spherical']; - if(options['uniqueDocs'] != null) commandObject['uniqueDocs'] = options['uniqueDocs']; - if(options['includeLocs'] != null) commandObject['includeLocs'] = options['includeLocs']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Execute a geo search using a geo haystack index on a collection. - * - * Options - * - **maxDistance** {Number}, include results up to maxDistance from the point. - * - **search** {Object}, filter the results by a query. - * - **limit** {Number}, max number of results to return. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order. - * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order. - * @param {Objects} [options] options for the map reduce job. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoHaystackSearch method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - geoSearch:this.collectionName, - near: [x, y] - } - - // Decorate object if any with known properties - if(options['maxDistance'] != null) commandObject['maxDistance'] = options['maxDistance']; - if(options['query'] != null) commandObject['search'] = options['query']; - if(options['search'] != null) commandObject['search'] = options['search']; - if(options['limit'] != null) commandObject['limit'] = options['limit']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * Retrieve all the indexes on the collection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexes method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.indexes = function indexes(callback) { - // Return all the index information - this.db.indexInformation(this.collectionName, {full:true}, callback); -} - -/** - * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.1 - * - * Options - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Array} array containing all the aggregation framework commands for the execution. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the aggregate method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.aggregate = function(pipeline, options, callback) { - // * - **explain** {Boolean}, return the query plan for the aggregation pipeline instead of the results. 2.3, 2.4 - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - var self = this; - - // If we have any of the supported options in the options object - var opts = args[args.length - 1]; - options = opts.readPreference || opts.explain ? args.pop() : {} - - // Convert operations to an array - if(!Array.isArray(args[0])) { - pipeline = []; - // Push all the operations to the pipeline - for(var i = 0; i < args.length; i++) pipeline.push(args[i]); - } - - // Build the command - var command = { aggregate : this.collectionName, pipeline : pipeline}; - // Add all options - var keys = Object.keys(options); - // Add all options - for(var i = 0; i < keys.length; i++) { - command[keys[i]] = options[keys[i]]; - } - - // Execute the command - this.db.command(command, options, function(err, result) { - if(err) { - callback(err); - } else if(result['err'] || result['errmsg']) { - callback(utils.toError(result)); - } else if(typeof result == 'object' && result['serverPipeline']) { - callback(null, result); - } else { - callback(null, result.result); - } - }); -} - -/** - * Get all the collection statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the stats method or null if an error occured. - * @return {null} - * @api public - */ -Collection.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - collStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.db.command(commandObject, options, callback); -} - -/** - * @ignore - */ -Object.defineProperty(Collection.prototype, "hint", { - enumerable: true - , get: function () { - return this.internalHint; - } - , set: function (v) { - this.internalHint = normalizeHintField(v); - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(self.opts.w != null || typeof self.opts.j == 'boolean' || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.opts); - } else if(typeof self.opts.safe == "boolean") { - finalOptions = {w: (self.opts.safe ? 1 : 0)}; - } else if(self.db.safe.w != null || typeof self.db.safe.j == 'boolean' || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.safe); - } else if(self.db.options.w != null || typeof self.db.options.j == 'boolean' || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.db.options); - } else if(typeof self.db.safe == "boolean") { - finalOptions = {w: (self.db.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Expose. - */ -exports.Collection = Collection; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js deleted file mode 100644 index 955858283ce..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/base_command.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - Base object used for common functionality -**/ -var BaseCommand = exports.BaseCommand = function BaseCommand() { -}; - -var id = 1; -BaseCommand.prototype.getRequestId = function getRequestId() { - if (!this.requestId) this.requestId = id++; - return this.requestId; -}; - -BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {} - -BaseCommand.prototype.updateRequestId = function() { - this.requestId = id++; - return this.requestId; -}; - -// OpCodes -BaseCommand.OP_REPLY = 1; -BaseCommand.OP_MSG = 1000; -BaseCommand.OP_UPDATE = 2001; -BaseCommand.OP_INSERT = 2002; -BaseCommand.OP_GET_BY_OID = 2003; -BaseCommand.OP_QUERY = 2004; -BaseCommand.OP_GET_MORE = 2005; -BaseCommand.OP_DELETE = 2006; -BaseCommand.OP_KILL_CURSORS = 2007; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js deleted file mode 100644 index 9e85ab02d7b..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/db_command.js +++ /dev/null @@ -1,241 +0,0 @@ -var QueryCommand = require('./query_command').QueryCommand, - InsertCommand = require('./insert_command').InsertCommand, - inherits = require('util').inherits, - utils = require('../utils'), - crypto = require('crypto'); - -/** - Db Command -**/ -var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - QueryCommand.call(this); - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = dbInstance; - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(DbCommand, QueryCommand); - -// Constants -DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"; -DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes"; -DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile"; -DbCommand.SYSTEM_USER_COLLECTION = "system.users"; -DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd"; -DbCommand.SYSTEM_JS_COLLECTION = "system.js"; - -// New commands -DbCommand.NcreateIsMasterCommand = function(db, databaseName) { - return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -// Provide constructors for different db commands -DbCommand.createIsMasterCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null); -}; - -DbCommand.createCollectionInfoCommand = function(db, selector) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null); -}; - -DbCommand.createGetNonceCommand = function(db, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null); -}; - -DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) { - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var hash_password = md5.digest('hex'); - // Final key - md5 = crypto.createHash('md5'); - md5.update(nonce + username + hash_password); - var key = md5.digest('hex'); - // Creat selector - var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key}; - // Create db command - return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null); -}; - -DbCommand.createLogoutCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null); -}; - -DbCommand.createCreateCollectionCommand = function(db, collectionName, options) { - var selector = {'create':collectionName}; - // Modify the options to ensure correct behaviour - for(var name in options) { - if(options[name] != null && options[name].constructor != Function) selector[name] = options[name]; - } - // Execute the command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null); -}; - -DbCommand.createDropCollectionCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null); -}; - -DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName, options) { - var renameCollection = db.databaseName + "." + fromCollectionName; - var toCollection = db.databaseName + "." + toCollectionName; - var dropTarget = options && options.dropTarget ? options.dropTarget : false; - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget}, null); -}; - -DbCommand.createGetLastErrorCommand = function(options, db) { - - if (typeof db === 'undefined') { - db = options; - options = {}; - } - // Final command - var command = {'getlasterror':1}; - // If we have an options Object let's merge in the fields (fsync/wtimeout/w) - if('object' === typeof options) { - for(var name in options) { - command[name] = options[name] - } - } - - // Special case for w == 1, remove the w - if(1 == command.w) { - delete command.w; - } - - // Execute command - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null); -}; - -DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand; - -DbCommand.createGetPreviousErrorsCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null); -}; - -DbCommand.createResetErrorHistoryCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null); -}; - -DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) { - var fieldHash = {}; - var indexes = []; - var keys; - - // Get all the fields accordingly - if('string' == typeof fieldOrSpec) { - // 'type' - indexes.push(fieldOrSpec + '_' + 1); - fieldHash[fieldOrSpec] = 1; - - } else if(utils.isArray(fieldOrSpec)) { - - fieldOrSpec.forEach(function(f) { - if('string' == typeof f) { - // [{location:'2d'}, 'type'] - indexes.push(f + '_' + 1); - fieldHash[f] = 1; - } else if(utils.isArray(f)) { - // [['location', '2d'],['type', 1]] - indexes.push(f[0] + '_' + (f[1] || 1)); - fieldHash[f[0]] = f[1] || 1; - } else if(utils.isObject(f)) { - // [{location:'2d'}, {type:1}] - keys = Object.keys(f); - keys.forEach(function(k) { - indexes.push(k + '_' + f[k]); - fieldHash[k] = f[k]; - }); - } else { - // undefined (ignore) - } - }); - - } else if(utils.isObject(fieldOrSpec)) { - // {location:'2d', type:1} - keys = Object.keys(fieldOrSpec); - keys.forEach(function(key) { - indexes.push(key + '_' + fieldOrSpec[key]); - fieldHash[key] = fieldOrSpec[key]; - }); - } - - // Generate the index name - var indexName = typeof options.name == 'string' - ? options.name - : indexes.join("_"); - - var selector = { - 'ns': db.databaseName + "." + collectionName, - 'key': fieldHash, - 'name': indexName - } - - // Ensure we have a correct finalUnique - var finalUnique = options == null || 'object' === typeof options - ? false - : options; - - // Set up options - options = options == null || typeof options == 'boolean' - ? {} - : options; - - // Add all the options - var keys = Object.keys(options); - for(var i = 0; i < keys.length; i++) { - selector[keys[i]] = options[keys[i]]; - } - - if(selector['unique'] == null) - selector['unique'] = finalUnique; - - var name = db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION; - var cmd = new InsertCommand(db, name, false); - return cmd.add(selector); -}; - -DbCommand.logoutCommand = function(db, command_hash, options) { - var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName; - // Create logout command - return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -} - -DbCommand.createDropIndexCommand = function(db, collectionName, indexName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null); -}; - -DbCommand.createReIndexCommand = function(db, collectionName) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null); -}; - -DbCommand.createDropDatabaseCommand = function(db) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null); -}; - -DbCommand.createDbCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options); -}; - -DbCommand.createAdminDbCommand = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null); -}; - -DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) { - return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null); -}; - -DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) { - return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options); -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js deleted file mode 100644 index e6ae20ab6e6..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/delete_command.js +++ /dev/null @@ -1,114 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = selector; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.flags = flags; - this.collectionName = collectionName; - this.selector = selector; - this.db = db; -}; - -inherits(DeleteCommand, BaseCommand); - -DeleteCommand.OP_DELETE = 2006; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 ZERO; // 0 - reserved for future use - mongo.BSON selector; // query object. See below for details. -} -*/ -DeleteCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff; - _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff; - _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff; - _command[_index] = DeleteCommand.OP_DELETE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(this.selector)) { - documentLength = this.selector.length; - // Copy the data into the current buffer - this.selector.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js deleted file mode 100644 index d3aac02ef81..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/get_more_command.js +++ /dev/null @@ -1,83 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Get More Document Command -**/ -var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.numberToReturn = numberToReturn; - this.cursorId = cursorId; - this.db = db; -}; - -inherits(GetMoreCommand, BaseCommand); - -GetMoreCommand.OP_GET_MORE = 2005; - -GetMoreCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index++] = totalLengthOfCommand & 0xff; - _command[_index++] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index++] = (totalLengthOfCommand >> 24) & 0xff; - - // Write the request ID - _command[_index++] = this.requestId & 0xff; - _command[_index++] = (this.requestId >> 8) & 0xff; - _command[_index++] = (this.requestId >> 16) & 0xff; - _command[_index++] = (this.requestId >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the op_code for the command - _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff; - _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Number of documents to return - _command[_index++] = this.numberToReturn & 0xff; - _command[_index++] = (this.numberToReturn >> 8) & 0xff; - _command[_index++] = (this.numberToReturn >> 16) & 0xff; - _command[_index++] = (this.numberToReturn >> 24) & 0xff; - - // Encode the cursor id - var low_bits = this.cursorId.getLowBits(); - // Encode low bits - _command[_index++] = low_bits & 0xff; - _command[_index++] = (low_bits >> 8) & 0xff; - _command[_index++] = (low_bits >> 16) & 0xff; - _command[_index++] = (low_bits >> 24) & 0xff; - - var high_bits = this.cursorId.getHighBits(); - // Encode high bits - _command[_index++] = high_bits & 0xff; - _command[_index++] = (high_bits >> 8) & 0xff; - _command[_index++] = (high_bits >> 16) & 0xff; - _command[_index++] = (high_bits >> 24) & 0xff; - // Return command - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js deleted file mode 100644 index d6a210017a5..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/insert_command.js +++ /dev/null @@ -1,147 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) { - BaseCommand.call(this); - - this.collectionName = collectionName; - this.documents = []; - this.checkKeys = checkKeys == null ? true : checkKeys; - this.db = db; - this.flags = 0; - this.serializeFunctions = false; - - // Ensure valid options hash - options = options == null ? {} : options; - - // Check if we have keepGoing set -> set flag if it's the case - if(options['keepGoing'] != null && options['keepGoing']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Check if we have keepGoing set -> set flag if it's the case - if(options['continueOnError'] != null && options['continueOnError']) { - // This will finish inserting all non-index violating documents even if it returns an error - this.flags = 1; - } - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(InsertCommand, BaseCommand); - -// OpCodes -InsertCommand.OP_INSERT = 2002; - -InsertCommand.prototype.add = function(document) { - if(Buffer.isBuffer(document)) { - var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24; - if(object_size != document.length) { - var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.documents.push(document); - return this; -}; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - BSON[] documents; // one or more documents to insert into the collection -} -*/ -InsertCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4); - // var docLength = 0 - for(var i = 0; i < this.documents.length; i++) { - if(Buffer.isBuffer(this.documents[i])) { - totalLengthOfCommand += this.documents[i].length; - } else { - // Calculate size of document - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true); - } - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff; - _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff; - _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff; - _command[_index] = InsertCommand.OP_INSERT & 0xff; - // Adjust index - _index = _index + 4; - // Write flags if any - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write all the bson documents to the buffer at the index offset - for(var i = 0; i < this.documents.length; i++) { - // Document binary length - var documentLength = 0 - var object = this.documents[i]; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - return _command; -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js deleted file mode 100644 index d8ccb0c3a64..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js +++ /dev/null @@ -1,98 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits, - binaryutils = require('../utils'); - -/** - Insert Document Command -**/ -var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) { - BaseCommand.call(this); - - this.cursorIds = cursorIds; - this.db = db; -}; - -inherits(KillCursorCommand, BaseCommand); - -KillCursorCommand.OP_KILL_CURSORS = 2007; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - int32 numberOfCursorIDs; // number of cursorIDs in message - int64[] cursorIDs; // array of cursorIDs to close -} -*/ -KillCursorCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8); - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff; - _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff; - _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff; - _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Number of cursors to kill - var numberOfCursors = this.cursorIds.length; - _command[_index + 3] = (numberOfCursors >> 24) & 0xff; - _command[_index + 2] = (numberOfCursors >> 16) & 0xff; - _command[_index + 1] = (numberOfCursors >> 8) & 0xff; - _command[_index] = numberOfCursors & 0xff; - // Adjust index - _index = _index + 4; - - // Encode all the cursors - for(var i = 0; i < this.cursorIds.length; i++) { - // Encode the cursor id - var low_bits = this.cursorIds[i].getLowBits(); - // Encode low bits - _command[_index + 3] = (low_bits >> 24) & 0xff; - _command[_index + 2] = (low_bits >> 16) & 0xff; - _command[_index + 1] = (low_bits >> 8) & 0xff; - _command[_index] = low_bits & 0xff; - // Adjust index - _index = _index + 4; - - var high_bits = this.cursorIds[i].getHighBits(); - // Encode high bits - _command[_index + 3] = (high_bits >> 24) & 0xff; - _command[_index + 2] = (high_bits >> 16) & 0xff; - _command[_index + 1] = (high_bits >> 8) & 0xff; - _command[_index] = high_bits & 0xff; - // Adjust index - _index = _index + 4; - } - - return _command; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js deleted file mode 100644 index 76829d9991f..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/query_command.js +++ /dev/null @@ -1,261 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Insert Document Command -**/ -var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) { - BaseCommand.call(this); - - // Validate correctness off the selector - var object = query, - object_size; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - object = returnFieldSelector; - if(Buffer.isBuffer(object)) { - object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - // Make sure we don't get a null exception - options = options == null ? {} : options; - // Set up options - this.collectionName = collectionName; - this.queryOptions = queryOptions; - this.numberToSkip = numberToSkip; - this.numberToReturn = numberToReturn; - - // Ensure we have no null query - query = query == null ? {} : query; - // Wrap query in the $query parameter so we can add read preferences for mongos - this.query = query; - this.returnFieldSelector = returnFieldSelector; - this.db = db; - - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(QueryCommand, BaseCommand); - -QueryCommand.OP_QUERY = 2004; - -/* - * Adds the read prefrence to the current command - */ -QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) { - // If we have readPreference set to true set to secondary prefered - if(readPreference == true) { - readPreference = 'secondaryPreferred'; - } else if(readPreference == 'false') { - readPreference = 'primary'; - } - - // Force the slave ok flag to be set if we are not using primary read preference - if(readPreference != false && readPreference != 'primary') { - this.queryOptions |= QueryCommand.OPTS_SLAVE; - } - - // Backward compatibility, ensure $query only set on read preference so 1.8.X works - if((readPreference != null || tags != null) && this.query['$query'] == null) { - this.query = {'$query': this.query}; - } - - // If we have no readPreference set and no tags, check if the slaveOk bit is set - if(readPreference == null && tags == null) { - // If we have a slaveOk bit set the read preference for MongoS - if(this.queryOptions & QueryCommand.OPTS_SLAVE) { - this.query['$readPreference'] = {mode: 'secondary'} - } else { - this.query['$readPreference'] = {mode: 'primary'} - } - } - - // Build read preference object - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - this.query['$readPreference'] = readPreference.toObject(); - } else if(readPreference != null) { - // Add the read preference - this.query['$readPreference'] = {mode: readPreference}; - - // If we have tags let's add them - if(tags != null) { - this.query['$readPreference']['tags'] = tags; - } - } -} - -/* -struct { - MsgHeader header; // standard message header - int32 opts; // query options. See below for details. - cstring fullCollectionName; // "dbname.collectionname" - int32 numberToSkip; // number of documents to skip when returning results - int32 numberToReturn; // number of documents to return in the first OP_REPLY - BSON query ; // query object. See below for details. - [ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details. -} -*/ -QueryCommand.prototype.toBinary = function() { - // Total length of the command - var totalLengthOfCommand = 0; - // Calculate total length of the document - if(Buffer.isBuffer(this.query)) { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4); - } else { - totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4); - } - - // Calculate extra fields size - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true); - } - } else if(Buffer.isBuffer(this.returnFieldSelector)) { - totalLengthOfCommand += this.returnFieldSelector.length; - } - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff; - _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff; - _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff; - _command[_index] = QueryCommand.OP_QUERY & 0xff; - // Adjust index - _index = _index + 4; - - // Write the query options - _command[_index + 3] = (this.queryOptions >> 24) & 0xff; - _command[_index + 2] = (this.queryOptions >> 16) & 0xff; - _command[_index + 1] = (this.queryOptions >> 8) & 0xff; - _command[_index] = this.queryOptions & 0xff; - // Adjust index - _index = _index + 4; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the number of documents to skip - _command[_index + 3] = (this.numberToSkip >> 24) & 0xff; - _command[_index + 2] = (this.numberToSkip >> 16) & 0xff; - _command[_index + 1] = (this.numberToSkip >> 8) & 0xff; - _command[_index] = this.numberToSkip & 0xff; - // Adjust index - _index = _index + 4; - - // Write the number of documents to return - _command[_index + 3] = (this.numberToReturn >> 24) & 0xff; - _command[_index + 2] = (this.numberToReturn >> 16) & 0xff; - _command[_index + 1] = (this.numberToReturn >> 8) & 0xff; - _command[_index] = this.numberToReturn & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.query; - - // Serialize the selector - if(Buffer.isBuffer(object)) { - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - // Serialize the document straight to the buffer - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Push field selector if available - if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) { - if(Object.keys(this.returnFieldSelector).length > 0) { - var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) { - // Document binary length - var documentLength = 0 - var object = this.returnFieldSelector; - - // Serialize the selector - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - } - - // Return finished command - return _command; -}; - -// Constants -QueryCommand.OPTS_NONE = 0; -QueryCommand.OPTS_TAILABLE_CURSOR = 2; -QueryCommand.OPTS_SLAVE = 4; -QueryCommand.OPTS_OPLOG_REPLY = 8; -QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16; -QueryCommand.OPTS_AWAIT_DATA = 32; -QueryCommand.OPTS_EXHAUST = 64; -QueryCommand.OPTS_PARTIAL = 128; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js deleted file mode 100644 index 9829dea453d..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/commands/update_command.js +++ /dev/null @@ -1,174 +0,0 @@ -var BaseCommand = require('./base_command').BaseCommand, - inherits = require('util').inherits; - -/** - Update Document Command -**/ -var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) { - BaseCommand.call(this); - - var object = spec; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - var object = document; - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) { - var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - error.name = 'MongoError'; - throw error; - } - } - - this.collectionName = collectionName; - this.spec = spec; - this.document = document; - this.db = db; - this.serializeFunctions = false; - - // Generate correct flags - var db_upsert = 0; - var db_multi_update = 0; - db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert; - db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update; - - // Flags - this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2); - // Let us defined on a command basis if we want functions to be serialized or not - if(options['serializeFunctions'] != null && options['serializeFunctions']) { - this.serializeFunctions = true; - } -}; - -inherits(UpdateCommand, BaseCommand); - -UpdateCommand.OP_UPDATE = 2001; - -/* -struct { - MsgHeader header; // standard message header - int32 ZERO; // 0 - reserved for future use - cstring fullCollectionName; // "dbname.collectionname" - int32 flags; // bit vector. see below - BSON spec; // the query to select the document - BSON document; // the document data to update with or insert -} -*/ -UpdateCommand.prototype.toBinary = function() { - // Calculate total length of the document - var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) + - this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4); - - // Let's build the single pass buffer command - var _index = 0; - var _command = new Buffer(totalLengthOfCommand); - // Write the header information to the buffer - _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff; - _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff; - _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff; - _command[_index] = totalLengthOfCommand & 0xff; - // Adjust index - _index = _index + 4; - // Write the request ID - _command[_index + 3] = (this.requestId >> 24) & 0xff; - _command[_index + 2] = (this.requestId >> 16) & 0xff; - _command[_index + 1] = (this.requestId >> 8) & 0xff; - _command[_index] = this.requestId & 0xff; - // Adjust index - _index = _index + 4; - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - // Write the op_code for the command - _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff; - _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff; - _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff; - _command[_index] = UpdateCommand.OP_UPDATE & 0xff; - // Adjust index - _index = _index + 4; - - // Write zero - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - _command[_index++] = 0; - - // Write the collection name to the command - _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1; - _command[_index - 1] = 0; - - // Write the update flags - _command[_index + 3] = (this.flags >> 24) & 0xff; - _command[_index + 2] = (this.flags >> 16) & 0xff; - _command[_index + 1] = (this.flags >> 8) & 0xff; - _command[_index] = this.flags & 0xff; - // Adjust index - _index = _index + 4; - - // Document binary length - var documentLength = 0 - var object = this.spec; - - // Serialize the selector - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - // Document binary length - var documentLength = 0 - var object = this.document; - - // Serialize the document - // If we are passing a raw buffer, do minimal validation - if(Buffer.isBuffer(object)) { - var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24; - if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]"); - documentLength = object.length; - // Copy the data into the current buffer - object.copy(_command, _index); - } else { - documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1; - } - - // Write the length to the document - _command[_index + 3] = (documentLength >> 24) & 0xff; - _command[_index + 2] = (documentLength >> 16) & 0xff; - _command[_index + 1] = (documentLength >> 8) & 0xff; - _command[_index] = documentLength & 0xff; - // Update index in buffer - _index = _index + documentLength; - // Add terminating 0 for the object - _command[_index - 1] = 0; - - return _command; -}; - -// Constants -UpdateCommand.DB_UPSERT = 0; -UpdateCommand.DB_MULTI_UPDATE = 1; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js deleted file mode 100644 index e93463c305f..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js +++ /dev/null @@ -1,169 +0,0 @@ -var EventEmitter = require('events').EventEmitter - , inherits = require('util').inherits; - -/** - * Internal class for callback storage - * @ignore - */ -var CallbackStore = function() { - // Make class an event emitter - EventEmitter.call(this); - // Add a info about call variable - this._notReplied = {}; -} - -/** - * @ignore - */ -inherits(CallbackStore, EventEmitter); - -var Base = function Base() { - EventEmitter.call(this); - - // Callback store is part of connection specification - if(Base._callBackStore == null) { - Base._callBackStore = new CallbackStore(); - } - - // this._callBackStore = Base._callBackStore; - this._callBackStore = new CallbackStore(); -} - -/** - * @ignore - */ -inherits(Base, EventEmitter); - -/** - * Fire all the errors - * @ignore - */ -Base.prototype.__executeAllCallbacksWithError = function(err) { - // Check all callbacks - var keys = Object.keys(this._callBackStore._notReplied); - // For each key check if it's a callback that needs to be returned - for(var j = 0; j < keys.length; j++) { - var info = this._callBackStore._notReplied[keys[j]]; - // Check if we have a chained command (findAndModify) - if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) { - var chained = info['chained']; - // Only callback once and the last one is the right one - var finalCallback = chained.pop(); - // Emit only the last event - this._callBackStore.emit(finalCallback, err, null); - - // Put back the final callback to ensure we don't call all commands in the chain - chained.push(finalCallback); - - // Remove all chained callbacks - for(var i = 0; i < chained.length; i++) { - delete this._callBackStore._notReplied[chained[i]]; - } - } else { - this._callBackStore.emit(keys[j], err, null); - } - } -} - -/** - * Register a handler - * @ignore - * @api private - */ -Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) { - // If we have an array of commands, chain them - var chained = Array.isArray(db_command); - - // Check if we have exhausted - if(typeof exhaust == 'function') { - callback = exhaust; - exhaust = false; - } - - // If they are chained we need to add a special handler situation - if(chained) { - // List off chained id's - var chainedIds = []; - // Add all id's - for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString()); - // Register all the commands together - for(var i = 0; i < db_command.length; i++) { - var command = db_command[i]; - // Add the callback to the store - this._callBackStore.once(command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection, exhaust:false}; - } - } else { - // Add the callback to the list of handlers - this._callBackStore.once(db_command.getRequestId(), callback); - // Add the information about the reply - this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust}; - } -} - -/** - * Re-Register a handler, on the cursor id f.ex - * @ignore - * @api private - */ -Base.prototype._reRegisterHandler = function(newId, object, callback) { - // Add the callback to the list of handlers - this._callBackStore.once(newId, object.callback.listener); - // Add the information about the reply - this._callBackStore._notReplied[newId] = object.info; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._callHandler = function(id, document, err) { - // If there is a callback peform it - if(this._callBackStore.listeners(id).length >= 1) { - // Get info object - var info = this._callBackStore._notReplied[id]; - // Delete the current object - delete this._callBackStore._notReplied[id]; - // Emit to the callback of the object - this._callBackStore.emit(id, err, document, info.connection); - } -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._hasHandler = function(id) { - // If there is a callback peform it - return this._callBackStore.listeners(id).length >= 1; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._removeHandler = function(id) { - // Remove the information - if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id]; - // Remove the callback if it's registered - this._callBackStore.removeAllListeners(id); - // Force cleanup _events, node.js seems to set it as a null value - if(this._callBackStore._events != null) delete this._callBackStore._events[id]; -} - -/** - * - * @ignore - * @api private - */ -Base.prototype._findHandler = function(id) { - var info = this._callBackStore._notReplied[id]; - // Return the callback - return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null} -} - -exports.Base = Base; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js deleted file mode 100644 index 41647a36538..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection.js +++ /dev/null @@ -1,504 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - binaryutils = require('../utils'), - tls = require('tls'); - -var Connection = exports.Connection = function(id, socketOptions) { - // Set up event emitter - EventEmitter.call(this); - // Store all socket options - this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false}; - // Set keep alive default if not overriden - if(this.socketOptions.keepAlive == null && (process.platform !== "sunos" || process.platform !== "win32")) this.socketOptions.keepAlive = 100; - // Id for the connection - this.id = id; - // State of the connection - this.connected = false; - // Set if this is a domain socket - this.domainSocket = this.socketOptions.domainSocket; - - // - // Connection parsing state - // - this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE; - this.maxMessageSizeBytes = socketOptions.maxMessageSizeBytes ? socketOptions.maxMessageSizeBytes : Connection.DEFAULT_MAX_MESSAGE_SIZE; - // Contains the current message bytes - this.buffer = null; - // Contains the current message size - this.sizeOfMessage = 0; - // Contains the readIndex for the messaage - this.bytesRead = 0; - // Contains spill over bytes from additional messages - this.stubBuffer = 0; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]}; - - // Just keeps list of events we allow - resetHandlers(this, false); -} - -// Set max bson size -Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4; -// Set default to max bson to avoid overflow or bad guesses -Connection.DEFAULT_MAX_MESSAGE_SIZE = Connection.DEFAULT_MAX_BSON_SIZE; - -// Inherit event emitter so we can emit stuff wohoo -inherits(Connection, EventEmitter); - -Connection.prototype.start = function() { - var self = this; - - // If we have a normal connection - if(this.socketOptions.ssl) { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Check if the driver should validate the certificate - var validate_certificates = this.socketOptions.sslValidate == true ? true : false; - - // Create options for the tls connection - var tls_options = { - socket: this.connection - , rejectUnauthorized: false - } - - // If we wish to validate the certificate we have provided a ca store - if(validate_certificates) { - tls_options.ca = this.socketOptions.sslCA; - } - - // If we have a certificate to present - if(this.socketOptions.sslCert) { - tls_options.cert = this.socketOptions.sslCert; - tls_options.key = this.socketOptions.sslKey; - } - - // If the driver has been provided a private key password - if(this.socketOptions.sslPass) { - tls_options.passphrase = this.socketOptions.sslPass; - } - - // Contains the cleartext stream - var cleartext = null; - // Attempt to establish a TLS connection to the server - try { - cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() { - // If we have a ssl certificate validation error return an error - if(cleartext.authorizationError && validate_certificates) { - // Emit an error - return self.emit("error", cleartext.authorizationError, self, {ssl:true}); - } - - // Connect to the server - connectHandler(self)(); - }) - } catch(err) { - return self.emit("error", "SSL connection failed", self, {ssl:true}); - } - - // Save the output stream - this.writeSteam = cleartext; - - // Set up data handler for the clear stream - cleartext.on("data", createDataHandler(this)); - // Do any handling of end event of the stream - cleartext.on("end", endHandler(this)); - cleartext.on("error", errorHandler(this)); - - // Handle any errors - this.connection.on("error", errorHandler(this)); - // Handle timeout - this.connection.on("timeout", timeoutHandler(this)); - // Handle drain event - this.connection.on("drain", drainHandler(this)); - // Handle the close event - this.connection.on("close", closeHandler(this)); - } else { - // Create new connection instance - if(this.domainSocket) { - this.connection = net.createConnection(this.socketOptions.host); - } else { - this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host); - } - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("opened connection", this.socketOptions); - } - - // Set options on the socket - this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout); - // Work around for 0.4.X - if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay); - // Set keep alive if defined - if(process.version.indexOf("v0.4") == -1) { - if(this.socketOptions.keepAlive > 0) { - this.connection.setKeepAlive(true, this.socketOptions.keepAlive); - } else { - this.connection.setKeepAlive(false); - } - } - - // Set up write stream - this.writeSteam = this.connection; - // Add handlers - this.connection.on("error", errorHandler(this)); - // Add all handlers to the socket to manage it - this.connection.on("connect", connectHandler(this)); - // this.connection.on("end", endHandler(this)); - this.connection.on("data", createDataHandler(this)); - this.connection.on("timeout", timeoutHandler(this)); - this.connection.on("drain", drainHandler(this)); - this.connection.on("close", closeHandler(this)); - } -} - -// Check if the sockets are live -Connection.prototype.isConnected = function() { - return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable; -} - -// Write the data out to the socket -Connection.prototype.write = function(command, callback) { - try { - // If we have a list off commands to be executed on the same socket - if(Array.isArray(command)) { - for(var i = 0; i < command.length; i++) { - var binaryCommand = command[i].toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]}); - - var r = this.writeSteam.write(binaryCommand); - } - } else { - var binaryCommand = command.toBinary() - - if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize) - return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes")); - - if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) { - return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes")); - } - - if(this.logger != null && this.logger.doDebug) - this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command}); - - var r = this.writeSteam.write(binaryCommand); - } - } catch (err) { - if(typeof callback === 'function') callback(err); - } -} - -// Force the closure of the connection -Connection.prototype.close = function() { - // clear out all the listeners - resetHandlers(this, true); - // Add a dummy error listener to catch any weird last moment errors (and ignore them) - this.connection.on("error", function() {}) - // destroy connection - this.connection.destroy(); - if(this.logger != null && this.logger.doDebug){ - this.logger.debug("closed connection", this.connection); - } -} - -// Reset all handlers -var resetHandlers = function(self, clearListeners) { - self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]}; - - // If we want to clear all the listeners - if(clearListeners && self.connection != null) { - var keys = Object.keys(self.eventHandlers); - // Remove all listeners - for(var i = 0; i < keys.length; i++) { - self.connection.removeAllListeners(keys[i]); - } - } -} - -// -// Handlers -// - -// Connect handler -var connectHandler = function(self) { - return function(data) { - // Set connected - self.connected = true; - // Now that we are connected set the socket timeout - self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout); - // Emit the connect event with no error - self.emit("connect", null, self); - } -} - -var createDataHandler = exports.Connection.createDataHandler = function(self) { - // We need to handle the parsing of the data - // and emit the messages when there is a complete one - return function(data) { - // Parse until we are done with the data - while(data.length > 0) { - // If we still have bytes to read on the current message - if(self.bytesRead > 0 && self.sizeOfMessage > 0) { - // Calculate the amount of remaining bytes - var remainingBytesToRead = self.sizeOfMessage - self.bytesRead; - // Check if the current chunk contains the rest of the message - if(remainingBytesToRead > data.length) { - // Copy the new data into the exiting buffer (should have been allocated when we know the message size) - data.copy(self.buffer, self.bytesRead); - // Adjust the number of bytes read so it point to the correct index in the buffer - self.bytesRead = self.bytesRead + data.length; - - // Reset state of buffer - data = new Buffer(0); - } else { - // Copy the missing part of the data into our current buffer - data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead); - // Slice the overflow into a new buffer that we will then re-parse - data = data.slice(remainingBytesToRead); - - // Emit current complete message - try { - var emitBuffer = self.buffer; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Emit the buffer - self.emit("message", emitBuffer, self); - } catch(err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } - } else { - // Stub buffer is kept in case we don't get enough bytes to determine the - // size of the message (< 4 bytes) - if(self.stubBuffer != null && self.stubBuffer.length > 0) { - - // If we have enough bytes to determine the message size let's do it - if(self.stubBuffer.length + data.length > 4) { - // Prepad the data - var newData = new Buffer(self.stubBuffer.length + data.length); - self.stubBuffer.copy(newData, 0); - data.copy(newData, self.stubBuffer.length); - // Reassign for parsing - data = newData; - - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - - } else { - - // Add the the bytes to the stub buffer - var newStubBuffer = new Buffer(self.stubBuffer.length + data.length); - // Copy existing stub buffer - self.stubBuffer.copy(newStubBuffer, 0); - // Copy missing part of the data - data.copy(newStubBuffer, self.stubBuffer.length); - // Exit parsing loop - data = new Buffer(0); - } - } else { - if(data.length > 4) { - // Retrieve the message size - var sizeOfMessage = binaryutils.decodeUInt32(data, 0); - // If we have a negative sizeOfMessage emit error and return - if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{ - sizeOfMessage: sizeOfMessage, - bytesRead: self.bytesRead, - stubBuffer: self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - return; - } - - // Ensure that the size of message is larger than 0 and less than the max allowed - if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) { - self.buffer = new Buffer(sizeOfMessage); - // Copy all the data into the buffer - data.copy(self.buffer, 0); - // Update bytes read - self.bytesRead = data.length; - // Update sizeOfMessage - self.sizeOfMessage = sizeOfMessage; - // Ensure stub buffer is null - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) { - try { - var emitBuffer = data; - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:self.sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) { - var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:0, - buffer:null, - stubBuffer:null}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - - // Clear out the state of the parser - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Exit parsing loop - data = new Buffer(0); - - } else { - try { - var emitBuffer = data.slice(0, sizeOfMessage); - // Reset state of buffer - self.buffer = null; - self.sizeOfMessage = 0; - self.bytesRead = 0; - self.stubBuffer = null; - // Copy rest of message - data = data.slice(sizeOfMessage); - // Emit the message - self.emit("message", emitBuffer, self); - } catch (err) { - var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{ - sizeOfMessage:sizeOfMessage, - bytesRead:self.bytesRead, - stubBuffer:self.stubBuffer}}; - if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject); - // We got a parse Error fire it off then keep going - self.emit("parseError", errorObject, self); - } - - } - } else { - // Create a buffer that contains the space for the non-complete message - self.stubBuffer = new Buffer(data.length) - // Copy the data to the stub buffer - data.copy(self.stubBuffer, 0); - // Exit parsing loop - data = new Buffer(0); - } - } - } - } - } -} - -var endHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit end event - self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var timeoutHandler = function(self) { - return function() { - // Set connected to false - self.connected = false; - // Emit timeout event - self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self); - } -} - -var drainHandler = function(self) { - return function() { - } -} - -var errorHandler = function(self) { - return function(err) { - // Set connected to false - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } -} - -var closeHandler = function(self) { - return function(hadError) { - // If we have an error during the connection phase - if(hadError && !self.connected) { - // Set disconnected - self.connected = false; - // Emit error - self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } else { - // Set disconnected - self.connected = false; - // Emit close - self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self); - } - } -} - -// Some basic defaults -Connection.DEFAULT_PORT = 27017; - - - - - - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js deleted file mode 100644 index 0ca433f5297..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_pool.js +++ /dev/null @@ -1,293 +0,0 @@ -var utils = require('./connection_utils'), - inherits = require('util').inherits, - net = require('net'), - timers = require('timers'), - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - MongoReply = require("../responses/mongo_reply").MongoReply, - Connection = require("./connection").Connection; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) { - if(typeof host !== 'string') { - throw new Error("host must be specified [" + host + "]"); - } - - // Set up event emitter - EventEmitter.call(this); - - // Keep all options for the socket in a specific collection allowing the user to specify the - // Wished upon socket connection parameters - this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {}; - this.socketOptions.host = host; - this.socketOptions.port = port; - this.socketOptions.domainSocket = false; - this.bson = bson; - // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc) - this.poolSize = poolSize; - this.minPoolSize = Math.floor(this.poolSize / 2) + 1; - - // Check if the host is a socket - if(host.match(/^\//)) { - this.socketOptions.domainSocket = true; - } else if(typeof port === 'string') { - try { - port = parseInt(port, 10); - } catch(err) { - new Error("port must be specified or valid integer[" + port + "]"); - } - } else if(typeof port !== 'number') { - throw new Error("port must be specified [" + port + "]"); - } - - // Set default settings for the socket options - utils.setIntegerParameter(this.socketOptions, 'timeout', 0); - // Delay before writing out the data to the server - utils.setBooleanParameter(this.socketOptions, 'noDelay', true); - // Delay before writing out the data to the server - utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0); - // Set the encoding of the data read, default is binary == null - utils.setStringParameter(this.socketOptions, 'encoding', null); - // Allows you to set a throttling bufferSize if you need to stop overflows - utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0); - - // Internal structures - this.openConnections = []; - // Assign connection id's - this.connectionId = 0; - - // Current index for selection of pool connection - this.currentConnectionIndex = 0; - // The pool state - this._poolState = 'disconnected'; - // timeout control - this._timeout = false; - // Time to wait between connections for the pool - this._timeToWait = 10; -} - -inherits(ConnectionPool, EventEmitter); - -ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) { - if(maxBsonSize == null){ - maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxBsonSize = maxBsonSize; - } -} - -ConnectionPool.prototype.setMaxMessageSizeBytes = function(maxMessageSizeBytes) { - if(maxMessageSizeBytes == null){ - maxMessageSizeBytes = Connection.DEFAULT_MAX_MESSAGE_SIZE; - } - - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].maxMessageSizeBytes = maxMessageSizeBytes; - } -} - -// Start a function -var _connect = function(_self) { - // return new function() { - // Create a new connection instance - var connection = new Connection(_self.connectionId++, _self.socketOptions); - // Set logger on pool - connection.logger = _self.logger; - // Connect handler - connection.on("connect", function(err, connection) { - // Add connection to list of open connections - _self.openConnections.push(connection); - // If the number of open connections is equal to the poolSize signal ready pool - if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') { - // Set connected - _self._poolState = 'connected'; - // Emit pool ready - _self.emit("poolReady"); - } else if(_self.openConnections.length < _self.poolSize) { - // Wait a little bit of time to let the close event happen if the server closes the connection - // so we don't leave hanging connections around - if(typeof _self._timeToWait == 'number') { - setTimeout(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }, _self._timeToWait); - } else { - processor(function() { - // If we are still connecting (no close events fired in between start another connection) - if(_self._poolState == 'connecting') { - _connect(_self); - } - }); - } - } - }); - - var numberOfErrors = 0 - - // Error handler - connection.on("error", function(err, connection, error_options) { - numberOfErrors++; - // If we are already disconnected ignore the event - if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) { - _self.emit("error", err, connection, error_options); - } - - // Close the connection - connection.close(); - // Set pool as disconnected - _self._poolState = 'disconnected'; - // Stop the pool - _self.stop(); - }); - - // Close handler - connection.on("close", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) { - _self.emit("close"); - } - - // Set disconnected - _self._poolState = 'disconnected'; - // Stop - _self.stop(); - }); - - // Timeout handler - connection.on("timeout", function(err, connection) { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) { - _self.emit("timeout", err); - } - - // Close the connection - connection.close(); - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - // Parse error, needs a complete shutdown of the pool - connection.on("parseError", function() { - // If we are already disconnected ignore the event - if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) { - _self.emit("parseError", new Error("parseError occured")); - } - - // Set disconnected - _self._poolState = 'disconnected'; - _self.stop(); - }); - - connection.on("message", function(message) { - _self.emit("message", message); - }); - - // Start connection in the next tick - connection.start(); - // }(); -} - - -// Start method, will throw error if no listeners are available -// Pass in an instance of the listener that contains the api for -// finding callbacks for a given message etc. -ConnectionPool.prototype.start = function() { - var markerDate = new Date().getTime(); - var self = this; - - if(this.listeners("poolReady").length == 0) { - throw "pool must have at least one listener ready that responds to the [poolReady] event"; - } - - // Set pool state to connecting - this._poolState = 'connecting'; - this._timeout = false; - - _connect(self); -} - -// Restart a connection pool (on a close the pool might be in a wrong state) -ConnectionPool.prototype.restart = function() { - // Close all connections - this.stop(false); - // Now restart the pool - this.start(); -} - -// Stop the connections in the pool -ConnectionPool.prototype.stop = function(removeListeners) { - removeListeners = removeListeners == null ? true : removeListeners; - // Set disconnected - this._poolState = 'disconnected'; - - // Clear all listeners if specified - if(removeListeners) { - this.removeAllEventListeners(); - } - - // Close all connections - for(var i = 0; i < this.openConnections.length; i++) { - this.openConnections[i].close(); - } - - // Clean up - this.openConnections = []; -} - -// Check the status of the connection -ConnectionPool.prototype.isConnected = function() { - return this._poolState === 'connected'; -} - -// Checkout a connection from the pool for usage, or grab a specific pool instance -ConnectionPool.prototype.checkoutConnection = function(id) { - var index = (this.currentConnectionIndex++ % (this.openConnections.length)); - var connection = this.openConnections[index]; - return connection; -} - -ConnectionPool.prototype.getAllConnections = function() { - return this.openConnections; -} - -// Remove all non-needed event listeners -ConnectionPool.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("connect"); - this.removeAllListeners("end"); - this.removeAllListeners("parseError"); - this.removeAllListeners("message"); - this.removeAllListeners("poolReady"); -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js deleted file mode 100644 index 591092495a8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/connection_utils.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.setIntegerParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) { - throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setBooleanParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "boolean") { - throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} - -exports.setStringParameter = function(object, field, defaultValue) { - if(object[field] == null) { - object[field] = defaultValue; - } else if(typeof object[field] !== "string") { - throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]"; - } -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js deleted file mode 100644 index 6bd1cdd1158..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/mongos.js +++ /dev/null @@ -1,357 +0,0 @@ -var ReadPreference = require('./read_preference').ReadPreference - , Base = require('./base').Base - , inherits = require('util').inherits; - -/** - * Mongos constructor provides a connection to a mongos proxy including failover to additional servers - * - * Options - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - * @class Represents a Mongos connection with failover to backup proxies - * @param {Array} list of mongos server objects - * @param {Object} [options] additional options for the mongos connection - */ -var Mongos = function Mongos(servers, options) { - // Set up basic - if(!(this instanceof Mongos)) - return new Mongos(servers, options); - - // Set up event emitter - Base.call(this); - - // Throw error on wrong setup - if(servers == null || !Array.isArray(servers) || servers.length == 0) - throw new Error("At least one mongos proxy must be in the array"); - - // Ensure we have at least an empty options object - this.options = options == null ? {} : options; - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - // How often are we checking for new servers in the replicaset - this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 2000 : this.options['haInterval']; - // Save all the server connections - this.servers = servers; - // Servers we need to attempt reconnect with - this.downServers = []; - // Just contains the current lowest ping time and server - this.lowestPingTimeServer = null; - this.lowestPingTime = 0; - - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - - // Add options to servers - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - server._callBackStore = this._callBackStore; - // Default empty socket options object - var socketOptions = {host: server.host, port: server.port}; - // If a socket option object exists clone it - if(this.socketOptions != null) { - var keys = Object.keys(this.socketOptions); - for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]]; - } - // Set socket options - server.socketOptions = socketOptions; - } -} - -/** - * @ignore - */ -inherits(Mongos, Base); - -/** - * @ignore - */ -Mongos.prototype.isMongos = function() { - return true; -} - -/** - * @ignore - */ -Mongos.prototype.connect = function(db, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - var self = this; - - // Keep reference to parent - this.db = db; - // Set server state to connecting - this._serverState = 'connecting'; - // Number of total servers that need to initialized (known servers) - this._numberOfServersLeftToInitialize = this.servers.length; - // Default to the first proxy server as the first one to use - this._currentMongos = this.servers[0]; - - // Connect handler - var connectHandler = function(_server) { - return function(err, result) { - self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1; - - if(self._numberOfServersLeftToInitialize == 0) { - // Start ha function if it exists - if(self.haEnabled) { - // Setup the ha process - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - - // Set the mongos to connected - self._serverState = "connected"; - // Emit the open event - self.db.emit("open", null, self.db); - // Callback - callback(null, self.db); - } - } - }; - - // Error handler - var errorOrCloseHandler = function(_server) { - return function(err, result) { - // Create current mongos comparision - var currentUrl = self._currentMongos.host + ":" + self._currentMongos.port; - var serverUrl = this.host + ":" + this.port; - // We need to check if the server that closed is the actual current proxy we are using, otherwise - // just ignore - if(currentUrl == serverUrl) { - // Remove the server from the list - if(self.servers.indexOf(_server) != -1) { - self.servers.splice(self.servers.indexOf(_server), 1); - } - - // Pick the next one on the list if there is one - for(var i = 0; i < self.servers.length; i++) { - // Grab the server out of the array (making sure there is no servers in the list if none available) - var server = self.servers[i]; - // Generate url for comparision - var serverUrl = server.host + ":" + server.port; - // It's not the current one and connected set it as the current db - if(currentUrl != serverUrl && server.isConnected()) { - self._currentMongos = server; - break; - } - } - } - - // Ensure we don't store the _server twice - if(self.downServers.indexOf(_server) == -1) { - // Add the server instances - self.downServers.push(_server); - } - } - } - - // Mongo function - this.mongosCheckFunction = function() { - // If we have down servers let's attempt a reconnect - if(self.downServers.length > 0) { - var numberOfServersLeft = self.downServers.length; - // Attempt to reconnect - for(var i = 0; i < self.downServers.length; i++) { - var downServer = self.downServers.pop(); - - // Configuration - var options = { - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - returnIsMasterResults: true - } - - // Attemp to reconnect - downServer.connect(self.db, options, function(_server) { - // Return a function to check for the values - return function(err, result) { - // Adjust the number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - - if(err != null) { - self.downServers.push(_server); - } else { - // Add server event handlers - _server.on("close", errorOrCloseHandler(_server)); - _server.on("error", errorOrCloseHandler(_server)); - // Add to list of servers - self.servers.push(_server); - } - - if(numberOfServersLeft <= 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - }(downServer)); - } - } else if(self.servers.length > 0) { - var numberOfServersLeft = self.servers.length; - var _s = new Date().getTime() - - // Else let's perform a ping command - for(var i = 0; i < self.servers.length; i++) { - var executePing = function(_server) { - // Get a read connection - var _connection = _server.checkoutReader(); - // Execute ping command - self.db.command({ping:1}, {failFast:true, connection:_connection}, function(err, result) { - var pingTime = new Date().getTime() - _s; - // If no server set set the first one, otherwise check - // the lowest ping time and assign the server if it's got a lower ping time - if(self.lowestPingTimeServer == null) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } else if(self.lowestPingTime > pingTime - && (_server.host != self.lowestPingTimeServer.host || _server.port != self.lowestPingTimeServer.port)) { - self.lowestPingTimeServer = _server; - self.lowestPingTime = pingTime; - self._currentMongos = _server; - } - - // Number of servers left - numberOfServersLeft = numberOfServersLeft - 1; - // All active mongos's pinged - if(numberOfServersLeft == 0) { - // Perfom another ha - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - }) - } - - // Execute the function - executePing(self.servers[i]); - } - } else { - self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval); - } - } - - // Connect all the server instances - for(var i = 0; i < this.servers.length; i++) { - // Get the connection - var server = this.servers[i]; - server.mongosInstance = this; - // Add server event handlers - server.on("close", errorOrCloseHandler(server)); - server.on("timeout", errorOrCloseHandler(server)); - server.on("error", errorOrCloseHandler(server)); - // Configuration - var options = { - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self._connectTimeoutMS }, - returnIsMasterResults: true - } - - // Connect the instance - server.connect(self.db, options, connectHandler(server)); - } -} - -/** - * @ignore - * Just return the currently picked active connection - */ -Mongos.prototype.allServerInstances = function() { - return this.servers; -} - -/** - * Always ourselves - * @ignore - */ -Mongos.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Mongos.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - // Add all connections - for(var i = 0; i < this.servers.length; i++) { - allConnections = allConnections.concat(this.servers[i].allRawConnections()); - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -Mongos.prototype.isConnected = function() { - return this._serverState == "connected"; -} - -/** - * @ignore - */ -Mongos.prototype.checkoutWriter = function() { - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutWriter(); - } - return this._currentMongos.checkoutWriter(); -} - -/** - * @ignore - */ -Mongos.prototype.checkoutReader = function(read) { - // If we have a read preference object unpack it - if(typeof read == 'object' && read['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode); - } else if(!ReadPreference.isValid(read)) { - throw new Error("Illegal readPreference mode specified, " + read); - } - - // No current mongo, just pick first server - if(this._currentMongos == null && this.servers.length > 0) { - return this.servers[0].checkoutReader(); - } - return this._currentMongos.checkoutReader(); -} - -/** - * @ignore - */ -Mongos.prototype.close = function(callback) { - var self = this; - // Set server status as disconnected - this._serverState = 'disconnected'; - // Number of connections to close - var numberOfConnectionsToClose = self.servers.length; - // If we have a ha process running kill it - if(self._replicasetTimeoutId != null) clearTimeout(self._replicasetTimeoutId); - // Close all proxy connections - for(var i = 0; i < self.servers.length; i++) { - self.servers[i].close(function(err, result) { - numberOfConnectionsToClose = numberOfConnectionsToClose - 1; - // Callback if we have one defined - if(numberOfConnectionsToClose == 0 && typeof callback == 'function') { - callback(null); - } - }); - } -} - -/** - * @ignore - * Return the used state - */ -Mongos.prototype._isUsed = function() { - return this._used; -} - -exports.Mongos = Mongos; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js deleted file mode 100644 index 4cba58792b1..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/read_preference.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * A class representation of the Read Preference. - * - * Read Preferences - * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.). - * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary. - * - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error. - * - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary. - * - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection. - * - * @class Represents a Read Preference. - * @param {String} the read preference type - * @param {Object} tags - * @return {ReadPreference} - */ -var ReadPreference = function(mode, tags) { - if(!(this instanceof ReadPreference)) - return new ReadPreference(mode, tags); - this._type = 'ReadPreference'; - this.mode = mode; - this.tags = tags; -} - -/** - * @ignore - */ -ReadPreference.isValid = function(_mode) { - return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED - || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED - || _mode == ReadPreference.NEAREST); -} - -/** - * @ignore - */ -ReadPreference.prototype.isValid = function(mode) { - var _mode = typeof mode == 'string' ? mode : this.mode; - return ReadPreference.isValid(_mode); -} - -/** - * @ignore - */ -ReadPreference.prototype.toObject = function() { - var object = {mode:this.mode}; - - if(this.tags != null) { - object['tags'] = this.tags; - } - - return object; -} - -/** - * @ignore - */ -ReadPreference.PRIMARY = 'primary'; -ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred'; -ReadPreference.SECONDARY = 'secondary'; -ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred'; -ReadPreference.NEAREST = 'nearest' - -/** - * @ignore - */ -exports.ReadPreference = ReadPreference; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js deleted file mode 100644 index 92171a6e450..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/repl_set.js +++ /dev/null @@ -1,1471 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - debug = require('util').debug, - inherits = require('util').inherits, - inspect = require('util').inspect, - Server = require('./server').Server, - PingStrategy = require('./strategies/ping_strategy').PingStrategy, - StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy, - Base = require('./base').Base; - -const STATE_STARTING_PHASE_1 = 0; -const STATE_PRIMARY = 1; -const STATE_SECONDARY = 2; -const STATE_RECOVERING = 3; -const STATE_FATAL_ERROR = 4; -const STATE_STARTING_PHASE_2 = 5; -const STATE_UNKNOWN = 6; -const STATE_ARBITER = 7; -const STATE_DOWN = 8; -const STATE_ROLLBACK = 9; - -/** - * ReplSet constructor provides replicaset functionality - * - * Options - * - **ha** {Boolean, default:true}, turn on high availability. - * - **haInterval** {Number, default:2000}, time between each replicaset status check. - * - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect. - * - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect. - * - **rs_name** {String}, the name of the replicaset to connect to. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strategy** {String, default:'ping'}, selection strategy for reads choose between (ping, statistical and none, default is ping) - * - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms) - * - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - * @class Represents a Replicaset Configuration - * @param {Array} list of server objects participating in the replicaset. - * @param {Object} [options] additional options for the replicaset connection. - */ -var ReplSet = exports.ReplSet = function(servers, options) { - this.count = 0; - - // Set up basic - if(!(this instanceof ReplSet)) - return new ReplSet(servers, options); - - // Set up event emitter - Base.call(this); - - // Ensure no Mongos's - for(var i = 0; i < servers.length; i++) { - if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server"); - } - - // Just reference for simplicity - var self = this; - // Contains the master server entry - this.options = options == null ? {} : options; - this.reconnectWait = this.options["reconnectWait"] != null ? this.options["reconnectWait"] : 1000; - this.retries = this.options["retries"] != null ? this.options["retries"] : 30; - this.replicaSet = this.options["rs_name"]; - - // Are we allowing reads from secondaries ? - this.readSecondary = this.options["read_secondary"]; - this.slaveOk = true; - this.closedConnectionCount = 0; - this._used = false; - - // Connect arbiters ? - this.connectArbiter = this.options.connectArbiter == null ? false : this.options.connectArbiter; - - // Default poolSize for new server instances - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this._currentServerChoice = 0; - - // Set up ssl connections - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Internal state of server connection - this._serverState = 'disconnected'; - // Read preference - this._readPreference = null; - // HA running - this._haRunning = false; - // Do we record server stats or not - this.recordQueryStats = false; - // Update health try server - this.updateHealthServerTry = 0; - - // Get the readPreference - var readPreference = this.options['readPreference']; - - // Validate correctness of Read preferences - if(readPreference != null) { - if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED - && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED - && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("Illegal readPreference mode specified, " + readPreference); - } - - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Ensure read_secondary is set correctly - if(!this.readSecondary) - this.readSecondary = this._readPreference == ReadPreference.PRIMARY - || this._readPreference == false - || this._readPreference == null ? false : true; - - // Ensure correct slave set - if(this.readSecondary) this.slaveOk = true; - - // Strategy for picking a secondary - this.secondaryAcceptableLatencyMS = this.options['secondaryAcceptableLatencyMS'] == null ? 15 : this.options['secondaryAcceptableLatencyMS']; - this.strategy = this.options['strategy']; - // Make sure strategy is one of the two allowed - if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical' && this.strategy != 'none')) - throw new Error("Only ping or statistical strategies allowed"); - if(this.strategy == null) this.strategy = 'ping'; - // Let's set up our strategy object for picking secodaries - if(this.strategy == 'ping') { - // Create a new instance - this.strategyInstance = new PingStrategy(this, this.secondaryAcceptableLatencyMS); - } else if(this.strategy == 'statistical') { - // Set strategy as statistical - this.strategyInstance = new StatisticsStrategy(this); - // Add enable query information - this.enableRecordQueryStats(true); - } - - // Set logger if strategy exists - if(this.strategyInstance) this.strategyInstance.logger = this.logger; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.debug == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Ensure all the instances are of type server and auto_reconnect is false - if(!Array.isArray(servers) || servers.length == 0) { - throw Error("The parameter must be an array of servers and contain at least one server"); - } else if(Array.isArray(servers) || servers.length > 0) { - var count = 0; - servers.forEach(function(server) { - if(server instanceof Server) count = count + 1; - // Ensure no server has reconnect on - server.options.auto_reconnect = false; - // Set up ssl options - server.ssl = self.ssl; - server.sslValidate = self.sslValidate; - server.sslCA = self.sslCA; - server.sslCert = self.sslCert; - server.sslKey = self.sslKey; - server.sslPass = self.sslPass; - server.poolSize = self.poolSize; - // Set callback store - server._callBackStore = self._callBackStore; - }); - - if(count < servers.length) { - throw Error("All server entries must be of type Server"); - } else { - this.servers = servers; - } - } - - // var deduplicate list - var uniqueServers = {}; - // De-duplicate any servers in the seed list - for(var i = 0; i < this.servers.length; i++) { - var server = this.servers[i]; - // If server does not exist set it - if(uniqueServers[server.host + ":" + server.port] == null) { - uniqueServers[server.host + ":" + server.port] = server; - } - } - - // Let's set the deduplicated list of servers - this.servers = []; - // Add the servers - for(var key in uniqueServers) { - this.servers.push(uniqueServers[key]); - } - - // Enabled ha - this.haEnabled = this.options['ha'] == null ? true : this.options['ha']; - this._haServer = null; - // How often are we checking for new servers in the replicaset - this.replicasetStatusCheckInterval = this.options['haInterval'] == null ? 5000 : this.options['haInterval']; - - // Connection timeout - this._connectTimeoutMS = this.socketOptions.connectTimeoutMS - ? this.socketOptions.connectTimeoutMS - : 1000; - // Socket connection timeout - this._socketTimeoutMS = this.socketOptions.socketTimeoutMS - ? this.socketOptions.socketTimeoutMS - : (this.replicasetStatusCheckInterval + 1000); -}; - -/** - * @ignore - */ -inherits(ReplSet, Base); - -/** - * @ignore - */ -// Allow setting the read preference at the replicaset level -ReplSet.prototype.setReadPreference = function(preference) { - // Set read preference - this._readPreference = preference; - // Ensure slaveOk is correct for secondaries read preference and tags - if((this._readPreference == ReadPreference.SECONDARY_PREFERRED - || this._readPreference == ReadPreference.SECONDARY - || this._readPreference == ReadPreference.NEAREST) - || (this._readPreference != null && typeof this._readPreference == 'object')) { - this.slaveOk = true; - } -} - -/** - * @ignore - */ -ReplSet.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -ReplSet.prototype.isMongos = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isConnected = function(read) { - if(read == null || read == ReadPreference.PRIMARY || read == false) - return this.primary != null && this._state.master != null && this._state.master.isConnected(); - - if((read == ReadPreference.PRIMARY_PREFERRED || read == ReadPreference.SECONDARY_PREFERRED || read == ReadPreference.NEAREST) - && ((this.primary != null && this._state.master != null && this._state.master.isConnected()) - || (this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0))) { - return true; - } else if(read == ReadPreference.SECONDARY) { - return this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0; - } - - // No valid connection return false - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isSetMember = function() { - return false; -} - -/** - * @ignore - */ -ReplSet.prototype.isPrimary = function(config) { - return this.readSecondary && Object.keys(this._state.secondaries).length > 0 ? false : true; -} - -/** - * @ignore - */ -ReplSet.prototype.isReadPrimary = ReplSet.prototype.isPrimary; - -/** - * @ignore - */ -ReplSet.prototype.allServerInstances = function() { - var self = this; - // If no state yet return empty - if(!self._state) return []; - // Close all the servers (concatenate entire list of servers first for ease) - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // Arbiter keys - var keys = Object.keys(self._state.arbiters); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.arbiters[keys[i]]); - } - - // Passive keys - var keys = Object.keys(self._state.passives); - // Add all arbiters - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.passives[keys[i]]); - } - - // Return complete list of all servers - return allServers; -} - -/** - * Enables high availability pings. - * - * @ignore - */ -ReplSet.prototype._enableHA = function () { - var self = this; - self._haRunning = true; - return check(); - - function ping () { - // We are disconnected stop pinging and close current connection if any - if("disconnected" == self._serverState) { - if(self._haServer != null) self._haServer.close(); - return; - } - - // Create a list of all servers we can send the ismaster command to - var allServers = self._state.master != null ? [self._state.master] : []; - - // Secondary keys - var keys = Object.keys(self._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self._state.secondaries[keys[i]]); - } - - // If no servers quit as are probably connecting - if(allServers.length == 0) return; - // Pick one of the servers - self.updateHealthServerTry = self.updateHealthServerTry++ % allServers.length; - var selectedServer = allServers[self.updateHealthServerTry]; - - // If we have an active db instance - if(self.dbInstances.length > 0) { - var db = self.dbInstances[0]; - - // We have an instance already - if(self._haServer == null) { - // Create a new master connection - self._haServer = new Server(selectedServer.host, selectedServer.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { - connectTimeoutMS: self._connectTimeoutMS, - socketTimeoutMS: self._socketTimeoutMS - }, - ssl: self.ssl, - sslValidate: self.sslValidate, - sslCA: self.sslCA, - sslCert: self.sslCert, - sslKey: self.sslKey, - sslPass: self.sslPass - }); - - self._haServer._callBackStore = self._callBackStore; - - // Add error handlers - self._haServer.on("close", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - self._haServer.on("error", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - self._haServer.on("timeout", function() { - if(self._haServer) self._haServer.close(); - self._haServer = null; - }); - - // Connect using the new _server connection to not impact the driver - // behavior on any errors we could possibly run into - self._haServer.connect(db, function(err, result, _server) { - if("disconnected" == self._serverState) { - if(_server && _server.close) _server.close(); - self._haRunning = false; - return; - } - - if(err) { - if(_server && _server.close) _server.close(); - return check(); - } - - executeMasterCommand(db, _server); - }); - } else { - executeMasterCommand(db, self._haServer); - } - } - } - - function executeMasterCommand(db, _server) { - try { - // Create is master command - var cmd = DbCommand.createIsMasterCommand(db); - // Execute is master command - db._executeQueryCommand(cmd, {failFast:true, connection: _server.checkoutReader()}, function(err, res) { - if("disconnected" == self._serverState) { - if(_server && _server.close) _server.close(); - self._haRunning = false; - self._haServer = null; - return; - } - // If error let's set perform another check - if(err) { - // Force new server selection - self._haServer = null; - return check(); - } - // Validate the replicaset - self._validateReplicaset(res, db.auths, function() { - check(); - }); - }); - } catch(err) { - if(self._haServer) self._haServer.close(); - self._haServer = null; - check(); - } - } - - function check() { - self._haTimer = setTimeout(ping, self.replicasetStatusCheckInterval); - } -} - -/** - * @ignore - */ -ReplSet.prototype._validateReplicaset = function(result, auths, cb) { - var self = this; - var res = result.documents[0]; - - // manage master node changes - if(res.primary && self._state.master && self._state.master.name != res.primary) { - // Delete master record so we can rediscover it - delete self._state.addresses[self._state.master.name]; - - // TODO existing issue? this seems to only work if - // we already have a connection to the new primary. - - // Update information on new primary - // add as master, remove from secondary - var newMaster = self._state.addresses[res.primary]; - newMaster.isMasterDoc.ismaster = true; - newMaster.isMasterDoc.secondary = false; - self._state.master = newMaster; - delete self._state.secondaries[res.primary]; - } - - // discover new hosts - var hosts = []; - - for(var i = 0; i < res.hosts.length; ++i) { - var host = res.hosts[i]; - if (host == res.me) continue; - if (!(self._state.addresses[host] || ~hosts.indexOf(host))) { - // we dont already have a connection to this host and aren't - // already planning on connecting. - hosts.push(host); - } - } - - connectTo(hosts, auths, self, cb); -} - -/** - * Create connections to all `hosts` firing `cb` after - * connections are attempted for all `hosts`. - * - * @param {Array} hosts - * @param {Array} [auths] - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectTo(hosts, auths, replset, cb) { - var pending = hosts.length; - if (!pending) return cb(); - - for(var i = 0; i < hosts.length; ++i) { - connectToHost(hosts[i], auths, replset, handle); - } - - function handle () { - --pending; - if (0 === pending) cb(); - } -} - -/** - * Attempts connection to `host` and authenticates with optional `auth` - * for the given `replset` firing `cb` when finished. - * - * @param {String} host - * @param {Array} auths - * @param {ReplSet} replset - * @param {Function} cb - * @ignore - */ -function connectToHost(host, auths, replset, cb) { - var server = createServer(host, replset); - - var options = { - returnIsMasterResults: true, - eventReceiver: server - } - - server.connect(replset.db, options, function(err, result) { - var doc = result && result.documents && result.documents[0]; - - if (err || !doc) { - server.close(); - return cb(err, result, server); - } - - if(!(doc.ismaster || doc.secondary || doc.arbiterOnly)) { - server.close(); - return cb(null, result, server); - } - - // if host is an arbiter, disconnect if not configured for it - if(doc.arbiterOnly && !replset.connectArbiter) { - server.close(); - return cb(null, result, server); - } - - // create handler for successful connections - var handleConnect = _connectHandler(replset, null, server); - function complete () { - handleConnect(err, result); - cb(); - } - - // authenticate if necessary - if(!(Array.isArray(auths) && auths.length > 0)) { - return complete(); - } - - var pending = auths.length; - - var connections = server.allRawConnections(); - var pendingAuthConn = connections.length; - for(var x = 0; x 0) { - self.db.emit(event, err); - } - - // If it's the primary close all connections - if(self._state.master - && self._state.master.host == server.host - && self._state.master.port == server.port) { - // return self.close(); - self._state.master = null; - } - } -} - -var _connectHandler = function(self, candidateServers, instanceServer) { - return function(err, result) { - // If we have an ssl error store the error - if(err && err.ssl) { - self._sslError = err; - } - - // We are disconnected stop attempting reconnect or connect - if(self._serverState == 'disconnected') return instanceServer.close(); - - // If no error handle isMaster - if(err == null && result.documents[0].hosts != null) { - // Fetch the isMaster command result - var document = result.documents[0]; - // Break out the results - var setName = document.setName; - var isMaster = document.ismaster; - var secondary = document.secondary; - var passive = document.passive; - var arbiterOnly = document.arbiterOnly; - var hosts = Array.isArray(document.hosts) ? document.hosts : []; - var arbiters = Array.isArray(document.arbiters) ? document.arbiters : []; - var passives = Array.isArray(document.passives) ? document.passives : []; - var tags = document.tags ? document.tags : {}; - var primary = document.primary; - // Find the current server name and fallback if none - var userProvidedServerString = instanceServer.host + ":" + instanceServer.port; - var me = document.me || userProvidedServerString; - - // Verify if the set name is the same otherwise shut down and return an error - if(self.replicaSet == null) { - self.replicaSet = setName; - } else if(self.replicaSet != setName) { - // Stop the set - self.close(); - // Emit a connection error - return self.emit("connectionError", - new Error("configured mongodb replicaset does not match provided replicaset [" + setName + "] != [" + self.replicaSet + "]")) - } - - // Make sure we have the right reference - var oldServer = self._state.addresses[userProvidedServerString] - if (oldServer && oldServer !== instanceServer) oldServer.close(); - delete self._state.addresses[userProvidedServerString]; - - if (self._state.addresses[me] && self._state.addresses[me] !== instanceServer) { - self._state.addresses[me].close(); - } - - self._state.addresses[me] = instanceServer; - - // Let's add the server to our list of server types - if(secondary == true && (passive == false || passive == null)) { - self._state.secondaries[me] = instanceServer; - } else if(arbiterOnly == true) { - self._state.arbiters[me] = instanceServer; - } else if(secondary == true && passive == true) { - self._state.passives[me] = instanceServer; - } else if(isMaster == true) { - self._state.master = instanceServer; - } else if(isMaster == false && primary != null && self._state.addresses[primary]) { - self._state.master = self._state.addresses[primary]; - } - - // Set the name - instanceServer.name = me; - // Add tag info - instanceServer.tags = tags; - - // Add the handlers to the instance - instanceServer.on("close", _handler("close", self)); - instanceServer.on("error", _handler("error", self)); - instanceServer.on("timeout", _handler("timeout", self)); - - // Possible hosts - var possibleHosts = Array.isArray(hosts) ? hosts.slice() : []; - possibleHosts = Array.isArray(passives) ? possibleHosts.concat(passives) : possibleHosts; - - if(self.connectArbiter == true) { - possibleHosts = Array.isArray(arbiters) ? possibleHosts.concat(arbiters) : possibleHosts; - } - - if(Array.isArray(candidateServers)) { - // Add any new candidate servers for connection - for(var j = 0; j < possibleHosts.length; j++) { - if(self._state.addresses[possibleHosts[j]] == null && possibleHosts[j] != null) { - var parts = possibleHosts[j].split(/:/); - if(parts.length == 1) { - parts = [parts[0], Connection.DEFAULT_PORT]; - } - - // New candidate server - var candidateServer = new Server(parts[0], parseInt(parts[1])); - candidateServer._callBackStore = self._callBackStore; - candidateServer.name = possibleHosts[j]; - candidateServer.ssl = self.ssl; - candidateServer.sslValidate = self.sslValidate; - candidateServer.sslCA = self.sslCA; - candidateServer.sslCert = self.sslCert; - candidateServer.sslKey = self.sslKey; - candidateServer.sslPass = self.sslPass; - - // Set the candidate server - self._state.addresses[possibleHosts[j]] = candidateServer; - // Add the new server to the list of candidate servers - candidateServers.push(candidateServer); - } - } - } - } else if(err != null || self._serverState == 'disconnected'){ - delete self._state.addresses[instanceServer.host + ":" + instanceServer.port]; - // Remove it from the set - instanceServer.close(); - } - - // Attempt to connect to the next server - if(Array.isArray(candidateServers) && candidateServers.length > 0) { - var server = candidateServers.pop(); - - // Get server addresses - var addresses = self._state.addresses; - - // Default empty socket options object - var socketOptions = {}; - - // Set fast connect timeout - socketOptions['connectTimeoutMS'] = self._connectTimeoutMS; - - // If a socket option object exists clone it - if(self.socketOptions != null && typeof self.socketOptions === 'object') { - var keys = Object.keys(self.socketOptions); - for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = self.socketOptions[keys[j]]; - } - - // If ssl is specified - if(self.ssl) server.ssl = true; - - // Add host information to socket options - socketOptions['host'] = server.host; - socketOptions['port'] = server.port; - server.socketOptions = socketOptions; - server.replicasetInstance = self; - server.enableRecordQueryStats(self.recordQueryStats); - - // Set the server - if (addresses[server.host + ":" + server.port] != server) { - if (addresses[server.host + ":" + server.port]) { - // Close the connection before deleting - addresses[server.host + ":" + server.port].close(); - } - delete addresses[server.host + ":" + server.port]; - } - - addresses[server.host + ":" + server.port] = server; - // Connect - server.connect(self.db, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(self, candidateServers, server)); - } else if(Array.isArray(candidateServers)) { - // If we have no primary emit error - if(self._state.master == null) { - // Stop the set - self.close(); - - // If we have an ssl error send the message instead of no primary found - if(self._sslError) { - return self.emit("connectionError", self._sslError); - } - - // Emit a connection error - return self.emit("connectionError", - new Error("no primary server found in set")) - } else{ - if(self.strategyInstance) { - self.strategyInstance.start(); - } - - for(var i = 0; i < self.dbInstances.length; i++) self.dbInstances[i]._state = 'connected'; - self.emit("fullsetup", null, self.db, self); - self.emit("open", null, self.db, self); - } - } - } -} - -var _fullsetup_emitted = false; - -/** - * Interval state object constructor - * - * @ignore - */ -ReplSet.State = function ReplSetState () { - this.errorMessages = []; - this.secondaries = {}; - this.addresses = {}; - this.arbiters = {}; - this.passives = {}; - this.members = []; - this.errors = {}; - this.setName = null; - this.master = null; -} - -/** - * @ignore - */ -ReplSet.prototype.connect = function(parent, options, callback) { - var self = this; - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Ensure it's all closed - self.close(); - - // Set connecting status - this.db = parent; - this._serverState = 'connecting'; - this._callbackList = []; - - this._state = new ReplSet.State(); - - // Ensure parent can do a slave query if it's set - parent.slaveOk = this.slaveOk - ? this.slaveOk - : parent.slaveOk; - - // Remove any listeners - this.removeAllListeners("fullsetup"); - this.removeAllListeners("connectionError"); - - // Add primary found event handler - this.once("fullsetup", function() { - self._handleOnFullSetup(parent); - - // Callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(null, parent, self); - } - }); - - this.once("connectionError", function(err) { - self._serverState = 'disconnected'; - // Ensure it's all closed - self.close(); - // Perform the callback - if(typeof callback == 'function') { - var internalCallback = callback; - callback = null; - internalCallback(err, parent, self); - } - }); - - // Get server addresses - var addresses = this._state.addresses; - - // De-duplicate any servers - var server, key; - for(var i = 0; i < this.servers.length; i++) { - server = this.servers[i]; - key = server.host + ":" + server.port; - if(null == addresses[key]) { - addresses[key] = server; - } - } - - // Get the list of servers that is deduplicated and start connecting - var candidateServers = []; - var keys = Object.keys(addresses); - for(var i = 0; i < keys.length; i++) { - server = addresses[keys[i]]; - server.assignReplicaSet(this); - candidateServers.push(server); - } - - // Let's connect to the first one on the list - server = candidateServers.pop(); - var opts = { - returnIsMasterResults: true, - eventReceiver: server - } - - server.connect(parent, opts, _connectHandler(self, candidateServers, server)); -} - -/** - * Handles the first `fullsetup` event of this ReplSet. - * - * @param {Db} parent - * @ignore - */ -ReplSet.prototype._handleOnFullSetup = function (parent) { - this._serverState = 'connected'; - for(var i = 0; i < this.dbInstances.length; i++) this.dbInstances[i]._state = 'connected'; - if(parent._state) parent._state = 'connected'; - // Emit the fullsetup and open event - parent.emit("open", null, this.db, this); - parent.emit("fullsetup", null, this.db, this); - - if(!this.haEnabled) return; - if(this._haRunning) return; - this._enableHA(); -} - -/** - * Disables high availability pings. - * - * @ignore - */ -ReplSet.prototype._disableHA = function () { - clearTimeout(this._haTimer); - this._haTimer = undefined; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutWriter = function() { - // Establish connection - var connection = this._state.master != null ? this._state.master.checkoutWriter() : null; - // Return the connection - return connection; -} - -/** - * @ignore - */ -var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) { - var keys = Object.keys(self._state.secondaries); - var connection; - - // Find first available reader if any - for(var i = 0; i < keys.length; i++) { - connection = self._state.secondaries[keys[i]].checkoutReader(); - if(connection) return connection; - } - - // If we still have a null, read from primary if it's not secondary only - if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) { - connection = self._state.master.checkoutReader(); - if(connection) return connection; - } - - var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED - ? 'secondary' - : self._readPreference; - - return new Error("No replica set member available for query with ReadPreference " - + preferenceName + " and tags " + JSON.stringify(tags)); -} - -/** - * @ignore - */ -var _pickFromTags = function(self, tags) { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Match all the servers that match the provdided tags - var keys = Object.keys(self._state.secondaries); - var candidateServers = []; - - for(var i = 0; i < keys.length; i++) { - var server = self._state.secondaries[keys[i]]; - // If we have tags match - if(server.tags != null) { - var matching = true; - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - candidateServers.push(server); - } - } - } - - // If we have a candidate server return - if(candidateServers.length > 0) { - if(this.strategyInstance) return this.strategyInstance.checkoutConnection(tags, candidateServers); - // Set instance to return - return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader(); - } - } - - // No connection found - return null; -} - -/** - * @ignore - */ -ReplSet.prototype.checkoutReader = function(readPreference, tags) { - var connection = null; - - // If we have a read preference object unpack it - if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') { - // Validate if the object is using a valid mode - if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + readPreference.mode); - // Set the tag - tags = readPreference.tags; - readPreference = readPreference.mode; - } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') { - throw new Error("read preferences must be either a string or an instance of ReadPreference"); - } - - // Set up our read Preference, allowing us to override the readPreference - var finalReadPreference = readPreference != null ? readPreference : this._readPreference; - finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference; - finalReadPreference = finalReadPreference == null ? ReadPreference.PRIMARY : finalReadPreference; - - // If we are reading from a primary - if(finalReadPreference == 'primary') { - // If we provide a tags set send an error - if(typeof tags == 'object' && tags != null) { - return new Error("PRIMARY cannot be combined with tags"); - } - - // If we provide a tags set send an error - if(this._state.master == null) { - return new Error("No replica set primary available for query with ReadPreference PRIMARY"); - } - - // Checkout a writer - return this.checkoutWriter(); - } - - // If we have specified to read from a secondary server grab a random one and read - // from it, otherwise just pass the primary connection - if((this.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - // Only pick from secondaries - var _secondaries = []; - for(var key in this._state.secondaries) { - _secondaries.push(this._state.secondaries[key]); - } - - if(finalReadPreference == ReadPreference.SECONDARY) { - // Check out the nearest from only the secondaries - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - } else { - connection = this.strategyInstance.checkoutConnection(tags, _secondaries); - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) { - // Check if there is a primary available and return that if possible - connection = this.checkoutWriter(); - // If no connection available checkout a secondary - if(connection == null) { - // If we have tags, look for servers matching the specific tag - if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - return new Error("No replica set members available for query"); - } - } else { - connection = _roundRobin(this, tags); - } - } - } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) { - // If we have tags, look for servers matching the specific tag - if(this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - // No candidate servers that match the tags, error - if(connection == null || connection instanceof Error) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - // return new Error("No replica set members available for query"); - } - } - } else if(tags != null && typeof tags == 'object') { - // Get connection - connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) { - // No candidate servers that match the tags, error - if(connection == null) { - // No secondary server avilable, attemp to checkout a primary server - connection = this.checkoutWriter(); - // If no connection return an error - if(connection == null) { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - // return new Error("No replica set members available for query"); - } - } - } - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) { - connection = this.strategyInstance.checkoutConnection(tags); - } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) { - return new Error("A strategy for calculating nearness must be enabled such as ping or statistical"); - } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) { - if(tags != null && typeof tags == 'object') { - var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference; - connection = new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags)); - } else { - connection = new Error("No replica set secondary available for query with ReadPreference SECONDARY"); - } - } else { - connection = this.checkoutWriter(); - } - - // Return the connection - return connection; -} - -/** - * Pick a secondary using round robin - * - * @ignore - */ -function _roundRobin (replset, tags) { - var keys = Object.keys(replset._state.secondaries); - var key = keys[replset._currentServerChoice++ % keys.length]; - - var conn = null != replset._state.secondaries[key] - ? replset._state.secondaries[key].checkoutReader() - : null; - - // If connection is null fallback to first available secondary - if (null == conn) { - conn = pickFirstConnectedSecondary(replset, tags); - } - - return conn; -} - -/** - * @ignore - */ -ReplSet.prototype.allRawConnections = function() { - // Neeed to build a complete list of all raw connections, start with master server - var allConnections = []; - if(this._state.master == null) return []; - // Get connection object - var allMasterConnections = this._state.master.connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(allMasterConnections); - // If we have read secondary let's add all secondary servers - if(Object.keys(this._state.secondaries).length > 0) { - // Get all the keys - var keys = Object.keys(this._state.secondaries); - // For each of the secondaries grab the connections - for(var i = 0; i < keys.length; i++) { - // Get connection object - var secondaryPoolConnections = this._state.secondaries[keys[i]].connectionPool.getAllConnections(); - // Add all connections to list - allConnections = allConnections.concat(secondaryPoolConnections); - } - } - - // Return all the conections - return allConnections; -} - -/** - * @ignore - */ -ReplSet.prototype.enableRecordQueryStats = function(enable) { - // Set the global enable record query stats - this.recordQueryStats = enable; - // Ensure all existing servers already have the flag set, even if the - // connections are up already or we have not connected yet - if(this._state != null && this._state.addresses != null) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances and set the enableRecordQueryStats flag - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].enableRecordQueryStats(enable); - } - } else if(Array.isArray(this.servers)) { - for(var i = 0; i < this.servers.length; i++) { - this.servers[i].enableRecordQueryStats(enable); - } - } -} - -/** - * @ignore - */ -ReplSet.prototype.disconnect = function(callback) { - this.close(callback); -} - -/** - * @ignore - */ -ReplSet.prototype.close = function(callback) { - var self = this; - // Disconnect - this._serverState = 'disconnected'; - // Close all servers - if(this._state && this._state.addresses) { - var keys = Object.keys(this._state.addresses); - // Iterate over all server instances - for(var i = 0; i < keys.length; i++) { - this._state.addresses[keys[i]].close(); - } - } - - // If we have a strategy stop it - if(this.strategyInstance) { - this.strategyInstance.stop(); - } - // Shut down HA if running connection - if(this._haServer) this._haServer.close(); - - // If it's a callback - if(typeof callback == 'function') callback(null, null); -} - -/** - * Auto Reconnect property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "autoReconnect", { enumerable: true - , get: function () { - return true; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return ReadPreference.SECONDARY_PREFERRED; - } else if(this._readPreference == null && !this.readSecondary) { - return ReadPreference.PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * Db Instances - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "dbInstances", {enumerable:true - , get: function() { - var servers = this.allServerInstances(); - return servers.length > 0 ? servers[0].dbInstances : []; - } -}) - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "host", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.host; - } -}); - -/** - * Just make compatible with server.js - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "port", { enumerable: true - , get: function () { - if (this.primary != null) return this.primary.port; - } -}); - -/** - * Get status of read - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "read", { enumerable: true - , get: function () { - return this.secondaries.length > 0 ? this.secondaries[0] : null; - } -}); - -/** - * Get list of secondaries - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.secondaries); - var array = new Array(keys.length); - // Convert secondaries to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.secondaries[keys[i]]; - } - return array; - } -}); - -/** - * Get list of all secondaries including passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "allSecondaries", {enumerable: true - , get: function() { - return this.secondaries.concat(this.passives); - } -}); - -/** - * Get list of arbiters - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.arbiters); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.arbiters[keys[i]]; - } - return array; - } -}); - -/** - * Get list of passives - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "passives", {enumerable: true - , get: function() { - var keys = Object.keys(this._state.passives); - var array = new Array(keys.length); - // Convert arbiters to array - for(var i = 0; i < keys.length; i++) { - array[i] = this._state.passives[keys[i]]; - } - return array; - } -}); - -/** - * Master connection property - * @ignore - */ -Object.defineProperty(ReplSet.prototype, "primary", { enumerable: true - , get: function () { - return this._state != null ? this._state.master : null; - } -}); - -/** - * @ignore - */ -// Backward compatibility -exports.ReplSetServers = ReplSet; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js deleted file mode 100644 index 20392fa0af4..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/server.js +++ /dev/null @@ -1,905 +0,0 @@ -var Connection = require('./connection').Connection, - ReadPreference = require('./read_preference').ReadPreference, - DbCommand = require('../commands/db_command').DbCommand, - MongoReply = require('../responses/mongo_reply').MongoReply, - ConnectionPool = require('./connection_pool').ConnectionPool, - EventEmitter = require('events').EventEmitter, - Base = require('./base').Base, - utils = require('../utils'), - timers = require('timers'), - inherits = require('util').inherits; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * Class representing a single MongoDB Server connection - * - * Options - * - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST) - * - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support) - * - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher) - * - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher) - * - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons. - * - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number)) - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - **auto_reconnect** {Boolean, default:false}, reconnect on error. - * - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big - * - * @class Represents a Server connection. - * @param {String} host the server host - * @param {Number} port the server port - * @param {Object} [options] optional options for insert command - */ -function Server(host, port, options) { - // Set up Server instance - if(!(this instanceof Server)) return new Server(host, port, options); - - // Set up event emitter - Base.call(this); - - // Ensure correct values - if(port != null && typeof port == 'object') { - options = port; - port = Connection.DEFAULT_PORT; - } - - var self = this; - this.host = host; - this.port = port; - this.options = options == null ? {} : options; - this.internalConnection; - this.internalMaster = false; - this.connected = false; - this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize; - this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false; - this.slaveOk = this.options["slave_ok"] ? this.options["slave_ok"] : this.options["slaveOk"]; - this._used = false; - this.replicasetInstance = null; - - // Set ssl as connection method - this.ssl = this.options.ssl == null ? false : this.options.ssl; - // Set ssl validation - this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null; - // Certificate to present to the server - this.sslCert = this.options.sslCert; - // Certificate private key if in separate file - this.sslKey = this.options.sslKey; - // Password to unlock private key - this.sslPass = this.options.sslPass; - - // Ensure we are not trying to validate with no list of certificates - if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) { - throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate"); - } - - // Get the readPreference - var readPreference = this.options['readPreference']; - // If readPreference is an object get the mode string - var validateReadPreference = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - // Read preference setting - if(validateReadPreference != null) { - if(validateReadPreference != ReadPreference.PRIMARY && validateReadPreference != ReadPreference.SECONDARY && validateReadPreference != ReadPreference.NEAREST - && validateReadPreference != ReadPreference.SECONDARY_PREFERRED && validateReadPreference != ReadPreference.PRIMARY_PREFERRED) { - throw new Error("Illegal readPreference mode specified, " + validateReadPreference); - } - - // Set read Preference - this._readPreference = readPreference; - } else { - this._readPreference = null; - } - - // Contains the isMaster information returned from the server - this.isMasterDoc; - - // Set default connection pool options - this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {}; - if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck; - - // Set ssl up if it's defined - if(this.ssl) { - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Set up logger if any set - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]}; - // Internal state of server connection - this._serverState = 'disconnected'; - // this._timeout = false; - // Contains state information about server connection - this._state = {'runtimeStats': {'queryStats':new RunningStats()}}; - // Do we record server stats or not - this.recordQueryStats = false; -}; - -/** - * @ignore - */ -inherits(Server, Base); - -// -// Deprecated, USE ReadPreferences class -// -Server.READ_PRIMARY = ReadPreference.PRIMARY; -Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED; -Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY; - -/** - * Always ourselves - * @ignore - */ -Server.prototype.setReadPreference = function() {} - -/** - * @ignore - */ -Server.prototype.isMongos = function() { - return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false; -} - -/** - * @ignore - */ -Server.prototype._isUsed = function() { - return this._used; -} - -/** - * @ignore - */ -Server.prototype.close = function(callback) { - // Remove all local listeners - this.removeAllListeners(); - - if(this.connectionPool != null) { - // Remove all the listeners on the pool so it does not fire messages all over the place - this.connectionPool.removeAllEventListeners(); - // Close the connection if it's open - this.connectionPool.stop(true); - } - - // Set server status as disconnected - this._serverState = 'disconnected'; - // Peform callback if present - if(typeof callback === 'function') callback(null); -}; - -/** - * @ignore - */ -Server.prototype.isConnected = function() { - return this._serverState == 'connected'; -} - -/** - * @ignore - */ -Server.prototype.allServerInstances = function() { - return [this]; -} - -/** - * @ignore - */ -Server.prototype.isSetMember = function() { - return this.replicasetInstance != null || this.mongosInstance != null; -} - -/** - * Assigns a replica set to this `server`. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.assignReplicaSet = function (replset) { - this.replicasetInstance = replset; - this.inheritReplSetOptionsFrom(replset); - this.enableRecordQueryStats(replset.recordQueryStats); -} - -/** - * Takes needed options from `replset` and overwrites - * our own options. - * - * @param {ReplSet} replset - * @ignore - */ -Server.prototype.inheritReplSetOptionsFrom = function (replset) { - this.socketOptions = {}; - this.socketOptions.connectTimeoutMS = replset._connectTimeoutMS; - - if(replset.ssl) { - // Set ssl on - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = replset.sslValidate == null ? false : replset.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(replset.sslCA) ? replset.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = replset.sslCert; - // Set certificate to present - this.socketOptions.sslKey = replset.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = replset.sslPass; - } - - // If a socket option object exists clone it - if(utils.isObject(replset.socketOptions)) { - var keys = Object.keys(replset.socketOptions); - for(var i = 0; i < keys.length; i++) - this.socketOptions[keys[i]] = replset.socketOptions[keys[i]]; - } -} - -/** - * Opens this server connection. - * - * @ignore - */ -Server.prototype.connect = function(dbInstance, options, callback) { - if('function' === typeof options) callback = options, options = {}; - if(options == null) options = {}; - if(!('function' === typeof callback)) callback = null; - - // Currently needed to work around problems with multiple connections in a pool with ssl - // TODO fix if possible - if(this.ssl == true) { - // Set up socket options for ssl - this.socketOptions.ssl = true; - // Set ssl validation - this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate; - // Set the ssl certificate authority (array of Buffer/String keys) - this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null; - // Set certificate to present - this.socketOptions.sslCert = this.sslCert; - // Set certificate to present - this.socketOptions.sslKey = this.sslKey; - // Password to unlock private key - this.socketOptions.sslPass = this.sslPass; - } - - // Let's connect - var server = this; - // Let's us override the main receiver of events - var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this; - // Save reference to dbInstance - this.db = dbInstance; // `db` property matches ReplSet and Mongos - this.dbInstances = [dbInstance]; - - // Force connection pool if there is one - if(server.connectionPool) server.connectionPool.stop(); - - // Set server state to connecting - this._serverState = 'connecting'; - // Ensure dbInstance can do a slave query if it's set - dbInstance.slaveOk = this.slaveOk ? this.slaveOk : dbInstance.slaveOk; - // Create connection Pool instance with the current BSON serializer - var connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions); - // If ssl is not enabled don't wait between the pool connections - if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null; - // Set logger on pool - connectionPool.logger = this.logger; - - // Set up a new pool using default settings - server.connectionPool = connectionPool; - - // Set basic parameters passed in - var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults; - - // Create a default connect handler, overriden when using replicasets - var connectCallback = function(err, reply) { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // If something close down the connection and removed the callback before - // proxy killed connection etc, ignore the erorr as close event was isssued - if(err != null && internalCallback == null) return; - // Internal callback - if(err != null) return internalCallback(err, null, server); - server.master = reply.documents[0].ismaster == 1 ? true : false; - server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize); - server.connectionPool.setMaxMessageSizeBytes(reply.documents[0].maxMessageSizeBytes); - // Set server as connected - server.connected = true; - // Save document returned so we can query it - server.isMasterDoc = reply.documents[0]; - - // Emit open event - _emitAcrossAllDbInstances(server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null); - - // If we have it set to returnIsMasterResults - if(returnIsMasterResults) { - internalCallback(null, reply, server); - } else { - internalCallback(null, dbInstance, server); - } - }; - - // Let's us override the main connect callback - var connectHandler = options.connectHandler == null ? connectCallback : options.connectHandler; - - // Set up on connect method - connectionPool.on("poolReady", function() { - // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks) - var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName); - // Check out a reader from the pool - var connection = connectionPool.checkoutConnection(); - // Set server state to connEcted - server._serverState = 'connected'; - - // Register handler for messages - server._registerHandler(db_command, false, connection, connectHandler); - - // Write the command out - connection.write(db_command); - }) - - // Set up item connection - connectionPool.on("message", function(message) { - // Attempt to parse the message - try { - // Create a new mongo reply - var mongoReply = new MongoReply() - // Parse the header - mongoReply.parseHeader(message, connectionPool.bson) - - // If message size is not the same as the buffer size - // something went terribly wrong somewhere - if(mongoReply.messageLength != message.length) { - // Emit the error - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server); - // Remove all listeners - server.removeAllListeners(); - } else { - var startDate = new Date().getTime(); - - // Callback instance - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - - // The command executed another request, log the handler again under that request id - if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0" - && callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) { - server._reRegisterHandler(mongoReply.requestId, callbackInfo); - } - - // Only execute callback if we have a caller - // chained is for findAndModify as it does not respect write concerns - if(callbackInfo && callbackInfo.callback && callbackInfo.info && Array.isArray(callbackInfo.info.chained)) { - // Check if callback has already been fired (missing chain command) - var chained = callbackInfo.info.chained; - var numberOfFoundCallbacks = 0; - for(var i = 0; i < chained.length; i++) { - if(server._hasHandler(chained[i])) numberOfFoundCallbacks++; - } - - // If we have already fired then clean up rest of chain and move on - if(numberOfFoundCallbacks != chained.length) { - for(var i = 0; i < chained.length; i++) { - server._removeHandler(chained[i]); - } - - // Just return from function - return; - } - - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Fetch the callback - var callbackInfo = server._findHandler(mongoReply.responseTo.toString()); - // If we have an error let's execute the callback and clean up all other - // chained commands - var firstResult = mongoReply && mongoReply.documents; - - // Check for an error, if we have one let's trigger the callback and clean up - // The chained callbacks - if(firstResult[0].err != null || firstResult[0].errmsg != null) { - // Trigger the callback for the error - server._callHandler(mongoReply.responseTo, mongoReply, null); - } else { - var chainedIds = callbackInfo.info.chained; - - if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) { - // Cleanup all other chained calls - chainedIds.pop(); - // Remove listeners - for(var i = 0; i < chainedIds.length; i++) server._removeHandler(chainedIds[i]); - // Call the handler - server._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null); - } else{ - // Add the results to all the results - for(var i = 0; i < chainedIds.length; i++) { - var handler = server._findHandler(chainedIds[i]); - // Check if we have an object, if it's the case take the current object commands and - // and add this one - if(handler.info != null) { - handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : []; - handler.info.results.push(mongoReply); - } - } - } - } - }); - } else if(callbackInfo && callbackInfo.callback && callbackInfo.info) { - // Parse the body - mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) { - if(err != null) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Remove all listeners and close the connection pool - server.removeAllListeners(); - connectionPool.stop(true); - - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - // Short cut - return; - } - - // Let's record the stats info if it's enabled - if(server.recordQueryStats == true && server._state['runtimeStats'] != null - && server._state.runtimeStats['queryStats'] instanceof RunningStats) { - // Add data point to the running statistics object - server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start); - } - - server._callHandler(mongoReply.responseTo, mongoReply, null); - }); - } - } - } catch (err) { - // Throw error in next tick - processor(function() { - throw err; - }) - } - }); - - // Handle timeout - connectionPool.on("timeout", function(err) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(err, null, server); - } else if(server.isSetMember()) { - if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server); - } else { - if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(err); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true); - } - }); - - // Handle errors - connectionPool.on("error", function(message, connection, error_options) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // Error message - var error_message = new Error(message && message.err ? message.err : message); - // Error message coming from ssl - if(error_options && error_options.ssl) error_message.ssl = true; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(error_message, null, server); - } else if(server.isSetMember()) { - if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server); - } else { - if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(error_message); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true); - } - }); - - // Handle close events - connectionPool.on("close", function() { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback == 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server); - } else { - if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true); - } - }); - - // If we have a parser error we are in an unknown state, close everything and emit - // error - connectionPool.on("parseError", function(message) { - // If pool connection is already closed - if(server._serverState === 'disconnected') return; - // Set server state to disconnected - server._serverState = 'disconnected'; - // If we have a callback return the error - if(typeof callback === 'function') { - // ensure no callbacks get called twice - var internalCallback = callback; - callback = null; - // Perform callback - internalCallback(new Error("connection closed due to parseError"), null, server); - } else if(server.isSetMember()) { - if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server); - } else { - if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server); - } - - // If we are a single server connection fire errors correctly - if(!server.isSetMember()) { - // Fire all callback errors - server.__executeAllCallbacksWithError(new Error("connection closed due to parseError")); - // Emit error - _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true); - } - }); - - // Boot up connection poole, pass in a locator of callbacks - connectionPool.start(); -} - -/** - * @ignore - */ -var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) { - // Emit close event across all db instances sharing the sockets - var allServerInstances = server.allServerInstances(); - // Fetch the first server instance - var serverInstance = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(serverInstance.dbInstances) && serverInstance.dbInstances.length >= 1) { - for(var i = 0; i < serverInstance.dbInstances.length; i++) { - var dbInstance = serverInstance.dbInstances[i]; - // Set the parent - if(resetConnection && typeof dbInstance.openCalled != 'undefined') - dbInstance.openCalled = false; - // Check if it's our current db instance and skip if it is - if(filterDb == null || filterDb.databaseName !== dbInstance.databaseName || filterDb.tag !== dbInstance.tag) { - // Only emit if there is a listener - if(dbInstance.listeners(event).length > 0) - dbInstance.emit(event, message, object); - } - } - } -} - -/** - * @ignore - */ -Server.prototype.allRawConnections = function() { - return this.connectionPool.getAllConnections(); -} - -/** - * Check if a writer can be provided - * @ignore - */ -var canCheckoutWriter = function(self, read) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } if(self.isMasterDoc['secondary'] == true) { - return new Error("Cannot write to a secondary"); - } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutWriter = function(read) { - if(read == true) return this.connectionPool.checkoutConnection(); - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutWriter(this, read); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * Check if a reader can be provided - * @ignore - */ -var canCheckoutReader = function(self) { - // We cannot write to an arbiter or secondary server - if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) { - return new Error("Cannot write to an arbiter"); - } else if(self._readPreference != null) { - // If the read preference is Primary and the instance is not a master return an error - if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) { - return new Error("Read preference is Server.PRIMARY and server is not master"); - } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) { - return new Error("Cannot read from primary when secondary only specified"); - } - } - - // Return no error - return null; -} - -/** - * @ignore - */ -Server.prototype.checkoutReader = function() { - // Check if are allowed to do a checkout (if we try to use an arbiter f.ex) - var result = canCheckoutReader(this); - // If the result is null check out a writer - if(result == null && this.connectionPool != null) { - return this.connectionPool.checkoutConnection(); - } else if(result == null) { - return null; - } else { - return result; - } -} - -/** - * @ignore - */ -Server.prototype.enableRecordQueryStats = function(enable) { - this.recordQueryStats = enable; -} - -/** - * Internal statistics object used for calculating average and standard devitation on - * running queries - * @ignore - */ -var RunningStats = function() { - var self = this; - this.m_n = 0; - this.m_oldM = 0.0; - this.m_oldS = 0.0; - this.m_newM = 0.0; - this.m_newS = 0.0; - - // Define getters - Object.defineProperty(this, "numDataValues", { enumerable: true - , get: function () { return this.m_n; } - }); - - Object.defineProperty(this, "mean", { enumerable: true - , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; } - }); - - Object.defineProperty(this, "variance", { enumerable: true - , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); } - }); - - Object.defineProperty(this, "standardDeviation", { enumerable: true - , get: function () { return Math.sqrt(this.variance); } - }); - - Object.defineProperty(this, "sScore", { enumerable: true - , get: function () { - var bottom = this.mean + this.standardDeviation; - if(bottom == 0) return 0; - return ((2 * this.mean * this.standardDeviation)/(bottom)); - } - }); -} - -/** - * @ignore - */ -RunningStats.prototype.push = function(x) { - // Update the number of samples - this.m_n = this.m_n + 1; - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if(this.m_n == 1) { - this.m_oldM = this.m_newM = x; - this.m_oldS = 0.0; - } else { - this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n; - this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM); - - // set up for next iteration - this.m_oldM = this.m_newM; - this.m_oldS = this.m_newS; - } -} - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true - , get: function () { - return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect']; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "connection", { enumerable: true - , get: function () { - return this.internalConnection; - } - , set: function(connection) { - this.internalConnection = connection; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "master", { enumerable: true - , get: function () { - return this.internalMaster; - } - , set: function(value) { - this.internalMaster = value; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "primary", { enumerable: true - , get: function () { - return this; - } -}); - -/** - * Getter for query Stats - * @ignore - */ -Object.defineProperty(Server.prototype, "queryStats", { enumerable: true - , get: function () { - return this._state.runtimeStats.queryStats; - } -}); - -/** - * @ignore - */ -Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true - , get: function () { - return this._state.runtimeStats; - } -}); - -/** - * Get Read Preference method - * @ignore - */ -Object.defineProperty(Server.prototype, "readPreference", { enumerable: true - , get: function () { - if(this._readPreference == null && this.readSecondary) { - return Server.READ_SECONDARY; - } else if(this._readPreference == null && !this.readSecondary) { - return Server.READ_PRIMARY; - } else { - return this._readPreference; - } - } -}); - -/** - * @ignore - */ -exports.Server = Server; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js deleted file mode 100644 index dff9c1260a4..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js +++ /dev/null @@ -1,290 +0,0 @@ -var Server = require("../server").Server - , format = require('util').format; - -// The ping strategy uses pings each server and records the -// elapsed time for the server so it can pick a server based on lowest -// return time for the db command {ping:true} -var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) { - this.replicaset = replicaset; - this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS; - this.state = 'disconnected'; - this.pingInterval = 5000; - // Class instance - this.Db = require("../../db").Db; - // Active db connections - this.dbs = {}; - // Logger api - this.Logger = null; -} - -// Starts any needed code -PingStrategy.prototype.start = function(callback) { - // already running? - if ('connected' == this.state) return; - - this.state = 'connected'; - - // Start ping server - this._pingServer(callback); -} - -// Stops and kills any processes running -PingStrategy.prototype.stop = function(callback) { - // Stop the ping process - this.state = 'disconnected'; - - // Stop all the server instances - for(var key in this.dbs) { - this.dbs[key].close(); - } - - // optional callback - callback && callback(null, null); -} - -PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - var self = this; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // Sort by ping time - finalCandidates.sort(function(a, b) { - return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs']; - }); - - if(0 === finalCandidates.length) - return new Error("No replica set members available for query"); - - // find lowest server with a ping time - var lowest = finalCandidates.filter(function (server) { - return undefined != server.runtimeStats.pingMs; - })[0]; - - if(!lowest) { - lowest = finalCandidates[0]; - } - - // convert to integer - var lowestPing = lowest.runtimeStats.pingMs | 0; - - // determine acceptable latency - var acceptable = lowestPing + this.secondaryAcceptableLatencyMS; - - // remove any server responding slower than acceptable - var len = finalCandidates.length; - while(len--) { - if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) { - finalCandidates.splice(len, 1); - } - } - - if(self.logger && self.logger.debug) { - self.logger.debug("Ping strategy selection order for tags", tags); - finalCandidates.forEach(function(c) { - self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null); - }) - } - - // If no candidates available return an error - if(finalCandidates.length == 0) - return new Error("No replica set members available for query"); - - // Pick a random acceptable server - var connection = finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); - if(self.logger && self.logger.debug) { - if(connection) - self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port); - } - return connection; -} - -PingStrategy.prototype._pingServer = function(callback) { - var self = this; - - // Ping server function - var pingFunction = function() { - if(self.state == 'disconnected') return; - - // Create a list of all servers we can send the ismaster command to - var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : []; - - // Secondary keys - var keys = Object.keys(self.replicaset._state.secondaries); - // Add all secondaries - for(var i = 0; i < keys.length; i++) { - allServers.push(self.replicaset._state.secondaries[keys[i]]); - } - - // Number of server entries - var numberOfEntries = allServers.length; - - // We got keys - for(var i = 0; i < allServers.length; i++) { - - // We got a server instance - var server = allServers[i]; - - // Create a new server object, avoid using internal connections as they might - // be in an illegal state - new function(serverInstance) { - var _db = self.dbs[serverInstance.host + ":" + serverInstance.port]; - // If we have a db - if(_db != null) { - // Startup time of the command - var startTime = Date.now(); - - // Execute ping command in own scope - var _ping = function(__db, __serverInstance) { - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }; - // Ping - _ping(_db, serverInstance); - } else { - // Create a new master connection - var _server = new Server(serverInstance.host, serverInstance.port, { - auto_reconnect: false, - returnIsMasterResults: true, - slaveOk: true, - poolSize: 1, - socketOptions: { connectTimeoutMS: self.replicaset._connectTimeoutMS }, - ssl: self.replicaset.ssl, - sslValidate: self.replicaset.sslValidate, - sslCA: self.replicaset.sslCA, - sslCert: self.replicaset.sslCert, - sslKey: self.replicaset.sslKey, - sslPass: self.replicaset.sslPass - }); - - // Create Db instance - var _db = new self.Db(self.replicaset.db.databaseName, _server, { safe: true }); - _db.on("close", function() { - delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port]; - }) - - var _ping = function(__db, __serverInstance) { - if(self.state == 'disconnected') { - self.stop(); - return; - } - - __db.open(function(err, db) { - if(self.state == 'disconnected' && __db != null) { - return __db.close(); - } - - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - // Save instance - self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db; - - // Startup time of the command - var startTime = Date.now(); - - // Execute ping on this connection - __db.executeDbCommand({ping:1}, {failFast:true}, function(err) { - if(err) { - delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port]; - __db.close(); - return done(); - } - - if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) { - __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime; - } - - done(); - }); - }); - }; - - _ping(_db, serverInstance); - } - - function done() { - // Adjust the number of checks - numberOfEntries--; - - // If we are done with all results coming back trigger ping again - if(0 === numberOfEntries && 'connected' == self.state) { - setTimeout(pingFunction, self.pingInterval); - } - } - }(server); - } - } - - // Start pingFunction - pingFunction(); - - callback && callback(null); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js deleted file mode 100644 index f9b8c46433c..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js +++ /dev/null @@ -1,80 +0,0 @@ -// The Statistics strategy uses the measure of each end-start time for each -// query executed against the db to calculate the mean, variance and standard deviation -// and pick the server which the lowest mean and deviation -var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) { - this.replicaset = replicaset; - // Logger api - this.Logger = null; -} - -// Starts any needed code -StatisticsStrategy.prototype.start = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.stop = function(callback) { - callback && callback(null, null); -} - -StatisticsStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) { - // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS - // Create a list of candidat servers, containing the primary if available - var candidateServers = []; - - // If we have not provided a list of candidate servers use the default setup - if(!Array.isArray(secondaryCandidates)) { - candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : []; - // Add all the secondaries - var keys = Object.keys(this.replicaset._state.secondaries); - for(var i = 0; i < keys.length; i++) { - candidateServers.push(this.replicaset._state.secondaries[keys[i]]) - } - } else { - candidateServers = secondaryCandidates; - } - - // Final list of eligable server - var finalCandidates = []; - - // If we have tags filter by tags - if(tags != null && typeof tags == 'object') { - // If we have an array or single tag selection - var tagObjects = Array.isArray(tags) ? tags : [tags]; - // Iterate over all tags until we find a candidate server - for(var _i = 0; _i < tagObjects.length; _i++) { - // Grab a tag object - var tagObject = tagObjects[_i]; - // Matching keys - var matchingKeys = Object.keys(tagObject); - // Remove any that are not tagged correctly - for(var i = 0; i < candidateServers.length; i++) { - var server = candidateServers[i]; - // If we have tags match - if(server.tags != null) { - var matching = true; - - // Ensure we have all the values - for(var j = 0; j < matchingKeys.length; j++) { - if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) { - matching = false; - break; - } - } - - // If we have a match add it to the list of matching servers - if(matching) { - finalCandidates.push(server); - } - } - } - } - } else { - // Final array candidates - var finalCandidates = candidateServers; - } - - // If no candidates available return an error - if(finalCandidates.length == 0) return new Error("No replica set members available for query"); - // Pick a random server - return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader(); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js deleted file mode 100644 index 4c13d0c273f..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/url_parser.js +++ /dev/null @@ -1,225 +0,0 @@ -var fs = require('fs'), - ReadPreference = require('./read_preference').ReadPreference; - -exports.parse = function(url, options) { - // Ensure we have a default options object if none set - options = options || {}; - // Variables - var connection_part = ''; - var auth_part = ''; - var query_string_part = ''; - var dbName = 'admin'; - - // Must start with mongodb - if(url.indexOf("mongodb://") != 0) - throw Error("URL must be in the format mongodb://user:pass@host:port/dbname"); - // If we have a ? mark cut the query elements off - if(url.indexOf("?") != -1) { - query_string_part = url.substr(url.indexOf("?") + 1); - connection_part = url.substring("mongodb://".length, url.indexOf("?")) - } else { - connection_part = url.substring("mongodb://".length); - } - - // Check if we have auth params - if(connection_part.indexOf("@") != -1) { - auth_part = connection_part.split("@")[0]; - connection_part = connection_part.split("@")[1]; - } - - // Check if the connection string has a db - if(connection_part.indexOf(".sock") != -1) { - if(connection_part.indexOf(".sock/") != -1) { - dbName = connection_part.split(".sock/")[1]; - connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length); - } - } else if(connection_part.indexOf("/") != -1) { - dbName = connection_part.split("/")[1]; - connection_part = connection_part.split("/")[0]; - } - - // Result object - var object = {}; - - // Pick apart the authentication part of the string - var authPart = auth_part || ''; - var auth = authPart.split(':', 2); - if(options['uri_decode_auth']){ - auth[0] = decodeURIComponent(auth[0]); - if(auth[1]){ - auth[1] = decodeURIComponent(auth[1]); - } - } - - // Add auth to final object if we have 2 elements - if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]}; - - // Variables used for temporary storage - var hostPart; - var urlOptions; - var servers; - var serverOptions = {socketOptions: {}}; - var dbOptions = {read_preference_tags: []}; - var replSetServersOptions = {socketOptions: {}}; - // Add server options to final object - object.server_options = serverOptions; - object.db_options = dbOptions; - object.rs_options = replSetServersOptions; - object.mongos_options = {}; - - // Let's check if we are using a domain socket - if(url.match(/\.sock/)) { - // Split out the socket part - var domainSocket = url.substring( - url.indexOf("mongodb://") + "mongodb://".length - , url.lastIndexOf(".sock") + ".sock".length); - // Clean out any auth stuff if any - if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1]; - servers = [{domain_socket: domainSocket}]; - } else { - // Split up the db - hostPart = connection_part; - // Parse all server results - servers = hostPart.split(',').map(function(h) { - var hostPort = h.split(':', 2); - var _host = hostPort[0] || 'localhost'; - var _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017; - // Check for localhost?safe=true style case - if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0]; - - // Return the mapped object - return {host: _host, port: _port}; - }); - } - - // Get the db name - object.dbName = dbName || 'admin'; - // Split up all the options - urlOptions = (query_string_part || '').split(/[&;]/); - // Ugh, we have to figure out which options go to which constructor manually. - urlOptions.forEach(function(opt) { - if(!opt) return; - var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1]; - // Options implementations - switch(name) { - case 'slaveOk': - case 'slave_ok': - serverOptions.slave_ok = (value == 'true'); - break; - case 'maxPoolSize': - case 'poolSize': - serverOptions.poolSize = parseInt(value, 10); - replSetServersOptions.poolSize = parseInt(value, 10); - break; - case 'autoReconnect': - case 'auto_reconnect': - serverOptions.auto_reconnect = (value == 'true'); - break; - case 'minPoolSize': - throw new Error("minPoolSize not supported"); - case 'maxIdleTimeMS': - throw new Error("maxIdleTimeMS not supported"); - case 'waitQueueMultiple': - throw new Error("waitQueueMultiple not supported"); - case 'waitQueueTimeoutMS': - throw new Error("waitQueueTimeoutMS not supported"); - case 'uuidRepresentation': - throw new Error("uuidRepresentation not supported"); - case 'ssl': - if(value == 'prefer') { - serverOptions.ssl = value; - replSetServersOptions.ssl = value; - break; - } - serverOptions.ssl = (value == 'true'); - replSetServersOptions.ssl = (value == 'true'); - break; - case 'replicaSet': - case 'rs_name': - replSetServersOptions.rs_name = value; - break; - case 'reconnectWait': - replSetServersOptions.reconnectWait = parseInt(value, 10); - break; - case 'retries': - replSetServersOptions.retries = parseInt(value, 10); - break; - case 'readSecondary': - case 'read_secondary': - replSetServersOptions.read_secondary = (value == 'true'); - break; - case 'fsync': - dbOptions.fsync = (value == 'true'); - break; - case 'journal': - dbOptions.journal = (value == 'true'); - break; - case 'safe': - dbOptions.safe = (value == 'true'); - break; - case 'nativeParser': - case 'native_parser': - dbOptions.native_parser = (value == 'true'); - break; - case 'connectTimeoutMS': - serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10); - break; - case 'socketTimeoutMS': - serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10); - break; - case 'w': - dbOptions.w = parseInt(value, 10); - break; - case 'authSource': - dbOptions.authSource = value; - case 'wtimeoutMS': - dbOptions.wtimeoutMS = parseInt(value, 10); - break; - case 'readPreference': - if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest"); - dbOptions.read_preference = value; - break; - case 'readPreferenceTags': - // Contains the tag object - var tagObject = {}; - if(value == null || value == '') { - dbOptions.read_preference_tags.push(tagObject); - break; - } - - // Split up the tags - var tags = value.split(/\,/); - for(var i = 0; i < tags.length; i++) { - var parts = tags[i].trim().split(/\:/); - tagObject[parts[0]] = parts[1]; - } - - // Set the preferences tags - dbOptions.read_preference_tags.push(tagObject); - break; - default: - break; - } - }); - - // No tags: should be null (not []) - if(dbOptions.read_preference_tags.length === 0) { - dbOptions.read_preference_tags = null; - } - - // Validate if there are an invalid write concern combinations - if((dbOptions.w == -1 || dbOptions.w == 0) && ( - dbOptions.journal == true - || dbOptions.fsync == true - || dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync") - - // If no read preference set it to primary - if(!dbOptions.read_preference) dbOptions.read_preference = 'primary'; - - // Add servers to result - object.servers = servers; - // Returned parsed object - return object; -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js deleted file mode 100644 index f7aa55610e5..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursor.js +++ /dev/null @@ -1,988 +0,0 @@ -var QueryCommand = require('./commands/query_command').QueryCommand, - GetMoreCommand = require('./commands/get_more_command').GetMoreCommand, - KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand, - Long = require('bson').Long, - ReadPreference = require('./connection/read_preference').ReadPreference, - CursorStream = require('./cursorstream'), - timers = require('timers'), - utils = require('./utils'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Constructor for a cursor object that handles all the operations on query result - * using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly, - * but use find to acquire a cursor. (INTERNAL TYPE) - * - * Options - * - **skip** {Number} skip number of documents to skip. - * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1. - * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. - * - **hint** {Object}, hint force the query to use a specific index. - * - **explain** {Boolean}, explain return the explaination of the query. - * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned. - * - **timeout** {Boolean}, timeout allow the query to timeout. - * - **tailable** {Boolean}, tailable allow the cursor to be tailable. - * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor. - * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database. - * - **raw** {Boolean}, raw return all query documents as raw buffers (default false). - * - **read** {Boolean}, read specify override of read from source (primary/secondary). - * - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries. - * - **returnKey** {Boolean}, returnKey only return the index key. - * - **maxScan** {Number}, maxScan limit the number of items to scan. - * - **min** {Number}, min set index bounds. - * - **max** {Number}, max set index bounds. - * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results. - * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler. - * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout. - * - **dbName** {String}, dbName override the default dbName. - * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor. - * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets. - * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos. - * - * @class Represents a Cursor. - * @param {Db} db the database object to work with. - * @param {Collection} collection the collection to query. - * @param {Object} selector the query selector. - * @param {Object} fields an object containing what fields to include or exclude from objects returned. - * @param {Object} [options] additional options for the collection. -*/ -function Cursor(db, collection, selector, fields, options) { - this.db = db; - this.collection = collection; - this.selector = selector; - this.fields = fields; - options = !options ? {} : options; - - this.skipValue = options.skip == null ? 0 : options.skip; - this.limitValue = options.limit == null ? 0 : options.limit; - this.sortValue = options.sort; - this.hint = options.hint; - this.explainValue = options.explain; - this.snapshot = options.snapshot; - this.timeout = options.timeout == null ? true : options.timeout; - this.tailable = options.tailable; - this.awaitdata = options.awaitdata; - this.numberOfRetries = options.numberOfRetries == null ? 5 : options.numberOfRetries; - this.currentNumberOfRetries = this.numberOfRetries; - this.batchSizeValue = options.batchSize == null ? 0 : options.batchSize; - this.slaveOk = options.slaveOk == null ? collection.slaveOk : options.slaveOk; - this.raw = options.raw == null ? false : options.raw; - this.read = options.read == null ? ReadPreference.PRIMARY : options.read; - this.returnKey = options.returnKey; - this.maxScan = options.maxScan; - this.min = options.min; - this.max = options.max; - this.showDiskLoc = options.showDiskLoc; - this.comment = options.comment; - this.tailableRetryInterval = options.tailableRetryInterval || 100; - this.exhaust = options.exhaust || false; - this.partial = options.partial || false; - - this.totalNumberOfRecords = 0; - this.items = []; - this.cursorId = Long.fromInt(0); - - // This name - this.dbName = options.dbName; - - // State variables for the cursor - this.state = Cursor.INIT; - // Keep track of the current query run - this.queryRun = false; - this.getMoreTimer = false; - - // If we are using a specific db execute against it - if(this.dbName != null) { - this.collectionName = this.dbName + "." + this.collection.collectionName; - } else { - this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName; - } -}; - -/** - * Resets this cursor to its initial state. All settings like the query string, - * tailable, batchSizeValue, skipValue and limits are preserved. - * - * @return {Cursor} returns itself with rewind applied. - * @api public - */ -Cursor.prototype.rewind = function() { - var self = this; - - if (self.state != Cursor.INIT) { - if (self.state != Cursor.CLOSED) { - self.close(function() {}); - } - - self.numberOfReturned = 0; - self.totalNumberOfRecords = 0; - self.items = []; - self.cursorId = Long.fromInt(0); - self.state = Cursor.INIT; - self.queryRun = false; - } - - return self; -}; - - -/** - * Returns an array of documents. The caller is responsible for making sure that there - * is enough memory to store the results. Note that the array only contain partial - * results when this cursor had been previouly accessed. In that case, - * cursor.rewind() can be used to reset the cursor. - * - * @param {Function} callback This will be called after executing this method successfully. The first parameter will contain the Error object if an error occured, or null otherwise. The second parameter will contain an array of BSON deserialized objects as a result of the query. - * @return {null} - * @api public - */ -Cursor.prototype.toArray = function(callback) { - var self = this; - - if(!callback) { - throw new Error('callback is mandatory'); - } - - if(this.tailable) { - callback(new Error("Tailable cursor cannot be converted to array"), null); - } else if(this.state != Cursor.CLOSED) { - // return toArrayExhaust(self, callback); - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return toArrayExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - self.nextObject({noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err), null); - if(self.cursorId.toString() == "0") { - self.state = Cursor.CLOSED; - return callback(null, self.items); - } - - // Let's issue getMores until we have no more records waiting - getAllByGetMore(self, function(err, done) { - self.state = Cursor.CLOSED; - if(err) return callback(utils.toError(err), null); - callback(null, self.items); - }); - }) - - } else { - callback(new Error("Cursor is closed"), null); - } -} - -var toArrayExhaust = function(self, callback) { - var items = []; - - self.each(function(err, item) { - if(err != null) { - return callback(utils.toError(err), null); - } - - if(item != null && Array.isArray(items)) { - items.push(item); - } else { - var resultItems = items; - items = null; - self.items = []; - callback(null, resultItems); - } - }); -} - -var getAllByGetMore = function(self, callback) { - getMore(self, {noReturn: true}, function(err, result) { - if(err) return callback(utils.toError(err)); - if(result == null) return callback(null, null); - if(self.cursorId.toString() == "0") return callback(null, null); - getAllByGetMore(self, callback); - }) -} - -/** - * Iterates over all the documents for this cursor. As with **{cursor.toArray}**, - * not all of the elements will be iterated if this cursor had been previouly accessed. - * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike - * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements - * at any given time if batch size is specified. Otherwise, the caller is responsible - * for making sure that the entire result can fit the memory. - * - * @param {Function} callback this will be called for while iterating every document of the query result. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the document. - * @return {null} - * @api public - */ -Cursor.prototype.each = function(callback) { - var self = this; - var fn; - - if (!callback) { - throw new Error('callback is mandatory'); - } - - if(this.state != Cursor.CLOSED) { - // If we are using exhaust we can't use the quick fire method - if(self.exhaust) return eachExhaust(self, callback); - // Quick fire using trampoline to avoid nextTick - if(this.items.length > 0) { - // Trampoline all the entries - while(fn = loop(self, callback)) fn(self, callback); - // Call each again - self.each(callback); - } else { - self.nextObject(function(err, item) { - - if(err) { - self.state = Cursor.CLOSED; - return callback(utils.toError(err), item); - } - - if(item == null) return callback(null, null); - callback(null, item); - self.each(callback); - }) - } - } else { - callback(new Error("Cursor is closed"), null); - } -} - -// Special for exhaust command as we don't initiate the actual result sets -// the server just sends them as they arrive meaning we need to get the IO event -// loop happen so we can receive more data from the socket or we return to early -// after the first fetch and loose all the incoming getMore's automatically issued -// from the server. -var eachExhaust = function(self, callback) { - //FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2) - processor(function(){ - // Fetch the next object until there is no more objects - self.nextObject(function(err, item) { - if(err != null) return callback(err, null); - if(item != null) { - callback(null, item); - eachExhaust(self, callback); - } else { - // Close the cursor if done - self.state = Cursor.CLOSED; - callback(err, null); - } - }); - }); -} - -// Trampoline emptying the number of retrieved items -// without incurring a nextTick operation -var loop = function(self, callback) { - // No more items we are done - if(self.items.length == 0) return; - // Get the next document - var doc = self.items.shift(); - // Callback - callback(null, doc); - // Loop - return loop; -} - -/** - * Determines how many result the query for this cursor will return - * - * @param {Boolean} applySkipLimit if set to true will apply the skip and limits set on the cursor. Defaults to false. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the number of results or null if an error occured. - * @return {null} - * @api public - */ -Cursor.prototype.count = function(applySkipLimit, callback) { - if(typeof applySkipLimit == 'function') { - callback = applySkipLimit; - applySkipLimit = false; - } - - var options = {}; - if(applySkipLimit) { - if(typeof this.skipValue == 'number') options.skip = this.skipValue; - if(typeof this.limitValue == 'number') options.limit = this.limitValue; - } - - // Call count command - this.collection.count(this.selector, options, callback); -}; - -/** - * Sets the sort parameter of this cursor to the given value. - * - * This method has the following method signatures: - * (keyOrList, callback) - * (keyOrList, direction, callback) - * - * @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction]. - * @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive. - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.sort = function(keyOrList, direction, callback) { - callback = callback || function(){}; - if(typeof direction === "function") { callback = direction; direction = null; } - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support sorting"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - var order = keyOrList; - - if(direction != null) { - order = [[keyOrList, direction]]; - } - - this.sortValue = order; - callback(null, this); - } - return this; -}; - -/** - * Sets the limit parameter of this cursor to the given value. - * - * @param {Number} limit the new limit. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.limit = function(limit, callback) { - if(this.tailable) { - if(callback) { - callback(new Error("Tailable cursor doesn't support limit"), null); - } else { - throw new Error("Tailable cursor doesn't support limit"); - } - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback) { - callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else { - if(limit != null && limit.constructor != Number) { - if(callback) { - callback(new Error("limit requires an integer"), null); - } else { - throw new Error("limit requires an integer"); - } - } else { - this.limitValue = limit; - if(callback) return callback(null, this); - } - } - - return this; -}; - -/** - * Sets the read preference for the cursor - * - * @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.setReadPreference = function(readPreference, tags, callback) { - if(typeof tags == 'function') callback = tags; - - var _mode = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference; - - if(this.queryRun == true || this.state == Cursor.CLOSED) { - if(callback == null) throw new Error("Cannot change read preference on executed query or closed cursor"); - callback(new Error("Cannot change read preference on executed query or closed cursor")); - } else if(_mode != null && _mode != 'primary' - && _mode != 'secondaryOnly' && _mode != 'secondary' - && _mode != 'nearest' && _mode != 'primaryPreferred' && _mode != 'secondaryPreferred') { - if(callback == null) throw new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported"); - callback(new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported")); - } else { - this.read = readPreference; - if(callback != null) callback(null, this); - } - - return this; -} - -/** - * Sets the skip parameter of this cursor to the given value. - * - * @param {Number} skip the new skip value. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.skip = function(skip, callback) { - callback = callback || function(){}; - - if(this.tailable) { - callback(new Error("Tailable cursor doesn't support skip"), null); - } else if(this.queryRun == true || this.state == Cursor.CLOSED) { - callback(new Error("Cursor is closed"), null); - } else { - if(skip != null && skip.constructor != Number) { - callback(new Error("skip requires an integer"), null); - } else { - this.skipValue = skip; - callback(null, this); - } - } - - return this; -}; - -/** - * Sets the batch size parameter of this cursor to the given value. - * - * @param {Number} batchSize the new batch size. - * @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution. - * @return {Cursor} an instance of this object. - * @api public - */ -Cursor.prototype.batchSize = function(batchSize, callback) { - if(this.state == Cursor.CLOSED) { - if(callback != null) { - return callback(new Error("Cursor is closed"), null); - } else { - throw new Error("Cursor is closed"); - } - } else if(batchSize != null && batchSize.constructor != Number) { - if(callback != null) { - return callback(new Error("batchSize requires an integer"), null); - } else { - throw new Error("batchSize requires an integer"); - } - } else { - this.batchSizeValue = batchSize; - if(callback != null) return callback(null, this); - } - - return this; -}; - -/** - * The limit used for the getMore command - * - * @return {Number} The number of records to request per batch. - * @ignore - * @api private - */ -var limitRequest = function(self) { - var requestedLimit = self.limitValue; - var absLimitValue = Math.abs(self.limitValue); - var absBatchValue = Math.abs(self.batchSizeValue); - - if(absLimitValue > 0) { - if (absBatchValue > 0) { - requestedLimit = Math.min(absLimitValue, absBatchValue); - } - } else { - requestedLimit = self.batchSizeValue; - } - - return requestedLimit; -}; - - -/** - * Generates a QueryCommand object using the parameters of this cursor. - * - * @return {QueryCommand} The command object - * @ignore - * @api private - */ -var generateQueryCommand = function(self) { - // Unpack the options - var queryOptions = QueryCommand.OPTS_NONE; - if(!self.timeout) { - queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT; - } - - if(self.tailable != null) { - queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR; - self.skipValue = self.limitValue = 0; - - // if awaitdata is set - if(self.awaitdata != null) { - queryOptions |= QueryCommand.OPTS_AWAIT_DATA; - } - } - - if(self.exhaust) { - queryOptions |= QueryCommand.OPTS_EXHAUST; - } - - if(self.slaveOk) { - queryOptions |= QueryCommand.OPTS_SLAVE; - } - - if(self.partial) { - queryOptions |= QueryCommand.OPTS_PARTIAL; - } - - // limitValue of -1 is a special case used by Db#eval - var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self); - - // Check if we need a special selector - if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null - || self.returnKey != null || self.maxScan != null || self.min != null || self.max != null - || self.showDiskLoc != null || self.comment != null) { - - // Build special selector - var specialSelector = {'$query':self.selector}; - if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue); - if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint; - if(self.snapshot != null) specialSelector['$snapshot'] = true; - if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey; - if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan; - if(self.min != null) specialSelector['$min'] = self.min; - if(self.max != null) specialSelector['$max'] = self.max; - if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc; - if(self.comment != null) specialSelector['$comment'] = self.comment; - // If we have explain set only return a single document with automatic cursor close - if(self.explainValue != null) { - numberToReturn = (-1)*Math.abs(numberToReturn); - specialSelector['$explain'] = true; - } - - // Return the query - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields); - } else { - return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields); - } -}; - -/** - * @return {Object} Returns an object containing the sort value of this cursor with - * the proper formatting that can be used internally in this cursor. - * @ignore - * @api private - */ -Cursor.prototype.formattedOrderClause = function() { - return utils.formattedOrderClause(this.sortValue); -}; - -/** - * Converts the value of the sort direction into its equivalent numerical value. - * - * @param sortDirection {String|number} Range of acceptable values: - * 'ascending', 'descending', 'asc', 'desc', 1, -1 - * - * @return {number} The equivalent numerical value - * @throws Error if the given sortDirection is invalid - * @ignore - * @api private - */ -Cursor.prototype.formatSortValue = function(sortDirection) { - return utils.formatSortValue(sortDirection); -}; - -/** - * Gets the next document from the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @api public - */ -Cursor.prototype.nextObject = function(options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.INIT) { - var cmd; - try { - cmd = generateQueryCommand(self); - } catch (err) { - return callback(err, null); - } - - // Execute command - var commandHandler = function(err, result) { - self.state = Cursor.OPEN; - if(err != null && result == null) return callback(utils.toError(err), null); - - if(!err && result.documents[0] && result.documents[0]['$err']) { - return self.close(function() {callback(utils.toError(result.documents[0]['$err']), null);}); - } - - self.queryRun = true; - self.state = Cursor.OPEN; // Adjust the state of the cursor - self.cursorId = result.cursorId; - self.totalNumberOfRecords = result.numberReturned; - - // Add the new documents to the list of items, using forloop to avoid - // new array allocations and copying - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // If we have noReturn set just return (not modifying the internal item list) - // used for toArray - if(options.noReturn) { - return callback(null, true); - } - - // Ignore callbacks until the cursor is dead for exhausted - if(self.exhaust && result.cursorId.toString() == "0") { - self.nextObject(callback); - } else if(self.exhaust == false || self.exhaust == null) { - self.nextObject(callback); - } - }; - - // If we have no connection set on this cursor check one out - if(self.connection == null) { - try { - self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read); - } catch(err) { - return callback(utils.toError(err), null); - } - } - - // Execute the command - self.db._executeQueryCommand(cmd, {exhaust: self.exhaust, raw:self.raw, read:self.read, connection:self.connection}, commandHandler); - // Set the command handler to null - commandHandler = null; - } else if(self.items.length) { - callback(null, self.items.shift()); - } else if(self.cursorId.greaterThan(Long.fromInt(0))) { - getMore(self, callback); - } else { - // Force cursor to stay open - return self.close(function() {callback(null, null);}); - } -} - -/** - * Gets more results from the database if any. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results. - * @ignore - * @api private - */ -var getMore = function(self, options, callback) { - var limit = 0; - - if(typeof options == 'function') { - callback = options; - options = {}; - } - - if(self.state == Cursor.GET_MORE) return callback(null, null); - - // Set get more in progress - self.state = Cursor.GET_MORE; - - // Set options - if (!self.tailable && self.limitValue > 0) { - limit = self.limitValue - self.totalNumberOfRecords; - if (limit < 1) { - self.close(function() {callback(null, null);}); - return; - } - } - - try { - var getMoreCommand = new GetMoreCommand( - self.db - , self.collectionName - , limitRequest(self) - , self.cursorId - ); - - // Set up options - var command_options = {read: self.read, raw: self.raw, connection:self.connection }; - - // Execute the command - self.db._executeQueryCommand(getMoreCommand, command_options, function(err, result) { - var cbValue; - - // Get more done - self.state = Cursor.OPEN; - - if(err != null) { - return callback(utils.toError(err), null); - } - - try { - var isDead = 1 === result.responseFlag && result.cursorId.isZero(); - - self.cursorId = result.cursorId; - self.totalNumberOfRecords += result.numberReturned; - - // Determine if there's more documents to fetch - if(result.numberReturned > 0) { - if (self.limitValue > 0) { - var excessResult = self.totalNumberOfRecords - self.limitValue; - - if (excessResult > 0) { - result.documents.splice(-1 * excessResult, excessResult); - } - } - - // Reset the tries for awaitdata if we are using it - self.currentNumberOfRetries = self.numberOfRetries; - // Get the documents - for(var i = 0; i < result.documents.length; i++) { - self.items.push(result.documents[i]); - } - - // Don's shift a document out as we need it for toArray - if(options.noReturn) { - cbValue = true; - } else { - cbValue = self.items.shift(); - } - } else if(self.tailable && !isDead && self.awaitdata) { - // Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used - self.currentNumberOfRetries = self.currentNumberOfRetries - 1; - if(self.currentNumberOfRetries == 0) { - self.close(function() { - callback(new Error("tailable cursor timed out"), null); - }); - } else { - getMore(self, callback); - } - } else if(self.tailable && !isDead) { - self.getMoreTimer = setTimeout(function() { getMore(self, callback); }, self.tailableRetryInterval); - } else { - self.close(function() {callback(null, null); }); - } - - result = null; - } catch(err) { - callback(utils.toError(err), null); - } - if (cbValue != null) callback(null, cbValue); - }); - - getMoreCommand = null; - } catch(err) { - // Get more done - self.state = Cursor.OPEN; - - var handleClose = function() { - callback(utils.toError(err), null); - }; - - self.close(handleClose); - handleClose = null; - } -} - -/** - * Gets a detailed information about how the query is performed on this cursor and how - * long it took the database to process it. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details. - * @api public - */ -Cursor.prototype.explain = function(callback) { - var limit = (-1)*Math.abs(this.limitValue); - - // Create a new cursor and fetch the plan - var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, { - skip: this.skipValue - , limit:limit - , sort: this.sortValue - , hint: this.hint - , explain: true - , snapshot: this.snapshot - , timeout: this.timeout - , tailable: this.tailable - , batchSize: this.batchSizeValue - , slaveOk: this.slaveOk - , raw: this.raw - , read: this.read - , returnKey: this.returnKey - , maxScan: this.maxScan - , min: this.min - , max: this.max - , showDiskLoc: this.showDiskLoc - , comment: this.comment - , awaitdata: this.awaitdata - , numberOfRetries: this.numberOfRetries - , dbName: this.dbName - }); - - // Fetch the explaination document - cursor.nextObject(function(err, item) { - if(err != null) return callback(utils.toError(err), null); - // close the cursor - cursor.close(function(err, result) { - if(err != null) return callback(utils.toError(err), null); - callback(null, item); - }); - }); -}; - -/** - * @ignore - */ -Cursor.prototype.streamRecords = function(options) { - console.log("[WARNING] streamRecords method is deprecated, please use stream method which is much faster"); - var args = Array.prototype.slice.call(arguments, 0); - options = args.length ? args.shift() : {}; - - var - self = this, - stream = new process.EventEmitter(), - recordLimitValue = this.limitValue || 0, - emittedRecordCount = 0, - queryCommand = generateQueryCommand(self); - - // see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol - queryCommand.numberToReturn = options.fetchSize ? options.fetchSize : 500; - // Execute the query - execute(queryCommand); - - function execute(command) { - self.db._executeQueryCommand(command, {exhaust: self.exhaust, read:self.read, raw:self.raw, connection:self.connection}, function(err,result) { - if(err) { - stream.emit('error', err); - self.close(function(){}); - return; - } - - if (!self.queryRun && result) { - self.queryRun = true; - self.cursorId = result.cursorId; - self.state = Cursor.OPEN; - self.getMoreCommand = new GetMoreCommand(self.db, self.collectionName, queryCommand.numberToReturn, result.cursorId); - } - - var resflagsMap = { - CursorNotFound:1<<0, - QueryFailure:1<<1, - ShardConfigStale:1<<2, - AwaitCapable:1<<3 - }; - - if(result.documents && result.documents.length && !(result.responseFlag & resflagsMap.QueryFailure)) { - try { - result.documents.forEach(function(doc){ - if(recordLimitValue && emittedRecordCount>=recordLimitValue) { - throw("done"); - } - emittedRecordCount++; - stream.emit('data', doc); - }); - } catch(err) { - if (err != "done") { throw err; } - else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - self.close(function(){}); - return; - } - } - // rinse & repeat - execute(self.getMoreCommand); - } else { - self.close(function(){ - stream.emit('end', recordLimitValue); - }); - } - }); - } - - return stream; -}; - -/** - * Returns a Node ReadStream interface for this cursor. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * @return {CursorStream} returns a stream object. - * @api public - */ -Cursor.prototype.stream = function stream(options) { - return new CursorStream(this, options); -} - -/** - * Close the cursor. - * - * @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor. - * @return {null} - * @api public - */ -Cursor.prototype.close = function(callback) { - var self = this - this.getMoreTimer && clearTimeout(this.getMoreTimer); - // Close the cursor if not needed - if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) { - try { - var command = new KillCursorCommand(this.db, [this.cursorId]); - // Added an empty callback to ensure we don't throw any null exceptions - this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function() {}); - } catch(err) {} - } - - // Null out the connection - self.connection = null; - // Reset cursor id - this.cursorId = Long.fromInt(0); - // Set to closed status - this.state = Cursor.CLOSED; - - if(callback) { - callback(null, self); - self.items = []; - } - - return this; -}; - -/** - * Check if the cursor is closed or open. - * - * @return {Boolean} returns the state of the cursor. - * @api public - */ -Cursor.prototype.isClosed = function() { - return this.state == Cursor.CLOSED ? true : false; -}; - -/** - * Init state - * - * @classconstant INIT - **/ -Cursor.INIT = 0; - -/** - * Cursor open - * - * @classconstant OPEN - **/ -Cursor.OPEN = 1; - -/** - * Cursor closed - * - * @classconstant CLOSED - **/ -Cursor.CLOSED = 2; - -/** - * Cursor performing a get more - * - * @classconstant OPEN - **/ -Cursor.GET_MORE = 3; - -/** - * @ignore - * @api private - */ -exports.Cursor = Cursor; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js deleted file mode 100644 index 27520913e2b..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/cursorstream.js +++ /dev/null @@ -1,164 +0,0 @@ -var timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; - -/** - * Module dependecies. - */ -var Stream = require('stream').Stream; - -/** - * CursorStream - * - * Returns a stream interface for the **cursor**. - * - * Options - * - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - **close** {function() {}} the end event triggers when there is no more documents available. - * - * @class Represents a CursorStream. - * @param {Cursor} cursor a cursor object that the stream wraps. - * @return {Stream} - */ -function CursorStream(cursor, options) { - if(!(this instanceof CursorStream)) return new CursorStream(cursor); - options = options ? options : {}; - - Stream.call(this); - - this.readable = true; - this.paused = false; - this._cursor = cursor; - this._destroyed = null; - this.options = options; - - // give time to hook up events - var self = this; - process.nextTick(function() { - self._init(); - }); -} - -/** - * Inherit from Stream - * @ignore - * @api private - */ -CursorStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -CursorStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -CursorStream.prototype.paused; - -/** - * Initialize the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._init = function () { - if (this._destroyed) return; - this._next(); -} - -/** - * Pull the next document from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._next = function () { - if(this.paused || this._destroyed) return; - - var self = this; - // Get the next object - processor(function() { - if(self.paused || self._destroyed) return; - - self._cursor.nextObject(function (err, doc) { - self._onNextObject(err, doc); - }); - }); -} - -/** - * Handle each document as its returned from the cursor. - * @ignore - * @api private - */ -CursorStream.prototype._onNextObject = function (err, doc) { - if(err) return this.destroy(err); - - // when doc is null we hit the end of the cursor - if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) { - this.emit('end') - return this.destroy(); - } else if(doc) { - var data = typeof this.options.transform == 'function' ? this.options.transform(doc) : doc; - this.emit('data', data); - this._next(); - } -} - -/** - * Pauses the stream. - * - * @api public - */ -CursorStream.prototype.pause = function () { - this.paused = true; -} - -/** - * Resumes the stream. - * - * @api public - */ -CursorStream.prototype.resume = function () { - var self = this; - - // Don't do anything if we are not paused - if(!this.paused) return; - if(!this._cursor.state == 3) return; - - process.nextTick(function() { - self.paused = false; - // Only trigger more fetching if the cursor is open - self._next(); - }) -} - -/** - * Destroys the stream, closing the underlying - * cursor. No more events will be emitted. - * - * @api public - */ -CursorStream.prototype.destroy = function (err) { - if (this._destroyed) return; - this._destroyed = true; - this.readable = false; - - this._cursor.close(); - - if(err) { - this.emit('error', err); - } - - this.emit('close'); -} - -// TODO - maybe implement the raw option to pass binary? -//CursorStream.prototype.setEncoding = function () { -//} - -module.exports = exports = CursorStream; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js deleted file mode 100644 index 957e43639fc..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/db.js +++ /dev/null @@ -1,2147 +0,0 @@ -/** - * Module dependencies. - * @ignore - */ -var QueryCommand = require('./commands/query_command').QueryCommand, - DbCommand = require('./commands/db_command').DbCommand, - MongoReply = require('./responses/mongo_reply').MongoReply, - Admin = require('./admin').Admin, - Collection = require('./collection').Collection, - Server = require('./connection/server').Server, - ReplSet = require('./connection/repl_set').ReplSet, - ReadPreference = require('./connection/read_preference').ReadPreference, - Mongos = require('./connection/mongos').Mongos, - Cursor = require('./cursor').Cursor, - EventEmitter = require('events').EventEmitter, - inherits = require('util').inherits, - crypto = require('crypto'), - timers = require('timers'), - utils = require('./utils'), - parse = require('./connection/url_parser').parse; - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * Create a new Db instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a Db - * @param {String} databaseName name of the database. - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function Db(databaseName, serverConfig, options) { - if(!(this instanceof Db)) return new Db(databaseName, serverConfig, options); - - EventEmitter.call(this); - this.databaseName = databaseName; - this.serverConfig = serverConfig; - this.options = options == null ? {} : options; - // State to check against if the user force closed db - this._applicationClosed = false; - // Fetch the override flag if any - var overrideUsedFlag = this.options['override_used_flag'] == null ? false : this.options['override_used_flag']; - - // Verify that nobody is using this config - if(!overrideUsedFlag && this.serverConfig != null && typeof this.serverConfig == 'object' && this.serverConfig._isUsed && this.serverConfig._isUsed()) { - throw new Error("A Server or ReplSet instance cannot be shared across multiple Db instances"); - } else if(!overrideUsedFlag && typeof this.serverConfig == 'object'){ - // Set being used - this.serverConfig._used = true; - } - - // Ensure we have a valid db name - validateDatabaseName(databaseName); - - // Contains all the connections for the db - try { - this.native_parser = this.options.native_parser; - // The bson lib - var bsonLib = this.bsonLib = this.options.native_parser ? require('bson').BSONNative : require('bson').BSONPure; - // Fetch the serializer object - var BSON = bsonLib.BSON; - // Create a new instance - this.bson = new BSON([bsonLib.Long, bsonLib.ObjectID, bsonLib.Binary, bsonLib.Code, bsonLib.DBRef, bsonLib.Symbol, bsonLib.Double, bsonLib.Timestamp, bsonLib.MaxKey, bsonLib.MinKey]); - // Backward compatibility to access types - this.bson_deserializer = bsonLib; - this.bson_serializer = bsonLib; - } catch (err) { - // If we tried to instantiate the native driver - var msg = "Native bson parser not compiled, please compile " - + "or avoid using native_parser=true"; - throw Error(msg); - } - - // Internal state of the server - this._state = 'disconnected'; - - this.pkFactory = this.options.pk == null ? bsonLib.ObjectID : this.options.pk; - this.forceServerObjectId = this.options.forceServerObjectId != null ? this.options.forceServerObjectId : false; - - // Added safe - this.safe = this.options.safe == null ? false : this.options.safe; - - // If we have not specified a "safe mode" we just print a warning to the console - if(this.options.safe == null && this.options.w == null && this.options.journal == null && this.options.fsync == null) { - console.log("========================================================================================"); - console.log("= Please ensure that you set the default write concern for the database by setting ="); - console.log("= one of the options ="); - console.log("= ="); - console.log("= w: (value of > -1 or the string 'majority'), where < 1 means ="); - console.log("= no write acknowlegement ="); - console.log("= journal: true/false, wait for flush to journal before acknowlegement ="); - console.log("= fsync: true/false, wait for flush to file system before acknowlegement ="); - console.log("= ="); - console.log("= For backward compatibility safe is still supported and ="); - console.log("= allows values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}] ="); - console.log("= the default value is false which means the driver receives does not ="); - console.log("= return the information of the success/error of the insert/update/remove ="); - console.log("= ="); - console.log("= ex: new Db(new Server('localhost', 27017), {safe:false}) ="); - console.log("= ="); - console.log("= http://www.mongodb.org/display/DOCS/getLastError+Command ="); - console.log("= ="); - console.log("= The default of no acknowlegement will change in the very near future ="); - console.log("= ="); - console.log("= This message will disappear when the default safe is set on the driver Db ="); - console.log("========================================================================================"); - } - - // Internal states variables - this.notReplied ={}; - this.isInitializing = true; - this.auths = []; - this.openCalled = false; - - // Command queue, keeps a list of incoming commands that need to be executed once the connection is up - this.commands = []; - - // Set up logger - this.logger = this.options.logger != null - && (typeof this.options.logger.debug == 'function') - && (typeof this.options.logger.error == 'function') - && (typeof this.options.logger.log == 'function') - ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}}; - // Allow slaveOk - this.slaveOk = this.options["slave_ok"] == null ? false : this.options["slave_ok"]; - - var self = this; - // Associate the logger with the server config - this.serverConfig.logger = this.logger; - if(this.serverConfig.strategyInstance) this.serverConfig.strategyInstance.logger = this.logger; - this.tag = new Date().getTime(); - // Just keeps list of events we allow - this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[]}; - - // Controls serialization options - this.serializeFunctions = this.options.serializeFunctions != null ? this.options.serializeFunctions : false; - - // Raw mode - this.raw = this.options.raw != null ? this.options.raw : false; - - // Record query stats - this.recordQueryStats = this.options.recordQueryStats != null ? this.options.recordQueryStats : false; - - // If we have server stats let's make sure the driver objects have it enabled - if(this.recordQueryStats == true) { - this.serverConfig.enableRecordQueryStats(true); - } - - // Retry information - this.retryMiliSeconds = this.options.retryMiliSeconds != null ? this.options.retryMiliSeconds : 1000; - this.numberOfRetries = this.options.numberOfRetries != null ? this.options.numberOfRetries : 60; - - // Set default read preference if any - this.readPreference = this.options.readPreference; -}; - -/** - * @ignore - */ -function validateDatabaseName(databaseName) { - if(typeof databaseName !== 'string') throw new Error("database name must be a string"); - if(databaseName.length === 0) throw new Error("database name cannot be the empty string"); - - var invalidChars = [" ", ".", "$", "/", "\\"]; - for(var i = 0; i < invalidChars.length; i++) { - if(databaseName.indexOf(invalidChars[i]) != -1) throw new Error("database names cannot contain the character '" + invalidChars[i] + "'"); - } -} - -/** - * @ignore - */ -inherits(Db, EventEmitter); - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the index information or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.open = function(callback) { - var self = this; - - // Check that the user has not called this twice - if(this.openCalled) { - // Close db - this.close(); - // Throw error - throw new Error("db object already connecting, open cannot be called multiple times"); - } - - // If we have a specified read preference - if(this.readPreference != null) this.serverConfig.setReadPreference(this.readPreference); - - // Set that db has been opened - this.openCalled = true; - - // Set the status of the server - self._state = 'connecting'; - // Set up connections - if(self.serverConfig instanceof Server || self.serverConfig instanceof ReplSet || self.serverConfig instanceof Mongos) { - self.serverConfig.connect(self, {firstCall: true}, function(err, result) { - if(err != null) { - // Set that db has been closed - self.openCalled = false; - // Return error from connection - return callback(err, null); - } - // Set the status of the server - self._state = 'connected'; - // If we have queued up commands execute a command to trigger replays - if(self.commands.length > 0) _execute_queued_command(self); - // Callback - return callback(null, self); - }); - } else { - return callback(Error("Server parameter must be of type Server, ReplSet or Mongos"), null); - } -}; - -// Execute any baked up commands -var _execute_queued_command = function(self) { - // Execute any backed up commands - processor(function() { - // Execute any backed up commands - while(self.commands.length > 0) { - // Fetch the command - var command = self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(self, command['db_command'], command['options'], command['callback']); - } - } - }); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -Db.prototype.db = function(dbName) { - // Copy the options and add out internal override of the not shared flag - var options = {}; - for(var key in this.options) { - options[key] = this.options[key]; - } - - // Add override flag - options['override_used_flag'] = true; - // Create a new db instance - var newDbInstance = new Db(dbName, this.serverConfig, options); - //copy over any auths, we may need them for reconnecting - if (this.serverConfig.db) { - newDbInstance.auths = this.serverConfig.db.auths; - } - // Add the instance to the list of approved db instances - var allServerInstances = this.serverConfig.allServerInstances(); - // Add ourselves to all server callback instances - for(var i = 0; i < allServerInstances.length; i++) { - var server = allServerInstances[i]; - server.dbInstances.push(newDbInstance); - } - // Return new db object - return newDbInstance; -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Boolean} [forceClose] connection can never be reused. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.close = function(forceClose, callback) { - var self = this; - // Ensure we force close all connections - this._applicationClosed = false; - - if(typeof forceClose == 'function') { - callback = forceClose; - } else if(typeof forceClose == 'boolean') { - this._applicationClosed = forceClose; - } - - // Remove all listeners and close the connection - this.serverConfig.close(function(err, result) { - // Emit the close event - if(typeof callback !== 'function') self.emit("close"); - - // Emit close event across all db instances sharing the sockets - var allServerInstances = self.serverConfig.allServerInstances(); - // Fetch the first server instance - if(Array.isArray(allServerInstances) && allServerInstances.length > 0) { - var server = allServerInstances[0]; - // For all db instances signal all db instances - if(Array.isArray(server.dbInstances) && server.dbInstances.length > 1) { - for(var i = 0; i < server.dbInstances.length; i++) { - var dbInstance = server.dbInstances[i]; - // Check if it's our current db instance and skip if it is - if(dbInstance.databaseName !== self.databaseName && dbInstance.tag !== self.tag) { - server.dbInstances[i].emit("close"); - } - } - } - } - - // Remove all listeners - self.removeAllEventListeners(); - // You can reuse the db as everything is shut down - self.openCalled = false; - // If we have a callback call it - if(callback) callback(err, result); - }); -}; - -/** - * Access the Admin database - * - * @param {Function} [callback] returns the results. - * @return {Admin} the admin db object. - * @api public - */ -Db.prototype.admin = function(callback) { - if(callback == null) return new Admin(this); - callback(null, new Admin(this)); -}; - -/** - * Returns a cursor to all the collection information. - * - * @param {String} [collectionName] the collection name we wish to retrieve the information from. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the options or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionsInfo = function(collectionName, callback) { - if(callback == null && typeof collectionName == 'function') { callback = collectionName; collectionName = null; } - // Create selector - var selector = {}; - // If we are limiting the access to a specific collection name - if(collectionName != null) selector.name = this.databaseName + "." + collectionName; - - // Return Cursor - // callback for backward compatibility - if(callback) { - callback(null, new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector)); - } else { - return new Cursor(this, new Collection(this, DbCommand.SYSTEM_NAMESPACE_COLLECTION), selector); - } -}; - -/** - * Get the list of all collection names for the specified db - * - * Options - * - **namesOnly** {String, default:false}, Return only the full collection namespace. - * - * @param {String} [collectionName] the collection name we wish to filter by. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection names or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collectionNames = function(collectionName, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - collectionName = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure no breaking behavior - if(collectionName != null && typeof collectionName == 'object') { - options = collectionName; - collectionName = null; - } - - // Let's make our own callback to reuse the existing collections info method - self.collectionsInfo(collectionName, function(err, cursor) { - if(err != null) return callback(err, null); - - cursor.toArray(function(err, documents) { - if(err != null) return callback(err, null); - - // List of result documents that have been filtered - var filtered_documents = documents.filter(function(document) { - return !(document.name.indexOf(self.databaseName) == -1 || document.name.indexOf('$') != -1); - }); - - // If we are returning only the names - if(options.namesOnly) { - filtered_documents = filtered_documents.map(function(document) { return document.name }); - } - - // Return filtered items - callback(null, filtered_documents); - }); - }); -}; - -/** - * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you can - * can use it without a callback in the following way. var collection = db.collection('mycollection'); - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if the collection does not exist - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collection = function(collectionName, options, callback) { - var self = this; - if(typeof options === "function") { callback = options; options = {}; } - // Execute safe - - if(options && (options.strict)) { - self.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - if(collections.length == 0) { - return callback(new Error("Collection " + collectionName + " does not exist. Currently in safe mode."), null); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - }); - } else { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - if(callback == null) { - throw err; - } else { - return callback(err, null); - } - } - - // If we have no callback return collection object - return callback == null ? collection : callback(null, collection); - } -}; - -/** - * Fetch all collections for the current db. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the collections or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.collections = function(callback) { - var self = this; - // Let's get the collection names - self.collectionNames(function(err, documents) { - if(err != null) return callback(err, null); - var collections = []; - documents.forEach(function(document) { - collections.push(new Collection(self, document.name.replace(self.databaseName + ".", ''), self.pkFactory)); - }); - // Return the collection objects - callback(null, collections); - }); -}; - -/** - * Evaluate javascript on the server - * - * Options - * - **nolock** {Boolean, default:false}, Tell MongoDB not to block on the evaulation of the javascript. - * - * @param {Code} code javascript to execute on server. - * @param {Object|Array} [parameters] the parameters for the call. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from eval or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.eval = function(code, parameters, options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - parameters = args.length ? args.shift() : parameters; - options = args.length ? args.shift() : {}; - - var finalCode = code; - var finalParameters = []; - // If not a code object translate to one - if(!(finalCode instanceof this.bsonLib.Code)) { - finalCode = new this.bsonLib.Code(finalCode); - } - - // Ensure the parameters are correct - if(parameters != null && parameters.constructor != Array && typeof parameters !== 'function') { - finalParameters = [parameters]; - } else if(parameters != null && parameters.constructor == Array && typeof parameters !== 'function') { - finalParameters = parameters; - } - - // Create execution selector - var selector = {'$eval':finalCode, 'args':finalParameters}; - // Check if the nolock parameter is passed in - if(options['nolock']) { - selector['nolock'] = options['nolock']; - } - - // Set primary read preference - options.readPreference = ReadPreference.PRIMARY; - - // Execute the eval - this.collection(DbCommand.SYSTEM_COMMAND_COLLECTION).findOne(selector, options, function(err, result) { - if(err) return callback(err); - - if(result && result.ok == 1) { - callback(null, result.retval); - } else if(result) { - callback(new Error("eval failed: " + result.errmsg), null); return; - } else { - callback(err, result); - } - }); -}; - -/** - * Dereference a dbref, against a db - * - * @param {DBRef} dbRef db reference object we wish to resolve. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dereference or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dereference = function(dbRef, callback) { - var db = this; - // If we have a db reference then let's get the db first - if(dbRef.db != null) db = this.db(dbRef.db); - // Fetch the collection and find the reference - var collection = db.collection(dbRef.namespace); - collection.findOne({'_id':dbRef.oid}, function(err, result) { - callback(err, result); - }); -}; - -/** - * Logout user from server, fire off on all connections and remove all auth info - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.logout = function(options, callback) { - var self = this; - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Number of connections we need to logout from - var numberOfConnections = this.serverConfig.allRawConnections().length; - - // Let's generate the logout command object - var logoutCommand = DbCommand.logoutCommand(self, {logout:1}, options); - self._executeQueryCommand(logoutCommand, {onAll:true}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - // Reset auth - self.auths = []; - // Handle any errors - if(err == null && result.documents[0].ok == 1) { - internalCallback(null, true); - } else { - err != null ? internalCallback(err, false) : internalCallback(new Error(result.documents[0].errmsg), false); - } - } - }); -} - -/** - * Authenticate a user against the server. - * - * Options - * - **authSource** {String}, The database that the credentials are for, - * different from the name of the current DB, for example admin - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] the options - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authentication or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.authenticate = function(username, password, options, callback) { - var self = this; - - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - // the default db to authenticate against is 'this' - // if authententicate is called from a retry context, it may be another one, like admin - var authdb = options.authdb ? options.authdb : self.databaseName; - authdb = options.authSource ? options.authSource : authdb; - // Push the new auth if we have no previous record - - var numberOfConnections = 0; - var errorObject = null; - - if(options['connection'] != null) { - //if a connection was explicitly passed on options, then we have only one... - numberOfConnections = 1; - } else { - // Get the amount of connections in the pool to ensure we have authenticated all comments - numberOfConnections = this.serverConfig.allRawConnections().length; - options['onAll'] = true; - } - - // Execute all four - this._executeQueryCommand(DbCommand.createGetNonceCommand(self), options, function(err, result, connection) { - // Execute on all the connections - if(err == null) { - // Nonce used to make authentication request with md5 hash - var nonce = result.documents[0].nonce; - // Execute command - self._executeQueryCommand(DbCommand.createAuthenticationCommand(self, username, password, nonce, authdb), {connection:connection}, function(err, result) { - // Count down - numberOfConnections = numberOfConnections - 1; - // Ensure we save any error - if(err) { - errorObject = err; - } else if(result.documents[0].err != null || result.documents[0].errmsg != null){ - errorObject = utils.toError(result.documents[0]); - } - - // Work around the case where the number of connections are 0 - if(numberOfConnections <= 0 && typeof callback == 'function') { - var internalCallback = callback; - callback = null; - - if(errorObject == null && result.documents[0].ok == 1) { - // We authenticated correctly save the credentials - self.auths = [{'username':username, 'password':password, 'authdb': authdb}]; - // Return callback - internalCallback(errorObject, true); - } else { - internalCallback(errorObject, false); - } - } - }); - } - }); -}; - -/** - * Add a user to the database. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {String} password password. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.addUser = function(username, password, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - errorOptions.w = errorOptions.w == null ? 1 : errorOptions.w; - // Use node md5 generator - var md5 = crypto.createHash('md5'); - // Generate keys used for authentication - md5.update(username + ":mongo:" + password); - var userPassword = md5.digest('hex'); - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - // Check if we are inserting the first user - collection.count({}, function(err, count) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Check if the user exists and update i - collection.find({user: username}, {dbName: options['dbName']}).toArray(function(err, documents) { - // We got an error (f.ex not authorized) - if(err != null) return callback(err, null); - // Add command keys - var commandOptions = errorOptions; - commandOptions.dbName = options['dbName']; - commandOptions.upsert = true; - - // We have a user, let's update the password or upsert if not - collection.update({user: username},{$set: {user: username, pwd: userPassword}}, commandOptions, function(err, results) { - if(count == 0 && err) { - callback(null, [{user:username, pwd:userPassword}]); - } else if(err) { - callback(err, null) - } else { - callback(null, [{user:username, pwd:userPassword}]); - } - }); - }); - }); -}; - -/** - * Remove a user from a database - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} username username. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.removeUser = function(username, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Fetch a user collection - var collection = this.collection(DbCommand.SYSTEM_USER_COLLECTION); - collection.findOne({user: username}, {dbName: options['dbName']}, function(err, user) { - if(user != null) { - // Add command keys - var commandOptions = safe; - commandOptions.dbName = options['dbName']; - - collection.remove({user: username}, commandOptions, function(err, result) { - callback(err, true); - }); - } else { - callback(err, false); - } - }); -}; - -/** - * Creates a collection on a server pre-allocating space, need to create f.ex capped collections. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **serializeFunctions** {Boolean, default:false}, serialize functions on the document. - * - **raw** {Boolean, default:false}, perform all operations using raw bson objects. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **capped** {Boolean, default:false}, create a capped collection. - * - **size** {Number}, the size of the capped collection in bytes. - * - **max** {Number}, the maximum number of documents in the capped collection. - * - **autoIndexId** {Boolean, default:true}, create an index on the _id field of the document, True by default on MongoDB 2.2 or higher off for version < 2.2. - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **strict**, (Boolean, default:false) throws and error if collection already exists - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName the collection name we wish to access. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createCollection = function(collectionName, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : null; - var self = this; - - // Figure out the safe mode settings - var safe = self.safe != null && self.safe == false ? {w: 1} : self.safe; - // Override with options passed in if applicable - safe = options != null && options['safe'] != null ? options['safe'] : safe; - // Ensure it's at least set to safe - safe = safe == null ? {w: 1} : safe; - - // Check if we have the name - this.collectionNames(collectionName, function(err, collections) { - if(err != null) return callback(err, null); - - var found = false; - collections.forEach(function(collection) { - if(collection.name == self.databaseName + "." + collectionName) found = true; - }); - - // If the collection exists either throw an exception (if db in safe mode) or return the existing collection - if(found && options && options.strict) { - return callback(new Error("Collection " + collectionName + " already exists. Currently in safe mode."), null); - } else if(found){ - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } - - // Create a new collection and return it - self._executeQueryCommand(DbCommand.createCreateCollectionCommand(self, collectionName, options), {read:false, safe:safe}, function(err, result) { - var document = result.documents[0]; - // If we have no error let's return the collection - if(err == null && document.ok == 1) { - try { - var collection = new Collection(self, collectionName, self.pkFactory, options); - } catch(err) { - return callback(err, null); - } - return callback(null, collection); - } else { - if (null == err) err = utils.toError(document); - callback(err, null); - } - }); - }); -}; - -/** - * Execute a command hash against MongoDB. This lets you acess any commands not available through the api on the server. - * - * @param {Object} selector the command hash to send to the server, ex: {ping:1}. - * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter. - * @return {null} - * @api public - */ -Db.prototype.command = function(selector, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - // Set up the options - var cursor = new Cursor(this - , new Collection(this, DbCommand.SYSTEM_COMMAND_COLLECTION), selector, {}, { - limit: -1, timeout: QueryCommand.OPTS_NO_CURSOR_TIMEOUT, dbName: options['dbName'] - }); - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : false; - - // Ensure only commands who support read Prefrences are exeuted otherwise override and use Primary - if(readPreference != false) { - if(selector['group'] || selector['aggregate'] || selector['collStats'] || selector['dbStats'] - || selector['count'] || selector['distinct'] || selector['geoNear'] || selector['geoSearch'] || selector['geoWalk'] - || (selector['mapreduce'] && selector.out == 'inline')) { - // Set the read preference - cursor.setReadPreference(readPreference); - } else { - cursor.setReadPreference(ReadPreference.PRIMARY); - } - } - - // Return the next object - cursor.nextObject(callback); -}; - -/** - * Drop a collection from the database, removing it permanently. New accesses will create a new collection. - * - * @param {String} collectionName the name of the collection we wish to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropCollection = function(collectionName, callback) { - var self = this; - callback || (callback = function(){}); - - // Drop the collection - this._executeQueryCommand(DbCommand.createDropCollectionCommand(this, collectionName), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, true); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Rename a collection. - * - * Options - * - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists. - * - * @param {String} fromCollection the name of the current collection we wish to rename. - * @param {String} toCollection the new name of the collection. - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from renameCollection or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) { - var self = this; - - if(typeof options == 'function') { - callback = options; - options = {} - } - - callback || (callback = function(){}); - // Execute the command, return the new renamed collection if successful - this._executeQueryCommand(DbCommand.createRenameCollectionCommand(this, fromCollection, toCollection, options), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - return callback(null, new Collection(self, toCollection, self.pkFactory)); - } - - if(null == err) err = utils.toError(result.documents[0]); - callback(err, null); - }); -}; - -/** - * Return last error message for the given connection, note options can be combined. - * - * Options - * - **fsync** {Boolean, default:false}, option forces the database to fsync all files before returning. - * - **j** {Boolean, default:false}, awaits the journal commit before returning, > MongoDB 2.0. - * - **w** {Number}, until a write operation has been replicated to N servers. - * - **wtimeout** {Number}, number of miliseconds to wait before timing out. - * - * Connection Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Object} [connectionOptions] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from lastError or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.lastError = function(options, connectionOptions, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - connectionOptions = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetLastErrorCommand(options, this), connectionOptions, function(err, error) { - callback(err, error && error.documents); - }); -}; - -/** - * Legacy method calls. - * - * @ignore - * @api private - */ -Db.prototype.error = Db.prototype.lastError; -Db.prototype.lastStatus = Db.prototype.lastError; - -/** - * Return all errors up to the last time db reset_error_history was called. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from previousErrors or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.previousErrors = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createGetPreviousErrorsCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Runs a command on the database. - * @ignore - * @api private - */ -Db.prototype.executeDbCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, command_hash, options), options, callback); -}; - -/** - * Runs a command on the database as admin. - * @ignore - * @api private - */ -Db.prototype.executeDbAdminCommand = function(command_hash, options, callback) { - if(callback == null) { callback = options; options = {}; } - this._executeQueryCommand(DbCommand.createAdminDbCommand(this, command_hash), options, callback); -}; - -/** - * Resets the error history of the mongo instance. - * - * Options - * - **connection** {Connection}, fire the getLastError down a specific connection. - * - * @param {Object} [options] returns option results. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from resetErrorHistory or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.resetErrorHistory = function(options, callback) { - // Unpack calls - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createResetErrorHistoryCommand(this), options, function(err, error) { - callback(err, error.documents); - }); -}; - -/** - * Creates an index on the collection. - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from createIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.createIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : {}; - options = typeof callback === 'function' ? options : callback; - options = options == null ? {} : options; - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - // Default command options - var commandOptions = {}; - - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // Set safe option - commandOptions['safe'] = errorOptions; - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - // Execute insert command - this._executeInsertCommand(command, commandOptions, function(err, result) { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - }); - } else if(_hasWriteConcern(errorOptions) && callback == null) { - throw new Error("Cannot use a writeConcern without a provided callback"); - } else { - // Execute insert command - var result = this._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, null); - } -}; - -/** - * Ensures that an index exists, if it does not it creates it - * - * Options -* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **unique** {Boolean, default:false}, creates an unique index. - * - **sparse** {Boolean, default:false}, creates a sparse index. - * - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible. - * - **dropDups** {Boolean, default:false}, a unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value - * - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates. - * - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates. - * - **v** {Number}, specify the format version of the indexes. - * - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) - * - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes) - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @param {String} collectionName name of the collection to create the index on. - * @param {Object} fieldOrSpec fieldOrSpec that defines the index. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ensureIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.ensureIndex = function(collectionName, fieldOrSpec, options, callback) { - var self = this; - - if (typeof callback === 'undefined' && typeof options === 'function') { - callback = options; - options = {}; - } - - if (options == null) { - options = {}; - } - - // Get the error options - var errorOptions = _getWriteConcern(this, options, callback); - // Make sure we don't try to do a write concern without a callback - if(_hasWriteConcern(errorOptions) && callback == null) - throw new Error("Cannot use a writeConcern without a provided callback"); - // Create command - var command = DbCommand.createCreateIndexCommand(this, collectionName, fieldOrSpec, options); - var index_name = command.documents[0].name; - - // Default command options - var commandOptions = {}; - // Check if the index allready exists - this.indexInformation(collectionName, function(err, collectionInfo) { - if(err != null) return callback(err, null); - - if(!collectionInfo[index_name]) { - // If we have error conditions set handle them - if(_hasWriteConcern(errorOptions) && typeof callback == 'function') { - // Insert options - commandOptions['read'] = false; - // If we have safe set set async to false - if(errorOptions == null) commandOptions['async'] = true; - - // If we have an error option - if(typeof errorOptions == 'object') { - var keys = Object.keys(errorOptions); - for(var i = 0; i < keys.length; i++) { - commandOptions[keys[i]] = errorOptions[keys[i]]; - } - } - - if(typeof callback === 'function' - && commandOptions.w < 1 && !commandOptions.fsync && !commandOptions.journal) { - commandOptions.w = 1; - } - - self._executeInsertCommand(command, commandOptions, function(err, result) { - // Only callback if we have one specified - if(typeof callback === 'function') { - if(err != null) return callback(err, null); - - result = result && result.documents; - if (result[0].err) { - callback(utils.toError(result[0])); - } else { - callback(null, command.documents[0].name); - } - } - }); - } else { - // Execute insert command - var result = self._executeInsertCommand(command, commandOptions); - // If no callback just return - if(!callback) return; - // If error return error - if(result instanceof Error) { - return callback(result); - } - // Otherwise just return - return callback(null, index_name); - } - } else { - if(typeof callback === 'function') return callback(null, index_name); - } - }); -}; - -/** - * Returns the information available on allocated cursors. - * - * Options - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from cursorInfo or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.cursorInfo = function(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - options = args.length ? args.shift() : {}; - - this._executeQueryCommand(DbCommand.createDbSlaveOkCommand(this, {'cursorInfo':1}), options, function(err, result) { - callback(err, result.documents[0]); - }); -}; - -/** - * Drop an index on a collection. - * - * @param {String} collectionName the name of the collection where the command will drop an index. - * @param {String} indexName name of the index to drop. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropIndex or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropIndex = function(collectionName, indexName, callback) { - this._executeQueryCommand(DbCommand.createDropIndexCommand(this, collectionName, indexName), callback); -}; - -/** - * Reindex all indexes on the collection - * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. - * - * @param {String} collectionName the name of the collection. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from reIndex or null if an error occured. - * @api public -**/ -Db.prototype.reIndex = function(collectionName, callback) { - this._executeQueryCommand(DbCommand.createReIndexCommand(this, collectionName), function(err, result) { - if(err != null) { - callback(err, false); - } else if(result.documents[0].errmsg == null) { - callback(null, true); - } else { - callback(new Error(result.documents[0].errmsg), false); - } - }); -}; - -/** - * Retrieves this collections index info. - * - * Options - * - **full** {Boolean, default:false}, returns the full raw index information. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {String} collectionName the name of the collection. - * @param {Object} [options] additional options during update. - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from indexInformation or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.indexInformation = function(collectionName, options, callback) { - if(typeof callback === 'undefined') { - if(typeof options === 'undefined') { - callback = collectionName; - collectionName = null; - } else { - callback = options; - } - options = {}; - } - - // If we specified full information - var full = options['full'] == null ? false : options['full']; - // Build selector for the indexes - var selector = collectionName != null ? {ns: (this.databaseName + "." + collectionName)} : {}; - - // Set read preference if we set one - var readPreference = options['readPreference'] ? options['readPreference'] : ReadPreference.PRIMARY; - - // Iterate through all the fields of the index - this.collection(DbCommand.SYSTEM_INDEX_COLLECTION, function(err, collection) { - // Perform the find for the collection - collection.find(selector).setReadPreference(readPreference).toArray(function(err, indexes) { - if(err != null) return callback(err, null); - // Contains all the information - var info = {}; - - // if full defined just return all the indexes directly - if(full) return callback(null, indexes); - - // Process all the indexes - for(var i = 0; i < indexes.length; i++) { - var index = indexes[i]; - // Let's unpack the object - info[index.name] = []; - for(var name in index.key) { - info[index.name].push([name, index.key[name]]); - } - } - - // Return all the indexes - callback(null, info); - }); - }); -}; - -/** - * Drop a database. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from dropDatabase or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.dropDatabase = function(callback) { - var self = this; - - this._executeQueryCommand(DbCommand.createDropDatabaseCommand(this), function(err, result) { - if(err == null && result.documents[0].ok == 1) { - callback(null, true); - } else { - if(err) { - callback(err, false); - } else { - callback(utils.toError(result.documents[0]), false); - } - } - }); -}; - -/** - * Get all the db statistics. - * - * Options - * - **scale** {Number}, divide the returned sizes by scale value. - * - **readPreference** {String}, the preferred read preference ((Server.PRIMARY, Server.PRIMARY_PREFERRED, Server.SECONDARY, Server.SECONDARY_PREFERRED, Server.NEAREST). - * - * @param {Objects} [options] options for the stats command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from stats or null if an error occured. - * @return {null} - * @api public - */ -Db.prototype.stats = function stats(options, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - // Fetch all commands - options = args.length ? args.shift() : {}; - - // Build command object - var commandObject = { - dbStats:this.collectionName, - } - - // Check if we have the scale value - if(options['scale'] != null) commandObject['scale'] = options['scale']; - - // Execute the command - this.command(commandObject, options, callback); -} - -/** - * @ignore - */ -var __executeQueryCommand = function(self, db_command, options, callback) { - // Options unpacking - var read = options['read'] != null ? options['read'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var onAll = options['onAll'] != null ? options['onAll'] : false; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - - // Correct read preference to default primary if set to false, null or primary - if(!(typeof read == 'object') && read._type == 'ReadPreference') { - read = (read == null || read == 'primary' || read == false) ? ReadPreference.PRIMARY : read; - if(!ReadPreference.isValid(read)) return callback(new Error("Illegal readPreference mode specified, " + read)); - } else if(typeof read == 'object' && read._type == 'ReadPreference') { - if(!read.isValid()) return callback(new Error("Illegal readPreference mode specified, " + read.mode)); - } - - // If we have a read preference set and we are a mongos pass the read preference on to the mongos instance, - if(self.serverConfig.isMongos() && read != null && read != false) { - db_command.setMongosReadPreference(read); - } - - // If we got a callback object - if(typeof callback === 'function' && !onAll) { - // Override connection if we passed in a specific connection - var connection = specifiedConnection != null ? specifiedConnection : null; - - if(connection instanceof Error) return callback(connection, null); - - // Fetch either a reader or writer dependent on the specified read option if no connection - // was passed in - if(connection == null) { - connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - } - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error || connection['message'] != null) { - return callback(connection); - } - - // Exhaust Option - var exhaust = options.exhaust || false; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, exhaust, callback); - // Write the message out and handle any errors if there are any - connection.write(db_command, function(err) { - if(err != null) { - // Call the handler with an error - self.serverConfig._callHandler(db_command.getRequestId(), null, err); - } - }); - } else if(typeof callback === 'function' && onAll) { - var connections = self.serverConfig.allRawConnections(); - var numberOfEntries = connections.length; - // Go through all the connections - for(var i = 0; i < connections.length; i++) { - // Fetch a connection - var connection = connections[i]; - - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command, raw, connection, callback); - // Write the message out - connection.write(db_command, function(err) { - // Adjust the number of entries we need to process - numberOfEntries = numberOfEntries - 1; - // Remove listener - if(err != null) { - // Clean up listener and return error - self.serverConfig._removeHandler(db_command.getRequestId()); - } - - // No more entries to process callback with the error - if(numberOfEntries <= 0) { - callback(err); - } - }); - - // Update the db_command request id - db_command.updateRequestId(); - } - } else { - // Fetch either a reader or writer dependent on the specified read option - var connection = read == null || read == 'primary' || read == false ? self.serverConfig.checkoutWriter(true) : self.serverConfig.checkoutReader(read); - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - // Ensure we have a valid connection - if(connection == null || connection instanceof Error || connection['message'] != null) return null; - // Write the message out - connection.write(db_command, function(err) { - if(err != null) { - // Emit the error - self.emit("error", err); - } - }); - } -} - -/** - * @ignore - */ -var __retryCommandOnFailure = function(self, retryInMilliseconds, numberOfTimes, command, db_command, options, callback) { - if(this._state == 'connected' || this._state == 'disconnected') this._state = 'connecting'; - // Number of retries done - var numberOfRetriesDone = numberOfTimes; - // Retry function, execute once - var retryFunction = function(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback) { - _self.serverConfig.connect(_self, {}, function(err, result, _serverConfig) { - if(_options) delete _options['connection']; - - // Adjust the number of retries left - _numberOfRetriesDone = _numberOfRetriesDone - 1; - // Definitively restart - if(err != null && _numberOfRetriesDone > 0) { - _self._state = 'connecting'; - // Close the server config - _serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } else if(err != null && _numberOfRetriesDone <= 0) { - _self._state = 'disconnected'; - // Force close the current connections - _serverConfig.close(function(_err) { - // Force close the current connections - if(typeof _callback == 'function') _callback(err, null); - }); - } else if(err == null && _self.serverConfig.isConnected() == true && Array.isArray(_self.auths) && _self.auths.length > 0) { - _self._state = 'connected'; - // Get number of auths we need to execute - var numberOfAuths = _self.auths.length; - // Apply all auths - for(var i = 0; i < _self.auths.length; i++) { - _self.authenticate(_self.auths[i].username, _self.auths[i].password, {'authdb':_self.auths[i].authdb}, function(err, authenticated) { - numberOfAuths = numberOfAuths - 1; - - // If we have no more authentications to replay - if(numberOfAuths == 0) { - if(err != null || !authenticated) { - if(typeof _callback == 'function') _callback(err, null); - return; - } else { - // Execute command - command(_self, _db_command, _options, _callback); - // Execute all the commands - if(_self.commands.length > 0) _execute_queued_command(_self); - } - } - }); - } - } else if(err == null && _self.serverConfig.isConnected() == true) { - _self._state = 'connected'; - - // Execute command - command(_self, _db_command, _options, _callback); - - processor(function() { - // Execute any backed up commands - while(_self.commands.length > 0) { - // Fetch the command - var command = _self.commands.shift(); - // Execute based on type - if(command['type'] == 'query') { - __executeQueryCommand(_self, command['db_command'], command['options'], command['callback']); - } else if(command['type'] == 'insert') { - __executeInsertCommand(_self, command['db_command'], command['options'], command['callback']); - } - } - }); - } else { - _self._state = 'connecting'; - // Force close the current connections - _serverConfig.close(function(err) { - // _self.serverConfig.close(function(err) { - // Retry the connect - setTimeout(function() { - retryFunction(_self, _numberOfRetriesDone, _retryInMilliseconds, _numberOfTimes, _command, _db_command, _options, _callback); - }, _retryInMilliseconds); - }); - } - }); - }; - - // Execute function first time - retryFunction(self, numberOfRetriesDone, retryInMilliseconds, numberOfTimes, command, db_command, options, callback); -} - -/** - * Execute db query command (not safe) - * @ignore - * @api private - */ -Db.prototype._executeQueryCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if (typeof callback === 'undefined') { - callback = options; - options = {}; - } - - // fast fail option used for HA, no retry - var failFast = options['failFast'] != null - ? options['failFast'] - : false; - - // Check if the user force closed the command - if(this._applicationClosed) { - var err = new Error("db closed by application"); - if('function' == typeof callback) { - return callback(err, null); - } else { - throw err; - } - } - - var config = this.serverConfig; - // If the pool is not connected, attemp to reconnect to send the message - if(this._state == 'connecting' && config.autoReconnect && !failFast) { - return processor(function() { - self.commands.push({ - type: 'query', - db_command: db_command, - options: options, - callback: callback - }); - }) - } - - if(!failFast && !config.isConnected(options.read) && config.autoReconnect - && (options.read == null - || options.read == false - || options.read == ReadPreference.PRIMARY - || config.checkoutReader(options.read) == null)) { - this._state = 'connecting'; - return __retryCommandOnFailure(this, - this.retryMiliSeconds, - this.numberOfRetries, - __executeQueryCommand, - db_command, - options, - callback); - } - - if(!config.isConnected(options.read) && !config.autoReconnect && callback) { - // Fire an error to the callback if we are not connected - // and don't reconnect. - return callback(new Error("no open connections"), null); - } - - __executeQueryCommand(self, db_command, options, function (err, result, conn) { - if(callback) callback(err, result, conn); - }); - -}; - -/** - * @ignore - */ -var __executeInsertCommand = function(self, db_command, options, callback) { - // Always checkout a writer for this kind of operations - var connection = self.serverConfig.checkoutWriter(); - // Get safe mode - var safe = options['safe'] != null ? options['safe'] : false; - var raw = options['raw'] != null ? options['raw'] : self.raw; - var specifiedConnection = options['connection'] != null ? options['connection'] : null; - // Override connection if needed - connection = specifiedConnection != null ? specifiedConnection : connection; - - // Ensure we have a valid connection - if(typeof callback === 'function') { - // Ensure we have a valid connection - if(connection == null) { - return callback(new Error("no open connections")); - } else if(connection instanceof Error) { - return callback(connection); - } - - var errorOptions = _getWriteConcern(self, options, callback); - if(errorOptions.w > 0 || errorOptions.w == 'majority' || errorOptions.j || errorOptions.journal || errorOptions.fsync) { - // db command is now an array of commands (original command + lastError) - db_command = [db_command, DbCommand.createGetLastErrorCommand(safe, self)]; - // Register the handler in the data structure - self.serverConfig._registerHandler(db_command[1], raw, connection, callback); - } - } - - // If we have no callback and there is no connection - if(connection == null) return null; - if(connection instanceof Error && typeof callback == 'function') return callback(connection, null); - if(connection instanceof Error) return null; - if(connection == null && typeof callback == 'function') return callback(new Error("no primary server found"), null); - - // Write the message out - connection.write(db_command, function(err) { - // Return the callback if it's not a safe operation and the callback is defined - if(typeof callback === 'function' && (safe == null || safe == false)) { - // Perform the callback - callback(err, null); - } else if(typeof callback === 'function') { - // Call the handler with an error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, err); - } else if(typeof callback == 'function' && safe && safe.w == -1) { - // Call the handler with no error - self.serverConfig._callHandler(db_command[1].getRequestId(), null, null); - } else if(!safe || safe.w == -1) { - self.emit("error", err); - } - }); -} - -/** - * Execute an insert Command - * @ignore - * @api private - */ -Db.prototype._executeInsertCommand = function(db_command, options, callback) { - var self = this; - - // Unpack the parameters - if(callback == null && typeof options === 'function') { - callback = options; - options = {}; - } - - // Ensure options are not null - options = options == null ? {} : options; - - // Check if the user force closed the command - if(this._applicationClosed) { - if(typeof callback == 'function') { - return callback(new Error("db closed by application"), null); - } else { - throw new Error("db closed by application"); - } - } - - // If the pool is not connected, attemp to reconnect to send the message - if(self._state == 'connecting' && this.serverConfig.autoReconnect) { - processor(function() { - self.commands.push({type:'insert', 'db_command':db_command, 'options':options, 'callback':callback}); - }) - } else if(!this.serverConfig.isConnected() && this.serverConfig.autoReconnect) { - this._state = 'connecting'; - // Retry command - __retryCommandOnFailure(this, this.retryMiliSeconds, this.numberOfRetries, __executeInsertCommand, db_command, options, callback); - } else if(!this.serverConfig.isConnected() && !this.serverConfig.autoReconnect && callback) { - // Fire an error to the callback if we are not connected and don't do reconnect - if(callback) callback(new Error("no open connections"), null); - } else { - __executeInsertCommand(self, db_command, options, callback); - } -} - -/** - * Update command is the same - * @ignore - * @api private - */ -Db.prototype._executeUpdateCommand = Db.prototype._executeInsertCommand; -/** - * Remove command is the same - * @ignore - * @api private - */ -Db.prototype._executeRemoveCommand = Db.prototype._executeInsertCommand; - -/** - * Wrap a Mongo error document into an Error instance. - * Deprecated. Use utils.toError instead. - * - * @ignore - * @api private - * @deprecated - */ -Db.prototype.wrap = utils.toError; - -/** - * Default URL - * - * @classconstant DEFAULT_URL - **/ -Db.DEFAULT_URL = 'mongodb://localhost:27017/default'; - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the db instance or null if an error occured. - * @return {null} - * @api public - */ -Db.connect = function(url, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = typeof args[args.length - 1] == 'function' ? args.pop() : null; - options = args.length ? args.shift() : null; - options = options || {}; - var serverOptions = options.server || {}; - var mongosOptions = options.mongos || {}; - var replSetServersOptions = options.replSet || options.replSetServers || {}; - var dbOptions = options.db || {}; - - // If callback is null throw an exception - if(callback == null) throw new Error("no callback function provided"); - - // Parse the string - var object = parse(url); - // Merge in any options for db in options object - if(dbOptions) { - for(var name in dbOptions) object.db_options[name] = dbOptions[name]; - } - - // Merge in any options for server in options object - if(serverOptions) { - for(var name in serverOptions) object.server_options[name] = serverOptions[name]; - } - - // Merge in any replicaset server options - if(replSetServersOptions) { - for(var name in replSetServersOptions) object.rs_options[name] = replSetServersOptions[name]; - } - - // Merge in any replicaset server options - if(mongosOptions) { - for(var name in mongosOptions) object.mongos_options[name] = mongosOptions[name]; - } - - // We need to ensure that the list of servers are only either direct members or mongos - // they cannot be a mix of monogs and mongod's - var totalNumberOfServers = object.servers.length; - var totalNumberOfMongosServers = 0; - var totalNumberOfMongodServers = 0; - var serverConfig = null; - var errorServers = {}; - - // Failure modes - if(object.servers.length == 0) throw new Error("connection string must contain at least one seed host"); - - // If we have no db setting for the native parser try to set the c++ one first - object.db_options.native_parser = _setNativeParser(object.db_options); - // If no auto_reconnect is set, set it to true as default for single servers - if(typeof object.server_options.auto_reconnect != 'boolean') { - object.server_options.auto_reconnect = true; - } - - // If we have more than a server, it could be replicaset or mongos list - // need to verify that it's one or the other and fail if it's a mix - // Connect to all servers and run ismaster - for(var i = 0; i < object.servers.length; i++) { - // Set up socket options - var _server_options = {poolSize:1, socketOptions:{connectTimeoutMS:1000}, auto_reconnect:false}; - - // Ensure we have ssl setup for the servers - if(object.rs_options.ssl) { - _server_options.ssl = object.rs_options.ssl; - _server_options.sslValidate = object.rs_options.sslValidate; - _server_options.sslCA = object.rs_options.sslCA; - _server_options.sslCert = object.rs_options.sslCert; - _server_options.sslKey = object.rs_options.sslKey; - _server_options.sslPass = object.rs_options.sslPass; - } else if(object.server_options.ssl) { - _server_options.ssl = object.server_options.ssl; - _server_options.sslValidate = object.server_options.sslValidate; - _server_options.sslCA = object.server_options.sslCA; - _server_options.sslCert = object.server_options.sslCert; - _server_options.sslKey = object.server_options.sslKey; - _server_options.sslPass = object.server_options.sslPass; - } - - // Set up the Server object - var _server = object.servers[i].domain_socket - ? new Server(object.servers[i].domain_socket, _server_options) - : new Server(object.servers[i].host, object.servers[i].port, _server_options); - - var connectFunction = function(__server) { - // Attempt connect - new Db(object.dbName, __server, {safe:false, native_parser:false}).open(function(err, db) { - // Update number of servers - totalNumberOfServers = totalNumberOfServers - 1; - // If no error do the correct checks - if(!err) { - // Close the connection - db.close(true); - var isMasterDoc = db.serverConfig.isMasterDoc; - // Check what type of server we have - if(isMasterDoc.setName) totalNumberOfMongodServers++; - if(isMasterDoc.msg && isMasterDoc.msg == "isdbgrid") totalNumberOfMongosServers++; - } else { - errorServers[__server.host + ":" + __server.port] = __server; - } - - if(totalNumberOfServers == 0) { - // If we have a mix of mongod and mongos, throw an error - if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) - return callback(new Error("cannot combine a list of replicaset seeds and mongos seeds")); - - if(totalNumberOfMongodServers == 0 && object.servers.length == 1) { - var obj = object.servers[0]; - serverConfig = obj.domain_socket ? - new Server(obj.domain_socket, object.server_options) - : new Server(obj.host, obj.port, object.server_options); - } else if(totalNumberOfMongodServers > 0 || totalNumberOfMongosServers > 0) { - var finalServers = object.servers - .filter(function(serverObj) { - return errorServers[serverObj.host + ":" + serverObj.port] == null; - }) - .map(function(serverObj) { - return new Server(serverObj.host, serverObj.port, object.server_options); - }); - // Clean out any error servers - errorServers = {}; - // Set up the final configuration - if(totalNumberOfMongodServers > 0) { - serverConfig = new ReplSet(finalServers, object.rs_options); - } else { - serverConfig = new Mongos(finalServers, object.mongos_options); - } - } - - if(serverConfig == null) return callback(new Error("Could not locate any valid servers in initial seed list")); - // Set up all options etc and connect to the database - _finishConnecting(serverConfig, object, options, callback) - } - }); - } - - // Wrap the context of the call - connectFunction(_server); - } -} - -var _setNativeParser = function(db_options) { - if(typeof db_options.native_parser == 'boolean') return db_options.native_parser; - - try { - require('bson').BSONNative.BSON; - return true; - } catch(err) { - return false; - } -} - -var _finishConnecting = function(serverConfig, object, options, callback) { - // Safe settings - var safe = {}; - // Build the safe parameter if needed - if(object.db_options.journal) safe.j = object.db_options.journal; - if(object.db_options.w) safe.w = object.db_options.w; - if(object.db_options.fsync) safe.fsync = object.db_options.fsync; - if(object.db_options.wtimeoutMS) safe.wtimeout = object.db_options.wtimeoutMS; - - // If we have a read Preference set - if(object.db_options.read_preference) { - var readPreference = new ReadPreference(object.db_options.read_preference); - // If we have the tags set up - if(object.db_options.read_preference_tags) - readPreference = new ReadPreference(object.db_options.read_preference, object.db_options.read_preference_tags); - // Add the read preference - object.db_options.readPreference = readPreference; - } - - // No safe mode if no keys - if(Object.keys(safe).length == 0) safe = false; - - // Add the safe object - object.db_options.safe = safe; - - // Set up the db options - var db = new Db(object.dbName, serverConfig, object.db_options); - - // Open the db - db.open(function(err, db){ - if(err == null && object.auth){ - // What db to authenticate against - var authentication_db = db; - if(object.db_options && object.db_options.authSource) { - authentication_db = db.db(object.db_options.authSource); - } - - // Authenticate - authentication_db.authenticate(object.auth.user, object.auth.password, function(err, success){ - if(success){ - callback(null, db); - } else { - if(db) db.close(); - callback(err ? err : new Error('Could not authenticate user ' + auth[0]), null); - } - }); - } else { - callback(err, db); - } - }); -} - -/** - * State of the db connection - * @ignore - */ -Object.defineProperty(Db.prototype, "state", { enumerable: true - , get: function () { - return this.serverConfig._serverState; - } -}); - -/** - * @ignore - */ -var _hasWriteConcern = function(errorOptions) { - return errorOptions == true - || errorOptions.w > 0 - || errorOptions.w == 'majority' - || errorOptions.j == true - || errorOptions.journal == true - || errorOptions.fsync == true -} - -/** - * @ignore - */ -var _setWriteConcernHash = function(options) { - var finalOptions = {}; - if(options.w != null) finalOptions.w = options.w; - if(options.journal == true) finalOptions.j = options.journal; - if(options.j == true) finalOptions.j = options.j; - if(options.fsync == true) finalOptions.fsync = options.fsync; - if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout; - return finalOptions; -} - -/** - * @ignore - */ -var _getWriteConcern = function(self, options, callback) { - // Final options - var finalOptions = {w:1}; - // Local options verification - if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(options); - } else if(options.safe != null && typeof options.safe == 'object') { - finalOptions = _setWriteConcernHash(options.safe); - } else if(typeof options.safe == "boolean") { - finalOptions = {w: (options.safe ? 1 : 0)}; - } else if(self.options.w != null || typeof self.options.j == 'boolean' || typeof self.options.journal == 'boolean' || typeof self.options.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.options); - } else if(self.safe.w != null || typeof self.safe.j == 'boolean' || typeof self.safe.journal == 'boolean' || typeof self.safe.fsync == 'boolean') { - finalOptions = _setWriteConcernHash(self.safe); - } else if(typeof self.safe == "boolean") { - finalOptions = {w: (self.safe ? 1 : 0)}; - } - - // Ensure we don't have an invalid combination of write concerns - if(finalOptions.w < 1 - && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true"); - - // Return the options - return finalOptions; -} - -/** - * Legacy support - * - * @ignore - * @api private - */ -exports.connect = Db.connect; -exports.Db = Db; - -/** - * Remove all listeners to the db instance. - * @ignore - * @api private - */ -Db.prototype.removeAllEventListeners = function() { - this.removeAllListeners("close"); - this.removeAllListeners("error"); - this.removeAllListeners("timeout"); - this.removeAllListeners("parseError"); - this.removeAllListeners("poolReady"); - this.removeAllListeners("message"); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js deleted file mode 100644 index 572d144653c..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/chunk.js +++ /dev/null @@ -1,213 +0,0 @@ -var Binary = require('bson').Binary, - ObjectID = require('bson').ObjectID; - -/** - * Class for representing a single chunk in GridFS. - * - * @class - * - * @param file {GridStore} The {@link GridStore} object holding this chunk. - * @param mongoObject {object} The mongo object representation of this chunk. - * - * @throws Error when the type of data field for {@link mongoObject} is not - * supported. Currently supported types for data field are instances of - * {@link String}, {@link Array}, {@link Binary} and {@link Binary} - * from the bson module - * - * @see Chunk#buildMongoObject - */ -var Chunk = exports.Chunk = function(file, mongoObject) { - if(!(this instanceof Chunk)) return new Chunk(file, mongoObject); - - this.file = file; - var self = this; - var mongoObjectFinal = mongoObject == null ? {} : mongoObject; - - this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id; - this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n; - this.data = new Binary(); - - if(mongoObjectFinal.data == null) { - } else if(typeof mongoObjectFinal.data == "string") { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data, 'binary', 0); - this.data = new Binary(buffer); - } else if(Array.isArray(mongoObjectFinal.data)) { - var buffer = new Buffer(mongoObjectFinal.data.length); - buffer.write(mongoObjectFinal.data.join(''), 'binary', 0); - this.data = new Binary(buffer); - } else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") { - this.data = mongoObjectFinal.data; - } else if(Buffer.isBuffer(mongoObjectFinal.data)) { - } else { - throw Error("Illegal chunk format"); - } - // Update position - this.internalPosition = 0; -}; - -/** - * Writes a data to this object and advance the read/write head. - * - * @param data {string} the data to write - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.write = function(data, callback) { - this.data.write(data, this.internalPosition); - this.internalPosition = this.data.length(); - if(callback != null) return callback(null, this); - return this; -}; - -/** - * Reads data and advances the read/write head. - * - * @param length {number} The length of data to read. - * - * @return {string} The data read if the given length will not exceed the end of - * the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.read = function(length) { - // Default to full read if no index defined - length = length == null || length == 0 ? this.length() : length; - - if(this.length() - this.internalPosition + 1 >= length) { - var data = this.data.read(this.internalPosition, length); - this.internalPosition = this.internalPosition + length; - return data; - } else { - return ''; - } -}; - -Chunk.prototype.readSlice = function(length) { - if ((this.length() - this.internalPosition) >= length) { - var data = null; - if (this.data.buffer != null) { //Pure BSON - data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length); - } else { //Native BSON - data = new Buffer(length); - length = this.data.readInto(data, this.internalPosition); - } - this.internalPosition = this.internalPosition + length; - return data; - } else { - return null; - } -}; - -/** - * Checks if the read/write head is at the end. - * - * @return {boolean} Whether the read/write head has reached the end of this - * chunk. - */ -Chunk.prototype.eof = function() { - return this.internalPosition == this.length() ? true : false; -}; - -/** - * Reads one character from the data of this chunk and advances the read/write - * head. - * - * @return {string} a single character data read if the the read/write head is - * not at the end of the chunk. Returns an empty String otherwise. - */ -Chunk.prototype.getc = function() { - return this.read(1); -}; - -/** - * Clears the contents of the data in this chunk and resets the read/write head - * to the initial position. - */ -Chunk.prototype.rewind = function() { - this.internalPosition = 0; - this.data = new Binary(); -}; - -/** - * Saves this chunk to the database. Also overwrites existing entries having the - * same id as this chunk. - * - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - */ -Chunk.prototype.save = function(callback) { - var self = this; - - self.file.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) { - if(err) return callback(err); - - if(self.data.length() > 0) { - self.buildMongoObject(function(mongoObject) { - collection.insert(mongoObject, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - } else { - callback(null, self); - } - }); - }); -}; - -/** - * Creates a mongoDB object representation of this chunk. - * - * @param callback {function(Object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this chunk
    - *          'files_id' : , // {number} foreign key to the file collection
    - *          'n' : , // {number} chunk number
    - *          'data' : , // {bson#Binary} the chunk data itself
    - *        }
    - *        
    - * - * @see MongoDB GridFS Chunk Object Structure - */ -Chunk.prototype.buildMongoObject = function(callback) { - var mongoObject = {'_id': this.objectId, - 'files_id': this.file.fileId, - 'n': this.chunkNumber, - 'data': this.data}; - callback(mongoObject); -}; - -/** - * @return {number} the length of the data - */ -Chunk.prototype.length = function() { - return this.data.length(); -}; - -/** - * The position of the read/write head - * @name position - * @lends Chunk# - * @field - */ -Object.defineProperty(Chunk.prototype, "position", { enumerable: true - , get: function () { - return this.internalPosition; - } - , set: function(value) { - this.internalPosition = value; - } -}); - -/** - * The default chunk size - * @constant - */ -Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js deleted file mode 100644 index aa695b723cd..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/grid.js +++ /dev/null @@ -1,103 +0,0 @@ -var GridStore = require('./gridstore').GridStore, - ObjectID = require('bson').ObjectID; - -/** - * A class representation of a simple Grid interface. - * - * @class Represents the Grid. - * @param {Db} db A database instance to interact with. - * @param {String} [fsName] optional different root collection for GridFS. - * @return {Grid} - */ -function Grid(db, fsName) { - - if(!(this instanceof Grid)) return new Grid(db, fsName); - - this.db = db; - this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName; -} - -/** - * Puts binary data to the grid - * - * Options - * - **_id** {Any}, unique id for this file - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @param {Buffer} data buffer with Binary Data. - * @param {Object} [options] the options for the files. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.put = function(data, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - options = args.length ? args.shift() : {}; - // If root is not defined add our default one - options['root'] = options['root'] == null ? this.fsName : options['root']; - - // Return if we don't have a buffer object as data - if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null); - // Get filename if we are using it - var filename = options['filename'] || null; - // Get id if we are using it - var id = options['_id'] || null; - // Create gridstore - var gridStore = new GridStore(this.db, id, filename, "w", options); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - gridStore.write(data, function(err, result) { - if(err) return callback(err, null); - - gridStore.close(function(err, result) { - if(err) return callback(err, null); - callback(null, result); - }) - }) - }) -} - -/** - * Get binary data to the grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.get = function(id, callback) { - // Create gridstore - var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName}); - gridStore.open(function(err, gridStore) { - if(err) return callback(err, null); - - // Return the data - gridStore.read(function(err, data) { - return callback(err, data) - }); - }) -} - -/** - * Delete file from grid - * - * @param {Any} id for file. - * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -Grid.prototype.delete = function(id, callback) { - // Create gridstore - GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) { - if(err) return callback(err, false); - return callback(null, true); - }); -} - -exports.Grid = Grid; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js deleted file mode 100644 index 615b22ecda5..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js +++ /dev/null @@ -1,1476 +0,0 @@ -/** - * @fileOverview GridFS is a tool for MongoDB to store files to the database. - * Because of the restrictions of the object size the database can hold, a - * facility to split a file into several chunks is needed. The {@link GridStore} - * class offers a simplified api to interact with files while managing the - * chunks of split files behind the scenes. More information about GridFS can be - * found here. - */ -var Chunk = require('./chunk').Chunk, - DbCommand = require('../commands/db_command').DbCommand, - ObjectID = require('bson').ObjectID, - Buffer = require('buffer').Buffer, - fs = require('fs'), - timers = require('timers'), - util = require('util'), - inherits = util.inherits, - ReadStream = require('./readstream').ReadStream, - Stream = require('stream'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -var REFERENCE_BY_FILENAME = 0, - REFERENCE_BY_ID = 1; - -/** - * A class representation of a file stored in GridFS. - * - * Modes - * - **"r"** - read only. This is the default mode. - * - **"w"** - write in truncate mode. Existing data will be overwriten. - * - **w+"** - write in edit mode. - * - * Options - * - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**. - * - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**. - * - **metadata** {Object}, arbitrary data the user wants to store. - * - * @class Represents the GridStore. - * @param {Db} db A database instance to interact with. - * @param {Any} [id] optional unique id for this file - * @param {String} [filename] optional filename for this file, no unique constrain on the field - * @param {String} mode set the mode for this file. - * @param {Object} options optional properties to specify. - * @return {GridStore} - */ -var GridStore = function GridStore(db, id, filename, mode, options) { - if(!(this instanceof GridStore)) return new GridStore(db, id, filename, mode, options); - - var self = this; - this.db = db; - - // Call stream constructor - if(typeof Stream == 'function') { - Stream.call(this); - } else { - // 0.4.X backward compatibility fix - Stream.Stream.call(this); - } - - // Handle options - if(typeof options === 'undefined') options = {}; - // Handle mode - if(typeof mode === 'undefined') { - mode = filename; - filename = undefined; - } else if(typeof mode == 'object') { - options = mode; - mode = filename; - filename = undefined; - } - - if(id instanceof ObjectID) { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } else if(typeof filename == 'undefined') { - this.referenceBy = REFERENCE_BY_FILENAME; - this.filename = id; - if (mode.indexOf('w') != null) { - this.fileId = new ObjectID(); - } - } else { - this.referenceBy = REFERENCE_BY_ID; - this.fileId = id; - this.filename = filename; - } - - // Set up the rest - this.mode = mode == null ? "r" : mode; - this.options = options == null ? {} : options; - this.root = this.options['root'] == null ? exports.GridStore.DEFAULT_ROOT_COLLECTION : this.options['root']; - this.position = 0; - // Set default chunk size - this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize']; -} - -/** - * Code for the streaming capabilities of the gridstore object - * Most code from Aaron heckmanns project https://github.com/aheckmann/gridfs-stream - * Modified to work on the gridstore object itself - * @ignore - */ -if(typeof Stream == 'function') { - GridStore.prototype = { __proto__: Stream.prototype } -} else { - // Node 0.4.X compatibility code - GridStore.prototype = { __proto__: Stream.Stream.prototype } -} - -// Move pipe to _pipe -GridStore.prototype._pipe = GridStore.prototype.pipe; - -/** - * Opens the file from the database and initialize this object. Also creates a - * new one if file does not exist. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain an **{Error}** object and the second parameter will be null if an error occured. Otherwise, the first parameter will be null and the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.open = function(callback) { - if( this.mode != "w" && this.mode != "w+" && this.mode != "r"){ - callback(new Error("Illegal mode " + this.mode), null); - return; - } - - var self = this; - - if((self.mode == "w" || self.mode == "w+") && self.db.serverConfig.primary != null) { - // Get files collection - self.collection(function(err, collection) { - if(err) return callback(err); - - // Put index on filename - collection.ensureIndex([['filename', 1]], function(err, index) { - if(err) return callback(err); - - // Get chunk collection - self.chunkCollection(function(err, chunkCollection) { - if(err) return callback(err); - - // Ensure index on chunk collection - chunkCollection.ensureIndex([['files_id', 1], ['n', 1]], function(err, index) { - if(err) return callback(err); - _open(self, callback); - }); - }); - }); - }); - } else { - // Open the gridstore - _open(self, callback); - } -}; - -/** - * Hidding the _open function - * @ignore - * @api private - */ -var _open = function(self, callback) { - self.collection(function(err, collection) { - if(err!==null) { - callback(new Error("at collection: "+err), null); - return; - } - - // Create the query - var query = self.referenceBy == REFERENCE_BY_ID ? {_id:self.fileId} : {filename:self.filename}; - query = null == self.fileId && this.filename == null ? null : query; - - // Fetch the chunks - if(query != null) { - collection.find(query, function(err, cursor) { - if(err) return error(err); - - // Fetch the file - cursor.nextObject(function(err, doc) { - if(err) return error(err); - - // Check if the collection for the files exists otherwise prepare the new one - if(doc != null) { - self.fileId = doc._id; - self.filename = doc.filename; - self.contentType = doc.contentType; - self.internalChunkSize = doc.chunkSize; - self.uploadDate = doc.uploadDate; - self.aliases = doc.aliases; - self.length = doc.length; - self.metadata = doc.metadata; - self.internalMd5 = doc.md5; - } else if (self.mode != 'r') { - self.fileId = self.fileId == null ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - } else { - self.length = 0; - var txtId = self.fileId instanceof ObjectID ? self.fileId.toHexString() : self.fileId; - return error(new Error((self.referenceBy == REFERENCE_BY_ID ? txtId : self.filename) + " does not exist", self)); - } - - // Process the mode of the object - if(self.mode == "r") { - nthChunk(self, 0, function(err, chunk) { - if(err) return error(err); - self.currentChunk = chunk; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - }); - } else { - // Write only mode - self.fileId = null == self.fileId ? new ObjectID() : self.fileId; - self.contentType = exports.GridStore.DEFAULT_CONTENT_TYPE; - self.internalChunkSize = self.internalChunkSize == null ? Chunk.DEFAULT_CHUNK_SIZE : self.internalChunkSize; - self.length = 0; - - self.chunkCollection(function(err, collection2) { - if(err) return error(err); - - // No file exists set up write mode - if(self.mode == "w") { - // Delete any existing chunks - deleteChunks(self, function(err, result) { - if(err) return error(err); - self.currentChunk = new Chunk(self, {'n':0}); - self.contentType = self.options['content_type'] == null ? self.contentType : self.options['content_type']; - self.internalChunkSize = self.options['chunk_size'] == null ? self.internalChunkSize : self.options['chunk_size']; - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = 0; - callback(null, self); - }); - } else if(self.mode == "w+") { - nthChunk(self, lastChunkNumber(self), function(err, chunk) { - if(err) return error(err); - // Set the current chunk - self.currentChunk = chunk == null ? new Chunk(self, {'n':0}) : chunk; - self.currentChunk.position = self.currentChunk.data.length(); - self.metadata = self.options['metadata'] == null ? self.metadata : self.options['metadata']; - self.position = self.length; - callback(null, self); - }); - } - }); - } - }); - - // only pass error to callback once - function error (err) { - if(error.err) return; - callback(error.err = err); - } -}; - -/** - * Stores a file from the file system to the GridFS database. - * - * @param {String|Buffer|FileHandle} file the file to store. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the the second will contain the reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.writeFile = function (file, callback) { - var self = this; - if (typeof file === 'string') { - fs.open(file, 'r', 0666, function (err, fd) { - if(err) return callback(err); - self.writeFile(fd, callback); - }); - return; - } - - self.open(function (err, self) { - if(err) return callback(err); - - fs.fstat(file, function (err, stats) { - if(err) return callback(err); - - var offset = 0; - var index = 0; - var numberOfChunksLeft = Math.min(stats.size / self.chunkSize); - - // Write a chunk - var writeChunk = function() { - fs.read(file, self.chunkSize, offset, 'binary', function(err, data, bytesRead) { - if(err) return callback(err); - - offset = offset + bytesRead; - - // Create a new chunk for the data - var chunk = new Chunk(self, {n:index++}); - chunk.write(data, function(err, chunk) { - if(err) return callback(err); - - chunk.save(function(err, result) { - if(err) return callback(err); - - self.position = self.position + data.length; - - // Point to current chunk - self.currentChunk = chunk; - - if(offset >= stats.size) { - fs.close(file); - self.close(callback); - } else { - return processor(writeChunk); - } - }); - }); - }); - } - - // Process the first write - processor(writeChunk); - }); - }); -}; - -/** - * Writes some data. This method will work properly only if initialized with mode - * "w" or "w+". - * - * @param string {string} The data to write. - * @param close {boolean=false} opt_argument Closes this file after writing if - * true. - * @param callback {function(*, GridStore)} This will be called after executing - * this method. The first parameter will contain null and the second one - * will contain a reference to this object. - * - * @ignore - * @api private - */ -var writeBuffer = function(self, buffer, close, callback) { - if(typeof close === "function") { callback = close; close = null; } - var finalClose = (close == null) ? false : close; - - if(self.mode[0] != "w") { - callback(new Error((self.referenceBy == REFERENCE_BY_ID ? self.toHexString() : self.filename) + " not opened for writing"), null); - } else { - if(self.currentChunk.position + buffer.length >= self.chunkSize) { - // Write out the current Chunk and then keep writing until we have less data left than a chunkSize left - // to a new chunk (recursively) - var previousChunkNumber = self.currentChunk.chunkNumber; - var leftOverDataSize = self.chunkSize - self.currentChunk.position; - var firstChunkData = buffer.slice(0, leftOverDataSize); - var leftOverData = buffer.slice(leftOverDataSize); - // A list of chunks to write out - var chunksToWrite = [self.currentChunk.write(firstChunkData)]; - // If we have more data left than the chunk size let's keep writing new chunks - while(leftOverData.length >= self.chunkSize) { - // Create a new chunk and write to it - var newChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - var firstChunkData = leftOverData.slice(0, self.chunkSize); - leftOverData = leftOverData.slice(self.chunkSize); - // Update chunk number - previousChunkNumber = previousChunkNumber + 1; - // Write data - newChunk.write(firstChunkData); - // Push chunk to save list - chunksToWrite.push(newChunk); - } - - // Set current chunk with remaining data - self.currentChunk = new Chunk(self, {'n': (previousChunkNumber + 1)}); - // If we have left over data write it - if(leftOverData.length > 0) self.currentChunk.write(leftOverData); - - // Update the position for the gridstore - self.position = self.position + buffer.length; - // Total number of chunks to write - var numberOfChunksToWrite = chunksToWrite.length; - // Write out all the chunks and then return - for(var i = 0; i < chunksToWrite.length; i++) { - var chunk = chunksToWrite[i]; - chunk.save(function(err, result) { - if(err) return callback(err); - - numberOfChunksToWrite = numberOfChunksToWrite - 1; - - if(numberOfChunksToWrite <= 0) { - return callback(null, self); - } - }) - } - } else { - // Update the position for the gridstore - self.position = self.position + buffer.length; - // We have less data than the chunk size just write it and callback - self.currentChunk.write(buffer); - callback(null, self); - } - } -}; - -/** - * Creates a mongoDB object representation of this object. - * - * @param callback {function(object)} This will be called after executing this - * method. The object will be passed to the first parameter and will have - * the structure: - * - *
    
    - *        {
    - *          '_id' : , // {number} id for this file
    - *          'filename' : , // {string} name for this file
    - *          'contentType' : , // {string} mime type for this file
    - *          'length' : , // {number} size of this file?
    - *          'chunksize' : , // {number} chunk size used by this file
    - *          'uploadDate' : , // {Date}
    - *          'aliases' : , // {array of string}
    - *          'metadata' : , // {string}
    - *        }
    - *        
    - * - * @ignore - * @api private - */ -var buildMongoObject = function(self, callback) { - // // Keeps the final chunk number - // var chunkNumber = 0; - // var previousChunkSize = 0; - // // Get the correct chunk Number, if we have an empty chunk return the previous chunk number - // if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) { - // chunkNumber = self.currentChunk.chunkNumber - 1; - // } else { - // chunkNumber = self.currentChunk.chunkNumber; - // previousChunkSize = self.currentChunk.position; - // } - - // // Calcuate the length - // var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0; - var mongoObject = { - '_id': self.fileId, - 'filename': self.filename, - 'contentType': self.contentType, - 'length': self.position ? self.position : 0, - 'chunkSize': self.chunkSize, - 'uploadDate': self.uploadDate, - 'aliases': self.aliases, - 'metadata': self.metadata - }; - - var md5Command = {filemd5:self.fileId, root:self.root}; - self.db.command(md5Command, function(err, results) { - mongoObject.md5 = results.md5; - callback(mongoObject); - }); -}; - -/** - * Saves this file to the database. This will overwrite the old entry if it - * already exists. This will work properly only if mode was initialized to - * "w" or "w+". - * - * @param {Function} callback this will be called after executing this method. Passes an **{Error}** object to the first parameter and null to the second if an error occured. Otherwise, passes null to the first and a reference to this object to the second. - * @return {null} - * @api public - */ -GridStore.prototype.close = function(callback) { - var self = this; - - if(self.mode[0] == "w") { - if(self.currentChunk != null && self.currentChunk.position > 0) { - self.currentChunk.save(function(err, chunk) { - if(err) return callback(err); - - self.collection(function(err, files) { - if(err) return callback(err); - - // Build the mongo object - if(self.uploadDate != null) { - files.remove({'_id':self.fileId}, {safe:true}, function(err, collection) { - if(err) return callback(err); - - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } else { - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - } - }); - }); - } else { - self.collection(function(err, files) { - if(err) return callback(err); - - self.uploadDate = new Date(); - buildMongoObject(self, function(mongoObject) { - files.save(mongoObject, {safe:true}, function(err) { - callback(err, mongoObject); - }); - }); - }); - } - } else if(self.mode[0] == "r") { - callback(null, null); - } else { - callback(new Error("Illegal mode " + self.mode), null); - } -}; - -/** - * Gets the nth chunk of this file. - * - * @param chunkNumber {number} The nth chunk to retrieve. - * @param callback {function(*, Chunk|object)} This will be called after - * executing this method. null will be passed to the first parameter while - * a new {@link Chunk} instance will be passed to the second parameter if - * the chunk was found or an empty object {} if not. - * - * @ignore - * @api private - */ -var nthChunk = function(self, chunkNumber, callback) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err); - - collection.find({'files_id':self.fileId, 'n':chunkNumber}, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, chunk) { - if(err) return callback(err); - - var finalChunk = chunk == null ? {} : chunk; - callback(null, new Chunk(self, finalChunk)); - }); - }); - }); -}; - -/** - * - * @ignore - * @api private - */ -GridStore.prototype._nthChunk = function(chunkNumber, callback) { - nthChunk(this, chunkNumber, callback); -} - -/** - * @return {Number} The last chunk number of this file. - * - * @ignore - * @api private - */ -var lastChunkNumber = function(self) { - return Math.floor(self.length/self.chunkSize); -}; - -/** - * Retrieve this file's chunks collection. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.chunkCollection = function(callback) { - this.db.collection((this.root + ".chunks"), callback); -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param callback {function(*, boolean)} This will be called after this method - * executes. Passes null to the first and true to the second argument. - * - * @ignore - * @api private - */ -var deleteChunks = function(self, callback) { - if(self.fileId != null) { - self.chunkCollection(function(err, collection) { - if(err) return callback(err, false); - collection.remove({'files_id':self.fileId}, {safe:true}, function(err, result) { - if(err) return callback(err, false); - callback(null, true); - }); - }); - } else { - callback(null, true); - } -}; - -/** - * Deletes all the chunks of this file in the database. - * - * @param {Function} callback this will be called after this method executes. Passes null to the first and true to the second argument. - * @return {null} - * @api public - */ -GridStore.prototype.unlink = function(callback) { - var self = this; - deleteChunks(this, function(err) { - if(err!==null) { - err.message = "at deleteChunks: " + err.message; - return callback(err); - } - - self.collection(function(err, collection) { - if(err!==null) { - err.message = "at collection: " + err.message; - return callback(err); - } - - collection.remove({'_id':self.fileId}, {safe:true}, function(err) { - callback(err, self); - }); - }); - }); -}; - -/** - * Retrieves the file collection associated with this object. - * - * @param {Function} callback this will be called after executing this method. An exception object will be passed to the first parameter when an error occured or null otherwise. A new **{Collection}** object will be passed to the second parameter if no error occured. - * @return {null} - * @api public - */ -GridStore.prototype.collection = function(callback) { - this.db.collection(this.root + ".files", callback); -}; - -/** - * Reads the data of this file. - * - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Function} callback This will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.prototype.readlines = function(separator, callback) { - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - separator = args.length ? args.shift() : "\n"; - - this.read(function(err, data) { - if(err) return callback(err); - - var items = data.toString().split(separator); - items = items.length > 0 ? items.splice(0, items.length - 1) : []; - for(var i = 0; i < items.length; i++) { - items[i] = items[i] + separator; - } - - callback(null, items); - }); -}; - -/** - * Deletes all the chunks of this file in the database if mode was set to "w" or - * "w+" and resets the read/write head to the initial position. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.rewind = function(callback) { - var self = this; - - if(this.currentChunk.chunkNumber != 0) { - if(this.mode[0] == "w") { - deleteChunks(self, function(err, gridStore) { - if(err) return callback(err); - self.currentChunk = new Chunk(self, {'n': 0}); - self.position = 0; - callback(null, self); - }); - } else { - self.currentChunk(0, function(err, chunk) { - if(err) return callback(err); - self.currentChunk = chunk; - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - }); - } - } else { - self.currentChunk.rewind(); - self.position = 0; - callback(null, self); - } -}; - -/** - * Retrieves the contents of this file and advances the read/write head. Works with Buffers only. - * - * There are 3 signatures for this method: - * - * (callback) - * (length, callback) - * (length, buffer, callback) - * - * @param {Number} [length] the number of characters to read. Reads all the characters from the read/write head to the EOF if not specified. - * @param {String|Buffer} [buffer] a string to hold temporary data. This is used for storing the string data read so far when recursively calling this method. - * @param {Function} callback this will be called after this method is executed. null will be passed to the first parameter and a string containing the contents of the buffer concatenated with the contents read from this file will be passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.read = function(length, buffer, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 0); - callback = args.pop(); - length = args.length ? args.shift() : null; - buffer = args.length ? args.shift() : null; - - // The data is a c-terminated string and thus the length - 1 - var finalLength = length == null ? self.length - self.position : length; - var finalBuffer = buffer == null ? new Buffer(finalLength) : buffer; - // Add a index to buffer to keep track of writing position or apply current index - finalBuffer._index = buffer != null && buffer._index != null ? buffer._index : 0; - - if((self.currentChunk.length() - self.currentChunk.position + finalBuffer._index) >= finalLength) { - var slice = self.currentChunk.readSlice(finalLength - finalBuffer._index); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update internal position - self.position = self.position + finalBuffer.length; - // Check if we don't have a file at all - if(finalLength == 0 && finalBuffer.length == 0) return callback(new Error("File does not exist"), null); - // Else return data - callback(null, finalBuffer); - } else { - var slice = self.currentChunk.readSlice(self.currentChunk.length() - self.currentChunk.position); - // Copy content to final buffer - slice.copy(finalBuffer, finalBuffer._index); - // Update index position - finalBuffer._index += slice.length; - - // Load next chunk and read more - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) return callback(err); - - if(chunk.length() > 0) { - self.currentChunk = chunk; - self.read(length, finalBuffer, callback); - } else { - if (finalBuffer._index > 0) { - callback(null, finalBuffer) - } else { - callback(new Error("no chunks found for file, possibly corrupt"), null); - } - } - }); - } -} - -/** - * Retrieves the position of the read/write head of this file. - * - * @param {Function} callback This gets called after this method terminates. null is passed to the first parameter and the position is passed to the second. - * @return {null} - * @api public - */ -GridStore.prototype.tell = function(callback) { - callback(null, this.position); -}; - -/** - * Moves the read/write head to a new location. - * - * There are 3 signatures for this method - * - * Seek Location Modes - * - **GridStore.IO_SEEK_SET**, **(default)** set the position from the start of the file. - * - **GridStore.IO_SEEK_CUR**, set the position from the current position in the file. - * - **GridStore.IO_SEEK_END**, set the position from the end of the file. - * - * @param {Number} [position] the position to seek to - * @param {Number} [seekLocation] seek mode. Use one of the Seek Location modes. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.seek = function(position, seekLocation, callback) { - var self = this; - - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - seekLocation = args.length ? args.shift() : null; - - var seekLocationFinal = seekLocation == null ? exports.GridStore.IO_SEEK_SET : seekLocation; - var finalPosition = position; - var targetPosition = 0; - - // console.dir(targetPosition) - - // Calculate the position - if(seekLocationFinal == exports.GridStore.IO_SEEK_CUR) { - targetPosition = self.position + finalPosition; - } else if(seekLocationFinal == exports.GridStore.IO_SEEK_END) { - targetPosition = self.length + finalPosition; - } else { - targetPosition = finalPosition; - } - - // Get the chunk - var newChunkNumber = Math.floor(targetPosition/self.chunkSize); - if(newChunkNumber != self.currentChunk.chunkNumber) { - var seekChunk = function() { - nthChunk(self, newChunkNumber, function(err, chunk) { - self.currentChunk = chunk; - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(err, self); - }); - }; - - if(self.mode[0] == 'w') { - self.currentChunk.save(function(err) { - if(err) return callback(err); - seekChunk(); - }); - } else { - seekChunk(); - } - } else { - self.position = targetPosition; - self.currentChunk.position = (self.position % self.chunkSize); - callback(null, self); - } -}; - -/** - * Verify if the file is at EOF. - * - * @return {Boolean} true if the read/write head is at the end of this file. - * @api public - */ -GridStore.prototype.eof = function() { - return this.position == this.length ? true : false; -}; - -/** - * Retrieves a single character from this file. - * - * @param {Function} callback this gets called after this method is executed. Passes null to the first parameter and the character read to the second or null to the second if the read/write head is at the end of the file. - * @return {null} - * @api public - */ -GridStore.prototype.getc = function(callback) { - var self = this; - - if(self.eof()) { - callback(null, null); - } else if(self.currentChunk.eof()) { - nthChunk(self, self.currentChunk.chunkNumber + 1, function(err, chunk) { - self.currentChunk = chunk; - self.position = self.position + 1; - callback(err, self.currentChunk.getc()); - }); - } else { - self.position = self.position + 1; - callback(null, self.currentChunk.getc()); - } -}; - -/** - * Writes a string to the file with a newline character appended at the end if - * the given string does not have one. - * - * @param {String} string the string to write. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.puts = function(string, callback) { - var finalString = string.match(/\n$/) == null ? string + "\n" : string; - this.write(finalString, callback); -}; - -/** - * Returns read stream based on this GridStore file - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @param {Boolean} autoclose if true current GridStore will be closed when EOF and 'close' event will be fired - * @return {null} - * @api public - */ -GridStore.prototype.stream = function(autoclose) { - return new ReadStream(autoclose, this); -}; - -/** -* The collection to be used for holding the files and chunks collection. -* -* @classconstant DEFAULT_ROOT_COLLECTION -**/ -GridStore.DEFAULT_ROOT_COLLECTION = 'fs'; - -/** -* Default file mime type -* -* @classconstant DEFAULT_CONTENT_TYPE -**/ -GridStore.DEFAULT_CONTENT_TYPE = 'binary/octet-stream'; - -/** -* Seek mode where the given length is absolute. -* -* @classconstant IO_SEEK_SET -**/ -GridStore.IO_SEEK_SET = 0; - -/** -* Seek mode where the given length is an offset to the current read/write head. -* -* @classconstant IO_SEEK_CUR -**/ -GridStore.IO_SEEK_CUR = 1; - -/** -* Seek mode where the given length is an offset to the end of the file. -* -* @classconstant IO_SEEK_END -**/ -GridStore.IO_SEEK_END = 2; - -/** - * Checks if a file exists in the database. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file to look for. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes true to the second if the file exists and false otherwise. - * @return {null} - * @api public - */ -GridStore.exist = function(db, fileIdObject, rootCollection, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - - // Fetch collection - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - db.collection(rootCollectionFinal + ".files", function(err, collection) { - if(err) return callback(err); - - // Build query - var query = (typeof fileIdObject == 'string' || Object.prototype.toString.call(fileIdObject) == '[object RegExp]' ) - ? {'filename':fileIdObject} - : {'_id':fileIdObject}; // Attempt to locate file - - collection.find(query, function(err, cursor) { - if(err) return callback(err); - - cursor.nextObject(function(err, item) { - if(err) return callback(err); - callback(null, item == null ? false : true); - }); - }); - }); -}; - -/** - * Gets the list of files stored in the GridFS. - * - * @param {Db} db the database to query. - * @param {String} [rootCollection] the root collection that holds the files and chunks collection. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**. - * @param {Function} callback this will be called after this method executes. Passes null to the first and passes an array of strings containing the names of the files. - * @return {null} - * @api public - */ -GridStore.list = function(db, rootCollection, options, callback) { - var args = Array.prototype.slice.call(arguments, 1); - callback = args.pop(); - rootCollection = args.length ? args.shift() : null; - options = args.length ? args.shift() : {}; - - // Ensure we have correct values - if(rootCollection != null && typeof rootCollection == 'object') { - options = rootCollection; - rootCollection = null; - } - - // Check if we are returning by id not filename - var byId = options['id'] != null ? options['id'] : false; - // Fetch item - var rootCollectionFinal = rootCollection != null ? rootCollection : GridStore.DEFAULT_ROOT_COLLECTION; - var items = []; - db.collection((rootCollectionFinal + ".files"), function(err, collection) { - if(err) return callback(err); - - collection.find(function(err, cursor) { - if(err) return callback(err); - - cursor.each(function(err, item) { - if(item != null) { - items.push(byId ? item._id : item.filename); - } else { - callback(err, items); - } - }); - }); - }); -}; - -/** - * Reads the contents of a file. - * - * This method has the following signatures - * - * (db, name, callback) - * (db, name, length, callback) - * (db, name, length, offset, callback) - * (db, name, length, offset, options, callback) - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {Number} [length] the size of data to read. - * @param {Number} [offset] the offset from the head of the file of which to start reading from. - * @param {Object} [options] the options for the file. - * @param {Function} callback this will be called after this method executes. A string with an error message will be passed to the first parameter when the length and offset combination exceeds the length of the file while an Error object will be passed if other forms of error occured, otherwise, a string is passed. The second parameter will contain the data read if successful or null if an error occured. - * @return {null} - * @api public - */ -GridStore.read = function(db, name, length, offset, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - length = args.length ? args.shift() : null; - offset = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - // Make sure we are not reading out of bounds - if(offset && offset >= gridStore.length) return callback("offset larger than size of file", null); - if(length && length > gridStore.length) return callback("length is larger than the size of the file", null); - if(offset && length && (offset + length) > gridStore.length) return callback("offset and length is larger than the size of the file", null); - - if(offset != null) { - gridStore.seek(offset, function(err, gridStore) { - if(err) return callback(err); - gridStore.read(length, callback); - }); - } else { - gridStore.read(length, callback); - } - }); -}; - -/** - * Reads the data of this file. - * - * @param {Db} db the database to query. - * @param {String} name the name of the file. - * @param {String} [separator] the character to be recognized as the newline separator. - * @param {Object} [options] file options. - * @param {Function} callback this will be called after this method is executed. The first parameter will be null and the second parameter will contain an array of strings representing the entire data, each element representing a line including the separator character. - * @return {null} - * @api public - */ -GridStore.readlines = function(db, name, separator, options, callback) { - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - separator = args.length ? args.shift() : null; - options = args.length ? args.shift() : null; - - var finalSeperator = separator == null ? "\n" : separator; - new GridStore(db, name, "r", options).open(function(err, gridStore) { - if(err) return callback(err); - gridStore.readlines(finalSeperator, callback); - }); -}; - -/** - * Deletes the chunks and metadata information of a file from GridFS. - * - * @param {Db} db the database to interact with. - * @param {String|Array} names the name/names of the files to delete. - * @param {Object} [options] the options for the files. - * @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.unlink = function(db, names, options, callback) { - var self = this; - var args = Array.prototype.slice.call(arguments, 2); - callback = args.pop(); - options = args.length ? args.shift() : null; - - if(names.constructor == Array) { - var tc = 0; - for(var i = 0; i < names.length; i++) { - ++tc; - self.unlink(db, names[i], function(result) { - if(--tc == 0) { - callback(null, self); - } - }); - } - } else { - new GridStore(db, names, "w", options).open(function(err, gridStore) { - if(err) return callback(err); - deleteChunks(gridStore, function(err, result) { - if(err) return callback(err); - gridStore.collection(function(err, collection) { - if(err) return callback(err); - collection.remove({'_id':gridStore.fileId}, {safe:true}, function(err, collection) { - callback(err, self); - }); - }); - }); - }); - } -}; - -/** - * Returns the current chunksize of the file. - * - * @field chunkSize - * @type {Number} - * @getter - * @setter - * @property return number of bytes in the current chunkSize. - */ -Object.defineProperty(GridStore.prototype, "chunkSize", { enumerable: true - , get: function () { - return this.internalChunkSize; - } - , set: function(value) { - if(!(this.mode[0] == "w" && this.position == 0 && this.uploadDate == null)) { - this.internalChunkSize = this.internalChunkSize; - } else { - this.internalChunkSize = value; - } - } -}); - -/** - * The md5 checksum for this file. - * - * @field md5 - * @type {Number} - * @getter - * @setter - * @property return this files md5 checksum. - */ -Object.defineProperty(GridStore.prototype, "md5", { enumerable: true - , get: function () { - return this.internalMd5; - } -}); - -/** - * GridStore Streaming methods - * Handles the correct return of the writeable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "writable", { enumerable: true - , get: function () { - if(this._writeable == null) { - this._writeable = this.mode != null && this.mode.indexOf("w") != -1; - } - // Return the _writeable - return this._writeable; - } - , set: function(value) { - this._writeable = value; - } -}); - -/** - * Handles the correct return of the readable stream status - * @ignore - */ -Object.defineProperty(GridStore.prototype, "readable", { enumerable: true - , get: function () { - if(this._readable == null) { - this._readable = this.mode != null && this.mode.indexOf("r") != -1; - } - return this._readable; - } - , set: function(value) { - this._readable = value; - } -}); - -GridStore.prototype.paused; - -/** - * Handles the correct setting of encoding for the stream - * @ignore - */ -GridStore.prototype.setEncoding = fs.ReadStream.prototype.setEncoding; - -/** - * Handles the end events - * @ignore - */ -GridStore.prototype.end = function end(data) { - var self = this; - // allow queued data to write before closing - if(!this.writable) return; - this.writable = false; - - if(data) { - this._q.push(data); - } - - this.on('drain', function () { - self.close(function (err) { - if (err) return _error(self, err); - self.emit('close'); - }); - }); - - _flush(self); -} - -/** - * Handles the normal writes to gridstore - * @ignore - */ -var _writeNormal = function(self, data, close, callback) { - // If we have a buffer write it using the writeBuffer method - if(Buffer.isBuffer(data)) { - return writeBuffer(self, data, close, callback); - } else { - // Wrap the string in a buffer and write - return writeBuffer(self, new Buffer(data, 'binary'), close, callback); - } -} - -/** - * Writes some data. This method will work properly only if initialized with mode "w" or "w+". - * - * @param {String|Buffer} data the data to write. - * @param {Boolean} [close] closes this file after writing if set to true. - * @param {Function} callback this will be called after executing this method. The first parameter will contain null and the second one will contain a reference to this object. - * @return {null} - * @api public - */ -GridStore.prototype.write = function write(data, close, callback) { - // If it's a normal write delegate the call - if(typeof close == 'function' || typeof callback == 'function') { - return _writeNormal(this, data, close, callback); - } - - // Otherwise it's a stream write - var self = this; - if (!this.writable) { - throw new Error('GridWriteStream is not writable'); - } - - // queue data until we open. - if (!this._opened) { - // Set up a queue to save data until gridstore object is ready - this._q = []; - _openStream(self); - this._q.push(data); - return false; - } - - // Push data to queue - this._q.push(data); - _flush(this); - // Return write successful - return true; -} - -/** - * Handles the destroy part of a stream - * @ignore - */ -GridStore.prototype.destroy = function destroy() { - // close and do not emit any more events. queued data is not sent. - if(!this.writable) return; - this.readable = false; - if(this.writable) { - this.writable = false; - this._q.length = 0; - this.emit('close'); - } -} - -/** - * Handles the destroySoon part of a stream - * @ignore - */ -GridStore.prototype.destroySoon = function destroySoon() { - // as soon as write queue is drained, destroy. - // may call destroy immediately if no data is queued. - if(!this._q.length) { - return this.destroy(); - } - this._destroying = true; -} - -/** - * Handles the pipe part of the stream - * @ignore - */ -GridStore.prototype.pipe = function(destination, options) { - var self = this; - // Open the gridstore - this.open(function(err, result) { - if(err) _errorRead(self, err); - if(!self.readable) return; - // Set up the pipe - self._pipe(destination, options); - // Emit the stream is open - self.emit('open'); - // Read from the stream - _read(self); - }) -} - -/** - * Internal module methods - * @ignore - */ -var _read = function _read(self) { - if (!self.readable || self.paused || self.reading) { - return; - } - - self.reading = true; - var stream = self._stream = self.stream(); - stream.paused = self.paused; - - stream.on('data', function (data) { - if (self._decoder) { - var str = self._decoder.write(data); - if (str.length) self.emit('data', str); - } else { - self.emit('data', data); - } - }); - - stream.on('end', function (data) { - self.emit('end', data); - }); - - stream.on('error', function (data) { - _errorRead(self, data); - }); - - stream.on('close', function (data) { - self.emit('close', data); - }); - - self.pause = function () { - // native doesn't always pause. - // bypass its pause() method to hack it - self.paused = stream.paused = true; - } - - self.resume = function () { - if(!self.paused) return; - - self.paused = false; - stream.resume(); - self.readable = stream.readable; - } - - self.destroy = function () { - self.readable = false; - stream.destroy(); - } -} - -/** - * pause - * @ignore - */ -GridStore.prototype.pause = function pause () { - // Overridden when the GridStore opens. - this.paused = true; -} - -/** - * resume - * @ignore - */ -GridStore.prototype.resume = function resume () { - // Overridden when the GridStore opens. - this.paused = false; -} - -/** - * Internal module methods - * @ignore - */ -var _flush = function _flush(self, _force) { - if (!self._opened) return; - if (!_force && self._flushing) return; - self._flushing = true; - - // write the entire q to gridfs - if (!self._q.length) { - self._flushing = false; - self.emit('drain'); - - if(self._destroying) { - self.destroy(); - } - return; - } - - self.write(self._q.shift(), function (err, store) { - if (err) return _error(self, err); - self.emit('progress', store.position); - _flush(self, true); - }); -} - -var _openStream = function _openStream (self) { - if(self._opening == true) return; - self._opening = true; - - // Open the store - self.open(function (err, gridstore) { - if (err) return _error(self, err); - self._opened = true; - self.emit('open'); - _flush(self); - }); -} - -var _error = function _error(self, err) { - self.destroy(); - self.emit('error', err); -} - -var _errorRead = function _errorRead (self, err) { - self.readable = false; - self.emit('error', err); -} - -/** - * @ignore - * @api private - */ -exports.GridStore = GridStore; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js deleted file mode 100644 index 8ff99731ea0..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/gridfs/readstream.js +++ /dev/null @@ -1,193 +0,0 @@ -var Stream = require('stream').Stream, - timers = require('timers'), - util = require('util'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - * ReadStream - * - * Returns a stream interface for the **file**. - * - * Events - * - **data** {function(item) {}} the data event triggers when a document is ready. - * - **end** {function() {}} the end event triggers when there is no more documents available. - * - **close** {function() {}} the close event triggers when the stream is closed. - * - **error** {function(err) {}} the error event triggers if an error happens. - * - * @class Represents a GridFS File Stream. - * @param {Boolean} autoclose automatically close file when the stream reaches the end. - * @param {GridStore} cursor a cursor object that the stream wraps. - * @return {ReadStream} - */ -function ReadStream(autoclose, gstore) { - if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore); - Stream.call(this); - - this.autoclose = !!autoclose; - this.gstore = gstore; - - this.finalLength = gstore.length - gstore.position; - this.completedLength = 0; - this.currentChunkNumber = gstore.currentChunk.chunkNumber; - - this.paused = false; - this.readable = true; - this.pendingChunk = null; - this.executing = false; - - // Calculate the number of chunks - this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize); - - // This seek start position inside the current chunk - this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize); - - var self = this; - processor(function() { - self._execute(); - }); -}; - -/** - * Inherit from Stream - * @ignore - * @api private - */ -ReadStream.prototype.__proto__ = Stream.prototype; - -/** - * Flag stating whether or not this stream is readable. - */ -ReadStream.prototype.readable; - -/** - * Flag stating whether or not this stream is paused. - */ -ReadStream.prototype.paused; - -/** - * @ignore - * @api private - */ -ReadStream.prototype._execute = function() { - if(this.paused === true || this.readable === false) { - return; - } - - var gstore = this.gstore; - var self = this; - // Set that we are executing - this.executing = true; - - var last = false; - var toRead = 0; - - if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) { - self.executing = false; - last = true; - } - - // Data setup - var data = null; - - // Read a slice (with seek set if none) - if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition); - this.seekStartPosition = 0; - } else { - data = gstore.currentChunk.readSlice(gstore.currentChunk.length()); - } - - // Return the data - if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) { - self.currentChunkNumber = self.currentChunkNumber + 1; - self.completedLength += data.length; - self.pendingChunk = null; - self.emit("data", data); - } - - if(last === true) { - self.readable = false; - self.emit("end"); - - if(self.autoclose === true) { - if(gstore.mode[0] == "w") { - gstore.close(function(err, doc) { - if (err) { - self.emit("error", err); - return; - } - self.readable = false; - self.emit("close", doc); - }); - } else { - self.readable = false; - self.emit("close"); - } - } - } else { - gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) { - if(err) { - self.readable = false; - self.emit("error", err); - self.executing = false; - return; - } - - self.pendingChunk = chunk; - if(self.paused === true) { - self.executing = false; - return; - } - - gstore.currentChunk = self.pendingChunk; - self._execute(); - }); - } -}; - -/** - * Pauses this stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.pause = function() { - if(!this.executing) { - this.paused = true; - } -}; - -/** - * Destroys the stream, then no farther events will be fired. - * - * @ignore - * @api public - */ -ReadStream.prototype.destroy = function() { - this.readable = false; - // Emit close event - this.emit("close"); -}; - -/** - * Resumes this stream. - * - * @ignore - * @api public - */ -ReadStream.prototype.resume = function() { - if(this.paused === false || !this.readable) { - return; - } - - this.paused = false; - var self = this; - processor(function() { - self._execute(); - }); -}; - -exports.ReadStream = ReadStream; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js deleted file mode 100644 index 6a2b72759dc..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/index.js +++ /dev/null @@ -1,69 +0,0 @@ -try { - exports.BSONPure = require('bson').BSONPure; - exports.BSONNative = require('bson').BSONNative; -} catch(err) { - // do nothing -} - -[ 'commands/base_command' - , 'admin' - , 'collection' - , 'connection/read_preference' - , 'connection/connection' - , 'connection/server' - , 'connection/mongos' - , 'connection/repl_set' - , 'mongo_client' - , 'cursor' - , 'db' - , 'mongo_client' - , 'gridfs/grid' - , 'gridfs/chunk' - , 'gridfs/gridstore'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } - - // backwards compat - exports.ReplSetServers = exports.ReplSet; - - // Add BSON Classes - exports.Binary = require('bson').Binary; - exports.Code = require('bson').Code; - exports.DBRef = require('bson').DBRef; - exports.Double = require('bson').Double; - exports.Long = require('bson').Long; - exports.MinKey = require('bson').MinKey; - exports.MaxKey = require('bson').MaxKey; - exports.ObjectID = require('bson').ObjectID; - exports.Symbol = require('bson').Symbol; - exports.Timestamp = require('bson').Timestamp; - - // Add BSON Parser - exports.BSON = require('bson').BSONPure.BSON; - -}); - -// Get the Db object -var Db = require('./db').Db; -// Set up the connect function -var connect = Db.connect; -var obj = connect; -// Map all values to the exports value -for(var name in exports) { - obj[name] = exports[name]; -} - -// Add the pure and native backward compatible functions -exports.pure = exports.native = function() { - return obj; -} - -// Map all values to the exports value -for(var name in exports) { - connect[name] = exports[name]; -} - -// Set our exports to be the connect function -module.exports = connect; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js deleted file mode 100644 index f1f3a8da62b..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/mongo_client.js +++ /dev/null @@ -1,116 +0,0 @@ -var Db = require('./db').Db; - -/** - * Create a new MongoClient instance. - * - * Options - * - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write - * - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option) - * - **fsync**, (Boolean, default:false) write waits for fsync before returning - * - **journal**, (Boolean, default:false) write waits for journal sync before returning - * - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). - * - **native_parser** {Boolean, default:false}, use c++ bson parser. - * - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client. - * - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation. - * - **serializeFunctions** {Boolean, default:false}, serialize functions. - * - **raw** {Boolean, default:false}, peform operations using raw bson buffers. - * - **recordQueryStats** {Boolean, default:false}, record query statistics during execution. - * - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries. - * - **numberOfRetries** {Number, default:5}, number of retries off connection. - * - * Deprecated Options - * - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB. - * - * @class Represents a MongoClient - * @param {Object} serverConfig server config object. - * @param {Object} [options] additional options for the collection. - */ -function MongoClient(serverConfig, options) { - options = options == null ? {} : options; - // If no write concern is set set the default to w:1 - if(options != null && !options.journal && !options.w && !options.fsync) { - options.w = 1; - } - - // The internal db instance we are wrapping - this._db = new Db('test', serverConfig, options); -} - -/** - * Initialize the database connection. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the connected mongoclient or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.open = function(callback) { - // Self reference - var self = this; - - this._db.open(function(err, db) { - if(err) return callback(err, null); - callback(null, self); - }) -} - -/** - * Close the current db connection, including all the child db instances. Emits close event if no callback is provided. - * - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the close method or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.prototype.close = function(callback) { - this._db.close(callback); -} - -/** - * Create a new Db instance sharing the current socket connections. - * - * @param {String} dbName the name of the database we want to use. - * @return {Db} a db instance using the new database. - * @api public - */ -MongoClient.prototype.db = function(dbName) { - return this._db.db(dbName); -} - -/** - * Connect to MongoDB using a url as documented at - * - * docs.mongodb.org/manual/reference/connection-string/ - * - * Options - * - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication - * - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor** - * - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor** - * - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor** - * - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor** - * - * @param {String} url connection url for MongoDB. - * @param {Object} [options] optional options for insert command - * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured. - * @return {null} - * @api public - */ -MongoClient.connect = function(url, options, callback) { - if(typeof options == 'function') { - callback = options; - options = {}; - } - - Db.connect(url, options, function(err, db) { - if(err) return callback(err, null); - - if(db.options !== null && !db.options.safe && !db.options.journal - && !db.options.w && !db.options.fsync && typeof db.options.w != 'number' - && (db.options.safe == false && url.indexOf("safe=") == -1)) { - db.options.w = 1; - } - - // Return the db - callback(null, db); - }); -} - -exports.MongoClient = MongoClient; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js deleted file mode 100644 index 743618fa4c6..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js +++ /dev/null @@ -1,145 +0,0 @@ -var Long = require('bson').Long - , timers = require('timers'); - -// Set processor, setImmediate if 0.10 otherwise nextTick -var processor = timers.setImmediate ? timers.setImmediate : process.nextTick; -processor = process.nextTick - -/** - Reply message from mongo db -**/ -var MongoReply = exports.MongoReply = function() { - this.documents = []; - this.index = 0; -}; - -MongoReply.prototype.parseHeader = function(binary_reply, bson) { - // Unpack the standard header first - this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the request id for this reply - this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Fetch the id of the request that triggered the response - this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // Skip op-code field - this.index = this.index + 4 + 4; - // Unpack the reply message - this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the cursor id (a 64 bit long integer) - var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - this.cursorId = new Long(low_bits, high_bits); - // Unpack the starting from - this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; - // Unpack the number of objects returned - this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - this.index = this.index + 4; -} - -MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) { - raw = raw == null ? false : raw; - // Just set a doc limit for deserializing - var docLimitSize = 1024*20; - - // If our message length is very long, let's switch to process.nextTick for messages - if(this.messageLength > docLimitSize) { - var batchSize = this.numberReturned; - this.documents = new Array(this.numberReturned); - - // Just walk down until we get a positive number >= 1 - for(var i = 50; i > 0; i--) { - if((this.numberReturned/i) >= 1) { - batchSize = i; - break; - } - } - - // Actual main creator of the processFunction setting internal state to control the flow - var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) { - var object_index = 0; - // Internal loop process that will use nextTick to ensure we yield some time - var processFunction = function() { - // Adjust batchSize if we have less results left than batchsize - if((_numberReturned - object_index) < _batchSize) { - _batchSize = _numberReturned - object_index; - } - - // If raw just process the entries - if(raw) { - // Iterate over the batch - for(var i = 0; i < _batchSize; i++) { - // Are we done ? - if(object_index <= _numberReturned) { - // Read the size of the bson object - var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - _self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize); - // Adjust binary index to point to next block of binary bson data - _self.index = _self.index + bsonObjectSize; - // Update number of docs parsed - object_index = object_index + 1; - } - } - } else { - try { - // Parse documents - _self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index); - // Adjust index - object_index = object_index + _batchSize; - } catch (err) { - return callback(err); - } - } - - // If we hav more documents process NextTick - if(object_index < _numberReturned) { - processor(processFunction); - } else { - callback(null); - } - } - - // Return the process function - return processFunction; - }(this, binary_reply, batchSize, this.numberReturned)(); - } else { - try { - // Let's unpack all the bson documents, deserialize them and store them - for(var object_index = 0; object_index < this.numberReturned; object_index++) { - // Read the size of the bson object - var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24; - // If we are storing the raw responses to pipe straight through - if(raw) { - // Deserialize the object and add to the documents array - this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize)); - } else { - // Deserialize the object and add to the documents array - this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize))); - } - // Adjust binary index to point to next block of binary bson data - this.index = this.index + bsonObjectSize; - } - } catch(err) { - return callback(err); - } - - // No error return - callback(null); - } -} - -MongoReply.prototype.is_error = function(){ - if(this.documents.length == 1) { - return this.documents[0].ok == 1 ? false : true; - } - return false; -}; - -MongoReply.prototype.error_message = function() { - return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg; -}; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js deleted file mode 100644 index a67aca5172f..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/utils.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Sort functions, Normalize and prepare sort parameters - */ -var formatSortValue = exports.formatSortValue = function(sortDirection) { - var value = ("" + sortDirection).toLowerCase(); - - switch (value) { - case 'ascending': - case 'asc': - case '1': - return 1; - case 'descending': - case 'desc': - case '-1': - return -1; - default: - throw new Error("Illegal sort clause, must be of the form " - + "[['field1', '(ascending|descending)'], " - + "['field2', '(ascending|descending)']]"); - } -}; - -var formattedOrderClause = exports.formattedOrderClause = function(sortValue) { - var orderBy = {}; - - if (Array.isArray(sortValue)) { - for(var i = 0; i < sortValue.length; i++) { - if(sortValue[i].constructor == String) { - orderBy[sortValue[i]] = 1; - } else { - orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]); - } - } - } else if(Object.prototype.toString.call(sortValue) === '[object Object]') { - orderBy = sortValue; - } else if (sortValue.constructor == String) { - orderBy[sortValue] = 1; - } else { - throw new Error("Illegal sort clause, must be of the form " + - "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]"); - } - - return orderBy; -}; - -exports.encodeInt = function(value) { - var buffer = new Buffer(4); - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = value & 0xff; - return buffer; -} - -exports.encodeIntInPlace = function(value, buffer, index) { - buffer[index + 3] = (value >> 24) & 0xff; - buffer[index + 2] = (value >> 16) & 0xff; - buffer[index + 1] = (value >> 8) & 0xff; - buffer[index] = value & 0xff; -} - -exports.encodeCString = function(string) { - var buf = new Buffer(string, 'utf8'); - return [buf, new Buffer([0])]; -} - -exports.decodeUInt32 = function(array, index) { - return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24; -} - -// Decode the int -exports.decodeUInt8 = function(array, index) { - return array[index]; -} - -/** - * Context insensitive type checks - */ - -var toString = Object.prototype.toString; - -exports.isObject = function (arg) { - return '[object Object]' == toString.call(arg) -} - -exports.isArray = function (arg) { - return Array.isArray(arg) || - 'object' == typeof arg && '[object Array]' == toString.call(arg) -} - -exports.isDate = function (arg) { - return 'object' == typeof arg && '[object Date]' == toString.call(arg) -} - -exports.isRegExp = function (arg) { - return 'object' == typeof arg && '[object RegExp]' == toString.call(arg) -} - -/** - * Wrap a Mongo error document in an Error instance - * @ignore - * @api private - */ -exports.toError = function(error) { - if (error instanceof Error) return error; - - var msg = error.err || error.errmsg || error; - var e = new Error(msg); - e.name = 'MongoError'; - - // Get all object keys - var keys = typeof error == 'object' - ? Object.keys(error) - : []; - - for(var i = 0; i < keys.length; i++) { - e[keys[i]] = error[keys[i]]; - } - - return e; -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml deleted file mode 100644 index 94740d04564..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.6 - - 0.8 - - 0.9 # development version of 0.8, may be unstable \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile deleted file mode 100644 index 77ce4e04085..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -NODE = node -NPM = npm -NODEUNIT = node_modules/nodeunit/bin/nodeunit - -all: clean node_gyp - -test: clean node_gyp - npm test - -node_gyp: clean - node-gyp configure build - -clean: - node-gyp clean - -browserify: - node_modules/.bin/onejs build browser_build/package.json browser_build/bson.js - -.PHONY: all diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md deleted file mode 100644 index 73892e2d19a..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/README.md +++ /dev/null @@ -1 +0,0 @@ -A JS/C++ Bson parser for node, used in the MongoDB Native driver \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js deleted file mode 100644 index 45a11115484..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/benchmarks/benchmarks.js +++ /dev/null @@ -1,130 +0,0 @@ -// var BSON = require('../../lib/mongodb').BSONNative.BSON, -// ObjectID = require('../../lib/mongodb').BSONNative.ObjectID, -// Code = require('../../lib/mongodb').BSONNative.Code, -// Long = require('../../lib/mongodb').BSONNative.Long, -// Binary = require('../../lib/mongodb').BSONNative.Binary, -// debug = require('util').debug, -// inspect = require('util').inspect, -// -// Long = require('../../lib/mongodb').Long, -// ObjectID = require('../../lib/mongodb').ObjectID, -// Binary = require('../../lib/mongodb').Binary, -// Code = require('../../lib/mongodb').Code, -// DBRef = require('../../lib/mongodb').DBRef, -// Symbol = require('../../lib/mongodb').Symbol, -// Double = require('../../lib/mongodb').Double, -// MaxKey = require('../../lib/mongodb').MaxKey, -// MinKey = require('../../lib/mongodb').MinKey, -// Timestamp = require('../../lib/mongodb').Timestamp; - - -// var BSON = require('../../lib/mongodb').BSONPure.BSON, -// ObjectID = require('../../lib/mongodb').BSONPure.ObjectID, -// Code = require('../../lib/mongodb').BSONPure.Code, -// Long = require('../../lib/mongodb').BSONPure.Long, -// Binary = require('../../lib/mongodb').BSONPure.Binary; - -var BSON = require('../lib/bson').BSONNative.BSON, - Long = require('../lib/bson').Long, - ObjectID = require('../lib/bson').ObjectID, - Binary = require('../lib/bson').Binary, - Code = require('../lib/bson').Code, - DBRef = require('../lib/bson').DBRef, - Symbol = require('../lib/bson').Symbol, - Double = require('../lib/bson').Double, - MaxKey = require('../lib/bson').MaxKey, - MinKey = require('../lib/bson').MinKey, - Timestamp = require('../lib/bson').Timestamp; - - // console.dir(require('../lib/bson')) - -var COUNT = 1000; -var COUNT = 100; - -var object = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - date: new Date(), - double: new Double(1.4), - id: new ObjectID(), - min: new MinKey(), - max: new MaxKey(), - symbol: new Symbol('hello'), - long: Long.fromNumber(100), - bin: new Binary(new Buffer(100)), - - subObject: { - moreText: "Bacon ipsum dolor sit amet cow pork belly rump ribeye pastrami andouille. Tail hamburger pork belly, drumstick flank salami t-bone sirloin pork chop ribeye ham chuck pork loin shankle. Ham fatback pork swine, sirloin shankle short loin andouille shank sausage meatloaf drumstick. Pig chicken cow bresaola, pork loin jerky meatball tenderloin brisket strip steak jowl spare ribs. Biltong sirloin pork belly boudin, bacon pastrami rump chicken. Jowl rump fatback, biltong bacon t-bone turkey. Turkey pork loin boudin, tenderloin jerky beef ribs pastrami spare ribs biltong pork chop beef.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly boudin shoulder ribeye pork chop brisket biltong short ribs. Salami beef pork belly, t-bone sirloin meatloaf tail jowl spare ribs. Sirloin biltong bresaola cow turkey. Biltong fatback meatball, bresaola tail shankle turkey pancetta ham ribeye flank bacon jerky pork chop. Boudin sirloin shoulder, salami swine flank jerky t-bone pork chop pork beef tongue. Bresaola ribeye jerky andouille. Ribeye ground round sausage biltong beef ribs chuck, shank hamburger chicken short ribs spare ribs tenderloin meatloaf pork loin." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string", - code: new Code("function() {}", {i:1}) -} - -// Number of objects -var numberOfObjects = 10000; -var bson = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -console.log("---------------------- 1") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - objectBSON = bson.serialize(object, null, true) -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -console.log("---------------------- 2") -var s = new Date() -// Object serialized -for(var i = 0; i < numberOfObjects; i++) { - bson.deserialize(objectBSON); -} -console.log("====================== " + (new Date().getTime() - s.getTime()) + " :: " + ((new Date().getTime() - s.getTime()))/numberOfObjects) - -// // Buffer With copies of the objectBSON -// var data = new Buffer(objectBSON.length * numberOfObjects); -// var index = 0; -// -// // Copy the buffer 1000 times to create a strea m of objects -// for(var i = 0; i < numberOfObjects; i++) { -// // Copy data -// objectBSON.copy(data, index); -// // Adjust index -// index = index + objectBSON.length; -// } -// -// // console.log("-----------------------------------------------------------------------------------") -// // console.dir(objectBSON) -// -// var x, start, end, j -// var objectBSON, objectJSON -// -// // Allocate the return array (avoid concatinating everything) -// var results = new Array(numberOfObjects); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// // var objects = BSON.deserializeStream(data, 0, numberOfObjects); -// // console.log("----------------------------------------------------------------------------------- 0") -// // var objects = BSON.deserialize(data); -// // console.log("----------------------------------------------------------------------------------- 1") -// // console.dir(objects) -// -// for (j=COUNT; --j>=0; ) { -// var nextIndex = BSON.deserializeStream(data, 0, numberOfObjects, results, 0); -// } -// -// end = new Date -// var opsprsecond = COUNT / ((end - start)/1000); -// console.log("bson size (bytes): ", objectBSON.length); -// console.log("time = ", end - start, "ms -", COUNT / ((end - start)/1000), " ops/sec"); -// console.log("MB/s = " + ((opsprsecond*objectBSON.length)/1024)); -// -// // console.dir(nextIndex) -// // console.dir(results) - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp deleted file mode 100644 index 42445d325d7..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/binding.gyp +++ /dev/null @@ -1,17 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'bson', - 'sources': [ 'ext/bson.cc' ], - 'cflags!': [ '-fno-exceptions' ], - 'cflags_cc!': [ '-fno-exceptions' ], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES' - } - }] - ] - } - ] -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js deleted file mode 100644 index e7a1c74fea3..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/bson.js +++ /dev/null @@ -1,4814 +0,0 @@ -var bson = (function(){ - - var pkgmap = {}, - global = {}, - nativeRequire = typeof require != 'undefined' && require, - lib, ties, main, async; - - function exports(){ return main(); }; - - exports.main = exports; - exports.module = module; - exports.packages = pkgmap; - exports.pkg = pkg; - exports.require = function require(uri){ return pkgmap.main.index.require(uri); }; - - - ties = {}; - - aliases = {}; - - - return exports; - -function join() { - return normalize(Array.prototype.join.call(arguments, "/")); -}; - -function normalize(path) { - var ret = [], parts = path.split('/'), cur, prev; - - var i = 0, l = parts.length-1; - for (; i <= l; i++) { - cur = parts[i]; - - if (cur === "." && prev !== undefined) continue; - - if (cur === ".." && ret.length && prev !== ".." && prev !== "." && prev !== undefined) { - ret.pop(); - prev = ret.slice(-1)[0]; - } else { - if (prev === ".") ret.pop(); - ret.push(cur); - prev = cur; - } - } - - return ret.join("/"); -}; - -function dirname(path) { - return path && path.substr(0, path.lastIndexOf("/")) || "."; -}; - -function findModule(workingModule, uri){ - var moduleId = join(dirname(workingModule.id), uri).replace(/\.js$/, ''), - moduleIndexId = join(moduleId, 'index'), - pkg = workingModule.pkg, - module; - - var i = pkg.modules.length, - id; - - while(i-->0){ - id = pkg.modules[i].id; - if(id==moduleId || id == moduleIndexId){ - module = pkg.modules[i]; - break; - } - } - - return module; -} - -function newRequire(callingModule){ - function require(uri){ - var module, pkg; - - if(/^\./.test(uri)){ - module = findModule(callingModule, uri); - } else if ( ties && ties.hasOwnProperty( uri ) ) { - return ties[uri]; - } else if ( aliases && aliases.hasOwnProperty( uri ) ) { - return require(aliases[uri]); - } else { - pkg = pkgmap[uri]; - - if(!pkg && nativeRequire){ - try { - pkg = nativeRequire(uri); - } catch (nativeRequireError) {} - - if(pkg) return pkg; - } - - if(!pkg){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module = pkg.index; - } - - if(!module){ - throw new Error('Cannot find module "'+uri+'" @[module: '+callingModule.id+' package: '+callingModule.pkg.name+']'); - } - - module.parent = callingModule; - return module.call(); - }; - - - return require; -} - - -function module(parent, id, wrapper){ - var mod = { pkg: parent, id: id, wrapper: wrapper }, - cached = false; - - mod.exports = {}; - mod.require = newRequire(mod); - - mod.call = function(){ - if(cached) { - return mod.exports; - } - - cached = true; - - global.require = mod.require; - - mod.wrapper(mod, mod.exports, global, global.require); - return mod.exports; - }; - - if(parent.mainModuleId == mod.id){ - parent.index = mod; - parent.parents.length === 0 && ( main = mod.call ); - } - - parent.modules.push(mod); -} - -function pkg(/* [ parentId ...], wrapper */){ - var wrapper = arguments[ arguments.length - 1 ], - parents = Array.prototype.slice.call(arguments, 0, arguments.length - 1), - ctx = wrapper(parents); - - - pkgmap[ctx.name] = ctx; - - arguments.length == 1 && ( pkgmap.main = ctx ); - - return function(modules){ - var id; - for(id in modules){ - module(ctx, id, modules[id]); - } - }; -} - - -}(this)); - -bson.pkg(function(parents){ - - return { - 'name' : 'bson', - 'mainModuleId' : 'bson', - 'modules' : [], - 'parents' : parents - }; - -})({ 'binary': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - - -}, - - - -'binary_parser': function(module, exports, global, require, undefined){ - /** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; - -}, - - - -'bson': function(module, exports, global, require, undefined){ - var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; -}, - - - -'code': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; -}, - - - -'db_ref': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; -}, - - - -'double': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; -}, - - - -'float_parser': function(module, exports, global, require, undefined){ - // Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; -}, - - - -'index': function(module, exports, global, require, undefined){ - try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -}, - - - -'long': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; -}, - - - -'max_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; -}, - - - -'min_key': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; -}, - - - -'objectid': function(module, exports, global, require, undefined){ - /** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; -}, - - - -'symbol': function(module, exports, global, require, undefined){ - /** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; -}, - - - -'timestamp': function(module, exports, global, require, undefined){ - // Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; -}, - - }); - - -if(typeof module != 'undefined' && module.exports ){ - module.exports = bson; - - if( !module.parent ){ - bson(); - } -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json deleted file mode 100644 index 3ebb58761c5..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/browser_build/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ "name" : "bson" -, "description" : "A bson parser for node.js and the browser" -, "main": "../lib/bson/bson" -, "directories" : { "lib" : "../lib/bson" } -, "engines" : { "node" : ">=0.6.0" } -, "licenses" : [ { "type" : "Apache License, Version 2.0" - , "url" : "http://www.apache.org/licenses/LICENSE-2.0" } ] -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile deleted file mode 100644 index 70b5e9c7722..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Makefile +++ /dev/null @@ -1,333 +0,0 @@ -# We borrow heavily from the kernel build setup, though we are simpler since -# we don't have Kconfig tweaking settings on us. - -# The implicit make rules have it looking for RCS files, among other things. -# We instead explicitly write all the rules we care about. -# It's even quicker (saves ~200ms) to pass -r on the command line. -MAKEFLAGS=-r - -# The source directory tree. -srcdir := .. -abs_srcdir := $(abspath $(srcdir)) - -# The name of the builddir. -builddir_name ?= . - -# The V=1 flag on command line makes us verbosely print command lines. -ifdef V - quiet= -else - quiet=quiet_ -endif - -# Specify BUILDTYPE=Release on the command line for a release build. -BUILDTYPE ?= Release - -# Directory all our build output goes into. -# Note that this must be two directories beneath src/ for unit tests to pass, -# as they reach into the src/ directory for data with relative paths. -builddir ?= $(builddir_name)/$(BUILDTYPE) -abs_builddir := $(abspath $(builddir)) -depsdir := $(builddir)/.deps - -# Object output directory. -obj := $(builddir)/obj -abs_obj := $(abspath $(obj)) - -# We build up a list of every single one of the targets so we can slurp in the -# generated dependency rule Makefiles in one pass. -all_deps := - - - -# C++ apps need to be linked with g++. -# -# Note: flock is used to seralize linking. Linking is a memory-intensive -# process so running parallel links can often lead to thrashing. To disable -# the serialization, override LINK via an envrionment variable as follows: -# -# export LINK=g++ -# -# This will allow make to invoke N linker processes as specified in -jN. -LINK ?= flock $(builddir)/linker.lock $(CXX) - -CC.target ?= $(CC) -CFLAGS.target ?= $(CFLAGS) -CXX.target ?= $(CXX) -CXXFLAGS.target ?= $(CXXFLAGS) -LINK.target ?= $(LINK) -LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) - -# TODO(evan): move all cross-compilation logic to gyp-time so we don't need -# to replicate this environment fallback in make as well. -CC.host ?= gcc -CFLAGS.host ?= -CXX.host ?= g++ -CXXFLAGS.host ?= -LINK.host ?= g++ -LDFLAGS.host ?= -AR.host ?= ar - -# Define a dir function that can handle spaces. -# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions -# "leading spaces cannot appear in the text of the first argument as written. -# These characters can be put into the argument value by variable substitution." -empty := -space := $(empty) $(empty) - -# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces -replace_spaces = $(subst $(space),?,$1) -unreplace_spaces = $(subst ?,$(space),$1) -dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) - -# Flags to make gcc output dependency info. Note that you need to be -# careful here to use the flags that ccache and distcc can understand. -# We write to a dep file on the side first and then rename at the end -# so we can't end up with a broken dep file. -depfile = $(depsdir)/$(call replace_spaces,$@).d -DEPFLAGS = -MMD -MF $(depfile).raw - -# We have to fixup the deps output in a few ways. -# (1) the file output should mention the proper .o file. -# ccache or distcc lose the path to the target, so we convert a rule of -# the form: -# foobar.o: DEP1 DEP2 -# into -# path/to/foobar.o: DEP1 DEP2 -# (2) we want missing files not to cause us to fail to build. -# We want to rewrite -# foobar.o: DEP1 DEP2 \ -# DEP3 -# to -# DEP1: -# DEP2: -# DEP3: -# so if the files are missing, they're just considered phony rules. -# We have to do some pretty insane escaping to get those backslashes -# and dollar signs past make, the shell, and sed at the same time. -# Doesn't work with spaces, but that's fine: .d files have spaces in -# their names replaced with other characters. -define fixup_dep -# The depfile may not exist if the input file didn't have any #includes. -touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds, and deletes the output file when done -# if any of the postbuilds failed. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - F=$$?;\ - if [ $$F -ne 0 ]; then\ - E=$$F;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bson.target.mk)))),) - include bson.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp -fmake --ignore-environment "--toplevel-dir=." -I/home/b/Desktop/countly/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/root/.node-gyp/0.10.11/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/root/.node-gyp/0.10.11" "-Dmodule_root_dir=/home/b/Desktop/countly/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../../../root/.node-gyp/0.10.11/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d deleted file mode 100644 index 866c155bc23..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bson.node := rm -rf "Release/bson.node" && cp -af "Release/obj.target/bson.node" "Release/bson.node" diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d deleted file mode 100644 index a7317de71b7..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/bson.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m32 -Wl,-soname=bson.node -o Release/obj.target/bson.node -Wl,--start-group Release/obj.target/bson/ext/bson.o -Wl,--end-group diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d deleted file mode 100644 index 5cdc93f8392..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d +++ /dev/null @@ -1,28 +0,0 @@ -cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/root/.node-gyp/0.10.11/src -I/root/.node-gyp/0.10.11/deps/uv/include -I/root/.node-gyp/0.10.11/deps/v8/include -Wall -Wextra -Wno-unused-parameter -pthread -m32 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-tree-sink -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc -Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \ - /root/.node-gyp/0.10.11/deps/v8/include/v8.h \ - /root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h \ - /root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h \ - /root/.node-gyp/0.10.11/src/node.h \ - /root/.node-gyp/0.10.11/src/node_version.h \ - /root/.node-gyp/0.10.11/src/node_buffer.h ../ext/bson.h \ - /root/.node-gyp/0.10.11/src/node_object_wrap.h -../ext/bson.cc: -/root/.node-gyp/0.10.11/deps/v8/include/v8.h: -/root/.node-gyp/0.10.11/deps/v8/include/v8stdint.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-unix.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/ngx-queue.h: -/root/.node-gyp/0.10.11/deps/uv/include/uv-private/uv-linux.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: -/root/.node-gyp/0.10.11/src/node.h: -/root/.node-gyp/0.10.11/src/node_version.h: -/root/.node-gyp/0.10.11/src/node_buffer.h: -../ext/bson.h: -/root/.node-gyp/0.10.11/src/node_object_wrap.h: diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node deleted file mode 100644 index aaa41ae6545..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o deleted file mode 100644 index a2bfc494436..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/Release/obj.target/bson/ext/bson.o and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile deleted file mode 100644 index 90bf8247b39..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= build/./. -.PHONY: all -all: - $(MAKE) bson diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk deleted file mode 100644 index 5359f669c3e..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/bson.target.mk +++ /dev/null @@ -1,126 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bson -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti - -INCS_Debug := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m32 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-tree-sink - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti - -INCS_Release := \ - -I/root/.node-gyp/0.10.11/src \ - -I/root/.node-gyp/0.10.11/deps/uv/include \ - -I/root/.node-gyp/0.10.11/deps/v8/include - -OBJS := \ - $(obj).target/$(TARGET)/ext/bson.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m32 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m32 - -LIBS := - -$(obj).target/bson.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/bson.node: LIBS := $(LIBS) -$(obj).target/bson.node: TOOLSET := $(TOOLSET) -$(obj).target/bson.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/bson.node -# Add target alias -.PHONY: bson -bson: $(builddir)/bson.node - -# Copy this to the executable output path. -$(builddir)/bson.node: TOOLSET := $(TOOLSET) -$(builddir)/bson.node: $(obj).target/bson.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/bson.node -# Short alias for building this executable. -.PHONY: bson.node -bson.node: $(obj).target/bson.node $(builddir)/bson.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bson.node - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi deleted file mode 100644 index 69c52b6eb0f..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build/config.gypi +++ /dev/null @@ -1,114 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 44, - "host_arch": "ia32", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "ia32", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/root/.node-gyp/0.10.11", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "pre": "", - "sign_git_tag": "", - "always_auth": "", - "user_agent": "node/v0.10.11 linux ia32", - "bin_links": "true", - "description": "true", - "fetch_retries": "2", - "init_version": "0.0.0", - "user": "", - "force": "", - "ignore": "", - "cache_min": "10", - "editor": "vi", - "rollback": "true", - "cache_max": "null", - "userconfig": "/root/.npmrc", - "coverage": "", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/root/tmp", - "userignorefile": "/root/.npmignore", - "yes": "", - "depth": "null", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/root/.npm", - "npaturl": "http://npat.npmjs.org/", - "searchsort": "name", - "version": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.11", - "tag": "latest", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/root/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "group": "", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "json": "" - } -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js deleted file mode 100644 index bb802384453..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/build_browser.js +++ /dev/null @@ -1,7 +0,0 @@ -require('one'); - -one('./package.json') - .tie('bson', BSON) - // .exclude('buffer') - .tie('buffer', {}) - .save('./browser_build/bson.js') \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile deleted file mode 100644 index 435999ee960..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -NODE = node -name = all -JOBS = 1 - -all: - rm -rf build .lock-wscript bson.node - node-waf configure build - cp -R ./build/Release/bson.node . || true - -all_debug: - rm -rf build .lock-wscript bson.node - node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clang: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf configure build - cp -R ./build/Release/bson.node . || true - -clang_debug: - rm -rf build .lock-wscript bson.node - CXX=clang node-waf --debug configure build - cp -R ./build/Release/bson.node . || true - -clean: - rm -rf build .lock-wscript bson.node - -.PHONY: all \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc deleted file mode 100644 index 8a2ec8b7e7a..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.cc +++ /dev/null @@ -1,1006 +0,0 @@ -//=========================================================================== - -#include -#include -#include -#include -#include - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#endif - -#include - -// this and the above block must be around the v8.h header otherwise -// v8 is not happy -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef __sun - #include -#endif - -#include "bson.h" - -using namespace v8; -using namespace node; - -//=========================================================================== - -void DataStream::WriteObjectId(const Handle& object, const Handle& key) -{ - uint16_t buffer[12]; - object->Get(key)->ToString()->Write(buffer, 0, 12); - for(uint32_t i = 0; i < 12; ++i) - { - *p++ = (char) buffer[i]; - } -} - -void ThrowAllocatedStringException(size_t allocationSize, const char* format, ...) -{ - va_list args; - va_start(args, format); - char* string = (char*) malloc(allocationSize); - vsprintf(string, format, args); - va_end(args); - - throw string; -} - -void DataStream::CheckKey(const Local& keyName) -{ - size_t keyLength = keyName->Utf8Length(); - if(keyLength == 0) return; - - char* keyStringBuffer = (char*) alloca(keyLength+1); - keyName->WriteUtf8(keyStringBuffer); - - if(keyStringBuffer[0] == '$') - { - ThrowAllocatedStringException(64+keyLength, "key %s must not start with '$'", keyStringBuffer); - } - - if(strchr(keyStringBuffer, '.') != NULL) - { - ThrowAllocatedStringException(64+keyLength, "key %s must not contain '.'", keyStringBuffer); - } -} - -template void BSONSerializer::SerializeDocument(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - Local object = bson->GetSerializeObject(value); - - // Get the object property names - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - Local propertyNames = object->GetPropertyNames(); - #else - Local propertyNames = object->GetOwnPropertyNames(); - #endif - - // Length of the property - int propertyLength = propertyNames->Length(); - for(int i = 0; i < propertyLength; ++i) - { - const Local& propertyName = propertyNames->Get(i)->ToString(); - if(checkKeys) this->CheckKey(propertyName); - - const Local& propertyValue = object->Get(propertyName); - - if(serializeFunctions || !propertyValue->IsFunction()) - { - void* typeLocation = this->BeginWriteType(); - this->WriteString(propertyName); - SerializeValue(typeLocation, propertyValue); - } - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -template void BSONSerializer::SerializeArray(const Handle& value) -{ - void* documentSize = this->BeginWriteSize(); - - Local array = Local::Cast(value->ToObject()); - uint32_t arrayLength = array->Length(); - - for(uint32_t i = 0; i < arrayLength; ++i) - { - void* typeLocation = this->BeginWriteType(); - this->WriteUInt32String(i); - SerializeValue(typeLocation, array->Get(i)); - } - - this->WriteByte(0); - this->CommitSize(documentSize); -} - -// This is templated so that we can use this function to both count the number of bytes, and to serialize those bytes. -// The template approach eliminates almost all of the inspection of values unless they're required (eg. string lengths) -// and ensures that there is always consistency between bytes counted and bytes written by design. -template void BSONSerializer::SerializeValue(void* typeLocation, const Handle& value) -{ - if(value->IsNumber()) - { - double doubleValue = value->NumberValue(); - int intValue = (int) doubleValue; - if(intValue == doubleValue) - { - this->CommitType(typeLocation, BSON_TYPE_INT); - this->WriteInt32(intValue); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(doubleValue); - } - } - else if(value->IsString()) - { - this->CommitType(typeLocation, BSON_TYPE_STRING); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsBoolean()) - { - this->CommitType(typeLocation, BSON_TYPE_BOOLEAN); - this->WriteBool(value); - } - else if(value->IsArray()) - { - this->CommitType(typeLocation, BSON_TYPE_ARRAY); - SerializeArray(value); - } - else if(value->IsDate()) - { - this->CommitType(typeLocation, BSON_TYPE_DATE); - this->WriteInt64(value); - } - else if(value->IsRegExp()) - { - this->CommitType(typeLocation, BSON_TYPE_REGEXP); - const Handle& regExp = Handle::Cast(value); - - this->WriteString(regExp->GetSource()); - - int flags = regExp->GetFlags(); - if(flags & RegExp::kGlobal) this->WriteByte('s'); - if(flags & RegExp::kIgnoreCase) this->WriteByte('i'); - if(flags & RegExp::kMultiline) this->WriteByte('m'); - this->WriteByte(0); - } - else if(value->IsFunction()) - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(value->ToString()); - } - else if(value->IsObject()) - { - const Local& object = value->ToObject(); - if(object->Has(bson->_bsontypeString)) - { - const Local& constructorString = object->GetConstructorName(); - if(bson->longString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_LONG); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->timestampString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_TIMESTAMP); - this->WriteInt32(object, bson->_longLowString); - this->WriteInt32(object, bson->_longHighString); - } - else if(bson->objectIDString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OID); - this->WriteObjectId(object, bson->_objectIDidString); - } - else if(bson->binaryString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - uint32_t length = object->Get(bson->_binaryPositionString)->Uint32Value(); - Local bufferObj = object->Get(bson->_binaryBufferString)->ToObject(); - - this->WriteInt32(length); - this->WriteByte(object, bson->_binarySubTypeString); // write subtype - // If type 0x02 write the array length aswell - if(object->Get(bson->_binarySubTypeString)->Int32Value() == 0x02) { - this->WriteInt32(length); - } - // Write the actual data - this->WriteData(Buffer::Data(bufferObj), length); - } - else if(bson->doubleString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_NUMBER); - this->WriteDouble(object, bson->_doubleValueString); - } - else if(bson->symbolString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_SYMBOL); - this->WriteLengthPrefixedString(object->Get(bson->_symbolValueString)->ToString()); - } - else if(bson->codeString->StrictEquals(constructorString)) - { - const Local& function = object->Get(bson->_codeCodeString)->ToString(); - const Local& scope = object->Get(bson->_codeScopeString)->ToObject(); - - // For Node < 0.6.X use the GetPropertyNames - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 6 - uint32_t propertyNameLength = scope->GetPropertyNames()->Length(); - #else - uint32_t propertyNameLength = scope->GetOwnPropertyNames()->Length(); - #endif - - if(propertyNameLength > 0) - { - this->CommitType(typeLocation, BSON_TYPE_CODE_W_SCOPE); - void* codeWidthScopeSize = this->BeginWriteSize(); - this->WriteLengthPrefixedString(function->ToString()); - SerializeDocument(scope); - this->CommitSize(codeWidthScopeSize); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_CODE); - this->WriteLengthPrefixedString(function->ToString()); - } - } - else if(bson->dbrefString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - - void* dbRefSize = this->BeginWriteSize(); - - void* refType = this->BeginWriteType(); - this->WriteData("$ref", 5); - SerializeValue(refType, object->Get(bson->_dbRefNamespaceString)); - - void* idType = this->BeginWriteType(); - this->WriteData("$id", 4); - SerializeValue(idType, object->Get(bson->_dbRefOidString)); - - const Local& refDbValue = object->Get(bson->_dbRefDbString); - if(!refDbValue->IsUndefined()) - { - void* dbType = this->BeginWriteType(); - this->WriteData("$db", 4); - SerializeValue(dbType, refDbValue); - } - - this->WriteByte(0); - this->CommitSize(dbRefSize); - } - else if(bson->minKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MIN_KEY); - } - else if(bson->maxKeyString->StrictEquals(constructorString)) - { - this->CommitType(typeLocation, BSON_TYPE_MAX_KEY); - } - } - else if(Buffer::HasInstance(value)) - { - this->CommitType(typeLocation, BSON_TYPE_BINARY); - - #if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(value->ToObject()); - uint32_t length = object->length(); - #else - uint32_t length = Buffer::Length(value->ToObject()); - #endif - - this->WriteInt32(length); - this->WriteByte(0); - this->WriteData(Buffer::Data(value->ToObject()), length); - } - else - { - this->CommitType(typeLocation, BSON_TYPE_OBJECT); - SerializeDocument(value); - } - } - else if(value->IsNull() || value->IsUndefined()) - { - this->CommitType(typeLocation, BSON_TYPE_NULL); - } -} - -// Data points to start of element list, length is length of entire document including '\0' but excluding initial size -BSONDeserializer::BSONDeserializer(BSON* aBson, char* data, size_t length) -: bson(aBson), - pStart(data), - p(data), - pEnd(data + length - 1) -{ - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -BSONDeserializer::BSONDeserializer(BSONDeserializer& parentSerializer, size_t length) -: bson(parentSerializer.bson), - pStart(parentSerializer.p), - p(parentSerializer.p), - pEnd(parentSerializer.p + length - 1) -{ - parentSerializer.p += length; - if(pEnd > parentSerializer.pEnd) ThrowAllocatedStringException(64, "Child document exceeds parent's bounds"); - if(*pEnd != '\0') ThrowAllocatedStringException(64, "Missing end of document marker '\\0'"); -} - -Local BSONDeserializer::ReadCString() -{ - char* start = p; - while(*p++) { } - return String::New(start, (int32_t) (p-start-1) ); -} - -int32_t BSONDeserializer::ReadRegexOptions() -{ - int32_t options = 0; - for(;;) - { - switch(*p++) - { - case '\0': return options; - case 's': options |= RegExp::kGlobal; break; - case 'i': options |= RegExp::kIgnoreCase; break; - case 'm': options |= RegExp::kMultiline; break; - } - } -} - -uint32_t BSONDeserializer::ReadIntegerString() -{ - uint32_t value = 0; - while(*p) - { - if(*p < '0' || *p > '9') ThrowAllocatedStringException(64, "Invalid key for array"); - value = value * 10 + *p++ - '0'; - } - ++p; - return value; -} - -Local BSONDeserializer::ReadString() -{ - uint32_t length = ReadUInt32(); - char* start = p; - p += length; - return String::New(start, length-1); -} - -Local BSONDeserializer::ReadObjectId() -{ - uint16_t objectId[12]; - for(size_t i = 0; i < 12; ++i) - { - objectId[i] = *reinterpret_cast(p++); - } - return String::New(objectId, 12); -} - -Handle BSONDeserializer::DeserializeDocument() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeDocumentInternal(); -} - -Handle BSONDeserializer::DeserializeDocumentInternal() -{ - Local returnObject = Object::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - const Local& name = ReadCString(); - const Handle& value = DeserializeValue(type); - returnObject->ForceSet(name, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Document: Serialize consumed unexpected number of bytes"); - - // From JavaScript: - // if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - if(returnObject->Has(bson->_dbRefIdRefString)) - { - Local argv[] = { returnObject->Get(bson->_dbRefRefString), returnObject->Get(bson->_dbRefIdRefString), returnObject->Get(bson->_dbRefDbRefString) }; - return bson->dbrefConstructor->NewInstance(3, argv); - } - else - { - return returnObject; - } -} - -Handle BSONDeserializer::DeserializeArray() -{ - uint32_t length = ReadUInt32(); - if(length < 5) ThrowAllocatedStringException(64, "Bad BSON: Array Document is less than 5 bytes"); - - BSONDeserializer documentDeserializer(*this, length-4); - return documentDeserializer.DeserializeArrayInternal(); -} - -Handle BSONDeserializer::DeserializeArrayInternal() -{ - Local returnArray = Array::New(); - - while(HasMoreData()) - { - BsonType type = (BsonType) ReadByte(); - uint32_t index = ReadIntegerString(); - const Handle& value = DeserializeValue(type); - returnArray->Set(index, value); - } - if(p != pEnd) ThrowAllocatedStringException(64, "Bad BSON Array: Serialize consumed unexpected number of bytes"); - - return returnArray; -} - -Handle BSONDeserializer::DeserializeValue(BsonType type) -{ - switch(type) - { - case BSON_TYPE_STRING: - return ReadString(); - - case BSON_TYPE_INT: - return Integer::New(ReadInt32()); - - case BSON_TYPE_NUMBER: - return Number::New(ReadDouble()); - - case BSON_TYPE_NULL: - return Null(); - - case BSON_TYPE_UNDEFINED: - return Undefined(); - - case BSON_TYPE_TIMESTAMP: - { - int32_t lowBits = ReadInt32(); - int32_t highBits = ReadInt32(); - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->timestampConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_BOOLEAN: - return (ReadByte() != 0) ? True() : False(); - - case BSON_TYPE_REGEXP: - { - const Local& regex = ReadCString(); - int32_t options = ReadRegexOptions(); - return RegExp::New(regex, (RegExp::Flags) options); - } - - case BSON_TYPE_CODE: - { - const Local& code = ReadString(); - const Local& scope = Object::New(); - Local argv[] = { code, scope }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_CODE_W_SCOPE: - { - ReadUInt32(); - const Local& code = ReadString(); - const Handle& scope = DeserializeDocument(); - Local argv[] = { code, scope->ToObject() }; - return bson->codeConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_OID: - { - Local argv[] = { ReadObjectId() }; - return bson->objectIDConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_BINARY: - { - uint32_t length = ReadUInt32(); - uint32_t subType = ReadByte(); - if(subType == 0x02) { - length = ReadInt32(); - } - - Buffer* buffer = Buffer::New(p, length); - p += length; - - Handle argv[] = { buffer->handle_, Uint32::New(subType) }; - return bson->binaryConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_LONG: - { - // Read 32 bit integers - int32_t lowBits = (int32_t) ReadInt32(); - int32_t highBits = (int32_t) ReadInt32(); - - // If value is < 2^53 and >-2^53 - if((highBits < 0x200000 || (highBits == 0x200000 && lowBits == 0)) && highBits >= -0x200000) { - // Adjust the pointer and read as 64 bit value - p -= 8; - // Read the 64 bit value - int64_t finalValue = (int64_t) ReadInt64(); - return Number::New(finalValue); - } - - Local argv[] = { Int32::New(lowBits), Int32::New(highBits) }; - return bson->longConstructor->NewInstance(2, argv); - } - - case BSON_TYPE_DATE: - return Date::New((double) ReadInt64()); - - case BSON_TYPE_ARRAY: - return DeserializeArray(); - - case BSON_TYPE_OBJECT: - return DeserializeDocument(); - - case BSON_TYPE_SYMBOL: - { - const Local& string = ReadString(); - Local argv[] = { string }; - return bson->symbolConstructor->NewInstance(1, argv); - } - - case BSON_TYPE_MIN_KEY: - return bson->minKeyConstructor->NewInstance(); - - case BSON_TYPE_MAX_KEY: - return bson->maxKeyConstructor->NewInstance(); - - default: - ThrowAllocatedStringException(64, "Unhandled BSON Type: %d", type); - } - - return v8::Null(); -} - - -static Handle VException(const char *msg) -{ - HandleScope scope; - return ThrowException(Exception::Error(String::New(msg))); -} - -Persistent BSON::constructor_template; - -BSON::BSON() : ObjectWrap() -{ - // Setup pre-allocated comparision objects - _bsontypeString = Persistent::New(String::New("_bsontype")); - _longLowString = Persistent::New(String::New("low_")); - _longHighString = Persistent::New(String::New("high_")); - _objectIDidString = Persistent::New(String::New("id")); - _binaryPositionString = Persistent::New(String::New("position")); - _binarySubTypeString = Persistent::New(String::New("sub_type")); - _binaryBufferString = Persistent::New(String::New("buffer")); - _doubleValueString = Persistent::New(String::New("value")); - _symbolValueString = Persistent::New(String::New("value")); - _dbRefRefString = Persistent::New(String::New("$ref")); - _dbRefIdRefString = Persistent::New(String::New("$id")); - _dbRefDbRefString = Persistent::New(String::New("$db")); - _dbRefNamespaceString = Persistent::New(String::New("namespace")); - _dbRefDbString = Persistent::New(String::New("db")); - _dbRefOidString = Persistent::New(String::New("oid")); - _codeCodeString = Persistent::New(String::New("code")); - _codeScopeString = Persistent::New(String::New("scope")); - _toBSONString = Persistent::New(String::New("toBSON")); - - longString = Persistent::New(String::New("Long")); - objectIDString = Persistent::New(String::New("ObjectID")); - binaryString = Persistent::New(String::New("Binary")); - codeString = Persistent::New(String::New("Code")); - dbrefString = Persistent::New(String::New("DBRef")); - symbolString = Persistent::New(String::New("Symbol")); - doubleString = Persistent::New(String::New("Double")); - timestampString = Persistent::New(String::New("Timestamp")); - minKeyString = Persistent::New(String::New("MinKey")); - maxKeyString = Persistent::New(String::New("MaxKey")); -} - -void BSON::Initialize(v8::Handle target) -{ - // Grab the scope of the call from Node - HandleScope scope; - // Define a new function template - Local t = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("BSON")); - - // Instance methods - NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream); - - target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction()); -} - -// Create a new instance of BSON and passing it the existing context -Handle BSON::New(const Arguments &args) -{ - HandleScope scope; - - // Check that we have an array - if(args.Length() == 1 && args[0]->IsArray()) - { - // Cast the array to a local reference - Local array = Local::Cast(args[0]); - - if(array->Length() > 0) - { - // Create a bson object instance and return it - BSON *bson = new BSON(); - - uint32_t foundClassesMask = 0; - - // Iterate over all entries to save the instantiate funtions - for(uint32_t i = 0; i < array->Length(); i++) { - // Let's get a reference to the function - Local func = Local::Cast(array->Get(i)); - Local functionName = func->GetName()->ToString(); - - // Save the functions making them persistant handles (they don't get collected) - if(functionName->StrictEquals(bson->longString)) { - bson->longConstructor = Persistent::New(func); - foundClassesMask |= 1; - } else if(functionName->StrictEquals(bson->objectIDString)) { - bson->objectIDConstructor = Persistent::New(func); - foundClassesMask |= 2; - } else if(functionName->StrictEquals(bson->binaryString)) { - bson->binaryConstructor = Persistent::New(func); - foundClassesMask |= 4; - } else if(functionName->StrictEquals(bson->codeString)) { - bson->codeConstructor = Persistent::New(func); - foundClassesMask |= 8; - } else if(functionName->StrictEquals(bson->dbrefString)) { - bson->dbrefConstructor = Persistent::New(func); - foundClassesMask |= 0x10; - } else if(functionName->StrictEquals(bson->symbolString)) { - bson->symbolConstructor = Persistent::New(func); - foundClassesMask |= 0x20; - } else if(functionName->StrictEquals(bson->doubleString)) { - bson->doubleConstructor = Persistent::New(func); - foundClassesMask |= 0x40; - } else if(functionName->StrictEquals(bson->timestampString)) { - bson->timestampConstructor = Persistent::New(func); - foundClassesMask |= 0x80; - } else if(functionName->StrictEquals(bson->minKeyString)) { - bson->minKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x100; - } else if(functionName->StrictEquals(bson->maxKeyString)) { - bson->maxKeyConstructor = Persistent::New(func); - foundClassesMask |= 0x200; - } - } - - // Check if we have the right number of constructors otherwise throw an error - if(foundClassesMask != 0x3ff) { - delete bson; - return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]"); - } else { - bson->Wrap(args.This()); - return args.This(); - } - } - else - { - return VException("No types passed in"); - } - } - else - { - return VException("Argument passed in must be an array of types"); - } -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ - -Handle BSON::BSONDeserialize(const Arguments &args) -{ - HandleScope scope; - - // Ensure that we have an parameter - if(Buffer::HasInstance(args[0]) && args.Length() > 1) return VException("One argument required - buffer1."); - if(args[0]->IsString() && args.Length() > 1) return VException("One argument required - string1."); - // Throw an exception if the argument is not of type Buffer - if(!Buffer::HasInstance(args[0]) && !args[0]->IsString()) return VException("Argument must be a Buffer or String."); - - // Define pointer to data - Local obj = args[0]->ToObject(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // If we passed in a buffer, let's unpack it, otherwise let's unpack the string - if(Buffer::HasInstance(obj)) - { -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Validate that we have at least 5 bytes - if(length < 5) return VException("corrupt bson message < 5 bytes long"); - - try - { - BSONDeserializer deserializer(bson, data, length); - return deserializer.DeserializeDocument(); - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - } - else - { - // The length of the data for this encoding - ssize_t len = DecodeBytes(args[0], BINARY); - - // Validate that we have at least 5 bytes - if(len < 5) return VException("corrupt bson message < 5 bytes long"); - - // Let's define the buffer size - char* data = (char *)malloc(len); - DecodeWrite(data, len, args[0], BINARY); - - try - { - BSONDeserializer deserializer(bson, data, len); - Handle result = deserializer.DeserializeDocument(); - free(data); - return result; - - } - catch(char* exception) - { - Handle error = VException(exception); - free(exception); - free(data); - return error; - } - } -} - -Local BSON::GetSerializeObject(const Handle& argValue) -{ - Local object = argValue->ToObject(); - if(object->Has(_toBSONString)) - { - const Local& toBSON = object->Get(_toBSONString); - if(!toBSON->IsFunction()) ThrowAllocatedStringException(64, "toBSON is not a function"); - - Local result = Local::Cast(toBSON)->Call(object, 0, NULL); - if(!result->IsObject()) ThrowAllocatedStringException(64, "toBSON function did not return an object"); - return result->ToObject(); - } - else - { - return object; - } -} - -Handle BSON::BSONSerialize(const Arguments &args) -{ - HandleScope scope; - - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 3 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !args[2]->IsBoolean() && !args[3]->IsBoolean()) return VException("One, two or tree arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - if(args.Length() > 4) return VException("One, two, tree or four arguments required - [object] or [object, boolean] or [object, boolean, boolean] or [object, boolean, boolean, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Calculate the total size of the document in binary form to ensure we only allocate memory once - // With serialize function - bool serializeFunctions = (args.Length() >= 4) && args[3]->BooleanValue(); - - char *serialized_object = NULL; - size_t object_size; - try - { - Local object = bson->GetSerializeObject(args[0]); - - BSONSerializer counter(bson, false, serializeFunctions); - counter.SerializeDocument(object); - object_size = counter.GetSerializeSize(); - - // Allocate the memory needed for the serialization - serialized_object = (char *)malloc(object_size); - - // Check if we have a boolean value - bool checkKeys = args.Length() >= 3 && args[1]->IsBoolean() && args[1]->BooleanValue(); - BSONSerializer data(bson, checkKeys, serializeFunctions, serialized_object); - data.SerializeDocument(object); - } - catch(char *err_msg) - { - free(serialized_object); - Handle error = VException(err_msg); - free(err_msg); - return error; - } - - // If we have 3 arguments - if(args.Length() == 3 || args.Length() == 4) - { - Buffer *buffer = Buffer::New(serialized_object, object_size); - free(serialized_object); - return scope.Close(buffer->handle_); - } - else - { - Local bin_value = Encode(serialized_object, object_size, BINARY)->ToString(); - free(serialized_object); - return bin_value; - } -} - -Handle BSON::CalculateObjectSize(const Arguments &args) -{ - HandleScope scope; - // Ensure we have a valid object - if(args.Length() == 1 && !args[0]->IsObject()) return VException("One argument required - [object]"); - if(args.Length() == 2 && !args[0]->IsObject() && !args[1]->IsBoolean()) return VException("Two arguments required - [object, boolean]"); - if(args.Length() > 3) return VException("One or two arguments required - [object] or [object, boolean]"); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - bool serializeFunctions = (args.Length() >= 2) && args[1]->BooleanValue(); - BSONSerializer countSerializer(bson, false, serializeFunctions); - countSerializer.SerializeDocument(args[0]); - - // Return the object size - return scope.Close(Uint32::New((uint32_t) countSerializer.GetSerializeSize())); -} - -Handle BSON::SerializeWithBufferAndIndex(const Arguments &args) -{ - HandleScope scope; - - //BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, ->, buffer, index) { - // Ensure we have the correct values - if(args.Length() > 5) return VException("Four or five parameters required [object, boolean, Buffer, int] or [object, boolean, Buffer, int, boolean]"); - if(args.Length() == 4 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32()) return VException("Four parameters required [object, boolean, Buffer, int]"); - if(args.Length() == 5 && !args[0]->IsObject() && !args[1]->IsBoolean() && !Buffer::HasInstance(args[2]) && !args[3]->IsUint32() && !args[4]->IsBoolean()) return VException("Four parameters required [object, boolean, Buffer, int, boolean]"); - - uint32_t index; - size_t object_size; - - try - { - BSON *bson = ObjectWrap::Unwrap(args.This()); - - Local obj = args[2]->ToObject(); - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); - - index = args[3]->Uint32Value(); - bool checkKeys = args.Length() >= 4 && args[1]->IsBoolean() && args[1]->BooleanValue(); - bool serializeFunctions = (args.Length() == 5) && args[4]->BooleanValue(); - - BSONSerializer dataSerializer(bson, checkKeys, serializeFunctions, data+index); - dataSerializer.SerializeDocument(bson->GetSerializeObject(args[0])); - object_size = dataSerializer.GetSerializeSize(); - - if(object_size + index > length) return VException("Serious error - overflowed buffer!!"); - } - catch(char *exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - - return scope.Close(Uint32::New((uint32_t) (index + object_size - 1))); -} - -Handle BSON::BSONDeserializeStream(const Arguments &args) -{ - HandleScope scope; - - // At least 3 arguments required - if(args.Length() < 5) return VException("Arguments required (Buffer(data), Number(index in data), Number(number of documents to deserialize), Array(results), Number(index in the array), Object(optional))"); - - // If the number of argumets equals 3 - if(args.Length() >= 5) - { - if(!Buffer::HasInstance(args[0])) return VException("First argument must be Buffer instance"); - if(!args[1]->IsUint32()) return VException("Second argument must be a positive index number"); - if(!args[2]->IsUint32()) return VException("Third argument must be a positive number of documents to deserialize"); - if(!args[3]->IsArray()) return VException("Fourth argument must be an array the size of documents to deserialize"); - if(!args[4]->IsUint32()) return VException("Sixth argument must be a positive index number"); - } - - // If we have 4 arguments - if(args.Length() == 6 && !args[5]->IsObject()) return VException("Fifth argument must be an object with options"); - - // Define pointer to data - Local obj = args[0]->ToObject(); - uint32_t numberOfDocuments = args[2]->Uint32Value(); - uint32_t index = args[1]->Uint32Value(); - uint32_t resultIndex = args[4]->Uint32Value(); - - // Unpack the BSON parser instance - BSON *bson = ObjectWrap::Unwrap(args.This()); - - // Unpack the buffer variable -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION < 3 - Buffer *buffer = ObjectWrap::Unwrap(obj); - char* data = buffer->data(); - size_t length = buffer->length(); -#else - char* data = Buffer::Data(obj); - size_t length = Buffer::Length(obj); -#endif - - // Fetch the documents - Local documents = args[3]->ToObject(); - - BSONDeserializer deserializer(bson, data+index, length-index); - for(uint32_t i = 0; i < numberOfDocuments; i++) - { - try - { - documents->Set(i + resultIndex, deserializer.DeserializeDocument()); - } - catch (char* exception) - { - Handle error = VException(exception); - free(exception); - return error; - } - } - - // Return new index of parsing - return scope.Close(Uint32::New((uint32_t) (index + deserializer.GetSerializeSize()))); -} - -// Exporting function -extern "C" void init(Handle target) -{ - HandleScope scope; - BSON::Initialize(target); -} - -NODE_MODULE(bson, BSON::Initialize); diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h deleted file mode 100644 index 580abd4de2b..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/bson.h +++ /dev/null @@ -1,273 +0,0 @@ -//=========================================================================== - -#ifndef BSON_H_ -#define BSON_H_ - -//=========================================================================== - -#define USE_MISALIGNED_MEMORY_ACCESS 1 - -#include -#include -#include - -using namespace v8; -using namespace node; - -//=========================================================================== - -enum BsonType -{ - BSON_TYPE_NUMBER = 1, - BSON_TYPE_STRING = 2, - BSON_TYPE_OBJECT = 3, - BSON_TYPE_ARRAY = 4, - BSON_TYPE_BINARY = 5, - BSON_TYPE_UNDEFINED = 6, - BSON_TYPE_OID = 7, - BSON_TYPE_BOOLEAN = 8, - BSON_TYPE_DATE = 9, - BSON_TYPE_NULL = 10, - BSON_TYPE_REGEXP = 11, - BSON_TYPE_CODE = 13, - BSON_TYPE_SYMBOL = 14, - BSON_TYPE_CODE_W_SCOPE = 15, - BSON_TYPE_INT = 16, - BSON_TYPE_TIMESTAMP = 17, - BSON_TYPE_LONG = 18, - BSON_TYPE_MAX_KEY = 0x7f, - BSON_TYPE_MIN_KEY = 0xff -}; - -//=========================================================================== - -template class BSONSerializer; - -class BSON : public ObjectWrap { -public: - BSON(); - ~BSON() {} - - static void Initialize(Handle target); - static Handle BSONDeserializeStream(const Arguments &args); - - // JS based objects - static Handle BSONSerialize(const Arguments &args); - static Handle BSONDeserialize(const Arguments &args); - - // Calculate size of function - static Handle CalculateObjectSize(const Arguments &args); - static Handle SerializeWithBufferAndIndex(const Arguments &args); - - // Constructor used for creating new BSON objects from C++ - static Persistent constructor_template; - -private: - static Handle New(const Arguments &args); - static Handle deserialize(BSON *bson, char *data, uint32_t dataLength, uint32_t startIndex, bool is_array_item); - - // BSON type instantiate functions - Persistent longConstructor; - Persistent objectIDConstructor; - Persistent binaryConstructor; - Persistent codeConstructor; - Persistent dbrefConstructor; - Persistent symbolConstructor; - Persistent doubleConstructor; - Persistent timestampConstructor; - Persistent minKeyConstructor; - Persistent maxKeyConstructor; - - // Equality Objects - Persistent longString; - Persistent objectIDString; - Persistent binaryString; - Persistent codeString; - Persistent dbrefString; - Persistent symbolString; - Persistent doubleString; - Persistent timestampString; - Persistent minKeyString; - Persistent maxKeyString; - - // Equality speed up comparison objects - Persistent _bsontypeString; - Persistent _longLowString; - Persistent _longHighString; - Persistent _objectIDidString; - Persistent _binaryPositionString; - Persistent _binarySubTypeString; - Persistent _binaryBufferString; - Persistent _doubleValueString; - Persistent _symbolValueString; - - Persistent _dbRefRefString; - Persistent _dbRefIdRefString; - Persistent _dbRefDbRefString; - Persistent _dbRefNamespaceString; - Persistent _dbRefDbString; - Persistent _dbRefOidString; - - Persistent _codeCodeString; - Persistent _codeScopeString; - Persistent _toBSONString; - - Local GetSerializeObject(const Handle& object); - - template friend class BSONSerializer; - friend class BSONDeserializer; -}; - -//=========================================================================== - -class CountStream -{ -public: - CountStream() : count(0) { } - - void WriteByte(int value) { ++count; } - void WriteByte(const Handle&, const Handle&) { ++count; } - void WriteBool(const Handle& value) { ++count; } - void WriteInt32(int32_t value) { count += 4; } - void WriteInt32(const Handle& value) { count += 4; } - void WriteInt32(const Handle& object, const Handle& key) { count += 4; } - void WriteInt64(int64_t value) { count += 8; } - void WriteInt64(const Handle& value) { count += 8; } - void WriteDouble(double value) { count += 8; } - void WriteDouble(const Handle& value) { count += 8; } - void WriteDouble(const Handle&, const Handle&) { count += 8; } - void WriteUInt32String(uint32_t name) { char buffer[32]; count += sprintf(buffer, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { count += value->Utf8Length()+5; } - void WriteObjectId(const Handle& object, const Handle& key) { count += 12; } - void WriteString(const Local& value) { count += value->Utf8Length() + 1; } // This returns the number of bytes exclusive of the NULL terminator - void WriteData(const char* data, size_t length) { count += length; } - - void* BeginWriteType() { ++count; return NULL; } - void CommitType(void*, BsonType) { } - void* BeginWriteSize() { count += 4; return NULL; } - void CommitSize(void*) { } - - size_t GetSerializeSize() const { return count; } - - // Do nothing. CheckKey is implemented for DataStream - void CheckKey(const Local&) { } - -private: - size_t count; -}; - -class DataStream -{ -public: - DataStream(char* aDestinationBuffer) : destinationBuffer(aDestinationBuffer), p(aDestinationBuffer) { } - - void WriteByte(int value) { *p++ = value; } - void WriteByte(const Handle& object, const Handle& key) { *p++ = object->Get(key)->Int32Value(); } -#if USE_MISALIGNED_MEMORY_ACCESS - void WriteInt32(int32_t value) { *reinterpret_cast(p) = value; p += 4; } - void WriteInt64(int64_t value) { *reinterpret_cast(p) = value; p += 8; } - void WriteDouble(double value) { *reinterpret_cast(p) = value; p += 8; } -#else - void WriteInt32(int32_t value) { memcpy(p, &value, 4); p += 4; } - void WriteInt64(int64_t value) { memcpy(p, &value, 8); p += 8; } - void WriteDouble(double value) { memcpy(p, &value, 8); p += 8; } -#endif - void WriteBool(const Handle& value) { WriteByte(value->BooleanValue() ? 1 : 0); } - void WriteInt32(const Handle& value) { WriteInt32(value->Int32Value()); } - void WriteInt32(const Handle& object, const Handle& key) { WriteInt32(object->Get(key)); } - void WriteInt64(const Handle& value) { WriteInt64(value->IntegerValue()); } - void WriteDouble(const Handle& value) { WriteDouble(value->NumberValue()); } - void WriteDouble(const Handle& object, const Handle& key) { WriteDouble(object->Get(key)); } - void WriteUInt32String(uint32_t name) { p += sprintf(p, "%u", name) + 1; } - void WriteLengthPrefixedString(const Local& value) { WriteInt32(value->Utf8Length()+1); WriteString(value); } - void WriteObjectId(const Handle& object, const Handle& key); - void WriteString(const Local& value) { p += value->WriteUtf8(p); } // This returns the number of bytes inclusive of the NULL terminator. - void WriteData(const char* data, size_t length) { memcpy(p, data, length); p += length; } - - void* BeginWriteType() { void* returnValue = p; p++; return returnValue; } - void CommitType(void* beginPoint, BsonType value) { *reinterpret_cast(beginPoint) = value; } - void* BeginWriteSize() { void* returnValue = p; p += 4; return returnValue; } - -#if USE_MISALIGNED_MEMORY_ACCESS - void CommitSize(void* beginPoint) { *reinterpret_cast(beginPoint) = (int32_t) (p - (char*) beginPoint); } -#else - void CommitSize(void* beginPoint) { int32_t value = (int32_t) (p - (char*) beginPoint); memcpy(beginPoint, &value, 4); } -#endif - - size_t GetSerializeSize() const { return p - destinationBuffer; } - - void CheckKey(const Local& keyName); - -protected: - char *const destinationBuffer; // base, never changes - char* p; // cursor into buffer -}; - -template class BSONSerializer : public T -{ -private: - typedef T Inherited; - -public: - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions) : Inherited(), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - BSONSerializer(BSON* aBson, bool aCheckKeys, bool aSerializeFunctions, char* parentParam) : Inherited(parentParam), checkKeys(aCheckKeys), serializeFunctions(aSerializeFunctions), bson(aBson) { } - - void SerializeDocument(const Handle& value); - void SerializeArray(const Handle& value); - void SerializeValue(void* typeLocation, const Handle& value); - -private: - bool checkKeys; - bool serializeFunctions; - BSON* bson; -}; - -//=========================================================================== - -class BSONDeserializer -{ -public: - BSONDeserializer(BSON* aBson, char* data, size_t length); - BSONDeserializer(BSONDeserializer& parentSerializer, size_t length); - - Handle DeserializeDocument(); - - bool HasMoreData() const { return p < pEnd; } - Local ReadCString(); - uint32_t ReadIntegerString(); - int32_t ReadRegexOptions(); - Local ReadString(); - Local ReadObjectId(); - - unsigned char ReadByte() { return *reinterpret_cast(p++); } -#if USE_MISALIGNED_MEMORY_ACCESS - int32_t ReadInt32() { int32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue = *reinterpret_cast(p); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue = *reinterpret_cast(p); p += 8; return returnValue; } - double ReadDouble() { double returnValue = *reinterpret_cast(p); p += 8; return returnValue; } -#else - int32_t ReadInt32() { int32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - uint32_t ReadUInt32() { uint32_t returnValue; memcpy(&returnValue, p, 4); p += 4; return returnValue; } - int64_t ReadInt64() { int64_t returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } - double ReadDouble() { double returnValue; memcpy(&returnValue, p, 8); p += 8; return returnValue; } -#endif - - size_t GetSerializeSize() const { return p - pStart; } - -private: - Handle DeserializeArray(); - Handle DeserializeValue(BsonType type); - Handle DeserializeDocumentInternal(); - Handle DeserializeArrayInternal(); - - BSON* bson; - char* const pStart; - char* p; - char* const pEnd; -}; - -//=========================================================================== - -#endif // BSON_H_ - -//=========================================================================== diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js deleted file mode 100644 index 85e243cc2e1..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/index.js +++ /dev/null @@ -1,30 +0,0 @@ -var bson = null; - -// Load the precompiled win32 binary -if(process.platform == "win32" && process.arch == "x64") { - bson = require('./win32/x64/bson'); -} else if(process.platform == "win32" && process.arch == "ia32") { - bson = require('./win32/ia32/bson'); -} else { - bson = require('../build/Release/bson'); -} - -exports.BSON = bson.BSON; -exports.Long = require('../lib/bson/long').Long; -exports.ObjectID = require('../lib/bson/objectid').ObjectID; -exports.DBRef = require('../lib/bson/db_ref').DBRef; -exports.Code = require('../lib/bson/code').Code; -exports.Timestamp = require('../lib/bson/timestamp').Timestamp; -exports.Binary = require('../lib/bson/binary').Binary; -exports.Double = require('../lib/bson/double').Double; -exports.MaxKey = require('../lib/bson/max_key').MaxKey; -exports.MinKey = require('../lib/bson/min_key').MinKey; -exports.Symbol = require('../lib/bson/symbol').Symbol; - -// Just add constants tot he Native BSON parser -exports.BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -exports.BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -exports.BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -exports.BSON.BSON_BINARY_SUBTYPE_UUID = 3; -exports.BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -exports.BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node deleted file mode 100644 index b27819bb1a8..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/ia32/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node deleted file mode 100644 index a544c8ed638..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/win32/x64/bson.node and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript deleted file mode 100644 index 40f5317f116..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/ext/wscript +++ /dev/null @@ -1,39 +0,0 @@ -import Options -from os import unlink, symlink, popen -from os.path import exists - -srcdir = "." -blddir = "build" -VERSION = "0.1.0" - -def set_options(opt): - opt.tool_options("compiler_cxx") - opt.add_option( '--debug' - , action='store_true' - , default=False - , help='Build debug variant [Default: False]' - , dest='debug' - ) - -def configure(conf): - conf.check_tool("compiler_cxx") - conf.check_tool("node_addon") - conf.env.append_value('CXXFLAGS', ['-O3', '-funroll-loops']) - - # conf.env.append_value('CXXFLAGS', ['-DDEBUG', '-g', '-O0', '-Wall', '-Wextra']) - # conf.check(lib='node', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='NODE') - -def build(bld): - obj = bld.new_task_gen("cxx", "shlib", "node_addon") - obj.target = "bson" - obj.source = ["bson.cc"] - # obj.uselib = "NODE" - -def shutdown(): - # HACK to get compress.node out of build directory. - # better way to do this? - if Options.commands['clean']: - if exists('bson.node'): unlink('bson.node') - else: - if exists('build/default/bson.node') and not exists('bson.node'): - symlink('build/default/bson.node', 'bson.node') diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js deleted file mode 100644 index 82d4d04c10b..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary.js +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Module dependencies. - */ -if(typeof window === 'undefined') { - var Buffer = require('buffer').Buffer; // TODO just use global Buffer -} - -// Binary default subtype -var BSON_BINARY_SUBTYPE_DEFAULT = 0; - -/** - * @ignore - * @api private - */ -var writeStringToArray = function(data) { - // Create a buffer - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(data.length)) : new Array(data.length); - // Write the content to the buffer - for(var i = 0; i < data.length; i++) { - buffer[i] = data.charCodeAt(i); - } - // Write the string to the buffer - return buffer; -} - -/** - * Convert Array ot Uint8Array to Binary String - * - * @ignore - * @api private - */ -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - return result; -}; - -/** - * A class representation of the BSON Binary type. - * - * Sub types - * - **BSON.BSON_BINARY_SUBTYPE_DEFAULT**, default BSON type. - * - **BSON.BSON_BINARY_SUBTYPE_FUNCTION**, BSON function type. - * - **BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY**, BSON byte array type. - * - **BSON.BSON_BINARY_SUBTYPE_UUID**, BSON uuid type. - * - **BSON.BSON_BINARY_SUBTYPE_MD5**, BSON md5 type. - * - **BSON.BSON_BINARY_SUBTYPE_USER_DEFINED**, BSON user defined type. - * - * @class Represents the Binary BSON type. - * @param {Buffer} buffer a buffer object containing the binary data. - * @param {Number} [subType] the option binary type. - * @return {Grid} - */ -function Binary(buffer, subType) { - if(!(this instanceof Binary)) return new Binary(buffer, subType); - - this._bsontype = 'Binary'; - - if(buffer instanceof Number) { - this.sub_type = buffer; - this.position = 0; - } else { - this.sub_type = subType == null ? BSON_BINARY_SUBTYPE_DEFAULT : subType; - this.position = 0; - } - - if(buffer != null && !(buffer instanceof Number)) { - // Only accept Buffer, Uint8Array or Arrays - if(typeof buffer == 'string') { - // Different ways of writing the length of the string for the different types - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(buffer); - } else if(typeof Uint8Array != 'undefined' || (Object.prototype.toString.call(buffer) == '[object Array]')) { - this.buffer = writeStringToArray(buffer); - } else { - throw new Error("only String, Buffer, Uint8Array or Array accepted"); - } - } else { - this.buffer = buffer; - } - this.position = buffer.length; - } else { - if(typeof Buffer != 'undefined') { - this.buffer = new Buffer(Binary.BUFFER_SIZE); - } else if(typeof Uint8Array != 'undefined'){ - this.buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE)); - } else { - this.buffer = new Array(Binary.BUFFER_SIZE); - } - // Set position to start of buffer - this.position = 0; - } -}; - -/** - * Updates this binary with byte_value. - * - * @param {Character} byte_value a single byte we wish to write. - * @api public - */ -Binary.prototype.put = function put(byte_value) { - // If it's a string and a has more than one character throw an error - if(byte_value['length'] != null && typeof byte_value != 'number' && byte_value.length != 1) throw new Error("only accepts single character String, Uint8Array or Array"); - if(typeof byte_value != 'number' && byte_value < 0 || byte_value > 255) throw new Error("only accepts number in a valid unsigned byte range 0-255"); - - // Decode the byte value once - var decoded_byte = null; - if(typeof byte_value == 'string') { - decoded_byte = byte_value.charCodeAt(0); - } else if(byte_value['length'] != null) { - decoded_byte = byte_value[0]; - } else { - decoded_byte = byte_value; - } - - if(this.buffer.length > this.position) { - this.buffer[this.position++] = decoded_byte; - } else { - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - // Create additional overflow buffer - var buffer = new Buffer(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; - this.buffer[this.position++] = decoded_byte; - } else { - var buffer = null; - // Create a new buffer (typed or normal array) - if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - buffer = new Uint8Array(new ArrayBuffer(Binary.BUFFER_SIZE + this.buffer.length)); - } else { - buffer = new Array(Binary.BUFFER_SIZE + this.buffer.length); - } - - // We need to copy all the content to the new array - for(var i = 0; i < this.buffer.length; i++) { - buffer[i] = this.buffer[i]; - } - - // Reassign the buffer - this.buffer = buffer; - // Write the byte - this.buffer[this.position++] = decoded_byte; - } - } -}; - -/** - * Writes a buffer or string to the binary. - * - * @param {Buffer|String} string a string or buffer to be written to the Binary BSON object. - * @param {Number} offset specify the binary of where to write the content. - * @api public - */ -Binary.prototype.write = function write(string, offset) { - offset = typeof offset == 'number' ? offset : this.position; - - // If the buffer is to small let's extend the buffer - if(this.buffer.length < offset + string.length) { - var buffer = null; - // If we are in node.js - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - buffer = new Buffer(this.buffer.length + string.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); - } else if(Object.prototype.toString.call(this.buffer) == '[object Uint8Array]') { - // Create a new buffer - buffer = new Uint8Array(new ArrayBuffer(this.buffer.length + string.length)) - // Copy the content - for(var i = 0; i < this.position; i++) { - buffer[i] = this.buffer[i]; - } - } - - // Assign the new buffer - this.buffer = buffer; - } - - if(typeof Buffer != 'undefined' && Buffer.isBuffer(string) && Buffer.isBuffer(this.buffer)) { - string.copy(this.buffer, offset, 0, string.length); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length - } else if(typeof Buffer != 'undefined' && typeof string == 'string' && Buffer.isBuffer(this.buffer)) { - this.buffer.write(string, 'binary', offset); - this.position = (offset + string.length) > this.position ? (offset + string.length) : this.position; - // offset = string.length; - } else if(Object.prototype.toString.call(string) == '[object Uint8Array]' - || Object.prototype.toString.call(string) == '[object Array]' && typeof string != 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string[i]; - } - - this.position = offset > this.position ? offset : this.position; - } else if(typeof string == 'string') { - for(var i = 0; i < string.length; i++) { - this.buffer[offset++] = string.charCodeAt(i); - } - - this.position = offset > this.position ? offset : this.position; - } -}; - -/** - * Reads **length** bytes starting at **position**. - * - * @param {Number} position read from the given position in the Binary. - * @param {Number} length the number of bytes to read. - * @return {Buffer} - * @api public - */ -Binary.prototype.read = function read(position, length) { - length = length && length > 0 - ? length - : this.position; - - // Let's return the data based on the type we have - if(this.buffer['slice']) { - return this.buffer.slice(position, position + length); - } else { - // Create a buffer to keep the result - var buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(length)) : new Array(length); - for(var i = 0; i < length; i++) { - buffer[i] = this.buffer[position++]; - } - } - // Return the buffer - return buffer; -}; - -/** - * Returns the value of this binary as a string. - * - * @return {String} - * @api public - */ -Binary.prototype.value = function value(asRaw) { - asRaw = asRaw == null ? false : asRaw; - - // If it's a node.js buffer object - if(typeof Buffer != 'undefined' && Buffer.isBuffer(this.buffer)) { - return asRaw ? this.buffer.slice(0, this.position) : this.buffer.toString('binary', 0, this.position); - } else { - if(asRaw) { - // we support the slice command use it - if(this.buffer['slice'] != null) { - return this.buffer.slice(0, this.position); - } else { - // Create a new buffer to copy content to - var newBuffer = Object.prototype.toString.call(this.buffer) == '[object Uint8Array]' ? new Uint8Array(new ArrayBuffer(this.position)) : new Array(this.position); - // Copy content - for(var i = 0; i < this.position; i++) { - newBuffer[i] = this.buffer[i]; - } - // Return the buffer - return newBuffer; - } - } else { - return convertArraytoUtf8BinaryString(this.buffer, 0, this.position); - } - } -}; - -/** - * Length. - * - * @return {Number} the length of the binary. - * @api public - */ -Binary.prototype.length = function length() { - return this.position; -}; - -/** - * @ignore - * @api private - */ -Binary.prototype.toJSON = function() { - return this.buffer != null ? this.buffer.toString('base64') : ''; -} - -/** - * @ignore - * @api private - */ -Binary.prototype.toString = function(format) { - return this.buffer != null ? this.buffer.slice(0, this.position).toString(format) : ''; -} - -Binary.BUFFER_SIZE = 256; - -/** - * Default BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_DEFAULT = 0; -/** - * Function BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_FUNCTION = 1; -/** - * Byte Array BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_BYTE_ARRAY = 2; -/** - * OLD UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID_OLD = 3; -/** - * UUID BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_UUID = 4; -/** - * MD5 BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_MD5 = 5; -/** - * User BSON type - * - * @classconstant SUBTYPE_DEFAULT - **/ -Binary.SUBTYPE_USER_DEFINED = 128; - -/** - * Expose. - */ -exports.Binary = Binary; - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js deleted file mode 100644 index d2fc811f416..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/binary_parser.js +++ /dev/null @@ -1,385 +0,0 @@ -/** - * Binary Parser. - * Jonas Raoni Soares Silva - * http://jsfromhell.com/classes/binary-parser [v1.0] - */ -var chr = String.fromCharCode; - -var maxBits = []; -for (var i = 0; i < 64; i++) { - maxBits[i] = Math.pow(2, i); -} - -function BinaryParser (bigEndian, allowExceptions) { - if(!(this instanceof BinaryParser)) return new BinaryParser(bigEndian, allowExceptions); - - this.bigEndian = bigEndian; - this.allowExceptions = allowExceptions; -}; - -BinaryParser.warn = function warn (msg) { - if (this.allowExceptions) { - throw new Error(msg); - } - - return 1; -}; - -BinaryParser.decodeFloat = function decodeFloat (data, precisionBits, exponentBits) { - var b = new this.Buffer(this.bigEndian, data); - - b.checkBuffer(precisionBits + exponentBits + 1); - - var bias = maxBits[exponentBits - 1] - 1 - , signal = b.readBits(precisionBits + exponentBits, 1) - , exponent = b.readBits(precisionBits, exponentBits) - , significand = 0 - , divisor = 2 - , curByte = b.buffer.length + (-precisionBits >> 3) - 1; - - do { - for (var byteValue = b.buffer[ ++curByte ], startBit = precisionBits % 8 || 8, mask = 1 << startBit; mask >>= 1; ( byteValue & mask ) && ( significand += 1 / divisor ), divisor *= 2 ); - } while (precisionBits -= startBit); - - return exponent == ( bias << 1 ) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity : ( 1 + signal * -2 ) * ( exponent || significand ? !exponent ? Math.pow( 2, -bias + 1 ) * significand : Math.pow( 2, exponent - bias ) * ( 1 + significand ) : 0 ); -}; - -BinaryParser.decodeInt = function decodeInt (data, bits, signed, forceBigEndian) { - var b = new this.Buffer(this.bigEndian || forceBigEndian, data) - , x = b.readBits(0, bits) - , max = maxBits[bits]; //max = Math.pow( 2, bits ); - - return signed && x >= max / 2 - ? x - max - : x; -}; - -BinaryParser.encodeFloat = function encodeFloat (data, precisionBits, exponentBits) { - var bias = maxBits[exponentBits - 1] - 1 - , minExp = -bias + 1 - , maxExp = bias - , minUnnormExp = minExp - precisionBits - , n = parseFloat(data) - , status = isNaN(n) || n == -Infinity || n == +Infinity ? n : 0 - , exp = 0 - , len = 2 * bias + 1 + precisionBits + 3 - , bin = new Array(len) - , signal = (n = status !== 0 ? 0 : n) < 0 - , intPart = Math.floor(n = Math.abs(n)) - , floatPart = n - intPart - , lastBit - , rounded - , result - , i - , j; - - for (i = len; i; bin[--i] = 0); - - for (i = bias + 2; intPart && i; bin[--i] = intPart % 2, intPart = Math.floor(intPart / 2)); - - for (i = bias + 1; floatPart > 0 && i; (bin[++i] = ((floatPart *= 2) >= 1) - 0 ) && --floatPart); - - for (i = -1; ++i < len && !bin[i];); - - if (bin[(lastBit = precisionBits - 1 + (i = (exp = bias + 1 - i) >= minExp && exp <= maxExp ? i + 1 : bias + 1 - (exp = minExp - 1))) + 1]) { - if (!(rounded = bin[lastBit])) { - for (j = lastBit + 2; !rounded && j < len; rounded = bin[j++]); - } - - for (j = lastBit + 1; rounded && --j >= 0; (bin[j] = !bin[j] - 0) && (rounded = 0)); - } - - for (i = i - 2 < 0 ? -1 : i - 3; ++i < len && !bin[i];); - - if ((exp = bias + 1 - i) >= minExp && exp <= maxExp) { - ++i; - } else if (exp < minExp) { - exp != bias + 1 - len && exp < minUnnormExp && this.warn("encodeFloat::float underflow"); - i = bias + 1 - (exp = minExp - 1); - } - - if (intPart || status !== 0) { - this.warn(intPart ? "encodeFloat::float overflow" : "encodeFloat::" + status); - exp = maxExp + 1; - i = bias + 2; - - if (status == -Infinity) { - signal = 1; - } else if (isNaN(status)) { - bin[i] = 1; - } - } - - for (n = Math.abs(exp + bias), j = exponentBits + 1, result = ""; --j; result = (n % 2) + result, n = n >>= 1); - - for (n = 0, j = 0, i = (result = (signal ? "1" : "0") + result + bin.slice(i, i + precisionBits).join("")).length, r = []; i; j = (j + 1) % 8) { - n += (1 << j) * result.charAt(--i); - if (j == 7) { - r[r.length] = String.fromCharCode(n); - n = 0; - } - } - - r[r.length] = n - ? String.fromCharCode(n) - : ""; - - return (this.bigEndian ? r.reverse() : r).join(""); -}; - -BinaryParser.encodeInt = function encodeInt (data, bits, signed, forceBigEndian) { - var max = maxBits[bits]; - - if (data >= max || data < -(max / 2)) { - this.warn("encodeInt::overflow"); - data = 0; - } - - if (data < 0) { - data += max; - } - - for (var r = []; data; r[r.length] = String.fromCharCode(data % 256), data = Math.floor(data / 256)); - - for (bits = -(-bits >> 3) - r.length; bits--; r[r.length] = "\0"); - - return ((this.bigEndian || forceBigEndian) ? r.reverse() : r).join(""); -}; - -BinaryParser.toSmall = function( data ){ return this.decodeInt( data, 8, true ); }; -BinaryParser.fromSmall = function( data ){ return this.encodeInt( data, 8, true ); }; -BinaryParser.toByte = function( data ){ return this.decodeInt( data, 8, false ); }; -BinaryParser.fromByte = function( data ){ return this.encodeInt( data, 8, false ); }; -BinaryParser.toShort = function( data ){ return this.decodeInt( data, 16, true ); }; -BinaryParser.fromShort = function( data ){ return this.encodeInt( data, 16, true ); }; -BinaryParser.toWord = function( data ){ return this.decodeInt( data, 16, false ); }; -BinaryParser.fromWord = function( data ){ return this.encodeInt( data, 16, false ); }; -BinaryParser.toInt = function( data ){ return this.decodeInt( data, 32, true ); }; -BinaryParser.fromInt = function( data ){ return this.encodeInt( data, 32, true ); }; -BinaryParser.toLong = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromLong = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toDWord = function( data ){ return this.decodeInt( data, 32, false ); }; -BinaryParser.fromDWord = function( data ){ return this.encodeInt( data, 32, false ); }; -BinaryParser.toQWord = function( data ){ return this.decodeInt( data, 64, true ); }; -BinaryParser.fromQWord = function( data ){ return this.encodeInt( data, 64, true ); }; -BinaryParser.toFloat = function( data ){ return this.decodeFloat( data, 23, 8 ); }; -BinaryParser.fromFloat = function( data ){ return this.encodeFloat( data, 23, 8 ); }; -BinaryParser.toDouble = function( data ){ return this.decodeFloat( data, 52, 11 ); }; -BinaryParser.fromDouble = function( data ){ return this.encodeFloat( data, 52, 11 ); }; - -// Factor out the encode so it can be shared by add_header and push_int32 -BinaryParser.encode_int32 = function encode_int32 (number, asArray) { - var a, b, c, d, unsigned; - unsigned = (number < 0) ? (number + 0x100000000) : number; - a = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - b = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - c = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - d = Math.floor(unsigned); - return asArray ? [chr(a), chr(b), chr(c), chr(d)] : chr(a) + chr(b) + chr(c) + chr(d); -}; - -BinaryParser.encode_int64 = function encode_int64 (number) { - var a, b, c, d, e, f, g, h, unsigned; - unsigned = (number < 0) ? (number + 0x10000000000000000) : number; - a = Math.floor(unsigned / 0xffffffffffffff); - unsigned &= 0xffffffffffffff; - b = Math.floor(unsigned / 0xffffffffffff); - unsigned &= 0xffffffffffff; - c = Math.floor(unsigned / 0xffffffffff); - unsigned &= 0xffffffffff; - d = Math.floor(unsigned / 0xffffffff); - unsigned &= 0xffffffff; - e = Math.floor(unsigned / 0xffffff); - unsigned &= 0xffffff; - f = Math.floor(unsigned / 0xffff); - unsigned &= 0xffff; - g = Math.floor(unsigned / 0xff); - unsigned &= 0xff; - h = Math.floor(unsigned); - return chr(a) + chr(b) + chr(c) + chr(d) + chr(e) + chr(f) + chr(g) + chr(h); -}; - -/** - * UTF8 methods - */ - -// Take a raw binary string and return a utf8 string -BinaryParser.decode_utf8 = function decode_utf8 (binaryStr) { - var len = binaryStr.length - , decoded = '' - , i = 0 - , c = 0 - , c1 = 0 - , c2 = 0 - , c3; - - while (i < len) { - c = binaryStr.charCodeAt(i); - if (c < 128) { - decoded += String.fromCharCode(c); - i++; - } else if ((c > 191) && (c < 224)) { - c2 = binaryStr.charCodeAt(i+1); - decoded += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = binaryStr.charCodeAt(i+1); - c3 = binaryStr.charCodeAt(i+2); - decoded += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return decoded; -}; - -// Encode a cstring -BinaryParser.encode_cstring = function encode_cstring (s) { - return unescape(encodeURIComponent(s)) + BinaryParser.fromByte(0); -}; - -// Take a utf8 string and return a binary string -BinaryParser.encode_utf8 = function encode_utf8 (s) { - var a = "" - , c; - - for (var n = 0, len = s.length; n < len; n++) { - c = s.charCodeAt(n); - - if (c < 128) { - a += String.fromCharCode(c); - } else if ((c > 127) && (c < 2048)) { - a += String.fromCharCode((c>>6) | 192) ; - a += String.fromCharCode((c&63) | 128); - } else { - a += String.fromCharCode((c>>12) | 224); - a += String.fromCharCode(((c>>6) & 63) | 128); - a += String.fromCharCode((c&63) | 128); - } - } - - return a; -}; - -BinaryParser.hprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - process.stdout.write(number + " ") - } - } - - process.stdout.write("\n\n"); -}; - -BinaryParser.ilprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(10) - : s.charCodeAt(i).toString(10); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -BinaryParser.hlprint = function hprint (s) { - var number; - - for (var i = 0, len = s.length; i < len; i++) { - if (s.charCodeAt(i) < 32) { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '); - } else { - number = s.charCodeAt(i) <= 15 - ? "0" + s.charCodeAt(i).toString(16) - : s.charCodeAt(i).toString(16); - require('util').debug(number+' : '+ s.charAt(i)); - } - } -}; - -/** - * BinaryParser buffer constructor. - */ -function BinaryParserBuffer (bigEndian, buffer) { - this.bigEndian = bigEndian || 0; - this.buffer = []; - this.setBuffer(buffer); -}; - -BinaryParserBuffer.prototype.setBuffer = function setBuffer (data) { - var l, i, b; - - if (data) { - i = l = data.length; - b = this.buffer = new Array(l); - for (; i; b[l - i] = data.charCodeAt(--i)); - this.bigEndian && b.reverse(); - } -}; - -BinaryParserBuffer.prototype.hasNeededBits = function hasNeededBits (neededBits) { - return this.buffer.length >= -(-neededBits >> 3); -}; - -BinaryParserBuffer.prototype.checkBuffer = function checkBuffer (neededBits) { - if (!this.hasNeededBits(neededBits)) { - throw new Error("checkBuffer::missing bytes"); - } -}; - -BinaryParserBuffer.prototype.readBits = function readBits (start, length) { - //shl fix: Henri Torgemane ~1996 (compressed by Jonas Raoni) - - function shl (a, b) { - for (; b--; a = ((a %= 0x7fffffff + 1) & 0x40000000) == 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1); - return a; - } - - if (start < 0 || length <= 0) { - return 0; - } - - this.checkBuffer(start + length); - - var offsetLeft - , offsetRight = start % 8 - , curByte = this.buffer.length - ( start >> 3 ) - 1 - , lastByte = this.buffer.length + ( -( start + length ) >> 3 ) - , diff = curByte - lastByte - , sum = ((this.buffer[ curByte ] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1)) + (diff && (offsetLeft = (start + length) % 8) ? (this.buffer[lastByte++] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight : 0); - - for(; diff; sum += shl(this.buffer[lastByte++], (diff-- << 3) - offsetRight)); - - return sum; -}; - -/** - * Expose. - */ -BinaryParser.Buffer = BinaryParserBuffer; - -exports.BinaryParser = BinaryParser; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js deleted file mode 100644 index 57fdd7958b8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/bson.js +++ /dev/null @@ -1,1519 +0,0 @@ -var Long = require('./long').Long - , Double = require('./double').Double - , Timestamp = require('./timestamp').Timestamp - , ObjectID = require('./objectid').ObjectID - , Symbol = require('./symbol').Symbol - , Code = require('./code').Code - , MinKey = require('./min_key').MinKey - , MaxKey = require('./max_key').MaxKey - , DBRef = require('./db_ref').DBRef - , Binary = require('./binary').Binary - , BinaryParser = require('./binary_parser').BinaryParser - , writeIEEE754 = require('./float_parser').writeIEEE754 - , readIEEE754 = require('./float_parser').readIEEE754 - -// To ensure that 0.4 of node works correctly -var isDate = function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -/** - * Create a new BSON instance - * - * @class Represents the BSON Parser - * @return {BSON} instance of BSON Parser. - */ -function BSON () {}; - -/** - * @ignore - * @api private - */ -// BSON MAX VALUES -BSON.BSON_INT32_MAX = 0x7FFFFFFF; -BSON.BSON_INT32_MIN = -0x80000000; - -BSON.BSON_INT64_MAX = Math.pow(2, 63) - 1; -BSON.BSON_INT64_MIN = -Math.pow(2, 63); - -// JS MAX PRECISE VALUES -BSON.JS_INT_MAX = 0x20000000000000; // Any integer up to 2^53 can be precisely represented by a double. -BSON.JS_INT_MIN = -0x20000000000000; // Any integer down to -2^53 can be precisely represented by a double. - -// Internal long versions -var JS_INT_MAX_LONG = Long.fromNumber(0x20000000000000); // Any integer up to 2^53 can be precisely represented by a double. -var JS_INT_MIN_LONG = Long.fromNumber(-0x20000000000000); // Any integer down to -2^53 can be precisely represented by a double. - -/** - * Number BSON Type - * - * @classconstant BSON_DATA_NUMBER - **/ -BSON.BSON_DATA_NUMBER = 1; -/** - * String BSON Type - * - * @classconstant BSON_DATA_STRING - **/ -BSON.BSON_DATA_STRING = 2; -/** - * Object BSON Type - * - * @classconstant BSON_DATA_OBJECT - **/ -BSON.BSON_DATA_OBJECT = 3; -/** - * Array BSON Type - * - * @classconstant BSON_DATA_ARRAY - **/ -BSON.BSON_DATA_ARRAY = 4; -/** - * Binary BSON Type - * - * @classconstant BSON_DATA_BINARY - **/ -BSON.BSON_DATA_BINARY = 5; -/** - * ObjectID BSON Type - * - * @classconstant BSON_DATA_OID - **/ -BSON.BSON_DATA_OID = 7; -/** - * Boolean BSON Type - * - * @classconstant BSON_DATA_BOOLEAN - **/ -BSON.BSON_DATA_BOOLEAN = 8; -/** - * Date BSON Type - * - * @classconstant BSON_DATA_DATE - **/ -BSON.BSON_DATA_DATE = 9; -/** - * null BSON Type - * - * @classconstant BSON_DATA_NULL - **/ -BSON.BSON_DATA_NULL = 10; -/** - * RegExp BSON Type - * - * @classconstant BSON_DATA_REGEXP - **/ -BSON.BSON_DATA_REGEXP = 11; -/** - * Code BSON Type - * - * @classconstant BSON_DATA_CODE - **/ -BSON.BSON_DATA_CODE = 13; -/** - * Symbol BSON Type - * - * @classconstant BSON_DATA_SYMBOL - **/ -BSON.BSON_DATA_SYMBOL = 14; -/** - * Code with Scope BSON Type - * - * @classconstant BSON_DATA_CODE_W_SCOPE - **/ -BSON.BSON_DATA_CODE_W_SCOPE = 15; -/** - * 32 bit Integer BSON Type - * - * @classconstant BSON_DATA_INT - **/ -BSON.BSON_DATA_INT = 16; -/** - * Timestamp BSON Type - * - * @classconstant BSON_DATA_TIMESTAMP - **/ -BSON.BSON_DATA_TIMESTAMP = 17; -/** - * Long BSON Type - * - * @classconstant BSON_DATA_LONG - **/ -BSON.BSON_DATA_LONG = 18; -/** - * MinKey BSON Type - * - * @classconstant BSON_DATA_MIN_KEY - **/ -BSON.BSON_DATA_MIN_KEY = 0xff; -/** - * MaxKey BSON Type - * - * @classconstant BSON_DATA_MAX_KEY - **/ -BSON.BSON_DATA_MAX_KEY = 0x7f; - -/** - * Binary Default Type - * - * @classconstant BSON_BINARY_SUBTYPE_DEFAULT - **/ -BSON.BSON_BINARY_SUBTYPE_DEFAULT = 0; -/** - * Binary Function Type - * - * @classconstant BSON_BINARY_SUBTYPE_FUNCTION - **/ -BSON.BSON_BINARY_SUBTYPE_FUNCTION = 1; -/** - * Binary Byte Array Type - * - * @classconstant BSON_BINARY_SUBTYPE_BYTE_ARRAY - **/ -BSON.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -/** - * Binary UUID Type - * - * @classconstant BSON_BINARY_SUBTYPE_UUID - **/ -BSON.BSON_BINARY_SUBTYPE_UUID = 3; -/** - * Binary MD5 Type - * - * @classconstant BSON_BINARY_SUBTYPE_MD5 - **/ -BSON.BSON_BINARY_SUBTYPE_MD5 = 4; -/** - * Binary User Defined Type - * - * @classconstant BSON_BINARY_SUBTYPE_USER_DEFINED - **/ -BSON.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.calculateObjectSize = function calculateObjectSize(object, serializeFunctions) { - var totalLength = (4 + 1); - - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - totalLength += calculateElement(i.toString(), object[i], serializeFunctions) - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Calculate size - for(var key in object) { - totalLength += calculateElement(key, object[key], serializeFunctions) - } - } - - return totalLength; -} - -/** - * @ignore - * @api private - */ -function calculateElement(name, value, serializeFunctions) { - var isBuffer = typeof Buffer !== 'undefined'; - - switch(typeof value) { - case 'string': - return 1 + (!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1 + 4 + (!isBuffer ? numberOfBytes(value) : Buffer.byteLength(value, 'utf8')) + 1; - case 'number': - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { // 32 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (4 + 1); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - } else { // 64 bit - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } - case 'undefined': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - case 'boolean': - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 1); - case 'object': - if(value == null || value instanceof MinKey || value instanceof MaxKey || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1); - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (12 + 1); - } else if(value instanceof Date || isDate(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (1 + 4 + 1) + value.length; - } else if(value instanceof Long || value instanceof Double || value instanceof Timestamp - || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Double' || value['_bsontype'] == 'Timestamp') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (8 + 1); - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - // Calculate size depending on the availability of a scope - if(value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.code.toString()) : Buffer.byteLength(value.code.toString(), 'utf8')) + 1; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Check what kind of subtype we have - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1 + 4); - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + (value.position + 1 + 4 + 1); - } - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + ((!isBuffer ? numberOfBytes(value.value) : Buffer.byteLength(value.value, 'utf8')) + 4 + 1 + 1); - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + BSON.calculateObjectSize(ordered_values, serializeFunctions); - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + BSON.calculateObjectSize(value, serializeFunctions) + 1; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + (!isBuffer ? numberOfBytes(value.source) : Buffer.byteLength(value.source, 'utf8')) + 1 - + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + (value.multiline ? 1 : 0) + 1 - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1 + BSON.calculateObjectSize(value.scope, serializeFunctions); - } else if(serializeFunctions) { - return (name != null ? ((!isBuffer ? numberOfBytes(name) : Buffer.byteLength(name, 'utf8')) + 1) : 0) + 1 + 4 + (!isBuffer ? numberOfBytes(value.toString()) : Buffer.byteLength(value.toString(), 'utf8')) + 1; - } - } - } - - return 0; -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.serializeWithBufferAndIndex = function serializeWithBufferAndIndex(object, checkKeys, buffer, index, serializeFunctions) { - // Default setting false - serializeFunctions = serializeFunctions == null ? false : serializeFunctions; - // Write end information (length of the object) - var size = buffer.length; - // Write the size of the object - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return serializeObject(object, checkKeys, buffer, index, serializeFunctions) - 1; -} - -/** - * @ignore - * @api private - */ -var serializeObject = function(object, checkKeys, buffer, index, serializeFunctions) { - // Process the object - if(Array.isArray(object)) { - for(var i = 0; i < object.length; i++) { - index = packElement(i.toString(), object[i], checkKeys, buffer, index, serializeFunctions); - } - } else { - // If we have toBSON defined, override the current object - if(object.toBSON) { - object = object.toBSON(); - } - - // Serialize the object - for(var key in object) { - // Check the key and throw error if it's illegal - if(checkKeys == true && (key != '$db' && key != '$ref' && key != '$id')) { - BSON.checkKey(key); - } - - // Pack the element - index = packElement(key, object[key], checkKeys, buffer, index, serializeFunctions); - } - } - - // Write zero - buffer[index++] = 0; - return index; -} - -var stringToBytes = function(str) { - var ch, st, re = []; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re.concat( st.reverse() ); - } - // return an array of bytes - return re; -} - -var numberOfBytes = function(str) { - var ch, st, re = 0; - for (var i = 0; i < str.length; i++ ) { - ch = str.charCodeAt(i); // get char - st = []; // set up "stack" - do { - st.push( ch & 0xFF ); // push byte to stack - ch = ch >> 8; // shift value down by 1 byte - } - while ( ch ); - // add stack contents to result - // done because chars have "wrong" endianness - re = re + st.length; - } - // return an array of bytes - return re; -} - -/** - * @ignore - * @api private - */ -var writeToTypedArray = function(buffer, string, index) { - var bytes = stringToBytes(string); - for(var i = 0; i < bytes.length; i++) { - buffer[index + i] = bytes[i]; - } - return bytes.length; -} - -/** - * @ignore - * @api private - */ -var supportsBuffer = typeof Buffer != 'undefined'; - -/** - * @ignore - * @api private - */ -var packElement = function(name, value, checkKeys, buffer, index, serializeFunctions) { - var startIndex = index; - - switch(typeof value) { - case 'string': - // Encode String type - buffer[index++] = BSON.BSON_DATA_STRING; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value) + 1 : numberOfBytes(value) + 1; - // Write the size of the string to buffer - buffer[index + 3] = (size >> 24) & 0xff; - buffer[index + 2] = (size >> 16) & 0xff; - buffer[index + 1] = (size >> 8) & 0xff; - buffer[index] = size & 0xff; - // Ajust the index - index = index + 4; - // Write the string - supportsBuffer ? buffer.write(value, index, 'utf8') : writeToTypedArray(buffer, value, index); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - // Return index - return index; - case 'number': - // We have an integer value - if(Math.floor(value) === value && value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // If the value fits in 32 bits encode as int, if it fits in a double - // encode it as a double, otherwise long - if(value >= BSON.BSON_INT32_MIN && value <= BSON.BSON_INT32_MAX) { - // Set int type 32 bits or less - buffer[index++] = BSON.BSON_DATA_INT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the int value - buffer[index++] = value & 0xff; - buffer[index++] = (value >> 8) & 0xff; - buffer[index++] = (value >> 16) & 0xff; - buffer[index++] = (value >> 24) & 0xff; - } else if(value >= BSON.JS_INT_MIN && value <= BSON.JS_INT_MAX) { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } else { - // Set long type - buffer[index++] = BSON.BSON_DATA_LONG; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var longVal = Long.fromNumber(value); - var lowBits = longVal.getLowBits(); - var highBits = longVal.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - } - } else { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - } - - return index; - case 'undefined': - // Set long type - buffer[index++] = BSON.BSON_DATA_NULL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - case 'boolean': - // Write the type - buffer[index++] = BSON.BSON_DATA_BOOLEAN; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Encode the boolean value - buffer[index++] = value ? 1 : 0; - return index; - case 'object': - if(value === null || value instanceof MinKey || value instanceof MaxKey - || value['_bsontype'] == 'MinKey' || value['_bsontype'] == 'MaxKey') { - // Write the type of either min or max key - if(value === null) { - buffer[index++] = BSON.BSON_DATA_NULL; - } else if(value instanceof MinKey) { - buffer[index++] = BSON.BSON_DATA_MIN_KEY; - } else { - buffer[index++] = BSON.BSON_DATA_MAX_KEY; - } - - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - return index; - } else if(value instanceof ObjectID || value['_bsontype'] == 'ObjectID') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OID; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write objectid - supportsBuffer ? buffer.write(value.id, index, 'binary') : writeToTypedArray(buffer, value.id, index); - // Ajust index - index = index + 12; - return index; - } else if(value instanceof Date || isDate(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_DATE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the date - var dateInMilis = Long.fromNumber(value.getTime()); - var lowBits = dateInMilis.getLowBits(); - var highBits = dateInMilis.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Get size of the buffer (current write point) - var size = value.length; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the default subtype - buffer[index++] = BSON.BSON_BINARY_SUBTYPE_DEFAULT; - // Copy the content form the binary field to the buffer - value.copy(buffer, index, 0, size); - // Adjust the index - index = index + size; - return index; - } else if(value instanceof Long || value instanceof Timestamp || value['_bsontype'] == 'Long' || value['_bsontype'] == 'Timestamp') { - // Write the type - buffer[index++] = value instanceof Long ? BSON.BSON_DATA_LONG : BSON.BSON_DATA_TIMESTAMP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write the date - var lowBits = value.getLowBits(); - var highBits = value.getHighBits(); - // Encode low bits - buffer[index++] = lowBits & 0xff; - buffer[index++] = (lowBits >> 8) & 0xff; - buffer[index++] = (lowBits >> 16) & 0xff; - buffer[index++] = (lowBits >> 24) & 0xff; - // Encode high bits - buffer[index++] = highBits & 0xff; - buffer[index++] = (highBits >> 8) & 0xff; - buffer[index++] = (highBits >> 16) & 0xff; - buffer[index++] = (highBits >> 24) & 0xff; - return index; - } else if(value instanceof Double || value['_bsontype'] == 'Double') { - // Encode as double - buffer[index++] = BSON.BSON_DATA_NUMBER; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Write float - writeIEEE754(buffer, value, index, 'little', 52, 8); - // Ajust index - index = index + 8; - return index; - } else if(value instanceof Code || value['_bsontype'] == 'Code') { - if(value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.code.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize + 4; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - supportsBuffer ? buffer.write(functionString, index, 'utf8') : writeToTypedArray(buffer, functionString, index); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = supportsBuffer ? new Buffer(scopeSize) : new Uint8Array(new ArrayBuffer(scopeSize)); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - supportsBuffer ? scopeObjectBuffer.copy(buffer, index, 0, scopeSize) : buffer.set(scopeObjectBuffer, index); - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.code.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } else if(value instanceof Binary || value['_bsontype'] == 'Binary') { - // Write the type - buffer[index++] = BSON.BSON_DATA_BINARY; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Extract the buffer - var data = value.value(true); - // Calculate size - var size = value.position; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the subtype to the buffer - buffer[index++] = value.sub_type; - - // If we have binary type 2 the 4 first bytes are the size - if(value.sub_type == Binary.SUBTYPE_BYTE_ARRAY) { - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - } - - // Write the data to the object - supportsBuffer ? data.copy(buffer, index, 0, value.position) : buffer.set(data, index); - // Ajust index - index = index + value.position; - return index; - } else if(value instanceof Symbol || value['_bsontype'] == 'Symbol') { - // Write the type - buffer[index++] = BSON.BSON_DATA_SYMBOL; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate size - var size = supportsBuffer ? Buffer.byteLength(value.value) + 1 : numberOfBytes(value.value) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(value.value, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0x00; - return index; - } else if(value instanceof DBRef || value['_bsontype'] == 'DBRef') { - // Write the type - buffer[index++] = BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Set up correct object for serialization - var ordered_values = { - '$ref': value.namespace - , '$id' : value.oid - }; - - // Add db reference if it exists - if(null != value.db) { - ordered_values['$db'] = value.db; - } - - // Message size - var size = BSON.calculateObjectSize(ordered_values, serializeFunctions); - // Serialize the object - var endIndex = BSON.serializeWithBufferAndIndex(ordered_values, checkKeys, buffer, index, serializeFunctions); - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write zero for object - buffer[endIndex++] = 0x00; - // Return the end index - return endIndex; - } else if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - supportsBuffer ? buffer.write(value.source, index, 'utf8') : writeToTypedArray(buffer, value.source, index); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - // Write the type - buffer[index++] = Array.isArray(value) ? BSON.BSON_DATA_ARRAY : BSON.BSON_DATA_OBJECT; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Adjust the index - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - var endIndex = serializeObject(value, checkKeys, buffer, index + 4, serializeFunctions); - // Write size - var size = endIndex - index; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - return endIndex; - } - case 'function': - // WTF for 0.4.X where typeof /someregexp/ === 'function' - if(value instanceof RegExp || Object.prototype.toString.call(value) === '[object RegExp]' || String.call(value) == '[object RegExp]') { - // Write the type - buffer[index++] = BSON.BSON_DATA_REGEXP; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - - // Write the regular expression string - buffer.write(value.source, index, 'utf8'); - // Adjust the index - index = index + (supportsBuffer ? Buffer.byteLength(value.source) : numberOfBytes(value.source)); - // Write zero - buffer[index++] = 0x00; - // Write the parameters - if(value.global) buffer[index++] = 0x73; // s - if(value.ignoreCase) buffer[index++] = 0x69; // i - if(value.multiline) buffer[index++] = 0x6d; // m - // Add ending zero - buffer[index++] = 0x00; - return index; - } else { - if(serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { - // Write the type - buffer[index++] = BSON.BSON_DATA_CODE_W_SCOPE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Calculate the scope size - var scopeSize = BSON.calculateObjectSize(value.scope, serializeFunctions); - // Function string - var functionString = value.toString(); - // Function Size - var codeSize = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - - // Calculate full size of the object - var totalSize = 4 + codeSize + scopeSize; - - // Write the total size of the object - buffer[index++] = totalSize & 0xff; - buffer[index++] = (totalSize >> 8) & 0xff; - buffer[index++] = (totalSize >> 16) & 0xff; - buffer[index++] = (totalSize >> 24) & 0xff; - - // Write the size of the string to buffer - buffer[index++] = codeSize & 0xff; - buffer[index++] = (codeSize >> 8) & 0xff; - buffer[index++] = (codeSize >> 16) & 0xff; - buffer[index++] = (codeSize >> 24) & 0xff; - - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + codeSize - 1; - // Write zero - buffer[index++] = 0; - // Serialize the scope object - var scopeObjectBuffer = new Buffer(scopeSize); - // Execute the serialization into a seperate buffer - serializeObject(value.scope, checkKeys, scopeObjectBuffer, 0, serializeFunctions); - - // Adjusted scope Size (removing the header) - var scopeDocSize = scopeSize - 4; - // Write scope object size - buffer[index++] = scopeDocSize & 0xff; - buffer[index++] = (scopeDocSize >> 8) & 0xff; - buffer[index++] = (scopeDocSize >> 16) & 0xff; - buffer[index++] = (scopeDocSize >> 24) & 0xff; - - // Write the scopeObject into the buffer - scopeObjectBuffer.copy(buffer, index, 0, scopeSize); - - // Adjust index, removing the empty size of the doc (5 bytes 0000000005) - index = index + scopeDocSize - 5; - // Write trailing zero - buffer[index++] = 0; - return index - } else if(serializeFunctions) { - buffer[index++] = BSON.BSON_DATA_CODE; - // Number of written bytes - var numberOfWrittenBytes = supportsBuffer ? buffer.write(name, index, 'utf8') : writeToTypedArray(buffer, name, index); - // Encode the name - index = index + numberOfWrittenBytes + 1; - buffer[index - 1] = 0; - // Function string - var functionString = value.toString(); - // Function Size - var size = supportsBuffer ? Buffer.byteLength(functionString) + 1 : numberOfBytes(functionString) + 1; - // Write the size of the string to buffer - buffer[index++] = size & 0xff; - buffer[index++] = (size >> 8) & 0xff; - buffer[index++] = (size >> 16) & 0xff; - buffer[index++] = (size >> 24) & 0xff; - // Write the string - buffer.write(functionString, index, 'utf8'); - // Update index - index = index + size - 1; - // Write zero - buffer[index++] = 0; - return index; - } - } - } - - // If no value to serialize - return index; -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - var buffer = null; - // Calculate the size of the object - var size = BSON.calculateObjectSize(object, serializeFunctions); - // Fetch the best available type for storing the binary data - if(buffer = typeof Buffer != 'undefined') { - buffer = new Buffer(size); - asBuffer = true; - } else if(typeof Uint8Array != 'undefined') { - buffer = new Uint8Array(new ArrayBuffer(size)); - } else { - buffer = new Array(size); - } - - // If asBuffer is false use typed arrays - BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, 0, serializeFunctions); - return buffer; -} - -/** - * Contains the function cache if we have that enable to allow for avoiding the eval step on each deserialization, comparison is by md5 - * - * @ignore - * @api private - */ -var functionCache = BSON.functionCache = {}; - -/** - * Crc state variables shared by function - * - * @ignore - * @api private - */ -var table = [0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]; - -/** - * CRC32 hash method, Fast and enough versitility for our usage - * - * @ignore - * @api private - */ -var crc32 = function(string, start, end) { - var crc = 0 - var x = 0; - var y = 0; - crc = crc ^ (-1); - - for(var i = start, iTop = end; i < iTop;i++) { - y = (crc ^ string[i]) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - // if(numberOfDocuments !== documents.length) throw new Error("Number of expected results back is less than the number of documents"); - options = options != null ? options : {}; - var index = startIndex; - // Loop over all documents - for(var i = 0; i < numberOfDocuments; i++) { - // Find size of the document - var size = data[index] | data[index + 1] << 8 | data[index + 2] << 16 | data[index + 3] << 24; - // Update options with index - options['index'] = index; - // Parse the document at this point - documents[docStartIndex + i] = BSON.deserialize(data, options); - // Adjust index by the document size - index = index + size; - } - - // Return object containing end index of parsing and list of documents - return index; -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEvalWithHash = function(functionCache, hash, functionString, object) { - // Contains the value we are going to set - var value = null; - - // Check for cache hit, eval if missing and return cached function - if(functionCache[hash] == null) { - eval("value = " + functionString); - functionCache[hash] = value; - } - // Set the object - return functionCache[hash].bind(object); -} - -/** - * Ensure eval is isolated. - * - * @ignore - * @api private - */ -var isolateEval = function(functionString) { - // Contains the value we are going to set - var value = null; - // Eval the function - eval("value = " + functionString); - return value; -} - -/** - * Convert Uint8Array to String - * - * @ignore - * @api private - */ -var convertUint8ArrayToUtf8String = function(byteArray, startIndex, endIndex) { - return BinaryParser.decode_utf8(convertArraytoUtf8BinaryString(byteArray, startIndex, endIndex)); -} - -var convertArraytoUtf8BinaryString = function(byteArray, startIndex, endIndex) { - var result = ""; - for(var i = startIndex; i < endIndex; i++) { - result = result + String.fromCharCode(byteArray[i]); - } - - return result; -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.deserialize = function(buffer, options, isArray) { - // Options - options = options == null ? {} : options; - var evalFunctions = options['evalFunctions'] == null ? false : options['evalFunctions']; - var cacheFunctions = options['cacheFunctions'] == null ? false : options['cacheFunctions']; - var cacheFunctionsCrc32 = options['cacheFunctionsCrc32'] == null ? false : options['cacheFunctionsCrc32']; - - // Validate that we have at least 4 bytes of buffer - if(buffer.length < 5) throw new Error("corrupt bson message < 5 bytes long"); - - // Set up index - var index = typeof options['index'] == 'number' ? options['index'] : 0; - // Reads in a C style string - var readCStyleString = function() { - // Get the start search index - var i = index; - // Locate the end of the c string - while(buffer[i] !== 0x00) { i++ } - // Grab utf8 encoded string - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, i) : convertUint8ArrayToUtf8String(buffer, index, i); - // Update index position - index = i + 1; - // Return string - return string; - } - - // Create holding object - var object = isArray ? [] : {}; - - // Read the document size - var size = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - - // Ensure buffer is valid size - if(size < 5 || size > buffer.length) throw new Error("corrupt bson message"); - - // While we have more left data left keep parsing - while(true) { - // Read the type - var elementType = buffer[index++]; - // If we get a zero it's the last byte, exit - if(elementType == 0) break; - // Read the name of the field - var name = readCStyleString(); - // Switch on the type - switch(elementType) { - case BSON.BSON_DATA_OID: - var string = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('binary', index, index + 12) : convertArraytoUtf8BinaryString(buffer, index, index + 12); - // Decode the oid - object[name] = new ObjectID(string); - // Update index - index = index + 12; - break; - case BSON.BSON_DATA_STRING: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_INT: - // Decode the 32bit value - object[name] = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - break; - case BSON.BSON_DATA_NUMBER: - // Decode the double value - object[name] = readIEEE754(buffer, index, 'little', 52, 8); - // Update the index - index = index + 8; - break; - case BSON.BSON_DATA_DATE: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set date object - object[name] = new Date(new Long(lowBits, highBits).toNumber()); - break; - case BSON.BSON_DATA_BOOLEAN: - // Parse the boolean value - object[name] = buffer[index++] == 1; - break; - case BSON.BSON_DATA_NULL: - // Parse the boolean value - object[name] = null; - break; - case BSON.BSON_DATA_BINARY: - // Decode the size of the binary blob - var binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Decode the subtype - var subType = buffer[index++]; - // Decode as raw Buffer object if options specifies it - if(buffer['slice'] != null) { - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Slice the data - object[name] = new Binary(buffer.slice(index, index + binarySize), subType); - } else { - var _buffer = typeof Uint8Array != 'undefined' ? new Uint8Array(new ArrayBuffer(binarySize)) : new Array(binarySize); - // If we have subtype 2 skip the 4 bytes for the size - if(subType == Binary.SUBTYPE_BYTE_ARRAY) { - binarySize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - } - // Copy the data - for(var i = 0; i < binarySize; i++) { - _buffer[i] = buffer[index + i]; - } - // Create the binary object - object[name] = new Binary(_buffer, subType); - } - // Update the index - index = index + binarySize; - break; - case BSON.BSON_DATA_ARRAY: - options['index'] = index; - // Decode the size of the array document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, true); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_OBJECT: - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Set the array to the object - object[name] = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - break; - case BSON.BSON_DATA_REGEXP: - // Create the regexp - var source = readCStyleString(); - var regExpOptions = readCStyleString(); - // For each option add the corresponding one for javascript - var optionsArray = new Array(regExpOptions.length); - - // Parse options - for(var i = 0; i < regExpOptions.length; i++) { - switch(regExpOptions[i]) { - case 'm': - optionsArray[i] = 'm'; - break; - case 's': - optionsArray[i] = 'g'; - break; - case 'i': - optionsArray[i] = 'i'; - break; - } - } - - object[name] = new RegExp(source, optionsArray.join('')); - break; - case BSON.BSON_DATA_LONG: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Create long object - var long = new Long(lowBits, highBits); - // Set the object - object[name] = long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG) ? long.toNumber() : long; - break; - case BSON.BSON_DATA_SYMBOL: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Add string to object - object[name] = new Symbol(buffer.toString('utf8', index, index + stringSize - 1)); - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_TIMESTAMP: - // Unpack the low and high bits - var lowBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var highBits = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Set the object - object[name] = new Timestamp(lowBits, highBits); - break; - case BSON.BSON_DATA_MIN_KEY: - // Parse the object - object[name] = new MinKey(); - break; - case BSON.BSON_DATA_MAX_KEY: - // Parse the object - object[name] = new MaxKey(); - break; - case BSON.BSON_DATA_CODE: - // Read the content of the field - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Function string - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - } else { - object[name] = new Code(functionString, {}); - } - - // Update parse index position - index = index + stringSize; - break; - case BSON.BSON_DATA_CODE_W_SCOPE: - // Read the content of the field - var totalSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - var stringSize = buffer[index++] | buffer[index++] << 8 | buffer[index++] << 16 | buffer[index++] << 24; - // Javascript function - var functionString = supportsBuffer && Buffer.isBuffer(buffer) ? buffer.toString('utf8', index, index + stringSize - 1) : convertUint8ArrayToUtf8String(buffer, index, index + stringSize - 1); - // Update parse index position - index = index + stringSize; - // Parse the element - options['index'] = index; - // Decode the size of the object document - var objectSize = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24; - // Decode the scope object - var scopeObject = BSON.deserialize(buffer, options, false); - // Adjust the index - index = index + objectSize; - - // If we are evaluating the functions - if(evalFunctions) { - // Contains the value we are going to set - var value = null; - // If we have cache enabled let's look for the md5 of the function in the cache - if(cacheFunctions) { - var hash = cacheFunctionsCrc32 ? crc32(functionString) : functionString; - // Got to do this to avoid V8 deoptimizing the call due to finding eval - object[name] = isolateEvalWithHash(functionCache, hash, functionString, object); - } else { - // Set directly - object[name] = isolateEval(functionString); - } - - // Set the scope on the object - object[name].scope = scopeObject; - } else { - object[name] = new Code(functionString, scopeObject); - } - - // Add string to object - break; - } - } - - // Check if we have a db ref object - if(object['$id'] != null) object = new DBRef(object['$ref'], object['$id'], object['$db']); - - // Return the final objects - return object; -} - -/** - * Check if key name is valid. - * - * @ignore - * @api private - */ -BSON.checkKey = function checkKey (key) { - if (!key.length) return; - // Check if we have a legal key for the object - if('$' == key[0]) { - throw Error("key " + key + " must not start with '$'"); - } else if (!!~key.indexOf('.')) { - throw Error("key " + key + " must not contain '.'"); - } -}; - -/** - * Deserialize data as BSON. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} buffer the buffer containing the serialized set of BSON documents. - * @param {Object} [options] additional options used for the deserialization. - * @param {Boolean} [isArray] ignore used for recursive parsing. - * @return {Object} returns the deserialized Javascript Object. - * @api public - */ -BSON.prototype.deserialize = function(data, options) { - return BSON.deserialize(data, options); -} - -/** - * Deserialize stream data as BSON documents. - * - * Options - * - **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized. - * - **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse. - * - **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function. - * - * @param {Buffer} data the buffer containing the serialized set of BSON documents. - * @param {Number} startIndex the start index in the data Buffer where the deserialization is to start. - * @param {Number} numberOfDocuments number of documents to deserialize. - * @param {Array} documents an array where to store the deserialized documents. - * @param {Number} docStartIndex the index in the documents array from where to start inserting documents. - * @param {Object} [options] additional options used for the deserialization. - * @return {Number} returns the next index in the buffer after deserialization **x** numbers of documents. - * @api public - */ -BSON.prototype.deserializeStream = function(data, startIndex, numberOfDocuments, documents, docStartIndex, options) { - return BSON.deserializeStream(data, startIndex, numberOfDocuments, documents, docStartIndex, options); -} - -/** - * Serialize a Javascript object. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Buffer} returns the Buffer object containing the serialized object. - * @api public - */ -BSON.prototype.serialize = function(object, checkKeys, asBuffer, serializeFunctions) { - return BSON.serialize(object, checkKeys, asBuffer, serializeFunctions); -} - -/** - * Calculate the bson size for a passed in Javascript object. - * - * @param {Object} object the Javascript object to calculate the BSON byte size for. - * @param {Boolean} [serializeFunctions] serialize all functions in the object **(default:false)**. - * @return {Number} returns the number of bytes the BSON object will take up. - * @api public - */ -BSON.prototype.calculateObjectSize = function(object, serializeFunctions) { - return BSON.calculateObjectSize(object, serializeFunctions); -} - -/** - * Serialize a Javascript object using a predefined Buffer and index into the buffer, useful when pre-allocating the space for serialization. - * - * @param {Object} object the Javascript object to serialize. - * @param {Boolean} checkKeys the serializer will check if keys are valid. - * @param {Buffer} buffer the Buffer you pre-allocated to store the serialized BSON object. - * @param {Number} index the index in the buffer where we wish to start serializing into. - * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**. - * @return {Number} returns the new write index in the Buffer. - * @api public - */ -BSON.prototype.serializeWithBufferAndIndex = function(object, checkKeys, buffer, startIndex, serializeFunctions) { - return BSON.serializeWithBufferAndIndex(object, checkKeys, buffer, startIndex, serializeFunctions); -} - -/** - * @ignore - * @api private - */ -exports.Code = Code; -exports.Symbol = Symbol; -exports.BSON = BSON; -exports.DBRef = DBRef; -exports.Binary = Binary; -exports.ObjectID = ObjectID; -exports.Long = Long; -exports.Timestamp = Timestamp; -exports.Double = Double; -exports.MinKey = MinKey; -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js deleted file mode 100644 index 69b56a3ff51..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/code.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A class representation of the BSON Code type. - * - * @class Represents the BSON Code type. - * @param {String|Function} code a string or function. - * @param {Object} [scope] an optional scope for the function. - * @return {Code} - */ -function Code(code, scope) { - if(!(this instanceof Code)) return new Code(code, scope); - - this._bsontype = 'Code'; - this.code = code; - this.scope = scope == null ? {} : scope; -}; - -/** - * @ignore - * @api private - */ -Code.prototype.toJSON = function() { - return {scope:this.scope, code:this.code}; -} - -exports.Code = Code; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js deleted file mode 100644 index 56b651029bd..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/db_ref.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * A class representation of the BSON DBRef type. - * - * @class Represents the BSON DBRef type. - * @param {String} namespace the collection name. - * @param {ObjectID} oid the reference ObjectID. - * @param {String} [db] optional db name, if omitted the reference is local to the current db. - * @return {DBRef} - */ -function DBRef(namespace, oid, db) { - if(!(this instanceof DBRef)) return new DBRef(namespace, oid, db); - - this._bsontype = 'DBRef'; - this.namespace = namespace; - this.oid = oid; - this.db = db; -}; - -/** - * @ignore - * @api private - */ -DBRef.prototype.toJSON = function() { - return { - '$ref':this.namespace, - '$id':this.oid, - '$db':this.db == null ? '' : this.db - }; -} - -exports.DBRef = DBRef; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js deleted file mode 100644 index ae5146378f0..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/double.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * A class representation of the BSON Double type. - * - * @class Represents the BSON Double type. - * @param {Number} value the number we want to represent as a double. - * @return {Double} - */ -function Double(value) { - if(!(this instanceof Double)) return new Double(value); - - this._bsontype = 'Double'; - this.value = value; -} - -/** - * Access the number value. - * - * @return {Number} returns the wrapped double number. - * @api public - */ -Double.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Double.prototype.toJSON = function() { - return this.value; -} - -exports.Double = Double; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js deleted file mode 100644 index 6fca3924f6c..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/float_parser.js +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2008, Fair Oaks Labs, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// -// Modifications to writeIEEE754 to support negative zeroes made by Brian White - -var readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { - var e, m, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = bBE ? 0 : (nBytes - 1), - d = bBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -var writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { - var e, m, c, - bBE = (endian === 'big'), - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = bBE ? (nBytes-1) : 0, - d = bBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e+eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -exports.readIEEE754 = readIEEE754; -exports.writeIEEE754 = writeIEEE754; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js deleted file mode 100644 index 950fcad343d..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/index.js +++ /dev/null @@ -1,74 +0,0 @@ -try { - exports.BSONPure = require('./bson'); - exports.BSONNative = require('../../ext'); -} catch(err) { - // do nothing -} - -[ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - exports[i] = module[i]; - } -}); - -// Exports all the classes for the NATIVE JS BSON Parser -exports.native = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '../../ext' -].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} - -// Exports all the classes for the PURE JS BSON Parser -exports.pure = function() { - var classes = {}; - // Map all the classes - [ './binary_parser' - , './binary' - , './code' - , './db_ref' - , './double' - , './max_key' - , './min_key' - , './objectid' - , './symbol' - , './timestamp' - , './long' - , '././bson'].forEach(function (path) { - var module = require('./' + path); - for (var i in module) { - classes[i] = module[i]; - } - }); - // Return classes list - return classes; -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js deleted file mode 100644 index f8f37a6b865..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/long.js +++ /dev/null @@ -1,854 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Long class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Long". This - * implementation is derived from LongLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Longs. - * - * The internal representation of a Long is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Long type. - * @param {Number} low the low (signed) 32 bits of the Long. - * @param {Number} high the high (signed) 32 bits of the Long. - */ -function Long(low, high) { - if(!(this instanceof Long)) return new Long(low, high); - - this._bsontype = 'Long'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Long.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Long.prototype.toNumber = function() { - return this.high_ * Long.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Long.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Long.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = Long.fromNumber(radix); - var div = this.div(radixLong); - var rem = div.multiply(radixLong).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Long.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Long.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Long.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Long.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Long. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Long. - * @api public - */ -Long.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Long.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Long.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Long.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Long.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Long equals the other - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long equals the other - * @api public - */ -Long.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Long does not equal the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long does not equal the other. - * @api public - */ -Long.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Long is less than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than the other. - * @api public - */ -Long.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Long is less than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is less than or equal to the other. - * @api public - */ -Long.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Long is greater than the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than the other. - * @api public - */ -Long.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Long is greater than or equal to the other. - * - * @param {Long} other Long to compare against. - * @return {Boolean} whether this Long is greater than or equal to the other. - * @api public - */ -Long.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Long with the given one. - * - * @param {Long} other Long to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Long.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Long} the negation of this value. - * @api public - */ -Long.prototype.negate = function() { - if (this.equals(Long.MIN_VALUE)) { - return Long.MIN_VALUE; - } else { - return this.not().add(Long.ONE); - } -}; - -/** - * Returns the sum of this and the given Long. - * - * @param {Long} other Long to add to this one. - * @return {Long} the sum of this and the given Long. - * @api public - */ -Long.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Long. - * - * @param {Long} other Long to subtract from this. - * @return {Long} the difference of this and the given Long. - * @api public - */ -Long.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Long. - * - * @param {Long} other Long to multiply with this. - * @return {Long} the product of this and the other. - * @api public - */ -Long.prototype.multiply = function(other) { - if (this.isZero()) { - return Long.ZERO; - } else if (other.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - return other.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } else if (other.equals(Long.MIN_VALUE)) { - return this.isOdd() ? Long.MIN_VALUE : Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Longs are small, use float multiplication - if (this.lessThan(Long.TWO_PWR_24_) && - other.lessThan(Long.TWO_PWR_24_)) { - return Long.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Long divided by the given one. - * - * @param {Long} other Long by which to divide. - * @return {Long} this Long divided by the given one. - * @api public - */ -Long.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Long.ZERO; - } - - if (this.equals(Long.MIN_VALUE)) { - if (other.equals(Long.ONE) || - other.equals(Long.NEG_ONE)) { - return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Long.ZERO)) { - return other.isNegative() ? Long.ONE : Long.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Long.MIN_VALUE)) { - return Long.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Long.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Long.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Long.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Long.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Long modulo the given one. - * - * @param {Long} other Long by which to mod. - * @return {Long} this Long modulo the given one. - * @api public - */ -Long.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Long} the bitwise-NOT of this value. - * @api public - */ -Long.prototype.not = function() { - return Long.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Long and the given one. - * - * @param {Long} other the Long with which to AND. - * @return {Long} the bitwise-AND of this and the other. - * @api public - */ -Long.prototype.and = function(other) { - return Long.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Long and the given one. - * - * @param {Long} other the Long with which to OR. - * @return {Long} the bitwise-OR of this and the other. - * @api public - */ -Long.prototype.or = function(other) { - return Long.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Long and the given one. - * - * @param {Long} other the Long with which to XOR. - * @return {Long} the bitwise-XOR of this and the other. - * @api public - */ -Long.prototype.xor = function(other) { - return Long.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Long with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the left by the given amount. - * @api public - */ -Long.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Long.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Long.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount. - * @api public - */ -Long.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Long.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Long with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Long} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Long.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Long.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Long.fromBits(high, 0); - } else { - return Long.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Long representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Long.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Long(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Long.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Long.ZERO; - } else if (value <= -Long.TWO_PWR_63_DBL_) { - return Long.MIN_VALUE; - } else if (value + 1 >= Long.TWO_PWR_63_DBL_) { - return Long.MAX_VALUE; - } else if (value < 0) { - return Long.fromNumber(-value).negate(); - } else { - return new Long( - (value % Long.TWO_PWR_32_DBL_) | 0, - (value / Long.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Long representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromBits = function(lowBits, highBits) { - return new Long(lowBits, highBits); -}; - -/** - * Returns a Long representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Long. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Long} the corresponding Long value. - * @api public - */ -Long.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Long.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Long.fromNumber(Math.pow(radix, 8)); - - var result = Long.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Long.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Long.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Long.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Long representations of small integer values. - * @type {Object} - * @api private - */ -Long.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Long.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_32_DBL_ = Long.TWO_PWR_16_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_31_DBL_ = Long.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_48_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_64_DBL_ = Long.TWO_PWR_32_DBL_ * Long.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Long.TWO_PWR_63_DBL_ = Long.TWO_PWR_64_DBL_ / 2; - -/** @type {Long} */ -Long.ZERO = Long.fromInt(0); - -/** @type {Long} */ -Long.ONE = Long.fromInt(1); - -/** @type {Long} */ -Long.NEG_ONE = Long.fromInt(-1); - -/** @type {Long} */ -Long.MAX_VALUE = - Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Long} */ -Long.MIN_VALUE = Long.fromBits(0, 0x80000000 | 0); - -/** - * @type {Long} - * @api private - */ -Long.TWO_PWR_24_ = Long.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Long = Long; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js deleted file mode 100644 index 0825408d0c9..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/max_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MaxKey type. - * - * @class Represents the BSON MaxKey type. - * @return {MaxKey} - */ -function MaxKey() { - if(!(this instanceof MaxKey)) return new MaxKey(); - - this._bsontype = 'MaxKey'; -} - -exports.MaxKey = MaxKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js deleted file mode 100644 index 230c2e64a1d..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/min_key.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * A class representation of the BSON MinKey type. - * - * @class Represents the BSON MinKey type. - * @return {MinKey} - */ -function MinKey() { - if(!(this instanceof MinKey)) return new MinKey(); - - this._bsontype = 'MinKey'; -} - -exports.MinKey = MinKey; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js deleted file mode 100644 index 1ff9a8326a8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Module dependencies. - */ -var BinaryParser = require('./binary_parser').BinaryParser; - -/** - * Machine id. - * - * Create a random 3-byte value (i.e. unique for this - * process). Other drivers use a md5 of the machine id here, but - * that would mean an asyc call to gethostname, so we don't bother. - */ -var MACHINE_ID = parseInt(Math.random() * 0xFFFFFF, 10); - -// Regular expression that checks for hex value -var checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$"); - -/** -* Create a new ObjectID instance -* -* @class Represents the BSON ObjectID type -* @param {String|Number} id Can be a 24 byte hex string, 12 byte binary string or a Number. -* @return {Object} instance of ObjectID. -*/ -var ObjectID = function ObjectID(id, _hex) { - if(!(this instanceof ObjectID)) return new ObjectID(id, _hex); - - this._bsontype = 'ObjectID'; - var __id = null; - - // Throw an error if it's not a valid setup - if(id != null && 'number' != typeof id && (id.length != 12 && id.length != 24)) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - // Generate id based on the input - if(id == null || typeof id == 'number') { - // convert to 12 byte binary string - this.id = this.generate(id); - } else if(id != null && id.length === 12) { - // assume 12 byte string - this.id = id; - } else if(checkForHexRegExp.test(id)) { - return ObjectID.createFromHexString(id); - } else if(!checkForHexRegExp.test(id)) { - throw new Error("Value passed in is not a valid 24 character hex string"); - } - - if(ObjectID.cacheHexString) this.__id = this.toHexString(); -}; - -// Allow usage of ObjectId aswell as ObjectID -var ObjectId = ObjectID; - -/** -* Return the ObjectID id as a 24 byte hex string representation -* -* @return {String} return the 24 byte hex string representation. -* @api public -*/ -ObjectID.prototype.toHexString = function() { - if(ObjectID.cacheHexString && this.__id) return this.__id; - - var hexString = '' - , number - , value; - - for (var index = 0, len = this.id.length; index < len; index++) { - value = BinaryParser.toByte(this.id[index]); - number = value <= 15 - ? '0' + value.toString(16) - : value.toString(16); - hexString = hexString + number; - } - - if(ObjectID.cacheHexString) this.__id = hexString; - return hexString; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.get_inc = function() { - return ObjectID.index = (ObjectID.index + 1) % 0xFFFFFF; -}; - -/** -* Update the ObjectID index used in generating new ObjectID's on the driver -* -* @return {Number} returns next index value. -* @api private -*/ -ObjectID.prototype.getInc = function() { - return this.get_inc(); -}; - -/** -* Generate a 12 byte id string used in ObjectID's -* -* @param {Number} [time] optional parameter allowing to pass in a second based timestamp. -* @return {String} return the 12 byte id binary string. -* @api private -*/ -ObjectID.prototype.generate = function(time) { - if ('number' == typeof time) { - var time4Bytes = BinaryParser.encodeInt(time, 32, true, true); - /* for time-based ObjectID the bytes following the time will be zeroed */ - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } else { - var unixTime = parseInt(Date.now()/1000,10); - var time4Bytes = BinaryParser.encodeInt(unixTime, 32, true, true); - var machine3Bytes = BinaryParser.encodeInt(MACHINE_ID, 24, false); - var pid2Bytes = BinaryParser.fromShort(typeof process === 'undefined' ? Math.floor(Math.random() * 100000) : process.pid); - var index3Bytes = BinaryParser.encodeInt(this.get_inc(), 24, false, true); - } - - return time4Bytes + machine3Bytes + pid2Bytes + index3Bytes; -}; - -/** -* Converts the id into a 24 byte hex string for printing -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toString = function() { - return this.toHexString(); -}; - -/** -* Converts to a string representation of this Id. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.inspect = ObjectID.prototype.toString; - -/** -* Converts to its JSON representation. -* -* @return {String} return the 24 byte hex string representation. -* @api private -*/ -ObjectID.prototype.toJSON = function() { - return this.toHexString(); -}; - -/** -* Compares the equality of this ObjectID with `otherID`. -* -* @param {Object} otherID ObjectID instance to compare against. -* @return {Bool} the result of comparing two ObjectID's -* @api public -*/ -ObjectID.prototype.equals = function equals (otherID) { - var id = (otherID instanceof ObjectID || otherID.toHexString) - ? otherID.id - : ObjectID.createFromHexString(otherID).id; - - return this.id === id; -} - -/** -* Returns the generation time in seconds that this ID was generated. -* -* @return {Number} return number of seconds in the timestamp part of the 12 byte id. -* @api public -*/ -ObjectID.prototype.getTimestamp = function() { - var timestamp = new Date(); - timestamp.setTime(Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)) * 1000); - return timestamp; -} - -/** -* @ignore -* @api private -*/ -ObjectID.index = 0; - -ObjectID.createPk = function createPk () { - return new ObjectID(); -}; - -/** -* Creates an ObjectID from a second based number, with the rest of the ObjectID zeroed out. Used for comparisons or sorting the ObjectID. -* -* @param {Number} time an integer number representing a number of seconds. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromTime = function createFromTime (time) { - var id = BinaryParser.encodeInt(time, 32, true, true) + - BinaryParser.encodeInt(0, 64, true, true); - return new ObjectID(id); -}; - -/** -* Creates an ObjectID from a hex string representation of an ObjectID. -* -* @param {String} hexString create a ObjectID from a passed in 24 byte hexstring. -* @return {ObjectID} return the created ObjectID -* @api public -*/ -ObjectID.createFromHexString = function createFromHexString (hexString) { - // Throw an error if it's not a valid setup - if(typeof hexString === 'undefined' || hexString != null && hexString.length != 24) - throw new Error("Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"); - - var len = hexString.length; - - if(len > 12*2) { - throw new Error('Id cannot be longer than 12 bytes'); - } - - var result = '' - , string - , number; - - for (var index = 0; index < len; index += 2) { - string = hexString.substr(index, 2); - number = parseInt(string, 16); - result += BinaryParser.fromByte(number); - } - - return new ObjectID(result, hexString); -}; - -/** -* @ignore -*/ -Object.defineProperty(ObjectID.prototype, "generationTime", { - enumerable: true - , get: function () { - return Math.floor(BinaryParser.decodeInt(this.id.substring(0,4), 32, true, true)); - } - , set: function (value) { - var value = BinaryParser.encodeInt(value, 32, true, true); - this.id = value + this.id.substr(4); - // delete this.__id; - this.toHexString(); - } -}); - -/** - * Expose. - */ -exports.ObjectID = ObjectID; -exports.ObjectId = ObjectID; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js deleted file mode 100644 index 8e2838d1783..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * A class representation of the BSON Symbol type. - * - * @class Represents the BSON Symbol type. - * @param {String} value the string representing the symbol. - * @return {Symbol} - */ -function Symbol(value) { - if(!(this instanceof Symbol)) return new Symbol(value); - this._bsontype = 'Symbol'; - this.value = value; -} - -/** - * Access the wrapped string value. - * - * @return {String} returns the wrapped string. - * @api public - */ -Symbol.prototype.valueOf = function() { - return this.value; -}; - -/** - * @ignore - * @api private - */ -Symbol.prototype.toString = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.inspect = function() { - return this.value; -} - -/** - * @ignore - * @api private - */ -Symbol.prototype.toJSON = function() { - return this.value; -} - -exports.Symbol = Symbol; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js deleted file mode 100644 index c650d1536c8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/lib/bson/timestamp.js +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Copyright 2009 Google Inc. All Rights Reserved - -/** - * Defines a Timestamp class for representing a 64-bit two's-complement - * integer value, which faithfully simulates the behavior of a Java "Timestamp". This - * implementation is derived from TimestampLib in GWT. - * - * Constructs a 64-bit two's-complement integer, given its low and high 32-bit - * values as *signed* integers. See the from* functions below for more - * convenient ways of constructing Timestamps. - * - * The internal representation of a Timestamp is the two given signed, 32-bit values. - * We use 32-bit pieces because these are the size of integers on which - * Javascript performs bit-operations. For operations like addition and - * multiplication, we split each number into 16-bit pieces, which can easily be - * multiplied within Javascript's floating-point representation without overflow - * or change in sign. - * - * In the algorithms below, we frequently reduce the negative case to the - * positive case by negating the input(s) and then post-processing the result. - * Note that we must ALWAYS check specially whether those values are MIN_VALUE - * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - * a positive number, it overflows back into a negative). Not handling this - * case would often result in infinite recursion. - * - * @class Represents the BSON Timestamp type. - * @param {Number} low the low (signed) 32 bits of the Timestamp. - * @param {Number} high the high (signed) 32 bits of the Timestamp. - */ -function Timestamp(low, high) { - if(!(this instanceof Timestamp)) return new Timestamp(low, high); - this._bsontype = 'Timestamp'; - /** - * @type {number} - * @api private - */ - this.low_ = low | 0; // force into 32 signed bits. - - /** - * @type {number} - * @api private - */ - this.high_ = high | 0; // force into 32 signed bits. -}; - -/** - * Return the int value. - * - * @return {Number} the value, assuming it is a 32-bit integer. - * @api public - */ -Timestamp.prototype.toInt = function() { - return this.low_; -}; - -/** - * Return the Number value. - * - * @return {Number} the closest floating-point representation to this value. - * @api public - */ -Timestamp.prototype.toNumber = function() { - return this.high_ * Timestamp.TWO_PWR_32_DBL_ + - this.getLowBitsUnsigned(); -}; - -/** - * Return the JSON value. - * - * @return {String} the JSON representation. - * @api public - */ -Timestamp.prototype.toJSON = function() { - return this.toString(); -} - -/** - * Return the String value. - * - * @param {Number} [opt_radix] the radix in which the text should be written. - * @return {String} the textual representation of this value. - * @api public - */ -Timestamp.prototype.toString = function(opt_radix) { - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (this.isZero()) { - return '0'; - } - - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - // We need to change the Timestamp value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixTimestamp = Timestamp.fromNumber(radix); - var div = this.div(radixTimestamp); - var rem = div.multiply(radixTimestamp).subtract(this); - return div.toString(radix) + rem.toInt().toString(radix); - } else { - return '-' + this.negate().toString(radix); - } - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 6)); - - var rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower); - var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt(); - var digits = intval.toString(radix); - - rem = remDiv; - if (rem.isZero()) { - return digits + result; - } else { - while (digits.length < 6) { - digits = '0' + digits; - } - result = '' + digits + result; - } - } -}; - -/** - * Return the high 32-bits value. - * - * @return {Number} the high 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getHighBits = function() { - return this.high_; -}; - -/** - * Return the low 32-bits value. - * - * @return {Number} the low 32-bits as a signed value. - * @api public - */ -Timestamp.prototype.getLowBits = function() { - return this.low_; -}; - -/** - * Return the low unsigned 32-bits value. - * - * @return {Number} the low 32-bits as an unsigned value. - * @api public - */ -Timestamp.prototype.getLowBitsUnsigned = function() { - return (this.low_ >= 0) ? - this.low_ : Timestamp.TWO_PWR_32_DBL_ + this.low_; -}; - -/** - * Returns the number of bits needed to represent the absolute value of this Timestamp. - * - * @return {Number} Returns the number of bits needed to represent the absolute value of this Timestamp. - * @api public - */ -Timestamp.prototype.getNumBitsAbs = function() { - if (this.isNegative()) { - if (this.equals(Timestamp.MIN_VALUE)) { - return 64; - } else { - return this.negate().getNumBitsAbs(); - } - } else { - var val = this.high_ != 0 ? this.high_ : this.low_; - for (var bit = 31; bit > 0; bit--) { - if ((val & (1 << bit)) != 0) { - break; - } - } - return this.high_ != 0 ? bit + 33 : bit + 1; - } -}; - -/** - * Return whether this value is zero. - * - * @return {Boolean} whether this value is zero. - * @api public - */ -Timestamp.prototype.isZero = function() { - return this.high_ == 0 && this.low_ == 0; -}; - -/** - * Return whether this value is negative. - * - * @return {Boolean} whether this value is negative. - * @api public - */ -Timestamp.prototype.isNegative = function() { - return this.high_ < 0; -}; - -/** - * Return whether this value is odd. - * - * @return {Boolean} whether this value is odd. - * @api public - */ -Timestamp.prototype.isOdd = function() { - return (this.low_ & 1) == 1; -}; - -/** - * Return whether this Timestamp equals the other - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp equals the other - * @api public - */ -Timestamp.prototype.equals = function(other) { - return (this.high_ == other.high_) && (this.low_ == other.low_); -}; - -/** - * Return whether this Timestamp does not equal the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp does not equal the other. - * @api public - */ -Timestamp.prototype.notEquals = function(other) { - return (this.high_ != other.high_) || (this.low_ != other.low_); -}; - -/** - * Return whether this Timestamp is less than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than the other. - * @api public - */ -Timestamp.prototype.lessThan = function(other) { - return this.compare(other) < 0; -}; - -/** - * Return whether this Timestamp is less than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is less than or equal to the other. - * @api public - */ -Timestamp.prototype.lessThanOrEqual = function(other) { - return this.compare(other) <= 0; -}; - -/** - * Return whether this Timestamp is greater than the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than the other. - * @api public - */ -Timestamp.prototype.greaterThan = function(other) { - return this.compare(other) > 0; -}; - -/** - * Return whether this Timestamp is greater than or equal to the other. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} whether this Timestamp is greater than or equal to the other. - * @api public - */ -Timestamp.prototype.greaterThanOrEqual = function(other) { - return this.compare(other) >= 0; -}; - -/** - * Compares this Timestamp with the given one. - * - * @param {Timestamp} other Timestamp to compare against. - * @return {Boolean} 0 if they are the same, 1 if the this is greater, and -1 if the given one is greater. - * @api public - */ -Timestamp.prototype.compare = function(other) { - if (this.equals(other)) { - return 0; - } - - var thisNeg = this.isNegative(); - var otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) { - return -1; - } - if (!thisNeg && otherNeg) { - return 1; - } - - // at this point, the signs are the same, so subtraction will not overflow - if (this.subtract(other).isNegative()) { - return -1; - } else { - return 1; - } -}; - -/** - * The negation of this value. - * - * @return {Timestamp} the negation of this value. - * @api public - */ -Timestamp.prototype.negate = function() { - if (this.equals(Timestamp.MIN_VALUE)) { - return Timestamp.MIN_VALUE; - } else { - return this.not().add(Timestamp.ONE); - } -}; - -/** - * Returns the sum of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to add to this one. - * @return {Timestamp} the sum of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.add = function(other) { - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns the difference of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to subtract from this. - * @return {Timestamp} the difference of this and the given Timestamp. - * @api public - */ -Timestamp.prototype.subtract = function(other) { - return this.add(other.negate()); -}; - -/** - * Returns the product of this and the given Timestamp. - * - * @param {Timestamp} other Timestamp to multiply with this. - * @return {Timestamp} the product of this and the other. - * @api public - */ -Timestamp.prototype.multiply = function(other) { - if (this.isZero()) { - return Timestamp.ZERO; - } else if (other.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - return other.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } else if (other.equals(Timestamp.MIN_VALUE)) { - return this.isOdd() ? Timestamp.MIN_VALUE : Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().multiply(other.negate()); - } else { - return this.negate().multiply(other).negate(); - } - } else if (other.isNegative()) { - return this.multiply(other.negate()).negate(); - } - - // If both Timestamps are small, use float multiplication - if (this.lessThan(Timestamp.TWO_PWR_24_) && - other.lessThan(Timestamp.TWO_PWR_24_)) { - return Timestamp.fromNumber(this.toNumber() * other.toNumber()); - } - - // Divide each Timestamp into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high_ >>> 16; - var a32 = this.high_ & 0xFFFF; - var a16 = this.low_ >>> 16; - var a00 = this.low_ & 0xFFFF; - - var b48 = other.high_ >>> 16; - var b32 = other.high_ & 0xFFFF; - var b16 = other.low_ >>> 16; - var b00 = other.low_ & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return Timestamp.fromBits((c16 << 16) | c00, (c48 << 16) | c32); -}; - -/** - * Returns this Timestamp divided by the given one. - * - * @param {Timestamp} other Timestamp by which to divide. - * @return {Timestamp} this Timestamp divided by the given one. - * @api public - */ -Timestamp.prototype.div = function(other) { - if (other.isZero()) { - throw Error('division by zero'); - } else if (this.isZero()) { - return Timestamp.ZERO; - } - - if (this.equals(Timestamp.MIN_VALUE)) { - if (other.equals(Timestamp.ONE) || - other.equals(Timestamp.NEG_ONE)) { - return Timestamp.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ONE; - } else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shiftRight(1); - var approx = halfThis.div(other).shiftLeft(1); - if (approx.equals(Timestamp.ZERO)) { - return other.isNegative() ? Timestamp.ONE : Timestamp.NEG_ONE; - } else { - var rem = this.subtract(other.multiply(approx)); - var result = approx.add(rem.div(other)); - return result; - } - } - } else if (other.equals(Timestamp.MIN_VALUE)) { - return Timestamp.ZERO; - } - - if (this.isNegative()) { - if (other.isNegative()) { - return this.negate().div(other.negate()); - } else { - return this.negate().div(other).negate(); - } - } else if (other.isNegative()) { - return this.div(other.negate()).negate(); - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - var res = Timestamp.ZERO; - var rem = this; - while (rem.greaterThanOrEqual(other)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2); - var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48); - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - var approxRes = Timestamp.fromNumber(approx); - var approxRem = approxRes.multiply(other); - while (approxRem.isNegative() || approxRem.greaterThan(rem)) { - approx -= delta; - approxRes = Timestamp.fromNumber(approx); - approxRem = approxRes.multiply(other); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) { - approxRes = Timestamp.ONE; - } - - res = res.add(approxRes); - rem = rem.subtract(approxRem); - } - return res; -}; - -/** - * Returns this Timestamp modulo the given one. - * - * @param {Timestamp} other Timestamp by which to mod. - * @return {Timestamp} this Timestamp modulo the given one. - * @api public - */ -Timestamp.prototype.modulo = function(other) { - return this.subtract(this.div(other).multiply(other)); -}; - -/** - * The bitwise-NOT of this value. - * - * @return {Timestamp} the bitwise-NOT of this value. - * @api public - */ -Timestamp.prototype.not = function() { - return Timestamp.fromBits(~this.low_, ~this.high_); -}; - -/** - * Returns the bitwise-AND of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to AND. - * @return {Timestamp} the bitwise-AND of this and the other. - * @api public - */ -Timestamp.prototype.and = function(other) { - return Timestamp.fromBits(this.low_ & other.low_, this.high_ & other.high_); -}; - -/** - * Returns the bitwise-OR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to OR. - * @return {Timestamp} the bitwise-OR of this and the other. - * @api public - */ -Timestamp.prototype.or = function(other) { - return Timestamp.fromBits(this.low_ | other.low_, this.high_ | other.high_); -}; - -/** - * Returns the bitwise-XOR of this Timestamp and the given one. - * - * @param {Timestamp} other the Timestamp with which to XOR. - * @return {Timestamp} the bitwise-XOR of this and the other. - * @api public - */ -Timestamp.prototype.xor = function(other) { - return Timestamp.fromBits(this.low_ ^ other.low_, this.high_ ^ other.high_); -}; - -/** - * Returns this Timestamp with bits shifted to the left by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the left by the given amount. - * @api public - */ -Timestamp.prototype.shiftLeft = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var low = this.low_; - if (numBits < 32) { - var high = this.high_; - return Timestamp.fromBits( - low << numBits, - (high << numBits) | (low >>> (32 - numBits))); - } else { - return Timestamp.fromBits(0, low << (numBits - 32)); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount. - * @api public - */ -Timestamp.prototype.shiftRight = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >> numBits); - } else { - return Timestamp.fromBits( - high >> (numBits - 32), - high >= 0 ? 0 : -1); - } - } -}; - -/** - * Returns this Timestamp with bits shifted to the right by the given amount, with the new top bits matching the current sign bit. - * - * @param {Number} numBits the number of bits by which to shift. - * @return {Timestamp} this shifted to the right by the given amount, with zeros placed into the new leading bits. - * @api public - */ -Timestamp.prototype.shiftRightUnsigned = function(numBits) { - numBits &= 63; - if (numBits == 0) { - return this; - } else { - var high = this.high_; - if (numBits < 32) { - var low = this.low_; - return Timestamp.fromBits( - (low >>> numBits) | (high << (32 - numBits)), - high >>> numBits); - } else if (numBits == 32) { - return Timestamp.fromBits(high, 0); - } else { - return Timestamp.fromBits(high >>> (numBits - 32), 0); - } - } -}; - -/** - * Returns a Timestamp representing the given (32-bit) integer value. - * - * @param {Number} value the 32-bit integer in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromInt = function(value) { - if (-128 <= value && value < 128) { - var cachedObj = Timestamp.INT_CACHE_[value]; - if (cachedObj) { - return cachedObj; - } - } - - var obj = new Timestamp(value | 0, value < 0 ? -1 : 0); - if (-128 <= value && value < 128) { - Timestamp.INT_CACHE_[value] = obj; - } - return obj; -}; - -/** - * Returns a Timestamp representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * - * @param {Number} value the number in question. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromNumber = function(value) { - if (isNaN(value) || !isFinite(value)) { - return Timestamp.ZERO; - } else if (value <= -Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MIN_VALUE; - } else if (value + 1 >= Timestamp.TWO_PWR_63_DBL_) { - return Timestamp.MAX_VALUE; - } else if (value < 0) { - return Timestamp.fromNumber(-value).negate(); - } else { - return new Timestamp( - (value % Timestamp.TWO_PWR_32_DBL_) | 0, - (value / Timestamp.TWO_PWR_32_DBL_) | 0); - } -}; - -/** - * Returns a Timestamp representing the 64-bit integer that comes by concatenating the given high and low bits. Each is assumed to use 32 bits. - * - * @param {Number} lowBits the low 32-bits. - * @param {Number} highBits the high 32-bits. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromBits = function(lowBits, highBits) { - return new Timestamp(lowBits, highBits); -}; - -/** - * Returns a Timestamp representation of the given string, written using the given radix. - * - * @param {String} str the textual representation of the Timestamp. - * @param {Number} opt_radix the radix in which the text is written. - * @return {Timestamp} the corresponding Timestamp value. - * @api public - */ -Timestamp.fromString = function(str, opt_radix) { - if (str.length == 0) { - throw Error('number format error: empty string'); - } - - var radix = opt_radix || 10; - if (radix < 2 || 36 < radix) { - throw Error('radix out of range: ' + radix); - } - - if (str.charAt(0) == '-') { - return Timestamp.fromString(str.substring(1), radix).negate(); - } else if (str.indexOf('-') >= 0) { - throw Error('number format error: interior "-" character: ' + str); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = Timestamp.fromNumber(Math.pow(radix, 8)); - - var result = Timestamp.ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i); - var value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = Timestamp.fromNumber(Math.pow(radix, size)); - result = result.multiply(power).add(Timestamp.fromNumber(value)); - } else { - result = result.multiply(radixToPower); - result = result.add(Timestamp.fromNumber(value)); - } - } - return result; -}; - -// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the -// from* methods on which they depend. - - -/** - * A cache of the Timestamp representations of small integer values. - * @type {Object} - * @api private - */ -Timestamp.INT_CACHE_ = {}; - -// NOTE: the compiler should inline these constant values below and then remove -// these variables, so there should be no runtime penalty for these. - -/** - * Number used repeated below in calculations. This must appear before the - * first call to any from* function below. - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_16_DBL_ = 1 << 16; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_24_DBL_ = 1 << 24; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_32_DBL_ = Timestamp.TWO_PWR_16_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_31_DBL_ = Timestamp.TWO_PWR_32_DBL_ / 2; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_48_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_16_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_64_DBL_ = Timestamp.TWO_PWR_32_DBL_ * Timestamp.TWO_PWR_32_DBL_; - -/** - * @type {number} - * @api private - */ -Timestamp.TWO_PWR_63_DBL_ = Timestamp.TWO_PWR_64_DBL_ / 2; - -/** @type {Timestamp} */ -Timestamp.ZERO = Timestamp.fromInt(0); - -/** @type {Timestamp} */ -Timestamp.ONE = Timestamp.fromInt(1); - -/** @type {Timestamp} */ -Timestamp.NEG_ONE = Timestamp.fromInt(-1); - -/** @type {Timestamp} */ -Timestamp.MAX_VALUE = - Timestamp.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0); - -/** @type {Timestamp} */ -Timestamp.MIN_VALUE = Timestamp.fromBits(0, 0x80000000 | 0); - -/** - * @type {Timestamp} - * @api private - */ -Timestamp.TWO_PWR_24_ = Timestamp.fromInt(1 << 24); - -/** - * Expose. - */ -exports.Timestamp = Timestamp; \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json deleted file mode 100644 index 1a4fde856aa..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "bson", - "description": "A bson parser for node.js and the browser", - "keywords": [ - "mongodb", - "bson", - "parser" - ], - "version": "0.1.8", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [], - "repository": { - "type": "git", - "url": "git://github.com/mongodb/js-bson.git" - }, - "bugs": { - "url": "https://github.com/mongodb/js-bson/issues" - }, - "devDependencies": { - "nodeunit": "0.7.3", - "gleak": "0.2.3", - "one": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/bson/index", - "directories": { - "lib": "./lib/bson" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "nodeunit ./test/node && TEST_NATIVE=TRUE nodeunit ./test/node" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "A JS/C++ Bson parser for node, used in the MongoDB Native driver", - "readmeFilename": "README.md", - "_id": "bson@0.1.8", - "_from": "bson@0.1.8" -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm deleted file mode 100644 index 4ee148bde39..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/browser_example.htm +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js deleted file mode 100644 index 84d8ffc78a9..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/bson_test.js +++ /dev/null @@ -1,260 +0,0 @@ -this.bson_test = { - 'Full document serialization and deserialization': function (test) { - var motherOfAllDocuments = { - 'string': "客家è¯", - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary('hello world'), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSON.serialize(motherOfAllDocuments, true, true, false); - // Deserialize the object - var object = BSON.deserialize(data); - - // Asserts - test.equal(Utf8.decode(motherOfAllDocuments.string), object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - test.ok(assertArrayEqual(motherOfAllDocuments.binary.value(true), object.binary.value(true))); - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); - }, - - 'exercise all the binary object constructor methods': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(assertArrayEqual(array, binary.buffer)); - test.done(); - }, - - 'exercise the put binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // String to array - var array = stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); - }, - - 'exercise the write binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); - }, - - 'exercise the read binary object method for an instance when using Uint8Array': function (test) { - // Construct using array - var string = 'hello world'; - var array = stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(assertArrayEqual(stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(assertArrayEqual(stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(assertArrayEqual(stringToArrayBuffer('world'), data)); - test.done(); - }, - - 'Should correctly handle toBson function for an object': function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = BSON.serialize(doc, false, true); - var deserialized_doc = BSON.deserialize(serialized_data); - test.equal(1, deserialized_doc.b); - test.done(); - } -}; - -var assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -var stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -var stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -var Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js deleted file mode 100644 index af7fd0b5867..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/nodeunit.js +++ /dev/null @@ -1,2034 +0,0 @@ -/*! - * Nodeunit - * https://github.com/caolan/nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * json2.js - * http://www.JSON.org/json2.js - * Public Domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ -nodeunit = (function(){ -/* - http://www.JSON.org/json2.js - 2010-11-17 - - Public Domain. - - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - - See http://www.JSON.org/js.html - - - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html - - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. - - - This file creates a global JSON object containing two methods: stringify - and parse. - - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. - - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. - - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. - - This method produces a JSON text from a JavaScript value. - - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value - - For example, this would serialize Dates as ISO strings. - - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; - - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. - - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. - - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. - - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. - - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. - - Example: - - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date ? - 'Date(' + this[key] + ')' : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint evil: true, strict: false, regexp: false */ - -/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, - call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, - lastIndex, length, parse, prototype, push, replace, slice, stringify, - test, toJSON, toString, valueOf -*/ - - -// Create a JSON object only if one does not already exist. We create the -// methods in a closure to avoid creating global variables. - -var JSON = {}; - -(function () { - "use strict"; - - function f(n) { - // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - if (typeof Date.prototype.toJSON !== 'function') { - - Date.prototype.toJSON = function (key) { - - return isFinite(this.valueOf()) ? - this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z' : null; - }; - - String.prototype.toJSON = - Number.prototype.toJSON = - Boolean.prototype.toJSON = function (key) { - return this.valueOf(); - }; - } - - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - gap, - indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, - rep; - - - function quote(string) { - -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can safely slap some quotes around it. -// Otherwise we must also replace the offending characters with safe escape -// sequences. - - escapable.lastIndex = 0; - return escapable.test(string) ? - '"' + string.replace(escapable, function (a) { - var c = meta[a]; - return typeof c === 'string' ? c : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : - '"' + string + '"'; - } - - - function str(key, holder) { - -// Produce a string from holder[key]. - - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; - -// If the value has a toJSON method, call it to obtain a replacement value. - - if (value && typeof value === 'object' && - typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - -// If we were called with a replacer function, then call the replacer to -// obtain a replacement value. - - if (typeof rep === 'function') { - value = rep.call(holder, key, value); - } - -// What happens next depends on the value's type. - - switch (typeof value) { - case 'string': - return quote(value); - - case 'number': - -// JSON numbers must be finite. Encode non-finite numbers as null. - - return isFinite(value) ? String(value) : 'null'; - - case 'boolean': - case 'null': - -// If the value is a boolean or null, convert it to a string. Note: -// typeof null does not produce 'null'. The case is included here in -// the remote chance that this gets fixed someday. - - return String(value); - -// If the type is 'object', we might be dealing with an object or an array or -// null. - - case 'object': - -// Due to a specification blunder in ECMAScript, typeof null is 'object', -// so watch out for that case. - - if (!value) { - return 'null'; - } - -// Make an array to hold the partial results of stringifying this object value. - - gap += indent; - partial = []; - -// Is the value an array? - - if (Object.prototype.toString.apply(value) === '[object Array]') { - -// The value is an array. Stringify every element. Use null as a placeholder -// for non-JSON values. - - length = value.length; - for (i = 0; i < length; i += 1) { - partial[i] = str(i, value) || 'null'; - } - -// Join all of the elements together, separated with commas, and wrap them in -// brackets. - - v = partial.length === 0 ? '[]' : - gap ? '[\n' + gap + - partial.join(',\n' + gap) + '\n' + - mind + ']' : - '[' + partial.join(',') + ']'; - gap = mind; - return v; - } - -// If the replacer is an array, use it to select the members to be stringified. - - if (rep && typeof rep === 'object') { - length = rep.length; - for (i = 0; i < length; i += 1) { - k = rep[i]; - if (typeof k === 'string') { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } else { - -// Otherwise, iterate through all of the keys in the object. - - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = str(k, value); - if (v) { - partial.push(quote(k) + (gap ? ': ' : ':') + v); - } - } - } - } - -// Join all of the member texts together, separated with commas, -// and wrap them in braces. - - v = partial.length === 0 ? '{}' : - gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + - mind + '}' : '{' + partial.join(',') + '}'; - gap = mind; - return v; - } - } - -// If the JSON object does not yet have a stringify method, give it one. - - if (typeof JSON.stringify !== 'function') { - JSON.stringify = function (value, replacer, space) { - -// The stringify method takes a value and an optional replacer, and an optional -// space parameter, and returns a JSON text. The replacer can be a function -// that can replace values, or an array of strings that will select the keys. -// A default replacer method can be provided. Use of the space parameter can -// produce text that is more easily readable. - - var i; - gap = ''; - indent = ''; - -// If the space parameter is a number, make an indent string containing that -// many spaces. - - if (typeof space === 'number') { - for (i = 0; i < space; i += 1) { - indent += ' '; - } - -// If the space parameter is a string, it will be used as the indent string. - - } else if (typeof space === 'string') { - indent = space; - } - -// If there is a replacer, it must be a function or an array. -// Otherwise, throw an error. - - rep = replacer; - if (replacer && typeof replacer !== 'function' && - (typeof replacer !== 'object' || - typeof replacer.length !== 'number')) { - throw new Error('JSON.stringify'); - } - -// Make a fake root object containing our value under the key of ''. -// Return the result of stringifying the value. - - return str('', {'': value}); - }; - } - - -// If the JSON object does not yet have a parse method, give it one. - - if (typeof JSON.parse !== 'function') { - JSON.parse = function (text, reviver) { - -// The parse method takes a text and an optional reviver function, and returns -// a JavaScript value if the text is a valid JSON text. - - var j; - - function walk(holder, key) { - -// The walk method is used to recursively walk the resulting structure so -// that modifications can be made. - - var k, v, value = holder[key]; - if (value && typeof value === 'object') { - for (k in value) { - if (Object.hasOwnProperty.call(value, k)) { - v = walk(value, k); - if (v !== undefined) { - value[k] = v; - } else { - delete value[k]; - } - } - } - } - return reviver.call(holder, key, value); - } - - -// Parsing happens in four stages. In the first stage, we replace certain -// Unicode characters with escape sequences. JavaScript handles many characters -// incorrectly, either silently deleting them, or treating them as line endings. - - text = String(text); - cx.lastIndex = 0; - if (cx.test(text)) { - text = text.replace(cx, function (a) { - return '\\u' + - ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - -// In the second stage, we run the text against regular expressions that look -// for non-JSON patterns. We are especially concerned with '()' and 'new' -// because they can cause invocation, and '=' because it can cause mutation. -// But just to be safe, we want to reject all unexpected forms. - -// We split the second stage into 4 regexp operations in order to work around -// crippling inefficiencies in IE's and Safari's regexp engines. First we -// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we -// replace all simple value tokens with ']' characters. Third, we delete all -// open brackets that follow a colon or comma or that begin the text. Finally, -// we look to see that the remaining characters are only whitespace or ']' or -// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - if (/^[\],:{}\s]*$/ -.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') -.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') -.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { - -// In the third stage we use the eval function to compile the text into a -// JavaScript structure. The '{' operator is subject to a syntactic ambiguity -// in JavaScript: it can begin a block or an object literal. We wrap the text -// in parens to eliminate the ambiguity. - - j = eval('(' + text + ')'); - -// In the optional fourth stage, we recursively walk the new structure, passing -// each name/value pair to a reviver function for possible transformation. - - return typeof reviver === 'function' ? - walk({'': j}, '') : j; - } - -// If the text is not JSON parseable, then a SyntaxError is thrown. - - throw new SyntaxError('JSON.parse'); - }; - } -}()); -var assert = this.assert = {}; -var types = {}; -var core = {}; -var nodeunit = {}; -var reporter = {}; -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - var _indexOf = function (arr, item) { - if (arr.indexOf) { - return arr.indexOf(item); - } - for (var i = 0; i < arr.length; i += 1) { - if (arr[i] === item) { - return i; - } - } - return -1; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var completed = []; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners, function (fn) { - fn(); - }); - }; - - addListener(function () { - if (completed.length === keys.length) { - callback(null); - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - completed.push(k); - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && _indexOf(completed, x) !== -1); - }, true); - }; - if (ready()) { - task[task.length - 1](taskCallback); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - if (!tasks.length) { - return callback(); - } - callback = callback || function () {}; - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args || null); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var tasks = []; - var q = { - concurrency: concurrency, - push: function (data, callback) { - tasks.push({data: data, callback: callback}); - async.nextTick(q.process); - }, - process: function () { - if (workers < q.concurrency && tasks.length) { - var task = tasks.splice(0, 1)[0]; - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - q.process(); - }); - } - }, - length: function () { - return tasks.length; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - hasher = hasher || function (x) { - return x; - }; - return function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else { - fn.apply(null, args.concat([function () { - memo[key] = arguments; - callback.apply(null, arguments); - }])); - } - }; - }; - -}()); -(function(exports){ -/** - * This file is based on the node.js assert module, but with some small - * changes for browser-compatibility - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - */ - - -/** - * Added for browser compatibility - */ - -var _keys = function(obj){ - if(Object.keys) return Object.keys(obj); - if (typeof obj != 'object' && typeof obj != 'function') { - throw new TypeError('-'); - } - var keys = []; - for(var k in obj){ - if(obj.hasOwnProperty(k)) keys.push(k); - } - return keys; -}; - - - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -var pSlice = Array.prototype.slice; - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = exports; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({message: message, actual: actual, expected: expected}) - -assert.AssertionError = function AssertionError (options) { - this.name = "AssertionError"; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -// code from util.inherits in node -assert.AssertionError.super_ = Error; - - -// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call -// TODO: test what effect this may have -var ctor = function () { this.constructor = assert.AssertionError; }; -ctor.prototype = Error.prototype; -assert.AssertionError.prototype = new ctor(); - - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name+":", this.message].join(' '); - } else { - return [ this.name+":" - , JSON.stringify(this.expected ) - , this.operator - , JSON.stringify(this.actual) - ].join(" "); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -assert.ok = function ok(value, message) { - if (!!!value) fail(value, true, message, "==", assert.ok); -}; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, "==", assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, "!=", assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, "deepEqual", assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == "object", - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical "prototype" property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull (value) { - return value === null || value === undefined; -} - -function isArguments (object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv (a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical "prototype" property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try{ - var ka = _keys(a), - kb = _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; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, "===", assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, "!==", assert.notStrictEqual); - } -}; - -function _throws (shouldThrow, block, err, message) { - var exception = null, - threw = false, - typematters = true; - - message = message || ""; - - //handle optional arguments - if (arguments.length == 3) { - if (typeof(err) == "string") { - message = err; - typematters = false; - } - } else if (arguments.length == 2) { - typematters = false; - } - - try { - block(); - } catch (e) { - threw = true; - exception = e; - } - - if (shouldThrow && !threw) { - fail( "Missing expected exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if (!shouldThrow && threw && typematters && exception instanceof err) { - fail( "Got unwanted exception" - + (err && err.name ? " ("+err.name+")." : '.') - + (message ? " " + message : "") - ); - } - if ((shouldThrow && threw && typematters && !(exception instanceof err)) || - (!shouldThrow && threw)) { - throw exception; - } -}; - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function (err) { if (err) {throw err;}}; -})(assert); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var assert = require('./assert'), //@REMOVE_LINE_FOR_BROWSER -// async = require('../deps/async'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Creates assertion objects representing the result of an assert call. - * Accepts an object or AssertionError as its argument. - * - * @param {object} obj - * @api public - */ - -exports.assertion = function (obj) { - return { - method: obj.method || '', - message: obj.message || (obj.error && obj.error.message) || '', - error: obj.error, - passed: function () { - return !this.error; - }, - failed: function () { - return Boolean(this.error); - } - }; -}; - -/** - * Creates an assertion list object representing a group of assertions. - * Accepts an array of assertion objects. - * - * @param {Array} arr - * @param {Number} duration - * @api public - */ - -exports.assertionList = function (arr, duration) { - var that = arr || []; - that.failures = function () { - var failures = 0; - for (var i = 0; i < this.length; i += 1) { - if (this[i].failed()) { - failures += 1; - } - } - return failures; - }; - that.passes = function () { - return that.length - that.failures(); - }; - that.duration = duration || 0; - return that; -}; - -/** - * Create a wrapper function for assert module methods. Executes a callback - * after the it's complete with an assertion object representing the result. - * - * @param {Function} callback - * @api private - */ - -var assertWrapper = function (callback) { - return function (new_method, assert_method, arity) { - return function () { - var message = arguments[arity - 1]; - var a = exports.assertion({method: new_method, message: message}); - try { - assert[assert_method].apply(null, arguments); - } - catch (e) { - a.error = e; - } - callback(a); - }; - }; -}; - -/** - * Creates the 'test' object that gets passed to every test function. - * Accepts the name of the test function as its first argument, followed by - * the start time in ms, the options object and a callback function. - * - * @param {String} name - * @param {Number} start - * @param {Object} options - * @param {Function} callback - * @api public - */ - -exports.test = function (name, start, options, callback) { - var expecting; - var a_list = []; - - var wrapAssert = assertWrapper(function (a) { - a_list.push(a); - if (options.log) { - async.nextTick(function () { - options.log(a); - }); - } - }); - - var test = { - done: function (err) { - if (expecting !== undefined && expecting !== a_list.length) { - var e = new Error( - 'Expected ' + expecting + ' assertions, ' + - a_list.length + ' ran' - ); - var a1 = exports.assertion({method: 'expect', error: e}); - a_list.push(a1); - if (options.log) { - async.nextTick(function () { - options.log(a1); - }); - } - } - if (err) { - var a2 = exports.assertion({error: err}); - a_list.push(a2); - if (options.log) { - async.nextTick(function () { - options.log(a2); - }); - } - } - var end = new Date().getTime(); - async.nextTick(function () { - var assertion_list = exports.assertionList(a_list, end - start); - options.testDone(name, assertion_list); - callback(null, a_list); - }); - }, - ok: wrapAssert('ok', 'ok', 2), - same: wrapAssert('same', 'deepEqual', 3), - equals: wrapAssert('equals', 'equal', 3), - expect: function (num) { - expecting = num; - }, - _assertion_list: a_list - }; - // add all functions from the assert module - for (var k in assert) { - if (assert.hasOwnProperty(k)) { - test[k] = wrapAssert(k, k, assert[k].length); - } - } - return test; -}; - -/** - * Ensures an options object has all callbacks, adding empty callback functions - * if any are missing. - * - * @param {Object} opt - * @return {Object} - * @api public - */ - -exports.options = function (opt) { - var optionalCallback = function (name) { - opt[name] = opt[name] || function () {}; - }; - - optionalCallback('moduleStart'); - optionalCallback('moduleDone'); - optionalCallback('testStart'); - optionalCallback('testDone'); - //optionalCallback('log'); - - // 'done' callback is not optional. - - return opt; -}; -})(types); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - -/** - * Module dependencies - */ - -//var async = require('../deps/async'), //@REMOVE_LINE_FOR_BROWSER -// types = require('./types'); //@REMOVE_LINE_FOR_BROWSER - - -/** - * Added for browser compatibility - */ - -var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; -}; - - -var _copy = function (obj) { - var nobj = {}; - var keys = _keys(obj); - for (var i = 0; i < keys.length; i += 1) { - nobj[keys[i]] = obj[keys[i]]; - } - return nobj; -}; - - -/** - * Runs a test function (fn) from a loaded module. After the test function - * calls test.done(), the callback is executed with an assertionList as its - * second argument. - * - * @param {String} name - * @param {Function} fn - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runTest = function (name, fn, opt, callback) { - var options = types.options(opt); - - options.testStart(name); - var start = new Date().getTime(); - var test = types.test(name, start, options, callback); - - try { - fn(test); - } - catch (e) { - test.done(e); - } -}; - -/** - * Takes an object containing test functions or other test suites as properties - * and runs each in series. After all tests have completed, the callback is - * called with a list of all assertions as the second argument. - * - * If a name is passed to this function it is prepended to all test and suite - * names that run within it. - * - * @param {String} name - * @param {Object} suite - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runSuite = function (name, suite, opt, callback) { - var keys = _keys(suite); - - async.concatSeries(keys, function (k, cb) { - var prop = suite[k], _name; - - _name = name ? [].concat(name, k) : [k]; - - _name.toString = function () { - // fallback for old one - return this.join(' - '); - }; - - if (typeof prop === 'function') { - var in_name = false; - for (var i = 0; i < _name.length; i += 1) { - if (_name[i] === opt.testspec) { - in_name = true; - } - } - if (!opt.testspec || in_name) { - if (opt.moduleStart) { - opt.moduleStart(); - } - exports.runTest(_name, suite[k], opt, cb); - } - else { - return cb(); - } - } - else { - exports.runSuite(_name, suite[k], opt, cb); - } - }, callback); -}; - -/** - * Run each exported test function or test suite from a loaded module. - * - * @param {String} name - * @param {Object} mod - * @param {Object} opt - * @param {Function} callback - * @api public - */ - -exports.runModule = function (name, mod, opt, callback) { - var options = _copy(types.options(opt)); - - var _run = false; - var _moduleStart = options.moduleStart; - function run_once() { - if (!_run) { - _run = true; - _moduleStart(name); - } - } - options.moduleStart = run_once; - - var start = new Date().getTime(); - - exports.runSuite(null, mod, options, function (err, a_list) { - var end = new Date().getTime(); - var assertion_list = types.assertionList(a_list, end - start); - options.moduleDone(name, assertion_list); - callback(null, a_list); - }); -}; - -/** - * Treats an object literal as a list of modules keyed by name. Runs each - * module and finished with calling 'done'. You can think of this as a browser - * safe alternative to runFiles in the nodeunit module. - * - * @param {Object} modules - * @param {Object} opt - * @api public - */ - -// TODO: add proper unit tests for this function -exports.runModules = function (modules, opt) { - var all_assertions = []; - var options = types.options(opt); - var start = new Date().getTime(); - - async.concatSeries(_keys(modules), function (k, cb) { - exports.runModule(k, modules[k], options, cb); - }, - function (err, all_assertions) { - var end = new Date().getTime(); - options.done(types.assertionList(all_assertions, end - start)); - }); -}; - - -/** - * Wraps a test function with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Function} fn - * @api private - */ - -var wrapTest = function (setUp, tearDown, fn) { - return function (test) { - var context = {}; - if (tearDown) { - var done = test.done; - test.done = function (err) { - try { - tearDown.call(context, function (err2) { - if (err && err2) { - test._assertion_list.push( - types.assertion({error: err}) - ); - return done(err2); - } - done(err || err2); - }); - } - catch (e) { - done(e); - } - }; - } - if (setUp) { - setUp.call(context, function (err) { - if (err) { - return test.done(err); - } - fn.call(context, test); - }); - } - else { - fn.call(context, test); - } - }; -}; - - -/** - * Wraps a group of tests with setUp and tearDown functions. - * Used by testCase. - * - * @param {Function} setUp - * @param {Function} tearDown - * @param {Object} group - * @api private - */ - -var wrapGroup = function (setUp, tearDown, group) { - var tests = {}; - var keys = _keys(group); - for (var i = 0; i < keys.length; i += 1) { - var k = keys[i]; - if (typeof group[k] === 'function') { - tests[k] = wrapTest(setUp, tearDown, group[k]); - } - else if (typeof group[k] === 'object') { - tests[k] = wrapGroup(setUp, tearDown, group[k]); - } - } - return tests; -}; - - -/** - * Utility for wrapping a suite of test functions with setUp and tearDown - * functions. - * - * @param {Object} suite - * @return {Object} - * @api public - */ - -exports.testCase = function (suite) { - var setUp = suite.setUp; - var tearDown = suite.tearDown; - delete suite.setUp; - delete suite.tearDown; - return wrapGroup(setUp, tearDown, suite); -}; -})(core); -(function(exports){ -/*! - * Nodeunit - * Copyright (c) 2010 Caolan McMahon - * MIT Licensed - * - * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS! - * You can use @REMOVE_LINE_FOR_BROWSER to remove code from the browser build. - * Only code on that line will be removed, its mostly to avoid requiring code - * that is node specific - */ - - -/** - * NOTE: this test runner is not listed in index.js because it cannot be - * used with the command-line tool, only inside the browser. - */ - - -/** - * Reporter info string - */ - -exports.info = "Browser-based test reporter"; - - -/** - * Run all tests within each module, reporting the results - * - * @param {Array} files - * @api public - */ - -exports.run = function (modules, options) { - var start = new Date().getTime(); - - function setText(el, txt) { - if ('innerText' in el) { - el.innerText = txt; - } - else if ('textContent' in el){ - el.textContent = txt; - } - } - - function getOrCreate(tag, id) { - var el = document.getElementById(id); - if (!el) { - el = document.createElement(tag); - el.id = id; - document.body.appendChild(el); - } - return el; - }; - - var header = getOrCreate('h1', 'nodeunit-header'); - var banner = getOrCreate('h2', 'nodeunit-banner'); - var userAgent = getOrCreate('h2', 'nodeunit-userAgent'); - var tests = getOrCreate('ol', 'nodeunit-tests'); - var result = getOrCreate('p', 'nodeunit-testresult'); - - setText(userAgent, navigator.userAgent); - - nodeunit.runModules(modules, { - moduleStart: function (name) { - /*var mheading = document.createElement('h2'); - mheading.innerText = name; - results.appendChild(mheading); - module = document.createElement('ol'); - results.appendChild(module);*/ - }, - testDone: function (name, assertions) { - var test = document.createElement('li'); - var strong = document.createElement('strong'); - strong.innerHTML = name + ' (' + - '' + assertions.failures() + ', ' + - '' + assertions.passes() + ', ' + - assertions.length + - ')'; - test.className = assertions.failures() ? 'fail': 'pass'; - test.appendChild(strong); - - var aList = document.createElement('ol'); - aList.style.display = 'none'; - test.onclick = function () { - var d = aList.style.display; - aList.style.display = (d == 'none') ? 'block': 'none'; - }; - for (var i=0; i' + (a.error.stack || a.error) + ''; - li.className = 'fail'; - } - else { - li.innerHTML = a.message || a.method || 'no message'; - li.className = 'pass'; - } - aList.appendChild(li); - } - test.appendChild(aList); - tests.appendChild(test); - }, - done: function (assertions) { - var end = new Date().getTime(); - var duration = end - start; - - var failures = assertions.failures(); - banner.className = failures ? 'fail': 'pass'; - - result.innerHTML = 'Tests completed in ' + duration + - ' milliseconds.
    ' + - assertions.passes() + ' assertions of ' + - '' + assertions.length + ' passed, ' + - assertions.failures() + ' failed.'; - } - }); -}; -})(reporter); -nodeunit = core; -nodeunit.assert = assert; -nodeunit.reporter = reporter; -nodeunit.run = reporter.run; -return nodeunit; })(); diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js deleted file mode 100644 index c7288e8d875..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite2.js +++ /dev/null @@ -1,13 +0,0 @@ -this.suite2 = { - 'another test': function (test) { - setTimeout(function () { - // lots of assertions - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.ok(true, 'everythings ok'); - test.done(); - }, 10); - } -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js deleted file mode 100644 index 89297419bf1..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/suite3.js +++ /dev/null @@ -1,7 +0,0 @@ -this.suite3 = { - 'test for ie6,7,8': function (test) { - test.deepEqual(["test"], ["test"]); - test.notDeepEqual(["a"], ["b"]); - test.done(); - } -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html deleted file mode 100644 index 56d4d9643b6..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/browser/test.html +++ /dev/null @@ -1,30 +0,0 @@ - - - Example tests - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js deleted file mode 100644 index 5304bef45c8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_array_test.js +++ /dev/null @@ -1,240 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -var _Uint8Array = null; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - _Uint8Array = global.Uint8Array; - delete global['Uint8Array']; - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - global['Uint8Array'] = _Uint8Array; - callback(); -} - -// /** -// * @ignore -// */ -// exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { -// var motherOfAllDocuments = { -// 'string': '客家è¯', -// 'array': [1,2,3], -// 'hash': {'a':1, 'b':2}, -// 'date': new Date(), -// 'oid': new ObjectID(), -// 'binary': new Binary(new Buffer("hello")), -// 'int': 42, -// 'float': 33.3333, -// 'regexp': /regexp/, -// 'boolean': true, -// 'long': Long.fromNumber(100), -// 'where': new Code('this.a > i', {i:1}), -// 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), -// 'minkey': new MinKey(), -// 'maxkey': new MaxKey() -// } -// -// // Let's serialize it -// var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); -// // Build a typed array -// var arr = new Uint8Array(new ArrayBuffer(data.length)); -// // Iterate over all the fields and copy -// for(var i = 0; i < data.length; i++) { -// arr[i] = data[i] -// } -// -// // Deserialize the object -// var object = BSONDE.BSON.deserialize(arr); -// // Asserts -// test.equal(motherOfAllDocuments.string, object.string); -// test.deepEqual(motherOfAllDocuments.array, object.array); -// test.deepEqual(motherOfAllDocuments.date, object.date); -// test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); -// // Assert the values of the binary -// for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { -// test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); -// } -// test.deepEqual(motherOfAllDocuments.int, object.int); -// test.deepEqual(motherOfAllDocuments.float, object.float); -// test.deepEqual(motherOfAllDocuments.regexp, object.regexp); -// test.deepEqual(motherOfAllDocuments.boolean, object.boolean); -// test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); -// test.deepEqual(motherOfAllDocuments.where, object.where); -// test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); -// test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); -// test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); -// test.deepEqual(motherOfAllDocuments.minkey, object.minkey); -// test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); -// test.done(); -// } - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js deleted file mode 100644 index 74815402ffb..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_parser_comparision_test.js +++ /dev/null @@ -1,493 +0,0 @@ -var sys = require('util'), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple edge value'] = function(test) { - // Simple serialization and deserialization of edge value - var doc = {doc:0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-0x1ffffffffffffe}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly execute toJSON'] = function(test) { - var a = Long.fromNumber(10); - assert.equal(10, a); - - var a = Long.fromNumber(9223372036854775807); - assert.equal(9223372036854775807, a); - - // Simple serialization and deserialization test for a Single String value - var doc = {doc:'Serialize'}; - var simple_string_serialized = bsonC.serialize(doc, true, false); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize nested document'] = function(test) { - // Nested doc - var doc = {a:{b:{c:1}}}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple integer serialization/deserialization test, including testing boundary conditions'] = function(test) { - var doc = {doc:-1}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2147483648}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization test for a Long value'] = function(test) { - var doc = {doc:Long.fromNumber(9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:Long.fromNumber(-9223372036854775807)}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:Long.fromNumber(-9223372036854775807)}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Float value'] = function(test) { - var doc = {doc:2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - - var doc = {doc:-2222.3333}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a null value'] = function(test) { - var doc = {doc:null}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:true}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a date value'] = function(test) { - var date = new Date(); - var doc = {doc:date}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')), bsonC.deserialize(simple_string_serialized)); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a boolean value'] = function(test) { - var doc = {doc:/abcd/mi}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - - var doc = {doc:/abcd/}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc, false, true)); - assert.equal(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a objectId value'] = function(test) { - var doc = {doc:new ObjectID()}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var doc2 = {doc:ObjectID.createFromHexString(doc.doc.toHexString())}; - - assert.deepEqual(simple_string_serialized, bsonJS.serialize(doc2, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.toString(), bsonC.deserialize(simple_string_serialized).doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value'] = function(test) { - var binary = new Binary(); - var string = 'binstring' - for(var index = 0; index < string.length; index++) { binary.put(string.charAt(index)); } - - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Binary value of type 2'] = function(test) { - var binary = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var simple_string_serialized = bsonC.serialize({doc:binary}, false, true); - assert.deepEqual(simple_string_serialized, bsonJS.serialize({doc:binary}, false, true)); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized, 'binary')).doc.value(), bsonC.deserialize(simple_string_serialized).doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a Code value'] = function(test) { - var code = new Code('this.a > i', {'i': 1}); - var simple_string_serialized_2 = bsonJS.serialize({doc:code}, false, true); - var simple_string_serialized = bsonC.serialize({doc:code}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2); - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc.scope, bsonC.deserialize(simple_string_serialized).doc.scope); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for an Object'] = function(test) { - var simple_string_serialized = bsonC.serialize({doc:{a:1, b:{c:2}}}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:{a:1, b:{c:2}}}, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - - // Simple serialization and deserialization for an Array - var simple_string_serialized = bsonC.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - var simple_string_serialized_2 = bsonJS.serialize({doc:[9, 9, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1]}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - assert.deepEqual(bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')).doc, bsonC.deserialize(simple_string_serialized).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Simple serialization and deserialization for a DBRef'] = function(test) { - var oid = new ObjectID() - var oid2 = new ObjectID.createFromHexString(oid.toHexString()) - var simple_string_serialized = bsonJS.serialize({doc:new DBRef('namespace', oid2, 'integration_tests_')}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:new DBRef('namespace', oid, 'integration_tests_')}, false, true); - - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - // Ensure we have the same values for the dbref - var object_js = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object_c = bsonC.deserialize(simple_string_serialized); - - assert.equal(object_js.doc.namespace, object_c.doc.namespace); - assert.equal(object_js.doc.oid.toHexString(), object_c.doc.oid.toHexString()); - assert.equal(object_js.doc.db, object_c.doc.db); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize bytes array'] = function(test) { - // Serialized document - var bytes = [47,0,0,0,2,110,97,109,101,0,6,0,0,0,80,97,116,116,121,0,16,97,103,101,0,34,0,0,0,7,95,105,100,0,76,100,12,23,11,30,39,8,89,0,0,1,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - var object = bsonC.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal('Patty', object.name) - assert.equal(34, object.age) - assert.equal('4c640c170b1e270859000001', object._id.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize utf8'] = function(test) { - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.equal(doc.name, object.name) - assert.equal(doc.name1, object.name1) - assert.equal(doc.name2, object.name2) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize object with array'] = function(test) { - var doc = {b:[1, 2, 3]}; - var simple_string_serialized = bsonC.serialize(doc, false, true); - var simple_string_serialized_2 = bsonJS.serialize(doc, false, true); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - - var object = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc, object) - test.done(); -} - -/** - * @ignore - */ -exports['Test equality of an object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id_2 = new ObjectID(); - assert.ok(object_id.equals(object_id)); - assert.ok(!(object_id.equals(object_id_2))) - test.done(); -} - -/** - * @ignore - */ -exports['Test same serialization for Object ID'] = function(test) { - var object_id = new ObjectID(); - var object_id2 = ObjectID.createFromHexString(object_id.toString()) - var simple_string_serialized = bsonJS.serialize({doc:object_id}, false, true); - var simple_string_serialized_2 = bsonC.serialize({doc:object_id2}, false, true); - - assert.equal(simple_string_serialized_2.length, simple_string_serialized.length); - assert.deepEqual(simple_string_serialized, simple_string_serialized_2) - var object = bsonJS.deserialize(new Buffer(simple_string_serialized_2, 'binary')); - var object2 = bsonC.deserialize(simple_string_serialized); - assert.equal(object.doc.id, object2.doc.id) - test.done(); -} - -/** - * @ignore - */ -exports['Complex object serialization'] = function(test) { - // JS Object - var c1 = { _id: new ObjectID, comments: [], title: 'number 1' }; - var c2 = { _id: new ObjectID, comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: new ObjectID - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - - // C++ Object - var c1 = { _id: ObjectID.createFromHexString(c1._id.toHexString()), comments: [], title: 'number 1' }; - var c2 = { _id: ObjectID.createFromHexString(c2._id.toHexString()), comments: [], title: 'number 2' }; - var doc = { - numbers: [] - , owners: [] - , comments: [c1, c2] - , _id: ObjectID.createFromHexString(doc._id.toHexString()) - }; - - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - - for(var i = 0; i < simple_string_serialized_2.length; i++) { - // debug(i + "[" + simple_string_serialized_2[i] + "] = [" + simple_string_serialized[i] + "]") - assert.equal(simple_string_serialized_2[i], simple_string_serialized[i]); - } - - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc._id.id, doc1._id.id) - assert.equal(doc._id.id, doc2._id.id) - assert.equal(doc1._id.id, doc2._id.id) - - var doc = { - _id: 'testid', - key1: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 }, - key2: { code: 'test1', time: {start:1309323402727,end:1309323402727}, x:10, y:5 } - }; - - var simple_string_serialized = bsonJS.serialize(doc, false, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize function'] = function(test) { - var doc = { - _id: 'testid', - key1: function() {} - } - - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Deserialize the string - var doc1 = bsonJS.deserialize(new Buffer(simple_string_serialized_2)); - var doc2 = bsonC.deserialize(new Buffer(simple_string_serialized_2)); - assert.equal(doc1.key1.code.toString(), doc2.key1.code.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Serialize document with special operators'] = function(test) { - var doc = {"user_id":"4e9fc8d55883d90100000003","lc_status":{"$ne":"deleted"},"owner_rating":{"$exists":false}}; - var simple_string_serialized = bsonJS.serialize(doc, false, true, true); - var simple_string_serialized_2 = bsonC.serialize(doc, false, true, true); - - // Should serialize to the same value - assert.equal(simple_string_serialized_2.toString('base64'), simple_string_serialized.toString('base64')) - var doc1 = bsonJS.deserialize(simple_string_serialized_2); - var doc2 = bsonC.deserialize(simple_string_serialized); - assert.deepEqual(doc1, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Create ObjectID from hex string'] = function(test) { - // Hex Id - var hexId = new ObjectID().toString(); - var docJS = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docC = {_id: ObjectID.createFromHexString(hexId), 'funds.remaining': {$gte: 1.222}, 'transactions.id': {$ne: ObjectID.createFromHexString(hexId)}}; - var docJSBin = bsonJS.serialize(docJS, false, true, true); - var docCBin = bsonC.serialize(docC, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Serialize big complex document'] = function(test) { - // Complex document serialization - var doc = {"DateTime": "Tue Nov 40 2011 17:27:55 GMT+0000 (WEST)","isActive": true,"Media": {"URL": "http://videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb"},"Title": "Lisboa fecha a ganhar 0.19%","SetPosition": 60,"Type": "videos","Thumbnail": [{"URL": "http://rd3.videos.sapo.pt/Tc85NsjaKjj8o5aV7Ubb/pic/320x240","Dimensions": {"Height": 240,"Width": 320}}],"Source": {"URL": "http://videos.sapo.pt","SetID": "1288","SourceID": "http://videos.sapo.pt/tvnet/rss2","SetURL": "http://noticias.sapo.pt/videos/tv-net_1288/","ItemID": "Tc85NsjaKjj8o5aV7Ubb","Name": "SAPO Vídeos"},"Category": "Tec_ciencia","Description": "Lisboa fecha a ganhar 0.19%","GalleryID": new ObjectID("4eea2a634ce8573200000000"),"InternalRefs": {"RegisterDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","ChangeDate": "Thu Dec 15 2011 17:12:51 GMT+0000 (WEST)","Hash": 332279244514},"_id": new ObjectID("4eea2a96e52778160000003a")} - var docJSBin = bsonJS.serialize(doc, false, true, true); - var docCBin = bsonC.serialize(doc, false, true, true); - assert.equal(docCBin.toString('base64'), docJSBin.toString('base64')); - test.done(); -} - -/** - * @ignore - */ -exports['Should error out due to 24 characters but not valid hexstring for ObjectID'] = function(test) { - try { - var oid = new ObjectID("tttttttttttttttttttttttt"); - test.ok(false); - } catch(err) {} - - test.done(); -} - - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js deleted file mode 100644 index 9eb5756e193..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_test.js +++ /dev/null @@ -1,1694 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - ObjectId = mongoO.ObjectId, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - vm = require('vm'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly create ObjectID and do deep equals'] = function(test) { - var test_string = {hello: new ObjectID()}; - test_string.hello.toHexString(); - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly get BSON types from require'] = function(test) { - var _mongodb = require('../../lib/bson'); - test.ok(_mongodb.ObjectID === ObjectID); - test.ok(_mongodb.Binary === Binary); - test.ok(_mongodb.Long === Long); - test.ok(_mongodb.Timestamp === Timestamp); - test.ok(_mongodb.Code === Code); - test.ok(_mongodb.DBRef === DBRef); - test.ok(_mongodb.Symbol === Symbol); - test.ok(_mongodb.MinKey === MinKey); - test.ok(_mongodb.MaxKey === MaxKey); - test.ok(_mongodb.Double === Double); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary')); - test.equal("a_1", object.name); - test.equal(false, object.unique); - test.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(new Buffer(serialized_data, 'binary'));//, false, true); - // Perform tests - test.equal("hello", object.string); - test.deepEqual([1,2,3], object.array); - test.equal(1, object.hash.a); - test.equal(2, object.hash.b); - test.ok(object.date != null); - test.ok(object.oid != null); - test.ok(object.binary != null); - test.equal(42, object.int); - test.equal(33.3333, object.float); - test.ok(object.regexp != null); - test.equal(true, object.boolean); - test.ok(object.where != null); - test.ok(object.dbref != null); - test.ok(object[null] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize Empty String'] = function(test) { - var test_string = {hello: ''}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_string, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_string)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_string, false, serialized_data2, 0); - - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_string, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data2)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_null, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_null)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_null, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var object = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(null, object.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_number, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_number)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_number, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(test_number, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -5600}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: 2147483647}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - - test_int = {doc: -2147483648}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - test.deepEqual(test_int.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.age, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.age); - test.deepEqual(doc.doc.name, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.name); - test.deepEqual(doc.doc.shoe_size, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.shoe_size); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - Array.prototype.toXml = function() {}; - var doc = {doc: [1, 2, 'a', 'b']}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc.doc[0], deserialized.doc[0]) - test.equal(doc.doc[1], deserialized.doc[1]) - test.equal(doc.doc[2], deserialized.doc[2]) - test.equal(doc.doc[3], deserialized.doc[3]) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly deserialize a nested object'] = function(test) { - var doc = {doc: {doc:1}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc.doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date(); - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date from another VM'] = function(test) { - var script = "date1 = new Date();", - ctx = vm.createContext({ - date1 : null - }); - vm.runInContext(script, ctx, 'myfile.vm'); - - var date = ctx.date1; - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12); - date.setUTCFullYear(2009); - date.setUTCMonth(11 - 1); - date.setUTCHours(12); - date.setUTCMinutes(0); - date.setUTCSeconds(30); - var doc = {doc: date}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.equal(doc.date, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc.date); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize nested doc'] = function(test) { - var doc = { - string: "Strings are great", - decimal: 3.14159265, - bool: true, - integer: 5, - - subObject: { - moreText: "Bacon ipsum dolor.", - longKeylongKeylongKeylongKeylongKeylongKey: "Pork belly." - }, - - subArray: [1,2,3,4,5,6,7,8,9,10], - anotherString: "another string" - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()}; - var doc2 = {doc: ObjectID.createFromHexString(doc.doc.toHexString())}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - test.deepEqual(doc, new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var decoded_hash = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data).doc; - var keys = []; - - for(var name in decoded_hash) keys.push(name); - test.deepEqual(['b', 'a', 'c', 'd'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - // Serialize the regular expression - var doc = {doc: /foobar/mi}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.toString(), doc2.doc.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary(); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Type 2 Binary object'] = function(test) { - var bin = new Binary(new Buffer('binstring'), Binary.SUBTYPE_BYTE_ARRAY); - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary(); - bin.write(data); - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports["Should Correctly Serialize and Deserialize DBRef"] = function(test) { - var oid = new ObjectID(); - var doc = {dbref: new DBRef('namespace', oid, null)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal("namespace", doc2.dbref.namespace); - test.deepEqual(doc2.dbref.oid.toHexString(), oid.toHexString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize partial DBRef'] = function(test) { - var id = new ObjectID(); - var doc = {'name':'something', 'user':{'$ref':'username', '$id': id}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal('something', doc2.name); - test.equal('username', doc2.user.namespace); - test.equal(id.toString(), doc2.user.oid.toString()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize simple Int'] = function(test) { - var doc = {doc:2147483648}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, doc2.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer'] = function(test) { - var doc = {doc: Long.fromNumber(9223372036854775807)}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - - doc = {doc: Long.fromNumber(-9223372036854775809)}; - serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Deserialize Large Integers as Number not Long'] = function(test) { - function roundTrip(val) { - var doc = {doc: val}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc, deserialized_data.doc); - }; - - roundTrip(Math.pow(2,52)); - roundTrip(Math.pow(2,53) - 1); - roundTrip(Math.pow(2,53)); - roundTrip(-Math.pow(2,52)); - roundTrip(-Math.pow(2,53) + 1); - roundTrip(-Math.pow(2,53)); - roundTrip(Math.pow(2,65)); // Too big for Long. - roundTrip(-Math.pow(2,65)); - roundTrip(9223372036854775807); - roundTrip(1234567890123456800); // Bigger than 2^53, stays a double. - roundTrip(-1234567890123456800); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Long Integer and Timestamp as different types'] = function(test) { - var long = Long.fromNumber(9223372036854775807); - var timestamp = Timestamp.fromNumber(9223372036854775807); - test.ok(long instanceof Long); - test.ok(!(long instanceof Timestamp)); - test.ok(timestamp instanceof Timestamp); - test.ok(!(timestamp instanceof Long)); - - var test_int = {doc: long, doc2: timestamp}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(test_int, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(test_int)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(test_int, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(test_int.doc, deserialized_data.doc); - test.done(); -} - -/** - * @ignore - */ -exports['Should Always put the id as the first item in a hash'] = function(test) { - var hash = {doc: {not_id:1, '_id':2}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(hash, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(hash)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(hash, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - var keys = []; - - for(var name in deserialized_data.doc) { - keys.push(name); - } - - test.deepEqual(['not_id', '_id'], keys); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a User defined Binary object'] = function(test) { - var bin = new Binary(); - bin.sub_type = BSON.BSON_BINARY_SUBTYPE_USER_DEFINED; - var string = 'binstring'; - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)); - } - - var doc = {doc: bin}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(deserialized_data.doc.sub_type, BSON.BSON_BINARY_SUBTYPE_USER_DEFINED); - test.deepEqual(doc.doc.value(), deserialized_data.doc.value()); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correclty Serialize and Deserialize a Code object'] = function(test) { - var doc = {'doc': {'doc2': new Code('this.a > i', {i:1})}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.doc.doc2.code, deserialized_data.doc.doc2.code); - test.deepEqual(doc.doc.doc2.scope.i, deserialized_data.doc.doc2.scope.i); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly serialize and deserialize and embedded array'] = function(test) { - var doc = {'a':0, - 'b':['tmp1', 'tmp2', 'tmp3', 'tmp4', 'tmp5', 'tmp6', 'tmp7', 'tmp8', 'tmp9', 'tmp10', 'tmp11', 'tmp12', 'tmp13', 'tmp14', 'tmp15', 'tmp16'] - }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.a, deserialized_data.a); - test.deepEqual(doc.b, deserialized_data.b); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize UTF8'] = function(test) { - // Serialize utf8 - var doc = { "name" : "本è˜ç”±åˆ©åœ°åŸŸã«æ´ªæ°´è­¦å ±", "name1" : "öüóőúéáűíÖÜÓÅÚÉÃÅ°Ã", "name2" : "abcdedede"}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize query object'] = function(test) { - var doc = { count: 'remove_with_no_callback_bug_test', query: {}, fields: null}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize empty query object'] = function(test) { - var doc = {}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize array based doc'] = function(test) { - var doc = { b: [ 1, 2, 3 ], _id: new ObjectID() }; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Symbol'] = function(test) { - if(Symbol != null) { - var doc = { b: [ new Symbol('test') ]}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc.b, deserialized_data.b) - test.deepEqual(doc, deserialized_data); - test.ok(deserialized_data.b[0] instanceof Symbol); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should handle Deeply nested document'] = function(test) { - var doc = {a:{b:{c:{d:2}}}}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var deserialized_data = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, deserialized_data); - test.done(); -} - -/** - * @ignore - */ -exports['Should handle complicated all typed object'] = function(test) { - // First doc - var date = new Date(); - var oid = new ObjectID(); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - // Second doc - var oid = new ObjectID.createFromHexString(oid.toHexString()); - var string = 'binstring' - var bin = new Binary() - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - - var doc2 = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': date, - 'oid': oid, - 'binary': bin, - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': date.getTime(), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', oid, 'integration_tests_') - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize Complex Nested Object'] = function(test) { - var doc = { email: 'email@email.com', - encrypted_password: 'password', - friends: [ '4db96b973d01205364000006', - '4dc77b24c5ba38be14000002' ], - location: [ 72.4930088, 23.0431957 ], - name: 'Amit Kumar', - password_salt: 'salty', - profile_fields: [], - username: 'amit', - _id: new ObjectID() } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = doc; - doc2._id = ObjectID.createFromHexString(doc2._id.toHexString()); - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly massive doc'] = function(test) { - var oid1 = new ObjectID(); - var oid2 = new ObjectID(); - - // JS doc - var doc = { dbref2: new DBRef('namespace', oid1, 'integration_tests_'), - _id: oid2 }; - - var doc2 = { dbref2: new DBRef('namespace', ObjectID.createFromHexString(oid1.toHexString()), 'integration_tests_'), - _id: new ObjectID.createFromHexString(oid2.toHexString()) }; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize regexp object'] = function(test) { - var doc = {'b':/foobaré/}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var serialized_data2 = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - for(var i = 0; i < serialized_data2.length; i++) { - require('assert').equal(serialized_data2[i], serialized_data[i]) - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize complicated object'] = function(test) { - var doc = {a:{b:{c:[new ObjectID(), new ObjectID()]}}, d:{f:1332.3323}}; - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object'] = function(test) { - var doc = { "_id" : { "date" : new Date(), "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize/Deserialize nested object with even more nesting'] = function(test) { - var doc = { "_id" : { "date" : {a:1, b:2, c:new Date()}, "gid" : "6f35f74d2bea814e21000000" }, - "value" : { - "b" : { "countries" : { "--" : 386 }, "total" : 1599 }, - "bc" : { "countries" : { "--" : 3 }, "total" : 10 }, - "gp" : { "countries" : { "--" : 2 }, "total" : 13 }, - "mgc" : { "countries" : { "--" : 2 }, "total" : 14 } - } - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize empty name object'] = function(test) { - var doc = {'':'test', - 'bbbb':1}; - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.equal(doc2[''], 'test'); - test.equal(doc2['bbbb'], 1); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly handle Forced Doubles to ensure we allocate enough space for cap collections'] = function(test) { - if(Double != null) { - var doubleValue = new Double(100); - var doc = {value:doubleValue}; - - // Serialize - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({value:100}, doc2); - } - - test.done(); -} - -/** - * @ignore - */ -exports['Should deserialize correctly'] = function(test) { - var doc = { - "_id" : new ObjectID("4e886e687ff7ef5e00000162"), - "str" : "foreign", - "type" : 2, - "timestamp" : ISODate("2011-10-02T14:00:08.383Z"), - "links" : [ - "http://www.reddit.com/r/worldnews/comments/kybm0/uk_home_secretary_calls_for_the_scrapping_of_the/" - ] - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize and deserialize MinKey and MaxKey values'] = function(test) { - var doc = { - _id : new ObjectID("4e886e687ff7ef5e00000162"), - minKey : new MinKey(), - maxKey : new MaxKey() - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.deepEqual(doc, doc2) - test.ok(doc2.minKey instanceof MinKey); - test.ok(doc2.maxKey instanceof MaxKey); - test.done(); -} - -/** - * @ignore - */ -exports['Should correctly serialize Double value'] = function(test) { - var doc = { - value : new Double(34343.2222) - } - - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); - new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); - assertBuffersEqual(test, serialized_data, serialized_data2, 0); - var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - - test.ok(doc.value.valueOf(), doc2.value); - test.ok(doc.value.value, doc2.value); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly create objects'] = function(test) { - try { - var object1 = ObjectID.createFromHexString('000000000000000000000001') - var object2 = ObjectID.createFromHexString('00000000000000000000001') - test.ok(false); - } catch(err) { - test.ok(err != null); - } - - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should correctly retrieve timestamp'] = function(test) { - var testDate = new Date(); - var object1 = new ObjectID(); - test.equal(Math.floor(testDate.getTime()/1000), Math.floor(object1.getTimestamp().getTime()/1000)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly throw error on bsonparser errors'] = function(test) { - var data = new Buffer(3); - var parser = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - - // Catch to small buffer error - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - data = new Buffer(5); - data[0] = 0xff; - data[1] = 0xff; - // Catch illegal size - try { - parser.deserialize(data); - test.ok(false); - } catch(err) {} - - // Finish up - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function BSON.calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the object without serializing the function - var size = BSON.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = BSON.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.calculateObjectSize function returning the number of BSON bytes a javascript object needs. - * - * @_class bson - * @_function calculateObjectSize - * @ignore - */ -exports['Should correctly calculate the size of a given javascript object using instance method'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the object without serializing the function - var size = bson.calculateObjectSize(doc, false); - test.equal(12, size); - // Calculate the size of the object serializing the function - size = bson.calculateObjectSize(doc, true); - // Validate the correctness - test.equal(36, size); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function BSON.serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = BSON.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = BSON.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serializeWithBufferAndIndex function. - * - * @_class bson - * @_function serializeWithBufferAndIndex - * @ignore - */ -exports['Should correctly serializeWithBufferAndIndex a given javascript object using a BSON instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, false); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, false); - // Validate the correctness - test.equal(12, size); - test.equal(11, index); - - // Serialize with functions - // Calculate the size of the document, no function serialization - var size = bson.calculateObjectSize(doc, true); - // Allocate a buffer - var buffer = new Buffer(size); - // Serialize the object to the buffer, checking keys and not serializing functions - var index = bson.serializeWithBufferAndIndex(doc, true, buffer, 0, true); - // Validate the correctness - test.equal(36, size); - test.equal(35, index); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function BSON.serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = BSON.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.serialize function returning serialized BSON Buffer object. - * - * @_class bson - * @_function serialize - * @ignore - */ -exports['Should correctly serialize a given javascript object using a bson instance'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){}} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and not serializing functions - var buffer = bson.serialize(doc, true, true, false); - // Validate the correctness - test.equal(12, buffer.length); - - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(36, buffer.length); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function BSON.deserialize - * @ignore - */ - exports['Should correctly deserialize a buffer using the BSON class level parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = BSON.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = BSON.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserialize function returning a deserialized Javascript function. - * - * @_class bson - * @_function deserialize - * @ignore - */ -exports['Should correctly deserialize a buffer using the BSON instance parser'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // Deserialize the object with no eval for the functions - var deserializedDoc = bson.deserialize(buffer); - // Validate the correctness - test.equal('object', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - - // Deserialize the object with eval for the functions caching the functions - deserializedDoc = bson.deserialize(buffer, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal('function', typeof deserializedDoc.func); - test.equal(1, deserializedDoc.a); - test.done(); -} - -/** - * A simple example showing the usage of BSON.deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function BSON.deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = BSON.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = BSON.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * A simple example showing the usage of BSON instance deserializeStream function returning deserialized Javascript objects. - * - * @_class bson - * @_function deserializeStream - * @ignore - */ -exports['Should correctly deserializeStream a buffer object'] = function(test) { - // Create a simple object - var doc = {a: 1, func:function(){ console.log('hello world'); }} - // Create a BSON parser instance - var bson = new BSON(); - // Serialize the object to a buffer, checking keys and serializing functions - var buffer = bson.serialize(doc, true, true, true); - // Validate the correctness - test.equal(65, buffer.length); - - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('object', typeof documents[0].func); - - // Deserialize the object with eval for the functions caching the functions - // The array holding the number of retuned documents - var documents = new Array(1); - // Deserialize the object with no eval for the functions - var index = bson.deserializeStream(buffer, 0, 1, documents, 0, {evalFunctions:true, cacheFunctions:true}); - // Validate the correctness - test.equal(65, index); - test.equal(1, documents.length); - test.equal(1, documents[0].a); - test.equal('function', typeof documents[0].func); - test.done(); -} - -/** - * @ignore - */ -exports['ObjectID should have a correct cached representation of the hexString'] = function (test) { - ObjectID.cacheHexString = true; - var a = new ObjectID; - var __id = a.__id; - test.equal(__id, a.toHexString()); - - // hexString - a = new ObjectID(__id); - test.equal(__id, a.toHexString()); - - // fromHexString - a = ObjectID.createFromHexString(__id); - test.equal(a.__id, a.toHexString()); - test.equal(__id, a.toHexString()); - - // number - var genTime = a.generationTime; - a = new ObjectID(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - - // generationTime - delete a.__id; - a.generationTime = genTime; - test.equal(__id, a.toHexString()); - - // createFromTime - a = ObjectId.createFromTime(genTime); - __id = a.__id; - test.equal(__id, a.toHexString()); - ObjectId.cacheHexString = false; - - test.done(); -} - -/** - * @ignore - */ -// 'Should Correctly Function' = function(test) { -// var doc = {b:1, func:function() { -// this.b = 2; -// }}; -// -// var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); -// -// debug("----------------------------------------------------------------------") -// debug(inspect(serialized_data)) -// -// // var serialized_data2 = new Buffer(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).calculateObjectSize(doc, false, true)); -// // new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serializeWithBufferAndIndex(doc, false, serialized_data2, 0); -// // assertBuffersEqual(test, serialized_data, serialized_data2, 0); -// var COUNT = 100000; -// -// // var b = null; -// // eval("b = function(x) { return x+x; }"); -// // var b = new Function("x", "return x+x;"); -// -// console.log(COUNT + "x (objectBSON = BSON.serialize(object))") -// start = new Date -// -// for (i=COUNT; --i>=0; ) { -// var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// } -// -// end = new Date -// console.log("time = ", end - start, "ms -", COUNT * 1000 / (end - start), " ops/sec") -// -// // debug(inspect(new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).functionCache)) -// // -// // var doc2 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // // test.deepEqual(doc, doc2) -// // // -// // debug(inspect(doc2)) -// // doc2.func() -// // debug(inspect(doc2)) -// // -// // var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc2, false, true); -// // var doc3 = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data, {evalFunctions: true, cacheFunctions:true}); -// // -// // debug("-----------------------------------------------") -// // debug(inspect(doc3)) -// -// // var key = "0" -// // for(var i = 1; i < 10000; i++) { -// // key = key + " " + i -// // } -// -// test.done(); -// -// -// // var car = { -// // model : "Volvo", -// // country : "Sweden", -// // -// // isSwedish : function() { -// // return this.country == "Sweden"; -// // } -// // } -// -// }, - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js deleted file mode 100644 index cde83f8fd03..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/bson_typed_array_test.js +++ /dev/null @@ -1,392 +0,0 @@ -var mongodb = require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - debug = require('util').debug, - inspect = require('util').inspect, - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser, - utils = require('./tools/utils'); - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Module for parsing an ISO 8601 formatted string into a Date object. - */ -var ISODate = function (string) { - var match; - - if (typeof string.getTime === "function") - return string; - else if (match = string.match(/^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/)) { - var date = new Date(); - date.setUTCFullYear(Number(match[1])); - date.setUTCMonth(Number(match[3]) - 1 || 0); - date.setUTCDate(Number(match[5]) || 0); - date.setUTCHours(Number(match[7]) || 0); - date.setUTCMinutes(Number(match[8]) || 0); - date.setUTCSeconds(Number(match[10]) || 0); - date.setUTCMilliseconds(Number("." + match[12]) * 1000 || 0); - - if (match[13] && match[13] !== "Z") { - var h = Number(match[16]) || 0, - m = Number(match[17]) || 0; - - h *= 3600000; - m *= 60000; - - var offset = h + m; - if (match[15] == "+") - offset = -offset; - - date = new Date(date.valueOf() + offset); - } - - return date; - } else - throw new Error("Invalid ISO 8601 date given.", __filename); -}; - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports.shouldCorrectlyDeserializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': '客家è¯', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, true, false); - // Build a typed array - var arr = new Uint8Array(new ArrayBuffer(data.length)); - // Iterate over all the fields and copy - for(var i = 0; i < data.length; i++) { - arr[i] = data[i] - } - - // Deserialize the object - var object = BSONDE.BSON.deserialize(arr); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports.shouldCorrectlySerializeUsingTypedArray = function(test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - var motherOfAllDocuments = { - 'string': 'hello', - 'array': [1,2,3], - 'hash': {'a':1, 'b':2}, - 'date': new Date(), - 'oid': new ObjectID(), - 'binary': new Binary(new Buffer("hello")), - 'int': 42, - 'float': 33.3333, - 'regexp': /regexp/, - 'boolean': true, - 'long': Long.fromNumber(100), - 'where': new Code('this.a > i', {i:1}), - 'dbref': new DBRef('namespace', new ObjectID(), 'integration_tests_'), - 'minkey': new MinKey(), - 'maxkey': new MaxKey() - } - - // Let's serialize it - var data = BSONSE.BSON.serialize(motherOfAllDocuments, true, false, false); - // And deserialize it again - var object = BSONSE.BSON.deserialize(data); - // Asserts - test.equal(motherOfAllDocuments.string, object.string); - test.deepEqual(motherOfAllDocuments.array, object.array); - test.deepEqual(motherOfAllDocuments.date, object.date); - test.deepEqual(motherOfAllDocuments.oid.toHexString(), object.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.binary.length(), object.binary.length()); - // Assert the values of the binary - for(var i = 0; i < motherOfAllDocuments.binary.length(); i++) { - test.equal(motherOfAllDocuments.binary.value[i], object.binary[i]); - } - test.deepEqual(motherOfAllDocuments.int, object.int); - test.deepEqual(motherOfAllDocuments.float, object.float); - test.deepEqual(motherOfAllDocuments.regexp, object.regexp); - test.deepEqual(motherOfAllDocuments.boolean, object.boolean); - test.deepEqual(motherOfAllDocuments.long.toNumber(), object.long); - test.deepEqual(motherOfAllDocuments.where, object.where); - test.deepEqual(motherOfAllDocuments.dbref.oid.toHexString(), object.dbref.oid.toHexString()); - test.deepEqual(motherOfAllDocuments.dbref.namespace, object.dbref.namespace); - test.deepEqual(motherOfAllDocuments.dbref.db, object.dbref.db); - test.deepEqual(motherOfAllDocuments.minkey, object.minkey); - test.deepEqual(motherOfAllDocuments.maxkey, object.maxkey); - test.done(); -} - -/** - * @ignore - */ -exports['exercise all the binary object constructor methods'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using number of chars - binary = new Binary(5); - test.ok(5, binary.buffer.length); - - // Construct using an Array - var binary = new Binary(utils.stringToArray(string)); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - - // Construct using a string - var binary = new Binary(string); - test.ok(string.length, binary.buffer.length); - test.ok(utils.assertArrayEqual(array, binary.buffer)); - test.done(); -}; - -/** - * @ignore - */ -exports['exercise the put binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // String to array - var array = utils.stringToArrayBuffer(string + 'a'); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(string.length + 1, binary.position); - test.ok(utils.assertArrayEqual(array, binary.value(true))); - test.equal('hello worlda', binary.value()); - - // Exercise a binary with lots of space in the buffer - var binary = new Binary(); - test.ok(Binary.BUFFER_SIZE, binary.buffer.length); - - // Write a byte to the array - binary.put('a') - - // Verify that the data was writtencorrectly - test.equal(1, binary.position); - test.ok(utils.assertArrayEqual(['a'.charCodeAt(0)], binary.value(true))); - test.equal('a', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the write binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - // Array - var writeArrayBuffer = new Uint8Array(new ArrayBuffer(1)); - writeArrayBuffer[0] = 'a'.charCodeAt(0); - var arrayBuffer = ['a'.charCodeAt(0)]; - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Write a string starting at end of buffer - binary.write('a'); - test.equal('hello worlda', binary.value()); - // Write a string starting at index 0 - binary.write('a', 0); - test.equal('aello worlda', binary.value()); - // Write a arraybuffer starting at end of buffer - binary.write(writeArrayBuffer); - test.equal('aello worldaa', binary.value()); - // Write a arraybuffer starting at position 5 - binary.write(writeArrayBuffer, 5); - test.equal('aelloaworldaa', binary.value()); - // Write a array starting at end of buffer - binary.write(arrayBuffer); - test.equal('aelloaworldaaa', binary.value()); - // Write a array starting at position 6 - binary.write(arrayBuffer, 6); - test.equal('aelloaaorldaaa', binary.value()); - test.done(); -}, - -/** - * @ignore - */ -exports['exercise the read binary object method for an instance when using Uint8Array'] = function (test) { - if(typeof ArrayBuffer == 'undefined') { - test.done(); - return; - } - - // Construct using array - var string = 'hello world'; - var array = utils.stringToArrayBuffer(string); - - // Binary from array buffer - var binary = new Binary(utils.stringToArrayBuffer(string)); - test.ok(string.length, binary.buffer.length); - - // Read the first 2 bytes - var data = binary.read(0, 2); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('he'), data)); - - // Read the entire field - var data = binary.read(0); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer(string), data)); - - // Read 3 bytes - var data = binary.read(6, 5); - test.ok(utils.assertArrayEqual(utils.stringToArrayBuffer('world'), data)); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} \ No newline at end of file diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/data/test_gs_weird_bug.png and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js deleted file mode 100644 index 7a78347ec7e..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/test_full_bson.js +++ /dev/null @@ -1,315 +0,0 @@ -var sys = require('util'), - fs = require('fs'), - BSON = require('../../ext').BSON, - Buffer = require('buffer').Buffer, - BSONJS = require('../../lib/bson/bson').BSON, - BinaryParser = require('../../lib/bson/binary_parser').BinaryParser, - Long = require('../../lib/bson/long').Long, - ObjectID = require('../../lib/bson/bson').ObjectID, - Binary = require('../../lib/bson/bson').Binary, - Code = require('../../lib/bson/bson').Code, - DBRef = require('../../lib/bson/bson').DBRef, - Symbol = require('../../lib/bson/bson').Symbol, - Double = require('../../lib/bson/bson').Double, - MaxKey = require('../../lib/bson/bson').MaxKey, - MinKey = require('../../lib/bson/bson').MinKey, - Timestamp = require('../../lib/bson/bson').Timestamp, - gleak = require('../../tools/gleak'), - assert = require('assert'); - -// Parsers -var bsonC = new BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); -var bsonJS = new BSONJS([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]); - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object'] = function(test) { - var bytes = [95,0,0,0,2,110,115,0,42,0,0,0,105,110,116,101,103,114,97,116,105,111,110,95,116,101,115,116,115,95,46,116,101,115,116,95,105,110,100,101,120,95,105,110,102,111,114,109,97,116,105,111,110,0,8,117,110,105,113,117,101,0,0,3,107,101,121,0,12,0,0,0,16,97,0,1,0,0,0,0,2,110,97,109,101,0,4,0,0,0,97,95,49,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonC.deserialize(serialized_data); - assert.equal("a_1", object.name); - assert.equal(false, object.unique); - assert.equal(1, object.key.a); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Deserialize object with all types'] = function(test) { - var bytes = [26,1,0,0,7,95,105,100,0,161,190,98,75,118,169,3,0,0,3,0,0,4,97,114,114,97,121,0,26,0,0,0,16,48,0,1,0,0,0,16,49,0,2,0,0,0,16,50,0,3,0,0,0,0,2,115,116,114,105,110,103,0,6,0,0,0,104,101,108,108,111,0,3,104,97,115,104,0,19,0,0,0,16,97,0,1,0,0,0,16,98,0,2,0,0,0,0,9,100,97,116,101,0,161,190,98,75,0,0,0,0,7,111,105,100,0,161,190,98,75,90,217,18,0,0,1,0,0,5,98,105,110,97,114,121,0,7,0,0,0,2,3,0,0,0,49,50,51,16,105,110,116,0,42,0,0,0,1,102,108,111,97,116,0,223,224,11,147,169,170,64,64,11,114,101,103,101,120,112,0,102,111,111,98,97,114,0,105,0,8,98,111,111,108,101,97,110,0,1,15,119,104,101,114,101,0,25,0,0,0,12,0,0,0,116,104,105,115,46,120,32,61,61,32,51,0,5,0,0,0,0,3,100,98,114,101,102,0,37,0,0,0,2,36,114,101,102,0,5,0,0,0,116,101,115,116,0,7,36,105,100,0,161,190,98,75,2,180,1,0,0,2,0,0,0,10,110,117,108,108,0,0]; - var serialized_data = ''; - // Convert to chars - for(var i = 0; i < bytes.length; i++) { - serialized_data = serialized_data + BinaryParser.fromByte(bytes[i]); - } - - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal("hello", object.string); - assert.deepEqual([1, 2, 3], object.array); - assert.equal(1, object.hash.a); - assert.equal(2, object.hash.b); - assert.ok(object.date != null); - assert.ok(object.oid != null); - assert.ok(object.binary != null); - assert.equal(42, object.int); - assert.equal(33.3333, object.float); - assert.ok(object.regexp != null); - assert.equal(true, object.boolean); - assert.ok(object.where != null); - assert.ok(object.dbref != null); - assert.ok(object['null'] == null); - test.done(); -} - -/** - * @ignore - */ -exports['Should Serialize and Deserialize String'] = function(test) { - var test_string = {hello: 'world'} - var serialized_data = bsonC.serialize(test_string) - assert.deepEqual(test_string, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_number = {doc: 5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize null value'] = function(test) { - var test_null = {doc:null} - var serialized_data = bsonC.serialize(test_null) - var object = bsonC.deserialize(serialized_data); - assert.deepEqual(test_null, object); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize undefined value'] = function(test) { - var test_undefined = {doc:undefined} - var serialized_data = bsonC.serialize(test_undefined) - var object = bsonJS.deserialize(new Buffer(serialized_data, 'binary')); - assert.equal(null, object.doc) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Number'] = function(test) { - var test_number = {doc: 5.5} - var serialized_data = bsonC.serialize(test_number) - assert.deepEqual(test_number, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Integer'] = function(test) { - var test_int = {doc: 42} - var serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -5600} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: 2147483647} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - - test_int = {doc: -2147483648} - serialized_data = bsonC.serialize(test_int) - assert.deepEqual(test_int, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Object'] = function(test) { - var doc = {doc: {age: 42, name: 'Spongebob', shoe_size: 9.5}} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Array with added on functions'] = function(test) { - var doc = {doc: [1, 2, 'a', 'b']} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize A Boolean'] = function(test) { - var doc = {doc: true} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Date'] = function(test) { - var date = new Date() - //(2009, 11, 12, 12, 00, 30) - date.setUTCDate(12) - date.setUTCFullYear(2009) - date.setUTCMonth(11 - 1) - date.setUTCHours(12) - date.setUTCMinutes(0) - date.setUTCSeconds(30) - var doc = {doc: date} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Oid'] = function(test) { - var doc = {doc: new ObjectID()} - var serialized_data = bsonC.serialize(doc) - assert.deepEqual(doc.doc.toHexString(), bsonC.deserialize(serialized_data).doc.toHexString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Buffer'] = function(test) { - var doc = {doc: new Buffer("123451234512345")} - var serialized_data = bsonC.serialize(doc) - - assert.equal("123451234512345", bsonC.deserialize(serialized_data).doc.buffer.toString('ascii')); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly encode Empty Hash'] = function(test) { - var test_code = {} - var serialized_data = bsonC.serialize(test_code) - assert.deepEqual(test_code, bsonC.deserialize(serialized_data)); - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Ordered Hash'] = function(test) { - var doc = {doc: {b:1, a:2, c:3, d:4}} - var serialized_data = bsonC.serialize(doc) - var decoded_hash = bsonC.deserialize(serialized_data).doc - var keys = [] - for(var name in decoded_hash) keys.push(name) - assert.deepEqual(['b', 'a', 'c', 'd'], keys) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize Regular Expression'] = function(test) { - var doc = {doc: /foobar/mi} - var serialized_data = bsonC.serialize(doc) - var doc2 = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.toString(), doc2.doc.toString()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a Binary object'] = function(test) { - var bin = new Binary() - var string = 'binstring' - for(var index = 0; index < string.length; index++) { - bin.put(string.charAt(index)) - } - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports['Should Correctly Serialize and Deserialize a big Binary object'] = function(test) { - var data = fs.readFileSync("test/node/data/test_gs_weird_bug.png", 'binary'); - var bin = new Binary() - bin.write(data) - var doc = {doc: bin} - var serialized_data = bsonC.serialize(doc) - var deserialized_data = bsonC.deserialize(serialized_data); - assert.equal(doc.doc.value(), deserialized_data.doc.value()) - test.done(); -} - -/** - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js deleted file mode 100644 index e9282e54908..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/to_bson_test.js +++ /dev/null @@ -1,109 +0,0 @@ -var mongodb = process.env['TEST_NATIVE'] != null ? require('../../lib/bson').native() : require('../../lib/bson').pure(); - -var testCase = require('nodeunit').testCase, - mongoO = require('../../lib/bson').pure(), - Buffer = require('buffer').Buffer, - gleak = require('../../tools/gleak'), - fs = require('fs'), - BSON = mongoO.BSON, - Code = mongoO.Code, - Binary = mongoO.Binary, - Timestamp = mongoO.Timestamp, - Long = mongoO.Long, - MongoReply = mongoO.MongoReply, - ObjectID = mongoO.ObjectID, - Symbol = mongoO.Symbol, - DBRef = mongoO.DBRef, - Double = mongoO.Double, - MinKey = mongoO.MinKey, - MaxKey = mongoO.MaxKey, - BinaryParser = mongoO.BinaryParser; - -var BSONSE = mongodb, - BSONDE = mongodb; - -// for tests -BSONDE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONDE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONDE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONDE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONDE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONDE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -BSONSE.BSON_BINARY_SUBTYPE_DEFAULT = 0; -BSONSE.BSON_BINARY_SUBTYPE_FUNCTION = 1; -BSONSE.BSON_BINARY_SUBTYPE_BYTE_ARRAY = 2; -BSONSE.BSON_BINARY_SUBTYPE_UUID = 3; -BSONSE.BSON_BINARY_SUBTYPE_MD5 = 4; -BSONSE.BSON_BINARY_SUBTYPE_USER_DEFINED = 128; - -var hexStringToBinary = function(string) { - var numberofValues = string.length / 2; - var array = ""; - - for(var i = 0; i < numberofValues; i++) { - array += String.fromCharCode(parseInt(string[i*2] + string[i*2 + 1], 16)); - } - return array; -} - -var assertBuffersEqual = function(test, buffer1, buffer2) { - if(buffer1.length != buffer2.length) test.fail("Buffers do not have the same length", buffer1, buffer2); - - for(var i = 0; i < buffer1.length; i++) { - test.equal(buffer1[i], buffer2[i]); - } -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.setUp = function(callback) { - callback(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.tearDown = function(callback) { - callback(); -} - -/** - * @ignore - */ -exports['Should correctly handle toBson function for an object'] = function(test) { - // Test object - var doc = { - hello: new ObjectID(), - a:1 - }; - // Add a toBson method to the object - doc.toBSON = function() { - return {b:1}; - } - - // Serialize the data - var serialized_data = new BSONSE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).serialize(doc, false, true); - var deserialized_doc = new BSONDE.BSON([Long, ObjectID, Binary, Code, DBRef, Symbol, Double, Timestamp, MaxKey, MinKey]).deserialize(serialized_data); - test.deepEqual({b:1}, deserialized_doc); - test.done(); -} - -/** - * Retrieve the server information for the current - * instance of the db client - * - * @ignore - */ -exports.noGlobalsLeaked = function(test) { - var leaks = gleak.detectNew(); - test.equal(0, leaks.length, "global var leak detected: " + leaks.join(', ')); - test.done(); -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js deleted file mode 100644 index 9d7cbe7c6ea..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/test/node/tools/utils.js +++ /dev/null @@ -1,80 +0,0 @@ -exports.assertArrayEqual = function(array1, array2) { - if(array1.length != array2.length) return false; - for(var i = 0; i < array1.length; i++) { - if(array1[i] != array2[i]) return false; - } - - return true; -} - -// String to arraybuffer -exports.stringToArrayBuffer = function(string) { - var dataBuffer = new Uint8Array(new ArrayBuffer(string.length)); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -// String to arraybuffer -exports.stringToArray = function(string) { - var dataBuffer = new Array(string.length); - // Return the strings - for(var i = 0; i < string.length; i++) { - dataBuffer[i] = string.charCodeAt(i); - } - // Return the data buffer - return dataBuffer; -} - -exports.Utf8 = { - // public method for url encoding - encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // public method for url decoding - decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if(c < 128) { - string += String.fromCharCode(c); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - return string; - } -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js deleted file mode 100644 index c707cfcb56c..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/gleak.js +++ /dev/null @@ -1,21 +0,0 @@ - -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE deleted file mode 100644 index 7c435baaec8..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js deleted file mode 100644 index 73834010f60..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine-html.js +++ /dev/null @@ -1,190 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('span', { className: 'title' }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount === 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap.spec) { - return true; - } - return spec.getFullName().indexOf(paramMap.spec) === 0; -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css deleted file mode 100644 index 6583fe7c66d..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js deleted file mode 100644 index c3d2dc7d2d3..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine.js +++ /dev/null @@ -1,2476 +0,0 @@ -var isCommonJS = typeof window == "undefined"; - -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; -if (isCommonJS) exports.jasmine = jasmine; -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Show diagnostic messages in the console if set to true - * - */ -jasmine.VERBOSE = false; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for (var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - this.message = this.passed_ ? 'Passed.' : params.message; - - var trace = (params.trace || new Error(this.message)); - this.trace = this.passed_ ? '' : trace; -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); - return env; -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj.nodeType > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; -if (isCommonJS) exports.spyOn = spyOn; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; -if (isCommonJS) exports.it = it; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; -if (isCommonJS) exports.xit = xit; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; -if (isCommonJS) exports.expect = expect; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; -if (isCommonJS) exports.runs = runs; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; -if (isCommonJS) exports.waits = waits; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; -if (isCommonJS) exports.waitsFor = waitsFor; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; -if (isCommonJS) exports.beforeEach = beforeEach; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; -if (isCommonJS) exports.afterEach = afterEach; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; -if (isCommonJS) exports.describe = describe; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; -if (isCommonJS) exports.xdescribe = xdescribe; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - function tryIt(f) { - try { - return f(); - } catch(e) { - } - return null; - } - - var xhr = tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }) || - tryIt(function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }) || - tryIt(function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }); - - if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); - - return xhr; -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass(); -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (!jasmine.version_) { - return "version unknown"; - } - - var version = this.version(); - var versionString = version.major + "." + version.minor + "." + version.build; - if (version.release_candidate) { - versionString += ".rc" + version.release_candidate; - } - versionString += " revision " + version.revision; - return versionString; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - this.currentSuite = parentSuite; - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj !== null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length === 0 && mismatchValues.length === 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount === 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ]; - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected item is equal to the actual item - * up to a given level of decimal precision (default 2). - * - * @param {Number} expected - * @param {Number} precision - */ -jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { - if (!(precision === 0)) { - precision = precision || 2; - } - var multiplier = Math.pow(10, precision); - var actual = Math.round(this.actual * multiplier); - expected = Math.round(expected * multiplier); - return expected == actual; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && - obj.__lookupGetter__(property) !== null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception', - trace: { stack: e.stack } - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - } - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - if (jasmine.VERBOSE) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - } - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - -jasmine.version_= { - "major": 1, - "minor": 1, - "build": 0, - "revision": 1315677058 -}; diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png b/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png deleted file mode 100644 index 218f3b43713..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/node_modules/bson/tools/jasmine-1.1.0/jasmine_favicon.png and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/package.json b/frontend/express/node_modules/mongoskin/node_modules/mongodb/package.json deleted file mode 100644 index 3d1c45c0673..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/package.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "name": "mongodb", - "description": "A node.js driver for MongoDB", - "keywords": [ - "mongodb", - "mongo", - "driver", - "db" - ], - "version": "1.2.14", - "author": { - "name": "Christian Amor Kvalheim", - "email": "christkv@gmail.com" - }, - "contributors": [ - { - "name": "Aaron Heckmann" - }, - { - "name": "Christoph Pojer" - }, - { - "name": "Pau Ramon Revilla" - }, - { - "name": "Nathan White" - }, - { - "name": "Emmerman" - }, - { - "name": "Seth LaForge" - }, - { - "name": "Boris Filipov" - }, - { - "name": "Stefan Schärmeli" - }, - { - "name": "Tedde Lundgren" - }, - { - "name": "renctan" - }, - { - "name": "Sergey Ukustov" - }, - { - "name": "Ciaran Jessup" - }, - { - "name": "kuno" - }, - { - "name": "srimonti" - }, - { - "name": "Erik Abele" - }, - { - "name": "Pratik Daga" - }, - { - "name": "Slobodan Utvic" - }, - { - "name": "Kristina Chodorow" - }, - { - "name": "Yonathan Randolph" - }, - { - "name": "Brian Noguchi" - }, - { - "name": "Sam Epstein" - }, - { - "name": "James Harrison Fisher" - }, - { - "name": "Vladimir Dronnikov" - }, - { - "name": "Ben Hockey" - }, - { - "name": "Henrik Johansson" - }, - { - "name": "Simon Weare" - }, - { - "name": "Alex Gorbatchev" - }, - { - "name": "Shimon Doodkin" - }, - { - "name": "Kyle Mueller" - }, - { - "name": "Eran Hammer-Lahav" - }, - { - "name": "Marcin Ciszak" - }, - { - "name": "François de Metz" - }, - { - "name": "Vinay Pulim" - }, - { - "name": "nstielau" - }, - { - "name": "Adam Wiggins" - }, - { - "name": "entrinzikyl" - }, - { - "name": "Jeremy Selier" - }, - { - "name": "Ian Millington" - }, - { - "name": "Public Keating" - }, - { - "name": "andrewjstone" - }, - { - "name": "Christopher Stott" - }, - { - "name": "Corey Jewett" - }, - { - "name": "brettkiefer" - }, - { - "name": "Rob Holland" - }, - { - "name": "Senmiao Liu" - }, - { - "name": "heroic" - }, - { - "name": "gitfy" - }, - { - "name": "Andrew Stone" - }, - { - "name": "John Le Drew" - }, - { - "name": "Lucasfilm Singapore" - }, - { - "name": "Roman Shtylman" - }, - { - "name": "Matt Self" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/mongodb/node-mongodb-native.git" - }, - "bugs": { - "url": "http://github.com/mongodb/node-mongodb-native/issues" - }, - "dependencies": { - "bson": "0.1.8" - }, - "devDependencies": { - "dox": "0.2.0", - "uglify-js": "1.2.5", - "ejs": "0.6.1", - "nodeunit": "0.7.4", - "github3": ">=0.3.0", - "markdown": "0.3.1", - "gleak": "0.2.3", - "step": "0.0.5", - "async": "0.1.22", - "integra": "0.0.1", - "optimist": "latest" - }, - "config": { - "native": false - }, - "main": "./lib/mongodb/index", - "homepage": "http://mongodb.github.com/node-mongodb-native/", - "directories": { - "lib": "./lib/mongodb" - }, - "engines": { - "node": ">=0.6.19" - }, - "scripts": { - "test": "make test_functional" - }, - "licenses": [ - { - "type": "Apache License, Version 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "readme": "Up to date documentation\n========================\n\n[Documentation](http://mongodb.github.com/node-mongodb-native/)\n\nInstall\n=======\n\nTo install the most recent release from npm, run:\n\n npm install mongodb\n\nThat may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version)\n\nTo install the latest from the repository, run::\n\n npm install path/to/node-mongodb-native\n\nCommunity\n=========\nCheck out the google group [node-mongodb-native](http://groups.google.com/group/node-mongodb-native) for questions/answers from users of the driver.\n\nTry it live\n============\n\n\nIntroduction\n============\n\nThis is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/.\n\nA simple example of inserting a document.\n\n```javascript\n var client = new Db('test', new Server(\"127.0.0.1\", 27017, {}), {w: 1}),\n test = function (err, collection) {\n collection.insert({a:2}, function(err, docs) {\n\n collection.count(function(err, count) {\n test.assertEquals(1, count);\n });\n\n // Locate all the entries using find\n collection.find().toArray(function(err, results) {\n test.assertEquals(1, results.length);\n test.assertTrue(results[0].a === 2);\n\n // Let's close the db\n client.close();\n });\n });\n };\n\n client.open(function(err, p_client) {\n client.collection('test_insert', test);\n });\n```\n\nData types\n==========\n\nTo store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code).\n\nIn particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example:\n\n```javascript\n // Get the objectID type\n var ObjectID = require('mongodb').ObjectID;\n\n var idString = '4e4e1638c85e808431000003';\n collection.findOne({_id: new ObjectID(idString)}, console.log) // ok\n collection.findOne({_id: idString}, console.log) // wrong! callback gets undefined\n```\n\nHere are the constructors the non-Javascript BSON primitive types:\n\n```javascript\n // Fetch the library\n var mongo = require('mongodb');\n // Create new instances of BSON types\n new mongo.Long(numberString)\n new mongo.ObjectID(hexString)\n new mongo.Timestamp() // the actual unique number is generated on insert.\n new mongo.DBRef(collectionName, id, dbName)\n new mongo.Binary(buffer) // takes a string or Buffer\n new mongo.Code(code, [context])\n new mongo.Symbol(string)\n new mongo.MinKey()\n new mongo.MaxKey()\n new mongo.Double(number)\t// Force double storage\n```\n\nThe C/C++ bson parser/serializer\n--------------------------------\n\nIf you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below\n\n```javascript\n // using native_parser:\n var client = new Db('integration_tests_20',\n new Server(\"127.0.0.1\", 27017),\n {native_parser:true});\n```\n\nThe C++ parser uses the js objects both for serialization and deserialization.\n\nGitHub information\n==================\n\nThe source code is available at http://github.com/mongodb/node-mongodb-native.\nYou can either clone the repository or download a tarball of the latest release.\n\nOnce you have the source you can test the driver by running\n\n $ make test\n\nin the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass.\n\nExamples\n========\n\nFor examples look in the examples/ directory. You can execute the examples using node.\n\n $ cd examples\n $ node queries.js\n\nGridStore\n=========\n\nThe GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition.\n\nFor more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)\n\nReplicasets\n===========\nFor more information about how to connect to a replicaset have a look at [Replicasets](https://github.com/mongodb/node-mongodb-native/blob/master/docs/replicaset.md)\n\nPrimary Key Factories\n---------------------\n\nDefining your own primary key factory allows you to generate your own series of id's\n(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long \"string\".\n\nSimple example below\n\n```javascript\n // Custom factory (need to provide a 12 byte array);\n CustomPKFactory = function() {}\n CustomPKFactory.prototype = new Object();\n CustomPKFactory.createPk = function() {\n return new ObjectID(\"aaaaaaaaaaaa\");\n }\n\n var p_client = new Db('integration_tests_20', new Server(\"127.0.0.1\", 27017, {}), {'pk':CustomPKFactory});\n p_client.open(function(err, p_client) {\n p_client.dropDatabase(function(err, done) {\n p_client.createCollection('test_custom_key', function(err, collection) {\n collection.insert({'a':1}, function(err, docs) {\n collection.find({'_id':new ObjectID(\"aaaaaaaaaaaa\")}, function(err, cursor) {\n cursor.toArray(function(err, items) {\n test.assertEquals(1, items.length);\n\n // Let's close the db\n p_client.close();\n });\n });\n });\n });\n });\n });\n```\n\nStrict mode\n-----------\n\nEach database has an optional strict mode. If it is set then asking for a collection\nthat does not exist will return an Error object in the callback. Similarly if you\nattempt to create a collection that already exists. Strict is provided for convenience.\n\n```javascript\n var error_client = new Db('integration_tests_', new Server(\"127.0.0.1\", 27017, {auto_reconnect: false}), {strict:true});\n test.assertEquals(true, error_client.strict);\n\n error_client.open(function(err, error_client) {\n error_client.collection('does-not-exist', function(err, collection) {\n test.assertTrue(err instanceof Error);\n test.assertEquals(\"Collection does-not-exist does not exist. Currently in strict mode.\", err.message);\n });\n\n error_client.createCollection('test_strict_access_collection', function(err, collection) {\n error_client.collection('test_strict_access_collection', function(err, collection) {\n test.assertTrue(collection instanceof Collection);\n // Let's close the db\n error_client.close();\n });\n });\n });\n```\n\nDocumentation\n=============\n\nIf this document doesn't answer your questions, see the source of\n[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js)\nor [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js),\nor the documentation at MongoDB for query and update formats.\n\nFind\n----\n\nThe find method is actually a factory method to create\nCursor objects. A Cursor lazily uses the connection the first time\nyou call `nextObject`, `each`, or `toArray`.\n\nThe basic operation on a cursor is the `nextObject` method\nthat fetches the next matching document from the database. The convenience\nmethods `each` and `toArray` call `nextObject` until the cursor is exhausted.\n\nSignatures:\n\n```javascript\n var cursor = collection.find(query, [fields], options);\n cursor.sort(fields).limit(n).skip(m).\n\n cursor.nextObject(function(err, doc) {});\n cursor.each(function(err, doc) {});\n cursor.toArray(function(err, docs) {});\n\n cursor.rewind() // reset the cursor to its initial state.\n```\n\nUseful chainable methods of cursor. These can optionally be options of `find` instead of method calls:\n\n* `.limit(n).skip(m)` to control paging.\n* `.sort(fields)` Order by the given fields. There are several equivalent syntaxes:\n * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2.\n * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above\n * `.sort([['field1', 'desc'], 'field2'])` same as above\n * `.sort('field1')` ascending by field1\n\nOther options of `find`:\n\n* `fields` the fields to fetch (to avoid transferring the entire document)\n* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors).\n* `batchSize` The number of the subset of results to request the database\nto return for every request. This should initially be greater than 1 otherwise\nthe database will automatically close the cursor. The batch size can be set to 1\nwith `batchSize(n, function(err){})` after performing the initial query to the database.\n* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint).\n* `explain` turns this into an explain query. You can also call\n`explain()` on any cursor to fetch the explanation.\n* `snapshot` prevents documents that are updated while the query is active\nfrom being returned multiple times. See more\n[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database).\n* `timeout` if false, asks MongoDb not to time out this cursor after an\ninactivity period.\n\n\nFor information on how to create queries, see the\n[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.find({}, {limit:10}).toArray(function(err, docs) {\n console.dir(docs);\n });\n });\n```\n\nInsert\n------\n\nSignature:\n\n```javascript\n collection.insert(docs, options, [callback]);\n```\n\nwhere `docs` can be a single document or an array of documents.\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n\nSee also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting).\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.insert({hello: 'world'}, {safe:true},\n function(err, objects) {\n if (err) console.warn(err.message);\n if (err && err.message.indexOf('E11000 ') !== -1) {\n // this _id was already inserted in the database\n }\n });\n });\n```\n\nNote that there's no reason to pass a callback to the insert or update commands\nunless you use the `safe:true` option. If you don't specify `safe:true`, then\nyour callback will be called immediately.\n\nUpdate; update and insert (upsert)\n----------------------------------\n\nThe update operation will update the first document that matches your query\n(or all documents that match if you use `multi:true`).\nIf `safe:true`, `upsert` is not set, and no documents match, your callback will return 0 documents updated.\n\nSee the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for\nthe modifier (`$inc`, `$set`, `$push`, etc.) formats.\n\nSignature:\n\n```javascript\n collection.update(criteria, objNew, options, [callback]);\n```\n\nUseful options:\n\n* `safe:true` Should always set if you have a callback.\n* `multi:true` If set, all matching documents are updated, not just the first.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `update`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.update({hi: 'here'}, {$set: {hi: 'there'}}, {safe:true},\n function(err) {\n if (err) console.warn(err.message);\n else console.log('successfully updated');\n });\n });\n```\n\nFind and modify\n---------------\n\n`findAndModify` is like `update`, but it also gives the updated document to\nyour callback. But there are a few key differences between findAndModify and\nupdate:\n\n 1. The signatures differ.\n 2. You can only findAndModify a single item, not multiple items.\n\nSignature:\n\n```javascript\n collection.findAndModify(query, sort, update, options, callback)\n```\n\nThe sort parameter is used to specify which object to operate on, if more than\none document matches. It takes the same format as the cursor sort (see\nConnection.find above).\n\nSee the\n[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command)\nfor more details.\n\nUseful options:\n\n* `remove:true` set to a true to remove the object before returning\n* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove.\n* `upsert:true` Atomically inserts the document if no documents matched.\n\nExample for `findAndModify`:\n\n```javascript\n var mongodb = require('mongodb');\n var server = new mongodb.Server(\"127.0.0.1\", 27017, {});\n new mongodb.Db('test', server, {w: 1}).open(function (error, client) {\n if (error) throw error;\n var collection = new mongodb.Collection(client, 'test_collection');\n collection.findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {},\n function(err, object) {\n if (err) console.warn(err.message);\n else console.dir(object); // undefined if no matching object exists.\n });\n });\n```\n\nSave\n----\n\nThe `save` method is a shorthand for upsert if the document contains an\n`_id`, or an insert if there is no `_id`.\n\nSponsors\n========\nJust as Felix Geisendörfer I'm also working on the driver for my own startup and this driver is a big project that also benefits other companies who are using MongoDB.\n\nIf your company could benefit from a even better-engineered node.js mongodb driver I would appreciate any type of sponsorship you may be able to provide. All the sponsors will get a lifetime display in this readme, priority support and help on problems and votes on the roadmap decisions for the driver. If you are interested contact me on [christkv AT g m a i l.com](mailto:christkv@gmail.com) for details.\n\nAnd I'm very thankful for code contributions. If you are interested in working on features please contact me so we can discuss API design and testing.\n\nRelease Notes\n=============\n\nSee HISTORY\n\nCredits\n=======\n\n1. [10gen](http://github.com/mongodb/mongo-ruby-driver/)\n2. [Google Closure Library](http://code.google.com/closure/library/)\n3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser)\n\nContributors\n============\n\nAaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy\n\nLicense\n=======\n\n Copyright 2009 - 2012 Christian Amor Kvalheim.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n", - "readmeFilename": "Readme.md", - "_id": "mongodb@1.2.14", - "_from": "mongodb@1.2.14" -} diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp b/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp deleted file mode 100644 index 1554dc3238d..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_weird_bug_streamed.tmp and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp b/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp deleted file mode 100644 index 74cba0de8ca..00000000000 Binary files a/frontend/express/node_modules/mongoskin/node_modules/mongodb/test_gs_working_field_read.tmp and /dev/null differ diff --git a/frontend/express/node_modules/mongoskin/node_modules/mongodb/upload.py b/frontend/express/node_modules/mongoskin/node_modules/mongodb/upload.py deleted file mode 100644 index 6296fdeddd2..00000000000 --- a/frontend/express/node_modules/mongoskin/node_modules/mongodb/upload.py +++ /dev/null @@ -1,2347 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 -# -# Copyright 2007 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tool for uploading diffs from a version control system to the codereview app. - -Usage summary: upload.py [options] [-- diff_options] [path...] - -Diff options are passed to the diff command of the underlying system. - -Supported version control systems: - Git - Mercurial - Subversion - Perforce - CVS - -It is important for Git/Mercurial users to specify a tree/node/branch to diff -against by using the '--rev' option. -""" -# This code is derived from appcfg.py in the App Engine SDK (open source), -# and from ASPN recipe #146306. - -import ConfigParser -import cookielib -import errno -import fnmatch -import getpass -import logging -import marshal -import mimetypes -import optparse -import os -import re -import socket -import subprocess -import sys -import urllib -import urllib2 -import urlparse - -# The md5 module was deprecated in Python 2.5. -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - -try: - import readline -except ImportError: - pass - -try: - import keyring -except ImportError: - keyring = None - -# The logging verbosity: -# 0: Errors only. -# 1: Status messages. -# 2: Info logs. -# 3: Debug logs. -verbosity = 1 - -# The account type used for authentication. -# This line could be changed by the review server (see handler for -# upload.py). -AUTH_ACCOUNT_TYPE = "HOSTED" - -# URL of the default review server. As for AUTH_ACCOUNT_TYPE, this line could be -# changed by the review server (see handler for upload.py). -DEFAULT_REVIEW_SERVER = "codereview.10gen.com" - -# Max size of patch or base file. -MAX_UPLOAD_SIZE = 900 * 1024 - -# Constants for version control names. Used by GuessVCSName. -VCS_GIT = "Git" -VCS_MERCURIAL = "Mercurial" -VCS_SUBVERSION = "Subversion" -VCS_PERFORCE = "Perforce" -VCS_CVS = "CVS" -VCS_UNKNOWN = "Unknown" - -VCS_ABBREVIATIONS = { - VCS_MERCURIAL.lower(): VCS_MERCURIAL, - "hg": VCS_MERCURIAL, - VCS_SUBVERSION.lower(): VCS_SUBVERSION, - "svn": VCS_SUBVERSION, - VCS_PERFORCE.lower(): VCS_PERFORCE, - "p4": VCS_PERFORCE, - VCS_GIT.lower(): VCS_GIT, - VCS_CVS.lower(): VCS_CVS, -} - -# The result of parsing Subversion's [auto-props] setting. -svn_auto_props_map = None - -def GetEmail(prompt): - """Prompts the user for their email address and returns it. - - The last used email address is saved to a file and offered up as a suggestion - to the user. If the user presses enter without typing in anything the last - used email address is used. If the user enters a new address, it is saved - for next time we prompt. - - """ - last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") - last_email = "" - if os.path.exists(last_email_file_name): - try: - last_email_file = open(last_email_file_name, "r") - last_email = last_email_file.readline().strip("\n") - last_email_file.close() - prompt += " [%s]" % last_email - except IOError, e: - pass - email = raw_input(prompt + ": ").strip() - if email: - try: - last_email_file = open(last_email_file_name, "w") - last_email_file.write(email) - last_email_file.close() - except IOError, e: - pass - else: - email = last_email - return email - - -def StatusUpdate(msg): - """Print a status message to stdout. - - If 'verbosity' is greater than 0, print the message. - - Args: - msg: The string to print. - """ - if verbosity > 0: - print msg - - -def ErrorExit(msg): - """Print an error message to stderr and exit.""" - print >>sys.stderr, msg - sys.exit(1) - - -class ClientLoginError(urllib2.HTTPError): - """Raised to indicate there was an error authenticating with ClientLogin.""" - - def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) - self.args = args - self.reason = args["Error"] - self.info = args.get("Info", None) - - -class AbstractRpcServer(object): - """Provides a common interface for a simple RPC server.""" - - def __init__(self, host, auth_function, host_override=None, extra_headers={}, - save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): - """Creates a new HttpRpcServer. - - Args: - host: The host to send requests to. - auth_function: A function that takes no arguments and returns an - (email, password) tuple when called. Will be called if authentication - is required. - host_override: The host header to send to the server (defaults to host). - extra_headers: A dict of extra headers to append to every request. - save_cookies: If True, save the authentication cookies to local disk. - If False, use an in-memory cookiejar instead. Subclasses must - implement this functionality. Defaults to False. - account_type: Account type used for authentication. Defaults to - AUTH_ACCOUNT_TYPE. - """ - self.host = host - if (not self.host.startswith("http://") and - not self.host.startswith("https://")): - self.host = "http://" + self.host - self.host_override = host_override - self.auth_function = auth_function - self.authenticated = False - self.extra_headers = extra_headers - self.save_cookies = save_cookies - self.account_type = account_type - self.opener = self._GetOpener() - if self.host_override: - logging.info("Server: %s; Host: %s", self.host, self.host_override) - else: - logging.info("Server: %s", self.host) - - def _GetOpener(self): - """Returns an OpenerDirector for making HTTP requests. - - Returns: - A urllib2.OpenerDirector object. - """ - raise NotImplementedError() - - def _CreateRequest(self, url, data=None): - """Creates a new urllib request.""" - logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data, headers={"Accept": "text/plain"}) - if self.host_override: - req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): - req.add_header(key, value) - return req - - def _GetAuthToken(self, email, password): - """Uses ClientLogin to authenticate the user, returning an auth token. - - Args: - email: The user's email address - password: The user's password - - Raises: - ClientLoginError: If there was an error authenticating with ClientLogin. - HTTPError: If there was some other form of HTTP error. - - Returns: - The authentication token returned by ClientLogin. - """ - account_type = self.account_type - if self.host.endswith(".google.com"): - # Needed for use inside Google. - account_type = "HOSTED" - req = self._CreateRequest( - url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ - "Email": email, - "Passwd": password, - "service": "ah", - "source": "rietveld-codereview-upload", - "accountType": account_type, - }), - ) - try: - response = self.opener.open(req) - response_body = response.read() - response_dict = dict(x.split("=") - for x in response_body.split("\n") if x) - return response_dict["Auth"] - except urllib2.HTTPError, e: - if e.code == 403: - body = e.read() - response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) - raise ClientLoginError(req.get_full_url(), e.code, e.msg, - e.headers, response_dict) - else: - raise - - def _GetAuthCookie(self, auth_token): - """Fetches authentication cookies for an authentication token. - - Args: - auth_token: The authentication token returned by ClientLogin. - - Raises: - HTTPError: If there was an error fetching the authentication cookies. - """ - # This is a dummy value to allow us to identify when we're successful. - continue_location = "http://localhost/" - args = {"continue": continue_location, "auth": auth_token} - req = self._CreateRequest("%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) - try: - response = self.opener.open(req) - except urllib2.HTTPError, e: - response = e - if (response.code != 302 or - response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) - self.authenticated = True - - def _Authenticate(self): - """Authenticates the user. - - The authentication process works as follows: - 1) We get a username and password from the user - 2) We use ClientLogin to obtain an AUTH token for the user - (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). - 3) We pass the auth token to /_ah/login on the server to obtain an - authentication cookie. If login was successful, it tries to redirect - us to the URL we provided. - - If we attempt to access the upload API without first obtaining an - authentication cookie, it returns a 401 response (or a 302) and - directs us to authenticate ourselves with ClientLogin. - """ - for i in range(3): - credentials = self.auth_function() - try: - auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: - print >>sys.stderr, '' - if e.reason == "BadAuthentication": - if e.info == "InvalidSecondFactor": - print >>sys.stderr, ( - "Use an application-specific password instead " - "of your regular account password.\n" - "See http://www.google.com/" - "support/accounts/bin/answer.py?answer=185833") - else: - print >>sys.stderr, "Invalid username or password." - elif e.reason == "CaptchaRequired": - print >>sys.stderr, ( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.\n" - "If you are using a Google Apps account the URL is:\n" - "https://www.google.com/a/yourdomain.com/UnlockCaptcha") - elif e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." - elif e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." - elif e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." - elif e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." - break - elif e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") - elif e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." - else: - # Unknown error. - raise - print >>sys.stderr, '' - continue - self._GetAuthCookie(auth_token) - return - - def Send(self, request_path, payload=None, - content_type="application/octet-stream", - timeout=None, - extra_headers=None, - **kwargs): - """Sends an RPC and returns the response. - - Args: - request_path: The path to send the request to, eg /api/appversion/create. - payload: The body of the request, or None to send an empty request. - content_type: The Content-Type header to use. - timeout: timeout in seconds; default None i.e. no timeout. - (Note: for large requests on OS X, the timeout doesn't work right.) - extra_headers: Dict containing additional HTTP headers that should be - included in the request (string header names mapped to their values), - or None to not include any additional headers. - kwargs: Any keyword arguments are converted into query string parameters. - - Returns: - The response body, as a string. - """ - # TODO: Don't require authentication. Let the server say - # whether it is necessary. - if not self.authenticated: - self._Authenticate() - - old_timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) - try: - tries = 0 - while True: - tries += 1 - args = dict(kwargs) - url = "%s%s" % (self.host, request_path) - if args: - url += "?" + urllib.urlencode(args) - req = self._CreateRequest(url=url, data=payload) - req.add_header("Content-Type", content_type) - if extra_headers: - for header, value in extra_headers.items(): - req.add_header(header, value) - try: - f = self.opener.open(req) - response = f.read() - f.close() - return response - except urllib2.HTTPError, e: - if tries > 3: - raise - elif e.code == 401 or e.code == 302: - self._Authenticate() - elif e.code == 301: - # Handle permanent redirect manually. - url = e.info()["location"] - url_loc = urlparse.urlparse(url) - self.host = '%s://%s' % (url_loc[0], url_loc[1]) - elif e.code >= 500: - ErrorExit(e.read()) - else: - raise - finally: - socket.setdefaulttimeout(old_timeout) - - -class HttpRpcServer(AbstractRpcServer): - """Provides a simplified RPC-style interface for HTTP requests.""" - - def _Authenticate(self): - """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() - if self.save_cookies: - StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) - self.cookie_jar.save() - - def _GetOpener(self): - """Returns an OpenerDirector that supports cookies and ignores redirects. - - Returns: - A urllib2.OpenerDirector object. - """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) - if self.save_cookies: - self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) - if os.path.exists(self.cookie_file): - try: - self.cookie_jar.load() - self.authenticated = True - StatusUpdate("Loaded authentication cookies from %s" % - self.cookie_file) - except (cookielib.LoadError, IOError): - # Failed to load cookies - just ignore them. - pass - else: - # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) - os.close(fd) - # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) - else: - # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) - return opener - - -class CondensedHelpFormatter(optparse.IndentedHelpFormatter): - """Frees more horizontal space by removing indentation from group - options and collapsing arguments between short and long, e.g. - '-o ARG, --opt=ARG' to -o --opt ARG""" - - def format_heading(self, heading): - return "%s:\n" % heading - - def format_option(self, option): - self.dedent() - res = optparse.HelpFormatter.format_option(self, option) - self.indent() - return res - - def format_option_strings(self, option): - self.set_long_opt_delimiter(" ") - optstr = optparse.HelpFormatter.format_option_strings(self, option) - optlist = optstr.split(", ") - if len(optlist) > 1: - if option.takes_value(): - # strip METAVAR from all but the last option - optlist = [x.split()[0] for x in optlist[:-1]] + optlist[-1:] - optstr = " ".join(optlist) - return optstr - - -parser = optparse.OptionParser( - usage="%prog [options] [-- diff_options] [path...]", - add_help_option=False, - formatter=CondensedHelpFormatter() -) -parser.add_option("-h", "--help", action="store_true", - help="Show this help message and exit.") -parser.add_option("-y", "--assume_yes", action="store_true", - dest="assume_yes", default=False, - help="Assume that the answer to yes/no questions is 'yes'.") -# Logging -group = parser.add_option_group("Logging options") -group.add_option("-q", "--quiet", action="store_const", const=0, - dest="verbose", help="Print errors only.") -group.add_option("-v", "--verbose", action="store_const", const=2, - dest="verbose", default=1, - help="Print info level logs.") -group.add_option("--noisy", action="store_const", const=3, - dest="verbose", help="Print all logs.") -group.add_option("--print_diffs", dest="print_diffs", action="store_true", - help="Print full diffs.") -# Review server -group = parser.add_option_group("Review server options") -group.add_option("-s", "--server", action="store", dest="server", - default=DEFAULT_REVIEW_SERVER, - metavar="SERVER", - help=("The server to upload to. The format is host[:port]. " - "Defaults to '%default'.")) -group.add_option("-e", "--email", action="store", dest="email", - metavar="EMAIL", default=None, - help="The username to use. Will prompt if omitted.") -group.add_option("-H", "--host", action="store", dest="host", - metavar="HOST", default=None, - help="Overrides the Host header sent with all RPCs.") -group.add_option("--no_cookies", action="store_false", - dest="save_cookies", default=True, - help="Do not save authentication cookies to local disk.") -group.add_option("--account_type", action="store", dest="account_type", - metavar="TYPE", default=AUTH_ACCOUNT_TYPE, - choices=["GOOGLE", "HOSTED"], - help=("Override the default account type " - "(defaults to '%default', " - "valid choices are 'GOOGLE' and 'HOSTED').")) -# Issue -group = parser.add_option_group("Issue options") -group.add_option("-t", "--title", action="store", dest="title", - help="New issue subject or new patch set title") -group.add_option("-m", "--message", action="store", dest="message", - default=None, - help="New issue description or new patch set message") -group.add_option("-F", "--file", action="store", dest="file", - default=None, help="Read the message above from file.") -group.add_option("-r", "--reviewers", action="store", dest="reviewers", - metavar="REVIEWERS", default=None, - help="Add reviewers (comma separated email addresses).") -group.add_option("--cc", action="store", dest="cc", - metavar="CC", default=None, - help="Add CC (comma separated email addresses).") -group.add_option("--private", action="store_true", dest="private", - default=False, - help="Make the issue restricted to reviewers and those CCed") -# Upload options -group = parser.add_option_group("Patch options") -group.add_option("-i", "--issue", type="int", action="store", - metavar="ISSUE", default=None, - help="Issue number to which to add. Defaults to new issue.") -group.add_option("--base_url", action="store", dest="base_url", default=None, - help="Base URL path for files (listed as \"Base URL\" when " - "viewing issue). If omitted, will be guessed automatically " - "for SVN repos and left blank for others.") -group.add_option("--download_base", action="store_true", - dest="download_base", default=False, - help="Base files will be downloaded by the server " - "(side-by-side diffs may not work on files with CRs).") -group.add_option("--rev", action="store", dest="revision", - metavar="REV", default=None, - help="Base revision/branch/tree to diff against. Use " - "rev1:rev2 range to review already committed changeset.") -group.add_option("--send_mail", action="store_true", - dest="send_mail", default=False, - help="Send notification email to reviewers.") -group.add_option("-p", "--send_patch", action="store_true", - dest="send_patch", default=False, - help="Same as --send_mail, but include diff as an " - "attachment, and prepend email subject with 'PATCH:'.") -group.add_option("--vcs", action="store", dest="vcs", - metavar="VCS", default=None, - help=("Version control system (optional, usually upload.py " - "already guesses the right VCS).")) -group.add_option("--emulate_svn_auto_props", action="store_true", - dest="emulate_svn_auto_props", default=False, - help=("Emulate Subversion's auto properties feature.")) -# Perforce-specific -group = parser.add_option_group("Perforce-specific options " - "(overrides P4 environment variables)") -group.add_option("--p4_port", action="store", dest="p4_port", - metavar="P4_PORT", default=None, - help=("Perforce server and port (optional)")) -group.add_option("--p4_changelist", action="store", dest="p4_changelist", - metavar="P4_CHANGELIST", default=None, - help=("Perforce changelist id")) -group.add_option("--p4_client", action="store", dest="p4_client", - metavar="P4_CLIENT", default=None, - help=("Perforce client/workspace")) -group.add_option("--p4_user", action="store", dest="p4_user", - metavar="P4_USER", default=None, - help=("Perforce user")) - -def GetRpcServer(server, email=None, host_override=None, save_cookies=True, - account_type=AUTH_ACCOUNT_TYPE): - """Returns an instance of an AbstractRpcServer. - - Args: - server: String containing the review server URL. - email: String containing user's email address. - host_override: If not None, string containing an alternate hostname to use - in the host header. - save_cookies: Whether authentication cookies should be saved to disk. - account_type: Account type for authentication, either 'GOOGLE' - or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. - - Returns: - A new AbstractRpcServer, on which RPC calls can be made. - """ - - rpc_server_class = HttpRpcServer - - # If this is the dev_appserver, use fake authentication. - host = (host_override or server).lower() - if re.match(r'(http://)?localhost([:/]|$)', host): - if email is None: - email = "test@example.com" - logging.info("Using debug user %s. Override with --email" % email) - server = rpc_server_class( - server, - lambda: (email, "password"), - host_override=host_override, - extra_headers={"Cookie": - 'dev_appserver_login="%s:False"' % email}, - save_cookies=save_cookies, - account_type=account_type) - # Don't try to talk to ClientLogin. - server.authenticated = True - return server - - def GetUserCredentials(): - """Prompts the user for a username and password.""" - # Create a local alias to the email variable to avoid Python's crazy - # scoping rules. - global keyring - local_email = email - if local_email is None: - local_email = GetEmail("Email (login for uploading to %s)" % server) - password = None - if keyring: - try: - password = keyring.get_password(host, local_email) - except: - # Sadly, we have to trap all errors here as - # gnomekeyring.IOError inherits from object. :/ - print "Failed to get password from keyring" - keyring = None - if password is not None: - print "Using password from system keyring." - else: - password = getpass.getpass("Password for %s: " % local_email) - if keyring: - answer = raw_input("Store password in system keyring?(y/N) ").strip() - if answer == "y": - keyring.set_password(host, local_email, password) - return (local_email, password) - - return rpc_server_class(server, - GetUserCredentials, - host_override=host_override, - save_cookies=save_cookies) - - -def EncodeMultipartFormData(fields, files): - """Encode form fields for multipart/form-data. - - Args: - fields: A sequence of (name, value) elements for regular form fields. - files: A sequence of (name, filename, value) elements for data to be - uploaded as files. - Returns: - (content_type, body) ready for httplib.HTTP instance. - - Source: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 - """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - for (key, value) in fields: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - for (key, filename, value) in files: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - lines.append('Content-Type: %s' % GetContentType(filename)) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - -def GetContentType(filename): - """Helper to guess the content-type from the filename.""" - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - -# Use a shell for subcommands on Windows to get a PATH search. -use_shell = sys.platform.startswith("win") - -def RunShellWithReturnCodeAndStderr(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout, stderr and the return code. - - Args: - command: Command to execute. - print_output: If True, the output is printed to stdout. - If False, both stdout and stderr are ignored. - universal_newlines: Use universal_newlines flag (default: True). - - Returns: - Tuple (stdout, stderr, return code) - """ - logging.info("Running %s", command) - env = env.copy() - env['LC_MESSAGES'] = 'C' - p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=use_shell, universal_newlines=universal_newlines, - env=env) - if print_output: - output_array = [] - while True: - line = p.stdout.readline() - if not line: - break - print line.strip("\n") - output_array.append(line) - output = "".join(output_array) - else: - output = p.stdout.read() - p.wait() - errout = p.stderr.read() - if print_output and errout: - print >>sys.stderr, errout - p.stdout.close() - p.stderr.close() - return output, errout, p.returncode - -def RunShellWithReturnCode(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout and the return code.""" - out, err, retcode = RunShellWithReturnCodeAndStderr(command, print_output, - universal_newlines, env) - return out, retcode - -def RunShell(command, silent_ok=False, universal_newlines=True, - print_output=False, env=os.environ): - data, retcode = RunShellWithReturnCode(command, print_output, - universal_newlines, env) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) - if not silent_ok and not data: - ErrorExit("No output from %s" % command) - return data - - -class VersionControlSystem(object): - """Abstract base class providing an interface to the VCS.""" - - def __init__(self, options): - """Constructor. - - Args: - options: Command line options. - """ - self.options = options - - def GetGUID(self): - """Return string to distinguish the repository from others, for example to - query all opened review issues for it""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def PostProcessDiff(self, diff): - """Return the diff with any special post processing this VCS needs, e.g. - to include an svn-style "Index:".""" - return diff - - def GenerateDiff(self, args): - """Return the current diff as a string. - - Args: - args: Extra arguments to pass to the diff command. - """ - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def CheckForUnknownFiles(self): - """Show an "are you sure?" prompt if there are unknown files.""" - unknown_files = self.GetUnknownFiles() - if unknown_files: - print "The following files are not added to version control:" - for line in unknown_files: - print line - prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() - if answer != "y": - ErrorExit("User aborted") - - def GetBaseFile(self, filename): - """Get the content of the upstream version of a file. - - Returns: - A tuple (base_content, new_content, is_binary, status) - base_content: The contents of the base file. - new_content: For text files, this is empty. For binary files, this is - the contents of the new file, since the diff output won't contain - information to reconstruct the current file. - is_binary: True iff the file is binary. - status: The status of the file. - """ - - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - - def GetBaseFiles(self, diff): - """Helper that calls GetBase file for each file in the patch. - - Returns: - A dictionary that maps from filename to GetBaseFile's tuple. Filenames - are retrieved based on lines that start with "Index:" or - "Property changes on:". - """ - files = {} - for line in diff.splitlines(True): - if line.startswith('Index:') or line.startswith('Property changes on:'): - unused, filename = line.split(':', 1) - # On Windows if a file has property changes its filename uses '\' - # instead of '/'. - filename = filename.strip().replace('\\', '/') - files[filename] = self.GetBaseFile(filename) - return files - - - def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, - files): - """Uploads the base files (and if necessary, the current ones as well).""" - - def UploadFile(filename, file_id, content, is_binary, status, is_base): - """Uploads a file to the server.""" - file_too_large = False - if is_base: - type = "base" - else: - type = "current" - if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % - (type, filename)) - file_too_large = True - content = "" - checksum = md5(content).hexdigest() - if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) - url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) - form_fields = [("filename", filename), - ("status", status), - ("checksum", checksum), - ("is_binary", str(is_binary)), - ("is_current", str(not is_base)), - ] - if file_too_large: - form_fields.append(("file_too_large", "1")) - if options.email: - form_fields.append(("user", options.email)) - ctype, body = EncodeMultipartFormData(form_fields, - [("data", filename, content)]) - response_body = rpc_server.Send(url, body, - content_type=ctype) - if not response_body.startswith("OK"): - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - - patches = dict() - [patches.setdefault(v, k) for k, v in patch_list] - for filename in patches.keys(): - base_content, new_content, is_binary, status = files[filename] - file_id_str = patches.get(filename) - if file_id_str.find("nobase") != -1: - base_content = None - file_id_str = file_id_str[file_id_str.rfind("_") + 1:] - file_id = int(file_id_str) - if base_content != None: - UploadFile(filename, file_id, base_content, is_binary, status, True) - if new_content != None: - UploadFile(filename, file_id, new_content, is_binary, status, False) - - def IsImage(self, filename): - """Returns true if the filename has an image extension.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False - return mimetype.startswith("image/") - - def IsBinaryData(self, data): - """Returns true if data contains a null byte.""" - # Derived from how Mercurial's heuristic, see - # http://selenic.com/hg/file/848a6658069e/mercurial/util.py#l229 - return bool(data and "\0" in data) - - -class SubversionVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Subversion.""" - - def __init__(self, options): - super(SubversionVCS, self).__init__(options) - if self.options.revision: - match = re.match(r"(\d+)(:(\d+))?", self.options.revision) - if not match: - ErrorExit("Invalid Subversion revision %s." % self.options.revision) - self.rev_start = match.group(1) - self.rev_end = match.group(3) - else: - self.rev_start = self.rev_end = None - # Cache output from "svn list -r REVNO dirname". - # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). - self.svnls_cache = {} - # Base URL is required to fetch files deleted in an older revision. - # Result is cached to not guess it over and over again in GetBaseFile(). - required = self.options.download_base or self.options.revision is not None - self.svn_base = self._GuessBase(required) - - def GetGUID(self): - return self._GetInfo("Repository UUID") - - def GuessBase(self, required): - """Wrapper for _GuessBase.""" - return self.svn_base - - def _GuessBase(self, required): - """Returns base URL for current diff. - - Args: - required: If true, exits if the url can't be guessed, otherwise None is - returned. - """ - url = self._GetInfo("URL") - if url: - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - guess = "" - # TODO(anatoli) - repository specific hacks should be handled by server - if netloc == "svn.python.org" and scheme == "svn+ssh": - path = "projects" + path - scheme = "http" - guess = "Python " - elif netloc.endswith(".googlecode.com"): - scheme = "http" - guess = "Google Code " - path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - logging.info("Guessed %sbase = %s", guess, base) - return base - if required: - ErrorExit("Can't find URL in output from svn info") - return None - - def _GetInfo(self, key): - """Parses 'svn info' for current dir. Returns value for key or None""" - for line in RunShell(["svn", "info"]).splitlines(): - if line.startswith(key + ": "): - return line.split(":", 1)[1].strip() - - def _EscapeFilename(self, filename): - """Escapes filename for SVN commands.""" - if "@" in filename and not filename.endswith("@"): - filename = "%s@" % filename - return filename - - def GenerateDiff(self, args): - cmd = ["svn", "diff"] - if self.options.revision: - cmd += ["-r", self.options.revision] - cmd.extend(args) - data = RunShell(cmd) - count = 0 - for line in data.splitlines(): - if line.startswith("Index:") or line.startswith("Property changes on:"): - count += 1 - logging.info(line) - if not count: - ErrorExit("No valid patches found in output from svn diff") - return data - - def _CollapseKeywords(self, content, keyword_str): - """Collapses SVN keywords.""" - # svn cat translates keywords but svn diff doesn't. As a result of this - # behavior patching.PatchChunks() fails with a chunk mismatch error. - # This part was originally written by the Review Board development team - # who had the same problem (http://reviews.review-board.org/r/276/). - # Mapping of keywords to known aliases - svn_keywords = { - # Standard keywords - 'Date': ['Date', 'LastChangedDate'], - 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], - 'Author': ['Author', 'LastChangedBy'], - 'HeadURL': ['HeadURL', 'URL'], - 'Id': ['Id'], - - # Aliases - 'LastChangedDate': ['LastChangedDate', 'Date'], - 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], - 'LastChangedBy': ['LastChangedBy', 'Author'], - 'URL': ['URL', 'HeadURL'], - } - - def repl(m): - if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) - return "$%s$" % m.group(1) - keywords = [keyword - for name in keyword_str.split(" ") - for keyword in svn_keywords.get(name, [])] - return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) - - def GetUnknownFiles(self): - status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) - unknown_files = [] - for line in status.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - - def ReadFile(self, filename): - """Returns the contents of a file.""" - file = open(filename, 'rb') - result = "" - try: - result = file.read() - finally: - file.close() - return result - - def GetStatus(self, filename): - """Returns the status of a file.""" - if not self.options.revision: - status = RunShell(["svn", "status", "--ignore-externals", - self._EscapeFilename(filename)]) - if not status: - ErrorExit("svn status returned no output for %s" % filename) - status_lines = status.splitlines() - # If file is in a cl, the output will begin with - # "\n--- Changelist 'cl_name':\n". See - # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt - if (len(status_lines) == 3 and - not status_lines[0] and - status_lines[1].startswith("--- Changelist")): - status = status_lines[2] - else: - status = status_lines[0] - # If we have a revision to diff against we need to run "svn list" - # for the old and the new revision and compare the results to get - # the correct status for a file. - else: - dirname, relfilename = os.path.split(filename) - if dirname not in self.svnls_cache: - cmd = ["svn", "list", "-r", self.rev_start, - self._EscapeFilename(dirname) or "."] - out, err, returncode = RunShellWithReturnCodeAndStderr(cmd) - if returncode: - # Directory might not yet exist at start revison - # svn: Unable to find repository location for 'abc' in revision nnn - if re.match('^svn: Unable to find repository location for .+ in revision \d+', err): - old_files = () - else: - ErrorExit("Failed to get status for %s:\n%s" % (filename, err)) - else: - old_files = out.splitlines() - args = ["svn", "list"] - if self.rev_end: - args += ["-r", self.rev_end] - cmd = args + [self._EscapeFilename(dirname) or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to run command %s" % cmd) - self.svnls_cache[dirname] = (old_files, out.splitlines()) - old_files, new_files = self.svnls_cache[dirname] - if relfilename in old_files and relfilename not in new_files: - status = "D " - elif relfilename in old_files and relfilename in new_files: - status = "M " - else: - status = "A " - return status - - def GetBaseFile(self, filename): - status = self.GetStatus(filename) - base_content = None - new_content = None - - # If a file is copied its status will be "A +", which signifies - # "addition-with-history". See "svn st" for more information. We need to - # upload the original file or else diff parsing will fail if the file was - # edited. - if status[0] == "A" and status[3] != "+": - # We'll need to upload the new content if we're adding a binary file - # since diff's output won't contain it. - mimetype = RunShell(["svn", "propget", "svn:mime-type", - self._EscapeFilename(filename)], silent_ok=True) - base_content = "" - is_binary = bool(mimetype) and not mimetype.startswith("text/") - if is_binary and self.IsImage(filename): - new_content = self.ReadFile(filename) - elif (status[0] in ("M", "D", "R") or - (status[0] == "A" and status[3] == "+") or # Copied file. - (status[0] == " " and status[1] == "M")): # Property change. - args = [] - if self.options.revision: - # filename must not be escaped. We already add an ampersand here. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - # Don't change filename, it's needed later. - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:mime-type", url] - mimetype, returncode = RunShellWithReturnCode(cmd) - if returncode: - # File does not exist in the requested revision. - # Reset mimetype, it contains an error message. - mimetype = "" - else: - mimetype = mimetype.strip() - get_base = False - # this test for binary is exactly the test prescribed by the - # official SVN docs at - # http://subversion.apache.org/faq.html#binary-files - is_binary = (bool(mimetype) and - not mimetype.startswith("text/") and - mimetype not in ("image/x-xbitmap", "image/x-xpixmap")) - if status[0] == " ": - # Empty base content just to force an upload. - base_content = "" - elif is_binary: - if self.IsImage(filename): - get_base = True - if status[0] == "M": - if not self.rev_end: - new_content = self.ReadFile(filename) - else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) - new_content = RunShell(["svn", "cat", url], - universal_newlines=True, silent_ok=True) - else: - base_content = "" - else: - get_base = True - - if get_base: - if is_binary: - universal_newlines = False - else: - universal_newlines = True - if self.rev_start: - # "svn cat -r REV delete_file.txt" doesn't work. cat requires - # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - else: - base_content, ret_code = RunShellWithReturnCode( - ["svn", "cat", self._EscapeFilename(filename)], - universal_newlines=universal_newlines) - if ret_code and status[0] == "R": - # It's a replaced file without local history (see issue208). - # The base file needs to be fetched from the server. - url = "%s/%s" % (self.svn_base, filename) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - elif ret_code: - ErrorExit("Got error status from 'svn cat %s'" % filename) - if not is_binary: - args = [] - if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:keywords", url] - keywords, returncode = RunShellWithReturnCode(cmd) - if keywords and not returncode: - base_content = self._CollapseKeywords(base_content, keywords) - else: - StatusUpdate("svn status returned unexpected output: %s" % status) - sys.exit(1) - return base_content, new_content, is_binary, status[0:5] - - -class GitVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Git.""" - - def __init__(self, options): - super(GitVCS, self).__init__(options) - # Map of filename -> (hash before, hash after) of base file. - # Hashes for "no such file" are represented as None. - self.hashes = {} - # Map of new filename -> old filename for renames. - self.renames = {} - - def GetGUID(self): - revlist = RunShell("git rev-list --parents HEAD".split()).splitlines() - # M-A: Return the 1st root hash, there could be multiple when a - # subtree is merged. In that case, more analysis would need to - # be done to figure out which HEAD is the 'most representative'. - for r in revlist: - if ' ' not in r: - return r - - def PostProcessDiff(self, gitdiff): - """Converts the diff output to include an svn-style "Index:" line as well - as record the hashes of the files, so we can upload them along with our - diff.""" - # Special used by git to indicate "no such content". - NULL_HASH = "0"*40 - - def IsFileNew(filename): - return filename in self.hashes and self.hashes[filename][0] is None - - def AddSubversionPropertyChange(filename): - """Add svn's property change information into the patch if given file is - new file. - - We use Subversion's auto-props setting to retrieve its property. - See http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2 for - Subversion's [auto-props] setting. - """ - if self.options.emulate_svn_auto_props and IsFileNew(filename): - svnprops = GetSubversionPropertyChanges(filename) - if svnprops: - svndiff.append("\n" + svnprops + "\n") - - svndiff = [] - filecount = 0 - filename = None - for line in gitdiff.splitlines(): - match = re.match(r"diff --git a/(.*) b/(.*)$", line) - if match: - # Add auto property here for previously seen file. - if filename is not None: - AddSubversionPropertyChange(filename) - filecount += 1 - # Intentionally use the "after" filename so we can show renames. - filename = match.group(2) - svndiff.append("Index: %s\n" % filename) - if match.group(1) != match.group(2): - self.renames[match.group(2)] = match.group(1) - else: - # The "index" line in a git diff looks like this (long hashes elided): - # index 82c0d44..b2cee3f 100755 - # We want to save the left hash, as that identifies the base file. - match = re.match(r"index (\w+)\.\.(\w+)", line) - if match: - before, after = (match.group(1), match.group(2)) - if before == NULL_HASH: - before = None - if after == NULL_HASH: - after = None - self.hashes[filename] = (before, after) - svndiff.append(line + "\n") - if not filecount: - ErrorExit("No valid patches found in output from git diff") - # Add auto property for the last seen file. - assert filename is not None - AddSubversionPropertyChange(filename) - return "".join(svndiff) - - def GenerateDiff(self, extra_args): - extra_args = extra_args[:] - if self.options.revision: - if ":" in self.options.revision: - extra_args = self.options.revision.split(":", 1) + extra_args - else: - extra_args = [self.options.revision] + extra_args - - # --no-ext-diff is broken in some versions of Git, so try to work around - # this by overriding the environment (but there is still a problem if the - # git config key "diff.external" is used). - env = os.environ.copy() - if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] - return RunShell( - [ "git", "diff", "--no-color", "--no-ext-diff", "--full-index", - "--ignore-submodules", "-M"] + extra_args, - env=env) - - def GetUnknownFiles(self): - status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], - silent_ok=True) - return status.splitlines() - - def GetFileContent(self, file_hash, is_binary): - """Returns the content of a file identified by its git hash.""" - data, retcode = RunShellWithReturnCode(["git", "show", file_hash], - universal_newlines=not is_binary) - if retcode: - ErrorExit("Got error status from 'git show %s'" % file_hash) - return data - - def GetBaseFile(self, filename): - hash_before, hash_after = self.hashes.get(filename, (None,None)) - base_content = None - new_content = None - status = None - - if filename in self.renames: - status = "A +" # Match svn attribute name for renames. - if filename not in self.hashes: - # If a rename doesn't change the content, we never get a hash. - base_content = RunShell( - ["git", "show", "HEAD:" + filename], silent_ok=True) - elif not hash_before: - status = "A" - base_content = "" - elif not hash_after: - status = "D" - else: - status = "M" - - is_binary = self.IsBinaryData(base_content) - is_image = self.IsImage(filename) - - # Grab the before/after content if we need it. - # We should include file contents if it's text or it's an image. - if not is_binary or is_image: - # Grab the base content if we don't have it already. - if base_content is None and hash_before: - base_content = self.GetFileContent(hash_before, is_binary) - # Only include the "after" file if it's an image; otherwise it - # it is reconstructed from the diff. - if is_image and hash_after: - new_content = self.GetFileContent(hash_after, is_binary) - - return (base_content, new_content, is_binary, status) - - -class CVSVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for CVS.""" - - def __init__(self, options): - super(CVSVCS, self).__init__(options) - - def GetGUID(self): - """For now we don't know how to get repository ID for CVS""" - return - - def GetOriginalContent_(self, filename): - RunShell(["cvs", "up", filename], silent_ok=True) - # TODO need detect file content encoding - content = open(filename).read() - return content.replace("\r\n", "\n") - - def GetBaseFile(self, filename): - base_content = None - new_content = None - status = "A" - - output, retcode = RunShellWithReturnCode(["cvs", "status", filename]) - if retcode: - ErrorExit("Got error status from 'cvs status %s'" % filename) - - if output.find("Status: Locally Modified") != -1: - status = "M" - temp_filename = "%s.tmp123" % filename - os.rename(filename, temp_filename) - base_content = self.GetOriginalContent_(filename) - os.rename(temp_filename, filename) - elif output.find("Status: Locally Added"): - status = "A" - base_content = "" - elif output.find("Status: Needs Checkout"): - status = "D" - base_content = self.GetOriginalContent_(filename) - - return (base_content, new_content, self.IsBinaryData(base_content), status) - - def GenerateDiff(self, extra_args): - cmd = ["cvs", "diff", "-u", "-N"] - if self.options.revision: - cmd += ["-r", self.options.revision] - - cmd.extend(extra_args) - data, retcode = RunShellWithReturnCode(cmd) - count = 0 - if retcode in [0, 1]: - for line in data.splitlines(): - if line.startswith("Index:"): - count += 1 - logging.info(line) - - if not count: - ErrorExit("No valid patches found in output from cvs diff") - - return data - - def GetUnknownFiles(self): - data, retcode = RunShellWithReturnCode(["cvs", "diff"]) - if retcode not in [0, 1]: - ErrorExit("Got error status from 'cvs diff':\n%s" % (data,)) - unknown_files = [] - for line in data.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - -class MercurialVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Mercurial.""" - - def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) - # Absolute path to repository (we can be in a subdir) - self.repo_dir = os.path.normpath(repo_dir) - # Compute the subdir - cwd = os.path.normpath(os.getcwd()) - assert cwd.startswith(self.repo_dir) - self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") - if self.options.revision: - self.base_rev = self.options.revision - else: - self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() - - def GetGUID(self): - # See chapter "Uniquely identifying a repository" - # http://hgbook.red-bean.com/read/customizing-the-output-of-mercurial.html - info = RunShell("hg log -r0 --template {node}".split()) - return info.strip() - - def _GetRelPath(self, filename): - """Get relative path of a file according to the current directory, - given its logical path in the repo.""" - absname = os.path.join(self.repo_dir, filename) - return os.path.relpath(absname) - - def GenerateDiff(self, extra_args): - cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args - data = RunShell(cmd, silent_ok=True) - svndiff = [] - filecount = 0 - for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) - if m: - # Modify line to make it look like as it comes from svn diff. - # With this modification no changes on the server side are required - # to make upload.py work with Mercurial repos. - # NOTE: for proper handling of moved/copied files, we have to use - # the second filename. - filename = m.group(2) - svndiff.append("Index: %s" % filename) - svndiff.append("=" * 67) - filecount += 1 - logging.info(line) - else: - svndiff.append(line) - if not filecount: - ErrorExit("No valid patches found in output from hg diff") - return "\n".join(svndiff) + "\n" - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - args = [] - status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], - silent_ok=True) - unknown_files = [] - for line in status.splitlines(): - st, fn = line.split(" ", 1) - if st == "?": - unknown_files.append(fn) - return unknown_files - - def GetBaseFile(self, filename): - # "hg status" and "hg cat" both take a path relative to the current subdir, - # but "hg diff" has given us the path relative to the repo root. - base_content = "" - new_content = None - is_binary = False - oldrelpath = relpath = self._GetRelPath(filename) - # "hg status -C" returns two lines for moved/copied files, one otherwise - out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) - out = out.splitlines() - # HACK: strip error message about missing file/directory if it isn't in - # the working copy - if out[0].startswith('%s: ' % relpath): - out = out[1:] - status, _ = out[0].split(' ', 1) - if len(out) > 1 and status == "A": - # Moved/copied => considered as modified, use old filename to - # retrieve base contents - oldrelpath = out[1].strip() - status = "M" - if ":" in self.base_rev: - base_rev = self.base_rev.split(":", 1)[0] - else: - base_rev = self.base_rev - if status != "A": - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True) - is_binary = self.IsBinaryData(base_content) - if status != "R": - new_content = open(relpath, "rb").read() - is_binary = is_binary or self.IsBinaryData(new_content) - if is_binary and base_content: - # Fetch again without converting newlines - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True, universal_newlines=False) - if not is_binary or not self.IsImage(relpath): - new_content = None - return base_content, new_content, is_binary, status - - -class PerforceVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Perforce.""" - - def __init__(self, options): - - def ConfirmLogin(): - # Make sure we have a valid perforce session - while True: - data, retcode = self.RunPerforceCommandWithReturnCode( - ["login", "-s"], marshal_output=True) - if not data: - ErrorExit("Error checking perforce login") - if not retcode and (not "code" in data or data["code"] != "error"): - break - print "Enter perforce password: " - self.RunPerforceCommandWithReturnCode(["login"]) - - super(PerforceVCS, self).__init__(options) - - self.p4_changelist = options.p4_changelist - if not self.p4_changelist: - ErrorExit("A changelist id is required") - if (options.revision): - ErrorExit("--rev is not supported for perforce") - - self.p4_port = options.p4_port - self.p4_client = options.p4_client - self.p4_user = options.p4_user - - ConfirmLogin() - - if not options.title: - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - if description and "desc" in description: - # Rietveld doesn't support multi-line descriptions - raw_title = description["desc"].strip() - lines = raw_title.splitlines() - if len(lines): - options.title = lines[0] - - def GetGUID(self): - """For now we don't know how to get repository ID for Perforce""" - return - - def RunPerforceCommandWithReturnCode(self, extra_args, marshal_output=False, - universal_newlines=True): - args = ["p4"] - if marshal_output: - # -G makes perforce format its output as marshalled python objects - args.extend(["-G"]) - if self.p4_port: - args.extend(["-p", self.p4_port]) - if self.p4_client: - args.extend(["-c", self.p4_client]) - if self.p4_user: - args.extend(["-u", self.p4_user]) - args.extend(extra_args) - - data, retcode = RunShellWithReturnCode( - args, print_output=False, universal_newlines=universal_newlines) - if marshal_output and data: - data = marshal.loads(data) - return data, retcode - - def RunPerforceCommand(self, extra_args, marshal_output=False, - universal_newlines=True): - # This might be a good place to cache call results, since things like - # describe or fstat might get called repeatedly. - data, retcode = self.RunPerforceCommandWithReturnCode( - extra_args, marshal_output, universal_newlines) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (extra_args, data)) - return data - - def GetFileProperties(self, property_key_prefix = "", command = "describe"): - description = self.RunPerforceCommand(["describe", self.p4_changelist], - marshal_output=True) - - changed_files = {} - file_index = 0 - # Try depotFile0, depotFile1, ... until we don't find a match - while True: - file_key = "depotFile%d" % file_index - if file_key in description: - filename = description[file_key] - change_type = description[property_key_prefix + str(file_index)] - changed_files[filename] = change_type - file_index += 1 - else: - break - return changed_files - - def GetChangedFiles(self): - return self.GetFileProperties("action") - - def GetUnknownFiles(self): - # Perforce doesn't detect new files, they have to be explicitly added - return [] - - def IsBaseBinary(self, filename): - base_filename = self.GetBaseFilename(filename) - return self.IsBinaryHelper(base_filename, "files") - - def IsPendingBinary(self, filename): - return self.IsBinaryHelper(filename, "describe") - - def IsBinaryHelper(self, filename, command): - file_types = self.GetFileProperties("type", command) - if not filename in file_types: - ErrorExit("Trying to check binary status of unknown file %s." % filename) - # This treats symlinks, macintosh resource files, temporary objects, and - # unicode as binary. See the Perforce docs for more details: - # http://www.perforce.com/perforce/doc.current/manuals/cmdref/o.ftypes.html - return not file_types[filename].endswith("text") - - def GetFileContent(self, filename, revision, is_binary): - file_arg = filename - if revision: - file_arg += "#" + revision - # -q suppresses the initial line that displays the filename and revision - return self.RunPerforceCommand(["print", "-q", file_arg], - universal_newlines=not is_binary) - - def GetBaseFilename(self, filename): - actionsWithDifferentBases = [ - "move/add", # p4 move - "branch", # p4 integrate (to a new file), similar to hg "add" - "add", # p4 integrate (to a new file), after modifying the new file - ] - - # We only see a different base for "add" if this is a downgraded branch - # after a file was branched (integrated), then edited. - if self.GetAction(filename) in actionsWithDifferentBases: - # -Or shows information about pending integrations/moves - fstat_result = self.RunPerforceCommand(["fstat", "-Or", filename], - marshal_output=True) - - baseFileKey = "resolveFromFile0" # I think it's safe to use only file0 - if baseFileKey in fstat_result: - return fstat_result[baseFileKey] - - return filename - - def GetBaseRevision(self, filename): - base_filename = self.GetBaseFilename(filename) - - have_result = self.RunPerforceCommand(["have", base_filename], - marshal_output=True) - if "haveRev" in have_result: - return have_result["haveRev"] - - def GetLocalFilename(self, filename): - where = self.RunPerforceCommand(["where", filename], marshal_output=True) - if "path" in where: - return where["path"] - - def GenerateDiff(self, args): - class DiffData: - def __init__(self, perforceVCS, filename, action): - self.perforceVCS = perforceVCS - self.filename = filename - self.action = action - self.base_filename = perforceVCS.GetBaseFilename(filename) - - self.file_body = None - self.base_rev = None - self.prefix = None - self.working_copy = True - self.change_summary = None - - def GenerateDiffHeader(diffData): - header = [] - header.append("Index: %s" % diffData.filename) - header.append("=" * 67) - - if diffData.base_filename != diffData.filename: - if diffData.action.startswith("move"): - verb = "rename" - else: - verb = "copy" - header.append("%s from %s" % (verb, diffData.base_filename)) - header.append("%s to %s" % (verb, diffData.filename)) - - suffix = "\t(revision %s)" % diffData.base_rev - header.append("--- " + diffData.base_filename + suffix) - if diffData.working_copy: - suffix = "\t(working copy)" - header.append("+++ " + diffData.filename + suffix) - if diffData.change_summary: - header.append(diffData.change_summary) - return header - - def GenerateMergeDiff(diffData, args): - # -du generates a unified diff, which is nearly svn format - diffData.file_body = self.RunPerforceCommand( - ["diff", "-du", diffData.filename] + args) - diffData.base_rev = self.GetBaseRevision(diffData.filename) - diffData.prefix = "" - - # We have to replace p4's file status output (the lines starting - # with +++ or ---) to match svn's diff format - lines = diffData.file_body.splitlines() - first_good_line = 0 - while (first_good_line < len(lines) and - not lines[first_good_line].startswith("@@")): - first_good_line += 1 - diffData.file_body = "\n".join(lines[first_good_line:]) - return diffData - - def GenerateAddDiff(diffData): - fstat = self.RunPerforceCommand(["fstat", diffData.filename], - marshal_output=True) - if "headRev" in fstat: - diffData.base_rev = fstat["headRev"] # Re-adding a deleted file - else: - diffData.base_rev = "0" # Brand new file - diffData.working_copy = False - rel_path = self.GetLocalFilename(diffData.filename) - diffData.file_body = open(rel_path, 'r').read() - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -0,0 +1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " @@" - diffData.prefix = "+" - return diffData - - def GenerateDeleteDiff(diffData): - diffData.base_rev = self.GetBaseRevision(diffData.filename) - is_base_binary = self.IsBaseBinary(diffData.filename) - # For deletes, base_filename == filename - diffData.file_body = self.GetFileContent(diffData.base_filename, - None, - is_base_binary) - # Replicate svn's list of changed lines - line_count = len(diffData.file_body.splitlines()) - diffData.change_summary = "@@ -1" - if line_count > 1: - diffData.change_summary += ",%d" % line_count - diffData.change_summary += " +0,0 @@" - diffData.prefix = "-" - return diffData - - changed_files = self.GetChangedFiles() - - svndiff = [] - filecount = 0 - for (filename, action) in changed_files.items(): - svn_status = self.PerforceActionToSvnStatus(action) - if svn_status == "SKIP": - continue - - diffData = DiffData(self, filename, action) - # Is it possible to diff a branched file? Stackoverflow says no: - # http://stackoverflow.com/questions/1771314/in-perforce-command-line-how-to-diff-a-file-reopened-for-add - if svn_status == "M": - diffData = GenerateMergeDiff(diffData, args) - elif svn_status == "A": - diffData = GenerateAddDiff(diffData) - elif svn_status == "D": - diffData = GenerateDeleteDiff(diffData) - else: - ErrorExit("Unknown file action %s (svn action %s)." % \ - (action, svn_status)) - - svndiff += GenerateDiffHeader(diffData) - - for line in diffData.file_body.splitlines(): - svndiff.append(diffData.prefix + line) - filecount += 1 - if not filecount: - ErrorExit("No valid patches found in output from p4 diff") - return "\n".join(svndiff) + "\n" - - def PerforceActionToSvnStatus(self, status): - # Mirroring the list at http://permalink.gmane.org/gmane.comp.version-control.mercurial.devel/28717 - # Is there something more official? - return { - "add" : "A", - "branch" : "A", - "delete" : "D", - "edit" : "M", # Also includes changing file types. - "integrate" : "M", - "move/add" : "M", - "move/delete": "SKIP", - "purge" : "D", # How does a file's status become "purge"? - }[status] - - def GetAction(self, filename): - changed_files = self.GetChangedFiles() - if not filename in changed_files: - ErrorExit("Trying to get base version of unknown file %s." % filename) - - return changed_files[filename] - - def GetBaseFile(self, filename): - base_filename = self.GetBaseFilename(filename) - base_content = "" - new_content = None - - status = self.PerforceActionToSvnStatus(self.GetAction(filename)) - - if status != "A": - revision = self.GetBaseRevision(base_filename) - if not revision: - ErrorExit("Couldn't find base revision for file %s" % filename) - is_base_binary = self.IsBaseBinary(base_filename) - base_content = self.GetFileContent(base_filename, - revision, - is_base_binary) - - is_binary = self.IsPendingBinary(filename) - if status != "D" and status != "SKIP": - relpath = self.GetLocalFilename(filename) - if is_binary and self.IsImage(relpath): - new_content = open(relpath, "rb").read() - - return base_content, new_content, is_binary, status - -# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. -def SplitPatch(data): - """Splits a patch into separate pieces for each file. - - Args: - data: A string containing the output of svn diff. - - Returns: - A list of 2-tuple (filename, text) where text is the svn diff output - pertaining to filename. - """ - patches = [] - filename = None - diff = [] - for line in data.splitlines(True): - new_filename = None - if line.startswith('Index:'): - unused, new_filename = line.split(':', 1) - new_filename = new_filename.strip() - elif line.startswith('Property changes on:'): - unused, temp_filename = line.split(':', 1) - # When a file is modified, paths use '/' between directories, however - # when a property is modified '\' is used on Windows. Make them the same - # otherwise the file shows up twice. - temp_filename = temp_filename.strip().replace('\\', '/') - if temp_filename != filename: - # File has property changes but no modifications, create a new diff. - new_filename = temp_filename - if new_filename: - if filename and diff: - patches.append((filename, ''.join(diff))) - filename = new_filename - diff = [line] - continue - if diff is not None: - diff.append(line) - if filename and diff: - patches.append((filename, ''.join(diff))) - return patches - - -def UploadSeparatePatches(issue, rpc_server, patchset, data, options): - """Uploads a separate patch for each file in the diff output. - - Returns a list of [patch_key, filename] for each file. - """ - patches = SplitPatch(data) - rv = [] - for patch in patches: - if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + - " because the file is too large.") - continue - form_fields = [("filename", patch[0])] - if not options.download_base: - form_fields.append(("content_upload", "1")) - files = [("data", "data.diff", patch[1])] - ctype, body = EncodeMultipartFormData(form_fields, files) - url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] - response_body = rpc_server.Send(url, body, content_type=ctype) - lines = response_body.splitlines() - if not lines or lines[0] != "OK": - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - rv.append([lines[1], patch[0]]) - return rv - - -def GuessVCSName(options): - """Helper to guess the version control system. - - This examines the current directory, guesses which VersionControlSystem - we're using, and returns an string indicating which VCS is detected. - - Returns: - A pair (vcs, output). vcs is a string indicating which VCS was detected - and is one of VCS_GIT, VCS_MERCURIAL, VCS_SUBVERSION, VCS_PERFORCE, - VCS_CVS, or VCS_UNKNOWN. - Since local perforce repositories can't be easily detected, this method - will only guess VCS_PERFORCE if any perforce options have been specified. - output is a string containing any interesting output from the vcs - detection routine, or None if there is nothing interesting. - """ - for attribute, value in options.__dict__.iteritems(): - if attribute.startswith("p4") and value != None: - return (VCS_PERFORCE, None) - - def RunDetectCommand(vcs_type, command): - """Helper to detect VCS by executing command. - - Returns: - A pair (vcs, output) or None. Throws exception on error. - """ - try: - out, returncode = RunShellWithReturnCode(command) - if returncode == 0: - return (vcs_type, out.strip()) - except OSError, (errcode, message): - if errcode != errno.ENOENT: # command not found code - raise - - # Mercurial has a command to get the base directory of a repository - # Try running it, but don't die if we don't have hg installed. - # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. - res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) - if res != None: - return res - - # Subversion from 1.7 has a single centralized .svn folder - # ( see http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng ) - # That's why we use 'svn info' instead of checking for .svn dir - res = RunDetectCommand(VCS_SUBVERSION, ["svn", "info"]) - if res != None: - return res - - # Git has a command to test if you're in a git tree. - # Try running it, but don't die if we don't have git installed. - res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", - "--is-inside-work-tree"]) - if res != None: - return res - - # detect CVS repos use `cvs status && $? == 0` rules - res = RunDetectCommand(VCS_CVS, ["cvs", "status"]) - if res != None: - return res - - return (VCS_UNKNOWN, None) - - -def GuessVCS(options): - """Helper to guess the version control system. - - This verifies any user-specified VersionControlSystem (by command line - or environment variable). If the user didn't specify one, this examines - the current directory, guesses which VersionControlSystem we're using, - and returns an instance of the appropriate class. Exit with an error - if we can't figure it out. - - Returns: - A VersionControlSystem instance. Exits if the VCS can't be guessed. - """ - vcs = options.vcs - if not vcs: - vcs = os.environ.get("CODEREVIEW_VCS") - if vcs: - v = VCS_ABBREVIATIONS.get(vcs.lower()) - if v is None: - ErrorExit("Unknown version control system %r specified." % vcs) - (vcs, extra_output) = (v, None) - else: - (vcs, extra_output) = GuessVCSName(options) - - if vcs == VCS_MERCURIAL: - if extra_output is None: - extra_output = RunShell(["hg", "root"]).strip() - return MercurialVCS(options, extra_output) - elif vcs == VCS_SUBVERSION: - return SubversionVCS(options) - elif vcs == VCS_PERFORCE: - return PerforceVCS(options) - elif vcs == VCS_GIT: - return GitVCS(options) - elif vcs == VCS_CVS: - return CVSVCS(options) - - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) - - -def CheckReviewer(reviewer): - """Validate a reviewer -- either a nickname or an email addres. - - Args: - reviewer: A nickname or an email address. - - Calls ErrorExit() if it is an invalid email address. - """ - if "@" not in reviewer: - return # Assume nickname - parts = reviewer.split("@") - if len(parts) > 2: - ErrorExit("Invalid email address: %r" % reviewer) - assert len(parts) == 2 - if "." not in parts[1]: - ErrorExit("Invalid email address: %r" % reviewer) - - -def LoadSubversionAutoProperties(): - """Returns the content of [auto-props] section of Subversion's config file as - a dictionary. - - Returns: - A dictionary whose key-value pair corresponds the [auto-props] section's - key-value pair. - In following cases, returns empty dictionary: - - config file doesn't exist, or - - 'enable-auto-props' is not set to 'true-like-value' in [miscellany]. - """ - if os.name == 'nt': - subversion_config = os.environ.get("APPDATA") + "\\Subversion\\config" - else: - subversion_config = os.path.expanduser("~/.subversion/config") - if not os.path.exists(subversion_config): - return {} - config = ConfigParser.ConfigParser() - config.read(subversion_config) - if (config.has_section("miscellany") and - config.has_option("miscellany", "enable-auto-props") and - config.getboolean("miscellany", "enable-auto-props") and - config.has_section("auto-props")): - props = {} - for file_pattern in config.options("auto-props"): - props[file_pattern] = ParseSubversionPropertyValues( - config.get("auto-props", file_pattern)) - return props - else: - return {} - -def ParseSubversionPropertyValues(props): - """Parse the given property value which comes from [auto-props] section and - returns a list whose element is a (svn_prop_key, svn_prop_value) pair. - - See the following doctest for example. - - >>> ParseSubversionPropertyValues('svn:eol-style=LF') - [('svn:eol-style', 'LF')] - >>> ParseSubversionPropertyValues('svn:mime-type=image/jpeg') - [('svn:mime-type', 'image/jpeg')] - >>> ParseSubversionPropertyValues('svn:eol-style=LF;svn:executable') - [('svn:eol-style', 'LF'), ('svn:executable', '*')] - """ - key_value_pairs = [] - for prop in props.split(";"): - key_value = prop.split("=") - assert len(key_value) <= 2 - if len(key_value) == 1: - # If value is not given, use '*' as a Subversion's convention. - key_value_pairs.append((key_value[0], "*")) - else: - key_value_pairs.append((key_value[0], key_value[1])) - return key_value_pairs - - -def GetSubversionPropertyChanges(filename): - """Return a Subversion's 'Property changes on ...' string, which is used in - the patch file. - - Args: - filename: filename whose property might be set by [auto-props] config. - - Returns: - A string like 'Property changes on |filename| ...' if given |filename| - matches any entries in [auto-props] section. None, otherwise. - """ - global svn_auto_props_map - if svn_auto_props_map is None: - svn_auto_props_map = LoadSubversionAutoProperties() - - all_props = [] - for file_pattern, props in svn_auto_props_map.items(): - if fnmatch.fnmatch(filename, file_pattern): - all_props.extend(props) - if all_props: - return FormatSubversionPropertyChanges(filename, all_props) - return None - - -def FormatSubversionPropertyChanges(filename, props): - """Returns Subversion's 'Property changes on ...' strings using given filename - and properties. - - Args: - filename: filename - props: A list whose element is a (svn_prop_key, svn_prop_value) pair. - - Returns: - A string which can be used in the patch file for Subversion. - - See the following doctest for example. - - >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) - Property changes on: foo.cc - ___________________________________________________________________ - Added: svn:eol-style - + LF - - """ - prop_changes_lines = [ - "Property changes on: %s" % filename, - "___________________________________________________________________"] - for key, value in props: - prop_changes_lines.append("Added: " + key) - prop_changes_lines.append(" + " + value) - return "\n".join(prop_changes_lines) + "\n" - - -def RealMain(argv, data=None): - """The real main function. - - Args: - argv: Command line arguments. - data: Diff contents. If None (default) the diff is generated by - the VersionControlSystem implementation returned by GuessVCS(). - - Returns: - A 2-tuple (issue id, patchset id). - The patchset id is None if the base files are not uploaded by this - script (applies only to SVN checkouts). - """ - options, args = parser.parse_args(argv[1:]) - if options.help: - if options.verbose < 2: - # hide Perforce options - parser.epilog = "Use '--help -v' to show additional Perforce options." - parser.option_groups.remove(parser.get_option_group('--p4_port')) - parser.print_help() - sys.exit(0) - - global verbosity - verbosity = options.verbose - if verbosity >= 3: - logging.getLogger().setLevel(logging.DEBUG) - elif verbosity >= 2: - logging.getLogger().setLevel(logging.INFO) - - vcs = GuessVCS(options) - - base = options.base_url - if isinstance(vcs, SubversionVCS): - # Guessing the base field is only supported for Subversion. - # Note: Fetching base files may become deprecated in future releases. - guessed_base = vcs.GuessBase(options.download_base) - if base: - if guessed_base and base != guessed_base: - print "Using base URL \"%s\" from --base_url instead of \"%s\"" % \ - (base, guessed_base) - else: - base = guessed_base - - if not base and options.download_base: - options.download_base = True - logging.info("Enabled upload of base file") - if not options.assume_yes: - vcs.CheckForUnknownFiles() - if data is None: - data = vcs.GenerateDiff(args) - data = vcs.PostProcessDiff(data) - if options.print_diffs: - print "Rietveld diff start:*****" - print data - print "Rietveld diff end:*****" - files = vcs.GetBaseFiles(data) - if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" - rpc_server = GetRpcServer(options.server, - options.email, - options.host, - options.save_cookies, - options.account_type) - form_fields = [] - - repo_guid = vcs.GetGUID() - if repo_guid: - form_fields.append(("repo_guid", repo_guid)) - if base: - b = urlparse.urlparse(base) - username, netloc = urllib.splituser(b.netloc) - if username: - logging.info("Removed username from base URL") - base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params, - b.query, b.fragment)) - form_fields.append(("base", base)) - if options.issue: - form_fields.append(("issue", str(options.issue))) - if options.email: - form_fields.append(("user", options.email)) - if options.reviewers: - for reviewer in options.reviewers.split(','): - CheckReviewer(reviewer) - form_fields.append(("reviewers", options.reviewers)) - if options.cc: - for cc in options.cc.split(','): - CheckReviewer(cc) - form_fields.append(("cc", options.cc)) - - # Process --message, --title and --file. - message = options.message or "" - title = options.title or "" - if options.file: - if options.message: - ErrorExit("Can't specify both message and message file options") - file = open(options.file, 'r') - message = file.read() - file.close() - if options.issue: - prompt = "Title describing this patch set: " - else: - prompt = "New issue subject: " - title = ( - title or message.split('\n', 1)[0].strip() or raw_input(prompt).strip()) - if not title and not options.issue: - ErrorExit("A non-empty title is required for a new issue") - # For existing issues, it's fine to give a patchset an empty name. Rietveld - # doesn't accept that so use a whitespace. - title = title or " " - if len(title) > 100: - title = title[:99] + '…' - if title and not options.issue: - message = message or title - - form_fields.append(("subject", title)) - # If it's a new issue send message as description. Otherwise a new - # message is created below on upload_complete. - if message and not options.issue: - form_fields.append(("description", message)) - - # Send a hash of all the base file so the server can determine if a copy - # already exists in an earlier patchset. - base_hashes = "" - for file, info in files.iteritems(): - if not info[0] is None: - checksum = md5(info[0]).hexdigest() - if base_hashes: - base_hashes += "|" - base_hashes += checksum + ":" + file - form_fields.append(("base_hashes", base_hashes)) - if options.private: - if options.issue: - print "Warning: Private flag ignored when updating an existing issue." - else: - form_fields.append(("private", "1")) - if options.send_patch: - options.send_mail = True - if not options.download_base: - form_fields.append(("content_upload", "1")) - if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." - uploaded_diff_file = [] - form_fields.append(("separate_patches", "1")) - else: - uploaded_diff_file = [("data", "data.diff", data)] - ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) - response_body = rpc_server.Send("/upload", body, content_type=ctype) - patchset = None - if not options.download_base or not uploaded_diff_file: - lines = response_body.splitlines() - if len(lines) >= 2: - msg = lines[0] - patchset = lines[1].strip() - patches = [x.split(" ", 1) for x in lines[2:]] - else: - msg = response_body - else: - msg = response_body - StatusUpdate(msg) - if not response_body.startswith("Issue created.") and \ - not response_body.startswith("Issue updated."): - sys.exit(0) - issue = msg[msg.rfind("/")+1:] - - if not uploaded_diff_file: - result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) - if not options.download_base: - patches = result - - if not options.download_base: - vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) - - payload = {} # payload for final request - if options.send_mail: - payload["send_mail"] = "yes" - if options.send_patch: - payload["attach_patch"] = "yes" - if options.issue and message: - payload["message"] = message - payload = urllib.urlencode(payload) - rpc_server.Send("/" + issue + "/upload_complete/" + (patchset or ""), - payload=payload) - return issue, patchset - - -def main(): - try: - logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" - "%(lineno)s %(message)s ")) - os.environ['LC_ALL'] = 'C' - RealMain(sys.argv) - except KeyboardInterrupt: - print - StatusUpdate("Interrupted.") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/frontend/express/node_modules/mongoskin/package.json b/frontend/express/node_modules/mongoskin/package.json deleted file mode 100644 index 27c438dc2e0..00000000000 --- a/frontend/express/node_modules/mongoskin/package.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "name": "mongoskin", - "description": "The future layer above node-mongodb-native", - "version": "0.5.0", - "author": { - "name": "Gui Lin", - "email": "guileen@gmail.com" - }, - "homepage": "https://github.com/kissjs/node-mongoskin", - "repository": { - "type": "git", - "url": "git://github.com/guileen/node-mongoskin.git" - }, - "bugs": { - "url": "https://github.com/kissjs/node-mongoskin/issues" - }, - "main": "./index.js", - "keywords": [ - "mongodb", - "database", - "nosql" - ], - "engines": { - "node": ">= 0.4.0" - }, - "dependencies": { - "mongodb": "1.2.x" - }, - "devDependencies": { - "mocha": "*", - "jscover": "*", - "should": "*" - }, - "scripts": { - "test": "make test" - }, - "directories": { - "example": "./examples", - "lib": "./lib/mongoskin" - }, - "license": "MIT", - "contributors": [ - { - "name": "Gui Lin", - "email": "guileen@gmail.com", - "url": "https://github.com/guileen" - }, - { - "name": "François de Metz", - "email": "francois@2metz.fr", - "url": "https://github.com/francois2metz" - }, - { - "name": "fengmk2", - "email": "fengmk2@gmail.com", - "url": "http://fengmk2.github.com" - }, - { - "name": "Quang Van", - "email": "quangvvv@gmail.com", - "url": "https://github.com/quangv" - }, - { - "name": "Matt Perpick", - "email": "clutchski@gmail.com", - "url": "https://github.com/clutchski" - }, - { - "name": "humanchimp", - "email": "morphcham@gmail.com", - "url": "https://github.com/humanchimp" - }, - { - "name": "Joe Faber", - "email": "joe.faber@mandiant.com", - "url": "https://github.com/jlfaber" - }, - { - "name": "Harvey McQueen", - "email": "hmcqueen@gmail.com", - "url": "https://github.com/hmcqueen" - }, - { - "name": "Paul Gebheim", - "email": "pgebheim@monkeyinferno.com", - "url": "https://github.com/paulirish" - }, - { - "name": "Aneil Mallavarapu", - "email": "aneil@blipboard.com", - "url": "https://github.com/amallavarapu" - }, - { - "name": "wmertens", - "email": "Wout.Mertens@gmail.com", - "url": "https://github.com/wmertens" - }, - { - "name": "Rakshit Menpara", - "email": "deltasquare4@gmail.com", - "url": "https://github.com/deltasquare4" - } - ], - "readme": "# mongoskin [![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin)\n\n![logo](https://raw.github.com/kissjs/node-mongoskin/master/logo.png)\n\nThis project is a wrapper of [node-mongodb-native](https://github.com/mongodb/node-mongodb-native).\nThe api is same to node-mongodb-native, please see the [document](http://mongodb.github.com/node-mongodb-native/) first.\n\n## Test\n\n* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md)\n* jscoverage: [**89%**](http://fengmk2.github.com/coverage/mongoskin.html)\n\n## Test pass [mongodb] versions\n\n* >= 0.9.8 < 1.0.0: mongodb have bug, it will throw a `TypeError: object is not a function` \n when connection open error.\n* 1.0.x\n* 1.1.x\n* 1.2.x\n\n```bash\n$ make test\n```\n\n\n\n# Mongoskin document\n\n* [Nodejs mongodb drivers comparation](#comparation)\n* [Install](#install)\n* [Quick Start](#quickstart)\n * [Connect easier](#quickstart-1)\n * [Server options and BSON options](#quickstart-2)\n * [Similar API with node-mongodb-native](#quickstart-3)\n * [Cursor easier](#quickstart-4)\n * [MVC helper](#quickstart-5)\n* [Documentation](#documentation)\n * [Module](#module)\n * [SkinServer](#skinserver)\n * [SkinDb](#skindb)\n * [SkinCollection](#skincollection)\n * [Additional methods](#additional-collection-op)\n * [Collection operation](#inherit-collection-op)\n * [Indexes](#inherit-indexes)\n * [Querying](#inherit-query)\n * [Aggregation](#inherit-aggregation)\n * [Inserting](#inherit-inserting)\n * [Updating](#inherit-updating)\n * [Removing](#inherit-removing)\n * [SkinCursor](#skincursor)\n\n\n\nNodejs Mongodb Driver Comparison\n========\n\nnode-mongodb-native\n--------\n\nOne of the most powerful Mongo drivers is node-mongodb-native. Most other drivers build\non top of it, including mongoskin. Unfortunately, it has an awkward interface with too many \ncallbacks. Also, mongoskin needs a way to hold a Collection instance as an MVC model.\n \nSee [mongodb-native](https://github.com/christkv/node-mongodb-native/tree/master/docs)\n\nmongoose\n--------\n\nMongoose provides an ORM way to hold Collection instance as Model,\n you should define schema first. But why mongodb need schema?\n Some guys like me, want to write code from application layer but not database layer,\n and we can use any fields without define it before.\n\n Mongoose provide a DAL that you can do validation, and write your middlewares.\n But some guys like me would like to validate manually, I think it is the tao of mongodb.\n\n If you don't thinks so, [Mongoose-ORM](https://github.com/LearnBoost/mongoose) is probably your choice.\n\nmongoskin\n--------\n\nMongoskin is an easy to use driver of mongodb for nodejs,\n it is similar with mongo shell, powerful like node-mongodb-native,\n and support additional javascript method binding, which make it can act as a Model(in document way).\n\nIt will provide full features of [node-mongodb-native](https://github.com/christkv/node-mongodb-native),\n and make it [future](http://en.wikipedia.org/wiki/Future_%28programming%29).\n\nIf you need validation, you can use [node-iform](https://github.com/guileen/node-iform).\n\n[Back to index](#index)\n\n\n\nInstall\n========\n\n```bash\n$ npm install mongoskin\n```\n\n[Back to index](#index)\n\n\n\n\nQuick Start\n========\n\n **Is mongoskin synchronized?**\n\nNope! It is asynchronized, it use the [future pattern](http://en.wikipedia.org/wiki/Future_%28programming%29).\n**Mongoskin** is the future layer above [node-mongodb-native](https://github.com/christkv/node-mongodb-native)\n\n\n\nConnect easier\n--------\nYou can connect to mongodb easier now.\n\n```js\nvar mongo = require('mongoskin');\nmongo.db('localhost:27017/testdb').collection('blog').find().toArray(function (err, items) {\n console.dir(items);\n})\n```\n\n\n\nServer options and BSON options\n--------\nYou can also set `auto_reconnect` options querystring.\nAnd native_parser options will automatically set if native_parser is available.\n\n```js\nvar mongo = require('mongoskin');\nvar db = mongo.db('localhost:27017/test?auto_reconnect');\n```\n\n\n\nSimilar API with node-mongodb-native\n--------\nYou can do everything that node-mongodb-native can do.\n\n```js\ndb.createCollection(...);\ndb.collection('user').ensureIndex([['username', 1]], true, function (err, replies) {});\ndb.collection('posts').hint = 'slug';\ndb.collection('posts').findOne({slug: 'whats-up'}, function (err, post) {\n // do something\n});\n```\n\n\n\nCursor easier\n--------\n\n```js\ndb.collection('posts').find().toArray(function (err, posts) {\n // do something\n});\n```\n\n\n\nMVC helper\n--------\n\nYou can bind **additional methods** for collection.\nIt is very useful if you want to use MVC patterns with nodejs and mongodb.\nYou can also invoke collection by properties after bind,\nit could simplfy your `require`.\n\nTo keep your code in line with DRY principles, it's possible to create your own\ndata layer by for example, setting up your own validators and/or default values\ninside the MVC methods as shown below in the config example\n\n```js\ndb.bind('posts', {\n findTop10 : function (fn) {\n this.find({}, {limit:10, sort:[['views', -1]]}).toArray(fn);\n },\n removeTagWith : function (tag, fn) {\n this.remove({tags:tag},fn);\n }\n } \n});\n\ndb.bind('settings', {\n\n getAll: function(user, fn) {\n \n \tthis.find({user: user}).toArray(function(err, settings) {\n \t\n \t // We want to set a default currency from within our app instead of storing it\n \t // for every user\n \t settings.currency = (typeof settings.currency !== \"undefined\") ? settings.currency : 'USD';\n \t\t\n \t fn(err, settings);\n \t\n \t});\n }\n});\n\n \ndb.bind('comments');\n\ndb.collection('posts').removeTagWith('delete', function (err, replies) {\n //do something\n});\n\ndb.posts.findTop10(function (err, topPosts) {\n //do something\n});\n\ndb.comments.find().toArray(function (err, comments) {\n //do something\n});\n```\n\n[Back to index](#index)\n\n\n\n\nDocumentation\n========\n\nfor more information, see the source.\n\n[Back to index](#index)\n\n\n\n\nModule\n--------\n\n### MongoSkin Url format\n\n```\n[*://][username:password@]host[:port][/database][?auto_reconnect[=true|false]]`\n```\n\ne.g.\n\n```\nlocalhost/blog\nmongo://admin:pass@127.0.0.1:27017/blog?auto_reconnect\n127.0.0.1?auto_reconnect=false\n```\n\n### db(serverURL[s], dbOptions, replicasetOptions)\n\nGet or create instance of [SkinDb](#skindb).\n\n```js\nvar db = mongoskin.db('localhost:27017/testdb?auto_reconnect=true&poolSize=5');\n```\n\nfor ReplSet server\n\n```js\nvar db = mongoskin.db([\n '192.168.0.1:27017/?auto_reconnect=true',\n '192.168.0.2:27017/?auto_reconnect=true',\n '192.168.0.3:27017/?auto_reconnect=true'\n], {\n database: 'testdb',\n safe: true\n}, {\n connectArbiter: false,\n socketOptions: {\n timeout: 2000\n }\n});\n```\n\n### router(select)\n\nselect is `function(collectionName)` returns a database instance, means router collectionName to that database.\n\n```js\nvar db = mongo.router(function (coll_name) {\n switch(coll_name) {\n case 'user':\n case 'message':\n return mongo.db('192.168.1.3/auth_db');\n default:\n return mongo.db('192.168.1.2/app_db');\n }\n});\ndb.bind('user', require('./shared-user-methods'));\nvar users = db.user; //auth_db.user\nvar messages = db.collection('message'); // auth_db.message\nvar products = db.collection('product'); //app_db.product\n```\n\n### classes extends frome node-mongodb-native\n\n* BSONPure\n* BSONNative\n* BinaryParser\n* Binary\n* Code\n* DBRef\n* Double\n* MaxKey\n* MinKey\n* ObjectID\n* Symbol\n* Timestamp\n* Long\n* BaseCommand\n* DbCommand\n* DeleteCommand\n* GetMoreCommand\n* InsertCommand\n* KillCursorCommand\n* QueryCommand\n* UpdateCommand\n* MongoReply\n* Admin\n* Collection\n* Connection\n* Server\n* ReplSetServers\n* Cursor\n* Db\n* connect\n* Grid\n* Chunk\n* GridStore\n* native\n* pure\n\n\n[Back to index](#index)\n\n\n\nSkinServer\n--------\n\n### SkinServer(server)\n\nConstruct SkinServer from native Server instance.\n\n### db(dbname, username=null, password=null)\n\nConstruct [SkinDb](#skindb) from SkinServer.\n\n[Back to index](#index)\n\n\n\nSkinDb\n--------\n\n### SkinDb(db, username=null, password=null)\n\nConstruct SkinDb.\n\n### open(callback)\n\nConnect to database, retrieval native\n[Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17)\ninstance, callback is function(err, db).\n\n### collection(collectionName)\n\nRetrieval [SkinCollection](#skincollection) instance of specified collection name.\n\n\n\n### bind(collectionName)\n\n### bind(collectionName, SkinCollection)\n\n### bind(collectionName, extendObject1, extendObject2 ...)\n\nBind [SkinCollection](#skincollection) to db properties as a shortcut to db.collection(name).\nYou can also bind additional methods to the SkinCollection, it is useful when\nyou want to reuse a complex operation. This will also affect\ndb.collection(name) method.\n\ne.g.\n\n```js\ndb.bind('book', {\n firstBook: function (fn) {\n this.findOne(fn);\n }\n});\ndb.book.firstBook(function (err, book) {});\n```\n\n### all the methods from Db.prototype\n\nSee [Db](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/db.js#L17) of node-mongodb-native for more information.\n\n[Back to index](#index)\n\n\n\nSkinCollection\n--------\n\nSee [Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45) of node-mongodb-native for more information.\n\n\n### open(callback)\n\nRetrieval native\n[Collection](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L45)\ninstance, callback is function(err, collection).\n\n### id(hex)\n\nEquivalent to\n\n```js\ndb.bson_serializer.ObjectID.createFromHexString(hex);\n```\n\nSee [ObjectID.createFromHexString](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/bson/bson.js#L548)\n\n\n\n\n### Collection operation\n\n```js\ncheckCollectionName(collectionName)\noptions(callback)\nrename(collectionName, callback)\ndrop(callback)\n```\n\n\n\n### Indexes\n\n```js\ncreateIndex(fieldOrSpec, unique, callback)\nensureIndex(fieldOrSpec, unique, callback)\nindexInformation(callback)\ndropIndex(indexName, callback)\ndropIndexes(callback)\n```\n \nSee [mongodb-native indexes](https://github.com/christkv/node-mongodb-native/blob/master/docs/indexes.md)\n\n\n\n### Queries\n\nSee [mongodb-native queries](https://github.com/christkv/node-mongodb-native/blob/master/docs/queries.md)\n\n#### findItems(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.toArray(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findEach(..., callback)\n\nEquivalent to\n\n```js\ncollection.find(..., function (err, cursor) {\n cursor.each(callback);\n});\n```\n\nSee [Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\n\n#### findById(id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.findOne({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.findOne](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L417)\n\n#### find(...)\n\nIf the last parameter is function, it is equivalent to native\n[Collection.find](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L348)\nmethod, else it will return a future [SkinCursor](#skincursor).\n\ne.g.\n\n```js\n// callback\ndb.book.find({}, function (err, cursor) {/* do something */});\n// future SkinCursor\ndb.book.find().toArray(function (err, books) {/* do something */});\n```\n\n#### normalizeHintField(hint)\n\n#### find\n\n```js\n/**\n * Various argument possibilities\n * 1 callback\n * 2 selector, callback,\n * 2 callback, options // really?!\n * 3 selector, fields, callback\n * 3 selector, options, callback\n * 4,selector, fields, options, callback\n * 5 selector, fields, skip, limit, callback\n * 6 selector, fields, skip, limit, timeout, callback\n *\n * Available options:\n * limit, sort, fields, skip, hint, explain, snapshot, timeout, tailable, batchSize\n */\n```\n\n#### findAndModify(query, sort, update, options, callback) \n\n```js\n/**\n Fetch and update a collection\n query: a filter for the query\n sort: if multiple docs match, choose the first one in the specified sort order as the object to manipulate\n update: an object describing the modifications to the documents selected by the query\n options:\n remove: set to a true to remove the object before returning\n new: set to true if you want to return the modified object rather than the original. Ignored for remove.\n upsert: true/false (perform upsert operation)\n**/\n```\n\n#### findOne(queryObject, options, callback)\n\n\n\n### Aggregation\n\n#### mapReduce(map, reduce, options, callback)\n\ne.g.\n\n```js\nvar map = function () {\n emit(test(this.timestamp.getYear()), 1);\n}\n\nvar reduce = function (k, v){\n count = 0;\n for (i = 0; i < v.length; i++) {\n count += v[i];\n }\n return count;\n}\nvar options = {scope: {test: new client.bson_serializer.Code(t.toString())}};\ncollection.mapReduce(map, reduce, options, function (err, collection) {\n collection.find(function (err, cursor) {\n cursor.toArray(function (err, results) {\n test.equal(2, results[0].value)\n finished_test({test_map_reduce_functions_scope:'ok'}); \n })\n})\n```\n\n#### group(keys, condition, initial, reduce, command, callback)\n\ne.g. \n\n```js\ncollection.group([], {}, {\"count\":0}, \"function (obj, prev) { prev.count++; }\", true, function(err, results) {});\n```\n\n#### count(query, callback)\n#### distinct(key, query, callback)\n\n\n\n### Inserting\n\n#### insert(docs, options, callback)\n\n\n\n### Updating\n\n#### save(doc, options, callback)\n\n```js\n/**\n Update a single document in this collection.\n spec - a associcated array containing the fields that need to be present in\n the document for the update to succeed\n\n document - an associated array with the fields to be updated or in the case of\n a upsert operation the fields to be inserted.\n\n Options:\n upsert - true/false (perform upsert operation)\n multi - true/false (update all documents matching spec)\n strict - true/false (perform check if the operation failed, required extra call to db)\n Deprecated Options:\n safe - true/false (perform check if the operation failed, required extra call to db)\n**/\n```\n\n#### update(spec, document, options, callback)\n\n#### updateById(_id, ..., callback)\n\nEquivalent to\n\n```js\ncollection.update({_id, ObjectID.createFromHexString(id)}, ..., callback);\n```\n\nSee [Collection.update](https://github.com/christkv/node-mongodb-native/blob/master/docs/insert.md)\n\n\n\n### Removing\n\n#### remove(selector, options, callback)\n\n#### removeById(_id, options, callback)\n\n[Back to index](#index)\n\n\n\nSkinCursor\n---------\n\nSee [Cursor](https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/cursor.js#L1)\nof node-mongodb-native for more information.\n\nAll these methods will return the SkinCursor itself.\n\n```js\nsort(keyOrList, [direction], [callback])\nlimit(limit, [callback])\nskip(skip, [callback])\nbatchSize(skip, [callback])\n\ntoArray(callback)\neach(callback)\ncount(callback)\nnextObject(callback)\ngetMore(callback)\nexplain(callback)\n```\n\n[Back to index](#index)\n\n## How to validate input?\n\nI wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform) \nbase on [node-validator](https://github.com/chriso/node-validator)\n\n## Authors\n\nBelow is the output from `git-summary`.\n\n```\n project: node-mongoskin\n commits: 112\n active : 54 days\n files : 39\n authors: \n 49 Lin Gui 43.8%\n 34 guilin æ¡‚æž— 30.4%\n 9 fengmk2 8.0%\n 5 guilin 4.5%\n 2 François de Metz 1.8%\n 2 Paul Gebheim 1.8%\n 2 Gui Lin 1.8%\n 1 humanchimp 0.9%\n 1 Aneil Mallavarapu 0.9%\n 1 wmertens 0.9%\n 1 Harvey McQueen 0.9%\n 1 Joe Faber 0.9%\n 1 Matt Perpick 0.9%\n 1 Quang Van 0.9%\n 1 Rakshit Menpara 0.9%\n 1 Wout Mertens 0.9%\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2011 - 2012 kissjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "readmeFilename": "Readme.md", - "_id": "mongoskin@0.5.0", - "_from": "mongoskin" -} diff --git a/frontend/express/node_modules/mongoskin/test/collection.test.js b/frontend/express/node_modules/mongoskin/test/collection.test.js deleted file mode 100644 index 462180b2c1a..00000000000 --- a/frontend/express/node_modules/mongoskin/test/collection.test.js +++ /dev/null @@ -1,55 +0,0 @@ - -/** - * Module dependencies. - */ - -var mongoskin = require('../') - , should = require('should'); - - -module.exports = { - 'test id()': function() { - var db = mongoskin.db('localhost/test'); - db.bind('testcollection'); - var id = '4ec4b2b9f44a927223000001'; - id = db.testcollection.id(id); - id.should.be.instanceof(db.testcollection.ObjectID); - id = db.testcollection.id(id); - id.should.be.instanceof(db.testcollection.ObjectID); - db.close(); - }, - 'test findById string id': function() { - var db = mongoskin.db('localhost/test'); - var ObjectID = db.db.bson_serializer.ObjectID; - db.bind('article'); - var now = new Date(); - var article = {title: 'test article title ' + now.getTime(), created_at: now}; - db.article.insert(article, function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.length(1); - article.should.have.property('_id').with.instanceof(ObjectID); - obj[0].should.have.property('_id').with.instanceof(ObjectID); - - var count = 2; - db.article.findById(article._id.toString(), function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.property('_id').with.instanceof(ObjectID); - obj._id.should.eql(article._id); - if(--count === 0) { - db.close(); - } - }); - db.article.findById(article._id, function(err, obj) { - should.not.exist(err); - should.exist(obj); - obj.should.have.property('_id').with.instanceof(ObjectID); - obj._id.should.eql(article._id); - if(--count === 0) { - db.close(); - } - }); - }); - } -}; \ No newline at end of file diff --git a/frontend/express/node_modules/request/LICENSE b/frontend/express/node_modules/request/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/frontend/express/node_modules/request/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/frontend/express/node_modules/request/README.md b/frontend/express/node_modules/request/README.md deleted file mode 100644 index eca6a5ab302..00000000000 --- a/frontend/express/node_modules/request/README.md +++ /dev/null @@ -1,344 +0,0 @@ -# Request -- Simplified HTTP request method - -## Install - -
    -  npm install request
    -
    - -Or from source: - -
    -  git clone git://github.com/mikeal/request.git 
    -  cd request
    -  npm link
    -
    - -## Super simple to use - -Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default. - -```javascript -var request = require('request'); -request('http://www.google.com', function (error, response, body) { - if (!error && response.statusCode == 200) { - console.log(body) // Print the google web page. - } -}) -``` - -## Streaming - -You can stream any response to a file stream. - -```javascript -request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) -``` - -You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. - -```javascript -fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) -``` - -Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. - -```javascript -request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')) -``` - -Now let's get fancy. - -```javascript -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - if (req.method === 'PUT') { - req.pipe(request.put('http://mysite.com/doodle.png')) - } else if (req.method === 'GET' || req.method === 'HEAD') { - request.get('http://mysite.com/doodle.png').pipe(resp) - } - } -}) -``` - -You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do: - -```javascript -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - var x = request('http://mysite.com/doodle.png') - req.pipe(x) - x.pipe(resp) - } -}) -``` - -And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :) - -```javascript -req.pipe(request('http://mysite.com/doodle.png')).pipe(resp) -``` - -Also, none of this new functionality conflicts with requests previous features, it just expands them. - -```javascript -var r = request.defaults({'proxy':'http://localproxy.com'}) - -http.createServer(function (req, resp) { - if (req.url === '/doodle.png') { - r.get('http://google.com/doodle.png').pipe(resp) - } -}) -``` -You can still use intermediate proxies, the requests will still follow HTTP forwards, etc. - -## Forms - -`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API. - -Url encoded forms are simple - -```javascript -request.post('http://service.com/upload', {form:{key:'value'}}) -// or -request.post('http://service.com/upload').form({key:'value'}) -``` - -For `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you. - -```javascript -var r = request.post('http://service.com/upload') -var form = r.form() -form.append('my_field', 'my_value') -form.append('my_buffer', new Buffer([1, 2, 3])) -form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')) -form.append('remote_file', request('http://google.com/doodle.png')) -``` - -## HTTP Authentication - -```javascript -request.auth('username', 'password', false).get('http://some.server.com/'); -// or -request.get('http://some.server.com/', { - 'auth': { - 'user': 'username', - 'pass': 'password', - 'sendImmediately': false - } -}); -``` - -If passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`. - -`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method). - -Digest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail). - -## OAuth Signing - -```javascript -// Twitter OAuth -var qs = require('querystring') - , oauth = - { callback: 'http://mysite.com/callback/' - , consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - } - , url = 'https://api.twitter.com/oauth/request_token' - ; -request.post({url:url, oauth:oauth}, function (e, r, body) { - // Ideally, you would take the body in the response - // and construct a URL that a user clicks on (like a sign in button). - // The verifier is only available in the response after a user has - // verified with twitter that they are authorizing your app. - var access_token = qs.parse(body) - , oauth = - { consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - , token: access_token.oauth_token - , verifier: access_token.oauth_verifier - } - , url = 'https://api.twitter.com/oauth/access_token' - ; - request.post({url:url, oauth:oauth}, function (e, r, body) { - var perm_token = qs.parse(body) - , oauth = - { consumer_key: CONSUMER_KEY - , consumer_secret: CONSUMER_SECRET - , token: perm_token.oauth_token - , token_secret: perm_token.oauth_token_secret - } - , url = 'https://api.twitter.com/1/users/show.json?' - , params = - { screen_name: perm_token.screen_name - , user_id: perm_token.user_id - } - ; - url += qs.stringify(params) - request.get({url:url, oauth:oauth, json:true}, function (e, r, user) { - console.log(user) - }) - }) -}) -``` - - - -### request(options, callback) - -The first argument can be either a url or an options object. The only required option is uri, all others are optional. - -* `uri` || `url` - fully qualified uri or a parsed url object from url.parse() -* `qs` - object containing querystring values to be appended to the uri -* `method` - http method, defaults to GET -* `headers` - http headers, defaults to {} -* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string. -* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request. -* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above. -* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json. -* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. -* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. -* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. -* `maxRedirects` - the maximum number of redirects to follow, defaults to 10. -* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. -* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets. -* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool. -* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request -* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri. -* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above. -* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example). -* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. -* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section) -* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services) -* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options. -* `localAddress` - Local interface to bind for network connections. - - -The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer. - -## Convenience methods - -There are also shorthand methods for different HTTP METHODs and some other conveniences. - -### request.defaults(options) - -This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it. - -### request.put - -Same as request() but defaults to `method: "PUT"`. - -```javascript -request.put(url) -``` - -### request.patch - -Same as request() but defaults to `method: "PATCH"`. - -```javascript -request.patch(url) -``` - -### request.post - -Same as request() but defaults to `method: "POST"`. - -```javascript -request.post(url) -``` - -### request.head - -Same as request() but defaults to `method: "HEAD"`. - -```javascript -request.head(url) -``` - -### request.del - -Same as request() but defaults to `method: "DELETE"`. - -```javascript -request.del(url) -``` - -### request.get - -Alias to normal request method for uniformity. - -```javascript -request.get(url) -``` -### request.cookie - -Function that creates a new cookie. - -```javascript -request.cookie('cookie_string_here') -``` -### request.jar - -Function that creates a new cookie jar. - -```javascript -request.jar() -``` - - -## Examples: - -```javascript - var request = require('request') - , rand = Math.floor(Math.random()*100000000).toString() - ; - request( - { method: 'PUT' - , uri: 'http://mikeal.iriscouch.com/testjs/' + rand - , multipart: - [ { 'content-type': 'application/json' - , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) - } - , { body: 'I am an attachment' } - ] - } - , function (error, response, body) { - if(response.statusCode == 201){ - console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) - } else { - console.log('error: '+ response.statusCode) - console.log(body) - } - } - ) -``` -Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent). - -```javascript -var request = request.defaults({jar: false}) -request('http://www.google.com', function () { - request('http://images.google.com') -}) -``` - -If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option: - -```javascript -var j = request.jar() -var request = request.defaults({jar:j}) -request('http://www.google.com', function () { - request('http://images.google.com') -}) -``` -OR - -```javascript -var j = request.jar() -var cookie = request.cookie('your_cookie_here') -j.add(cookie) -request({url: 'http://www.google.com', jar: j}, function () { - request('http://images.google.com') -}) -``` diff --git a/frontend/express/node_modules/request/forever.js b/frontend/express/node_modules/request/forever.js deleted file mode 100644 index ac853c0d289..00000000000 --- a/frontend/express/node_modules/request/forever.js +++ /dev/null @@ -1,103 +0,0 @@ -module.exports = ForeverAgent -ForeverAgent.SSL = ForeverAgentSSL - -var util = require('util') - , Agent = require('http').Agent - , net = require('net') - , tls = require('tls') - , AgentSSL = require('https').Agent - -function ForeverAgent(options) { - var self = this - self.options = options || {} - self.requests = {} - self.sockets = {} - self.freeSockets = {} - self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets - self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets - self.on('free', function(socket, host, port) { - var name = host + ':' + port - if (self.requests[name] && self.requests[name].length) { - self.requests[name].shift().onSocket(socket) - } else if (self.sockets[name].length < self.minSockets) { - if (!self.freeSockets[name]) self.freeSockets[name] = [] - self.freeSockets[name].push(socket) - - // if an error happens while we don't use the socket anyway, meh, throw the socket away - function onIdleError() { - socket.destroy() - } - socket._onIdleError = onIdleError - socket.on('error', onIdleError) - } else { - // If there are no pending requests just destroy the - // socket and it will get removed from the pool. This - // gets us out of timeout issues and allows us to - // default to Connection:keep-alive. - socket.destroy(); - } - }) - -} -util.inherits(ForeverAgent, Agent) - -ForeverAgent.defaultMinSockets = 5 - - -ForeverAgent.prototype.createConnection = net.createConnection -ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest -ForeverAgent.prototype.addRequest = function(req, host, port) { - var name = host + ':' + port - if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { - var idleSocket = this.freeSockets[name].pop() - idleSocket.removeListener('error', idleSocket._onIdleError) - delete idleSocket._onIdleError - req._reusedSocket = true - req.onSocket(idleSocket) - } else { - this.addRequestNoreuse(req, host, port) - } -} - -ForeverAgent.prototype.removeSocket = function(s, name, host, port) { - if (this.sockets[name]) { - var index = this.sockets[name].indexOf(s); - if (index !== -1) { - this.sockets[name].splice(index, 1); - } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name]; - delete this.requests[name]; - } - - if (this.freeSockets[name]) { - var index = this.freeSockets[name].indexOf(s) - if (index !== -1) { - this.freeSockets[name].splice(index, 1) - if (this.freeSockets[name].length === 0) { - delete this.freeSockets[name] - } - } - } - - if (this.requests[name] && this.requests[name].length) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(name, host, port).emit('free'); - } -} - -function ForeverAgentSSL (options) { - ForeverAgent.call(this, options) -} -util.inherits(ForeverAgentSSL, ForeverAgent) - -ForeverAgentSSL.prototype.createConnection = createConnectionSSL -ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest - -function createConnectionSSL (port, host, options) { - options.port = port - options.host = host - return tls.connect(options) -} diff --git a/frontend/express/node_modules/request/index.js b/frontend/express/node_modules/request/index.js deleted file mode 100644 index 22707be7087..00000000000 --- a/frontend/express/node_modules/request/index.js +++ /dev/null @@ -1,1365 +0,0 @@ -// Copyright 2010-2012 Mikeal Rogers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -var http = require('http') - , https = false - , tls = false - , url = require('url') - , util = require('util') - , stream = require('stream') - , qs = require('qs') - , querystring = require('querystring') - , crypto = require('crypto') - - , oauth = require('oauth-sign') - , hawk = require('hawk') - , aws = require('aws-sign') - , httpSignature = require('http-signature') - , uuid = require('node-uuid') - , mime = require('mime') - , tunnel = require('tunnel-agent') - , safeStringify = require('json-stringify-safe') - - , ForeverAgent = require('forever-agent') - , FormData = require('form-data') - - , Cookie = require('cookie-jar') - , CookieJar = Cookie.Jar - , cookieJar = new CookieJar - ; - -try { - https = require('https') -} catch (e) {} - -try { - tls = require('tls') -} catch (e) {} - -var debug -if (/\brequest\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - console.error('REQUEST %s', util.format.apply(util, arguments)) - } -} else { - debug = function() {} -} - -function toBase64 (str) { - return (new Buffer(str || "", "ascii")).toString("base64") -} - -function md5 (str) { - return crypto.createHash('md5').update(str).digest('hex') -} - -// Hacky fix for pre-0.4.4 https -if (https && !https.Agent) { - https.Agent = function (options) { - http.Agent.call(this, options) - } - util.inherits(https.Agent, http.Agent) - https.Agent.prototype._getConnection = function (host, port, cb) { - var s = tls.connect(port, host, this.options, function () { - // do other checks here? - if (cb) cb() - }) - return s - } -} - -function isReadStream (rs) { - if (rs.readable && rs.path && rs.mode) { - return true - } -} - -function copy (obj) { - var o = {} - Object.keys(obj).forEach(function (i) { - o[i] = obj[i] - }) - return o -} - -var isUrl = /^https?:/ - -var globalPool = {} - -function Request (options) { - stream.Stream.call(this) - this.readable = true - this.writable = true - - if (typeof options === 'string') { - options = {uri:options} - } - - var reserved = Object.keys(Request.prototype) - for (var i in options) { - if (reserved.indexOf(i) === -1) { - this[i] = options[i] - } else { - if (typeof options[i] === 'function') { - delete options[i] - } - } - } - - if (options.method) { - this.explicitMethod = true - } - - this.init(options) -} -util.inherits(Request, stream.Stream) -Request.prototype.init = function (options) { - // init() contains all the code to setup the request object. - // the actual outgoing request is not started until start() is called - // this function is called from both the constructor and on redirect. - var self = this - if (!options) options = {} - - if (!self.method) self.method = options.method || 'GET' - self.localAddress = options.localAddress - - debug(options) - if (!self.pool && self.pool !== false) self.pool = globalPool - self.dests = self.dests || [] - self.__isRequestRequest = true - - // Protect against double callback - if (!self._callback && self.callback) { - self._callback = self.callback - self.callback = function () { - if (self._callbackCalled) return // Print a warning maybe? - self._callbackCalled = true - self._callback.apply(self, arguments) - } - self.on('error', self.callback.bind()) - self.on('complete', self.callback.bind(self, null)) - } - - if (self.url) { - // People use this property instead all the time so why not just support it. - self.uri = self.url - delete self.url - } - - if (!self.uri) { - // this will throw if unhandled but is handleable when in a redirect - return self.emit('error', new Error("options.uri is a required argument")) - } else { - if (typeof self.uri == "string") self.uri = url.parse(self.uri) - } - - if (self.strictSSL === false) { - self.rejectUnauthorized = false - } - - if (self.proxy) { - if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) - - // do the HTTP CONNECT dance using koichik/node-tunnel - if (http.globalAgent && self.uri.protocol === "https:") { - var tunnelFn = self.proxy.protocol === "http:" - ? tunnel.httpsOverHttp : tunnel.httpsOverHttps - - var tunnelOptions = { proxy: { host: self.proxy.hostname - , port: +self.proxy.port - , proxyAuth: self.proxy.auth - , headers: { Host: self.uri.hostname + ':' + - (self.uri.port || self.uri.protocol === 'https:' ? 443 : 80) }} - , rejectUnauthorized: self.rejectUnauthorized - , ca: this.ca } - - self.agent = tunnelFn(tunnelOptions) - self.tunnel = true - } - } - - if (!self.uri.host || !self.uri.pathname) { - // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar - // Detect and reject it as soon as possible - var faultyUri = url.format(self.uri) - var message = 'Invalid URI "' + faultyUri + '"' - if (Object.keys(options).length === 0) { - // No option ? This can be the sign of a redirect - // As this is a case where the user cannot do anything (he didn't call request directly with this URL) - // he should be warned that it can be caused by a redirection (can save some hair) - message += '. This can be caused by a crappy redirection.' - } - self.emit('error', new Error(message)) - return // This error was fatal - } - - self._redirectsFollowed = self._redirectsFollowed || 0 - self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 - self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true - self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false - if (self.followRedirect || self.followAllRedirects) - self.redirects = self.redirects || [] - - self.headers = self.headers ? copy(self.headers) : {} - - self.setHost = false - if (!(self.headers.host || self.headers.Host)) { - self.headers.host = self.uri.hostname - if (self.uri.port) { - if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && - !(self.uri.port === 443 && self.uri.protocol === 'https:') ) - self.headers.host += (':'+self.uri.port) - } - self.setHost = true - } - - self.jar(self._jar || options.jar) - - if (!self.uri.pathname) {self.uri.pathname = '/'} - if (!self.uri.port) { - if (self.uri.protocol == 'http:') {self.uri.port = 80} - else if (self.uri.protocol == 'https:') {self.uri.port = 443} - } - - if (self.proxy && !self.tunnel) { - self.port = self.proxy.port - self.host = self.proxy.hostname - } else { - self.port = self.uri.port - self.host = self.uri.hostname - } - - self.clientErrorHandler = function (error) { - if (self._aborted) return - - if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' - && self.agent.addRequestNoreuse) { - self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } - self.start() - self.req.end() - return - } - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - self.emit('error', error) - } - - self._parserErrorHandler = function (error) { - if (this.res) { - if (this.res.request) { - this.res.request.emit('error', error) - } else { - this.res.emit('error', error) - } - } else { - this._httpMessage.emit('error', error) - } - } - - if (options.form) { - self.form(options.form) - } - - if (options.qs) self.qs(options.qs) - - if (self.uri.path) { - self.path = self.uri.path - } else { - self.path = self.uri.pathname + (self.uri.search || "") - } - - if (self.path.length === 0) self.path = '/' - - - // Auth must happen last in case signing is dependent on other headers - if (options.oauth) { - self.oauth(options.oauth) - } - - if (options.aws) { - self.aws(options.aws) - } - - if (options.hawk) { - self.hawk(options.hawk) - } - - if (options.httpSignature) { - self.httpSignature(options.httpSignature) - } - - if (options.auth) { - self.auth( - (options.auth.user==="") ? options.auth.user : (options.auth.user || options.auth.username ), - options.auth.pass || options.auth.password, - options.auth.sendImmediately) - } - - if (self.uri.auth && !self.headers.authorization) { - var authPieces = self.uri.auth.split(':').map(function(item){ return querystring.unescape(item) }) - self.auth(authPieces[0], authPieces.slice(1).join(':'), true) - } - if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) { - self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return querystring.unescape(item)}).join(':')) - } - - - if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - - if (options.json) { - self.json(options.json) - } else if (options.multipart) { - self.boundary = uuid() - self.multipart(options.multipart) - } - - if (self.body) { - var length = 0 - if (!Buffer.isBuffer(self.body)) { - if (Array.isArray(self.body)) { - for (var i = 0; i < self.body.length; i++) { - length += self.body[i].length - } - } else { - self.body = new Buffer(self.body) - length = self.body.length - } - } else { - length = self.body.length - } - if (length) { - if(!self.headers['content-length'] && !self.headers['Content-Length']) - self.headers['content-length'] = length - } else { - throw new Error('Argument error, options.body.') - } - } - - var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol - , defaultModules = {'http:':http, 'https:':https} - , httpModules = self.httpModules || {} - ; - self.httpModule = httpModules[protocol] || defaultModules[protocol] - - if (!self.httpModule) return this.emit('error', new Error("Invalid protocol")) - - if (options.ca) self.ca = options.ca - - if (!self.agent) { - if (options.agentOptions) self.agentOptions = options.agentOptions - - if (options.agentClass) { - self.agentClass = options.agentClass - } else if (options.forever) { - self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL - } else { - self.agentClass = self.httpModule.Agent - } - } - - if (self.pool === false) { - self.agent = false - } else { - self.agent = self.agent || self.getAgent() - if (self.maxSockets) { - // Don't use our pooling if node has the refactored client - self.agent.maxSockets = self.maxSockets - } - if (self.pool.maxSockets) { - // Don't use our pooling if node has the refactored client - self.agent.maxSockets = self.pool.maxSockets - } - } - - self.once('pipe', function (src) { - if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.") - self.src = src - if (isReadStream(src)) { - if (!self.headers['content-type'] && !self.headers['Content-Type']) - self.headers['content-type'] = mime.lookup(src.path) - } else { - if (src.headers) { - for (var i in src.headers) { - if (!self.headers[i]) { - self.headers[i] = src.headers[i] - } - } - } - if (self._json && !self.headers['content-type'] && !self.headers['Content-Type']) - self.headers['content-type'] = 'application/json' - if (src.method && !self.explicitMethod) { - self.method = src.method - } - } - - self.on('pipe', function () { - console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") - }) - }) - - process.nextTick(function () { - if (self._aborted) return - - if (self._form) { - self.setHeaders(self._form.getHeaders()) - self._form.pipe(self) - } - if (self.body) { - if (Array.isArray(self.body)) { - self.body.forEach(function (part) { - self.write(part) - }) - } else { - self.write(self.body) - } - self.end() - } else if (self.requestBodyStream) { - console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") - self.requestBodyStream.pipe(self) - } else if (!self.src) { - if (self.method !== 'GET' && typeof self.method !== 'undefined') { - self.headers['content-length'] = 0 - } - self.end() - } - self.ntick = true - }) -} - -// Must call this when following a redirect from https to http or vice versa -// Attempts to keep everything as identical as possible, but update the -// httpModule, Tunneling agent, and/or Forever Agent in use. -Request.prototype._updateProtocol = function () { - var self = this - var protocol = self.uri.protocol - - if (protocol === 'https:') { - // previously was doing http, now doing https - // if it's https, then we might need to tunnel now. - if (self.proxy) { - self.tunnel = true - var tunnelFn = self.proxy.protocol === 'http:' - ? tunnel.httpsOverHttp : tunnel.httpsOverHttps - var tunnelOptions = { proxy: { host: self.proxy.hostname - , port: +self.proxy.port - , proxyAuth: self.proxy.auth } - , rejectUnauthorized: self.rejectUnauthorized - , ca: self.ca } - self.agent = tunnelFn(tunnelOptions) - return - } - - self.httpModule = https - switch (self.agentClass) { - case ForeverAgent: - self.agentClass = ForeverAgent.SSL - break - case http.Agent: - self.agentClass = https.Agent - break - default: - // nothing we can do. Just hope for the best. - return - } - - // if there's an agent, we need to get a new one. - if (self.agent) self.agent = self.getAgent() - - } else { - // previously was doing https, now doing http - // stop any tunneling. - if (self.tunnel) self.tunnel = false - self.httpModule = http - switch (self.agentClass) { - case ForeverAgent.SSL: - self.agentClass = ForeverAgent - break - case https.Agent: - self.agentClass = http.Agent - break - default: - // nothing we can do. just hope for the best - return - } - - // if there's an agent, then get a new one. - if (self.agent) { - self.agent = null - self.agent = self.getAgent() - } - } -} - -Request.prototype.getAgent = function () { - var Agent = this.agentClass - var options = {} - if (this.agentOptions) { - for (var i in this.agentOptions) { - options[i] = this.agentOptions[i] - } - } - if (this.ca) options.ca = this.ca - if (typeof this.rejectUnauthorized !== 'undefined') options.rejectUnauthorized = this.rejectUnauthorized - - if (this.cert && this.key) { - options.key = this.key - options.cert = this.cert - } - - var poolKey = '' - - // different types of agents are in different pools - if (Agent !== this.httpModule.Agent) { - poolKey += Agent.name - } - - if (!this.httpModule.globalAgent) { - // node 0.4.x - options.host = this.host - options.port = this.port - if (poolKey) poolKey += ':' - poolKey += this.host + ':' + this.port - } - - // ca option is only relevant if proxy or destination are https - var proxy = this.proxy - if (typeof proxy === 'string') proxy = url.parse(proxy) - var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' - if (isHttps) { - if (options.ca) { - if (poolKey) poolKey += ':' - poolKey += options.ca - } - - if (typeof options.rejectUnauthorized !== 'undefined') { - if (poolKey) poolKey += ':' - poolKey += options.rejectUnauthorized - } - - if (options.cert) - poolKey += options.cert.toString('ascii') + options.key.toString('ascii') - } - - if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) { - // not doing anything special. Use the globalAgent - return this.httpModule.globalAgent - } - - // we're using a stored agent. Make sure it's protocol-specific - poolKey = this.uri.protocol + poolKey - - // already generated an agent for this setting - if (this.pool[poolKey]) return this.pool[poolKey] - - return this.pool[poolKey] = new Agent(options) -} - -Request.prototype.start = function () { - // start() is called once we are ready to send the outgoing HTTP request. - // this is usually called on the first write(), end() or on nextTick() - var self = this - - if (self._aborted) return - - self._started = true - self.method = self.method || 'GET' - self.href = self.uri.href - - if (self.src && self.src.stat && self.src.stat.size && !self.headers['content-length'] && !self.headers['Content-Length']) { - self.headers['content-length'] = self.src.stat.size - } - if (self._aws) { - self.aws(self._aws, true) - } - - // We have a method named auth, which is completely different from the http.request - // auth option. If we don't remove it, we're gonna have a bad time. - var reqOptions = copy(self) - delete reqOptions.auth - - debug('make request', self.uri.href) - self.req = self.httpModule.request(reqOptions, self.onResponse.bind(self)) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function () { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - - // Set additional timeout on socket - in case if remote - // server freeze after sending headers - if (self.req.setTimeout) { // only works on node 0.6+ - self.req.setTimeout(self.timeout, function () { - if (self.req) { - self.req.abort() - var e = new Error("ESOCKETTIMEDOUT") - e.code = "ESOCKETTIMEDOUT" - self.emit("error", e) - } - }) - } - } - - self.req.on('error', self.clientErrorHandler) - self.req.on('drain', function() { - self.emit('drain') - }) - self.on('end', function() { - if ( self.req.connection ) self.req.connection.removeListener('error', self._parserErrorHandler) - }) - self.emit('request', self.req) -} -Request.prototype.onResponse = function (response) { - var self = this - debug('onResponse', self.uri.href, response.statusCode, response.headers) - response.on('end', function() { - debug('response end', self.uri.href, response.statusCode, response.headers) - }); - - if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) { - response.connection.once('error', self._parserErrorHandler) - } - if (self._aborted) { - debug('aborted', self.uri.href) - response.resume() - return - } - if (self._paused) response.pause() - else response.resume() - - self.response = response - response.request = self - response.toJSON = toJSON - - // XXX This is different on 0.10, because SSL is strict by default - if (self.httpModule === https && - self.strictSSL && - !response.client.authorized) { - debug('strict ssl error', self.uri.href) - var sslErr = response.client.authorizationError - self.emit('error', new Error('SSL Error: '+ sslErr)) - return - } - - if (self.setHost) delete self.headers.host - if (self.timeout && self.timeoutTimer) { - clearTimeout(self.timeoutTimer) - self.timeoutTimer = null - } - - var addCookie = function (cookie) { - if (self._jar) self._jar.add(new Cookie(cookie)) - else cookieJar.add(new Cookie(cookie)) - } - - if (response.headers['set-cookie'] && (!self._disableCookies)) { - if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie) - else addCookie(response.headers['set-cookie']) - } - - var redirectTo = null - if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { - debug('redirect', response.headers.location) - - if (self.followAllRedirects) { - redirectTo = response.headers.location - } else if (self.followRedirect) { - switch (self.method) { - case 'PATCH': - case 'PUT': - case 'POST': - case 'DELETE': - // Do not follow redirects - break - default: - redirectTo = response.headers.location - break - } - } - } else if (response.statusCode == 401 && self._hasAuth && !self._sentAuth) { - var authHeader = response.headers['www-authenticate'] - var authVerb = authHeader && authHeader.split(' ')[0] - debug('reauth', authVerb) - - switch (authVerb) { - case 'Basic': - self.auth(self._user, self._pass, true) - redirectTo = self.uri - break - - case 'Digest': - // TODO: More complete implementation of RFC 2617. For reference: - // http://tools.ietf.org/html/rfc2617#section-3 - // https://github.com/bagder/curl/blob/master/lib/http_digest.c - - var matches = authHeader.match(/([a-z0-9_-]+)="([^"]+)"/gi) - var challenge = {} - - for (var i = 0; i < matches.length; i++) { - var eqPos = matches[i].indexOf('=') - var key = matches[i].substring(0, eqPos) - var quotedValue = matches[i].substring(eqPos + 1) - challenge[key] = quotedValue.substring(1, quotedValue.length - 1) - } - - var ha1 = md5(self._user + ':' + challenge.realm + ':' + self._pass) - var ha2 = md5(self.method + ':' + self.uri.path) - var digestResponse = md5(ha1 + ':' + challenge.nonce + ':1::auth:' + ha2) - var authValues = { - username: self._user, - realm: challenge.realm, - nonce: challenge.nonce, - uri: self.uri.path, - qop: challenge.qop, - response: digestResponse, - nc: 1, - cnonce: '' - } - - authHeader = [] - for (var k in authValues) { - authHeader.push(k + '="' + authValues[k] + '"') - } - authHeader = 'Digest ' + authHeader.join(', ') - self.setHeader('authorization', authHeader) - self._sentAuth = true - - redirectTo = self.uri - break - } - } - - if (redirectTo) { - debug('redirect to', redirectTo) - - // ignore any potential response body. it cannot possibly be useful - // to us at this point. - if (self._paused) response.resume() - - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop "+self.uri.href)) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(redirectTo)) { - redirectTo = url.resolve(self.uri.href, redirectTo) - } - - var uriPrev = self.uri - self.uri = url.parse(redirectTo) - - // handle the case where we change protocol from https to http or vice versa - if (self.uri.protocol !== uriPrev.protocol) { - self._updateProtocol() - } - - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: redirectTo - } - ) - if (self.followAllRedirects && response.statusCode != 401) self.method = 'GET' - // self.method = 'GET' // Force all redirects to use GET || commented out fixes #215 - delete self.src - delete self.req - delete self.agent - delete self._started - if (response.statusCode != 401) { - // Remove parameters from the previous response, unless this is the second request - // for a server that requires digest authentication. - delete self.body - delete self._form - if (self.headers) { - delete self.headers.host - delete self.headers['content-type'] - delete self.headers['content-length'] - } - } - - self.emit('redirect'); - - self.init() - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.emit('response', response) - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - debug('end event', self.uri.href) - if (self._aborted) { - debug('aborted', self.uri.href) - return - } - - if (buffer.length && Buffer.isBuffer(buffer[0])) { - debug('has body', self.uri.href, bodyLen) - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString(self.encoding) - } - } else if (buffer.length) { - // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. - // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). - if (self.encoding === 'utf8' && buffer[0].length > 0 && buffer[0][0] === "\uFEFF") { - buffer[0] = buffer[0].substring(1) - } - response.body = buffer.join('') - } - - if (self._json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - debug('emitting complete', self.uri.href) - if(response.body == undefined && !self._json) { - response.body = ""; - } - self.emit('complete', response, response.body) - }) - } - } - debug('finish init function', self.uri.href) -} - -Request.prototype.abort = function () { - this._aborted = true - - if (this.req) { - this.req.abort() - } - else if (this.response) { - this.response.abort() - } - - this.emit("abort") -} - -Request.prototype.pipeDest = function (dest) { - var response = this.response - // Called after the response is received - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (this.pipefilter) this.pipefilter(response, dest) -} - -// Composable API -Request.prototype.setHeader = function (name, value, clobber) { - if (clobber === undefined) clobber = true - if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value - else this.headers[name] += ',' + value - return this -} -Request.prototype.setHeaders = function (headers) { - for (var i in headers) {this.setHeader(i, headers[i])} - return this -} -Request.prototype.qs = function (q, clobber) { - var base - if (!clobber && this.uri.query) base = qs.parse(this.uri.query) - else base = {} - - for (var i in q) { - base[i] = q[i] - } - - if (qs.stringify(base) === ''){ - return this - } - - this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) - this.url = this.uri - this.path = this.uri.path - - return this -} -Request.prototype.form = function (form) { - if (form) { - this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - this.body = qs.stringify(form).toString('utf8') - return this - } - // create form-data object - this._form = new FormData() - return this._form -} -Request.prototype.multipart = function (multipart) { - var self = this - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary - } - - if (!multipart.forEach) throw new Error('Argument error, options.multipart.') - - if (self.preambleCRLF) { - self.body.push(new Buffer('\r\n')) - } - - multipart.forEach(function (part) { - var body = part.body - if(body == null) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--' + self.boundary + '\r\n' - Object.keys(part).forEach(function (key) { - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--' + self.boundary + '--')) - return self -} -Request.prototype.json = function (val) { - var self = this; - var setAcceptHeader = function() { - if (!self.headers['accept'] && !self.headers['Accept']) { - self.setHeader('accept', 'application/json') - } - } - setAcceptHeader(); - this._json = true - if (typeof val === 'boolean') { - if (typeof this.body === 'object') { - setAcceptHeader(); - this.body = safeStringify(this.body) - self.setHeader('content-type', 'application/json') - } - } else { - setAcceptHeader(); - this.body = safeStringify(val) - self.setHeader('content-type', 'application/json') - } - return this -} -function getHeader(name, headers) { - var result, re, match - Object.keys(headers).forEach(function (key) { - re = new RegExp(name, 'i') - match = key.match(re) - if (match) result = headers[key] - }) - return result -} -Request.prototype.auth = function (user, pass, sendImmediately) { - if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { - throw new Error('auth() received invalid user or password') - } - this._user = user - this._pass = pass - this._hasAuth = true - if (sendImmediately || typeof sendImmediately == 'undefined') { - this.setHeader('authorization', 'Basic ' + toBase64(user + ':' + pass)) - this._sentAuth = true - } - return this -} -Request.prototype.aws = function (opts, now) { - if (!now) { - this._aws = opts - return this - } - var date = new Date() - this.setHeader('date', date.toUTCString()) - var auth = - { key: opts.key - , secret: opts.secret - , verb: this.method.toUpperCase() - , date: date - , contentType: getHeader('content-type', this.headers) || '' - , md5: getHeader('content-md5', this.headers) || '' - , amazonHeaders: aws.canonicalizeHeaders(this.headers) - } - if (opts.bucket && this.path) { - auth.resource = '/' + opts.bucket + this.path - } else if (opts.bucket && !this.path) { - auth.resource = '/' + opts.bucket - } else if (!opts.bucket && this.path) { - auth.resource = this.path - } else if (!opts.bucket && !this.path) { - auth.resource = '/' - } - auth.resource = aws.canonicalizeResource(auth.resource) - this.setHeader('authorization', aws.authorization(auth)) - - return this -} -Request.prototype.httpSignature = function (opts) { - var req = this - httpSignature.signRequest({ - getHeader: function(header) { - return getHeader(header, req.headers) - }, - setHeader: function(header, value) { - req.setHeader(header, value) - }, - method: this.method, - path: this.path - }, opts) - debug('httpSignature authorization', getHeader('authorization', this.headers)) - - return this -} - -Request.prototype.hawk = function (opts) { - this.headers.Authorization = hawk.client.header(this.uri, this.method, opts).field -} - -Request.prototype.oauth = function (_oauth) { - var form - if (this.headers['content-type'] && - this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(this.body) - } - if (this.uri.query) { - form = qs.parse(this.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in _oauth) oa['oauth_'+i] = _oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - var timestamp = oa.oauth_timestamp - - var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname - var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in _oauth) { - // skip - } else { - delete oa['oauth_'+i] - if (i !== 'x_auth_mode') delete oa[i] - } - } - oa.oauth_timestamp = timestamp - this.headers.Authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - this.headers.Authorization += ',oauth_signature="' + oauth.rfc3986(signature) + '"' - return this -} -Request.prototype.jar = function (jar) { - var cookies - - if (this._redirectsFollowed === 0) { - this.originalCookieHeader = this.headers.cookie - } - - if (jar === false) { - // disable cookies - cookies = false - this._disableCookies = true - } else if (jar) { - // fetch cookie from the user defined cookie jar - cookies = jar.get({ url: this.uri.href }) - } else { - // fetch cookie from the global cookie jar - cookies = cookieJar.get({ url: this.uri.href }) - } - - if (cookies && cookies.length) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value - }).join("; ") - - if (this.originalCookieHeader) { - // Don't overwrite existing Cookie header - this.headers.cookie = this.originalCookieHeader + '; ' + cookieString - } else { - this.headers.cookie = cookieString - } - } - this._jar = jar - return this -} - - -// Stream API -Request.prototype.pipe = function (dest, opts) { - if (this.response) { - if (this._destdata) { - throw new Error("You cannot pipe after data has been emitted from the response.") - } else if (this._ended) { - throw new Error("You cannot pipe after the response has been ended.") - } else { - stream.Stream.prototype.pipe.call(this, dest, opts) - this.pipeDest(dest) - return dest - } - } else { - this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest, opts) - return dest - } -} -Request.prototype.write = function () { - if (!this._started) this.start() - return this.req.write.apply(this.req, arguments) -} -Request.prototype.end = function (chunk) { - if (chunk) this.write(chunk) - if (!this._started) this.start() - this.req.end() -} -Request.prototype.pause = function () { - if (!this.response) this._paused = true - else this.response.pause.apply(this.response, arguments) -} -Request.prototype.resume = function () { - if (!this.response) this._paused = false - else this.response.resume.apply(this.response, arguments) -} -Request.prototype.destroy = function () { - if (!this._ended) this.end() - else if (this.response) this.response.destroy() -} - -// organize params for patch, post, put, head, del -function initParams(uri, options, callback) { - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - uri = options.uri - } - return { uri: uri, options: options, callback: callback } -} - -function request (uri, options, callback) { - if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') - if ((typeof options === 'function') && !callback) callback = options - if (options && typeof options === 'object') { - options.uri = uri - } else if (typeof uri === 'string') { - options = {uri:uri} - } else { - options = uri - } - - options = copy(options) - - if (callback) options.callback = callback - var r = new Request(options) - return r -} - -module.exports = request - -request.debug = process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG) - -request.initParams = initParams - -request.defaults = function (options, requester) { - var def = function (method) { - var d = function (uri, opts, callback) { - var params = initParams(uri, opts, callback) - for (var i in options) { - if (params.options[i] === undefined) params.options[i] = options[i] - } - if(typeof requester === 'function') { - if(method === request) { - method = requester - } else { - params.options._requester = requester - } - } - return method(params.options, params.callback) - } - return d - } - var de = def(request) - de.get = def(request.get) - de.patch = def(request.patch) - de.post = def(request.post) - de.put = def(request.put) - de.head = def(request.head) - de.del = def(request.del) - de.cookie = def(request.cookie) - de.jar = request.jar - return de -} - -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - for (option in optionsArg) { - options[option] = optionsArg[option] - } - } - if (agentOptions) options.agentOptions = agentOptions - options.forever = true - return request.defaults(options) -} - -request.get = request -request.post = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'POST' - return request(params.uri || null, params.options, params.callback) -} -request.put = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'PUT' - return request(params.uri || null, params.options, params.callback) -} -request.patch = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'PATCH' - return request(params.uri || null, params.options, params.callback) -} -request.head = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'HEAD' - if (params.options.body || - params.options.requestBodyStream || - (params.options.json && typeof params.options.json !== 'boolean') || - params.options.multipart) { - throw new Error("HTTP HEAD requests MUST NOT include a request body.") - } - return request(params.uri || null, params.options, params.callback) -} -request.del = function (uri, options, callback) { - var params = initParams(uri, options, callback) - params.options.method = 'DELETE' - if(typeof params.options._requester === 'function') { - request = params.options._requester - } - return request(params.uri || null, params.options, params.callback) -} -request.jar = function () { - return new CookieJar -} -request.cookie = function (str) { - if (str && str.uri) str = str.uri - if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") - return new Cookie(str) -} - -// Safe toJSON - -function getSafe (self, uuid) { - if (typeof self === 'object' || typeof self === 'function') var safe = {} - if (Array.isArray(self)) var safe = [] - - var recurse = [] - - Object.defineProperty(self, uuid, {}) - - var attrs = Object.keys(self).filter(function (i) { - if (i === uuid) return false - if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true - return !(Object.getOwnPropertyDescriptor(self[i], uuid)) - }) - - - for (var i=0;i= 300 && response.statusCode < 400 && - (self.followAllRedirects || - (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) && - response.headers.location) { - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(response.headers.location)) { - response.headers.location = url.resolve(self.uri.href, response.headers.location) - } - self.uri = response.headers.location - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: response.headers.location - } - ) - if (self.followAllRedirects) self.method = 'GET' - // self.method = 'GET'; // Force all redirects to use GET || commented out fixes #215 - delete self.req - delete self.agent - delete self._started - delete self.body - if (self.headers) { - delete self.headers.host - } - if (log) log('Redirect to %uri', self) - self.init() - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - self.emit('response', response) - - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - if (self._aborted) return - - if (buffer.length && Buffer.isBuffer(buffer[0])) { - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString() - } - } else if (buffer.length) { - response.body = buffer.join('') - } - - if (self._json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - - self.emit('complete', response, response.body) - }) - } - } - }) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function() { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - - // Set additional timeout on socket - in case if remote - // server freeze after sending headers - if (self.req.setTimeout) { // only works on node 0.6+ - self.req.setTimeout(self.timeout, function(){ - if (self.req) { - self.req.abort() - var e = new Error("ESOCKETTIMEDOUT") - e.code = "ESOCKETTIMEDOUT" - self.emit("error", e) - } - }) - } - } - - self.req.on('error', self.clientErrorHandler) - - self.emit('request', self.req) -} - -Request.prototype.abort = function() { - this._aborted = true; - - if (this.req) { - this.req.abort() - } - else if (this.response) { - this.response.abort() - } - - this.emit("abort") -} - -Request.prototype.pipeDest = function (dest) { - var response = this.response - // Called after the response is received - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (this.pipefilter) this.pipefilter(response, dest) -} - -// Composable API -Request.prototype.setHeader = function (name, value, clobber) { - if (clobber === undefined) clobber = true - if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value - else this.headers[name] += ',' + value - return this -} -Request.prototype.setHeaders = function (headers) { - for (i in headers) {this.setHeader(i, headers[i])} - return this -} -Request.prototype.qs = function (q, clobber) { - var base - if (!clobber && this.uri.query) base = qs.parse(this.uri.query) - else base = {} - - for (var i in q) { - base[i] = q[i] - } - - this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base)) - this.url = this.uri - - return this -} -Request.prototype.form = function (form) { - this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - this.body = qs.stringify(form).toString('utf8') - return this -} -Request.prototype.multipart = function (multipart) { - var self = this - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related; boundary=frontier'; - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=frontier'; - } - - if (!multipart.forEach) throw new Error('Argument error, options.multipart.') - - multipart.forEach(function (part) { - var body = part.body - if(!body) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--frontier\r\n' - Object.keys(part).forEach(function(key){ - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--frontier--')) - return self -} -Request.prototype.json = function (val) { - this.setHeader('content-type', 'application/json') - this.setHeader('accept', 'application/json') - this._json = true - if (typeof val === 'boolean') { - if (typeof this.body === 'object') this.body = JSON.stringify(this.body) - } else { - this.body = JSON.stringify(val) - } - return this -} -Request.prototype.oauth = function (_oauth) { - var form - if (this.headers['content-type'] && - this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(this.body) - } - if (this.uri.query) { - form = qs.parse(this.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in _oauth) oa['oauth_'+i] = _oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - - var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname - var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in _oauth) { - // skip - } else { - delete oa['oauth_'+i] - } - } - this.headers.Authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - this.headers.Authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' - return this -} -Request.prototype.jar = function (jar) { - var cookies - - if (this._redirectsFollowed === 0) { - this.originalCookieHeader = this.headers.cookie - } - - if (jar === false) { - // disable cookies - cookies = false; - this._disableCookies = true; - } else if (jar) { - // fetch cookie from the user defined cookie jar - cookies = jar.get({ url: this.uri.href }) - } else { - // fetch cookie from the global cookie jar - cookies = cookieJar.get({ url: this.uri.href }) - } - - if (cookies && cookies.length) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value - }).join("; ") - - if (this.originalCookieHeader) { - // Don't overwrite existing Cookie header - this.headers.cookie = this.originalCookieHeader + '; ' + cookieString - } else { - this.headers.cookie = cookieString - } - } - this._jar = jar - return this -} - - -// Stream API -Request.prototype.pipe = function (dest, opts) { - if (this.response) { - if (this._destdata) { - throw new Error("You cannot pipe after data has been emitted from the response.") - } else if (this._ended) { - throw new Error("You cannot pipe after the response has been ended.") - } else { - stream.Stream.prototype.pipe.call(this, dest, opts) - this.pipeDest(dest) - return dest - } - } else { - this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest, opts) - return dest - } -} -Request.prototype.write = function () { - if (!this._started) this.start() - this.req.write.apply(this.req, arguments) -} -Request.prototype.end = function (chunk) { - if (chunk) this.write(chunk) - if (!this._started) this.start() - this.req.end() -} -Request.prototype.pause = function () { - if (!this.response) this._paused = true - else this.response.pause.apply(this.response, arguments) -} -Request.prototype.resume = function () { - if (!this.response) this._paused = false - else this.response.resume.apply(this.response, arguments) -} -Request.prototype.destroy = function () { - if (!this._ended) this.end() -} - -// organize params for post, put, head, del -function initParams(uri, options, callback) { - if ((typeof options === 'function') && !callback) callback = options; - if (typeof options === 'object') { - options.uri = uri; - } else if (typeof uri === 'string') { - options = {uri:uri}; - } else { - options = uri; - uri = options.uri; - } - return { uri: uri, options: options, callback: callback }; -} - -function request (uri, options, callback) { - if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') - if ((typeof options === 'function') && !callback) callback = options; - if (typeof options === 'object') { - options.uri = uri; - } else if (typeof uri === 'string') { - options = {uri:uri}; - } else { - options = uri; - } - - if (callback) options.callback = callback; - var r = new Request(options) - return r -} - -module.exports = request - -request.defaults = function (options) { - var def = function (method) { - var d = function (uri, opts, callback) { - var params = initParams(uri, opts, callback); - for (var i in options) { - if (params.options[i] === undefined) params.options[i] = options[i] - } - return method(params.options, params.callback) - } - return d - } - var de = def(request) - de.get = def(request.get) - de.post = def(request.post) - de.put = def(request.put) - de.head = def(request.head) - de.del = def(request.del) - de.cookie = def(request.cookie) - de.jar = def(request.jar) - return de -} - -request.forever = function (agentOptions, optionsArg) { - var options = {} - if (optionsArg) { - for (option in optionsArg) { - options[option] = optionsArg[option] - } - } - if (agentOptions) options.agentOptions = agentOptions - options.forever = true - return request.defaults(options) -} - -request.get = request -request.post = function (uri, options, callback) { - var params = initParams(uri, options, callback); - params.options.method = 'POST'; - return request(params.uri || null, params.options, params.callback) -} -request.put = function (uri, options, callback) { - var params = initParams(uri, options, callback); - params.options.method = 'PUT' - return request(params.uri || null, params.options, params.callback) -} -request.head = function (uri, options, callback) { - var params = initParams(uri, options, callback); - params.options.method = 'HEAD' - if (params.options.body || - params.options.requestBodyStream || - (params.options.json && typeof params.options.json !== 'boolean') || - params.options.multipart) { - throw new Error("HTTP HEAD requests MUST NOT include a request body.") - } - return request(params.uri || null, params.options, params.callback) -} -request.del = function (uri, options, callback) { - var params = initParams(uri, options, callback); - params.options.method = 'DELETE' - return request(params.uri || null, params.options, params.callback) -} -request.jar = function () { - return new CookieJar -} -request.cookie = function (str) { - if (str && str.uri) str = str.uri - if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") - return new Cookie(str) -} - -// Safe toJSON - -function getSafe (self, uuid) { - if (typeof self === 'object' || typeof self === 'function') var safe = {} - if (Array.isArray(self)) var safe = [] - - var recurse = [] - - Object.defineProperty(self, uuid, {}) - - var attrs = Object.keys(self).filter(function (i) { - if (i === uuid) return false - if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true - return !(Object.getOwnPropertyDescriptor(self[i], uuid)) - }) - - - for (var i=0;i - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var crypto = require('crypto') - , parse = require('url').parse - ; - -/** - * Valid keys. - */ - -var keys = - [ 'acl' - , 'location' - , 'logging' - , 'notification' - , 'partNumber' - , 'policy' - , 'requestPayment' - , 'torrent' - , 'uploadId' - , 'uploads' - , 'versionId' - , 'versioning' - , 'versions' - , 'website' - ] - -/** - * Return an "Authorization" header value with the given `options` - * in the form of "AWS :" - * - * @param {Object} options - * @return {String} - * @api private - */ - -function authorization (options) { - return 'AWS ' + options.key + ':' + sign(options) -} - -module.exports = authorization -module.exports.authorization = authorization - -/** - * Simple HMAC-SHA1 Wrapper - * - * @param {Object} options - * @return {String} - * @api private - */ - -function hmacSha1 (options) { - return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') -} - -module.exports.hmacSha1 = hmacSha1 - -/** - * Create a base64 sha1 HMAC for `options`. - * - * @param {Object} options - * @return {String} - * @api private - */ - -function sign (options) { - options.message = stringToSign(options) - return hmacSha1(options) -} -module.exports.sign = sign - -/** - * Create a base64 sha1 HMAC for `options`. - * - * Specifically to be used with S3 presigned URLs - * - * @param {Object} options - * @return {String} - * @api private - */ - -function signQuery (options) { - options.message = queryStringToSign(options) - return hmacSha1(options) -} -module.exports.signQuery= signQuery - -/** - * Return a string for sign() with the given `options`. - * - * Spec: - * - * \n - * \n - * \n - * \n - * [headers\n] - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function stringToSign (options) { - var headers = options.amazonHeaders || '' - if (headers) headers += '\n' - var r = - [ options.verb - , options.md5 - , options.contentType - , options.date.toUTCString() - , headers + options.resource - ] - return r.join('\n') -} -module.exports.queryStringToSign = stringToSign - -/** - * Return a string for sign() with the given `options`, but is meant exclusively - * for S3 presigned URLs - * - * Spec: - * - * \n - * - * - * @param {Object} options - * @return {String} - * @api private - */ - -function queryStringToSign (options){ - return 'GET\n\n\n' + options.date + '\n' + options.resource -} -module.exports.queryStringToSign = queryStringToSign - -/** - * Perform the following: - * - * - ignore non-amazon headers - * - lowercase fields - * - sort lexicographically - * - trim whitespace between ":" - * - join with newline - * - * @param {Object} headers - * @return {String} - * @api private - */ - -function canonicalizeHeaders (headers) { - var buf = [] - , fields = Object.keys(headers) - ; - for (var i = 0, len = fields.length; i < len; ++i) { - var field = fields[i] - , val = headers[field] - , field = field.toLowerCase() - ; - if (0 !== field.indexOf('x-amz')) continue - buf.push(field + ':' + val) - } - return buf.sort().join('\n') -} -module.exports.canonicalizeHeaders = canonicalizeHeaders - -/** - * Perform the following: - * - * - ignore non sub-resources - * - sort lexicographically - * - * @param {String} resource - * @return {String} - * @api private - */ - -function canonicalizeResource (resource) { - var url = parse(resource, true) - , path = url.pathname - , buf = [] - ; - - Object.keys(url.query).forEach(function(key){ - if (!~keys.indexOf(key)) return - var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) - buf.push(key + val) - }) - - return path + (buf.length ? '?' + buf.sort().join('&') : '') -} -module.exports.canonicalizeResource = canonicalizeResource diff --git a/frontend/express/node_modules/request/node_modules/aws-sign/package.json b/frontend/express/node_modules/request/node_modules/aws-sign/package.json deleted file mode 100644 index 54ebc98142b..00000000000 --- a/frontend/express/node_modules/request/node_modules/aws-sign/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "aws-sign", - "description": "AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/aws-sign" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "aws-sign\n========\n\nAWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/aws-sign/issues" - }, - "_id": "aws-sign@0.3.0", - "_from": "aws-sign@~0.3.0" -} diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/LICENSE b/frontend/express/node_modules/request/node_modules/cookie-jar/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/README.md b/frontend/express/node_modules/request/node_modules/cookie-jar/README.md deleted file mode 100644 index bcd8f8d4451..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/README.md +++ /dev/null @@ -1,4 +0,0 @@ -cookie-jar -========== - -Cookie Jar. Originally pulled from LearnBoost/tobi, maintained as vendor in request, now a standalone module. diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/index.js b/frontend/express/node_modules/request/node_modules/cookie-jar/index.js deleted file mode 100644 index 7d54d940cc7..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/index.js +++ /dev/null @@ -1,67 +0,0 @@ -/*! - * Tobi - Cookie - * Copyright(c) 2010 LearnBoost - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var url = require('url'); - -/** - * Initialize a new `Cookie` with the given cookie `str` and `req`. - * - * @param {String} str - * @param {IncomingRequest} req - * @api private - */ - -var Cookie = exports = module.exports = function Cookie(str, req) { - this.str = str; - - // Map the key/val pairs - str.split(/ *; */).reduce(function(obj, pair){ - var p = pair.indexOf('='); - var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); - var lowerCasedKey = key.toLowerCase(); - var value = p > 0 ? pair.substring(p + 1).trim() : true; - - if (!obj.name) { - // First key is the name - obj.name = key; - obj.value = value; - } - else if (lowerCasedKey === 'httponly') { - obj.httpOnly = value; - } - else { - obj[lowerCasedKey] = value; - } - return obj; - }, this); - - // Expires - this.expires = this.expires - ? new Date(this.expires) - : Infinity; - - // Default or trim path - this.path = this.path - ? this.path.trim(): req - ? url.parse(req.url).pathname: '/'; -}; - -/** - * Return the original cookie string. - * - * @return {String} - * @api public - */ - -Cookie.prototype.toString = function(){ - return this.str; -}; - -module.exports.Jar = require('./jar') \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/jar.js b/frontend/express/node_modules/request/node_modules/cookie-jar/jar.js deleted file mode 100644 index 34920e06201..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/jar.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! -* Tobi - CookieJar -* Copyright(c) 2010 LearnBoost -* MIT Licensed -*/ - -/** -* Module dependencies. -*/ - -var url = require('url'); - -/** -* Initialize a new `CookieJar`. -* -* @api private -*/ - -var CookieJar = exports = module.exports = function CookieJar() { - this.cookies = []; -}; - -/** -* Add the given `cookie` to the jar. -* -* @param {Cookie} cookie -* @api private -*/ - -CookieJar.prototype.add = function(cookie){ - this.cookies = this.cookies.filter(function(c){ - // Avoid duplication (same path, same name) - return !(c.name == cookie.name && c.path == cookie.path); - }); - this.cookies.push(cookie); -}; - -/** -* Get cookies for the given `req`. -* -* @param {IncomingRequest} req -* @return {Array} -* @api private -*/ - -CookieJar.prototype.get = function(req){ - var path = url.parse(req.url).pathname - , now = new Date - , specificity = {}; - return this.cookies.filter(function(cookie){ - if (0 == path.indexOf(cookie.path) && now < cookie.expires - && cookie.path.length > (specificity[cookie.name] || 0)) - return specificity[cookie.name] = cookie.path.length; - }); -}; - -/** -* Return Cookie string for the given `req`. -* -* @param {IncomingRequest} req -* @return {String} -* @api private -*/ - -CookieJar.prototype.cookieString = function(req){ - var cookies = this.get(req); - if (cookies.length) { - return cookies.map(function(cookie){ - return cookie.name + '=' + cookie.value; - }).join('; '); - } -}; diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/package.json b/frontend/express/node_modules/request/node_modules/cookie-jar/package.json deleted file mode 100644 index b42df9b80dc..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "cookie-jar", - "description": "Cookie Jar. Originally pulled form tobi, maintained as vendor in request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/cookie-jar" - }, - "main": "index.js", - "scripts": { - "test": "node tests/run.js" - }, - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "cookie-jar\n==========\n\nCookie Jar. Originally pulled from LearnBoost/tobi, maintained as vendor in request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/cookie-jar/issues" - }, - "_id": "cookie-jar@0.3.0", - "_from": "cookie-jar@~0.3.0" -} diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/run.js b/frontend/express/node_modules/request/node_modules/cookie-jar/tests/run.js deleted file mode 100644 index e717f02a31b..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/run.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn - , exitCode = 0 - , timeout = 10000 - , fs = require('fs') - ; - -fs.readdir(__dirname, function (e, files) { - if (e) throw e - - var tests = files.filter(function (f) {return f.slice(0, 'test-'.length) === 'test-'}) - - var next = function () { - if (tests.length === 0) process.exit(exitCode); - - var file = tests.shift() - console.log(file) - var proc = spawn('node', [ 'tests/' + file ]) - - var killed = false - var t = setTimeout(function () { - proc.kill() - exitCode += 1 - console.error(file + ' timeout') - killed = true - }, timeout) - - proc.stdout.pipe(process.stdout) - proc.stderr.pipe(process.stderr) - proc.on('exit', function (code) { - if (code && !killed) console.error(file + ' failed') - exitCode += code || 0 - clearTimeout(t) - next() - }) - } - next() - -}) - - diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js b/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js deleted file mode 100644 index 2cdc835bb4a..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookie.js +++ /dev/null @@ -1,29 +0,0 @@ -var Cookie = require('../index') - , assert = require('assert'); - -var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; -var cookie = new Cookie(str); - -// test .toString() -assert.equal(cookie.toString(), str); - -// test .path -assert.equal(cookie.path, '/'); - -// test .httpOnly -assert.equal(cookie.httpOnly, true); - -// test .name -assert.equal(cookie.name, 'Sid'); - -// test .value -assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); - -// test .expires -assert.equal(cookie.expires instanceof Date, true); - -// test .path default -var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); -assert.equal(cookie.path, '/bar'); - -console.log('All tests passed'); diff --git a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js b/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js deleted file mode 100644 index a33cfb23217..00000000000 --- a/frontend/express/node_modules/request/node_modules/cookie-jar/tests/test-cookiejar.js +++ /dev/null @@ -1,90 +0,0 @@ -var Cookie = require('../index') - , Jar = Cookie.Jar - , assert = require('assert'); - -function expires(ms) { - return new Date(Date.now() + ms).toUTCString(); -} - -// test .get() expiration -(function() { - var jar = new Jar; - var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); - jar.add(cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 0); - }, 1000); - }, 5); -})(); - -// test .get() path support -(function() { - var jar = new Jar; - var a = new Cookie('sid=1234; path=/'); - var b = new Cookie('sid=1111; path=/foo/bar'); - var c = new Cookie('sid=2222; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - - // should remove the duplicates - assert.equal(jar.cookies.length, 2); - - // same name, same path, latter prevails - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], c); - - // same name, diff path, path specifity prevails, latter prevails - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], a); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=3333; path=/foo/bar'); - var c = new Cookie('pid=3333; path=/foo/bar'); - var d = new Cookie('sid=2222; path=/foo/'); - var e = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - jar.add(d); - jar.add(e); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 2); - assert.equal(cookies[0], b); - assert.equal(cookies[1], c); - - var cookies = jar.get({ url: 'http://foo.com/foo/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], d); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], e); -})(); - -setTimeout(function() { - console.log('All tests passed'); -}, 1200); diff --git a/frontend/express/node_modules/request/node_modules/forever-agent/LICENSE b/frontend/express/node_modules/request/node_modules/forever-agent/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/frontend/express/node_modules/request/node_modules/forever-agent/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/forever-agent/README.md b/frontend/express/node_modules/request/node_modules/forever-agent/README.md deleted file mode 100644 index 9d5b66343c4..00000000000 --- a/frontend/express/node_modules/request/node_modules/forever-agent/README.md +++ /dev/null @@ -1,4 +0,0 @@ -forever-agent -============= - -HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module. diff --git a/frontend/express/node_modules/request/node_modules/forever-agent/index.js b/frontend/express/node_modules/request/node_modules/forever-agent/index.js deleted file mode 100644 index 5c07928aebf..00000000000 --- a/frontend/express/node_modules/request/node_modules/forever-agent/index.js +++ /dev/null @@ -1,119 +0,0 @@ -module.exports = ForeverAgent -ForeverAgent.SSL = ForeverAgentSSL - -var util = require('util') - , Agent = require('http').Agent - , net = require('net') - , tls = require('tls') - , AgentSSL = require('https').Agent - -function ForeverAgent(options) { - var self = this - self.options = options || {} - self.requests = {} - self.sockets = {} - self.freeSockets = {} - self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets - self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets - self.on('free', function(socket, host, port) { - var name = host + ':' + port - if (self.requests[name] && self.requests[name].length) { - self.requests[name].shift().onSocket(socket) - } else if (self.sockets[name].length < self.minSockets) { - if (!self.freeSockets[name]) self.freeSockets[name] = [] - self.freeSockets[name].push(socket) - - // if an error happens while we don't use the socket anyway, meh, throw the socket away - function onIdleError() { - socket.destroy() - } - socket._onIdleError = onIdleError - socket.on('error', onIdleError) - } else { - // If there are no pending requests just destroy the - // socket and it will get removed from the pool. This - // gets us out of timeout issues and allows us to - // default to Connection:keep-alive. - socket.destroy() - } - }) - -} -util.inherits(ForeverAgent, Agent) - -ForeverAgent.defaultMinSockets = 5 - - -ForeverAgent.prototype.createConnection = net.createConnection -ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest -ForeverAgent.prototype.addRequest = function(req, host, port) { - var name = host + ':' + port - if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { - var idleSocket = this.freeSockets[name].pop() - idleSocket.removeListener('error', idleSocket._onIdleError) - delete idleSocket._onIdleError - req._reusedSocket = true - req.onSocket(idleSocket) - } else { - this.addRequestNoreuse(req, host, port) - } -} - -ForeverAgent.prototype.removeSocket = function(s, name, host, port) { - if (this.sockets[name]) { - var index = this.sockets[name].indexOf(s) - if (index !== -1) { - this.sockets[name].splice(index, 1) - } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name] - delete this.requests[name] - } - - if (this.freeSockets[name]) { - var index = this.freeSockets[name].indexOf(s) - if (index !== -1) { - this.freeSockets[name].splice(index, 1) - if (this.freeSockets[name].length === 0) { - delete this.freeSockets[name] - } - } - } - - if (this.requests[name] && this.requests[name].length) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(name, host, port).emit('free') - } -} - -function ForeverAgentSSL (options) { - ForeverAgent.call(this, options) -} -util.inherits(ForeverAgentSSL, ForeverAgent) - -ForeverAgentSSL.prototype.createConnection = createConnectionSSL -ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest - -function createConnectionSSL (port, host, options) { - if (typeof port === 'object') { - options = port; - } else if (typeof host === 'object') { - options = host; - } else if (typeof options === 'object') { - options = options; - } else { - options = {}; - } - - if (typeof port === 'number') { - options.port = port; - } - - if (typeof host === 'string') { - options.host = host; - } - - return tls.connect(options); -} diff --git a/frontend/express/node_modules/request/node_modules/forever-agent/package.json b/frontend/express/node_modules/request/node_modules/forever-agent/package.json deleted file mode 100644 index cf20ed19a26..00000000000 --- a/frontend/express/node_modules/request/node_modules/forever-agent/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "forever-agent", - "description": "HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module.", - "version": "0.5.0", - "repository": { - "url": "https://github.com/mikeal/forever-agent" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "forever-agent\n=============\n\nHTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/forever-agent/issues" - }, - "_id": "forever-agent@0.5.0", - "_from": "forever-agent@~0.5.0" -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/.npmignore b/frontend/express/node_modules/request/node_modules/form-data/.npmignore deleted file mode 100644 index 85957343efd..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -*.un~ -/node_modules/* -/test/tmp -/.idea -*.iml diff --git a/frontend/express/node_modules/request/node_modules/form-data/.travis.yml b/frontend/express/node_modules/request/node_modules/form-data/.travis.yml deleted file mode 100644 index f7e975f5ee0..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.6" - - "0.8" diff --git a/frontend/express/node_modules/request/node_modules/form-data/License b/frontend/express/node_modules/request/node_modules/form-data/License deleted file mode 100644 index c7ff12a2f8a..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. diff --git a/frontend/express/node_modules/request/node_modules/form-data/Makefile b/frontend/express/node_modules/request/node_modules/form-data/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/frontend/express/node_modules/request/node_modules/form-data/Readme.md b/frontend/express/node_modules/request/node_modules/form-data/Readme.md deleted file mode 100644 index db671128534..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/Readme.md +++ /dev/null @@ -1,146 +0,0 @@ -# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data) - -A module to create readable `"multipart/form-data"` streams. Can be used to -submit forms and file uploads to other web applications. - -The API of this module is inspired by the -[XMLHttpRequest-2 FormData Interface][xhr2-fd]. - -[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface - -## Install - -``` -npm install form-data -``` - -## Usage - -In this example we are constructing a form with 3 fields that contain a string, -a buffer and a file stream. - -``` javascript -var FormData = require('form-data'); -var fs = require('fs'); - -var form = new FormData(); -form.append('my_field', 'my value'); -form.append('my_buffer', new Buffer(10)); -form.append('my_file', fs.createReadStream('/foo/bar.jpg')); -``` - -Also you can use http-response stream: - -``` javascript -var FormData = require('form-data'); -var http = require('http'); - -var form = new FormData(); - -http.request('http://nodejs.org/images/logo.png', function(response) { - form.append('my_field', 'my value'); - form.append('my_buffer', new Buffer(10)); - form.append('my_logo', response); -}); -``` - -Or @mikeal's request stream: - -``` javascript -var FormData = require('form-data'); -var request = require('request'); - -var form = new FormData(); - -form.append('my_field', 'my value'); -form.append('my_buffer', new Buffer(10)); -form.append('my_logo', request('http://nodejs.org/images/logo.png')); -``` - -In order to submit this form to a web application, you can use node's http -client interface: - -``` javascript -var http = require('http'); - -var request = http.request({ - method: 'post', - host: 'example.org', - path: '/upload', - headers: form.getHeaders() -}); - -form.pipe(request); - -request.on('response', function(res) { - console.log(res.statusCode); -}); -``` - -Or if you would prefer the `'Content-Length'` header to be set for you: - -``` javascript -form.submit('example.org/upload', function(err, res) { - console.log(res.statusCode); -}); -``` - -To use custom headers and pre-known length in parts: - -``` javascript -var CRLF = '\r\n'; -var form = new FormData(); - -var options = { - header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, - knownLength: 1 -}; - -form.append('my_buffer', buffer, options); - -form.submit('http://example.com/', function(err, res) { - if (err) throw err; - console.log('Done'); -}); -``` - -Form-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide "file"-related information manually: - -``` javascript -someModule.stream(function(err, stdout, stderr) { - if (err) throw err; - - var form = new FormData(); - - form.append('file', stdout, { - filename: 'unicycle.jpg', - contentType: 'image/jpg', - knownLength: 19806 - }); - - form.submit('http://example.com/', function(err, res) { - if (err) throw err; - console.log('Done'); - }); -}); -``` - -For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: - -``` javascript -form.submit({ - host: 'example.com', - path: '/probably.php?extra=params', - auth: 'username:password' -}, function(err, res) { - console.log(res.statusCode); -}); -``` - -## TODO - -- Add new streams (0.10) support and try really hard not to break it for 0.8.x. - -## License - -Form-Data is licensed under the MIT license. diff --git a/frontend/express/node_modules/request/node_modules/form-data/lib/form_data.js b/frontend/express/node_modules/request/node_modules/form-data/lib/form_data.js deleted file mode 100644 index 127b70a9942..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/lib/form_data.js +++ /dev/null @@ -1,292 +0,0 @@ -var CombinedStream = require('combined-stream'); -var util = require('util'); -var path = require('path'); -var http = require('http'); -var https = require('https'); -var parseUrl = require('url').parse; -var fs = require('fs'); -var mime = require('mime'); -var async = require('async'); - -module.exports = FormData; -function FormData() { - this._overheadLength = 0; - this._valueLength = 0; - this._lengthRetrievers = []; - - CombinedStream.call(this); -} -util.inherits(FormData, CombinedStream); - -FormData.LINE_BREAK = '\r\n'; - -FormData.prototype.append = function(field, value, options) { - options = options || {}; - - var append = CombinedStream.prototype.append.bind(this); - - // all that streamy business can't handle numbers - if (typeof value == 'number') value = ''+value; - - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(field, value, options); - - append(header); - append(value); - append(footer); - - // pass along options.knownLength - this._trackLength(header, value, options); -}; - -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; - - // used w/ trackLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } - - this._valueLength += valueLength; - - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - + FormData.LINE_BREAK.length; - - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { - return; - } - - this._lengthRetrievers.push(function(next) { - - // do we already know the size? - // 0 additional leaves value from getSyncLength() - if (options.knownLength != null) { - next(null, 0); - - // check if it's local file - } else if (value.hasOwnProperty('fd')) { - fs.stat(value.path, function(err, stat) { - if (err) { - next(err); - return; - } - - next(null, stat.size); - }); - - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - next(null, +value.headers['content-length']); - - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - next(null, +response.headers['content-length']); - }); - value.resume(); - - // something else - } else { - next('Unknown stream'); - } - }); -}; - -FormData.prototype._multiPartHeader = function(field, value, options) { - var boundary = this.getBoundary(); - var header = ''; - - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (options.header != null) { - header = options.header; - } else { - header += '--' + boundary + FormData.LINE_BREAK + - 'Content-Disposition: form-data; name="' + field + '"'; - - // fs- and request- streams have path property - // or use custom filename and/or contentType - // TODO: Use request's response mime-type - if (options.filename || value.path) { - header += - '; filename="' + path.basename(options.filename || value.path) + '"' + FormData.LINE_BREAK + - 'Content-Type: ' + (options.contentType || mime.lookup(options.filename || value.path)); - - // http response has not - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - header += - '; filename="' + path.basename(value.client._httpMessage.path) + '"' + FormData.LINE_BREAK + - 'Content-Type: ' + value.headers['content-type']; - } - - header += FormData.LINE_BREAK + FormData.LINE_BREAK; - } - - return header; -}; - -FormData.prototype._multiPartFooter = function(field, value, options) { - return function(next) { - var footer = FormData.LINE_BREAK; - - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); - } - - next(footer); - }.bind(this); -}; - -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--'; -}; - -FormData.prototype.getHeaders = function(userHeaders) { - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; - - for (var header in userHeaders) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - - return formHeaders; -} - -FormData.prototype.getCustomHeaders = function(contentType) { - contentType = contentType ? contentType : 'multipart/form-data'; - - var formHeaders = { - 'content-type': contentType + '; boundary=' + this.getBoundary(), - 'content-length': this.getLengthSync() - }; - - return formHeaders; -} - -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } - - return this._boundary; -}; - -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } - - this._boundary = boundary; -}; - -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; - - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - return knownLength; -}; - -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; - - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - - if (!this._lengthRetrievers.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } - - async.parallel(this._lengthRetrievers, function(err, values) { - if (err) { - cb(err); - return; - } - - values.forEach(function(length) { - knownLength += length; - }); - - cb(null, knownLength); - }); -}; - -FormData.prototype.submit = function(params, cb) { - this.getLength(function(err, length) { - - var request - , options - , defaults = { - method : 'post', - port : 80, - headers: this.getHeaders({'Content-Length': length}) - }; - - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { - params = parseUrl(params); - - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname - }, defaults); - } - else // use custom params - { - options = populate(params, defaults); - } - - // https if specified, fallback to http in any other case - if (params.protocol == 'https:') { - // override default port - if (!params.port) options.port = 443; - request = https.request(options); - } else { - request = http.request(options); - } - - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - - return request; - }.bind(this)); -}; - -/* - * Santa's little helpers - */ - -// populates missing values -function populate(dst, src) { - for (var prop in src) { - if (!dst[prop]) dst[prop] = src[prop]; - } - return dst; -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-project b/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-project deleted file mode 100644 index 38100b87f7f..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-project +++ /dev/null @@ -1,8 +0,0 @@ -{ - "folders": - [ - { - "path": "/Users/alexi/Dropbox/Projects/node-form-data" - } - ] -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace b/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace deleted file mode 100644 index e5eb02dc54a..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace +++ /dev/null @@ -1,673 +0,0 @@ -{ - "auto_complete": - { - "selected_items": - [ - [ - "back", - "background-clip" - ], - [ - "di", - "display" - ], - [ - "background-", - "background-position" - ], - [ - "de", - "defaults" - ], - [ - "no", - "normal" - ], - [ - "line", - "line-height" - ] - ] - }, - "buffers": - [ - { - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "line_ending": "Unix" - } - }, - { - "file": "package.json", - "settings": - { - "buffer_size": 673, - "line_ending": "Unix" - } - }, - { - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "line_ending": "Unix" - } - }, - { - "contents": "/*!\n * jQuery JavaScript Library v1.8.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)\n */\n(function( window, undefined ) {\nvar\n // A central reference to the root jQuery(document)\n rootjQuery,\n\n // The deferred used on DOM ready\n readyList,\n\n // Use the correct document accordingly with window argument (sandbox)\n document = window.document,\n location = window.location,\n navigator = window.navigator,\n\n // Map over jQuery in case of overwrite\n _jQuery = window.jQuery,\n\n // Map over the $ in case of overwrite\n _$ = window.$,\n\n // Save a reference to some core methods\n core_push = Array.prototype.push,\n core_slice = Array.prototype.slice,\n core_indexOf = Array.prototype.indexOf,\n core_toString = Object.prototype.toString,\n core_hasOwn = Object.prototype.hasOwnProperty,\n core_trim = String.prototype.trim,\n\n // Define a local copy of jQuery\n jQuery = function( selector, context ) {\n // The jQuery object is actually just the init constructor 'enhanced'\n return new jQuery.fn.init( selector, context, rootjQuery );\n },\n\n // Used for matching numbers\n core_pnum = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source,\n\n // Used for detecting and trimming whitespace\n core_rnotwhite = /\\S/,\n core_rspace = /\\s+/,\n\n // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n // A simple way to check for HTML strings\n // Prioritize #id over to avoid XSS via location.hash (#9521)\n rquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n // Match a standalone tag\n rsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n // JSON RegExp\n rvalidchars = /^[\\],:{}\\s]*$/,\n rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n rvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/g,\n\n // Matches dashed string for camelizing\n rmsPrefix = /^-ms-/,\n rdashAlpha = /-([\\da-z])/gi,\n\n // Used by jQuery.camelCase as callback to replace()\n fcamelCase = function( all, letter ) {\n return ( letter + \"\" ).toUpperCase();\n },\n\n // The ready event handler and self cleanup method\n DOMContentLoaded = function() {\n if ( document.addEventListener ) {\n document.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n jQuery.ready();\n } else if ( document.readyState === \"complete\" ) {\n // we're here because readyState === \"complete\" in oldIE\n // which is good enough for us to call the dom ready!\n document.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n jQuery.ready();\n }\n },\n\n // [[Class]] -> type pairs\n class2type = {};\n\njQuery.fn = jQuery.prototype = {\n constructor: jQuery,\n init: function( selector, context, rootjQuery ) {\n var match, elem, ret, doc;\n\n // Handle $(\"\"), $(null), $(undefined), $(false)\n if ( !selector ) {\n return this;\n }\n\n // Handle $(DOMElement)\n if ( selector.nodeType ) {\n this.context = this[0] = selector;\n this.length = 1;\n return this;\n }\n\n // Handle HTML strings\n if ( typeof selector === \"string\" ) {\n if ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n // Assume that strings that start and end with <> are HTML and skip the regex check\n match = [ null, selector, null ];\n\n } else {\n match = rquickExpr.exec( selector );\n }\n\n // Match html or make sure no context is specified for #id\n if ( match && (match[1] || !context) ) {\n\n // HANDLE: $(html) -> $(array)\n if ( match[1] ) {\n context = context instanceof jQuery ? context[0] : context;\n doc = ( context && context.nodeType ? context.ownerDocument || context : document );\n\n // scripts is true for back-compat\n selector = jQuery.parseHTML( match[1], doc, true );\n if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n this.attr.call( selector, context, true );\n }\n\n return jQuery.merge( this, selector );\n\n // HANDLE: $(#id)\n } else {\n elem = document.getElementById( match[2] );\n\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE and Opera return items\n // by name instead of ID\n if ( elem.id !== match[2] ) {\n return rootjQuery.find( selector );\n }\n\n // Otherwise, we inject the element directly into the jQuery object\n this.length = 1;\n this[0] = elem;\n }\n\n this.context = document;\n this.selector = selector;\n return this;\n }\n\n // HANDLE: $(expr, $(...))\n } else if ( !context || context.jquery ) {\n return ( context || rootjQuery ).find( selector );\n\n // HANDLE: $(expr, context)\n // (which is just equivalent to: $(context).find(expr)\n } else {\n return this.constructor( context ).find( selector );\n }\n\n // HANDLE: $(function)\n // Shortcut for document ready\n } else if ( jQuery.isFunction( selector ) ) {\n return rootjQuery.ready( selector );\n }\n\n if ( selector.selector !== undefined ) {\n this.selector = selector.selector;\n this.context = selector.context;\n }\n\n return jQuery.makeArray( selector, this );\n },\n\n // Start with an empty selector\n selector: \"\",\n\n // The current version of jQuery being used\n jquery: \"1.8.3\",\n\n // The default length of a jQuery object is 0\n length: 0,\n\n // The number of elements contained in the matched element set\n size: function() {\n return this.length;\n },\n\n toArray: function() {\n return core_slice.call( this );\n },\n\n // Get the Nth element in the matched element set OR\n // Get the whole matched element set as a clean array\n get: function( num ) {\n return num == null ?\n\n // Return a 'clean' array\n this.toArray() :\n\n // Return just the object\n ( num < 0 ? this[ this.length + num ] : this[ num ] );\n },\n\n // Take an array of elements and push it onto the stack\n // (returning the new matched element set)\n pushStack: function( elems, name, selector ) {\n\n // Build a new jQuery matched element set\n var ret = jQuery.merge( this.constructor(), elems );\n\n // Add the old object onto the stack (as a reference)\n ret.prevObject = this;\n\n ret.context = this.context;\n\n if ( name === \"find\" ) {\n ret.selector = this.selector + ( this.selector ? \" \" : \"\" ) + selector;\n } else if ( name ) {\n ret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n }\n\n // Return the newly-formed element set\n return ret;\n },\n\n // Execute a callback for every element in the matched set.\n // (You can seed the arguments with an array of args, but this is\n // only used internally.)\n each: function( callback, args ) {\n return jQuery.each( this, callback, args );\n },\n\n ready: function( fn ) {\n // Add the callback\n jQuery.ready.promise().done( fn );\n\n return this;\n },\n\n eq: function( i ) {\n i = +i;\n return i === -1 ?\n this.slice( i ) :\n this.slice( i, i + 1 );\n },\n\n first: function() {\n return this.eq( 0 );\n },\n\n last: function() {\n return this.eq( -1 );\n },\n\n slice: function() {\n return this.pushStack( core_slice.apply( this, arguments ),\n \"slice\", core_slice.call(arguments).join(\",\") );\n },\n\n map: function( callback ) {\n return this.pushStack( jQuery.map(this, function( elem, i ) {\n return callback.call( elem, i, elem );\n }));\n },\n\n end: function() {\n return this.prevObject || this.constructor(null);\n },\n\n // For internal use only.\n // Behaves like an Array's method, not like a jQuery method.\n push: core_push,\n sort: [].sort,\n splice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n var options, name, src, copy, copyIsArray, clone,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length,\n deep = false;\n\n // Handle a deep copy situation\n if ( typeof target === \"boolean\" ) {\n deep = target;\n target = arguments[1] || {};\n // skip the boolean and the target\n i = 2;\n }\n\n // Handle case when target is a string or something (possible in deep copy)\n if ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n target = {};\n }\n\n // extend jQuery itself if only one argument is passed\n if ( length === i ) {\n target = this;\n --i;\n }\n\n for ( ; i < length; i++ ) {\n // Only deal with non-null/undefined values\n if ( (options = arguments[ i ]) != null ) {\n // Extend the base object\n for ( name in options ) {\n src = target[ name ];\n copy = options[ name ];\n\n // Prevent never-ending loop\n if ( target === copy ) {\n continue;\n }\n\n // Recurse if we're merging plain objects or arrays\n if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n if ( copyIsArray ) {\n copyIsArray = false;\n clone = src && jQuery.isArray(src) ? src : [];\n\n } else {\n clone = src && jQuery.isPlainObject(src) ? src : {};\n }\n\n // Never move original objects, clone them\n target[ name ] = jQuery.extend( deep, clone, copy );\n\n // Don't bring in undefined values\n } else if ( copy !== undefined ) {\n target[ name ] = copy;\n }\n }\n }\n }\n\n // Return the modified object\n return target;\n};\n\njQuery.extend({\n noConflict: function( deep ) {\n if ( window.$ === jQuery ) {\n window.$ = _$;\n }\n\n if ( deep && window.jQuery === jQuery ) {\n window.jQuery = _jQuery;\n }\n\n return jQuery;\n },\n\n // Is the DOM ready to be used? Set to true once it occurs.\n isReady: false,\n\n // A counter to track how many items to wait for before\n // the ready event fires. See #6781\n readyWait: 1,\n\n // Hold (or release) the ready event\n holdReady: function( hold ) {\n if ( hold ) {\n jQuery.readyWait++;\n } else {\n jQuery.ready( true );\n }\n },\n\n // Handle when the DOM is ready\n ready: function( wait ) {\n\n // Abort if there are pending holds or we're already ready\n if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n return;\n }\n\n // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n if ( !document.body ) {\n return setTimeout( jQuery.ready, 1 );\n }\n\n // Remember that the DOM is ready\n jQuery.isReady = true;\n\n // If a normal DOM Ready event fired, decrement, and wait if need be\n if ( wait !== true && --jQuery.readyWait > 0 ) {\n return;\n }\n\n // If there are functions bound, to execute\n readyList.resolveWith( document, [ jQuery ] );\n\n // Trigger any bound ready events\n if ( jQuery.fn.trigger ) {\n jQuery( document ).trigger(\"ready\").off(\"ready\");\n }\n },\n\n // See test/unit/core.js for details concerning isFunction.\n // Since version 1.3, DOM methods and functions like alert\n // aren't supported. They return false on IE (#2968).\n isFunction: function( obj ) {\n return jQuery.type(obj) === \"function\";\n },\n\n isArray: Array.isArray || function( obj ) {\n return jQuery.type(obj) === \"array\";\n },\n\n isWindow: function( obj ) {\n return obj != null && obj == obj.window;\n },\n\n isNumeric: function( obj ) {\n return !isNaN( parseFloat(obj) ) && isFinite( obj );\n },\n\n type: function( obj ) {\n return obj == null ?\n String( obj ) :\n class2type[ core_toString.call(obj) ] || \"object\";\n },\n\n isPlainObject: function( obj ) {\n // Must be an Object.\n // Because of IE, we also have to check the presence of the constructor property.\n // Make sure that DOM nodes and window objects don't pass through, as well\n if ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n return false;\n }\n\n try {\n // Not own constructor property must be Object\n if ( obj.constructor &&\n !core_hasOwn.call(obj, \"constructor\") &&\n !core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n return false;\n }\n } catch ( e ) {\n // IE8,9 Will throw exceptions on certain host objects #9897\n return false;\n }\n\n // Own properties are enumerated firstly, so to speed up,\n // if last one is own, then all properties are own.\n\n var key;\n for ( key in obj ) {}\n\n return key === undefined || core_hasOwn.call( obj, key );\n },\n\n isEmptyObject: function( obj ) {\n var name;\n for ( name in obj ) {\n return false;\n }\n return true;\n },\n\n error: function( msg ) {\n throw new Error( msg );\n },\n\n // data: string of html\n // context (optional): If specified, the fragment will be created in this context, defaults to document\n // scripts (optional): If true, will include scripts passed in the html string\n parseHTML: function( data, context, scripts ) {\n var parsed;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n if ( typeof context === \"boolean\" ) {\n scripts = context;\n context = 0;\n }\n context = context || document;\n\n // Single tag\n if ( (parsed = rsingleTag.exec( data )) ) {\n return [ context.createElement( parsed[1] ) ];\n }\n\n parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );\n return jQuery.merge( [],\n (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );\n },\n\n parseJSON: function( data ) {\n if ( !data || typeof data !== \"string\") {\n return null;\n }\n\n // Make sure leading/trailing whitespace is removed (IE can't handle it)\n data = jQuery.trim( data );\n\n // Attempt to parse using the native JSON parser first\n if ( window.JSON && window.JSON.parse ) {\n return window.JSON.parse( data );\n }\n\n // Make sure the incoming data is actual JSON\n // Logic borrowed from http://json.org/json2.js\n if ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n .replace( rvalidtokens, \"]\" )\n .replace( rvalidbraces, \"\")) ) {\n\n return ( new Function( \"return \" + data ) )();\n\n }\n jQuery.error( \"Invalid JSON: \" + data );\n },\n\n // Cross-browser xml parsing\n parseXML: function( data ) {\n var xml, tmp;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n try {\n if ( window.DOMParser ) { // Standard\n tmp = new DOMParser();\n xml = tmp.parseFromString( data , \"text/xml\" );\n } else { // IE\n xml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n xml.async = \"false\";\n xml.loadXML( data );\n }\n } catch( e ) {\n xml = undefined;\n }\n if ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n jQuery.error( \"Invalid XML: \" + data );\n }\n return xml;\n },\n\n noop: function() {},\n\n // Evaluates a script in a global context\n // Workarounds based on findings by Jim Driscoll\n // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n globalEval: function( data ) {\n if ( data && core_rnotwhite.test( data ) ) {\n // We use execScript on Internet Explorer\n // We use an anonymous function so that context is window\n // rather than jQuery in Firefox\n ( window.execScript || function( data ) {\n window[ \"eval\" ].call( window, data );\n } )( data );\n }\n },\n\n // Convert dashed to camelCase; used by the css and data modules\n // Microsoft forgot to hump their vendor prefix (#9572)\n camelCase: function( string ) {\n return string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n },\n\n nodeName: function( elem, name ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n },\n\n // args is for internal usage only\n each: function( obj, callback, args ) {\n var name,\n i = 0,\n length = obj.length,\n isObj = length === undefined || jQuery.isFunction( obj );\n\n if ( args ) {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.apply( obj[ name ], args ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.apply( obj[ i++ ], args ) === false ) {\n break;\n }\n }\n }\n\n // A special, fast, case for the most common use of each\n } else {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {\n break;\n }\n }\n }\n }\n\n return obj;\n },\n\n // Use native String.trim function wherever possible\n trim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n function( text ) {\n return text == null ?\n \"\" :\n core_trim.call( text );\n } :\n\n // Otherwise use our own trimming functionality\n function( text ) {\n return text == null ?\n \"\" :\n ( text + \"\" ).replace( rtrim, \"\" );\n },\n\n // results is for internal usage only\n makeArray: function( arr, results ) {\n var type,\n ret = results || [];\n\n if ( arr != null ) {\n // The window, strings (and functions) also have 'length'\n // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n type = jQuery.type( arr );\n\n if ( arr.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( arr ) ) {\n core_push.call( ret, arr );\n } else {\n jQuery.merge( ret, arr );\n }\n }\n\n return ret;\n },\n\n inArray: function( elem, arr, i ) {\n var len;\n\n if ( arr ) {\n if ( core_indexOf ) {\n return core_indexOf.call( arr, elem, i );\n }\n\n len = arr.length;\n i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n for ( ; i < len; i++ ) {\n // Skip accessing in sparse arrays\n if ( i in arr && arr[ i ] === elem ) {\n return i;\n }\n }\n }\n\n return -1;\n },\n\n merge: function( first, second ) {\n var l = second.length,\n i = first.length,\n j = 0;\n\n if ( typeof l === \"number\" ) {\n for ( ; j < l; j++ ) {\n first[ i++ ] = second[ j ];\n }\n\n } else {\n while ( second[j] !== undefined ) {\n first[ i++ ] = second[ j++ ];\n }\n }\n\n first.length = i;\n\n return first;\n },\n\n grep: function( elems, callback, inv ) {\n var retVal,\n ret = [],\n i = 0,\n length = elems.length;\n inv = !!inv;\n\n // Go through the array, only saving the items\n // that pass the validator function\n for ( ; i < length; i++ ) {\n retVal = !!callback( elems[ i ], i );\n if ( inv !== retVal ) {\n ret.push( elems[ i ] );\n }\n }\n\n return ret;\n },\n\n // arg is for internal usage only\n map: function( elems, callback, arg ) {\n var value, key,\n ret = [],\n i = 0,\n length = elems.length,\n // jquery objects are treated as arrays\n isArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n // Go through the array, translating each of the items to their\n if ( isArray ) {\n for ( ; i < length; i++ ) {\n value = callback( elems[ i ], i, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n\n // Go through every key on the object,\n } else {\n for ( key in elems ) {\n value = callback( elems[ key ], key, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n }\n\n // Flatten any nested arrays\n return ret.concat.apply( [], ret );\n },\n\n // A global GUID counter for objects\n guid: 1,\n\n // Bind a function to a context, optionally partially applying any\n // arguments.\n proxy: function( fn, context ) {\n var tmp, args, proxy;\n\n if ( typeof context === \"string\" ) {\n tmp = fn[ context ];\n context = fn;\n fn = tmp;\n }\n\n // Quick check to determine if target is callable, in the spec\n // this throws a TypeError, but we will just return undefined.\n if ( !jQuery.isFunction( fn ) ) {\n return undefined;\n }\n\n // Simulated bind\n args = core_slice.call( arguments, 2 );\n proxy = function() {\n return fn.apply( context, args.concat( core_slice.call( arguments ) ) );\n };\n\n // Set the guid of unique handler to the same of original handler, so it can be removed\n proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n return proxy;\n },\n\n // Multifunctional method to get and set values of a collection\n // The value/s can optionally be executed if it's a function\n access: function( elems, fn, key, value, chainable, emptyGet, pass ) {\n var exec,\n bulk = key == null,\n i = 0,\n length = elems.length;\n\n // Sets many values\n if ( key && typeof key === \"object\" ) {\n for ( i in key ) {\n jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );\n }\n chainable = 1;\n\n // Sets one value\n } else if ( value !== undefined ) {\n // Optionally, function values get executed if exec is true\n exec = pass === undefined && jQuery.isFunction( value );\n\n if ( bulk ) {\n // Bulk operations only iterate when executing function values\n if ( exec ) {\n exec = fn;\n fn = function( elem, key, value ) {\n return exec.call( jQuery( elem ), value );\n };\n\n // Otherwise they run against the entire set\n } else {\n fn.call( elems, value );\n fn = null;\n }\n }\n\n if ( fn ) {\n for (; i < length; i++ ) {\n fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n }\n }\n\n chainable = 1;\n }\n\n return chainable ?\n elems :\n\n // Gets\n bulk ?\n fn.call( elems ) :\n length ? fn( elems[0], key ) : emptyGet;\n },\n\n now: function() {\n return ( new Date() ).getTime();\n }\n});\n\njQuery.ready.promise = function( obj ) {\n if ( !readyList ) {\n\n readyList = jQuery.Deferred();\n\n // Catch cases where $(document).ready() is called after the browser event has already occurred.\n // we once tried to use readyState \"interactive\" here, but it caused issues like the one\n // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n if ( document.readyState === \"complete\" ) {\n // Handle it asynchronously to allow scripts the opportunity to delay ready\n setTimeout( jQuery.ready, 1 );\n\n // Standards-based browsers support DOMContentLoaded\n } else if ( document.addEventListener ) {\n // Use the handy event callback\n document.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n // A fallback to window.onload, that will always work\n window.addEventListener( \"load\", jQuery.ready, false );\n\n // If IE event model is used\n } else {\n // Ensure firing before onload, maybe late but safe also for iframes\n document.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n // A fallback to window.onload, that will always work\n window.attachEvent( \"onload\", jQuery.ready );\n\n // If IE and not a frame\n // continually check to see if the document is ready\n var top = false;\n\n try {\n top = window.frameElement == null && document.documentElement;\n } catch(e) {}\n\n if ( top && top.doScroll ) {\n (function doScrollCheck() {\n if ( !jQuery.isReady ) {\n\n try {\n // Use the trick by Diego Perini\n // http://javascript.nwbox.com/IEContentLoaded/\n top.doScroll(\"left\");\n } catch(e) {\n return setTimeout( doScrollCheck, 50 );\n }\n\n // and execute any waiting functions\n jQuery.ready();\n }\n })();\n }\n }\n }\n return readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n var object = optionsCache[ options ] = {};\n jQuery.each( options.split( core_rspace ), function( _, flag ) {\n object[ flag ] = true;\n });\n return object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n * options: an optional list of space-separated options that will change how\n * the callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n * once: will ensure the callback list can only be fired once (like a Deferred)\n *\n * memory: will keep track of previous values and will call any callback added\n * after the list has been fired right away with the latest \"memorized\"\n * values (like a Deferred)\n *\n * unique: will ensure a callback can only be added once (no duplicate in the list)\n *\n * stopOnFalse: interrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n // Convert options from String-formatted to Object-formatted if needed\n // (we check in cache first)\n options = typeof options === \"string\" ?\n ( optionsCache[ options ] || createOptions( options ) ) :\n jQuery.extend( {}, options );\n\n var // Last fire value (for non-forgettable lists)\n memory,\n // Flag to know if list was already fired\n fired,\n // Flag to know if list is currently firing\n firing,\n // First callback to fire (used internally by add and fireWith)\n firingStart,\n // End of the loop when firing\n firingLength,\n // Index of currently firing callback (modified by remove if needed)\n firingIndex,\n // Actual callback list\n list = [],\n // Stack of fire calls for repeatable lists\n stack = !options.once && [],\n // Fire callbacks\n fire = function( data ) {\n memory = options.memory && data;\n fired = true;\n firingIndex = firingStart || 0;\n firingStart = 0;\n firingLength = list.length;\n firing = true;\n for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n memory = false; // To prevent further calls using add\n break;\n }\n }\n firing = false;\n if ( list ) {\n if ( stack ) {\n if ( stack.length ) {\n fire( stack.shift() );\n }\n } else if ( memory ) {\n list = [];\n } else {\n self.disable();\n }\n }\n },\n // Actual Callbacks object\n self = {\n // Add a callback or a collection of callbacks to the list\n add: function() {\n if ( list ) {\n // First, we save the current length\n var start = list.length;\n (function add( args ) {\n jQuery.each( args, function( _, arg ) {\n var type = jQuery.type( arg );\n if ( type === \"function\" ) {\n if ( !options.unique || !self.has( arg ) ) {\n list.push( arg );\n }\n } else if ( arg && arg.length && type !== \"string\" ) {\n // Inspect recursively\n add( arg );\n }\n });\n })( arguments );\n // Do we need to add the callbacks to the\n // current firing batch?\n if ( firing ) {\n firingLength = list.length;\n // With memory, if we're not firing then\n // we should call right away\n } else if ( memory ) {\n firingStart = start;\n fire( memory );\n }\n }\n return this;\n },\n // Remove a callback from the list\n remove: function() {\n if ( list ) {\n jQuery.each( arguments, function( _, arg ) {\n var index;\n while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n list.splice( index, 1 );\n // Handle firing indexes\n if ( firing ) {\n if ( index <= firingLength ) {\n firingLength--;\n }\n if ( index <= firingIndex ) {\n firingIndex--;\n }\n }\n }\n });\n }\n return this;\n },\n // Control if a given callback is in the list\n has: function( fn ) {\n return jQuery.inArray( fn, list ) > -1;\n },\n // Remove all callbacks from the list\n empty: function() {\n list = [];\n return this;\n },\n // Have the list do nothing anymore\n disable: function() {\n list = stack = memory = undefined;\n return this;\n },\n // Is it disabled?\n disabled: function() {\n return !list;\n },\n // Lock the list in its current state\n lock: function() {\n stack = undefined;\n if ( !memory ) {\n self.disable();\n }\n return this;\n },\n // Is it locked?\n locked: function() {\n return !stack;\n },\n // Call all callbacks with the given context and arguments\n fireWith: function( context, args ) {\n args = args || [];\n args = [ context, args.slice ? args.slice() : args ];\n if ( list && ( !fired || stack ) ) {\n if ( firing ) {\n stack.push( args );\n } else {\n fire( args );\n }\n }\n return this;\n },\n // Call all the callbacks with the given arguments\n fire: function() {\n self.fireWith( this, arguments );\n return this;\n },\n // To know if the callbacks have already been called at least once\n fired: function() {\n return !!fired;\n }\n };\n\n return self;\n};\njQuery.extend({\n\n Deferred: function( func ) {\n var tuples = [\n // action, add listener, listener list, final state\n [ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n [ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n [ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n ],\n state = \"pending\",\n promise = {\n state: function() {\n return state;\n },\n always: function() {\n deferred.done( arguments ).fail( arguments );\n return this;\n },\n then: function( /* fnDone, fnFail, fnProgress */ ) {\n var fns = arguments;\n return jQuery.Deferred(function( newDefer ) {\n jQuery.each( tuples, function( i, tuple ) {\n var action = tuple[ 0 ],\n fn = fns[ i ];\n // deferred[ done | fail | progress ] for forwarding actions to newDefer\n deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?\n function() {\n var returned = fn.apply( this, arguments );\n if ( returned && jQuery.isFunction( returned.promise ) ) {\n returned.promise()\n .done( newDefer.resolve )\n .fail( newDefer.reject )\n .progress( newDefer.notify );\n } else {\n newDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n }\n } :\n newDefer[ action ]\n );\n });\n fns = null;\n }).promise();\n },\n // Get a promise for this deferred\n // If obj is provided, the promise aspect is added to the object\n promise: function( obj ) {\n return obj != null ? jQuery.extend( obj, promise ) : promise;\n }\n },\n deferred = {};\n\n // Keep pipe for back-compat\n promise.pipe = promise.then;\n\n // Add list-specific methods\n jQuery.each( tuples, function( i, tuple ) {\n var list = tuple[ 2 ],\n stateString = tuple[ 3 ];\n\n // promise[ done | fail | progress ] = list.add\n promise[ tuple[1] ] = list.add;\n\n // Handle state\n if ( stateString ) {\n list.add(function() {\n // state = [ resolved | rejected ]\n state = stateString;\n\n // [ reject_list | resolve_list ].disable; progress_list.lock\n }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n }\n\n // deferred[ resolve | reject | notify ] = list.fire\n deferred[ tuple[0] ] = list.fire;\n deferred[ tuple[0] + \"With\" ] = list.fireWith;\n });\n\n // Make the deferred a promise\n promise.promise( deferred );\n\n // Call given func if any\n if ( func ) {\n func.call( deferred, deferred );\n }\n\n // All done!\n return deferred;\n },\n\n // Deferred helper\n when: function( subordinate /* , ..., subordinateN */ ) {\n var i = 0,\n resolveValues = core_slice.call( arguments ),\n length = resolveValues.length,\n\n // the count of uncompleted subordinates\n remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n // the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n deferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n // Update function for both resolve and progress values\n updateFunc = function( i, contexts, values ) {\n return function( value ) {\n contexts[ i ] = this;\n values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n if( values === progressValues ) {\n deferred.notifyWith( contexts, values );\n } else if ( !( --remaining ) ) {\n deferred.resolveWith( contexts, values );\n }\n };\n },\n\n progressValues, progressContexts, resolveContexts;\n\n // add listeners to Deferred subordinates; treat others as resolved\n if ( length > 1 ) {\n progressValues = new Array( length );\n progressContexts = new Array( length );\n resolveContexts = new Array( length );\n for ( ; i < length; i++ ) {\n if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n resolveValues[ i ].promise()\n .done( updateFunc( i, resolveContexts, resolveValues ) )\n .fail( deferred.reject )\n .progress( updateFunc( i, progressContexts, progressValues ) );\n } else {\n --remaining;\n }\n }\n }\n\n // if we're not waiting on anything, resolve the master\n if ( !remaining ) {\n deferred.resolveWith( resolveContexts, resolveValues );\n }\n\n return deferred.promise();\n }\n});\njQuery.support = (function() {\n\n var support,\n all,\n a,\n select,\n opt,\n input,\n fragment,\n eventName,\n i,\n isSupported,\n clickFn,\n div = document.createElement(\"div\");\n\n // Setup\n div.setAttribute( \"className\", \"t\" );\n div.innerHTML = \"
    a\";\n\n // Support tests won't run in some limited or non-browser environments\n all = div.getElementsByTagName(\"*\");\n a = div.getElementsByTagName(\"a\")[ 0 ];\n if ( !all || !a || !all.length ) {\n return {};\n }\n\n // First batch of tests\n select = document.createElement(\"select\");\n opt = select.appendChild( document.createElement(\"option\") );\n input = div.getElementsByTagName(\"input\")[ 0 ];\n\n a.style.cssText = \"top:1px;float:left;opacity:.5\";\n support = {\n // IE strips leading whitespace when .innerHTML is used\n leadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n // Make sure that tbody elements aren't automatically inserted\n // IE will insert them into empty tables\n tbody: !div.getElementsByTagName(\"tbody\").length,\n\n // Make sure that link elements get serialized correctly by innerHTML\n // This requires a wrapper element in IE\n htmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n // Get the style information from getAttribute\n // (IE uses .cssText instead)\n style: /top/.test( a.getAttribute(\"style\") ),\n\n // Make sure that URLs aren't manipulated\n // (IE normalizes it by default)\n hrefNormalized: ( a.getAttribute(\"href\") === \"/a\" ),\n\n // Make sure that element opacity exists\n // (IE uses filter instead)\n // Use a regex to work around a WebKit issue. See #5145\n opacity: /^0.5/.test( a.style.opacity ),\n\n // Verify style float existence\n // (IE uses styleFloat instead of cssFloat)\n cssFloat: !!a.style.cssFloat,\n\n // Make sure that if no value is specified for a checkbox\n // that it defaults to \"on\".\n // (WebKit defaults to \"\" instead)\n checkOn: ( input.value === \"on\" ),\n\n // Make sure that a selected-by-default option has a working selected property.\n // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n optSelected: opt.selected,\n\n // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n getSetAttribute: div.className !== \"t\",\n\n // Tests for enctype support on a form (#6743)\n enctype: !!document.createElement(\"form\").enctype,\n\n // Makes sure cloning an html5 element does not cause problems\n // Where outerHTML is undefined, this still works\n html5Clone: document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav>\",\n\n // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode\n boxModel: ( document.compatMode === \"CSS1Compat\" ),\n\n // Will be defined later\n submitBubbles: true,\n changeBubbles: true,\n focusinBubbles: false,\n deleteExpando: true,\n noCloneEvent: true,\n inlineBlockNeedsLayout: false,\n shrinkWrapBlocks: false,\n reliableMarginRight: true,\n boxSizingReliable: true,\n pixelPosition: false\n };\n\n // Make sure checked status is properly cloned\n input.checked = true;\n support.noCloneChecked = input.cloneNode( true ).checked;\n\n // Make sure that the options inside disabled selects aren't marked as disabled\n // (WebKit marks them as disabled)\n select.disabled = true;\n support.optDisabled = !opt.disabled;\n\n // Test to see if it's possible to delete an expando from an element\n // Fails in Internet Explorer\n try {\n delete div.test;\n } catch( e ) {\n support.deleteExpando = false;\n }\n\n if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n div.attachEvent( \"onclick\", clickFn = function() {\n // Cloning a node shouldn't copy over any\n // bound event handlers (IE does this)\n support.noCloneEvent = false;\n });\n div.cloneNode( true ).fireEvent(\"onclick\");\n div.detachEvent( \"onclick\", clickFn );\n }\n\n // Check if a radio maintains its value\n // after being appended to the DOM\n input = document.createElement(\"input\");\n input.value = \"t\";\n input.setAttribute( \"type\", \"radio\" );\n support.radioValue = input.value === \"t\";\n\n input.setAttribute( \"checked\", \"checked\" );\n\n // #11217 - WebKit loses check when the name is after the checked attribute\n input.setAttribute( \"name\", \"t\" );\n\n div.appendChild( input );\n fragment = document.createDocumentFragment();\n fragment.appendChild( div.lastChild );\n\n // WebKit doesn't clone checked state correctly in fragments\n support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n // Check if a disconnected checkbox will retain its checked\n // value of true after appended to the DOM (IE6/7)\n support.appendChecked = input.checked;\n\n fragment.removeChild( input );\n fragment.appendChild( div );\n\n // Technique from Juriy Zaytsev\n // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/\n // We only care about the case where non-standard event systems\n // are used, namely in IE. Short-circuiting here helps us to\n // avoid an eval call (in setAttribute) which can cause CSP\n // to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n if ( div.attachEvent ) {\n for ( i in {\n submit: true,\n change: true,\n focusin: true\n }) {\n eventName = \"on\" + i;\n isSupported = ( eventName in div );\n if ( !isSupported ) {\n div.setAttribute( eventName, \"return;\" );\n isSupported = ( typeof div[ eventName ] === \"function\" );\n }\n support[ i + \"Bubbles\" ] = isSupported;\n }\n }\n\n // Run tests that need a body at doc ready\n jQuery(function() {\n var container, div, tds, marginDiv,\n divReset = \"padding:0;margin:0;border:0;display:block;overflow:hidden;\",\n body = document.getElementsByTagName(\"body\")[0];\n\n if ( !body ) {\n // Return for frameset docs that don't have a body\n return;\n }\n\n container = document.createElement(\"div\");\n container.style.cssText = \"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px\";\n body.insertBefore( container, body.firstChild );\n\n // Construct the test element\n div = document.createElement(\"div\");\n container.appendChild( div );\n\n // Check if table cells still have offsetWidth/Height when they are set\n // to display:none and there are still other visible table cells in a\n // table row; if so, offsetWidth/Height are not reliable for use when\n // determining if an element has been hidden directly using\n // display:none (it is still safe to use offsets if a parent element is\n // hidden; don safety goggles and see bug #4512 for more information).\n // (only IE 8 fails this test)\n div.innerHTML = \"
    t
    \";\n tds = div.getElementsByTagName(\"td\");\n tds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n isSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n tds[ 0 ].style.display = \"\";\n tds[ 1 ].style.display = \"none\";\n\n // Check if empty table cells still have offsetWidth/Height\n // (IE <= 8 fail this test)\n support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n // Check box-sizing and margin behavior\n div.innerHTML = \"\";\n div.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n support.boxSizing = ( div.offsetWidth === 4 );\n support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );\n\n // NOTE: To any future maintainer, we've window.getComputedStyle\n // because jsdom on node.js will break without it.\n if ( window.getComputedStyle ) {\n support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n // Check if div with explicit width and no margin-right incorrectly\n // gets computed margin-right based on width of container. For more\n // info see bug #3333\n // Fails in WebKit before Feb 2011 nightlies\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n marginDiv = document.createElement(\"div\");\n marginDiv.style.cssText = div.style.cssText = divReset;\n marginDiv.style.marginRight = marginDiv.style.width = \"0\";\n div.style.width = \"1px\";\n div.appendChild( marginDiv );\n support.reliableMarginRight =\n !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n }\n\n if ( typeof div.style.zoom !== \"undefined\" ) {\n // Check if natively block-level elements act like inline-block\n // elements when setting their display to 'inline' and giving\n // them layout\n // (IE < 8 does this)\n div.innerHTML = \"\";\n div.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n // Check if elements with layout shrink-wrap their children\n // (IE 6 does this)\n div.style.display = \"block\";\n div.style.overflow = \"visible\";\n div.innerHTML = \"
    \";\n div.firstChild.style.width = \"5px\";\n support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n container.style.zoom = 1;\n }\n\n // Null elements to avoid leaks in IE\n body.removeChild( container );\n container = div = tds = marginDiv = null;\n });\n\n // Null elements to avoid leaks in IE\n fragment.removeChild( div );\n all = a = select = opt = input = fragment = div = null;\n\n return support;\n})();\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n rmultiDash = /([A-Z])/g;\n\njQuery.extend({\n cache: {},\n\n deletedIds: [],\n\n // Remove at next major release (1.9/2.0)\n uuid: 0,\n\n // Unique for each copy of jQuery on the page\n // Non-digits removed to match rinlinejQuery\n expando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n // The following elements throw uncatchable exceptions if you\n // attempt to add expando properties to them.\n noData: {\n \"embed\": true,\n // Ban all objects except for Flash (which handle expandos)\n \"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n \"applet\": true\n },\n\n hasData: function( elem ) {\n elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n return !!elem && !isEmptyDataObject( elem );\n },\n\n data: function( elem, name, data, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, ret,\n internalKey = jQuery.expando,\n getByName = typeof name === \"string\",\n\n // We have to handle DOM nodes and JS objects differently because IE6-7\n // can't GC object references properly across the DOM-JS boundary\n isNode = elem.nodeType,\n\n // Only DOM nodes need the global jQuery cache; JS object data is\n // attached directly to the object so GC can occur automatically\n cache = isNode ? jQuery.cache : elem,\n\n // Only defining an ID for JS objects if its cache already exists allows\n // the code to shortcut on the same path as a DOM node with no cache\n id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n // Avoid doing any more work than we need to when trying to get data on an\n // object that has no data at all\n if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {\n return;\n }\n\n if ( !id ) {\n // Only DOM nodes need a new unique ID for each element since their data\n // ends up in the global cache\n if ( isNode ) {\n elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;\n } else {\n id = internalKey;\n }\n }\n\n if ( !cache[ id ] ) {\n cache[ id ] = {};\n\n // Avoids exposing jQuery metadata on plain JS objects when the object\n // is serialized using JSON.stringify\n if ( !isNode ) {\n cache[ id ].toJSON = jQuery.noop;\n }\n }\n\n // An object can be passed to jQuery.data instead of a key/value pair; this gets\n // shallow copied over onto the existing cache\n if ( typeof name === \"object\" || typeof name === \"function\" ) {\n if ( pvt ) {\n cache[ id ] = jQuery.extend( cache[ id ], name );\n } else {\n cache[ id ].data = jQuery.extend( cache[ id ].data, name );\n }\n }\n\n thisCache = cache[ id ];\n\n // jQuery data() is stored in a separate object inside the object's internal data\n // cache in order to avoid key collisions between internal data and user-defined\n // data.\n if ( !pvt ) {\n if ( !thisCache.data ) {\n thisCache.data = {};\n }\n\n thisCache = thisCache.data;\n }\n\n if ( data !== undefined ) {\n thisCache[ jQuery.camelCase( name ) ] = data;\n }\n\n // Check for both converted-to-camel and non-converted data property names\n // If a data property was specified\n if ( getByName ) {\n\n // First Try to find as-is property data\n ret = thisCache[ name ];\n\n // Test for null|undefined property data\n if ( ret == null ) {\n\n // Try to find the camelCased property\n ret = thisCache[ jQuery.camelCase( name ) ];\n }\n } else {\n ret = thisCache;\n }\n\n return ret;\n },\n\n removeData: function( elem, name, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, i, l,\n\n isNode = elem.nodeType,\n\n // See jQuery.data for more information\n cache = isNode ? jQuery.cache : elem,\n id = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n // If there is already no cache entry for this object, there is no\n // purpose in continuing\n if ( !cache[ id ] ) {\n return;\n }\n\n if ( name ) {\n\n thisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n if ( thisCache ) {\n\n // Support array or space separated string names for data keys\n if ( !jQuery.isArray( name ) ) {\n\n // try the string as a key before any manipulation\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n\n // split the camel cased version by spaces unless a key with the spaces exists\n name = jQuery.camelCase( name );\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n name = name.split(\" \");\n }\n }\n }\n\n for ( i = 0, l = name.length; i < l; i++ ) {\n delete thisCache[ name[i] ];\n }\n\n // If there is no data left in the cache, we want to continue\n // and let the cache object itself get destroyed\n if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {\n return;\n }\n }\n }\n\n // See jQuery.data for more information\n if ( !pvt ) {\n delete cache[ id ].data;\n\n // Don't destroy the parent cache unless the internal data object\n // had been the only thing left in it\n if ( !isEmptyDataObject( cache[ id ] ) ) {\n return;\n }\n }\n\n // Destroy the cache\n if ( isNode ) {\n jQuery.cleanData( [ elem ], true );\n\n // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n } else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n delete cache[ id ];\n\n // When all else fails, null\n } else {\n cache[ id ] = null;\n }\n },\n\n // For internal use only.\n _data: function( elem, name, data ) {\n return jQuery.data( elem, name, data, true );\n },\n\n // A method for determining if a DOM node can handle the data expando\n acceptData: function( elem ) {\n var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n // nodes accept data unless otherwise specified; rejection can be conditional\n return !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n }\n});\n\njQuery.fn.extend({\n data: function( key, value ) {\n var parts, part, attr, name, l,\n elem = this[0],\n i = 0,\n data = null;\n\n // Gets all values\n if ( key === undefined ) {\n if ( this.length ) {\n data = jQuery.data( elem );\n\n if ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n attr = elem.attributes;\n for ( l = attr.length; i < l; i++ ) {\n name = attr[i].name;\n\n if ( !name.indexOf( \"data-\" ) ) {\n name = jQuery.camelCase( name.substring(5) );\n\n dataAttr( elem, name, data[ name ] );\n }\n }\n jQuery._data( elem, \"parsedAttrs\", true );\n }\n }\n\n return data;\n }\n\n // Sets multiple values\n if ( typeof key === \"object\" ) {\n return this.each(function() {\n jQuery.data( this, key );\n });\n }\n\n parts = key.split( \".\", 2 );\n parts[1] = parts[1] ? \".\" + parts[1] : \"\";\n part = parts[1] + \"!\";\n\n return jQuery.access( this, function( value ) {\n\n if ( value === undefined ) {\n data = this.triggerHandler( \"getData\" + part, [ parts[0] ] );\n\n // Try to fetch any internally stored data first\n if ( data === undefined && elem ) {\n data = jQuery.data( elem, key );\n data = dataAttr( elem, key, data );\n }\n\n return data === undefined && parts[1] ?\n this.data( parts[0] ) :\n data;\n }\n\n parts[1] = value;\n this.each(function() {\n var self = jQuery( this );\n\n self.triggerHandler( \"setData\" + part, parts );\n jQuery.data( this, key, value );\n self.triggerHandler( \"changeData\" + part, parts );\n });\n }, null, value, arguments.length > 1, null, false );\n },\n\n removeData: function( key ) {\n return this.each(function() {\n jQuery.removeData( this, key );\n });\n }\n});\n\nfunction dataAttr( elem, key, data ) {\n // If nothing was found internally, try to fetch any\n // data from the HTML5 data-* attribute\n if ( data === undefined && elem.nodeType === 1 ) {\n\n var name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n data = elem.getAttribute( name );\n\n if ( typeof data === \"string\" ) {\n try {\n data = data === \"true\" ? true :\n data === \"false\" ? false :\n data === \"null\" ? null :\n // Only convert to a number if it doesn't change the string\n +data + \"\" === data ? +data :\n rbrace.test( data ) ? jQuery.parseJSON( data ) :\n data;\n } catch( e ) {}\n\n // Make sure we set the data so it isn't changed later\n jQuery.data( elem, key, data );\n\n } else {\n data = undefined;\n }\n }\n\n return data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n var name;\n for ( name in obj ) {\n\n // if the public data object is empty, the private is still empty\n if ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n continue;\n }\n if ( name !== \"toJSON\" ) {\n return false;\n }\n }\n\n return true;\n}\njQuery.extend({\n queue: function( elem, type, data ) {\n var queue;\n\n if ( elem ) {\n type = ( type || \"fx\" ) + \"queue\";\n queue = jQuery._data( elem, type );\n\n // Speed up dequeue by getting out quickly if this is just a lookup\n if ( data ) {\n if ( !queue || jQuery.isArray(data) ) {\n queue = jQuery._data( elem, type, jQuery.makeArray(data) );\n } else {\n queue.push( data );\n }\n }\n return queue || [];\n }\n },\n\n dequeue: function( elem, type ) {\n type = type || \"fx\";\n\n var queue = jQuery.queue( elem, type ),\n startLength = queue.length,\n fn = queue.shift(),\n hooks = jQuery._queueHooks( elem, type ),\n next = function() {\n jQuery.dequeue( elem, type );\n };\n\n // If the fx queue is dequeued, always remove the progress sentinel\n if ( fn === \"inprogress\" ) {\n fn = queue.shift();\n startLength--;\n }\n\n if ( fn ) {\n\n // Add a progress sentinel to prevent the fx queue from being\n // automatically dequeued\n if ( type === \"fx\" ) {\n queue.unshift( \"inprogress\" );\n }\n\n // clear up the last queue stop function\n delete hooks.stop;\n fn.call( elem, next, hooks );\n }\n\n if ( !startLength && hooks ) {\n hooks.empty.fire();\n }\n },\n\n // not intended for public consumption - generates a queueHooks object, or returns the current one\n _queueHooks: function( elem, type ) {\n var key = type + \"queueHooks\";\n return jQuery._data( elem, key ) || jQuery._data( elem, key, {\n empty: jQuery.Callbacks(\"once memory\").add(function() {\n jQuery.removeData( elem, type + \"queue\", true );\n jQuery.removeData( elem, key, true );\n })\n });\n }\n});\n\njQuery.fn.extend({\n queue: function( type, data ) {\n var setter = 2;\n\n if ( typeof type !== \"string\" ) {\n data = type;\n type = \"fx\";\n setter--;\n }\n\n if ( arguments.length < setter ) {\n return jQuery.queue( this[0], type );\n }\n\n return data === undefined ?\n this :\n this.each(function() {\n var queue = jQuery.queue( this, type, data );\n\n // ensure a hooks for this queue\n jQuery._queueHooks( this, type );\n\n if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n jQuery.dequeue( this, type );\n }\n });\n },\n dequeue: function( type ) {\n return this.each(function() {\n jQuery.dequeue( this, type );\n });\n },\n // Based off of the plugin by Clint Helfers, with permission.\n // http://blindsignals.com/index.php/2009/07/jquery-delay/\n delay: function( time, type ) {\n time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n type = type || \"fx\";\n\n return this.queue( type, function( next, hooks ) {\n var timeout = setTimeout( next, time );\n hooks.stop = function() {\n clearTimeout( timeout );\n };\n });\n },\n clearQueue: function( type ) {\n return this.queue( type || \"fx\", [] );\n },\n // Get a promise resolved when queues of a certain type\n // are emptied (fx is the type by default)\n promise: function( type, obj ) {\n var tmp,\n count = 1,\n defer = jQuery.Deferred(),\n elements = this,\n i = this.length,\n resolve = function() {\n if ( !( --count ) ) {\n defer.resolveWith( elements, [ elements ] );\n }\n };\n\n if ( typeof type !== \"string\" ) {\n obj = type;\n type = undefined;\n }\n type = type || \"fx\";\n\n while( i-- ) {\n tmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n if ( tmp && tmp.empty ) {\n count++;\n tmp.empty.add( resolve );\n }\n }\n resolve();\n return defer.promise( obj );\n }\n});\nvar nodeHook, boolHook, fixSpecified,\n rclass = /[\\t\\r\\n]/g,\n rreturn = /\\r/g,\n rtype = /^(?:button|input)$/i,\n rfocusable = /^(?:button|input|object|select|textarea)$/i,\n rclickable = /^a(?:rea|)$/i,\n rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n getSetAttribute = jQuery.support.getSetAttribute;\n\njQuery.fn.extend({\n attr: function( name, value ) {\n return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n },\n\n removeAttr: function( name ) {\n return this.each(function() {\n jQuery.removeAttr( this, name );\n });\n },\n\n prop: function( name, value ) {\n return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n },\n\n removeProp: function( name ) {\n name = jQuery.propFix[ name ] || name;\n return this.each(function() {\n // try/catch handles cases where IE balks (such as removing a property on window)\n try {\n this[ name ] = undefined;\n delete this[ name ];\n } catch( e ) {}\n });\n },\n\n addClass: function( value ) {\n var classNames, i, l, elem,\n setClass, c, cl;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).addClass( value.call(this, j, this.className) );\n });\n }\n\n if ( value && typeof value === \"string\" ) {\n classNames = value.split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n\n if ( elem.nodeType === 1 ) {\n if ( !elem.className && classNames.length === 1 ) {\n elem.className = value;\n\n } else {\n setClass = \" \" + elem.className + \" \";\n\n for ( c = 0, cl = classNames.length; c < cl; c++ ) {\n if ( setClass.indexOf( \" \" + classNames[ c ] + \" \" ) < 0 ) {\n setClass += classNames[ c ] + \" \";\n }\n }\n elem.className = jQuery.trim( setClass );\n }\n }\n }\n }\n\n return this;\n },\n\n removeClass: function( value ) {\n var removes, className, elem, c, cl, i, l;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).removeClass( value.call(this, j, this.className) );\n });\n }\n if ( (value && typeof value === \"string\") || value === undefined ) {\n removes = ( value || \"\" ).split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n if ( elem.nodeType === 1 && elem.className ) {\n\n className = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\n // loop over each item in the removal list\n for ( c = 0, cl = removes.length; c < cl; c++ ) {\n // Remove until there is nothing to remove,\n while ( className.indexOf(\" \" + removes[ c ] + \" \") >= 0 ) {\n className = className.replace( \" \" + removes[ c ] + \" \" , \" \" );\n }\n }\n elem.className = value ? jQuery.trim( className ) : \"\";\n }\n }\n }\n\n return this;\n },\n\n toggleClass: function( value, stateVal ) {\n var type = typeof value,\n isBool = typeof stateVal === \"boolean\";\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( i ) {\n jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n });\n }\n\n return this.each(function() {\n if ( type === \"string\" ) {\n // toggle individual class names\n var className,\n i = 0,\n self = jQuery( this ),\n state = stateVal,\n classNames = value.split( core_rspace );\n\n while ( (className = classNames[ i++ ]) ) {\n // check each className given, space separated list\n state = isBool ? state : !self.hasClass( className );\n self[ state ? \"addClass\" : \"removeClass\" ]( className );\n }\n\n } else if ( type === \"undefined\" || type === \"boolean\" ) {\n if ( this.className ) {\n // store className if set\n jQuery._data( this, \"__className__\", this.className );\n }\n\n // toggle whole className\n this.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n }\n });\n },\n\n hasClass: function( selector ) {\n var className = \" \" + selector + \" \",\n i = 0,\n l = this.length;\n for ( ; i < l; i++ ) {\n if ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n return true;\n }\n }\n\n return false;\n },\n\n val: function( value ) {\n var hooks, ret, isFunction,\n elem = this[0];\n\n if ( !arguments.length ) {\n if ( elem ) {\n hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n return ret;\n }\n\n ret = elem.value;\n\n return typeof ret === \"string\" ?\n // handle most common string cases\n ret.replace(rreturn, \"\") :\n // handle cases where value is null/undef or number\n ret == null ? \"\" : ret;\n }\n\n return;\n }\n\n isFunction = jQuery.isFunction( value );\n\n return this.each(function( i ) {\n var val,\n self = jQuery(this);\n\n if ( this.nodeType !== 1 ) {\n return;\n }\n\n if ( isFunction ) {\n val = value.call( this, i, self.val() );\n } else {\n val = value;\n }\n\n // Treat null/undefined as \"\"; convert numbers to string\n if ( val == null ) {\n val = \"\";\n } else if ( typeof val === \"number\" ) {\n val += \"\";\n } else if ( jQuery.isArray( val ) ) {\n val = jQuery.map(val, function ( value ) {\n return value == null ? \"\" : value + \"\";\n });\n }\n\n hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n // If set returns undefined, fall back to normal setting\n if ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n this.value = val;\n }\n });\n }\n});\n\njQuery.extend({\n valHooks: {\n option: {\n get: function( elem ) {\n // attributes.value is undefined in Blackberry 4.7 but\n // uses .value. See #6932\n var val = elem.attributes.value;\n return !val || val.specified ? elem.value : elem.text;\n }\n },\n select: {\n get: function( elem ) {\n var value, option,\n options = elem.options,\n index = elem.selectedIndex,\n one = elem.type === \"select-one\" || index < 0,\n values = one ? null : [],\n max = one ? index + 1 : options.length,\n i = index < 0 ?\n max :\n one ? index : 0;\n\n // Loop through all the selected options\n for ( ; i < max; i++ ) {\n option = options[ i ];\n\n // oldIE doesn't update selected after form reset (#2551)\n if ( ( option.selected || i === index ) &&\n // Don't return options that are disabled or in a disabled optgroup\n ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n // Get the specific value for the option\n value = jQuery( option ).val();\n\n // We don't need an array for one selects\n if ( one ) {\n return value;\n }\n\n // Multi-Selects return an array\n values.push( value );\n }\n }\n\n return values;\n },\n\n set: function( elem, value ) {\n var values = jQuery.makeArray( value );\n\n jQuery(elem).find(\"option\").each(function() {\n this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n });\n\n if ( !values.length ) {\n elem.selectedIndex = -1;\n }\n return values;\n }\n }\n },\n\n // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9\n attrFn: {},\n\n attr: function( elem, name, value, pass ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set attributes on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {\n return jQuery( elem )[ name ]( value );\n }\n\n // Fallback to prop when attributes are not supported\n if ( typeof elem.getAttribute === \"undefined\" ) {\n return jQuery.prop( elem, name, value );\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n // All attributes are lowercase\n // Grab necessary hook if one is defined\n if ( notxml ) {\n name = name.toLowerCase();\n hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );\n }\n\n if ( value !== undefined ) {\n\n if ( value === null ) {\n jQuery.removeAttr( elem, name );\n return;\n\n } else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n elem.setAttribute( name, value + \"\" );\n return value;\n }\n\n } else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n\n ret = elem.getAttribute( name );\n\n // Non-existent attributes return null, we normalize to undefined\n return ret === null ?\n undefined :\n ret;\n }\n },\n\n removeAttr: function( elem, value ) {\n var propName, attrNames, name, isBool,\n i = 0;\n\n if ( value && elem.nodeType === 1 ) {\n\n attrNames = value.split( core_rspace );\n\n for ( ; i < attrNames.length; i++ ) {\n name = attrNames[ i ];\n\n if ( name ) {\n propName = jQuery.propFix[ name ] || name;\n isBool = rboolean.test( name );\n\n // See #9699 for explanation of this approach (setting first, then removal)\n // Do not do this for boolean attributes (see #10870)\n if ( !isBool ) {\n jQuery.attr( elem, name, \"\" );\n }\n elem.removeAttribute( getSetAttribute ? name : propName );\n\n // Set corresponding property to false for boolean attributes\n if ( isBool && propName in elem ) {\n elem[ propName ] = false;\n }\n }\n }\n }\n },\n\n attrHooks: {\n type: {\n set: function( elem, value ) {\n // We can't allow the type property to be changed (since it causes problems in IE)\n if ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n jQuery.error( \"type property can't be changed\" );\n } else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n // Setting the type on a radio button after the value resets the value in IE6-9\n // Reset value to it's default in case type is set after value\n // This is for element creation\n var val = elem.value;\n elem.setAttribute( \"type\", value );\n if ( val ) {\n elem.value = val;\n }\n return value;\n }\n }\n },\n // Use the value property for back compat\n // Use the nodeHook for button elements in IE6/7 (#1954)\n value: {\n get: function( elem, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.get( elem, name );\n }\n return name in elem ?\n elem.value :\n null;\n },\n set: function( elem, value, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.set( elem, value, name );\n }\n // Does not return so that setAttribute is also used\n elem.value = value;\n }\n }\n },\n\n propFix: {\n tabindex: \"tabIndex\",\n readonly: \"readOnly\",\n \"for\": \"htmlFor\",\n \"class\": \"className\",\n maxlength: \"maxLength\",\n cellspacing: \"cellSpacing\",\n cellpadding: \"cellPadding\",\n rowspan: \"rowSpan\",\n colspan: \"colSpan\",\n usemap: \"useMap\",\n frameborder: \"frameBorder\",\n contenteditable: \"contentEditable\"\n },\n\n prop: function( elem, name, value ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set properties on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n if ( notxml ) {\n // Fix name and attach hooks\n name = jQuery.propFix[ name ] || name;\n hooks = jQuery.propHooks[ name ];\n }\n\n if ( value !== undefined ) {\n if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n return ( elem[ name ] = value );\n }\n\n } else {\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n return elem[ name ];\n }\n }\n },\n\n propHooks: {\n tabIndex: {\n get: function( elem ) {\n // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n var attributeNode = elem.getAttributeNode(\"tabindex\");\n\n return attributeNode && attributeNode.specified ?\n parseInt( attributeNode.value, 10 ) :\n rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n 0 :\n undefined;\n }\n }\n }\n});\n\n// Hook for boolean attributes\nboolHook = {\n get: function( elem, name ) {\n // Align boolean attributes with corresponding properties\n // Fall back to attribute presence where some booleans are not supported\n var attrNode,\n property = jQuery.prop( elem, name );\n return property === true || typeof property !== \"boolean\" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\n name.toLowerCase() :\n undefined;\n },\n set: function( elem, value, name ) {\n var propName;\n if ( value === false ) {\n // Remove boolean attributes when set to false\n jQuery.removeAttr( elem, name );\n } else {\n // value is true since we know at this point it's type boolean and not false\n // Set boolean attributes to the same name and set the DOM property\n propName = jQuery.propFix[ name ] || name;\n if ( propName in elem ) {\n // Only set the IDL specifically if it already exists on the element\n elem[ propName ] = true;\n }\n\n elem.setAttribute( name, name.toLowerCase() );\n }\n return name;\n }\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n fixSpecified = {\n name: true,\n id: true,\n coords: true\n };\n\n // Use this for any attribute in IE6/7\n // This fixes almost every IE6/7 issue\n nodeHook = jQuery.valHooks.button = {\n get: function( elem, name ) {\n var ret;\n ret = elem.getAttributeNode( name );\n return ret && ( fixSpecified[ name ] ? ret.value !== \"\" : ret.specified ) ?\n ret.value :\n undefined;\n },\n set: function( elem, value, name ) {\n // Set the existing or create a new attribute node\n var ret = elem.getAttributeNode( name );\n if ( !ret ) {\n ret = document.createAttribute( name );\n elem.setAttributeNode( ret );\n }\n return ( ret.value = value + \"\" );\n }\n };\n\n // Set width and height to auto instead of 0 on empty string( Bug #8150 )\n // This is for removals\n jQuery.each([ \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n set: function( elem, value ) {\n if ( value === \"\" ) {\n elem.setAttribute( name, \"auto\" );\n return value;\n }\n }\n });\n });\n\n // Set contenteditable to false on removals(#10429)\n // Setting to empty string throws an error as an invalid value\n jQuery.attrHooks.contenteditable = {\n get: nodeHook.get,\n set: function( elem, value, name ) {\n if ( value === \"\" ) {\n value = \"false\";\n }\n nodeHook.set( elem, value, name );\n }\n };\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n jQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n get: function( elem ) {\n var ret = elem.getAttribute( name, 2 );\n return ret === null ? undefined : ret;\n }\n });\n });\n}\n\nif ( !jQuery.support.style ) {\n jQuery.attrHooks.style = {\n get: function( elem ) {\n // Return undefined in the case of empty string\n // Normalize to lowercase since IE uppercases css property names\n return elem.style.cssText.toLowerCase() || undefined;\n },\n set: function( elem, value ) {\n return ( elem.style.cssText = value + \"\" );\n }\n };\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n get: function( elem ) {\n var parent = elem.parentNode;\n\n if ( parent ) {\n parent.selectedIndex;\n\n // Make sure that it also works with optgroups, see #5701\n if ( parent.parentNode ) {\n parent.parentNode.selectedIndex;\n }\n }\n return null;\n }\n });\n}\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n jQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n jQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = {\n get: function( elem ) {\n // Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n }\n };\n });\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n set: function( elem, value ) {\n if ( jQuery.isArray( value ) ) {\n return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n }\n }\n });\n});\nvar rformElems = /^(?:textarea|input|select)$/i,\n rtypenamespace = /^([^\\.]*|)(?:\\.(.+)|)$/,\n rhoverHack = /(?:^|\\s)hover(\\.\\S+|)\\b/,\n rkeyEvent = /^key/,\n rmouseEvent = /^(?:mouse|contextmenu)|click/,\n rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n hoverHack = function( events ) {\n return jQuery.event.special.hover ? events : events.replace( rhoverHack, \"mouseenter$1 mouseleave$1\" );\n };\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n add: function( elem, types, handler, data, selector ) {\n\n var elemData, eventHandle, events,\n t, tns, type, namespaces, handleObj,\n handleObjIn, handlers, special;\n\n // Don't attach events to noData or text/comment nodes (allow plain objects tho)\n if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {\n return;\n }\n\n // Caller can pass in an object of custom data in lieu of the handler\n if ( handler.handler ) {\n handleObjIn = handler;\n handler = handleObjIn.handler;\n selector = handleObjIn.selector;\n }\n\n // Make sure that the handler has a unique ID, used to find/remove it later\n if ( !handler.guid ) {\n handler.guid = jQuery.guid++;\n }\n\n // Init the element's event structure and main handler, if this is the first\n events = elemData.events;\n if ( !events ) {\n elemData.events = events = {};\n }\n eventHandle = elemData.handle;\n if ( !eventHandle ) {\n elemData.handle = eventHandle = function( e ) {\n // Discard the second event of a jQuery.event.trigger() and\n // when an event is called after a page has unloaded\n return typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n undefined;\n };\n // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n eventHandle.elem = elem;\n }\n\n // Handle multiple events separated by a space\n // jQuery(...).bind(\"mouseover mouseout\", fn);\n types = jQuery.trim( hoverHack(types) ).split( \" \" );\n for ( t = 0; t < types.length; t++ ) {\n\n tns = rtypenamespace.exec( types[t] ) || [];\n type = tns[1];\n namespaces = ( tns[2] || \"\" ).split( \".\" ).sort();\n\n // If event changes its type, use the special event handlers for the changed type\n special = jQuery.event.special[ type ] || {};\n\n // If selector defined, determine special event api type, otherwise given type\n type = ( selector ? special.delegateType : special.bindType ) || type;\n\n // Update special based on newly reset type\n special = jQuery.event.special[ type ] || {};\n\n // handleObj is passed to all event handlers\n handleObj = jQuery.extend({\n type: type,\n origType: tns[1],\n data: data,\n handler: handler,\n guid: handler.guid,\n selector: selector,\n needsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n namespace: namespaces.join(\".\")\n }, handleObjIn );\n\n // Init the event handler queue if we're the first\n handlers = events[ type ];\n if ( !handlers ) {\n handlers = events[ type ] = [];\n handlers.delegateCount = 0;\n\n // Only use addEventListener/attachEvent if the special events handler returns false\n if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n // Bind the global event handler to the element\n if ( elem.addEventListener ) {\n elem.addEventListener( type, eventHandle, false );\n\n } else if ( elem.attachEvent ) {\n elem.attachEvent( \"on\" + type, eventHandle );\n }\n }\n }\n\n if ( special.add ) {\n special.add.call( elem, handleObj );\n\n if ( !handleObj.handler.guid ) {\n handleObj.handler.guid = handler.guid;\n }\n }\n\n // Add to the element's handler list, delegates in front\n if ( selector ) {\n handlers.splice( handlers.delegateCount++, 0, handleObj );\n } else {\n handlers.push( handleObj );\n }\n\n // Keep track of which events have ever been used, for event optimization\n jQuery.event.global[ type ] = true;\n }\n\n // Nullify elem to prevent memory leaks in IE\n elem = null;\n },\n\n global: {},\n\n // Detach an event or set of events from an element\n remove: function( elem, types, handler, selector, mappedTypes ) {\n\n var t, tns, type, origType, namespaces, origCount,\n j, events, special, eventType, handleObj,\n elemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n if ( !elemData || !(events = elemData.events) ) {\n return;\n }\n\n // Once for each type.namespace in types; type may be omitted\n types = jQuery.trim( hoverHack( types || \"\" ) ).split(\" \");\n for ( t = 0; t < types.length; t++ ) {\n tns = rtypenamespace.exec( types[t] ) || [];\n type = origType = tns[1];\n namespaces = tns[2];\n\n // Unbind all events (on this namespace, if provided) for the element\n if ( !type ) {\n for ( type in events ) {\n jQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n }\n continue;\n }\n\n special = jQuery.event.special[ type ] || {};\n type = ( selector? special.delegateType : special.bindType ) || type;\n eventType = events[ type ] || [];\n origCount = eventType.length;\n namespaces = namespaces ? new RegExp(\"(^|\\\\.)\" + namespaces.split(\".\").sort().join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\n // Remove matching events\n for ( j = 0; j < eventType.length; j++ ) {\n handleObj = eventType[ j ];\n\n if ( ( mappedTypes || origType === handleObj.origType ) &&\n ( !handler || handler.guid === handleObj.guid ) &&\n ( !namespaces || namespaces.test( handleObj.namespace ) ) &&\n ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n eventType.splice( j--, 1 );\n\n if ( handleObj.selector ) {\n eventType.delegateCount--;\n }\n if ( special.remove ) {\n special.remove.call( elem, handleObj );\n }\n }\n }\n\n // Remove generic event handler if we removed something and no more handlers exist\n // (avoids potential for endless recursion during removal of special event handlers)\n if ( eventType.length === 0 && origCount !== eventType.length ) {\n if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n jQuery.removeEvent( elem, type, elemData.handle );\n }\n\n delete events[ type ];\n }\n }\n\n // Remove the expando if it's no longer used\n if ( jQuery.isEmptyObject( events ) ) {\n delete elemData.handle;\n\n // removeData also checks for emptiness and clears the expando if empty\n // so use it instead of delete\n jQuery.removeData( elem, \"events\", true );\n }\n },\n\n // Events that are safe to short-circuit if no handlers are attached.\n // Native DOM events should not be added, they may have inline handlers.\n customEvent: {\n \"getData\": true,\n \"setData\": true,\n \"changeData\": true\n },\n\n trigger: function( event, data, elem, onlyHandlers ) {\n // Don't do events on text and comment nodes\n if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {\n return;\n }\n\n // Event object or event type\n var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,\n type = event.type || event,\n namespaces = [];\n\n // focus/blur morphs to focusin/out; ensure we're not firing them right now\n if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n return;\n }\n\n if ( type.indexOf( \"!\" ) >= 0 ) {\n // Exclusive events trigger only for the exact event (no namespaces)\n type = type.slice(0, -1);\n exclusive = true;\n }\n\n if ( type.indexOf( \".\" ) >= 0 ) {\n // Namespaced trigger; create a regexp to match event type in handle()\n namespaces = type.split(\".\");\n type = namespaces.shift();\n namespaces.sort();\n }\n\n if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n // No jQuery handlers for this event type, and it can't have inline handlers\n return;\n }\n\n // Caller can pass in an Event, Object, or just an event type string\n event = typeof event === \"object\" ?\n // jQuery.Event object\n event[ jQuery.expando ] ? event :\n // Object literal\n new jQuery.Event( type, event ) :\n // Just the event type (string)\n new jQuery.Event( type );\n\n event.type = type;\n event.isTrigger = true;\n event.exclusive = exclusive;\n event.namespace = namespaces.join( \".\" );\n event.namespace_re = event.namespace? new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n ontype = type.indexOf( \":\" ) < 0 ? \"on\" + type : \"\";\n\n // Handle a global trigger\n if ( !elem ) {\n\n // TODO: Stop taunting the data cache; remove global events and always attach to document\n cache = jQuery.cache;\n for ( i in cache ) {\n if ( cache[ i ].events && cache[ i ].events[ type ] ) {\n jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );\n }\n }\n return;\n }\n\n // Clean up the event in case it is being reused\n event.result = undefined;\n if ( !event.target ) {\n event.target = elem;\n }\n\n // Clone any incoming data and prepend the event, creating the handler arg list\n data = data != null ? jQuery.makeArray( data ) : [];\n data.unshift( event );\n\n // Allow special events to draw outside the lines\n special = jQuery.event.special[ type ] || {};\n if ( special.trigger && special.trigger.apply( elem, data ) === false ) {\n return;\n }\n\n // Determine event propagation path in advance, per W3C events spec (#9951)\n // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n eventPath = [[ elem, special.bindType || type ]];\n if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n bubbleType = special.delegateType || type;\n cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;\n for ( old = elem; cur; cur = cur.parentNode ) {\n eventPath.push([ cur, bubbleType ]);\n old = cur;\n }\n\n // Only add window if we got to document (e.g., not plain obj or detached DOM)\n if ( old === (elem.ownerDocument || document) ) {\n eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);\n }\n }\n\n // Fire handlers on the event path\n for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {\n\n cur = eventPath[i][0];\n event.type = eventPath[i][1];\n\n handle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n if ( handle ) {\n handle.apply( cur, data );\n }\n // Note that this is a bare JS function and not a jQuery handler\n handle = ontype && cur[ ontype ];\n if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n event.preventDefault();\n }\n }\n event.type = type;\n\n // If nobody prevented the default action, do it now\n if ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&\n !(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n // Call a native DOM method on the target with the same name name as the event.\n // Can't use an .isFunction() check here because IE6/7 fails that test.\n // Don't do default actions on window, that's where global variables be (#6170)\n // IE<9 dies on focus/blur to hidden element (#1486)\n if ( ontype && elem[ type ] && ((type !== \"focus\" && type !== \"blur\") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {\n\n // Don't re-trigger an onFOO event when we call its FOO() method\n old = elem[ ontype ];\n\n if ( old ) {\n elem[ ontype ] = null;\n }\n\n // Prevent re-triggering of the same event, since we already bubbled it above\n jQuery.event.triggered = type;\n elem[ type ]();\n jQuery.event.triggered = undefined;\n\n if ( old ) {\n elem[ ontype ] = old;\n }\n }\n }\n }\n\n return event.result;\n },\n\n dispatch: function( event ) {\n\n // Make a writable jQuery.Event from the native event object\n event = jQuery.event.fix( event || window.event );\n\n var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,\n handlers = ( (jQuery._data( this, \"events\" ) || {} )[ event.type ] || []),\n delegateCount = handlers.delegateCount,\n args = core_slice.call( arguments ),\n run_all = !event.exclusive && !event.namespace,\n special = jQuery.event.special[ event.type ] || {},\n handlerQueue = [];\n\n // Use the fix-ed jQuery.Event rather than the (read-only) native event\n args[0] = event;\n event.delegateTarget = this;\n\n // Call the preDispatch hook for the mapped type, and let it bail if desired\n if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n return;\n }\n\n // Determine handlers that should run if there are delegated events\n // Avoid non-left-click bubbling in Firefox (#3861)\n if ( delegateCount && !(event.button && event.type === \"click\") ) {\n\n for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {\n\n // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)\n if ( cur.disabled !== true || event.type !== \"click\" ) {\n selMatch = {};\n matches = [];\n for ( i = 0; i < delegateCount; i++ ) {\n handleObj = handlers[ i ];\n sel = handleObj.selector;\n\n if ( selMatch[ sel ] === undefined ) {\n selMatch[ sel ] = handleObj.needsContext ?\n jQuery( sel, this ).index( cur ) >= 0 :\n jQuery.find( sel, this, null, [ cur ] ).length;\n }\n if ( selMatch[ sel ] ) {\n matches.push( handleObj );\n }\n }\n if ( matches.length ) {\n handlerQueue.push({ elem: cur, matches: matches });\n }\n }\n }\n }\n\n // Add the remaining (directly-bound) handlers\n if ( handlers.length > delegateCount ) {\n handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });\n }\n\n // Run delegates first; they may want to stop propagation beneath us\n for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {\n matched = handlerQueue[ i ];\n event.currentTarget = matched.elem;\n\n for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {\n handleObj = matched.matches[ j ];\n\n // Triggered event must either 1) be non-exclusive and have no namespace, or\n // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {\n\n event.data = handleObj.data;\n event.handleObj = handleObj;\n\n ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n .apply( matched.elem, args );\n\n if ( ret !== undefined ) {\n event.result = ret;\n if ( ret === false ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }\n }\n }\n\n // Call the postDispatch hook for the mapped type\n if ( special.postDispatch ) {\n special.postDispatch.call( this, event );\n }\n\n return event.result;\n },\n\n // Includes some event props shared by KeyEvent and MouseEvent\n // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***\n props: \"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n fixHooks: {},\n\n keyHooks: {\n props: \"char charCode key keyCode\".split(\" \"),\n filter: function( event, original ) {\n\n // Add which for key events\n if ( event.which == null ) {\n event.which = original.charCode != null ? original.charCode : original.keyCode;\n }\n\n return event;\n }\n },\n\n mouseHooks: {\n props: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n filter: function( event, original ) {\n var eventDoc, doc, body,\n button = original.button,\n fromElement = original.fromElement;\n\n // Calculate pageX/Y if missing and clientX/Y available\n if ( event.pageX == null && original.clientX != null ) {\n eventDoc = event.target.ownerDocument || document;\n doc = eventDoc.documentElement;\n body = eventDoc.body;\n\n event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n }\n\n // Add relatedTarget, if necessary\n if ( !event.relatedTarget && fromElement ) {\n event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n }\n\n // Add which for click: 1 === left; 2 === middle; 3 === right\n // Note: button is not normalized, so don't use it\n if ( !event.which && button !== undefined ) {\n event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n }\n\n return event;\n }\n },\n\n fix: function( event ) {\n if ( event[ jQuery.expando ] ) {\n return event;\n }\n\n // Create a writable copy of the event object and normalize some properties\n var i, prop,\n originalEvent = event,\n fixHook = jQuery.event.fixHooks[ event.type ] || {},\n copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n event = jQuery.Event( originalEvent );\n\n for ( i = copy.length; i; ) {\n prop = copy[ --i ];\n event[ prop ] = originalEvent[ prop ];\n }\n\n // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)\n if ( !event.target ) {\n event.target = originalEvent.srcElement || document;\n }\n\n // Target should not be a text node (#504, Safari)\n if ( event.target.nodeType === 3 ) {\n event.target = event.target.parentNode;\n }\n\n // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)\n event.metaKey = !!event.metaKey;\n\n return fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n },\n\n special: {\n load: {\n // Prevent triggered image.load events from bubbling to window.load\n noBubble: true\n },\n\n focus: {\n delegateType: \"focusin\"\n },\n blur: {\n delegateType: \"focusout\"\n },\n\n beforeunload: {\n setup: function( data, namespaces, eventHandle ) {\n // We only want to do this special case on windows\n if ( jQuery.isWindow( this ) ) {\n this.onbeforeunload = eventHandle;\n }\n },\n\n teardown: function( namespaces, eventHandle ) {\n if ( this.onbeforeunload === eventHandle ) {\n this.onbeforeunload = null;\n }\n }\n }\n },\n\n simulate: function( type, elem, event, bubble ) {\n // Piggyback on a donor event to simulate a different one.\n // Fake originalEvent to avoid donor's stopPropagation, but if the\n // simulated event prevents default then we do the same on the donor.\n var e = jQuery.extend(\n new jQuery.Event(),\n event,\n { type: type,\n isSimulated: true,\n originalEvent: {}\n }\n );\n if ( bubble ) {\n jQuery.event.trigger( e, null, elem );\n } else {\n jQuery.event.dispatch.call( elem, e );\n }\n if ( e.isDefaultPrevented() ) {\n event.preventDefault();\n }\n }\n};\n\n// Some plugins are using, but it's undocumented/deprecated and will be removed.\n// The 1.7 special event interface should provide all the hooks needed now.\njQuery.event.handle = jQuery.event.dispatch;\n\njQuery.removeEvent = document.removeEventListener ?\n function( elem, type, handle ) {\n if ( elem.removeEventListener ) {\n elem.removeEventListener( type, handle, false );\n }\n } :\n function( elem, type, handle ) {\n var name = \"on\" + type;\n\n if ( elem.detachEvent ) {\n\n // #8545, #7054, preventing memory leaks for custom events in IE6-8\n // detachEvent needed property on element, by name of that event, to properly expose it to GC\n if ( typeof elem[ name ] === \"undefined\" ) {\n elem[ name ] = null;\n }\n\n elem.detachEvent( name, handle );\n }\n };\n\njQuery.Event = function( src, props ) {\n // Allow instantiation without the 'new' keyword\n if ( !(this instanceof jQuery.Event) ) {\n return new jQuery.Event( src, props );\n }\n\n // Event object\n if ( src && src.type ) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if ( props ) {\n jQuery.extend( this, props );\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || jQuery.now();\n\n // Mark it as fixed\n this[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n return false;\n}\nfunction returnTrue() {\n return true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n preventDefault: function() {\n this.isDefaultPrevented = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if ( e.preventDefault ) {\n e.preventDefault();\n\n // otherwise set the returnValue property of the original event to false (IE)\n } else {\n e.returnValue = false;\n }\n },\n stopPropagation: function() {\n this.isPropagationStopped = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n // if stopPropagation exists run it on the original event\n if ( e.stopPropagation ) {\n e.stopPropagation();\n }\n // otherwise set the cancelBubble property of the original event to true (IE)\n e.cancelBubble = true;\n },\n stopImmediatePropagation: function() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n mouseenter: \"mouseover\",\n mouseleave: \"mouseout\"\n}, function( orig, fix ) {\n jQuery.event.special[ orig ] = {\n delegateType: fix,\n bindType: fix,\n\n handle: function( event ) {\n var ret,\n target = this,\n related = event.relatedTarget,\n handleObj = event.handleObj,\n selector = handleObj.selector;\n\n // For mousenter/leave call the handler if related is outside the target.\n // NB: No relatedTarget if the mouse left/entered the browser window\n if ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n event.type = handleObj.origType;\n ret = handleObj.handler.apply( this, arguments );\n event.type = fix;\n }\n return ret;\n }\n };\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n jQuery.event.special.submit = {\n setup: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Lazy-add a submit handler when a descendant form may potentially be submitted\n jQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n // Node name check avoids a VML-related crash in IE (#9807)\n var elem = e.target,\n form = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n if ( form && !jQuery._data( form, \"_submit_attached\" ) ) {\n jQuery.event.add( form, \"submit._submit\", function( event ) {\n event._submit_bubble = true;\n });\n jQuery._data( form, \"_submit_attached\", true );\n }\n });\n // return undefined since we don't need an event listener\n },\n\n postDispatch: function( event ) {\n // If form was submitted by the user, bubble the event up the tree\n if ( event._submit_bubble ) {\n delete event._submit_bubble;\n if ( this.parentNode && !event.isTrigger ) {\n jQuery.event.simulate( \"submit\", this.parentNode, event, true );\n }\n }\n },\n\n teardown: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n jQuery.event.remove( this, \"._submit\" );\n }\n };\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n jQuery.event.special.change = {\n\n setup: function() {\n\n if ( rformElems.test( this.nodeName ) ) {\n // IE doesn't fire change on a check/radio until blur; trigger it on click\n // after a propertychange. Eat the blur-change in special.change.handle.\n // This still fires onchange a second time for check/radio after blur.\n if ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n jQuery.event.add( this, \"propertychange._change\", function( event ) {\n if ( event.originalEvent.propertyName === \"checked\" ) {\n this._just_changed = true;\n }\n });\n jQuery.event.add( this, \"click._change\", function( event ) {\n if ( this._just_changed && !event.isTrigger ) {\n this._just_changed = false;\n }\n // Allow triggered, simulated change events (#11500)\n jQuery.event.simulate( \"change\", this, event, true );\n });\n }\n return false;\n }\n // Delegated event; lazy-add a change handler on descendant inputs\n jQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n var elem = e.target;\n\n if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"_change_attached\" ) ) {\n jQuery.event.add( elem, \"change._change\", function( event ) {\n if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n jQuery.event.simulate( \"change\", this.parentNode, event, true );\n }\n });\n jQuery._data( elem, \"_change_attached\", true );\n }\n });\n },\n\n handle: function( event ) {\n var elem = event.target;\n\n // Swallow native change events from checkbox/radio, we already triggered them above\n if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n return event.handleObj.handler.apply( this, arguments );\n }\n },\n\n teardown: function() {\n jQuery.event.remove( this, \"._change\" );\n\n return !rformElems.test( this.nodeName );\n }\n };\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n jQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n // Attach a single capturing handler while someone wants focusin/focusout\n var attaches = 0,\n handler = function( event ) {\n jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n };\n\n jQuery.event.special[ fix ] = {\n setup: function() {\n if ( attaches++ === 0 ) {\n document.addEventListener( orig, handler, true );\n }\n },\n teardown: function() {\n if ( --attaches === 0 ) {\n document.removeEventListener( orig, handler, true );\n }\n }\n };\n });\n}\n\njQuery.fn.extend({\n\n on: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n var origFn, type;\n\n // Types can be a map of types/handlers\n if ( typeof types === \"object\" ) {\n // ( types-Object, selector, data )\n if ( typeof selector !== \"string\" ) { // && selector != null\n // ( types-Object, data )\n data = data || selector;\n selector = undefined;\n }\n for ( type in types ) {\n this.on( type, selector, data, types[ type ], one );\n }\n return this;\n }\n\n if ( data == null && fn == null ) {\n // ( types, fn )\n fn = selector;\n data = selector = undefined;\n } else if ( fn == null ) {\n if ( typeof selector === \"string\" ) {\n // ( types, selector, fn )\n fn = data;\n data = undefined;\n } else {\n // ( types, data, fn )\n fn = data;\n data = selector;\n selector = undefined;\n }\n }\n if ( fn === false ) {\n fn = returnFalse;\n } else if ( !fn ) {\n return this;\n }\n\n if ( one === 1 ) {\n origFn = fn;\n fn = function( event ) {\n // Can use an empty set, since event contains the info\n jQuery().off( event );\n return origFn.apply( this, arguments );\n };\n // Use same guid so caller can remove using origFn\n fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n }\n return this.each( function() {\n jQuery.event.add( this, types, fn, data, selector );\n });\n },\n one: function( types, selector, data, fn ) {\n return this.on( types, selector, data, fn, 1 );\n },\n off: function( types, selector, fn ) {\n var handleObj, type;\n if ( types && types.preventDefault && types.handleObj ) {\n // ( event ) dispatched jQuery.Event\n handleObj = types.handleObj;\n jQuery( types.delegateTarget ).off(\n handleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n handleObj.selector,\n handleObj.handler\n );\n return this;\n }\n if ( typeof types === \"object\" ) {\n // ( types-object [, selector] )\n for ( type in types ) {\n this.off( type, selector, types[ type ] );\n }\n return this;\n }\n if ( selector === false || typeof selector === \"function\" ) {\n // ( types [, fn] )\n fn = selector;\n selector = undefined;\n }\n if ( fn === false ) {\n fn = returnFalse;\n }\n return this.each(function() {\n jQuery.event.remove( this, types, fn, selector );\n });\n },\n\n bind: function( types, data, fn ) {\n return this.on( types, null, data, fn );\n },\n unbind: function( types, fn ) {\n return this.off( types, null, fn );\n },\n\n live: function( types, data, fn ) {\n jQuery( this.context ).on( types, this.selector, data, fn );\n return this;\n },\n die: function( types, fn ) {\n jQuery( this.context ).off( types, this.selector || \"**\", fn );\n return this;\n },\n\n delegate: function( selector, types, data, fn ) {\n return this.on( types, selector, data, fn );\n },\n undelegate: function( selector, types, fn ) {\n // ( namespace ) or ( selector, types [, fn] )\n return arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n },\n\n trigger: function( type, data ) {\n return this.each(function() {\n jQuery.event.trigger( type, data, this );\n });\n },\n triggerHandler: function( type, data ) {\n if ( this[0] ) {\n return jQuery.event.trigger( type, data, this[0], true );\n }\n },\n\n toggle: function( fn ) {\n // Save reference to arguments for access in closure\n var args = arguments,\n guid = fn.guid || jQuery.guid++,\n i = 0,\n toggler = function( event ) {\n // Figure out which function to execute\n var lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n jQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n // Make sure that clicks stop\n event.preventDefault();\n\n // and execute the function\n return args[ lastToggle ].apply( this, arguments ) || false;\n };\n\n // link all the functions, so any of them can unbind this click handler\n toggler.guid = guid;\n while ( i < args.length ) {\n args[ i++ ].guid = guid;\n }\n\n return this.click( toggler );\n },\n\n hover: function( fnOver, fnOut ) {\n return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n }\n});\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n \"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n // Handle event binding\n jQuery.fn[ name ] = function( data, fn ) {\n if ( fn == null ) {\n fn = data;\n data = null;\n }\n\n return arguments.length > 0 ?\n this.on( name, null, data, fn ) :\n this.trigger( name );\n };\n\n if ( rkeyEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;\n }\n\n if ( rmouseEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;\n }\n});\n/*!\n * Sizzle CSS Selector Engine\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://sizzlejs.com/\n */\n(function( window, undefined ) {\n\nvar cachedruns,\n assertGetIdNotName,\n Expr,\n getText,\n isXML,\n contains,\n compile,\n sortOrder,\n hasDuplicate,\n outermostContext,\n\n baseHasDuplicate = true,\n strundefined = \"undefined\",\n\n expando = ( \"sizcache\" + Math.random() ).replace( \".\", \"\" ),\n\n Token = String,\n document = window.document,\n docElem = document.documentElement,\n dirruns = 0,\n done = 0,\n pop = [].pop,\n push = [].push,\n slice = [].slice,\n // Use a stripped-down indexOf if a native one is unavailable\n indexOf = [].indexOf || function( elem ) {\n var i = 0,\n len = this.length;\n for ( ; i < len; i++ ) {\n if ( this[i] === elem ) {\n return i;\n }\n }\n return -1;\n },\n\n // Augment a function for special use by Sizzle\n markFunction = function( fn, value ) {\n fn[ expando ] = value == null || value;\n return fn;\n },\n\n createCache = function() {\n var cache = {},\n keys = [];\n\n return markFunction(function( key, value ) {\n // Only keep the most recent entries\n if ( keys.push( key ) > Expr.cacheLength ) {\n delete cache[ keys.shift() ];\n }\n\n // Retrieve with (key + \" \") to avoid collision with native Object.prototype properties (see Issue #157)\n return (cache[ key + \" \" ] = value);\n }, cache );\n },\n\n classCache = createCache(),\n tokenCache = createCache(),\n compilerCache = createCache(),\n\n // Regex\n\n // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n // http://www.w3.org/TR/css3-syntax/#characters\n characterEncoding = \"(?:\\\\\\\\.|[-\\\\w]|[^\\\\x00-\\\\xa0])+\",\n\n // Loosely modeled on CSS identifier characters\n // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)\n // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n identifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n operators = \"([*^$|!~]?=)\",\n attributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n \"*(?:\" + operators + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n // Prefer arguments not in parens/brackets,\n // then attribute selectors and non-pseudos (denoted by :),\n // then anything else\n // These preferences are here to reduce the number of selectors\n // needing tokenize in the PSEUDO preFilter\n pseudos = \":(\" + characterEncoding + \")(?:\\\\((?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\2|([^()[\\\\]]*|(?:(?:\" + attributes + \")|[^:]|\\\\\\\\.)*|.*))\\\\)|)\",\n\n // For matchExpr.POS and matchExpr.needsContext\n pos = \":(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\",\n\n // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n rtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n rcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n rcombinators = new RegExp( \"^\" + whitespace + \"*([\\\\x20\\\\t\\\\r\\\\n\\\\f>+~])\" + whitespace + \"*\" ),\n rpseudo = new RegExp( pseudos ),\n\n // Easily-parseable/retrievable ID or TAG or CLASS selectors\n rquickExpr = /^(?:#([\\w\\-]+)|(\\w+)|\\.([\\w\\-]+))$/,\n\n rnot = /^:not/,\n rsibling = /[\\x20\\t\\r\\n\\f]*[+~]/,\n rendsWithNot = /:not\\($/,\n\n rheader = /h\\d/i,\n rinputs = /input|select|textarea|button/i,\n\n rbackslash = /\\\\(?!\\\\)/g,\n\n matchExpr = {\n \"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n \"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n \"NAME\": new RegExp( \"^\\\\[name=['\\\"]?(\" + characterEncoding + \")['\\\"]?\\\\]\" ),\n \"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n \"ATTR\": new RegExp( \"^\" + attributes ),\n \"PSEUDO\": new RegExp( \"^\" + pseudos ),\n \"POS\": new RegExp( pos, \"i\" ),\n \"CHILD\": new RegExp( \"^:(only|nth|first|last)-child(?:\\\\(\" + whitespace +\n \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n // For use in libraries implementing .is()\n \"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|\" + pos, \"i\" )\n },\n\n // Support\n\n // Used for testing something on an element\n assert = function( fn ) {\n var div = document.createElement(\"div\");\n\n try {\n return fn( div );\n } catch (e) {\n return false;\n } finally {\n // release memory in IE\n div = null;\n }\n },\n\n // Check if getElementsByTagName(\"*\") returns only elements\n assertTagNameNoComments = assert(function( div ) {\n div.appendChild( document.createComment(\"\") );\n return !div.getElementsByTagName(\"*\").length;\n }),\n\n // Check if getAttribute returns normalized href attributes\n assertHrefNotNormalized = assert(function( div ) {\n div.innerHTML = \"\";\n return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\n div.firstChild.getAttribute(\"href\") === \"#\";\n }),\n\n // Check if attributes should be retrieved by attribute nodes\n assertAttributes = assert(function( div ) {\n div.innerHTML = \"\";\n var type = typeof div.lastChild.getAttribute(\"multiple\");\n // IE8 returns a string for some attributes even when not present\n return type !== \"boolean\" && type !== \"string\";\n }),\n\n // Check if getElementsByClassName can be trusted\n assertUsableClassName = assert(function( div ) {\n // Opera can't find a second classname (in 9.6)\n div.innerHTML = \"\";\n if ( !div.getElementsByClassName || !div.getElementsByClassName(\"e\").length ) {\n return false;\n }\n\n // Safari 3.2 caches class attributes and doesn't catch changes\n div.lastChild.className = \"e\";\n return div.getElementsByClassName(\"e\").length === 2;\n }),\n\n // Check if getElementById returns elements by name\n // Check if getElementsByName privileges form controls or returns elements by ID\n assertUsableName = assert(function( div ) {\n // Inject content\n div.id = expando + 0;\n div.innerHTML = \"
    \";\n docElem.insertBefore( div, docElem.firstChild );\n\n // Test\n var pass = document.getElementsByName &&\n // buggy browsers will return fewer than the correct 2\n document.getElementsByName( expando ).length === 2 +\n // buggy browsers will return more than the correct 0\n document.getElementsByName( expando + 0 ).length;\n assertGetIdNotName = !document.getElementById( expando );\n\n // Cleanup\n docElem.removeChild( div );\n\n return pass;\n });\n\n// If slice is not available, provide a backup\ntry {\n slice.call( docElem.childNodes, 0 )[0].nodeType;\n} catch ( e ) {\n slice = function( i ) {\n var elem,\n results = [];\n for ( ; (elem = this[i]); i++ ) {\n results.push( elem );\n }\n return results;\n };\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n results = results || [];\n context = context || document;\n var match, elem, xml, m,\n nodeType = context.nodeType;\n\n if ( !selector || typeof selector !== \"string\" ) {\n return results;\n }\n\n if ( nodeType !== 1 && nodeType !== 9 ) {\n return [];\n }\n\n xml = isXML( context );\n\n if ( !xml && !seed ) {\n if ( (match = rquickExpr.exec( selector )) ) {\n // Speed-up: Sizzle(\"#ID\")\n if ( (m = match[1]) ) {\n if ( nodeType === 9 ) {\n elem = context.getElementById( m );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE, Opera, and Webkit return items\n // by name instead of ID\n if ( elem.id === m ) {\n results.push( elem );\n return results;\n }\n } else {\n return results;\n }\n } else {\n // Context is not a document\n if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n contains( context, elem ) && elem.id === m ) {\n results.push( elem );\n return results;\n }\n }\n\n // Speed-up: Sizzle(\"TAG\")\n } else if ( match[2] ) {\n push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );\n return results;\n\n // Speed-up: Sizzle(\".CLASS\")\n } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {\n push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );\n return results;\n }\n }\n }\n\n // All others\n return select( selector.replace( rtrim, \"$1\" ), context, results, seed, xml );\n}\n\nSizzle.matches = function( expr, elements ) {\n return Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n};\n\n// Returns a function to use in pseudos for input types\nfunction createInputPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for buttons\nfunction createButtonPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return (name === \"input\" || name === \"button\") && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for positionals\nfunction createPositionalPseudo( fn ) {\n return markFunction(function( argument ) {\n argument = +argument;\n return markFunction(function( seed, matches ) {\n var j,\n matchIndexes = fn( [], seed.length, argument ),\n i = matchIndexes.length;\n\n // Match elements found at the specified indexes\n while ( i-- ) {\n if ( seed[ (j = matchIndexes[i]) ] ) {\n seed[j] = !(matches[j] = seed[j]);\n }\n }\n });\n });\n}\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n var node,\n ret = \"\",\n i = 0,\n nodeType = elem.nodeType;\n\n if ( nodeType ) {\n if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n // Use textContent for elements\n // innerText usage removed for consistency of new lines (see #11153)\n if ( typeof elem.textContent === \"string\" ) {\n return elem.textContent;\n } else {\n // Traverse its children\n for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n ret += getText( elem );\n }\n }\n } else if ( nodeType === 3 || nodeType === 4 ) {\n return elem.nodeValue;\n }\n // Do not include comment or processing instruction nodes\n } else {\n\n // If no nodeType, this is expected to be an array\n for ( ; (node = elem[i]); i++ ) {\n // Do not traverse comment nodes\n ret += getText( node );\n }\n }\n return ret;\n};\n\nisXML = Sizzle.isXML = function( elem ) {\n // documentElement is verified for cases where it doesn't yet exist\n // (such as loading iframes in IE - #4833)\n var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Element contains another\ncontains = Sizzle.contains = docElem.contains ?\n function( a, b ) {\n var adown = a.nodeType === 9 ? a.documentElement : a,\n bup = b && b.parentNode;\n return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\n } :\n docElem.compareDocumentPosition ?\n function( a, b ) {\n return b && !!( a.compareDocumentPosition( b ) & 16 );\n } :\n function( a, b ) {\n while ( (b = b.parentNode) ) {\n if ( b === a ) {\n return true;\n }\n }\n return false;\n };\n\nSizzle.attr = function( elem, name ) {\n var val,\n xml = isXML( elem );\n\n if ( !xml ) {\n name = name.toLowerCase();\n }\n if ( (val = Expr.attrHandle[ name ]) ) {\n return val( elem );\n }\n if ( xml || assertAttributes ) {\n return elem.getAttribute( name );\n }\n val = elem.getAttributeNode( name );\n return val ?\n typeof elem[ name ] === \"boolean\" ?\n elem[ name ] ? name : null :\n val.specified ? val.value : null :\n null;\n};\n\nExpr = Sizzle.selectors = {\n\n // Can be adjusted by the user\n cacheLength: 50,\n\n createPseudo: markFunction,\n\n match: matchExpr,\n\n // IE6/7 return a modified href\n attrHandle: assertHrefNotNormalized ?\n {} :\n {\n \"href\": function( elem ) {\n return elem.getAttribute( \"href\", 2 );\n },\n \"type\": function( elem ) {\n return elem.getAttribute(\"type\");\n }\n },\n\n find: {\n \"ID\": assertGetIdNotName ?\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n return m && m.parentNode ? [m] : [];\n }\n } :\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n\n return m ?\n m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode(\"id\").value === id ?\n [m] :\n undefined :\n [];\n }\n },\n\n \"TAG\": assertTagNameNoComments ?\n function( tag, context ) {\n if ( typeof context.getElementsByTagName !== strundefined ) {\n return context.getElementsByTagName( tag );\n }\n } :\n function( tag, context ) {\n var results = context.getElementsByTagName( tag );\n\n // Filter out possible comments\n if ( tag === \"*\" ) {\n var elem,\n tmp = [],\n i = 0;\n\n for ( ; (elem = results[i]); i++ ) {\n if ( elem.nodeType === 1 ) {\n tmp.push( elem );\n }\n }\n\n return tmp;\n }\n return results;\n },\n\n \"NAME\": assertUsableName && function( tag, context ) {\n if ( typeof context.getElementsByName !== strundefined ) {\n return context.getElementsByName( name );\n }\n },\n\n \"CLASS\": assertUsableClassName && function( className, context, xml ) {\n if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\n return context.getElementsByClassName( className );\n }\n }\n },\n\n relative: {\n \">\": { dir: \"parentNode\", first: true },\n \" \": { dir: \"parentNode\" },\n \"+\": { dir: \"previousSibling\", first: true },\n \"~\": { dir: \"previousSibling\" }\n },\n\n preFilter: {\n \"ATTR\": function( match ) {\n match[1] = match[1].replace( rbackslash, \"\" );\n\n // Move the given value to match[3] whether quoted or unquoted\n match[3] = ( match[4] || match[5] || \"\" ).replace( rbackslash, \"\" );\n\n if ( match[2] === \"~=\" ) {\n match[3] = \" \" + match[3] + \" \";\n }\n\n return match.slice( 0, 4 );\n },\n\n \"CHILD\": function( match ) {\n /* matches from matchExpr[\"CHILD\"]\n 1 type (only|nth|...)\n 2 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n 3 xn-component of xn+y argument ([+-]?\\d*n|)\n 4 sign of xn-component\n 5 x of xn-component\n 6 sign of y-component\n 7 y of y-component\n */\n match[1] = match[1].toLowerCase();\n\n if ( match[1] === \"nth\" ) {\n // nth-child requires argument\n if ( !match[2] ) {\n Sizzle.error( match[0] );\n }\n\n // numeric x and y parameters for Expr.filter.CHILD\n // remember that false/true cast respectively to 0/1\n match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === \"even\" || match[2] === \"odd\" ) );\n match[4] = +( ( match[6] + match[7] ) || match[2] === \"odd\" );\n\n // other types prohibit arguments\n } else if ( match[2] ) {\n Sizzle.error( match[0] );\n }\n\n return match;\n },\n\n \"PSEUDO\": function( match ) {\n var unquoted, excess;\n if ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n return null;\n }\n\n if ( match[3] ) {\n match[2] = match[3];\n } else if ( (unquoted = match[4]) ) {\n // Only check arguments that contain a pseudo\n if ( rpseudo.test(unquoted) &&\n // Get excess from tokenize (recursively)\n (excess = tokenize( unquoted, true )) &&\n // advance to the next closing parenthesis\n (excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n // excess is a negative index\n unquoted = unquoted.slice( 0, excess );\n match[0] = match[0].slice( 0, excess );\n }\n match[2] = unquoted;\n }\n\n // Return only captures needed by the pseudo filter method (type and argument)\n return match.slice( 0, 3 );\n }\n },\n\n filter: {\n \"ID\": assertGetIdNotName ?\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n return elem.getAttribute(\"id\") === id;\n };\n } :\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n return node && node.value === id;\n };\n },\n\n \"TAG\": function( nodeName ) {\n if ( nodeName === \"*\" ) {\n return function() { return true; };\n }\n nodeName = nodeName.replace( rbackslash, \"\" ).toLowerCase();\n\n return function( elem ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n };\n },\n\n \"CLASS\": function( className ) {\n var pattern = classCache[ expando ][ className + \" \" ];\n\n return pattern ||\n (pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n classCache( className, function( elem ) {\n return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\")) || \"\" );\n });\n },\n\n \"ATTR\": function( name, operator, check ) {\n return function( elem, context ) {\n var result = Sizzle.attr( elem, name );\n\n if ( result == null ) {\n return operator === \"!=\";\n }\n if ( !operator ) {\n return true;\n }\n\n result += \"\";\n\n return operator === \"=\" ? result === check :\n operator === \"!=\" ? result !== check :\n operator === \"^=\" ? check && result.indexOf( check ) === 0 :\n operator === \"*=\" ? check && result.indexOf( check ) > -1 :\n operator === \"$=\" ? check && result.substr( result.length - check.length ) === check :\n operator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n operator === \"|=\" ? result === check || result.substr( 0, check.length + 1 ) === check + \"-\" :\n false;\n };\n },\n\n \"CHILD\": function( type, argument, first, last ) {\n\n if ( type === \"nth\" ) {\n return function( elem ) {\n var node, diff,\n parent = elem.parentNode;\n\n if ( first === 1 && last === 0 ) {\n return true;\n }\n\n if ( parent ) {\n diff = 0;\n for ( node = parent.firstChild; node; node = node.nextSibling ) {\n if ( node.nodeType === 1 ) {\n diff++;\n if ( elem === node ) {\n break;\n }\n }\n }\n }\n\n // Incorporate the offset (or cast to NaN), then check against cycle size\n diff -= last;\n return diff === first || ( diff % first === 0 && diff / first >= 0 );\n };\n }\n\n return function( elem ) {\n var node = elem;\n\n switch ( type ) {\n case \"only\":\n case \"first\":\n while ( (node = node.previousSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n if ( type === \"first\" ) {\n return true;\n }\n\n node = elem;\n\n /* falls through */\n case \"last\":\n while ( (node = node.nextSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n return true;\n }\n };\n },\n\n \"PSEUDO\": function( pseudo, argument ) {\n // pseudo-class names are case-insensitive\n // http://www.w3.org/TR/selectors/#pseudo-classes\n // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n // Remember that setFilters inherits from pseudos\n var args,\n fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n Sizzle.error( \"unsupported pseudo: \" + pseudo );\n\n // The user may use createPseudo to indicate that\n // arguments are needed to create the filter function\n // just as Sizzle does\n if ( fn[ expando ] ) {\n return fn( argument );\n }\n\n // But maintain support for old signatures\n if ( fn.length > 1 ) {\n args = [ pseudo, pseudo, \"\", argument ];\n return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n markFunction(function( seed, matches ) {\n var idx,\n matched = fn( seed, argument ),\n i = matched.length;\n while ( i-- ) {\n idx = indexOf.call( seed, matched[i] );\n seed[ idx ] = !( matches[ idx ] = matched[i] );\n }\n }) :\n function( elem ) {\n return fn( elem, 0, args );\n };\n }\n\n return fn;\n }\n },\n\n pseudos: {\n \"not\": markFunction(function( selector ) {\n // Trim the selector passed to compile\n // to avoid treating leading and trailing\n // spaces as combinators\n var input = [],\n results = [],\n matcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n return matcher[ expando ] ?\n markFunction(function( seed, matches, context, xml ) {\n var elem,\n unmatched = matcher( seed, null, xml, [] ),\n i = seed.length;\n\n // Match elements unmatched by `matcher`\n while ( i-- ) {\n if ( (elem = unmatched[i]) ) {\n seed[i] = !(matches[i] = elem);\n }\n }\n }) :\n function( elem, context, xml ) {\n input[0] = elem;\n matcher( input, null, xml, results );\n return !results.pop();\n };\n }),\n\n \"has\": markFunction(function( selector ) {\n return function( elem ) {\n return Sizzle( selector, elem ).length > 0;\n };\n }),\n\n \"contains\": markFunction(function( text ) {\n return function( elem ) {\n return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n };\n }),\n\n \"enabled\": function( elem ) {\n return elem.disabled === false;\n },\n\n \"disabled\": function( elem ) {\n return elem.disabled === true;\n },\n\n \"checked\": function( elem ) {\n // In CSS3, :checked should return both checked and selected elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n var nodeName = elem.nodeName.toLowerCase();\n return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n },\n\n \"selected\": function( elem ) {\n // Accessing this property makes selected-by-default\n // options in Safari work properly\n if ( elem.parentNode ) {\n elem.parentNode.selectedIndex;\n }\n\n return elem.selected === true;\n },\n\n \"parent\": function( elem ) {\n return !Expr.pseudos[\"empty\"]( elem );\n },\n\n \"empty\": function( elem ) {\n // http://www.w3.org/TR/selectors/#empty-pseudo\n // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n // not comment, processing instructions, or others\n // Thanks to Diego Perini for the nodeName shortcut\n // Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n var nodeType;\n elem = elem.firstChild;\n while ( elem ) {\n if ( elem.nodeName > \"@\" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {\n return false;\n }\n elem = elem.nextSibling;\n }\n return true;\n },\n\n \"header\": function( elem ) {\n return rheader.test( elem.nodeName );\n },\n\n \"text\": function( elem ) {\n var type, attr;\n // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n // use getAttribute instead to test this case\n return elem.nodeName.toLowerCase() === \"input\" &&\n (type = elem.type) === \"text\" &&\n ( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === type );\n },\n\n // Input types\n \"radio\": createInputPseudo(\"radio\"),\n \"checkbox\": createInputPseudo(\"checkbox\"),\n \"file\": createInputPseudo(\"file\"),\n \"password\": createInputPseudo(\"password\"),\n \"image\": createInputPseudo(\"image\"),\n\n \"submit\": createButtonPseudo(\"submit\"),\n \"reset\": createButtonPseudo(\"reset\"),\n\n \"button\": function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === \"button\" || name === \"button\";\n },\n\n \"input\": function( elem ) {\n return rinputs.test( elem.nodeName );\n },\n\n \"focus\": function( elem ) {\n var doc = elem.ownerDocument;\n return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n },\n\n \"active\": function( elem ) {\n return elem === elem.ownerDocument.activeElement;\n },\n\n // Positional types\n \"first\": createPositionalPseudo(function() {\n return [ 0 ];\n }),\n\n \"last\": createPositionalPseudo(function( matchIndexes, length ) {\n return [ length - 1 ];\n }),\n\n \"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n return [ argument < 0 ? argument + length : argument ];\n }),\n\n \"even\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 0; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 1; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n })\n }\n};\n\nfunction siblingCheck( a, b, ret ) {\n if ( a === b ) {\n return ret;\n }\n\n var cur = a.nextSibling;\n\n while ( cur ) {\n if ( cur === b ) {\n return -1;\n }\n\n cur = cur.nextSibling;\n }\n\n return 1;\n}\n\nsortOrder = docElem.compareDocumentPosition ?\n function( a, b ) {\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n }\n\n return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?\n a.compareDocumentPosition :\n a.compareDocumentPosition(b) & 4\n ) ? -1 : 1;\n } :\n function( a, b ) {\n // The nodes are identical, we can exit early\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n\n // Fallback to using sourceIndex (in IE) if it's available on both nodes\n } else if ( a.sourceIndex && b.sourceIndex ) {\n return a.sourceIndex - b.sourceIndex;\n }\n\n var al, bl,\n ap = [],\n bp = [],\n aup = a.parentNode,\n bup = b.parentNode,\n cur = aup;\n\n // If the nodes are siblings (or identical) we can do a quick check\n if ( aup === bup ) {\n return siblingCheck( a, b );\n\n // If no parents were found then the nodes are disconnected\n } else if ( !aup ) {\n return -1;\n\n } else if ( !bup ) {\n return 1;\n }\n\n // Otherwise they're somewhere else in the tree so we need\n // to build up a full list of the parentNodes for comparison\n while ( cur ) {\n ap.unshift( cur );\n cur = cur.parentNode;\n }\n\n cur = bup;\n\n while ( cur ) {\n bp.unshift( cur );\n cur = cur.parentNode;\n }\n\n al = ap.length;\n bl = bp.length;\n\n // Start walking down the tree looking for a discrepancy\n for ( var i = 0; i < al && i < bl; i++ ) {\n if ( ap[i] !== bp[i] ) {\n return siblingCheck( ap[i], bp[i] );\n }\n }\n\n // We ended someplace up the tree so do a sibling check\n return i === al ?\n siblingCheck( a, bp[i], -1 ) :\n siblingCheck( ap[i], b, 1 );\n };\n\n// Always assume the presence of duplicates if sort doesn't\n// pass them to our comparison function (as in Google Chrome).\n[0, 0].sort( sortOrder );\nbaseHasDuplicate = !hasDuplicate;\n\n// Document sorting and removing duplicates\nSizzle.uniqueSort = function( results ) {\n var elem,\n duplicates = [],\n i = 1,\n j = 0;\n\n hasDuplicate = baseHasDuplicate;\n results.sort( sortOrder );\n\n if ( hasDuplicate ) {\n for ( ; (elem = results[i]); i++ ) {\n if ( elem === results[ i - 1 ] ) {\n j = duplicates.push( i );\n }\n }\n while ( j-- ) {\n results.splice( duplicates[ j ], 1 );\n }\n }\n\n return results;\n};\n\nSizzle.error = function( msg ) {\n throw new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nfunction tokenize( selector, parseOnly ) {\n var matched, match, tokens, type,\n soFar, groups, preFilters,\n cached = tokenCache[ expando ][ selector + \" \" ];\n\n if ( cached ) {\n return parseOnly ? 0 : cached.slice( 0 );\n }\n\n soFar = selector;\n groups = [];\n preFilters = Expr.preFilter;\n\n while ( soFar ) {\n\n // Comma and first run\n if ( !matched || (match = rcomma.exec( soFar )) ) {\n if ( match ) {\n // Don't consume trailing commas as valid\n soFar = soFar.slice( match[0].length ) || soFar;\n }\n groups.push( tokens = [] );\n }\n\n matched = false;\n\n // Combinators\n if ( (match = rcombinators.exec( soFar )) ) {\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n\n // Cast descendant combinators to space\n matched.type = match[0].replace( rtrim, \" \" );\n }\n\n // Filters\n for ( type in Expr.filter ) {\n if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n (match = preFilters[ type ]( match ))) ) {\n\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n matched.type = type;\n matched.matches = match;\n }\n }\n\n if ( !matched ) {\n break;\n }\n }\n\n // Return the length of the invalid excess\n // if we're just parsing\n // Otherwise, throw an error or return tokens\n return parseOnly ?\n soFar.length :\n soFar ?\n Sizzle.error( selector ) :\n // Cache the tokens\n tokenCache( selector, groups ).slice( 0 );\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n var dir = combinator.dir,\n checkNonElements = base && combinator.dir === \"parentNode\",\n doneName = done++;\n\n return combinator.first ?\n // Check against closest ancestor/preceding element\n function( elem, context, xml ) {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n return matcher( elem, context, xml );\n }\n }\n } :\n\n // Check against all ancestor/preceding elements\n function( elem, context, xml ) {\n // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n if ( !xml ) {\n var cache,\n dirkey = dirruns + \" \" + doneName + \" \",\n cachedkey = dirkey + cachedruns;\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( (cache = elem[ expando ]) === cachedkey ) {\n return elem.sizset;\n } else if ( typeof cache === \"string\" && cache.indexOf(dirkey) === 0 ) {\n if ( elem.sizset ) {\n return elem;\n }\n } else {\n elem[ expando ] = cachedkey;\n if ( matcher( elem, context, xml ) ) {\n elem.sizset = true;\n return elem;\n }\n elem.sizset = false;\n }\n }\n }\n } else {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( matcher( elem, context, xml ) ) {\n return elem;\n }\n }\n }\n }\n };\n}\n\nfunction elementMatcher( matchers ) {\n return matchers.length > 1 ?\n function( elem, context, xml ) {\n var i = matchers.length;\n while ( i-- ) {\n if ( !matchers[i]( elem, context, xml ) ) {\n return false;\n }\n }\n return true;\n } :\n matchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n var elem,\n newUnmatched = [],\n i = 0,\n len = unmatched.length,\n mapped = map != null;\n\n for ( ; i < len; i++ ) {\n if ( (elem = unmatched[i]) ) {\n if ( !filter || filter( elem, context, xml ) ) {\n newUnmatched.push( elem );\n if ( mapped ) {\n map.push( i );\n }\n }\n }\n }\n\n return newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n if ( postFilter && !postFilter[ expando ] ) {\n postFilter = setMatcher( postFilter );\n }\n if ( postFinder && !postFinder[ expando ] ) {\n postFinder = setMatcher( postFinder, postSelector );\n }\n return markFunction(function( seed, results, context, xml ) {\n var temp, i, elem,\n preMap = [],\n postMap = [],\n preexisting = results.length,\n\n // Get initial elements from seed or context\n elems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n // Prefilter to get matcher input, preserving a map for seed-results synchronization\n matcherIn = preFilter && ( seed || !selector ) ?\n condense( elems, preMap, preFilter, context, xml ) :\n elems,\n\n matcherOut = matcher ?\n // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n // ...intermediate processing is necessary\n [] :\n\n // ...otherwise use results directly\n results :\n matcherIn;\n\n // Find primary matches\n if ( matcher ) {\n matcher( matcherIn, matcherOut, context, xml );\n }\n\n // Apply postFilter\n if ( postFilter ) {\n temp = condense( matcherOut, postMap );\n postFilter( temp, [], context, xml );\n\n // Un-match failing elements by moving them back to matcherIn\n i = temp.length;\n while ( i-- ) {\n if ( (elem = temp[i]) ) {\n matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n }\n }\n }\n\n if ( seed ) {\n if ( postFinder || preFilter ) {\n if ( postFinder ) {\n // Get the final matcherOut by condensing this intermediate into postFinder contexts\n temp = [];\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) ) {\n // Restore matcherIn since elem is not yet a final match\n temp.push( (matcherIn[i] = elem) );\n }\n }\n postFinder( null, (matcherOut = []), temp, xml );\n }\n\n // Move matched elements from seed to results to keep them synchronized\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) &&\n (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n seed[temp] = !(results[temp] = elem);\n }\n }\n }\n\n // Add elements to results, through postFinder if defined\n } else {\n matcherOut = condense(\n matcherOut === results ?\n matcherOut.splice( preexisting, matcherOut.length ) :\n matcherOut\n );\n if ( postFinder ) {\n postFinder( null, results, matcherOut, xml );\n } else {\n push.apply( results, matcherOut );\n }\n }\n });\n}\n\nfunction matcherFromTokens( tokens ) {\n var checkContext, matcher, j,\n len = tokens.length,\n leadingRelative = Expr.relative[ tokens[0].type ],\n implicitRelative = leadingRelative || Expr.relative[\" \"],\n i = leadingRelative ? 1 : 0,\n\n // The foundational matcher ensures that elements are reachable from top-level context(s)\n matchContext = addCombinator( function( elem ) {\n return elem === checkContext;\n }, implicitRelative, true ),\n matchAnyContext = addCombinator( function( elem ) {\n return indexOf.call( checkContext, elem ) > -1;\n }, implicitRelative, true ),\n matchers = [ function( elem, context, xml ) {\n return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n (checkContext = context).nodeType ?\n matchContext( elem, context, xml ) :\n matchAnyContext( elem, context, xml ) );\n } ];\n\n for ( ; i < len; i++ ) {\n if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n } else {\n matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n // Return special upon seeing a positional matcher\n if ( matcher[ expando ] ) {\n // Find the next relative operator (if any) for proper handling\n j = ++i;\n for ( ; j < len; j++ ) {\n if ( Expr.relative[ tokens[j].type ] ) {\n break;\n }\n }\n return setMatcher(\n i > 1 && elementMatcher( matchers ),\n i > 1 && tokens.slice( 0, i - 1 ).join(\"\").replace( rtrim, \"$1\" ),\n matcher,\n i < j && matcherFromTokens( tokens.slice( i, j ) ),\n j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n j < len && tokens.join(\"\")\n );\n }\n matchers.push( matcher );\n }\n }\n\n return elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n var bySet = setMatchers.length > 0,\n byElement = elementMatchers.length > 0,\n superMatcher = function( seed, context, xml, results, expandContext ) {\n var elem, j, matcher,\n setMatched = [],\n matchedCount = 0,\n i = \"0\",\n unmatched = seed && [],\n outermost = expandContext != null,\n contextBackup = outermostContext,\n // We must always have either seed elements or context\n elems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n // Nested matchers should use non-integer dirruns\n dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\n\n if ( outermost ) {\n outermostContext = context !== document && context;\n cachedruns = superMatcher.el;\n }\n\n // Add elements passing elementMatchers directly to results\n for ( ; (elem = elems[i]) != null; i++ ) {\n if ( byElement && elem ) {\n for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\n if ( matcher( elem, context, xml ) ) {\n results.push( elem );\n break;\n }\n }\n if ( outermost ) {\n dirruns = dirrunsUnique;\n cachedruns = ++superMatcher.el;\n }\n }\n\n // Track unmatched elements for set filters\n if ( bySet ) {\n // They will have gone through all possible matchers\n if ( (elem = !matcher && elem) ) {\n matchedCount--;\n }\n\n // Lengthen the array for every element, matched or not\n if ( seed ) {\n unmatched.push( elem );\n }\n }\n }\n\n // Apply set filters to unmatched elements\n matchedCount += i;\n if ( bySet && i !== matchedCount ) {\n for ( j = 0; (matcher = setMatchers[j]); j++ ) {\n matcher( unmatched, setMatched, context, xml );\n }\n\n if ( seed ) {\n // Reintegrate element matches to eliminate the need for sorting\n if ( matchedCount > 0 ) {\n while ( i-- ) {\n if ( !(unmatched[i] || setMatched[i]) ) {\n setMatched[i] = pop.call( results );\n }\n }\n }\n\n // Discard index placeholder values to get only actual matches\n setMatched = condense( setMatched );\n }\n\n // Add matches to results\n push.apply( results, setMatched );\n\n // Seedless set matches succeeding multiple successful matchers stipulate sorting\n if ( outermost && !seed && setMatched.length > 0 &&\n ( matchedCount + setMatchers.length ) > 1 ) {\n\n Sizzle.uniqueSort( results );\n }\n }\n\n // Override manipulation of globals by nested matchers\n if ( outermost ) {\n dirruns = dirrunsUnique;\n outermostContext = contextBackup;\n }\n\n return unmatched;\n };\n\n superMatcher.el = 0;\n return bySet ?\n markFunction( superMatcher ) :\n superMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n var i,\n setMatchers = [],\n elementMatchers = [],\n cached = compilerCache[ expando ][ selector + \" \" ];\n\n if ( !cached ) {\n // Generate a function of recursive functions that can be used to check each element\n if ( !group ) {\n group = tokenize( selector );\n }\n i = group.length;\n while ( i-- ) {\n cached = matcherFromTokens( group[i] );\n if ( cached[ expando ] ) {\n setMatchers.push( cached );\n } else {\n elementMatchers.push( cached );\n }\n }\n\n // Cache the compiled function\n cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n }\n return cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n var i = 0,\n len = contexts.length;\n for ( ; i < len; i++ ) {\n Sizzle( selector, contexts[i], results );\n }\n return results;\n}\n\nfunction select( selector, context, results, seed, xml ) {\n var i, tokens, token, type, find,\n match = tokenize( selector ),\n j = match.length;\n\n if ( !seed ) {\n // Try to minimize operations if there is only one group\n if ( match.length === 1 ) {\n\n // Take a shortcut and set the context if the root selector is an ID\n tokens = match[0] = match[0].slice( 0 );\n if ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n context.nodeType === 9 && !xml &&\n Expr.relative[ tokens[1].type ] ) {\n\n context = Expr.find[\"ID\"]( token.matches[0].replace( rbackslash, \"\" ), context, xml )[0];\n if ( !context ) {\n return results;\n }\n\n selector = selector.slice( tokens.shift().length );\n }\n\n // Fetch a seed set for right-to-left matching\n for ( i = matchExpr[\"POS\"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\n token = tokens[i];\n\n // Abort if we hit a combinator\n if ( Expr.relative[ (type = token.type) ] ) {\n break;\n }\n if ( (find = Expr.find[ type ]) ) {\n // Search, expanding context for leading sibling combinators\n if ( (seed = find(\n token.matches[0].replace( rbackslash, \"\" ),\n rsibling.test( tokens[0].type ) && context.parentNode || context,\n xml\n )) ) {\n\n // If seed is empty or no tokens remain, we can return early\n tokens.splice( i, 1 );\n selector = seed.length && tokens.join(\"\");\n if ( !selector ) {\n push.apply( results, slice.call( seed, 0 ) );\n return results;\n }\n\n break;\n }\n }\n }\n }\n }\n\n // Compile and execute a filtering function\n // Provide `match` to avoid retokenization if we modified the selector above\n compile( selector, match )(\n seed,\n context,\n xml,\n results,\n rsibling.test( selector )\n );\n return results;\n}\n\nif ( document.querySelectorAll ) {\n (function() {\n var disconnectedMatch,\n oldSelect = select,\n rescape = /'|\\\\/g,\n rattributeQuotes = /\\=[\\x20\\t\\r\\n\\f]*([^'\"\\]]*)[\\x20\\t\\r\\n\\f]*\\]/g,\n\n // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\n // A support test would require too much code (would include document ready)\n rbuggyQSA = [ \":focus\" ],\n\n // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n // A support test would require too much code (would include document ready)\n // just skip matchesSelector for :active\n rbuggyMatches = [ \":active\" ],\n matches = docElem.matchesSelector ||\n docElem.mozMatchesSelector ||\n docElem.webkitMatchesSelector ||\n docElem.oMatchesSelector ||\n docElem.msMatchesSelector;\n\n // Build QSA regex\n // Regex strategy adopted from Diego Perini\n assert(function( div ) {\n // Select is set to empty string on purpose\n // This is to test IE's treatment of not explictly\n // setting a boolean content attribute,\n // since its presence should be enough\n // http://bugs.jquery.com/ticket/12359\n div.innerHTML = \"\";\n\n // IE8 - Some boolean attributes are not treated correctly\n if ( !div.querySelectorAll(\"[selected]\").length ) {\n rbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:checked|disabled|ismap|multiple|readonly|selected|value)\" );\n }\n\n // Webkit/Opera - :checked should return selected option elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n // IE8 throws error here (do not put tests after this one)\n if ( !div.querySelectorAll(\":checked\").length ) {\n rbuggyQSA.push(\":checked\");\n }\n });\n\n assert(function( div ) {\n\n // Opera 10-12/IE9 - ^= $= *= and empty values\n // Should not select anything\n div.innerHTML = \"

    \";\n if ( div.querySelectorAll(\"[test^='']\").length ) {\n rbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:\\\"\\\"|'')\" );\n }\n\n // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n // IE8 throws error here (do not put tests after this one)\n div.innerHTML = \"\";\n if ( !div.querySelectorAll(\":enabled\").length ) {\n rbuggyQSA.push(\":enabled\", \":disabled\");\n }\n });\n\n // rbuggyQSA always contains :focus, so no need for a length check\n rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join(\"|\") );\n\n select = function( selector, context, results, seed, xml ) {\n // Only use querySelectorAll when not filtering,\n // when this is not xml,\n // and when no QSA bugs apply\n if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\n var groups, i,\n old = true,\n nid = expando,\n newContext = context,\n newSelector = context.nodeType === 9 && selector;\n\n // qSA works strangely on Element-rooted queries\n // We can work around this by specifying an extra ID on the root\n // and working up from there (Thanks to Andrew Dupont for the technique)\n // IE 8 doesn't work on object elements\n if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n groups = tokenize( selector );\n\n if ( (old = context.getAttribute(\"id\")) ) {\n nid = old.replace( rescape, \"\\\\$&\" );\n } else {\n context.setAttribute( \"id\", nid );\n }\n nid = \"[id='\" + nid + \"'] \";\n\n i = groups.length;\n while ( i-- ) {\n groups[i] = nid + groups[i].join(\"\");\n }\n newContext = rsibling.test( selector ) && context.parentNode || context;\n newSelector = groups.join(\",\");\n }\n\n if ( newSelector ) {\n try {\n push.apply( results, slice.call( newContext.querySelectorAll(\n newSelector\n ), 0 ) );\n return results;\n } catch(qsaError) {\n } finally {\n if ( !old ) {\n context.removeAttribute(\"id\");\n }\n }\n }\n }\n\n return oldSelect( selector, context, results, seed, xml );\n };\n\n if ( matches ) {\n assert(function( div ) {\n // Check to see if it's possible to do matchesSelector\n // on a disconnected node (IE 9)\n disconnectedMatch = matches.call( div, \"div\" );\n\n // This should fail with an exception\n // Gecko does not error, returns false instead\n try {\n matches.call( div, \"[test!='']:sizzle\" );\n rbuggyMatches.push( \"!=\", pseudos );\n } catch ( e ) {}\n });\n\n // rbuggyMatches always contains :active and :focus, so no need for a length check\n rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join(\"|\") );\n\n Sizzle.matchesSelector = function( elem, expr ) {\n // Make sure that attribute selectors are quoted\n expr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n // rbuggyMatches always contains :active, so no need for an existence check\n if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\n try {\n var ret = matches.call( elem, expr );\n\n // IE 9's matchesSelector returns false on disconnected nodes\n if ( ret || disconnectedMatch ||\n // As well, disconnected nodes are said to be in a document\n // fragment in IE 9\n elem.document && elem.document.nodeType !== 11 ) {\n return ret;\n }\n } catch(e) {}\n }\n\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n };\n }\n })();\n}\n\n// Deprecated\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Back-compat\nfunction setFilters() {}\nExpr.filters = setFilters.prototype = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\n// Override sizzle attribute retrieval\nSizzle.attr = jQuery.attr;\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\nvar runtil = /Until$/,\n rparentsprev = /^(?:parents|prev(?:Until|All))/,\n isSimple = /^.[^:#\\[\\.,]*$/,\n rneedsContext = jQuery.expr.match.needsContext,\n // methods guaranteed to produce a unique set when starting from a unique set\n guaranteedUnique = {\n children: true,\n contents: true,\n next: true,\n prev: true\n };\n\njQuery.fn.extend({\n find: function( selector ) {\n var i, l, length, n, r, ret,\n self = this;\n\n if ( typeof selector !== \"string\" ) {\n return jQuery( selector ).filter(function() {\n for ( i = 0, l = self.length; i < l; i++ ) {\n if ( jQuery.contains( self[ i ], this ) ) {\n return true;\n }\n }\n });\n }\n\n ret = this.pushStack( \"\", \"find\", selector );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n length = ret.length;\n jQuery.find( selector, this[i], ret );\n\n if ( i > 0 ) {\n // Make sure that the results are unique\n for ( n = length; n < ret.length; n++ ) {\n for ( r = 0; r < length; r++ ) {\n if ( ret[r] === ret[n] ) {\n ret.splice(n--, 1);\n break;\n }\n }\n }\n }\n }\n\n return ret;\n },\n\n has: function( target ) {\n var i,\n targets = jQuery( target, this ),\n len = targets.length;\n\n return this.filter(function() {\n for ( i = 0; i < len; i++ ) {\n if ( jQuery.contains( this, targets[i] ) ) {\n return true;\n }\n }\n });\n },\n\n not: function( selector ) {\n return this.pushStack( winnow(this, selector, false), \"not\", selector);\n },\n\n filter: function( selector ) {\n return this.pushStack( winnow(this, selector, true), \"filter\", selector );\n },\n\n is: function( selector ) {\n return !!selector && (\n typeof selector === \"string\" ?\n // If this is a positional/relative selector, check membership in the returned set\n // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n rneedsContext.test( selector ) ?\n jQuery( selector, this.context ).index( this[0] ) >= 0 :\n jQuery.filter( selector, this ).length > 0 :\n this.filter( selector ).length > 0 );\n },\n\n closest: function( selectors, context ) {\n var cur,\n i = 0,\n l = this.length,\n ret = [],\n pos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n jQuery( selectors, context || this.context ) :\n 0;\n\n for ( ; i < l; i++ ) {\n cur = this[i];\n\n while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {\n if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n ret.push( cur );\n break;\n }\n cur = cur.parentNode;\n }\n }\n\n ret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n return this.pushStack( ret, \"closest\", selectors );\n },\n\n // Determine the position of an element within\n // the matched set of elements\n index: function( elem ) {\n\n // No argument, return index in parent\n if ( !elem ) {\n return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n }\n\n // index in selector\n if ( typeof elem === \"string\" ) {\n return jQuery.inArray( this[0], jQuery( elem ) );\n }\n\n // Locate the position of the desired element\n return jQuery.inArray(\n // If it receives a jQuery object, the first element is used\n elem.jquery ? elem[0] : elem, this );\n },\n\n add: function( selector, context ) {\n var set = typeof selector === \"string\" ?\n jQuery( selector, context ) :\n jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n all = jQuery.merge( this.get(), set );\n\n return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n all :\n jQuery.unique( all ) );\n },\n\n addBack: function( selector ) {\n return this.add( selector == null ?\n this.prevObject : this.prevObject.filter(selector)\n );\n }\n});\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n return !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\nfunction sibling( cur, dir ) {\n do {\n cur = cur[ dir ];\n } while ( cur && cur.nodeType !== 1 );\n\n return cur;\n}\n\njQuery.each({\n parent: function( elem ) {\n var parent = elem.parentNode;\n return parent && parent.nodeType !== 11 ? parent : null;\n },\n parents: function( elem ) {\n return jQuery.dir( elem, \"parentNode\" );\n },\n parentsUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"parentNode\", until );\n },\n next: function( elem ) {\n return sibling( elem, \"nextSibling\" );\n },\n prev: function( elem ) {\n return sibling( elem, \"previousSibling\" );\n },\n nextAll: function( elem ) {\n return jQuery.dir( elem, \"nextSibling\" );\n },\n prevAll: function( elem ) {\n return jQuery.dir( elem, \"previousSibling\" );\n },\n nextUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"nextSibling\", until );\n },\n prevUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"previousSibling\", until );\n },\n siblings: function( elem ) {\n return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n },\n children: function( elem ) {\n return jQuery.sibling( elem.firstChild );\n },\n contents: function( elem ) {\n return jQuery.nodeName( elem, \"iframe\" ) ?\n elem.contentDocument || elem.contentWindow.document :\n jQuery.merge( [], elem.childNodes );\n }\n}, function( name, fn ) {\n jQuery.fn[ name ] = function( until, selector ) {\n var ret = jQuery.map( this, fn, until );\n\n if ( !runtil.test( name ) ) {\n selector = until;\n }\n\n if ( selector && typeof selector === \"string\" ) {\n ret = jQuery.filter( selector, ret );\n }\n\n ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n if ( this.length > 1 && rparentsprev.test( name ) ) {\n ret = ret.reverse();\n }\n\n return this.pushStack( ret, name, core_slice.call( arguments ).join(\",\") );\n };\n});\n\njQuery.extend({\n filter: function( expr, elems, not ) {\n if ( not ) {\n expr = \":not(\" + expr + \")\";\n }\n\n return elems.length === 1 ?\n jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n jQuery.find.matches(expr, elems);\n },\n\n dir: function( elem, dir, until ) {\n var matched = [],\n cur = elem[ dir ];\n\n while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n if ( cur.nodeType === 1 ) {\n matched.push( cur );\n }\n cur = cur[dir];\n }\n return matched;\n },\n\n sibling: function( n, elem ) {\n var r = [];\n\n for ( ; n; n = n.nextSibling ) {\n if ( n.nodeType === 1 && n !== elem ) {\n r.push( n );\n }\n }\n\n return r;\n }\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n // Can't pass null or undefined to indexOf in Firefox 4\n // Set to 0 to skip string check\n qualifier = qualifier || 0;\n\n if ( jQuery.isFunction( qualifier ) ) {\n return jQuery.grep(elements, function( elem, i ) {\n var retVal = !!qualifier.call( elem, i, elem );\n return retVal === keep;\n });\n\n } else if ( qualifier.nodeType ) {\n return jQuery.grep(elements, function( elem, i ) {\n return ( elem === qualifier ) === keep;\n });\n\n } else if ( typeof qualifier === \"string\" ) {\n var filtered = jQuery.grep(elements, function( elem ) {\n return elem.nodeType === 1;\n });\n\n if ( isSimple.test( qualifier ) ) {\n return jQuery.filter(qualifier, filtered, !keep);\n } else {\n qualifier = jQuery.filter( qualifier, filtered );\n }\n }\n\n return jQuery.grep(elements, function( elem, i ) {\n return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;\n });\n}\nfunction createSafeFragment( document ) {\n var list = nodeNames.split( \"|\" ),\n safeFrag = document.createDocumentFragment();\n\n if ( safeFrag.createElement ) {\n while ( list.length ) {\n safeFrag.createElement(\n list.pop()\n );\n }\n }\n return safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n \"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n rinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n rleadingWhitespace = /^\\s+/,\n rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n rtagName = /<([\\w:]+)/,\n rtbody = /]\", \"i\"),\n rcheckableType = /^(?:checkbox|radio)$/,\n // checked=\"checked\" or checked\n rchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n rscriptType = /\\/(java|ecma)script/i,\n rcleanScript = /^\\s*\\s*$/g,\n wrapMap = {\n option: [ 1, \"\" ],\n legend: [ 1, \"
    \", \"
    \" ],\n thead: [ 1, \"\", \"
    \" ],\n tr: [ 2, \"\", \"
    \" ],\n td: [ 3, \"\", \"
    \" ],\n col: [ 2, \"\", \"
    \" ],\n area: [ 1, \"\", \"\" ],\n _default: [ 0, \"\", \"\" ]\n },\n safeFragment = createSafeFragment( document ),\n fragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n// unless wrapped in a div with non-breaking characters in front of it.\nif ( !jQuery.support.htmlSerialize ) {\n wrapMap._default = [ 1, \"X
    \", \"
    \" ];\n}\n\njQuery.fn.extend({\n text: function( value ) {\n return jQuery.access( this, function( value ) {\n return value === undefined ?\n jQuery.text( this ) :\n this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n }, null, value, arguments.length );\n },\n\n wrapAll: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapAll( html.call(this, i) );\n });\n }\n\n if ( this[0] ) {\n // The elements to wrap the target around\n var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n if ( this[0].parentNode ) {\n wrap.insertBefore( this[0] );\n }\n\n wrap.map(function() {\n var elem = this;\n\n while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n elem = elem.firstChild;\n }\n\n return elem;\n }).append( this );\n }\n\n return this;\n },\n\n wrapInner: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapInner( html.call(this, i) );\n });\n }\n\n return this.each(function() {\n var self = jQuery( this ),\n contents = self.contents();\n\n if ( contents.length ) {\n contents.wrapAll( html );\n\n } else {\n self.append( html );\n }\n });\n },\n\n wrap: function( html ) {\n var isFunction = jQuery.isFunction( html );\n\n return this.each(function(i) {\n jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n });\n },\n\n unwrap: function() {\n return this.parent().each(function() {\n if ( !jQuery.nodeName( this, \"body\" ) ) {\n jQuery( this ).replaceWith( this.childNodes );\n }\n }).end();\n },\n\n append: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.appendChild( elem );\n }\n });\n },\n\n prepend: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.insertBefore( elem, this.firstChild );\n }\n });\n },\n\n before: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( set, this ), \"before\", this.selector );\n }\n },\n\n after: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this.nextSibling );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( this, set ), \"after\", this.selector );\n }\n },\n\n // keepData is for internal use only--do not document\n remove: function( selector, keepData ) {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n if ( !keepData && elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n jQuery.cleanData( [ elem ] );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n }\n }\n\n return this;\n },\n\n empty: function() {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n // Remove element nodes and prevent memory leaks\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n }\n\n // Remove any remaining nodes\n while ( elem.firstChild ) {\n elem.removeChild( elem.firstChild );\n }\n }\n\n return this;\n },\n\n clone: function( dataAndEvents, deepDataAndEvents ) {\n dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n return this.map( function () {\n return jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n });\n },\n\n html: function( value ) {\n return jQuery.access( this, function( value ) {\n var elem = this[0] || {},\n i = 0,\n l = this.length;\n\n if ( value === undefined ) {\n return elem.nodeType === 1 ?\n elem.innerHTML.replace( rinlinejQuery, \"\" ) :\n undefined;\n }\n\n // See if we can take a shortcut and just use innerHTML\n if ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&\n ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n !wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n value = value.replace( rxhtmlTag, \"<$1>\" );\n\n try {\n for (; i < l; i++ ) {\n // Remove element nodes and prevent memory leaks\n elem = this[i] || {};\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName( \"*\" ) );\n elem.innerHTML = value;\n }\n }\n\n elem = 0;\n\n // If using innerHTML throws an exception, use the fallback method\n } catch(e) {}\n }\n\n if ( elem ) {\n this.empty().append( value );\n }\n }, null, value, arguments.length );\n },\n\n replaceWith: function( value ) {\n if ( !isDisconnected( this[0] ) ) {\n // Make sure that the elements are removed from the DOM before they are inserted\n // this can help fix replacing a parent with child elements\n if ( jQuery.isFunction( value ) ) {\n return this.each(function(i) {\n var self = jQuery(this), old = self.html();\n self.replaceWith( value.call( this, i, old ) );\n });\n }\n\n if ( typeof value !== \"string\" ) {\n value = jQuery( value ).detach();\n }\n\n return this.each(function() {\n var next = this.nextSibling,\n parent = this.parentNode;\n\n jQuery( this ).remove();\n\n if ( next ) {\n jQuery(next).before( value );\n } else {\n jQuery(parent).append( value );\n }\n });\n }\n\n return this.length ?\n this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n this;\n },\n\n detach: function( selector ) {\n return this.remove( selector, true );\n },\n\n domManip: function( args, table, callback ) {\n\n // Flatten any nested arrays\n args = [].concat.apply( [], args );\n\n var results, first, fragment, iNoClone,\n i = 0,\n value = args[0],\n scripts = [],\n l = this.length;\n\n // We can't cloneNode fragments that contain checked, in WebKit\n if ( !jQuery.support.checkClone && l > 1 && typeof value === \"string\" && rchecked.test( value ) ) {\n return this.each(function() {\n jQuery(this).domManip( args, table, callback );\n });\n }\n\n if ( jQuery.isFunction(value) ) {\n return this.each(function(i) {\n var self = jQuery(this);\n args[0] = value.call( this, i, table ? self.html() : undefined );\n self.domManip( args, table, callback );\n });\n }\n\n if ( this[0] ) {\n results = jQuery.buildFragment( args, this, scripts );\n fragment = results.fragment;\n first = fragment.firstChild;\n\n if ( fragment.childNodes.length === 1 ) {\n fragment = first;\n }\n\n if ( first ) {\n table = table && jQuery.nodeName( first, \"tr\" );\n\n // Use the original fragment for the last item instead of the first because it can end up\n // being emptied incorrectly in certain situations (#8070).\n // Fragments from the fragment cache must always be cloned and never used in place.\n for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {\n callback.call(\n table && jQuery.nodeName( this[i], \"table\" ) ?\n findOrAppend( this[i], \"tbody\" ) :\n this[i],\n i === iNoClone ?\n fragment :\n jQuery.clone( fragment, true, true )\n );\n }\n }\n\n // Fix #11809: Avoid leaking memory\n fragment = first = null;\n\n if ( scripts.length ) {\n jQuery.each( scripts, function( i, elem ) {\n if ( elem.src ) {\n if ( jQuery.ajax ) {\n jQuery.ajax({\n url: elem.src,\n type: \"GET\",\n dataType: \"script\",\n async: false,\n global: false,\n \"throws\": true\n });\n } else {\n jQuery.error(\"no ajax\");\n }\n } else {\n jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n });\n }\n }\n\n return this;\n }\n});\n\nfunction findOrAppend( elem, tag ) {\n return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n return;\n }\n\n var type, i, l,\n oldData = jQuery._data( src ),\n curData = jQuery._data( dest, oldData ),\n events = oldData.events;\n\n if ( events ) {\n delete curData.handle;\n curData.events = {};\n\n for ( type in events ) {\n for ( i = 0, l = events[ type ].length; i < l; i++ ) {\n jQuery.event.add( dest, type, events[ type ][ i ] );\n }\n }\n }\n\n // make the cloned public data object a copy from the original\n if ( curData.data ) {\n curData.data = jQuery.extend( {}, curData.data );\n }\n}\n\nfunction cloneFixAttributes( src, dest ) {\n var nodeName;\n\n // We do not need to do anything for non-Elements\n if ( dest.nodeType !== 1 ) {\n return;\n }\n\n // clearAttributes removes the attributes, which we don't want,\n // but also removes the attachEvent events, which we *do* want\n if ( dest.clearAttributes ) {\n dest.clearAttributes();\n }\n\n // mergeAttributes, in contrast, only merges back on the\n // original attributes, not the events\n if ( dest.mergeAttributes ) {\n dest.mergeAttributes( src );\n }\n\n nodeName = dest.nodeName.toLowerCase();\n\n if ( nodeName === \"object\" ) {\n // IE6-10 improperly clones children of object elements using classid.\n // IE10 throws NoModificationAllowedError if parent is null, #12132.\n if ( dest.parentNode ) {\n dest.outerHTML = src.outerHTML;\n }\n\n // This path appears unavoidable for IE9. When cloning an object\n // element in IE9, the outerHTML strategy above is not sufficient.\n // If the src has innerHTML and the destination does not,\n // copy the src.innerHTML into the dest.innerHTML. #10324\n if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {\n dest.innerHTML = src.innerHTML;\n }\n\n } else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n // IE6-8 fails to persist the checked state of a cloned checkbox\n // or radio button. Worse, IE6-7 fail to give the cloned element\n // a checked appearance if the defaultChecked value isn't also set\n\n dest.defaultChecked = dest.checked = src.checked;\n\n // IE6-7 get confused and end up setting the value of a cloned\n // checkbox/radio button to an empty string instead of \"on\"\n if ( dest.value !== src.value ) {\n dest.value = src.value;\n }\n\n // IE6-8 fails to return the selected option to the default selected\n // state when cloning options\n } else if ( nodeName === \"option\" ) {\n dest.selected = src.defaultSelected;\n\n // IE6-8 fails to set the defaultValue to the correct value when\n // cloning other types of input fields\n } else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n dest.defaultValue = src.defaultValue;\n\n // IE blanks contents when cloning scripts\n } else if ( nodeName === \"script\" && dest.text !== src.text ) {\n dest.text = src.text;\n }\n\n // Event data gets referenced instead of copied if the expando\n // gets copied too\n dest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, context, scripts ) {\n var fragment, cacheable, cachehit,\n first = args[ 0 ];\n\n // Set context from what may come in as undefined or a jQuery collection or a node\n // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &\n // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception\n context = context || document;\n context = !context.nodeType && context[0] || context;\n context = context.ownerDocument || context;\n\n // Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n // Cloning options loses the selected state, so don't cache them\n // IE 6 doesn't like it when you put or elements in a fragment\n // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501\n if ( args.length === 1 && typeof first === \"string\" && first.length < 512 && context === document &&\n first.charAt(0) === \"<\" && !rnocache.test( first ) &&\n (jQuery.support.checkClone || !rchecked.test( first )) &&\n (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {\n\n // Mark cacheable and look for a hit\n cacheable = true;\n fragment = jQuery.fragments[ first ];\n cachehit = fragment !== undefined;\n }\n\n if ( !fragment ) {\n fragment = context.createDocumentFragment();\n jQuery.clean( args, context, fragment, scripts );\n\n // Update the cache, but only store false\n // unless this is a second parsing of the same content\n if ( cacheable ) {\n jQuery.fragments[ first ] = cachehit && fragment;\n }\n }\n\n return { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n appendTo: \"append\",\n prependTo: \"prepend\",\n insertBefore: \"before\",\n insertAfter: \"after\",\n replaceAll: \"replaceWith\"\n}, function( name, original ) {\n jQuery.fn[ name ] = function( selector ) {\n var elems,\n i = 0,\n ret = [],\n insert = jQuery( selector ),\n l = insert.length,\n parent = this.length === 1 && this[0].parentNode;\n\n if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {\n insert[ original ]( this[0] );\n return this;\n } else {\n for ( ; i < l; i++ ) {\n elems = ( i > 0 ? this.clone(true) : this ).get();\n jQuery( insert[i] )[ original ]( elems );\n ret = ret.concat( elems );\n }\n\n return this.pushStack( ret, name, insert.selector );\n }\n };\n});\n\nfunction getAll( elem ) {\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n return elem.getElementsByTagName( \"*\" );\n\n } else if ( typeof elem.querySelectorAll !== \"undefined\" ) {\n return elem.querySelectorAll( \"*\" );\n\n } else {\n return [];\n }\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n if ( rcheckableType.test( elem.type ) ) {\n elem.defaultChecked = elem.checked;\n }\n}\n\njQuery.extend({\n clone: function( elem, dataAndEvents, deepDataAndEvents ) {\n var srcElements,\n destElements,\n i,\n clone;\n\n if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n clone = elem.cloneNode( true );\n\n // IE<=8 does not properly clone detached, unknown element nodes\n } else {\n fragmentDiv.innerHTML = elem.outerHTML;\n fragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n }\n\n if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n // IE copies events bound via attachEvent when using cloneNode.\n // Calling detachEvent on the clone will also remove the events\n // from the original. In order to get around this, we use some\n // proprietary methods to clear the events. Thanks to MooTools\n // guys for this hotness.\n\n cloneFixAttributes( elem, clone );\n\n // Using Sizzle here is crazy slow, so we use getElementsByTagName instead\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n // Weird iteration because IE will replace the length property\n // with an element if you are cloning the body and one of the\n // elements on the page has a name or id of \"length\"\n for ( i = 0; srcElements[i]; ++i ) {\n // Ensure that the destination node is not null; Fixes #9587\n if ( destElements[i] ) {\n cloneFixAttributes( srcElements[i], destElements[i] );\n }\n }\n }\n\n // Copy the events from the original to the clone\n if ( dataAndEvents ) {\n cloneCopyEvent( elem, clone );\n\n if ( deepDataAndEvents ) {\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n for ( i = 0; srcElements[i]; ++i ) {\n cloneCopyEvent( srcElements[i], destElements[i] );\n }\n }\n }\n\n srcElements = destElements = null;\n\n // Return the cloned set\n return clone;\n },\n\n clean: function( elems, context, fragment, scripts ) {\n var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,\n safe = context === document && safeFragment,\n ret = [];\n\n // Ensure that context is a document\n if ( !context || typeof context.createDocumentFragment === \"undefined\" ) {\n context = document;\n }\n\n // Use the already-created safe fragment if context permits\n for ( i = 0; (elem = elems[i]) != null; i++ ) {\n if ( typeof elem === \"number\" ) {\n elem += \"\";\n }\n\n if ( !elem ) {\n continue;\n }\n\n // Convert html string into DOM nodes\n if ( typeof elem === \"string\" ) {\n if ( !rhtml.test( elem ) ) {\n elem = context.createTextNode( elem );\n } else {\n // Ensure a safe container in which to render the html\n safe = safe || createSafeFragment( context );\n div = context.createElement(\"div\");\n safe.appendChild( div );\n\n // Fix \"XHTML\"-style tags in all browsers\n elem = elem.replace(rxhtmlTag, \"<$1>\");\n\n // Go to html and back, then peel off extra wrappers\n tag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n wrap = wrapMap[ tag ] || wrapMap._default;\n depth = wrap[0];\n div.innerHTML = wrap[1] + elem + wrap[2];\n\n // Move to the right depth\n while ( depth-- ) {\n div = div.lastChild;\n }\n\n // Remove IE's autoinserted from table fragments\n if ( !jQuery.support.tbody ) {\n\n // String was a , *may* have spurious \n hasBody = rtbody.test(elem);\n tbody = tag === \"table\" && !hasBody ?\n div.firstChild && div.firstChild.childNodes :\n\n // String was a bare or \n wrap[1] === \"
    \" && !hasBody ?\n div.childNodes :\n [];\n\n for ( j = tbody.length - 1; j >= 0 ; --j ) {\n if ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n tbody[ j ].parentNode.removeChild( tbody[ j ] );\n }\n }\n }\n\n // IE completely kills leading whitespace when innerHTML is used\n if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n }\n\n elem = div.childNodes;\n\n // Take out of fragment container (we need a fresh div each time)\n div.parentNode.removeChild( div );\n }\n }\n\n if ( elem.nodeType ) {\n ret.push( elem );\n } else {\n jQuery.merge( ret, elem );\n }\n }\n\n // Fix #11356: Clear elements from safeFragment\n if ( div ) {\n elem = div = safe = null;\n }\n\n // Reset defaultChecked for any radios and checkboxes\n // about to be appended to the DOM in IE 6/7 (#8060)\n if ( !jQuery.support.appendChecked ) {\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n if ( jQuery.nodeName( elem, \"input\" ) ) {\n fixDefaultChecked( elem );\n } else if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n jQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n }\n }\n }\n\n // Append elements to a provided document fragment\n if ( fragment ) {\n // Special handling of each script element\n handleScript = function( elem ) {\n // Check if we consider it executable\n if ( !elem.type || rscriptType.test( elem.type ) ) {\n // Detach the script and store it in the scripts array (if provided) or the fragment\n // Return truthy to indicate that it has been handled\n return scripts ?\n scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\n fragment.appendChild( elem );\n }\n };\n\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n // Check if we're done after handling an executable script\n if ( !( jQuery.nodeName( elem, \"script\" ) && handleScript( elem ) ) ) {\n // Append to fragment and handle embedded scripts\n fragment.appendChild( elem );\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\n jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName(\"script\") ), handleScript );\n\n // Splice the scripts into ret after their former ancestor and advance our index beyond them\n ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n i += jsTags.length;\n }\n }\n }\n }\n\n return ret;\n },\n\n cleanData: function( elems, /* internal */ acceptData ) {\n var data, id, elem, type,\n i = 0,\n internalKey = jQuery.expando,\n cache = jQuery.cache,\n deleteExpando = jQuery.support.deleteExpando,\n special = jQuery.event.special;\n\n for ( ; (elem = elems[i]) != null; i++ ) {\n\n if ( acceptData || jQuery.acceptData( elem ) ) {\n\n id = elem[ internalKey ];\n data = id && cache[ id ];\n\n if ( data ) {\n if ( data.events ) {\n for ( type in data.events ) {\n if ( special[ type ] ) {\n jQuery.event.remove( elem, type );\n\n // This is a shortcut to avoid jQuery.event.remove's overhead\n } else {\n jQuery.removeEvent( elem, type, data.handle );\n }\n }\n }\n\n // Remove cache only if it was not already removed by jQuery.event.remove\n if ( cache[ id ] ) {\n\n delete cache[ id ];\n\n // IE does not allow us to delete expando properties from nodes,\n // nor does it have a removeAttribute function on Document nodes;\n // we must handle all of these cases\n if ( deleteExpando ) {\n delete elem[ internalKey ];\n\n } else if ( elem.removeAttribute ) {\n elem.removeAttribute( internalKey );\n\n } else {\n elem[ internalKey ] = null;\n }\n\n jQuery.deletedIds.push( id );\n }\n }\n }\n }\n }\n});\n// Limit scope pollution from any deprecated API\n(function() {\n\nvar matched, browser;\n\n// Use of jQuery.browser is frowned upon.\n// More details: http://api.jquery.com/jQuery.browser\n// jQuery.uaMatch maintained for back-compat\njQuery.uaMatch = function( ua ) {\n ua = ua.toLowerCase();\n\n var match = /(chrome)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(webkit)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(msie) ([\\w.]+)/.exec( ua ) ||\n ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec( ua ) ||\n [];\n\n return {\n browser: match[ 1 ] || \"\",\n version: match[ 2 ] || \"0\"\n };\n};\n\nmatched = jQuery.uaMatch( navigator.userAgent );\nbrowser = {};\n\nif ( matched.browser ) {\n browser[ matched.browser ] = true;\n browser.version = matched.version;\n}\n\n// Chrome is Webkit, but Webkit is also Safari.\nif ( browser.chrome ) {\n browser.webkit = true;\n} else if ( browser.webkit ) {\n browser.safari = true;\n}\n\njQuery.browser = browser;\n\njQuery.sub = function() {\n function jQuerySub( selector, context ) {\n return new jQuerySub.fn.init( selector, context );\n }\n jQuery.extend( true, jQuerySub, this );\n jQuerySub.superclass = this;\n jQuerySub.fn = jQuerySub.prototype = this();\n jQuerySub.fn.constructor = jQuerySub;\n jQuerySub.sub = this.sub;\n jQuerySub.fn.init = function init( selector, context ) {\n if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n context = jQuerySub( context );\n }\n\n return jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n };\n jQuerySub.fn.init.prototype = jQuerySub.fn;\n var rootjQuerySub = jQuerySub(document);\n return jQuerySub;\n};\n\n})();\nvar curCSS, iframe, iframeDoc,\n ralpha = /alpha\\([^)]*\\)/i,\n ropacity = /opacity=([^)]*)/,\n rposition = /^(top|right|bottom|left)$/,\n // swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n rmargin = /^margin/,\n rnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n rnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n rrelNum = new RegExp( \"^([-+])=(\" + core_pnum + \")\", \"i\" ),\n elemdisplay = { BODY: \"block\" },\n\n cssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n cssNormalTransform = {\n letterSpacing: 0,\n fontWeight: 400\n },\n\n cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n cssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\n eventsToggle = jQuery.fn.toggle;\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n // shortcut for names that are not vendor prefixed\n if ( name in style ) {\n return name;\n }\n\n // check for vendor prefixed names\n var capName = name.charAt(0).toUpperCase() + name.slice(1),\n origName = name,\n i = cssPrefixes.length;\n\n while ( i-- ) {\n name = cssPrefixes[ i ] + capName;\n if ( name in style ) {\n return name;\n }\n }\n\n return origName;\n}\n\nfunction isHidden( elem, el ) {\n elem = el || elem;\n return jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n var elem, display,\n values = [],\n index = 0,\n length = elements.length;\n\n for ( ; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n values[ index ] = jQuery._data( elem, \"olddisplay\" );\n if ( show ) {\n // Reset the inline display of this element to learn if it is\n // being hidden by cascaded rules or not\n if ( !values[ index ] && elem.style.display === \"none\" ) {\n elem.style.display = \"\";\n }\n\n // Set elements which have been overridden with display: none\n // in a stylesheet to whatever the default browser style is\n // for such an element\n if ( elem.style.display === \"\" && isHidden( elem ) ) {\n values[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n }\n } else {\n display = curCSS( elem, \"display\" );\n\n if ( !values[ index ] && display !== \"none\" ) {\n jQuery._data( elem, \"olddisplay\", display );\n }\n }\n }\n\n // Set the display of most of the elements in a second loop\n // to avoid the constant reflow\n for ( index = 0; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n if ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n elem.style.display = show ? values[ index ] || \"\" : \"none\";\n }\n }\n\n return elements;\n}\n\njQuery.fn.extend({\n css: function( name, value ) {\n return jQuery.access( this, function( elem, name, value ) {\n return value !== undefined ?\n jQuery.style( elem, name, value ) :\n jQuery.css( elem, name );\n }, name, value, arguments.length > 1 );\n },\n show: function() {\n return showHide( this, true );\n },\n hide: function() {\n return showHide( this );\n },\n toggle: function( state, fn2 ) {\n var bool = typeof state === \"boolean\";\n\n if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {\n return eventsToggle.apply( this, arguments );\n }\n\n return this.each(function() {\n if ( bool ? state : isHidden( this ) ) {\n jQuery( this ).show();\n } else {\n jQuery( this ).hide();\n }\n });\n }\n});\n\njQuery.extend({\n // Add in style property hooks for overriding the default\n // behavior of getting and setting a style property\n cssHooks: {\n opacity: {\n get: function( elem, computed ) {\n if ( computed ) {\n // We should always get a number back from opacity\n var ret = curCSS( elem, \"opacity\" );\n return ret === \"\" ? \"1\" : ret;\n\n }\n }\n }\n },\n\n // Exclude the following css properties to add px\n cssNumber: {\n \"fillOpacity\": true,\n \"fontWeight\": true,\n \"lineHeight\": true,\n \"opacity\": true,\n \"orphans\": true,\n \"widows\": true,\n \"zIndex\": true,\n \"zoom\": true\n },\n\n // Add in properties whose names you wish to fix before\n // setting or getting the value\n cssProps: {\n // normalize float css property\n \"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n },\n\n // Get and set the style property on a DOM Node\n style: function( elem, name, value, extra ) {\n // Don't set styles on text and comment nodes\n if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n return;\n }\n\n // Make sure that we're working with the right name\n var ret, type, hooks,\n origName = jQuery.camelCase( name ),\n style = elem.style;\n\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // Check if we're setting a value\n if ( value !== undefined ) {\n type = typeof value;\n\n // convert relative number strings (+= or -=) to relative numbers. #7345\n if ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n // Fixes bug #9237\n type = \"number\";\n }\n\n // Make sure that NaN and null values aren't set. See: #7116\n if ( value == null || type === \"number\" && isNaN( value ) ) {\n return;\n }\n\n // If a number was passed in, add 'px' to the (except for certain CSS properties)\n if ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n value += \"px\";\n }\n\n // If a hook was provided, use that value, otherwise just set the specified value\n if ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n // Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n // Fixes bug #5509\n try {\n style[ name ] = value;\n } catch(e) {}\n }\n\n } else {\n // If a hook was provided get the non-computed value from there\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n return ret;\n }\n\n // Otherwise just get the value from the style object\n return style[ name ];\n }\n },\n\n css: function( elem, name, numeric, extra ) {\n var val, num, hooks,\n origName = jQuery.camelCase( name );\n\n // Make sure that we're working with the right name\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // If a hook was provided get the computed value from there\n if ( hooks && \"get\" in hooks ) {\n val = hooks.get( elem, true, extra );\n }\n\n // Otherwise, if a way to get the computed value exists, use that\n if ( val === undefined ) {\n val = curCSS( elem, name );\n }\n\n //convert \"normal\" to computed value\n if ( val === \"normal\" && name in cssNormalTransform ) {\n val = cssNormalTransform[ name ];\n }\n\n // Return, converting to number if forced or a qualifier was provided and val looks numeric\n if ( numeric || extra !== undefined ) {\n num = parseFloat( val );\n return numeric || jQuery.isNumeric( num ) ? num || 0 : val;\n }\n return val;\n },\n\n // A method for quickly swapping in/out CSS properties to get correct calculations\n swap: function( elem, options, callback ) {\n var ret, name,\n old = {};\n\n // Remember the old values, and insert the new ones\n for ( name in options ) {\n old[ name ] = elem.style[ name ];\n elem.style[ name ] = options[ name ];\n }\n\n ret = callback.call( elem );\n\n // Revert the old values\n for ( name in options ) {\n elem.style[ name ] = old[ name ];\n }\n\n return ret;\n }\n});\n\n// NOTE: To any future maintainer, we've window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n curCSS = function( elem, name ) {\n var ret, width, minWidth, maxWidth,\n computed = window.getComputedStyle( elem, null ),\n style = elem.style;\n\n if ( computed ) {\n\n // getPropertyValue is only needed for .css('filter') in IE9, see #12537\n ret = computed.getPropertyValue( name ) || computed[ name ];\n\n if ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n ret = jQuery.style( elem, name );\n }\n\n // A tribute to the \"awesome hack by Dean Edwards\"\n // Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n width = style.width;\n minWidth = style.minWidth;\n maxWidth = style.maxWidth;\n\n style.minWidth = style.maxWidth = style.width = ret;\n ret = computed.width;\n\n style.width = width;\n style.minWidth = minWidth;\n style.maxWidth = maxWidth;\n }\n }\n\n return ret;\n };\n} else if ( document.documentElement.currentStyle ) {\n curCSS = function( elem, name ) {\n var left, rsLeft,\n ret = elem.currentStyle && elem.currentStyle[ name ],\n style = elem.style;\n\n // Avoid setting ret to empty string here\n // so we don't default to auto\n if ( ret == null && style && style[ name ] ) {\n ret = style[ name ];\n }\n\n // From the awesome hack by Dean Edwards\n // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n // If we're not dealing with a regular pixel number\n // but a number that has a weird ending, we need to convert it to pixels\n // but not position css attributes, as those are proportional to the parent element instead\n // and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n // Remember the original values\n left = style.left;\n rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;\n\n // Put in the new values to get a computed value out\n if ( rsLeft ) {\n elem.runtimeStyle.left = elem.currentStyle.left;\n }\n style.left = name === \"fontSize\" ? \"1em\" : ret;\n ret = style.pixelLeft + \"px\";\n\n // Revert the changed values\n style.left = left;\n if ( rsLeft ) {\n elem.runtimeStyle.left = rsLeft;\n }\n }\n\n return ret === \"\" ? \"auto\" : ret;\n };\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n var matches = rnumsplit.exec( value );\n return matches ?\n Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n value;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox ) {\n var i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n // If we already have the right measurement, avoid augmentation\n 4 :\n // Otherwise initialize for horizontal or vertical properties\n name === \"width\" ? 1 : 0,\n\n val = 0;\n\n for ( ; i < 4; i += 2 ) {\n // both box models exclude margin, so add it if we want it\n if ( extra === \"margin\" ) {\n // we use jQuery.css instead of curCSS here\n // because of the reliableMarginRight CSS hook!\n val += jQuery.css( elem, extra + cssExpand[ i ], true );\n }\n\n // From this point on we use curCSS for maximum performance (relevant in animations)\n if ( isBorderBox ) {\n // border-box includes padding, so remove it if we want content\n if ( extra === \"content\" ) {\n val -= parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n }\n\n // at this point, extra isn't border nor margin, so remove border\n if ( extra !== \"margin\" ) {\n val -= parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n } else {\n // at this point, extra isn't content, so add padding\n val += parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\n // at this point, extra isn't content nor padding, so add border\n if ( extra !== \"padding\" ) {\n val += parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n }\n }\n\n return val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n // Start with offset property, which is equivalent to the border-box value\n var val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n valueIsBorderBox = true,\n isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\";\n\n // some non-html elements return undefined for offsetWidth, so check for null/undefined\n // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n if ( val <= 0 || val == null ) {\n // Fall back to computed then uncomputed css if necessary\n val = curCSS( elem, name );\n if ( val < 0 || val == null ) {\n val = elem.style[ name ];\n }\n\n // Computed unit is not pixels. Stop here and return.\n if ( rnumnonpx.test(val) ) {\n return val;\n }\n\n // we need the check for style in case a browser which returns unreliable values\n // for getComputedStyle silently falls back to the reliable elem.style\n valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n // Normalize \"\", auto, and prepare for extra\n val = parseFloat( val ) || 0;\n }\n\n // use the active box-sizing model to add/subtract irrelevant styles\n return ( val +\n augmentWidthOrHeight(\n elem,\n name,\n extra || ( isBorderBox ? \"border\" : \"content\" ),\n valueIsBorderBox\n )\n ) + \"px\";\n}\n\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n if ( elemdisplay[ nodeName ] ) {\n return elemdisplay[ nodeName ];\n }\n\n var elem = jQuery( \"<\" + nodeName + \">\" ).appendTo( document.body ),\n display = elem.css(\"display\");\n elem.remove();\n\n // If the simple way fails,\n // get element's real default display by attaching it to a temp iframe\n if ( display === \"none\" || display === \"\" ) {\n // Use the already-created iframe if possible\n iframe = document.body.appendChild(\n iframe || jQuery.extend( document.createElement(\"iframe\"), {\n frameBorder: 0,\n width: 0,\n height: 0\n })\n );\n\n // Create a cacheable copy of the iframe document on first call.\n // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n // document to it; WebKit & Firefox won't allow reusing the iframe document.\n if ( !iframeDoc || !iframe.createElement ) {\n iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n iframeDoc.write(\"\");\n iframeDoc.close();\n }\n\n elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );\n\n display = curCSS( elem, \"display\" );\n document.body.removeChild( iframe );\n }\n\n // Store the correct default display\n elemdisplay[ nodeName ] = display;\n\n return display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n jQuery.cssHooks[ name ] = {\n get: function( elem, computed, extra ) {\n if ( computed ) {\n // certain elements can have dimension info if we invisibly show them\n // however, it must have a current display style that would benefit from this\n if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, \"display\" ) ) ) {\n return jQuery.swap( elem, cssShow, function() {\n return getWidthOrHeight( elem, name, extra );\n });\n } else {\n return getWidthOrHeight( elem, name, extra );\n }\n }\n },\n\n set: function( elem, value, extra ) {\n return setPositiveNumber( elem, value, extra ?\n augmentWidthOrHeight(\n elem,\n name,\n extra,\n jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\"\n ) : 0\n );\n }\n };\n});\n\nif ( !jQuery.support.opacity ) {\n jQuery.cssHooks.opacity = {\n get: function( elem, computed ) {\n // IE uses filters for opacity\n return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n ( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n computed ? \"1\" : \"\";\n },\n\n set: function( elem, value ) {\n var style = elem.style,\n currentStyle = elem.currentStyle,\n opacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n filter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n // IE has trouble with opacity if it does not have layout\n // Force it by setting the zoom level\n style.zoom = 1;\n\n // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n if ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n style.removeAttribute ) {\n\n // Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n // if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n // style.removeAttribute is IE Only, but so apparently is this code path...\n style.removeAttribute( \"filter\" );\n\n // if there there is no filter style applied in a css rule, we are done\n if ( currentStyle && !currentStyle.filter ) {\n return;\n }\n }\n\n // otherwise, set new filter values\n style.filter = ralpha.test( filter ) ?\n filter.replace( ralpha, opacity ) :\n filter + \" \" + opacity;\n }\n };\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n if ( !jQuery.support.reliableMarginRight ) {\n jQuery.cssHooks.marginRight = {\n get: function( elem, computed ) {\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n // Work around by temporarily setting element display to inline-block\n return jQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n if ( computed ) {\n return curCSS( elem, \"marginRight\" );\n }\n });\n }\n };\n }\n\n // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n // getComputedStyle returns percent when specified for top/left/bottom/right\n // rather than make the css module depend on the offset module, we just check for it here\n if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n jQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n jQuery.cssHooks[ prop ] = {\n get: function( elem, computed ) {\n if ( computed ) {\n var ret = curCSS( elem, prop );\n // if curCSS returns percentage, fallback to offset\n return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + \"px\" : ret;\n }\n }\n };\n });\n }\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.hidden = function( elem ) {\n return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, \"display\" )) === \"none\");\n };\n\n jQuery.expr.filters.visible = function( elem ) {\n return !jQuery.expr.filters.hidden( elem );\n };\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n margin: \"\",\n padding: \"\",\n border: \"Width\"\n}, function( prefix, suffix ) {\n jQuery.cssHooks[ prefix + suffix ] = {\n expand: function( value ) {\n var i,\n\n // assumes a single number if not a string\n parts = typeof value === \"string\" ? value.split(\" \") : [ value ],\n expanded = {};\n\n for ( i = 0; i < 4; i++ ) {\n expanded[ prefix + cssExpand[ i ] + suffix ] =\n parts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n }\n\n return expanded;\n }\n };\n\n if ( !rmargin.test( prefix ) ) {\n jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n }\n});\nvar r20 = /%20/g,\n rbracket = /\\[\\]$/,\n rCRLF = /\\r?\\n/g,\n rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n rselectTextarea = /^(?:select|textarea)/i;\n\njQuery.fn.extend({\n serialize: function() {\n return jQuery.param( this.serializeArray() );\n },\n serializeArray: function() {\n return this.map(function(){\n return this.elements ? jQuery.makeArray( this.elements ) : this;\n })\n .filter(function(){\n return this.name && !this.disabled &&\n ( this.checked || rselectTextarea.test( this.nodeName ) ||\n rinput.test( this.type ) );\n })\n .map(function( i, elem ){\n var val = jQuery( this ).val();\n\n return val == null ?\n null :\n jQuery.isArray( val ) ?\n jQuery.map( val, function( val, i ){\n return { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }) :\n { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }).get();\n }\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n var prefix,\n s = [],\n add = function( key, value ) {\n // If value is a function, invoke it and return its value\n value = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n s[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n };\n\n // Set traditional to true for jQuery <= 1.3.2 behavior.\n if ( traditional === undefined ) {\n traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n }\n\n // If an array was passed in, assume that it is an array of form elements.\n if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n // Serialize the form elements\n jQuery.each( a, function() {\n add( this.name, this.value );\n });\n\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for ( prefix in a ) {\n buildParams( prefix, a[ prefix ], traditional, add );\n }\n }\n\n // Return the resulting serialization\n return s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n var name;\n\n if ( jQuery.isArray( obj ) ) {\n // Serialize array item.\n jQuery.each( obj, function( i, v ) {\n if ( traditional || rbracket.test( prefix ) ) {\n // Treat each array item as a scalar.\n add( prefix, v );\n\n } else {\n // If array item is non-scalar (array or object), encode its\n // numeric index to resolve deserialization ambiguity issues.\n // Note that rack (as of 1.0.0) can't currently deserialize\n // nested arrays properly, and attempting to do so may cause\n // a server error. Possible fixes are to modify rack's\n // deserialization algorithm or to provide an option or flag\n // to force array serialization to be shallow.\n buildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n }\n });\n\n } else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n // Serialize object item.\n for ( name in obj ) {\n buildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n }\n\n } else {\n // Serialize scalar item.\n add( prefix, obj );\n }\n}\nvar\n // Document location\n ajaxLocParts,\n ajaxLocation,\n\n rhash = /#.*$/,\n rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n // #7653, #8125, #8152: local protocol detection\n rlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n rnoContent = /^(?:GET|HEAD)$/,\n rprotocol = /^\\/\\//,\n rquery = /\\?/,\n rscript = /)<[^<]*)*<\\/script>/gi,\n rts = /([?&])_=[^&]*/,\n rurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n // Keep a copy of the old load method\n _load = jQuery.fn.load,\n\n /* Prefilters\n * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n * 2) These are called:\n * - BEFORE asking for a transport\n * - AFTER param serialization (s.data is a string if s.processData is true)\n * 3) key is the dataType\n * 4) the catchall symbol \"*\" can be used\n * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n */\n prefilters = {},\n\n /* Transports bindings\n * 1) key is the dataType\n * 2) the catchall symbol \"*\" can be used\n * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n */\n transports = {},\n\n // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n allTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n ajaxLocation = location.href;\n} catch( e ) {\n // Use the href attribute of an A element\n // since IE will modify it given document.location\n ajaxLocation = document.createElement( \"a\" );\n ajaxLocation.href = \"\";\n ajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n // dataTypeExpression is optional and defaults to \"*\"\n return function( dataTypeExpression, func ) {\n\n if ( typeof dataTypeExpression !== \"string\" ) {\n func = dataTypeExpression;\n dataTypeExpression = \"*\";\n }\n\n var dataType, list, placeBefore,\n dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),\n i = 0,\n length = dataTypes.length;\n\n if ( jQuery.isFunction( func ) ) {\n // For each dataType in the dataTypeExpression\n for ( ; i < length; i++ ) {\n dataType = dataTypes[ i ];\n // We control if we're asked to add before\n // any existing element\n placeBefore = /^\\+/.test( dataType );\n if ( placeBefore ) {\n dataType = dataType.substr( 1 ) || \"*\";\n }\n list = structure[ dataType ] = structure[ dataType ] || [];\n // then we add to the structure accordingly\n list[ placeBefore ? \"unshift\" : \"push\" ]( func );\n }\n }\n };\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n dataType /* internal */, inspected /* internal */ ) {\n\n dataType = dataType || options.dataTypes[ 0 ];\n inspected = inspected || {};\n\n inspected[ dataType ] = true;\n\n var selection,\n list = structure[ dataType ],\n i = 0,\n length = list ? list.length : 0,\n executeOnly = ( structure === prefilters );\n\n for ( ; i < length && ( executeOnly || !selection ); i++ ) {\n selection = list[ i ]( options, originalOptions, jqXHR );\n // If we got redirected to another dataType\n // we try there if executing only and not done already\n if ( typeof selection === \"string\" ) {\n if ( !executeOnly || inspected[ selection ] ) {\n selection = undefined;\n } else {\n options.dataTypes.unshift( selection );\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, selection, inspected );\n }\n }\n }\n // If we're only executing or nothing was selected\n // we try the catchall dataType if not done already\n if ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, \"*\", inspected );\n }\n // unnecessary when only executing (prefilters)\n // but it'll be ignored by the caller in that case\n return selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n var key, deep,\n flatOptions = jQuery.ajaxSettings.flatOptions || {};\n for ( key in src ) {\n if ( src[ key ] !== undefined ) {\n ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n }\n }\n if ( deep ) {\n jQuery.extend( true, target, deep );\n }\n}\n\njQuery.fn.load = function( url, params, callback ) {\n if ( typeof url !== \"string\" && _load ) {\n return _load.apply( this, arguments );\n }\n\n // Don't do a request if no elements are being requested\n if ( !this.length ) {\n return this;\n }\n\n var selector, type, response,\n self = this,\n off = url.indexOf(\" \");\n\n if ( off >= 0 ) {\n selector = url.slice( off, url.length );\n url = url.slice( 0, off );\n }\n\n // If it's a function\n if ( jQuery.isFunction( params ) ) {\n\n // We assume that it's the callback\n callback = params;\n params = undefined;\n\n // Otherwise, build a param string\n } else if ( params && typeof params === \"object\" ) {\n type = \"POST\";\n }\n\n // Request the remote document\n jQuery.ajax({\n url: url,\n\n // if \"type\" variable is undefined, then \"GET\" method will be used\n type: type,\n dataType: \"html\",\n data: params,\n complete: function( jqXHR, status ) {\n if ( callback ) {\n self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n }\n }\n }).done(function( responseText ) {\n\n // Save response for use in complete callback\n response = arguments;\n\n // See if a selector was specified\n self.html( selector ?\n\n // Create a dummy div to hold the results\n jQuery(\"
    \")\n\n // inject the contents of the document in, removing the scripts\n // to avoid any 'Permission Denied' errors in IE\n .append( responseText.replace( rscript, \"\" ) )\n\n // Locate the specified elements\n .find( selector ) :\n\n // If not, just inject the full result\n responseText );\n\n });\n\n return this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n jQuery.fn[ o ] = function( f ){\n return this.on( o, f );\n };\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n jQuery[ method ] = function( url, data, callback, type ) {\n // shift arguments if data argument was omitted\n if ( jQuery.isFunction( data ) ) {\n type = type || callback;\n callback = data;\n data = undefined;\n }\n\n return jQuery.ajax({\n type: method,\n url: url,\n data: data,\n success: callback,\n dataType: type\n });\n };\n});\n\njQuery.extend({\n\n getScript: function( url, callback ) {\n return jQuery.get( url, undefined, callback, \"script\" );\n },\n\n getJSON: function( url, data, callback ) {\n return jQuery.get( url, data, callback, \"json\" );\n },\n\n // Creates a full fledged settings object into target\n // with both ajaxSettings and settings fields.\n // If target is omitted, writes into ajaxSettings.\n ajaxSetup: function( target, settings ) {\n if ( settings ) {\n // Building a settings object\n ajaxExtend( target, jQuery.ajaxSettings );\n } else {\n // Extending ajaxSettings\n settings = target;\n target = jQuery.ajaxSettings;\n }\n ajaxExtend( target, settings );\n return target;\n },\n\n ajaxSettings: {\n url: ajaxLocation,\n isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n global: true,\n type: \"GET\",\n contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n processData: true,\n async: true,\n /*\n timeout: 0,\n data: null,\n dataType: null,\n username: null,\n password: null,\n cache: null,\n throws: false,\n traditional: false,\n headers: {},\n */\n\n accepts: {\n xml: \"application/xml, text/xml\",\n html: \"text/html\",\n text: \"text/plain\",\n json: \"application/json, text/javascript\",\n \"*\": allTypes\n },\n\n contents: {\n xml: /xml/,\n html: /html/,\n json: /json/\n },\n\n responseFields: {\n xml: \"responseXML\",\n text: \"responseText\"\n },\n\n // List of data converters\n // 1) key format is \"source_type destination_type\" (a single space in-between)\n // 2) the catchall symbol \"*\" can be used for source_type\n converters: {\n\n // Convert anything to text\n \"* text\": window.String,\n\n // Text to html (true = no transformation)\n \"text html\": true,\n\n // Evaluate text as a json expression\n \"text json\": jQuery.parseJSON,\n\n // Parse text as xml\n \"text xml\": jQuery.parseXML\n },\n\n // For options that shouldn't be deep extended:\n // you can add your own custom options here if\n // and when you create one that shouldn't be\n // deep extended (see ajaxExtend)\n flatOptions: {\n context: true,\n url: true\n }\n },\n\n ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n ajaxTransport: addToPrefiltersOrTransports( transports ),\n\n // Main method\n ajax: function( url, options ) {\n\n // If url is an object, simulate pre-1.5 signature\n if ( typeof url === \"object\" ) {\n options = url;\n url = undefined;\n }\n\n // Force options to be an object\n options = options || {};\n\n var // ifModified key\n ifModifiedKey,\n // Response headers\n responseHeadersString,\n responseHeaders,\n // transport\n transport,\n // timeout handle\n timeoutTimer,\n // Cross-domain detection vars\n parts,\n // To know if global events are to be dispatched\n fireGlobals,\n // Loop variable\n i,\n // Create the final options object\n s = jQuery.ajaxSetup( {}, options ),\n // Callbacks context\n callbackContext = s.context || s,\n // Context for global events\n // It's the callbackContext if one was provided in the options\n // and if it's a DOM node or a jQuery collection\n globalEventContext = callbackContext !== s &&\n ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n jQuery( callbackContext ) : jQuery.event,\n // Deferreds\n deferred = jQuery.Deferred(),\n completeDeferred = jQuery.Callbacks( \"once memory\" ),\n // Status-dependent callbacks\n statusCode = s.statusCode || {},\n // Headers (they are sent all at once)\n requestHeaders = {},\n requestHeadersNames = {},\n // The jqXHR state\n state = 0,\n // Default abort message\n strAbort = \"canceled\",\n // Fake xhr\n jqXHR = {\n\n readyState: 0,\n\n // Caches the header\n setRequestHeader: function( name, value ) {\n if ( !state ) {\n var lname = name.toLowerCase();\n name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n requestHeaders[ name ] = value;\n }\n return this;\n },\n\n // Raw string\n getAllResponseHeaders: function() {\n return state === 2 ? responseHeadersString : null;\n },\n\n // Builds headers hashtable if needed\n getResponseHeader: function( key ) {\n var match;\n if ( state === 2 ) {\n if ( !responseHeaders ) {\n responseHeaders = {};\n while( ( match = rheaders.exec( responseHeadersString ) ) ) {\n responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n }\n }\n match = responseHeaders[ key.toLowerCase() ];\n }\n return match === undefined ? null : match;\n },\n\n // Overrides response content-type header\n overrideMimeType: function( type ) {\n if ( !state ) {\n s.mimeType = type;\n }\n return this;\n },\n\n // Cancel the request\n abort: function( statusText ) {\n statusText = statusText || strAbort;\n if ( transport ) {\n transport.abort( statusText );\n }\n done( 0, statusText );\n return this;\n }\n };\n\n // Callback for when everything is done\n // It is defined here because jslint complains if it is declared\n // at the end of the function (which would be more logical and readable)\n function done( status, nativeStatusText, responses, headers ) {\n var isSuccess, success, error, response, modified,\n statusText = nativeStatusText;\n\n // Called once\n if ( state === 2 ) {\n return;\n }\n\n // State is \"done\" now\n state = 2;\n\n // Clear timeout if it exists\n if ( timeoutTimer ) {\n clearTimeout( timeoutTimer );\n }\n\n // Dereference transport for early garbage collection\n // (no matter how long the jqXHR object will be used)\n transport = undefined;\n\n // Cache response headers\n responseHeadersString = headers || \"\";\n\n // Set readyState\n jqXHR.readyState = status > 0 ? 4 : 0;\n\n // Get response data\n if ( responses ) {\n response = ajaxHandleResponses( s, jqXHR, responses );\n }\n\n // If successful, handle type chaining\n if ( status >= 200 && status < 300 || status === 304 ) {\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n\n modified = jqXHR.getResponseHeader(\"Last-Modified\");\n if ( modified ) {\n jQuery.lastModified[ ifModifiedKey ] = modified;\n }\n modified = jqXHR.getResponseHeader(\"Etag\");\n if ( modified ) {\n jQuery.etag[ ifModifiedKey ] = modified;\n }\n }\n\n // If not modified\n if ( status === 304 ) {\n\n statusText = \"notmodified\";\n isSuccess = true;\n\n // If we have data\n } else {\n\n isSuccess = ajaxConvert( s, response );\n statusText = isSuccess.state;\n success = isSuccess.data;\n error = isSuccess.error;\n isSuccess = !error;\n }\n } else {\n // We extract error from statusText\n // then normalize statusText and status for non-aborts\n error = statusText;\n if ( !statusText || status ) {\n statusText = \"error\";\n if ( status < 0 ) {\n status = 0;\n }\n }\n }\n\n // Set data for the fake xhr object\n jqXHR.status = status;\n jqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n // Success/Error\n if ( isSuccess ) {\n deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n } else {\n deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n }\n\n // Status-dependent callbacks\n jqXHR.statusCode( statusCode );\n statusCode = undefined;\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n [ jqXHR, s, isSuccess ? success : error ] );\n }\n\n // Complete\n completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n // Handle the global AJAX counter\n if ( !( --jQuery.active ) ) {\n jQuery.event.trigger( \"ajaxStop\" );\n }\n }\n }\n\n // Attach deferreds\n deferred.promise( jqXHR );\n jqXHR.success = jqXHR.done;\n jqXHR.error = jqXHR.fail;\n jqXHR.complete = completeDeferred.add;\n\n // Status-dependent callbacks\n jqXHR.statusCode = function( map ) {\n if ( map ) {\n var tmp;\n if ( state < 2 ) {\n for ( tmp in map ) {\n statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n }\n } else {\n tmp = map[ jqXHR.status ];\n jqXHR.always( tmp );\n }\n }\n return this;\n };\n\n // Remove hash character (#7531: and string promotion)\n // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n // We also use the url parameter if available\n s.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n // Extract dataTypes list\n s.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( core_rspace );\n\n // A cross-domain request is in order when we have a protocol:host:port mismatch\n if ( s.crossDomain == null ) {\n parts = rurl.exec( s.url.toLowerCase() );\n s.crossDomain = !!( parts &&\n ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n ( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n );\n }\n\n // Convert data if not already a string\n if ( s.data && s.processData && typeof s.data !== \"string\" ) {\n s.data = jQuery.param( s.data, s.traditional );\n }\n\n // Apply prefilters\n inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n // If request was aborted inside a prefilter, stop there\n if ( state === 2 ) {\n return jqXHR;\n }\n\n // We can fire global events as of now if asked to\n fireGlobals = s.global;\n\n // Uppercase the type\n s.type = s.type.toUpperCase();\n\n // Determine if request has content\n s.hasContent = !rnoContent.test( s.type );\n\n // Watch for a new set of requests\n if ( fireGlobals && jQuery.active++ === 0 ) {\n jQuery.event.trigger( \"ajaxStart\" );\n }\n\n // More options handling for requests with no content\n if ( !s.hasContent ) {\n\n // If data is available, append data to url\n if ( s.data ) {\n s.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n // #9682: remove data so that it's not used in an eventual retry\n delete s.data;\n }\n\n // Get ifModifiedKey before adding the anti-cache parameter\n ifModifiedKey = s.url;\n\n // Add anti-cache in url if needed\n if ( s.cache === false ) {\n\n var ts = jQuery.now(),\n // try replacing _= if it is there\n ret = s.url.replace( rts, \"$1_=\" + ts );\n\n // if nothing was replaced, add timestamp to the end\n s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n }\n }\n\n // Set the correct header, if data is being sent\n if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n jqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n }\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n ifModifiedKey = ifModifiedKey || s.url;\n if ( jQuery.lastModified[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n }\n if ( jQuery.etag[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n }\n }\n\n // Set the Accepts header for the server, depending on the dataType\n jqXHR.setRequestHeader(\n \"Accept\",\n s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n s.accepts[ \"*\" ]\n );\n\n // Check for headers option\n for ( i in s.headers ) {\n jqXHR.setRequestHeader( i, s.headers[ i ] );\n }\n\n // Allow custom headers/mimetypes and early abort\n if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n // Abort if not done already and return\n return jqXHR.abort();\n\n }\n\n // aborting is no longer a cancellation\n strAbort = \"abort\";\n\n // Install callbacks on deferreds\n for ( i in { success: 1, error: 1, complete: 1 } ) {\n jqXHR[ i ]( s[ i ] );\n }\n\n // Get transport\n transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n // If no transport, we auto-abort\n if ( !transport ) {\n done( -1, \"No Transport\" );\n } else {\n jqXHR.readyState = 1;\n // Send global event\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n }\n // Timeout\n if ( s.async && s.timeout > 0 ) {\n timeoutTimer = setTimeout( function(){\n jqXHR.abort( \"timeout\" );\n }, s.timeout );\n }\n\n try {\n state = 1;\n transport.send( requestHeaders, done );\n } catch (e) {\n // Propagate exception as error if not done\n if ( state < 2 ) {\n done( -1, e );\n // Simply rethrow otherwise\n } else {\n throw e;\n }\n }\n }\n\n return jqXHR;\n },\n\n // Counter for holding the number of active queries\n active: 0,\n\n // Last-Modified header cache for next request\n lastModified: {},\n etag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n var ct, type, finalDataType, firstDataType,\n contents = s.contents,\n dataTypes = s.dataTypes,\n responseFields = s.responseFields;\n\n // Fill responseXXX fields\n for ( type in responseFields ) {\n if ( type in responses ) {\n jqXHR[ responseFields[type] ] = responses[ type ];\n }\n }\n\n // Remove auto dataType and get content-type in the process\n while( dataTypes[ 0 ] === \"*\" ) {\n dataTypes.shift();\n if ( ct === undefined ) {\n ct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n }\n }\n\n // Check if we're dealing with a known content-type\n if ( ct ) {\n for ( type in contents ) {\n if ( contents[ type ] && contents[ type ].test( ct ) ) {\n dataTypes.unshift( type );\n break;\n }\n }\n }\n\n // Check to see if we have a response for the expected dataType\n if ( dataTypes[ 0 ] in responses ) {\n finalDataType = dataTypes[ 0 ];\n } else {\n // Try convertible dataTypes\n for ( type in responses ) {\n if ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n finalDataType = type;\n break;\n }\n if ( !firstDataType ) {\n firstDataType = type;\n }\n }\n // Or just use first one\n finalDataType = finalDataType || firstDataType;\n }\n\n // If we found a dataType\n // We add the dataType to the list if needed\n // and return the corresponding response\n if ( finalDataType ) {\n if ( finalDataType !== dataTypes[ 0 ] ) {\n dataTypes.unshift( finalDataType );\n }\n return responses[ finalDataType ];\n }\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n var conv, conv2, current, tmp,\n // Work with a copy of dataTypes in case we need to modify it for conversion\n dataTypes = s.dataTypes.slice(),\n prev = dataTypes[ 0 ],\n converters = {},\n i = 0;\n\n // Apply the dataFilter if provided\n if ( s.dataFilter ) {\n response = s.dataFilter( response, s.dataType );\n }\n\n // Create converters map with lowercased keys\n if ( dataTypes[ 1 ] ) {\n for ( conv in s.converters ) {\n converters[ conv.toLowerCase() ] = s.converters[ conv ];\n }\n }\n\n // Convert to each sequential dataType, tolerating list modification\n for ( ; (current = dataTypes[++i]); ) {\n\n // There's only work to do if current dataType is non-auto\n if ( current !== \"*\" ) {\n\n // Convert response if prev dataType is non-auto and differs from current\n if ( prev !== \"*\" && prev !== current ) {\n\n // Seek a direct converter\n conv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n // If none found, seek a pair\n if ( !conv ) {\n for ( conv2 in converters ) {\n\n // If conv2 outputs current\n tmp = conv2.split(\" \");\n if ( tmp[ 1 ] === current ) {\n\n // If prev can be converted to accepted input\n conv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n converters[ \"* \" + tmp[ 0 ] ];\n if ( conv ) {\n // Condense equivalence converters\n if ( conv === true ) {\n conv = converters[ conv2 ];\n\n // Otherwise, insert the intermediate dataType\n } else if ( converters[ conv2 ] !== true ) {\n current = tmp[ 0 ];\n dataTypes.splice( i--, 0, current );\n }\n\n break;\n }\n }\n }\n }\n\n // Apply converter (if not an equivalence)\n if ( conv !== true ) {\n\n // Unless errors are allowed to bubble, catch and return them\n if ( conv && s[\"throws\"] ) {\n response = conv( response );\n } else {\n try {\n response = conv( response );\n } catch ( e ) {\n return { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n }\n }\n }\n }\n\n // Update prev for next iteration\n prev = current;\n }\n }\n\n return { state: \"success\", data: response };\n}\nvar oldCallbacks = [],\n rquestion = /\\?/,\n rjsonp = /(=)\\?(?=&|$)|\\?\\?/,\n nonce = jQuery.now();\n\n// Default jsonp settings\njQuery.ajaxSetup({\n jsonp: \"callback\",\n jsonpCallback: function() {\n var callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n this[ callback ] = true;\n return callback;\n }\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n var callbackName, overwritten, responseContainer,\n data = s.data,\n url = s.url,\n hasCallback = s.jsonp !== false,\n replaceInUrl = hasCallback && rjsonp.test( url ),\n replaceInData = hasCallback && !replaceInUrl && typeof data === \"string\" &&\n !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") &&\n rjsonp.test( data );\n\n // Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n if ( s.dataTypes[ 0 ] === \"jsonp\" || replaceInUrl || replaceInData ) {\n\n // Get callback name, remembering preexisting value associated with it\n callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n s.jsonpCallback() :\n s.jsonpCallback;\n overwritten = window[ callbackName ];\n\n // Insert callback into url or form data\n if ( replaceInUrl ) {\n s.url = url.replace( rjsonp, \"$1\" + callbackName );\n } else if ( replaceInData ) {\n s.data = data.replace( rjsonp, \"$1\" + callbackName );\n } else if ( hasCallback ) {\n s.url += ( rquestion.test( url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n }\n\n // Use data converter to retrieve json after script execution\n s.converters[\"script json\"] = function() {\n if ( !responseContainer ) {\n jQuery.error( callbackName + \" was not called\" );\n }\n return responseContainer[ 0 ];\n };\n\n // force json dataType\n s.dataTypes[ 0 ] = \"json\";\n\n // Install callback\n window[ callbackName ] = function() {\n responseContainer = arguments;\n };\n\n // Clean-up function (fires after converters)\n jqXHR.always(function() {\n // Restore preexisting value\n window[ callbackName ] = overwritten;\n\n // Save back as free\n if ( s[ callbackName ] ) {\n // make sure that re-using the options doesn't screw things around\n s.jsonpCallback = originalSettings.jsonpCallback;\n\n // save the callback name for future use\n oldCallbacks.push( callbackName );\n }\n\n // Call if it was a function and we have a response\n if ( responseContainer && jQuery.isFunction( overwritten ) ) {\n overwritten( responseContainer[ 0 ] );\n }\n\n responseContainer = overwritten = undefined;\n });\n\n // Delegate to script\n return \"script\";\n }\n});\n// Install script dataType\njQuery.ajaxSetup({\n accepts: {\n script: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n },\n contents: {\n script: /javascript|ecmascript/\n },\n converters: {\n \"text script\": function( text ) {\n jQuery.globalEval( text );\n return text;\n }\n }\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n if ( s.cache === undefined ) {\n s.cache = false;\n }\n if ( s.crossDomain ) {\n s.type = \"GET\";\n s.global = false;\n }\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n // This transport only deals with cross domain requests\n if ( s.crossDomain ) {\n\n var script,\n head = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n return {\n\n send: function( _, callback ) {\n\n script = document.createElement( \"script\" );\n\n script.async = \"async\";\n\n if ( s.scriptCharset ) {\n script.charset = s.scriptCharset;\n }\n\n script.src = s.url;\n\n // Attach handlers for all browsers\n script.onload = script.onreadystatechange = function( _, isAbort ) {\n\n if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n // Handle memory leak in IE\n script.onload = script.onreadystatechange = null;\n\n // Remove the script\n if ( head && script.parentNode ) {\n head.removeChild( script );\n }\n\n // Dereference the script\n script = undefined;\n\n // Callback if not abort\n if ( !isAbort ) {\n callback( 200, \"success\" );\n }\n }\n };\n // Use insertBefore instead of appendChild to circumvent an IE6 bug.\n // This arises when a base node is used (#2709 and #4378).\n head.insertBefore( script, head.firstChild );\n },\n\n abort: function() {\n if ( script ) {\n script.onload( 0, 1 );\n }\n }\n };\n }\n});\nvar xhrCallbacks,\n // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n xhrOnUnloadAbort = window.ActiveXObject ? function() {\n // Abort all pending requests\n for ( var key in xhrCallbacks ) {\n xhrCallbacks[ key ]( 0, 1 );\n }\n } : false,\n xhrId = 0;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n try {\n return new window.XMLHttpRequest();\n } catch( e ) {}\n}\n\nfunction createActiveXHR() {\n try {\n return new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n } catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n /* Microsoft failed to properly\n * implement the XMLHttpRequest in IE7 (can't request local files),\n * so we use the ActiveXObject when it is available\n * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n * we need a fallback.\n */\n function() {\n return !this.isLocal && createStandardXHR() || createActiveXHR();\n } :\n // For all other browsers, use the standard XMLHttpRequest object\n createStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n jQuery.extend( jQuery.support, {\n ajax: !!xhr,\n cors: !!xhr && ( \"withCredentials\" in xhr )\n });\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n jQuery.ajaxTransport(function( s ) {\n // Cross domain only allowed if supported through XMLHttpRequest\n if ( !s.crossDomain || jQuery.support.cors ) {\n\n var callback;\n\n return {\n send: function( headers, complete ) {\n\n // Get a new xhr\n var handle, i,\n xhr = s.xhr();\n\n // Open the socket\n // Passing null username, generates a login popup on Opera (#2865)\n if ( s.username ) {\n xhr.open( s.type, s.url, s.async, s.username, s.password );\n } else {\n xhr.open( s.type, s.url, s.async );\n }\n\n // Apply custom fields if provided\n if ( s.xhrFields ) {\n for ( i in s.xhrFields ) {\n xhr[ i ] = s.xhrFields[ i ];\n }\n }\n\n // Override mime type if needed\n if ( s.mimeType && xhr.overrideMimeType ) {\n xhr.overrideMimeType( s.mimeType );\n }\n\n // X-Requested-With header\n // For cross-domain requests, seeing as conditions for a preflight are\n // akin to a jigsaw puzzle, we simply never set it to be sure.\n // (it can always be set on a per-request basis or even using ajaxSetup)\n // For same-domain requests, won't change header if already provided.\n if ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n headers[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n }\n\n // Need an extra try/catch for cross domain requests in Firefox 3\n try {\n for ( i in headers ) {\n xhr.setRequestHeader( i, headers[ i ] );\n }\n } catch( _ ) {}\n\n // Do send the request\n // This may raise an exception which is actually\n // handled in jQuery.ajax (so no try/catch here)\n xhr.send( ( s.hasContent && s.data ) || null );\n\n // Listener\n callback = function( _, isAbort ) {\n\n var status,\n statusText,\n responseHeaders,\n responses,\n xml;\n\n // Firefox throws exceptions when accessing properties\n // of an xhr when a network error occurred\n // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n try {\n\n // Was never called and is aborted or complete\n if ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n // Only called once\n callback = undefined;\n\n // Do not keep as active anymore\n if ( handle ) {\n xhr.onreadystatechange = jQuery.noop;\n if ( xhrOnUnloadAbort ) {\n delete xhrCallbacks[ handle ];\n }\n }\n\n // If it's an abort\n if ( isAbort ) {\n // Abort it manually if needed\n if ( xhr.readyState !== 4 ) {\n xhr.abort();\n }\n } else {\n status = xhr.status;\n responseHeaders = xhr.getAllResponseHeaders();\n responses = {};\n xml = xhr.responseXML;\n\n // Construct response list\n if ( xml && xml.documentElement /* #4958 */ ) {\n responses.xml = xml;\n }\n\n // When requesting binary data, IE6-9 will throw an exception\n // on any attempt to access responseText (#11426)\n try {\n responses.text = xhr.responseText;\n } catch( e ) {\n }\n\n // Firefox throws an exception when accessing\n // statusText for faulty cross-domain requests\n try {\n statusText = xhr.statusText;\n } catch( e ) {\n // We normalize with Webkit giving an empty statusText\n statusText = \"\";\n }\n\n // Filter status for non standard behaviors\n\n // If the request is local and we have data: assume a success\n // (success with no data won't get notified, that's the best we\n // can do given current implementations)\n if ( !status && s.isLocal && !s.crossDomain ) {\n status = responses.text ? 200 : 404;\n // IE - #1450: sometimes returns 1223 when it should be 204\n } else if ( status === 1223 ) {\n status = 204;\n }\n }\n }\n } catch( firefoxAccessException ) {\n if ( !isAbort ) {\n complete( -1, firefoxAccessException );\n }\n }\n\n // Call complete if needed\n if ( responses ) {\n complete( status, statusText, responses, responseHeaders );\n }\n };\n\n if ( !s.async ) {\n // if we're in sync mode we fire the callback\n callback();\n } else if ( xhr.readyState === 4 ) {\n // (IE6 & IE7) if it's in cache and has been\n // retrieved directly we need to fire the callback\n setTimeout( callback, 0 );\n } else {\n handle = ++xhrId;\n if ( xhrOnUnloadAbort ) {\n // Create the active xhrs callbacks list if needed\n // and attach the unload handler\n if ( !xhrCallbacks ) {\n xhrCallbacks = {};\n jQuery( window ).unload( xhrOnUnloadAbort );\n }\n // Add to list of active xhrs callbacks\n xhrCallbacks[ handle ] = callback;\n }\n xhr.onreadystatechange = callback;\n }\n },\n\n abort: function() {\n if ( callback ) {\n callback(0,1);\n }\n }\n };\n }\n });\n}\nvar fxNow, timerId,\n rfxtypes = /^(?:toggle|show|hide)$/,\n rfxnum = new RegExp( \"^(?:([-+])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n rrun = /queueHooks$/,\n animationPrefilters = [ defaultPrefilter ],\n tweeners = {\n \"*\": [function( prop, value ) {\n var end, unit,\n tween = this.createTween( prop, value ),\n parts = rfxnum.exec( value ),\n target = tween.cur(),\n start = +target || 0,\n scale = 1,\n maxIterations = 20;\n\n if ( parts ) {\n end = +parts[2];\n unit = parts[3] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\n // We need to compute starting value\n if ( unit !== \"px\" && start ) {\n // Iteratively approximate from a nonzero starting point\n // Prefer the current property, because this process will be trivial if it uses the same units\n // Fallback to end or a simple constant\n start = jQuery.css( tween.elem, prop, true ) || end || 1;\n\n do {\n // If previous iteration zeroed out, double until we get *something*\n // Use a string for doubling factor so we don't accidentally see scale as unchanged below\n scale = scale || \".5\";\n\n // Adjust and apply\n start = start / scale;\n jQuery.style( tween.elem, prop, start + unit );\n\n // Update scale, tolerating zero or NaN from tween.cur()\n // And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n }\n\n tween.unit = unit;\n tween.start = start;\n // If a +=/-= token was provided, we're doing a relative animation\n tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;\n }\n return tween;\n }]\n };\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n setTimeout(function() {\n fxNow = undefined;\n }, 0 );\n return ( fxNow = jQuery.now() );\n}\n\nfunction createTweens( animation, props ) {\n jQuery.each( props, function( prop, value ) {\n var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n index = 0,\n length = collection.length;\n for ( ; index < length; index++ ) {\n if ( collection[ index ].call( animation, prop, value ) ) {\n\n // we're done with this property\n return;\n }\n }\n });\n}\n\nfunction Animation( elem, properties, options ) {\n var result,\n index = 0,\n tweenerIndex = 0,\n length = animationPrefilters.length,\n deferred = jQuery.Deferred().always( function() {\n // don't match elem in the :animated selector\n delete tick.elem;\n }),\n tick = function() {\n var currentTime = fxNow || createFxNow(),\n remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n temp = remaining / animation.duration || 0,\n percent = 1 - temp,\n index = 0,\n length = animation.tweens.length;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( percent );\n }\n\n deferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n if ( percent < 1 && length ) {\n return remaining;\n } else {\n deferred.resolveWith( elem, [ animation ] );\n return false;\n }\n },\n animation = deferred.promise({\n elem: elem,\n props: jQuery.extend( {}, properties ),\n opts: jQuery.extend( true, { specialEasing: {} }, options ),\n originalProperties: properties,\n originalOptions: options,\n startTime: fxNow || createFxNow(),\n duration: options.duration,\n tweens: [],\n createTween: function( prop, end, easing ) {\n var tween = jQuery.Tween( elem, animation.opts, prop, end,\n animation.opts.specialEasing[ prop ] || animation.opts.easing );\n animation.tweens.push( tween );\n return tween;\n },\n stop: function( gotoEnd ) {\n var index = 0,\n // if we are going to the end, we want to run all the tweens\n // otherwise we skip this part\n length = gotoEnd ? animation.tweens.length : 0;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( 1 );\n }\n\n // resolve when we played the last frame\n // otherwise, reject\n if ( gotoEnd ) {\n deferred.resolveWith( elem, [ animation, gotoEnd ] );\n } else {\n deferred.rejectWith( elem, [ animation, gotoEnd ] );\n }\n return this;\n }\n }),\n props = animation.props;\n\n propFilter( props, animation.opts.specialEasing );\n\n for ( ; index < length ; index++ ) {\n result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n if ( result ) {\n return result;\n }\n }\n\n createTweens( animation, props );\n\n if ( jQuery.isFunction( animation.opts.start ) ) {\n animation.opts.start.call( elem, animation );\n }\n\n jQuery.fx.timer(\n jQuery.extend( tick, {\n anim: animation,\n queue: animation.opts.queue,\n elem: elem\n })\n );\n\n // attach callbacks from options\n return animation.progress( animation.opts.progress )\n .done( animation.opts.done, animation.opts.complete )\n .fail( animation.opts.fail )\n .always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n var index, name, easing, value, hooks;\n\n // camelCase, specialEasing and expand cssHook pass\n for ( index in props ) {\n name = jQuery.camelCase( index );\n easing = specialEasing[ name ];\n value = props[ index ];\n if ( jQuery.isArray( value ) ) {\n easing = value[ 1 ];\n value = props[ index ] = value[ 0 ];\n }\n\n if ( index !== name ) {\n props[ name ] = value;\n delete props[ index ];\n }\n\n hooks = jQuery.cssHooks[ name ];\n if ( hooks && \"expand\" in hooks ) {\n value = hooks.expand( value );\n delete props[ name ];\n\n // not quite $.extend, this wont overwrite keys already present.\n // also - reusing 'index' from above because we have the correct \"name\"\n for ( index in value ) {\n if ( !( index in props ) ) {\n props[ index ] = value[ index ];\n specialEasing[ index ] = easing;\n }\n }\n } else {\n specialEasing[ name ] = easing;\n }\n }\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n tweener: function( props, callback ) {\n if ( jQuery.isFunction( props ) ) {\n callback = props;\n props = [ \"*\" ];\n } else {\n props = props.split(\" \");\n }\n\n var prop,\n index = 0,\n length = props.length;\n\n for ( ; index < length ; index++ ) {\n prop = props[ index ];\n tweeners[ prop ] = tweeners[ prop ] || [];\n tweeners[ prop ].unshift( callback );\n }\n },\n\n prefilter: function( callback, prepend ) {\n if ( prepend ) {\n animationPrefilters.unshift( callback );\n } else {\n animationPrefilters.push( callback );\n }\n }\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,\n anim = this,\n style = elem.style,\n orig = {},\n handled = [],\n hidden = elem.nodeType && isHidden( elem );\n\n // handle queue: false promises\n if ( !opts.queue ) {\n hooks = jQuery._queueHooks( elem, \"fx\" );\n if ( hooks.unqueued == null ) {\n hooks.unqueued = 0;\n oldfire = hooks.empty.fire;\n hooks.empty.fire = function() {\n if ( !hooks.unqueued ) {\n oldfire();\n }\n };\n }\n hooks.unqueued++;\n\n anim.always(function() {\n // doing this makes sure that the complete handler will be called\n // before this completes\n anim.always(function() {\n hooks.unqueued--;\n if ( !jQuery.queue( elem, \"fx\" ).length ) {\n hooks.empty.fire();\n }\n });\n });\n }\n\n // height/width overflow pass\n if ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n // Make sure that nothing sneaks out\n // Record all 3 overflow attributes because IE does not\n // change the overflow attribute when overflowX and\n // overflowY are set to the same value\n opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n // Set display property to inline-block for height/width\n // animations on inline elements that are having width/height animated\n if ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n // inline-level elements accept inline-block;\n // block-level elements need to be inline with layout\n if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n style.display = \"inline-block\";\n\n } else {\n style.zoom = 1;\n }\n }\n }\n\n if ( opts.overflow ) {\n style.overflow = \"hidden\";\n if ( !jQuery.support.shrinkWrapBlocks ) {\n anim.done(function() {\n style.overflow = opts.overflow[ 0 ];\n style.overflowX = opts.overflow[ 1 ];\n style.overflowY = opts.overflow[ 2 ];\n });\n }\n }\n\n\n // show/hide pass\n for ( index in props ) {\n value = props[ index ];\n if ( rfxtypes.exec( value ) ) {\n delete props[ index ];\n toggle = toggle || value === \"toggle\";\n if ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n continue;\n }\n handled.push( index );\n }\n }\n\n length = handled.length;\n if ( length ) {\n dataShow = jQuery._data( elem, \"fxshow\" ) || jQuery._data( elem, \"fxshow\", {} );\n if ( \"hidden\" in dataShow ) {\n hidden = dataShow.hidden;\n }\n\n // store state if its toggle - enables .stop().toggle() to \"reverse\"\n if ( toggle ) {\n dataShow.hidden = !hidden;\n }\n if ( hidden ) {\n jQuery( elem ).show();\n } else {\n anim.done(function() {\n jQuery( elem ).hide();\n });\n }\n anim.done(function() {\n var prop;\n jQuery.removeData( elem, \"fxshow\", true );\n for ( prop in orig ) {\n jQuery.style( elem, prop, orig[ prop ] );\n }\n });\n for ( index = 0 ; index < length ; index++ ) {\n prop = handled[ index ];\n tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );\n orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );\n\n if ( !( prop in dataShow ) ) {\n dataShow[ prop ] = tween.start;\n if ( hidden ) {\n tween.end = tween.start;\n tween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n }\n }\n }\n }\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n return new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n constructor: Tween,\n init: function( elem, options, prop, end, easing, unit ) {\n this.elem = elem;\n this.prop = prop;\n this.easing = easing || \"swing\";\n this.options = options;\n this.start = this.now = this.cur();\n this.end = end;\n this.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n },\n cur: function() {\n var hooks = Tween.propHooks[ this.prop ];\n\n return hooks && hooks.get ?\n hooks.get( this ) :\n Tween.propHooks._default.get( this );\n },\n run: function( percent ) {\n var eased,\n hooks = Tween.propHooks[ this.prop ];\n\n if ( this.options.duration ) {\n this.pos = eased = jQuery.easing[ this.easing ](\n percent, this.options.duration * percent, 0, 1, this.options.duration\n );\n } else {\n this.pos = eased = percent;\n }\n this.now = ( this.end - this.start ) * eased + this.start;\n\n if ( this.options.step ) {\n this.options.step.call( this.elem, this.now, this );\n }\n\n if ( hooks && hooks.set ) {\n hooks.set( this );\n } else {\n Tween.propHooks._default.set( this );\n }\n return this;\n }\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n _default: {\n get: function( tween ) {\n var result;\n\n if ( tween.elem[ tween.prop ] != null &&\n (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n return tween.elem[ tween.prop ];\n }\n\n // passing any value as a 4th parameter to .css will automatically\n // attempt a parseFloat and fallback to a string if the parse fails\n // so, simple values such as \"10px\" are parsed to Float.\n // complex values such as \"rotate(1rad)\" are returned as is.\n result = jQuery.css( tween.elem, tween.prop, false, \"\" );\n // Empty strings, null, undefined and \"auto\" are converted to 0.\n return !result || result === \"auto\" ? 0 : result;\n },\n set: function( tween ) {\n // use step hook for back compat - use cssHook if its there - use .style if its\n // available and use plain properties where available\n if ( jQuery.fx.step[ tween.prop ] ) {\n jQuery.fx.step[ tween.prop ]( tween );\n } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n } else {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n }\n};\n\n// Remove in 2.0 - this supports IE8's panic based approach\n// to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n set: function( tween ) {\n if ( tween.elem.nodeType && tween.elem.parentNode ) {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n var cssFn = jQuery.fn[ name ];\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return speed == null || typeof speed === \"boolean\" ||\n // special check for .toggle( handler, handler, ... )\n ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?\n cssFn.apply( this, arguments ) :\n this.animate( genFx( name, true ), speed, easing, callback );\n };\n});\n\njQuery.fn.extend({\n fadeTo: function( speed, to, easing, callback ) {\n\n // show any hidden elements after setting opacity to 0\n return this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n // animate to the value specified\n .end().animate({ opacity: to }, speed, easing, callback );\n },\n animate: function( prop, speed, easing, callback ) {\n var empty = jQuery.isEmptyObject( prop ),\n optall = jQuery.speed( speed, easing, callback ),\n doAnimation = function() {\n // Operate on a copy of prop so per-property easing won't be lost\n var anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n // Empty animations resolve immediately\n if ( empty ) {\n anim.stop( true );\n }\n };\n\n return empty || optall.queue === false ?\n this.each( doAnimation ) :\n this.queue( optall.queue, doAnimation );\n },\n stop: function( type, clearQueue, gotoEnd ) {\n var stopQueue = function( hooks ) {\n var stop = hooks.stop;\n delete hooks.stop;\n stop( gotoEnd );\n };\n\n if ( typeof type !== \"string\" ) {\n gotoEnd = clearQueue;\n clearQueue = type;\n type = undefined;\n }\n if ( clearQueue && type !== false ) {\n this.queue( type || \"fx\", [] );\n }\n\n return this.each(function() {\n var dequeue = true,\n index = type != null && type + \"queueHooks\",\n timers = jQuery.timers,\n data = jQuery._data( this );\n\n if ( index ) {\n if ( data[ index ] && data[ index ].stop ) {\n stopQueue( data[ index ] );\n }\n } else {\n for ( index in data ) {\n if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n stopQueue( data[ index ] );\n }\n }\n }\n\n for ( index = timers.length; index--; ) {\n if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n timers[ index ].anim.stop( gotoEnd );\n dequeue = false;\n timers.splice( index, 1 );\n }\n }\n\n // start the next in the queue if the last step wasn't forced\n // timers currently will call their complete callbacks, which will dequeue\n // but only if they were gotoEnd\n if ( dequeue || !gotoEnd ) {\n jQuery.dequeue( this, type );\n }\n });\n }\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n var which,\n attrs = { height: type },\n i = 0;\n\n // if we include width, step value is 1 to do all cssExpand values,\n // if we don't include width, step value is 2 to skip over Left and Right\n includeWidth = includeWidth? 1 : 0;\n for( ; i < 4 ; i += 2 - includeWidth ) {\n which = cssExpand[ i ];\n attrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n }\n\n if ( includeWidth ) {\n attrs.opacity = attrs.width = type;\n }\n\n return attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n slideDown: genFx(\"show\"),\n slideUp: genFx(\"hide\"),\n slideToggle: genFx(\"toggle\"),\n fadeIn: { opacity: \"show\" },\n fadeOut: { opacity: \"hide\" },\n fadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return this.animate( props, speed, easing, callback );\n };\n});\n\njQuery.speed = function( speed, easing, fn ) {\n var opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n complete: fn || !fn && easing ||\n jQuery.isFunction( speed ) && speed,\n duration: speed,\n easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n };\n\n opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n // normalize opt.queue - true/undefined/null -> \"fx\"\n if ( opt.queue == null || opt.queue === true ) {\n opt.queue = \"fx\";\n }\n\n // Queueing\n opt.old = opt.complete;\n\n opt.complete = function() {\n if ( jQuery.isFunction( opt.old ) ) {\n opt.old.call( this );\n }\n\n if ( opt.queue ) {\n jQuery.dequeue( this, opt.queue );\n }\n };\n\n return opt;\n};\n\njQuery.easing = {\n linear: function( p ) {\n return p;\n },\n swing: function( p ) {\n return 0.5 - Math.cos( p*Math.PI ) / 2;\n }\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n var timer,\n timers = jQuery.timers,\n i = 0;\n\n fxNow = jQuery.now();\n\n for ( ; i < timers.length; i++ ) {\n timer = timers[ i ];\n // Checks the timer has not already been removed\n if ( !timer() && timers[ i ] === timer ) {\n timers.splice( i--, 1 );\n }\n }\n\n if ( !timers.length ) {\n jQuery.fx.stop();\n }\n fxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n if ( timer() && jQuery.timers.push( timer ) && !timerId ) {\n timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n }\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.stop = function() {\n clearInterval( timerId );\n timerId = null;\n};\n\njQuery.fx.speeds = {\n slow: 600,\n fast: 200,\n // Default speed\n _default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.animated = function( elem ) {\n return jQuery.grep(jQuery.timers, function( fn ) {\n return elem === fn.elem;\n }).length;\n };\n}\nvar rroot = /^(?:body|html)$/i;\n\njQuery.fn.offset = function( options ) {\n if ( arguments.length ) {\n return options === undefined ?\n this :\n this.each(function( i ) {\n jQuery.offset.setOffset( this, options, i );\n });\n }\n\n var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,\n box = { top: 0, left: 0 },\n elem = this[ 0 ],\n doc = elem && elem.ownerDocument;\n\n if ( !doc ) {\n return;\n }\n\n if ( (body = doc.body) === elem ) {\n return jQuery.offset.bodyOffset( elem );\n }\n\n docElem = doc.documentElement;\n\n // Make sure it's not a disconnected DOM node\n if ( !jQuery.contains( docElem, elem ) ) {\n return box;\n }\n\n // If we don't have gBCR, just use 0,0 rather than error\n // BlackBerry 5, iOS 3 (original iPhone)\n if ( typeof elem.getBoundingClientRect !== \"undefined\" ) {\n box = elem.getBoundingClientRect();\n }\n win = getWindow( doc );\n clientTop = docElem.clientTop || body.clientTop || 0;\n clientLeft = docElem.clientLeft || body.clientLeft || 0;\n scrollTop = win.pageYOffset || docElem.scrollTop;\n scrollLeft = win.pageXOffset || docElem.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n};\n\njQuery.offset = {\n\n bodyOffset: function( body ) {\n var top = body.offsetTop,\n left = body.offsetLeft;\n\n if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {\n top += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n left += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n }\n\n return { top: top, left: left };\n },\n\n setOffset: function( elem, options, i ) {\n var position = jQuery.css( elem, \"position\" );\n\n // set position first, in-case top/left are set even on static elem\n if ( position === \"static\" ) {\n elem.style.position = \"relative\";\n }\n\n var curElem = jQuery( elem ),\n curOffset = curElem.offset(),\n curCSSTop = jQuery.css( elem, \"top\" ),\n curCSSLeft = jQuery.css( elem, \"left\" ),\n calculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n props = {}, curPosition = {}, curTop, curLeft;\n\n // need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n if ( calculatePosition ) {\n curPosition = curElem.position();\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat( curCSSTop ) || 0;\n curLeft = parseFloat( curCSSLeft ) || 0;\n }\n\n if ( jQuery.isFunction( options ) ) {\n options = options.call( elem, i, curOffset );\n }\n\n if ( options.top != null ) {\n props.top = ( options.top - curOffset.top ) + curTop;\n }\n if ( options.left != null ) {\n props.left = ( options.left - curOffset.left ) + curLeft;\n }\n\n if ( \"using\" in options ) {\n options.using.call( elem, props );\n } else {\n curElem.css( props );\n }\n }\n};\n\n\njQuery.fn.extend({\n\n position: function() {\n if ( !this[0] ) {\n return;\n }\n\n var elem = this[0],\n\n // Get *real* offsetParent\n offsetParent = this.offsetParent(),\n\n // Get correct offsets\n offset = this.offset(),\n parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n // Subtract element margins\n // note: when an element has margin: auto the offsetLeft and marginLeft\n // are the same in Safari causing offset.left to incorrectly be 0\n offset.top -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n offset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n // Add offsetParent borders\n parentOffset.top += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n parentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n // Subtract the two offsets\n return {\n top: offset.top - parentOffset.top,\n left: offset.left - parentOffset.left\n };\n },\n\n offsetParent: function() {\n return this.map(function() {\n var offsetParent = this.offsetParent || document.body;\n while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || document.body;\n });\n }\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n var top = /Y/.test( prop );\n\n jQuery.fn[ method ] = function( val ) {\n return jQuery.access( this, function( elem, method, val ) {\n var win = getWindow( elem );\n\n if ( val === undefined ) {\n return win ? (prop in win) ? win[ prop ] :\n win.document.documentElement[ method ] :\n elem[ method ];\n }\n\n if ( win ) {\n win.scrollTo(\n !top ? val : jQuery( win ).scrollLeft(),\n top ? val : jQuery( win ).scrollTop()\n );\n\n } else {\n elem[ method ] = val;\n }\n }, method, val, arguments.length, null );\n };\n});\n\nfunction getWindow( elem ) {\n return jQuery.isWindow( elem ) ?\n elem :\n elem.nodeType === 9 ?\n elem.defaultView || elem.parentWindow :\n false;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n jQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n // margin is only for outerHeight, outerWidth\n jQuery.fn[ funcName ] = function( margin, value ) {\n var chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n extra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n return jQuery.access( this, function( elem, type, value ) {\n var doc;\n\n if ( jQuery.isWindow( elem ) ) {\n // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n // isn't a whole lot we can do. See pull request at this URL for discussion:\n // https://github.com/jquery/jquery/pull/764\n return elem.document.documentElement[ \"client\" + name ];\n }\n\n // Get document width or height\n if ( elem.nodeType === 9 ) {\n doc = elem.documentElement;\n\n // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n return Math.max(\n elem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n elem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n doc[ \"client\" + name ]\n );\n }\n\n return value === undefined ?\n // Get width or height on the element, requesting but not forcing parseFloat\n jQuery.css( elem, type, value, extra ) :\n\n // Set width or height on the element\n jQuery.style( elem, type, value, extra );\n }, type, chainable ? margin : undefined, chainable, null );\n };\n });\n});\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n\n// Expose jQuery as an AMD module, but only for AMD loaders that\n// understand the issues with loading multiple versions of jQuery\n// in a page that all might call define(). The loader will indicate\n// they have special allowances for multiple jQuery versions by\n// specifying define.amd.jQuery = true. Register as a named module,\n// since jQuery can be concatenated with other files that may use define,\n// but not use a proper concatenation script that understands anonymous\n// AMD modules. A named AMD is safest and most robust way to register.\n// Lowercase jquery is used because AMD module names are derived from\n// file names, and jQuery is normally delivered in a lowercase file name.\n// Do this after creating the global so that if an AMD module wants to call\n// noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd && define.amd.jQuery ) {\n define( \"jquery\", [], function () { return jQuery; } );\n}\n\n})( window );", - "settings": - { - "buffer_size": 287804, - "line_ending": "Unix", - "name": "/*!" - } - }, - { - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "line_ending": "Unix" - } - }, - { - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "line_ending": "Unix" - } - }, - { - "contents": "var CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});", - "settings": - { - "buffer_size": 322, - "line_ending": "Unix" - } - }, - { - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "line_ending": "Unix" - } - } - ], - "build_system": "", - "command_palette": - { - "height": 87.0, - "selected_items": - [ - [ - "Package Control: in", - "Package Control: Install Package" - ], - [ - "Package Control: ins", - "Package Control: Install Package" - ], - [ - "ins", - "Package Control: Install Package" - ], - [ - "insta", - "Package Control: Install Package" - ] - ], - "width": 467.0 - }, - "console": - { - "height": 125.0 - }, - "distraction_free": - { - "menu_visible": true, - "show_minimap": false, - "show_open_files": false, - "show_tabs": false, - "side_bar_visible": false, - "status_bar_visible": false - }, - "file_history": - [ - "/Users/alexi/Dropbox/Projects/node-form-data/test/integration/test-http-respone.js", - "/Users/alexi/Dropbox/Projects/node-form-data/test/run.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config-alt.json", - "/Users/alexi/Desktop/test/file.txt", - "/Users/alexi/Desktop/stuff/kodak/web.js", - "/Users/alexi/Desktop/test/test1.js", - "/Users/alexi/Desktop/test/spdy.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/echo.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/test.html", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/passthrough_stream.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/tests/test-pipes.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/a/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/lib/flickr.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/lib/socket.io.js", - "/var/folders/xn/475pdrpd72n4s6gdh4y_c2dm0000gn/T/sublime-sftp-browse-1342313240/mapped/var/www/libereco.ia.gs/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config.json", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/public/index.html", - "/Users/alexi/Desktop/kodak/dns.js", - "/Users/alexi/Dropbox/Projects/500.ia.gs/htdocs/s/fonts.css", - "/Users/alexi/Dropbox/Projects/ia.gs/sftp-config.json", - "/Users/alexi/Downloads/fabric_plaid.png", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Global.sublime-settings", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/router.js", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/404.html", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/500.html", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/http/index.js", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/SFTP.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/Default (OSX).sublime-keymap", - "/Users/alexi/Sites/new/sftp-config.json", - "/Users/alexi/Sites/new/polarbear.css", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/User/Base File.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Base File.sublime-settings", - "/Users/alexi/Sites/new/include/Controllers/Home/HomepageController.php" - ], - "find": - { - "height": 35.0 - }, - "find_in_files": - { - "height": 0.0, - "where_history": - [ - "" - ] - }, - "find_state": - { - "case_sensitive": false, - "find_history": - [ - "readable", - "argument", - "mikeal", - "return;", - "throw arguments[1]", - "arguments[1]", - "throw arguments", - "throw arguments[1]", - "path", - "conso", - "isStreamLike", - "parseUrl", - "stream", - "node.js", - "stream", - "http://libereco.ia.gs/", - "flickr_message_nopro", - "auth:done", - "con", - "console", - "photos", - "isReadStream", - "Buffer", - "Bufer", - "multipart", - "sig", - "api", - "api_", - "api_sig", - "writeFile", - "googledoodle.png", - "attachment", - "_write", - "fs", - "mime", - "_putOrPost", - "_performSecureRequest", - "8034", - "try", - "paramsToQueryString", - "_executeOAuthAPIRequest", - "oauth_client", - "_createClient", - "authorization", - "body", - "_performSecureRequest", - "query", - "io.", - ".listen", - "io", - "config", - "set", - "console", - "'next'", - "console", - "_asyncEverySeries", - "runlist", - "function", - "async", - "local", - "Find schools", - "What's up" - ], - "highlight": true, - "in_selection": false, - "preserve_case": false, - "regex": false, - "replace_history": - [ - ], - "reverse": false, - "show_context": true, - "use_buffer2": true, - "whole_word": false, - "wrap": true - }, - "groups": - [ - { - "selected": 1, - "sheets": - [ - { - "buffer": 0, - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "regions": - { - }, - "selection": - [ - [ - 654, - 673 - ] - ], - "settings": - { - "function_name_status_row": 18, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 238.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 1, - "file": "package.json", - "settings": - { - "buffer_size": 673, - "regions": - { - }, - "selection": - [ - [ - 282, - 282 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JSON.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 2, - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "regions": - { - }, - "selection": - [ - [ - 1940, - 1940 - ] - ], - "settings": - { - "function_name_status_row": 65, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 658.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 3, - "settings": - { - "buffer_size": 287804, - "regions": - { - }, - "selection": - [ - [ - 8273, - 8279 - ] - ], - "settings": - { - "auto_name": "/*!", - "function_name_status_row": 290, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 5683.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 4, - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "regions": - { - }, - "selection": - [ - [ - 3556, - 3556 - ] - ], - "settings": - { - "function_name_status_row": 111, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1200.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 5, - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "regions": - { - }, - "selection": - [ - [ - 3449, - 3449 - ] - ], - "settings": - { - "function_name_status_row": 104, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1268.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 6, - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "regions": - { - }, - "selection": - [ - [ - 2156, - 2156 - ] - ], - "settings": - { - "function_name_status_row": 88, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 59.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 7, - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "regions": - { - }, - "selection": - [ - [ - 0, - 0 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/Markdown/Markdown.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 996.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 8, - "settings": - { - "buffer_size": 322, - "regions": - { - }, - "selection": - [ - [ - 0, - 322 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 9, - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "regions": - { - }, - "selection": - [ - [ - 76, - 76 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - } - ] - } - ], - "incremental_find": - { - "height": 0.0 - }, - "input": - { - "height": 31.0 - }, - "layout": - { - "cells": - [ - [ - 0, - 0, - 1, - 1 - ] - ], - "cols": - [ - 0.0, - 1.0 - ], - "rows": - [ - 0.0, - 1.0 - ] - }, - "menu_visible": true, - "output.sftp": - { - "height": 108.0 - }, - "replace": - { - "height": 0.0 - }, - "save_all_on_build": true, - "select_file": - { - "height": 0.0, - "selected_items": - [ - [ - "homepagecon", - "include/Controllers/Home/HomepageController.php" - ], - [ - "polar", - "polarbear.css" - ], - [ - "homepageco", - "include/Controllers/Home/HomepageController.php" - ], - [ - "homepage.js", - "include/js/application/homepage/homepage.js" - ] - ], - "width": 0.0 - }, - "select_project": - { - "height": 0.0, - "selected_items": - [ - ], - "width": 0.0 - }, - "show_minimap": true, - "show_open_files": true, - "show_tabs": true, - "side_bar_visible": true, - "side_bar_width": 250.0, - "status_bar_visible": true -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/LICENSE b/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/LICENSE deleted file mode 100644 index b7f9d5001c0..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2010 Caolan McMahon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/README.md b/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/README.md deleted file mode 100644 index 9ff1acfdf57..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/README.md +++ /dev/null @@ -1,1414 +0,0 @@ -# Async.js - -Async is a utility module which provides straight-forward, powerful functions -for working with asynchronous JavaScript. Although originally designed for -use with [node.js](http://nodejs.org), it can also be used directly in the -browser. Also supports [component](https://github.com/component/component). - -Async provides around 20 functions that include the usual 'functional' -suspects (map, reduce, filter, each…) as well as some common patterns -for asynchronous control flow (parallel, series, waterfall…). All these -functions assume you follow the node.js convention of providing a single -callback as the last argument of your async function. - - -## Quick Examples - -```javascript -async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file -}); - -async.filter(['file1','file2','file3'], fs.exists, function(results){ - // results now equals an array of the existing files -}); - -async.parallel([ - function(){ ... }, - function(){ ... } -], callback); - -async.series([ - function(){ ... }, - function(){ ... } -]); -``` - -There are many more functions available so take a look at the docs below for a -full list. This module aims to be comprehensive, so if you feel anything is -missing please create a GitHub issue for it. - -## Common Pitfalls - -### Binding a context to an iterator - -This section is really about bind, not about async. If you are wondering how to -make async execute your iterators in a given context, or are confused as to why -a method of another library isn't working as an iterator, study this example: - -```js -// Here is a simple object with an (unnecessarily roundabout) squaring method -var AsyncSquaringLibrary = { - squareExponent: 2, - square: function(number, callback){ - var result = Math.pow(number, this.squareExponent); - setTimeout(function(){ - callback(null, result); - }, 200); - } -}; - -async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ - // result is [NaN, NaN, NaN] - // This fails because the `this.squareExponent` expression in the square - // function is not evaluated in the context of AsyncSquaringLibrary, and is - // therefore undefined. -}); - -async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ - // result is [1, 4, 9] - // With the help of bind we can attach a context to the iterator before - // passing it to async. Now the square function will be executed in its - // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` - // will be as expected. -}); -``` - -## Download - -The source is available for download from -[GitHub](http://github.com/caolan/async). -Alternatively, you can install using Node Package Manager (npm): - - npm install async - -__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed - -## In the Browser - -So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage: - -```html - - -``` - -## Documentation - -### Collections - -* [each](#each) -* [map](#map) -* [filter](#filter) -* [reject](#reject) -* [reduce](#reduce) -* [detect](#detect) -* [sortBy](#sortBy) -* [some](#some) -* [every](#every) -* [concat](#concat) - -### Control Flow - -* [series](#series) -* [parallel](#parallel) -* [whilst](#whilst) -* [doWhilst](#doWhilst) -* [until](#until) -* [doUntil](#doUntil) -* [forever](#forever) -* [waterfall](#waterfall) -* [compose](#compose) -* [applyEach](#applyEach) -* [queue](#queue) -* [cargo](#cargo) -* [auto](#auto) -* [iterator](#iterator) -* [apply](#apply) -* [nextTick](#nextTick) -* [times](#times) -* [timesSeries](#timesSeries) - -### Utils - -* [memoize](#memoize) -* [unmemoize](#unmemoize) -* [log](#log) -* [dir](#dir) -* [noConflict](#noConflict) - - -## Collections - - - -### each(arr, iterator, callback) - -Applies an iterator function to each item in an array, in parallel. -The iterator is called with an item from the list and a callback for when it -has finished. If the iterator passes an error to this callback, the main -callback for the each function is immediately called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err) which must be called once it has - completed. If no error has occured, the callback should be run without - arguments or with an explicit null argument. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - -```js -// assuming openFiles is an array of file names and saveFile is a function -// to save the modified contents of that file: - -async.each(openFiles, saveFile, function(err){ - // if any of the saves produced an error, err would equal that error -}); -``` - ---------------------------------------- - - - -### eachSeries(arr, iterator, callback) - -The same as each only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. This means the iterator functions will complete in order. - - ---------------------------------------- - - - -### eachLimit(arr, limit, iterator, callback) - -The same as each only no more than "limit" iterators will be simultaneously -running at any time. - -Note that the items are not processed in batches, so there is no guarantee that - the first "limit" iterator functions will complete before any others are -started. - -__Arguments__ - -* arr - An array to iterate over. -* limit - The maximum number of iterators to run at any time. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err) which must be called once it has - completed. If no error has occured, the callback should be run without - arguments or with an explicit null argument. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - -```js -// Assume documents is an array of JSON objects and requestApi is a -// function that interacts with a rate-limited REST api. - -async.eachLimit(documents, 20, requestApi, function(err){ - // if any of the saves produced an error, err would equal that error -}); -``` - ---------------------------------------- - - -### map(arr, iterator, callback) - -Produces a new array of values by mapping each value in the given array through -the iterator function. The iterator is called with an item from the array and a -callback for when it has finished processing. The callback takes 2 arguments, -an error and the transformed item from the array. If the iterator passes an -error to this callback, the main callback for the map function is immediately -called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order, however -the results array will be in the same order as the original array. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, transformed) which must be called once - it has completed with an error (which can be null) and a transformed item. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array of the - transformed items from the original array. - -__Example__ - -```js -async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file -}); -``` - ---------------------------------------- - - -### mapSeries(arr, iterator, callback) - -The same as map only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - - ---------------------------------------- - - -### mapLimit(arr, limit, iterator, callback) - -The same as map only no more than "limit" iterators will be simultaneously -running at any time. - -Note that the items are not processed in batches, so there is no guarantee that - the first "limit" iterator functions will complete before any others are -started. - -__Arguments__ - -* arr - An array to iterate over. -* limit - The maximum number of iterators to run at any time. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, transformed) which must be called once - it has completed with an error (which can be null) and a transformed item. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array of the - transformed items from the original array. - -__Example__ - -```js -async.map(['file1','file2','file3'], 1, fs.stat, function(err, results){ - // results is now an array of stats for each file -}); -``` - ---------------------------------------- - - -### filter(arr, iterator, callback) - -__Alias:__ select - -Returns a new array of all the values which pass an async truth test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. This operation is -performed in parallel, but the results array will be in the same order as the -original. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(results) - A callback which is called after all the iterator - functions have finished. - -__Example__ - -```js -async.filter(['file1','file2','file3'], fs.exists, function(results){ - // results now equals an array of the existing files -}); -``` - ---------------------------------------- - - -### filterSeries(arr, iterator, callback) - -__alias:__ selectSeries - -The same as filter only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - ---------------------------------------- - - -### reject(arr, iterator, callback) - -The opposite of filter. Removes values that pass an async truth test. - ---------------------------------------- - - -### rejectSeries(arr, iterator, callback) - -The same as reject, only the iterator is applied to each item in the array -in series. - - ---------------------------------------- - - -### reduce(arr, memo, iterator, callback) - -__aliases:__ inject, foldl - -Reduces a list of values into a single value using an async iterator to return -each successive step. Memo is the initial state of the reduction. This -function only operates in series. For performance reasons, it may make sense to -split a call to this function into a parallel map, then use the normal -Array.prototype.reduce on the results. This function is for situations where -each step in the reduction needs to be async, if you can get the data before -reducing it then it's probably a good idea to do so. - -__Arguments__ - -* arr - An array to iterate over. -* memo - The initial state of the reduction. -* iterator(memo, item, callback) - A function applied to each item in the - array to produce the next step in the reduction. The iterator is passed a - callback(err, reduction) which accepts an optional error as its first - argument, and the state of the reduction as the second. If an error is - passed to the callback, the reduction is stopped and the main callback is - immediately called with the error. -* callback(err, result) - A callback which is called after all the iterator - functions have finished. Result is the reduced value. - -__Example__ - -```js -async.reduce([1,2,3], 0, function(memo, item, callback){ - // pointless async: - process.nextTick(function(){ - callback(null, memo + item) - }); -}, function(err, result){ - // result is now equal to the last value of memo, which is 6 -}); -``` - ---------------------------------------- - - -### reduceRight(arr, memo, iterator, callback) - -__Alias:__ foldr - -Same as reduce, only operates on the items in the array in reverse order. - - ---------------------------------------- - - -### detect(arr, iterator, callback) - -Returns the first value in a list that passes an async truth test. The -iterator is applied in parallel, meaning the first iterator to return true will -fire the detect callback with that result. That means the result might not be -the first item in the original array (in terms of order) that passes the test. - -If order within the original array is important then look at detectSeries. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - the first item in the array that passes the truth test (iterator) or the - value undefined if none passed. - -__Example__ - -```js -async.detect(['file1','file2','file3'], fs.exists, function(result){ - // result now equals the first file in the list that exists -}); -``` - ---------------------------------------- - - -### detectSeries(arr, iterator, callback) - -The same as detect, only the iterator is applied to each item in the array -in series. This means the result is always the first in the original array (in -terms of array order) that passes the truth test. - - ---------------------------------------- - - -### sortBy(arr, iterator, callback) - -Sorts a list by the results of running each value through an async iterator. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, sortValue) which must be called once it - has completed with an error (which can be null) and a value to use as the sort - criteria. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is the items from - the original array sorted by the values returned by the iterator calls. - -__Example__ - -```js -async.sortBy(['file1','file2','file3'], function(file, callback){ - fs.stat(file, function(err, stats){ - callback(err, stats.mtime); - }); -}, function(err, results){ - // results is now the original array of files sorted by - // modified date -}); -``` - ---------------------------------------- - - -### some(arr, iterator, callback) - -__Alias:__ any - -Returns true if at least one element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. Once any iterator -call returns true, the main callback is immediately called. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - either true or false depending on the values of the async tests. - -__Example__ - -```js -async.some(['file1','file2','file3'], fs.exists, function(result){ - // if result is true then at least one of the files exists -}); -``` - ---------------------------------------- - - -### every(arr, iterator, callback) - -__Alias:__ all - -Returns true if every element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like fs.exists. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback(truthValue) which must be called with a - boolean argument once it has completed. -* callback(result) - A callback which is called after all the iterator - functions have finished. Result will be either true or false depending on - the values of the async tests. - -__Example__ - -```js -async.every(['file1','file2','file3'], fs.exists, function(result){ - // if result is true then every file exists -}); -``` - ---------------------------------------- - - -### concat(arr, iterator, callback) - -Applies an iterator to each item in a list, concatenating the results. Returns the -concatenated list. The iterators are called in parallel, and the results are -concatenated as they return. There is no guarantee that the results array will -be returned in the original order of the arguments passed to the iterator function. - -__Arguments__ - -* arr - An array to iterate over -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback(err, results) which must be called once it - has completed with an error (which can be null) and an array of results. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array containing - the concatenated results of the iterator function. - -__Example__ - -```js -async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ - // files is now a list of filenames that exist in the 3 directories -}); -``` - ---------------------------------------- - - -### concatSeries(arr, iterator, callback) - -Same as async.concat, but executes in series instead of parallel. - - -## Control Flow - - -### series(tasks, [callback]) - -Run an array of functions in series, each one running once the previous -function has completed. If any functions in the series pass an error to its -callback, no more functions are run and the callback for the series is -immediately called with the value of the error. Once the tasks have completed, -the results are passed to the final callback as an array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.series. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - -__Example__ - -```js -async.series([ - function(callback){ - // do some stuff ... - callback(null, 'one'); - }, - function(callback){ - // do some more stuff ... - callback(null, 'two'); - } -], -// optional callback -function(err, results){ - // results is now equal to ['one', 'two'] -}); - - -// an example using an object instead of an array -async.series({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equal to: {one: 1, two: 2} -}); -``` - ---------------------------------------- - - -### parallel(tasks, [callback]) - -Run an array of functions in parallel, without waiting until the previous -function has completed. If any of the functions pass an error to its -callback, the main callback is immediately called with the value of the error. -Once the tasks have completed, the results are passed to the final callback as an -array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.parallel. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - -__Example__ - -```js -async.parallel([ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - } -], -// optional callback -function(err, results){ - // the results array will equal ['one','two'] even though - // the second function had a shorter timeout. -}); - - -// an example using an object instead of an array -async.parallel({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equals to: {one: 1, two: 2} -}); -``` - ---------------------------------------- - - -### parallelLimit(tasks, limit, [callback]) - -The same as parallel only the tasks are executed in parallel with a maximum of "limit" -tasks executing at any time. - -Note that the tasks are not executed in batches, so there is no guarantee that -the first "limit" tasks will complete before any others are started. - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback(err, result) it must call on completion with an error (which can - be null) and an optional result value. -* limit - The maximum number of tasks to run at any time. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - ---------------------------------------- - - -### whilst(test, fn, callback) - -Repeatedly call fn, while test returns true. Calls the callback when stopped, -or an error occurs. - -__Arguments__ - -* test() - synchronous truth test to perform before each execution of fn. -* fn(callback) - A function to call each time the test passes. The function is - passed a callback(err) which must be called once it has completed with an - optional error argument. -* callback(err) - A callback which is called after the test fails and repeated - execution of fn has stopped. - -__Example__ - -```js -var count = 0; - -async.whilst( - function () { return count < 5; }, - function (callback) { - count++; - setTimeout(callback, 1000); - }, - function (err) { - // 5 seconds have passed - } -); -``` - ---------------------------------------- - - -### doWhilst(fn, test, callback) - -The post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. - ---------------------------------------- - - -### until(test, fn, callback) - -Repeatedly call fn, until test returns true. Calls the callback when stopped, -or an error occurs. - -The inverse of async.whilst. - ---------------------------------------- - - -### doUntil(fn, test, callback) - -Like doWhilst except the test is inverted. Note the argument ordering differs from `until`. - ---------------------------------------- - - -### forever(fn, callback) - -Calls the asynchronous function 'fn' repeatedly, in series, indefinitely. -If an error is passed to fn's callback then 'callback' is called with the -error, otherwise it will never be called. - ---------------------------------------- - - -### waterfall(tasks, [callback]) - -Runs an array of functions in series, each passing their results to the next in -the array. However, if any of the functions pass an error to the callback, the -next function is not executed and the main callback is immediately called with -the error. - -__Arguments__ - -* tasks - An array of functions to run, each function is passed a - callback(err, result1, result2, ...) it must call on completion. The first - argument is an error (which can be null) and any further arguments will be - passed as arguments in order to the next task. -* callback(err, [results]) - An optional callback to run once all the functions - have completed. This will be passed the results of the last task's callback. - - - -__Example__ - -```js -async.waterfall([ - function(callback){ - callback(null, 'one', 'two'); - }, - function(arg1, arg2, callback){ - callback(null, 'three'); - }, - function(arg1, callback){ - // arg1 now equals 'three' - callback(null, 'done'); - } -], function (err, result) { - // result now equals 'done' -}); -``` - ---------------------------------------- - -### compose(fn1, fn2...) - -Creates a function which is a composition of the passed asynchronous -functions. Each function consumes the return value of the function that -follows. Composing functions f(), g() and h() would produce the result of -f(g(h())), only this version uses callbacks to obtain the return values. - -Each function is executed with the `this` binding of the composed function. - -__Arguments__ - -* functions... - the asynchronous functions to compose - - -__Example__ - -```js -function add1(n, callback) { - setTimeout(function () { - callback(null, n + 1); - }, 10); -} - -function mul3(n, callback) { - setTimeout(function () { - callback(null, n * 3); - }, 10); -} - -var add1mul3 = async.compose(mul3, add1); - -add1mul3(4, function (err, result) { - // result now equals 15 -}); -``` - ---------------------------------------- - -### applyEach(fns, args..., callback) - -Applies the provided arguments to each function in the array, calling the -callback after all functions have completed. If you only provide the first -argument then it will return a function which lets you pass in the -arguments as if it were a single function call. - -__Arguments__ - -* fns - the asynchronous functions to all call with the same arguments -* args... - any number of separate arguments to pass to the function -* callback - the final argument should be the callback, called when all - functions have completed processing - - -__Example__ - -```js -async.applyEach([enableSearch, updateSchema], 'bucket', callback); - -// partial application example: -async.each( - buckets, - async.applyEach([enableSearch, updateSchema]), - callback -); -``` - ---------------------------------------- - - -### applyEachSeries(arr, iterator, callback) - -The same as applyEach only the functions are applied in series. - ---------------------------------------- - - -### queue(worker, concurrency) - -Creates a queue object with the specified concurrency. Tasks added to the -queue will be processed in parallel (up to the concurrency limit). If all -workers are in progress, the task is queued until one is available. Once -a worker has completed a task, the task's callback is called. - -__Arguments__ - -* worker(task, callback) - An asynchronous function for processing a queued - task, which must call its callback(err) argument when finished, with an - optional error as an argument. -* concurrency - An integer for determining how many worker functions should be - run in parallel. - -__Queue objects__ - -The queue object returned by this function has the following properties and -methods: - -* length() - a function returning the number of items waiting to be processed. -* concurrency - an integer for determining how many worker functions should be - run in parallel. This property can be changed after a queue is created to - alter the concurrency on-the-fly. -* push(task, [callback]) - add a new task to the queue, the callback is called - once the worker has finished processing the task. - instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. -* unshift(task, [callback]) - add a new task to the front of the queue. -* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued -* empty - a callback that is called when the last item from the queue is given to a worker -* drain - a callback that is called when the last item from the queue has returned from the worker - -__Example__ - -```js -// create a queue object with concurrency 2 - -var q = async.queue(function (task, callback) { - console.log('hello ' + task.name); - callback(); -}, 2); - - -// assign a callback -q.drain = function() { - console.log('all items have been processed'); -} - -// add some items to the queue - -q.push({name: 'foo'}, function (err) { - console.log('finished processing foo'); -}); -q.push({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); - -// add some items to the queue (batch-wise) - -q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { - console.log('finished processing bar'); -}); - -// add some items to the front of the queue - -q.unshift({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); -``` - ---------------------------------------- - - -### cargo(worker, [payload]) - -Creates a cargo object with the specified payload. Tasks added to the -cargo will be processed altogether (up to the payload limit). If the -worker is in progress, the task is queued until it is available. Once -the worker has completed some tasks, each callback of those tasks is called. - -__Arguments__ - -* worker(tasks, callback) - An asynchronous function for processing an array of - queued tasks, which must call its callback(err) argument when finished, with - an optional error as an argument. -* payload - An optional integer for determining how many tasks should be - processed per round; if omitted, the default is unlimited. - -__Cargo objects__ - -The cargo object returned by this function has the following properties and -methods: - -* length() - a function returning the number of items waiting to be processed. -* payload - an integer for determining how many tasks should be - process per round. This property can be changed after a cargo is created to - alter the payload on-the-fly. -* push(task, [callback]) - add a new task to the queue, the callback is called - once the worker has finished processing the task. - instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. -* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued -* empty - a callback that is called when the last item from the queue is given to a worker -* drain - a callback that is called when the last item from the queue has returned from the worker - -__Example__ - -```js -// create a cargo object with payload 2 - -var cargo = async.cargo(function (tasks, callback) { - for(var i=0; i -### auto(tasks, [callback]) - -Determines the best order for running functions based on their requirements. -Each function can optionally depend on other functions being completed first, -and each function is run as soon as its requirements are satisfied. If any of -the functions pass an error to their callback, that function will not complete -(so any other functions depending on it will not run) and the main callback -will be called immediately with the error. Functions also receive an object -containing the results of functions which have completed so far. - -Note, all functions are called with a results object as a second argument, -so it is unsafe to pass functions in the tasks object which cannot handle the -extra argument. For example, this snippet of code: - -```js -async.auto({ - readData: async.apply(fs.readFile, 'data.txt', 'utf-8'); -}, callback); -``` - -will have the effect of calling readFile with the results object as the last -argument, which will fail: - -```js -fs.readFile('data.txt', 'utf-8', cb, {}); -``` - -Instead, wrap the call to readFile in a function which does not forward the -results object: - -```js -async.auto({ - readData: function(cb, results){ - fs.readFile('data.txt', 'utf-8', cb); - } -}, callback); -``` - -__Arguments__ - -* tasks - An object literal containing named functions or an array of - requirements, with the function itself the last item in the array. The key - used for each function or array is used when specifying requirements. The - function receives two arguments: (1) a callback(err, result) which must be - called when finished, passing an error (which can be null) and the result of - the function's execution, and (2) a results object, containing the results of - the previously executed functions. -* callback(err, results) - An optional callback which is called when all the - tasks have been completed. The callback will receive an error as an argument - if any tasks pass an error to their callback. Results will always be passed - but if an error occurred, no other tasks will be performed, and the results - object will only contain partial results. - - -__Example__ - -```js -async.auto({ - get_data: function(callback){ - // async code to get some data - }, - make_folder: function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - }, - write_file: ['get_data', 'make_folder', function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - callback(null, filename); - }], - email_link: ['write_file', function(callback, results){ - // once the file is written let's email a link to it... - // results.write_file contains the filename returned by write_file. - }] -}); -``` - -This is a fairly trivial example, but to do this using the basic parallel and -series functions would look like this: - -```js -async.parallel([ - function(callback){ - // async code to get some data - }, - function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - } -], -function(err, results){ - async.series([ - function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - }, - function(callback){ - // once the file is written let's email a link to it... - } - ]); -}); -``` - -For a complicated series of async tasks using the auto function makes adding -new tasks much easier and makes the code more readable. - - ---------------------------------------- - - -### iterator(tasks) - -Creates an iterator function which calls the next function in the array, -returning a continuation to call the next one after that. It's also possible to -'peek' the next iterator by doing iterator.next(). - -This function is used internally by the async module but can be useful when -you want to manually control the flow of functions in series. - -__Arguments__ - -* tasks - An array of functions to run. - -__Example__ - -```js -var iterator = async.iterator([ - function(){ sys.p('one'); }, - function(){ sys.p('two'); }, - function(){ sys.p('three'); } -]); - -node> var iterator2 = iterator(); -'one' -node> var iterator3 = iterator2(); -'two' -node> iterator3(); -'three' -node> var nextfn = iterator2.next(); -node> nextfn(); -'three' -``` - ---------------------------------------- - - -### apply(function, arguments..) - -Creates a continuation function with some arguments already applied, a useful -shorthand when combined with other control flow functions. Any arguments -passed to the returned function are added to the arguments originally passed -to apply. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to automatically apply when the - continuation is called. - -__Example__ - -```js -// using apply - -async.parallel([ - async.apply(fs.writeFile, 'testfile1', 'test1'), - async.apply(fs.writeFile, 'testfile2', 'test2'), -]); - - -// the same process without using apply - -async.parallel([ - function(callback){ - fs.writeFile('testfile1', 'test1', callback); - }, - function(callback){ - fs.writeFile('testfile2', 'test2', callback); - } -]); -``` - -It's possible to pass any number of additional arguments when calling the -continuation: - -```js -node> var fn = async.apply(sys.puts, 'one'); -node> fn('two', 'three'); -one -two -three -``` - ---------------------------------------- - - -### nextTick(callback) - -Calls the callback on a later loop around the event loop. In node.js this just -calls process.nextTick, in the browser it falls back to setImmediate(callback) -if available, otherwise setTimeout(callback, 0), which means other higher priority -events may precede the execution of the callback. - -This is used internally for browser-compatibility purposes. - -__Arguments__ - -* callback - The function to call on a later loop around the event loop. - -__Example__ - -```js -var call_order = []; -async.nextTick(function(){ - call_order.push('two'); - // call_order now equals ['one','two'] -}); -call_order.push('one') -``` - - -### times(n, callback) - -Calls the callback n times and accumulates results in the same manner -you would use with async.map. - -__Arguments__ - -* n - The number of times to run the function. -* callback - The function to call n times. - -__Example__ - -```js -// Pretend this is some complicated async factory -var createUser = function(id, callback) { - callback(null, { - id: 'user' + id - }) -} -// generate 5 users -async.times(5, function(n, next){ - createUser(n, function(err, user) { - next(err, user) - }) -}, function(err, users) { - // we should now have 5 users -}); -``` - - -### timesSeries(n, callback) - -The same as times only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - - -## Utils - - -### memoize(fn, [hasher]) - -Caches the results of an async function. When creating a hash to store function -results against, the callback is omitted from the hash and an optional hash -function can be used. - -The cache of results is exposed as the `memo` property of the function returned -by `memoize`. - -__Arguments__ - -* fn - the function you to proxy and cache results from. -* hasher - an optional function for generating a custom hash for storing - results, it has all the arguments applied to it apart from the callback, and - must be synchronous. - -__Example__ - -```js -var slow_fn = function (name, callback) { - // do something - callback(null, result); -}; -var fn = async.memoize(slow_fn); - -// fn can now be used as if it were slow_fn -fn('some name', function () { - // callback -}); -``` - - -### unmemoize(fn) - -Undoes a memoized function, reverting it to the original, unmemoized -form. Comes handy in tests. - -__Arguments__ - -* fn - the memoized function - - -### log(function, arguments) - -Logs the result of an async function to the console. Only works in node.js or -in browsers that support console.log and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.log is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, 'hello ' + name); - }, 1000); -}; -``` -```js -node> async.log(hello, 'world'); -'hello world' -``` - ---------------------------------------- - - -### dir(function, arguments) - -Logs the result of an async function to the console using console.dir to -display the properties of the resulting object. Only works in node.js or -in browsers that support console.dir and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.dir is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, {hello: name}); - }, 1000); -}; -``` -```js -node> async.dir(hello, 'world'); -{hello: 'world'} -``` - ---------------------------------------- - - -### noConflict() - -Changes the value of async back to its original value, returning a reference to the -async object. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/component.json b/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/component.json deleted file mode 100644 index bbb011548c0..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/component.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "async", - "repo": "caolan/async", - "description": "Higher-order functions and common patterns for asynchronous code", - "version": "0.1.23", - "keywords": [], - "dependencies": {}, - "development": {}, - "main": "lib/async.js", - "scripts": [ "lib/async.js" ] -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js deleted file mode 100644 index cb6320d6ad7..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js +++ /dev/null @@ -1,955 +0,0 @@ -/*global setImmediate: false, setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root, previous_async; - - root = this; - if (root != null) { - previous_async = root.async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - function only_once(fn) { - var called = false; - return function() { - if (called) throw new Error("Callback was already called."); - called = true; - fn.apply(root, arguments); - } - } - - //// cross-browser compatiblity functions //// - - var _each = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _each(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _each(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - if (typeof setImmediate === 'function') { - async.nextTick = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); - }; - async.setImmediate = async.nextTick; - } - else { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - async.setImmediate = async.nextTick; - } - } - else { - async.nextTick = process.nextTick; - if (typeof setImmediate !== 'undefined') { - async.setImmediate = setImmediate; - } - else { - async.setImmediate = async.nextTick; - } - } - - async.each = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - _each(arr, function (x) { - iterator(x, only_once(function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(null); - } - } - })); - }); - }; - async.forEach = async.each; - - async.eachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(null); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - async.forEachSeries = async.eachSeries; - - async.eachLimit = function (arr, limit, iterator, callback) { - var fn = _eachLimit(limit); - fn.apply(null, [arr, iterator, callback]); - }; - async.forEachLimit = async.eachLimit; - - var _eachLimit = function (limit) { - - return function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); - } - var completed = 0; - var started = 0; - var running = 0; - - (function replenish () { - if (completed >= arr.length) { - return callback(); - } - - while (running < limit && started < arr.length) { - started += 1; - running += 1; - iterator(arr[started - 1], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - running -= 1; - if (completed >= arr.length) { - callback(); - } - else { - replenish(); - } - } - }); - } - })(); - }; - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.each].concat(args)); - }; - }; - var doParallelLimit = function(limit, fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [_eachLimit(limit)].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.eachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - async.mapLimit = function (arr, limit, iterator, callback) { - return _mapLimit(limit)(arr, iterator, callback); - }; - - var _mapLimit = function(limit) { - return doParallelLimit(limit, _asyncMap); - }; - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.eachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var results = {}; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _each(listeners.slice(0), function (fn) { - fn(); - }); - }; - - addListener(function () { - if (_keys(results).length === keys.length) { - callback(null, results); - callback = function () {}; - } - }); - - _each(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - if (err) { - var safeResults = {}; - _each(_keys(results), function(rkey) { - safeResults[rkey] = results[rkey]; - }); - safeResults[k] = args; - callback(err, safeResults); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - results[k] = args; - async.setImmediate(taskComplete); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); - }; - if (ready()) { - task[task.length - 1](taskCallback, results); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor !== Array) { - var err = new Error('First argument to waterfall must be an array of functions'); - return callback(err); - } - if (!tasks.length) { - return callback(); - } - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback.apply(null, arguments); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.setImmediate(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - var _parallel = function(eachfn, tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - eachfn.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - eachfn.each(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.parallel = function (tasks, callback) { - _parallel({ map: async.map, each: async.each }, tasks, callback); - }; - - async.parallelLimit = function(tasks, limit, callback) { - _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.eachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doWhilst = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - if (test()) { - async.doWhilst(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.doUntil = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - if (!test()) { - async.doUntil(iterator, test, callback); - } - else { - callback(); - } - }); - }; - - async.queue = function (worker, concurrency) { - if (concurrency === undefined) { - concurrency = 1; - } - function _insert(q, data, pos, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _each(data, function(task) { - var item = { - data: task, - callback: typeof callback === 'function' ? callback : null - }; - - if (pos) { - q.tasks.unshift(item); - } else { - q.tasks.push(item); - } - - if (q.saturated && q.tasks.length === concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); - } - - var workers = 0; - var q = { - tasks: [], - concurrency: concurrency, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - _insert(q, data, false, callback); - }, - unshift: function (data, callback) { - _insert(q, data, true, callback); - }, - process: function () { - if (workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if (q.empty && q.tasks.length === 0) { - q.empty(); - } - workers += 1; - var next = function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if (q.drain && q.tasks.length + workers === 0) { - q.drain(); - } - q.process(); - }; - var cb = only_once(next); - worker(task.data, cb); - } - }, - length: function () { - return q.tasks.length; - }, - running: function () { - return workers; - } - }; - return q; - }; - - async.cargo = function (worker, payload) { - var working = false, - tasks = []; - - var cargo = { - tasks: tasks, - payload: payload, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _each(data, function(task) { - tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - if (cargo.saturated && tasks.length === payload) { - cargo.saturated(); - } - }); - async.setImmediate(cargo.process); - }, - process: function process() { - if (working) return; - if (tasks.length === 0) { - if(cargo.drain) cargo.drain(); - return; - } - - var ts = typeof payload === 'number' - ? tasks.splice(0, payload) - : tasks.splice(0); - - var ds = _map(ts, function (task) { - return task.data; - }); - - if(cargo.empty) cargo.empty(); - working = true; - worker(ds, function () { - working = false; - - var args = arguments; - _each(ts, function (data) { - if (data.callback) { - data.callback.apply(null, args); - } - }); - - process(); - }); - }, - length: function () { - return tasks.length; - }, - running: function () { - return working; - } - }; - return cargo; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _each(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else if (key in queues) { - queues[key].push(callback); - } - else { - queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); - } - }])); - } - }; - memoized.memo = memo; - memoized.unmemoized = fn; - return memoized; - }; - - async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - }; - - async.times = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.map(counter, iterator, callback); - }; - - async.timesSeries = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.mapSeries(counter, iterator, callback); - }; - - async.compose = function (/* functions... */) { - var fns = Array.prototype.reverse.call(arguments); - return function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - async.reduce(fns, args, function (newargs, fn, cb) { - fn.apply(that, newargs.concat([function () { - var err = arguments[0]; - var nextargs = Array.prototype.slice.call(arguments, 1); - cb(err, nextargs); - }])) - }, - function (err, results) { - callback.apply(that, [err].concat(results)); - }); - }; - }; - - var _applyEach = function (eachfn, fns /*args...*/) { - var go = function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - return eachfn(fns, function (fn, cb) { - fn.apply(that, args.concat([cb])); - }, - callback); - }; - if (arguments.length > 2) { - var args = Array.prototype.slice.call(arguments, 2); - return go.apply(this, args); - } - else { - return go; - } - }; - async.applyEach = doParallel(_applyEach); - async.applyEachSeries = doSeries(_applyEach); - - async.forever = function (fn, callback) { - function next(err) { - if (err) { - if (callback) { - return callback(err); - } - throw err; - } - fn(next); - } - next(); - }; - - // AMD / RequireJS - if (typeof define !== 'undefined' && define.amd) { - define([], function () { - return async; - }); - } - // Node.js - else if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - // included directly via \n\n```\n\n## Documentation\n\n### Collections\n\n* [each](#each)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [doWhilst](#doWhilst)\n* [until](#until)\n* [doUntil](#doUntil)\n* [forever](#forever)\n* [waterfall](#waterfall)\n* [compose](#compose)\n* [applyEach](#applyEach)\n* [queue](#queue)\n* [cargo](#cargo)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n* [times](#times)\n* [timesSeries](#timesSeries)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n\n\n### each(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the each function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n\n\n### eachSeries(arr, iterator, callback)\n\nThe same as each only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n\n\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as each only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as map only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], 1, fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as reject, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then it's probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback(err, reduction) which accepts an optional error as its first \n argument, and the state of the reduction as the second. If an error is \n passed to the callback, the reduction is stopped and the main callback is \n immediately called with the error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n}, function(err, result){\n // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], fs.exists, function(result){\n // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, sortValue) which must be called once it\n has completed with an error (which can be null) and a value to use as the sort\n criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n}, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n});\n```\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, results) which must be called once it \n has completed with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n }\n],\n// optional callback\nfunction(err, results){\n // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n }\n],\n// optional callback\nfunction(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallelLimit(tasks, limit, [callback])\n\nThe same as parallel only the tasks are executed in parallel with a maximum of \"limit\" \ntasks executing at any time.\n\nNote that the tasks are not executed in batches, so there is no guarantee that \nthe first \"limit\" tasks will complete before any others are started.\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* limit - The maximum number of tasks to run at any time.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback(err) which must be called once it has completed with an \n optional error argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n);\n```\n\n---------------------------------------\n\n\n### doWhilst(fn, test, callback)\n\nThe post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n---------------------------------------\n\n\n### doUntil(fn, test, callback)\n\nLike doWhilst except the test is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n\n### forever(fn, callback)\n\nCalls the asynchronous function 'fn' repeatedly, in series, indefinitely.\nIf an error is passed to fn's callback then 'callback' is called with the\nerror, otherwise it will never be called.\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a \n callback(err, result1, result2, ...) it must call on completion. The first\n argument is an error (which can be null) and any further arguments will be \n passed as arguments in order to the next task.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n], function (err, result) {\n // result now equals 'done' \n});\n```\n\n---------------------------------------\n\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions f(), g() and h() would produce the result of\nf(g(h())), only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n setTimeout(function () {\n callback(null, n + 1);\n }, 10);\n}\n\nfunction mul3(n, callback) {\n setTimeout(function () {\n callback(null, n * 3);\n }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n // result now equals 15\n});\n```\n\n---------------------------------------\n\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling the\ncallback after all functions have completed. If you only provide the first\nargument then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* fns - the asynchronous functions to all call with the same arguments\n* args... - any number of separate arguments to pass to the function\n* callback - the final argument should be the callback, called when all\n functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n buckets,\n async.applyEach([enableSearch, updateSchema]),\n callback\n);\n```\n\n---------------------------------------\n\n\n### applyEachSeries(arr, iterator, callback)\n\nThe same as applyEach only the functions are applied in series.\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task, which must call its callback(err) argument when finished, with an \n optional error as an argument.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* unshift(task, [callback]) - add a new task to the front of the queue.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n```\n\n---------------------------------------\n\n\n### cargo(worker, [payload])\n\nCreates a cargo object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the payload limit). If the\nworker is in progress, the task is queued until it is available. Once\nthe worker has completed some tasks, each callback of those tasks is called.\n\n__Arguments__\n\n* worker(tasks, callback) - An asynchronous function for processing an array of\n queued tasks, which must call its callback(err) argument when finished, with \n an optional error as an argument.\n* payload - An optional integer for determining how many tasks should be\n processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe cargo object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* payload - an integer for determining how many tasks should be\n process per round. This property can be changed after a cargo is created to\n alter the payload on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n for(var i=0; i\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\nNote, all functions are called with a results object as a second argument, \nso it is unsafe to pass functions in the tasks object which cannot handle the\nextra argument. For example, this snippet of code:\n\n```js\nasync.auto({\n readData: async.apply(fs.readFile, 'data.txt', 'utf-8');\n}, callback);\n```\n\nwill have the effect of calling readFile with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to readFile in a function which does not forward the \nresults object:\n\n```js\nasync.auto({\n readData: function(cb, results){\n fs.readFile('data.txt', 'utf-8', cb);\n }\n}, callback);\n```\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The \n function receives two arguments: (1) a callback(err, result) which must be \n called when finished, passing an error (which can be null) and the result of \n the function's execution, and (2) a results object, containing the results of\n the previously executed functions.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. Results will always be passed\n\tbut if an error occurred, no other tasks will be performed, and the results\n\tobject will only contain partial results.\n \n\n__Example__\n\n```js\nasync.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n],\nfunction(err, results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n});\n```\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. It's also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setImmediate(callback)\nif available, otherwise setTimeout(callback, 0), which means other higher priority\nevents may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n\n### times(n, callback)\n\nCalls the callback n times and accumulates results in the same manner\nyou would use with async.map.\n\n__Arguments__\n\n* n - The number of times to run the function.\n* callback - The function to call n times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n callback(null, {\n id: 'user' + id\n })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n createUser(n, function(err, user) {\n next(err, user)\n })\n}, function(err, users) {\n // we should now have 5 users\n});\n```\n\n\n### timesSeries(n, callback)\n\nThe same as times only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n // callback\n});\n```\n\n\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", - "readmeFilename": "README.md", - "_id": "async@0.2.9", - "_from": "async@~0.2.7" -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore deleted file mode 100644 index aba34f0127c..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -*.un~ -/node_modules -/test/tmp diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/License b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/License deleted file mode 100644 index 4804b7ab411..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Debuggable Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md deleted file mode 100644 index 1a9999eb0e1..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/Readme.md +++ /dev/null @@ -1,132 +0,0 @@ -# combined-stream - -A stream that emits multiple other streams one after another. - -## Installation - -``` bash -npm install combined-stream -``` - -## Usage - -Here is a simple example that shows how you can use combined-stream to combine -two files into one: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create(); -combinedStream.append(fs.createReadStream('file1.txt')); -combinedStream.append(fs.createReadStream('file2.txt')); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -While the example above works great, it will pause all source streams until -they are needed. If you don't want that to happen, you can set `pauseStreams` -to `false`: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create({pauseStreams: false}); -combinedStream.append(fs.createReadStream('file1.txt')); -combinedStream.append(fs.createReadStream('file2.txt')); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -However, what if you don't have all the source streams yet, or you don't want -to allocate the resources (file descriptors, memory, etc.) for them right away? -Well, in that case you can simply provide a callback that supplies the stream -by calling a `next()` function: - -``` javascript -var CombinedStream = require('combined-stream'); -var fs = require('fs'); - -var combinedStream = CombinedStream.create(); -combinedStream.append(function(next) { - next(fs.createReadStream('file1.txt')); -}); -combinedStream.append(function(next) { - next(fs.createReadStream('file2.txt')); -}); - -combinedStream.pipe(fs.createWriteStream('combined.txt')); -``` - -## API - -### CombinedStream.create([options]) - -Returns a new combined stream object. Available options are: - -* `maxDataSize` -* `pauseStreams` - -The effect of those options is described below. - -### combinedStream.pauseStreams = true - -Whether to apply back pressure to the underlaying streams. If set to `false`, -the underlaying streams will never be paused. If set to `true`, the -underlaying streams will be paused right after being appended, as well as when -`delayedStream.pipe()` wants to throttle. - -### combinedStream.maxDataSize = 2 * 1024 * 1024 - -The maximum amount of bytes (or characters) to buffer for all source streams. -If this value is exceeded, `combinedStream` emits an `'error'` event. - -### combinedStream.dataSize = 0 - -The amount of bytes (or characters) currently buffered by `combinedStream`. - -### combinedStream.append(stream) - -Appends the given `stream` to the combinedStream object. If `pauseStreams` is -set to `true, this stream will also be paused right away. - -`streams` can also be a function that takes one parameter called `next`. `next` -is a function that must be invoked in order to provide the `next` stream, see -example above. - -Regardless of how the `stream` is appended, combined-stream always attaches an -`'error'` listener to it, so you don't have to do that manually. - -Special case: `stream` can also be a String or Buffer. - -### combinedStream.write(data) - -You should not call this, `combinedStream` takes care of piping the appended -streams into itself for you. - -### combinedStream.resume() - -Causes `combinedStream` to start drain the streams it manages. The function is -idempotent, and also emits a `'resume'` event each time which usually goes to -the stream that is currently being drained. - -### combinedStream.pause(); - -If `combinedStream.pauseStreams` is set to `false`, this does nothing. -Otherwise a `'pause'` event is emitted, this goes to the stream that is -currently being drained, so you can use it to apply back pressure. - -### combinedStream.end(); - -Sets `combinedStream.writable` to false, emits an `'end'` event, and removes -all streams from the queue. - -### combinedStream.destroy(); - -Same as `combinedStream.end()`, except it emits a `'close'` event instead of -`'end'`. - -## License - -combined-stream is licensed under the MIT license. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js deleted file mode 100644 index 32849fd109e..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js +++ /dev/null @@ -1,185 +0,0 @@ -var util = require('util'); -var Stream = require('stream').Stream; -var DelayedStream = require('delayed-stream'); - -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; - - this._released = false; - this._streams = []; - this._currentStream = null; -} -util.inherits(CombinedStream, Stream); - -CombinedStream.create = function(options) { - var combinedStream = new this(); - - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; - } - - return combinedStream; -}; - -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; - -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - stream.on('data', this._checkDataSize.bind(this)); - - stream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - } - - this._handleErrors(stream); - - if (this.pauseStreams) { - stream.pause(); - } - } - - this._streams.push(stream); - return this; -}; - -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); -}; - -CombinedStream.prototype._getNext = function() { - this._currentStream = null; - var stream = this._streams.shift(); - - - if (typeof stream == 'undefined') { - this.end(); - return; - } - - if (typeof stream !== 'function') { - this._pipeNext(stream); - return; - } - - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); - } - - this._pipeNext(stream); - }.bind(this)); -}; - -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; - - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)) - stream.pipe(this, {end: false}); - return; - } - - var value = stream; - this.write(value); - this._getNext(); -}; - -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; - -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; - -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; - } - - this.emit('pause'); -}; - -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); - } - - this.emit('resume'); -}; - -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; - -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; - -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; -}; - -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; - } - - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this._emitError(new Error(message)); -}; - -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; - - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } - - self.dataSize += stream.dataSize; - }); - - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } -}; - -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore deleted file mode 100644 index 2fedb26cce9..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.un~ -/node_modules/* diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License deleted file mode 100644 index 4804b7ab411..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Debuggable Limited - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md deleted file mode 100644 index 5cb5b35e5bb..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md +++ /dev/null @@ -1,154 +0,0 @@ -# delayed-stream - -Buffers events from a stream until you are ready to handle them. - -## Installation - -``` bash -npm install delayed-stream -``` - -## Usage - -The following example shows how to write a http echo server that delays its -response by 1000 ms. - -``` javascript -var DelayedStream = require('delayed-stream'); -var http = require('http'); - -http.createServer(function(req, res) { - var delayed = DelayedStream.create(req); - - setTimeout(function() { - res.writeHead(200); - delayed.pipe(res); - }, 1000); -}); -``` - -If you are not using `Stream#pipe`, you can also manually release the buffered -events by calling `delayedStream.resume()`: - -``` javascript -var delayed = DelayedStream.create(req); - -setTimeout(function() { - // Emit all buffered events and resume underlaying source - delayed.resume(); -}, 1000); -``` - -## Implementation - -In order to use this meta stream properly, here are a few things you should -know about the implementation. - -### Event Buffering / Proxying - -All events of the `source` stream are hijacked by overwriting the `source.emit` -method. Until node implements a catch-all event listener, this is the only way. - -However, delayed-stream still continues to emit all events it captures on the -`source`, regardless of whether you have released the delayed stream yet or -not. - -Upon creation, delayed-stream captures all `source` events and stores them in -an internal event buffer. Once `delayedStream.release()` is called, all -buffered events are emitted on the `delayedStream`, and the event buffer is -cleared. After that, delayed-stream merely acts as a proxy for the underlaying -source. - -### Error handling - -Error events on `source` are buffered / proxied just like any other events. -However, `delayedStream.create` attaches a no-op `'error'` listener to the -`source`. This way you only have to handle errors on the `delayedStream` -object, rather than in two places. - -### Buffer limits - -delayed-stream provides a `maxDataSize` property that can be used to limit -the amount of data being buffered. In order to protect you from bad `source` -streams that don't react to `source.pause()`, this feature is enabled by -default. - -## API - -### DelayedStream.create(source, [options]) - -Returns a new `delayedStream`. Available options are: - -* `pauseStream` -* `maxDataSize` - -The description for those properties can be found below. - -### delayedStream.source - -The `source` stream managed by this object. This is useful if you are -passing your `delayedStream` around, and you still want to access properties -on the `source` object. - -### delayedStream.pauseStream = true - -Whether to pause the underlaying `source` when calling -`DelayedStream.create()`. Modifying this property afterwards has no effect. - -### delayedStream.maxDataSize = 1024 * 1024 - -The amount of data to buffer before emitting an `error`. - -If the underlaying source is emitting `Buffer` objects, the `maxDataSize` -refers to bytes. - -If the underlaying source is emitting JavaScript strings, the size refers to -characters. - -If you know what you are doing, you can set this property to `Infinity` to -disable this feature. You can also modify this property during runtime. - -### delayedStream.maxDataSize = 1024 * 1024 - -The amount of data to buffer before emitting an `error`. - -If the underlaying source is emitting `Buffer` objects, the `maxDataSize` -refers to bytes. - -If the underlaying source is emitting JavaScript strings, the size refers to -characters. - -If you know what you are doing, you can set this property to `Infinity` to -disable this feature. - -### delayedStream.dataSize = 0 - -The amount of data buffered so far. - -### delayedStream.readable - -An ECMA5 getter that returns the value of `source.readable`. - -### delayedStream.resume() - -If the `delayedStream` has not been released so far, `delayedStream.release()` -is called. - -In either case, `source.resume()` is called. - -### delayedStream.pause() - -Calls `source.pause()`. - -### delayedStream.pipe(dest) - -Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. - -### delayedStream.release() - -Emits and clears all events that have been buffered up so far. This does not -resume the underlaying source, use `delayedStream.resume()` instead. - -## License - -delayed-stream is licensed under the MIT license. diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js deleted file mode 100644 index 7c10d482531..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js +++ /dev/null @@ -1,99 +0,0 @@ -var Stream = require('stream').Stream; -var util = require('util'); - -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; - - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); - -DelayedStream.create = function(source, options) { - var delayedStream = new this(); - - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } - - delayedStream.source = source; - - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; - - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } - - return delayedStream; -}; - -DelayedStream.prototype.__defineGetter__('readable', function() { - return this.source.readable; -}); - -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); - } - - this.source.resume(); -}; - -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; - -DelayedStream.prototype.release = function() { - this._released = true; - - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; - -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; - -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; - } - - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); - } - - this._bufferedEvents.push(args); -}; - -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; - } - - if (this.dataSize <= this.maxDataSize) { - return; - } - - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); -}; diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json deleted file mode 100644 index 38341b8a08f..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "delayed-stream", - "description": "Buffers events from a stream until you are ready to handle them.", - "version": "0.0.5", - "homepage": "https://github.com/felixge/node-delayed-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-delayed-stream.git" - }, - "main": "./lib/delayed_stream", - "engines": { - "node": ">=0.4.0" - }, - "dependencies": {}, - "devDependencies": { - "fake": "0.2.0", - "far": "0.0.1" - }, - "readme": "# delayed-stream\n\nBuffers events from a stream until you are ready to handle them.\n\n## Installation\n\n``` bash\nnpm install delayed-stream\n```\n\n## Usage\n\nThe following example shows how to write a http echo server that delays its\nresponse by 1000 ms.\n\n``` javascript\nvar DelayedStream = require('delayed-stream');\nvar http = require('http');\n\nhttp.createServer(function(req, res) {\n var delayed = DelayedStream.create(req);\n\n setTimeout(function() {\n res.writeHead(200);\n delayed.pipe(res);\n }, 1000);\n});\n```\n\nIf you are not using `Stream#pipe`, you can also manually release the buffered\nevents by calling `delayedStream.resume()`:\n\n``` javascript\nvar delayed = DelayedStream.create(req);\n\nsetTimeout(function() {\n // Emit all buffered events and resume underlaying source\n delayed.resume();\n}, 1000);\n```\n\n## Implementation\n\nIn order to use this meta stream properly, here are a few things you should\nknow about the implementation.\n\n### Event Buffering / Proxying\n\nAll events of the `source` stream are hijacked by overwriting the `source.emit`\nmethod. Until node implements a catch-all event listener, this is the only way.\n\nHowever, delayed-stream still continues to emit all events it captures on the\n`source`, regardless of whether you have released the delayed stream yet or\nnot.\n\nUpon creation, delayed-stream captures all `source` events and stores them in\nan internal event buffer. Once `delayedStream.release()` is called, all\nbuffered events are emitted on the `delayedStream`, and the event buffer is\ncleared. After that, delayed-stream merely acts as a proxy for the underlaying\nsource.\n\n### Error handling\n\nError events on `source` are buffered / proxied just like any other events.\nHowever, `delayedStream.create` attaches a no-op `'error'` listener to the\n`source`. This way you only have to handle errors on the `delayedStream`\nobject, rather than in two places.\n\n### Buffer limits\n\ndelayed-stream provides a `maxDataSize` property that can be used to limit\nthe amount of data being buffered. In order to protect you from bad `source`\nstreams that don't react to `source.pause()`, this feature is enabled by\ndefault.\n\n## API\n\n### DelayedStream.create(source, [options])\n\nReturns a new `delayedStream`. Available options are:\n\n* `pauseStream`\n* `maxDataSize`\n\nThe description for those properties can be found below.\n\n### delayedStream.source\n\nThe `source` stream managed by this object. This is useful if you are\npassing your `delayedStream` around, and you still want to access properties\non the `source` object.\n\n### delayedStream.pauseStream = true\n\nWhether to pause the underlaying `source` when calling\n`DelayedStream.create()`. Modifying this property afterwards has no effect.\n\n### delayedStream.maxDataSize = 1024 * 1024\n\nThe amount of data to buffer before emitting an `error`.\n\nIf the underlaying source is emitting `Buffer` objects, the `maxDataSize`\nrefers to bytes.\n\nIf the underlaying source is emitting JavaScript strings, the size refers to\ncharacters.\n\nIf you know what you are doing, you can set this property to `Infinity` to\ndisable this feature. You can also modify this property during runtime.\n\n### delayedStream.maxDataSize = 1024 * 1024\n\nThe amount of data to buffer before emitting an `error`.\n\nIf the underlaying source is emitting `Buffer` objects, the `maxDataSize`\nrefers to bytes.\n\nIf the underlaying source is emitting JavaScript strings, the size refers to\ncharacters.\n\nIf you know what you are doing, you can set this property to `Infinity` to\ndisable this feature.\n\n### delayedStream.dataSize = 0\n\nThe amount of data buffered so far.\n\n### delayedStream.readable\n\nAn ECMA5 getter that returns the value of `source.readable`.\n\n### delayedStream.resume()\n\nIf the `delayedStream` has not been released so far, `delayedStream.release()`\nis called.\n\nIn either case, `source.resume()` is called.\n\n### delayedStream.pause()\n\nCalls `source.pause()`.\n\n### delayedStream.pipe(dest)\n\nCalls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.\n\n### delayedStream.release()\n\nEmits and clears all events that have been buffered up so far. This does not\nresume the underlaying source, use `delayedStream.resume()` instead.\n\n## License\n\ndelayed-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-delayed-stream/issues" - }, - "_id": "delayed-stream@0.0.5", - "_from": "delayed-stream@0.0.5" -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js deleted file mode 100644 index 4d71b8a6471..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/common.js +++ /dev/null @@ -1,6 +0,0 @@ -var common = module.exports; - -common.DelayedStream = require('..'); -common.assert = require('assert'); -common.fake = require('fake'); -common.PORT = 49252; diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js deleted file mode 100644 index 9ecad5b8ad1..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-http-upload.js +++ /dev/null @@ -1,38 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var DelayedStream = common.DelayedStream; -var http = require('http'); - -var UPLOAD = new Buffer(10 * 1024 * 1024); - -var server = http.createServer(function(req, res) { - var delayed = DelayedStream.create(req, {maxDataSize: UPLOAD.length}); - - setTimeout(function() { - res.writeHead(200); - delayed.pipe(res); - }, 10); -}); -server.listen(common.PORT, function() { - var request = http.request({ - method: 'POST', - port: common.PORT, - }); - - request.write(UPLOAD); - request.end(); - - request.on('response', function(res) { - var received = 0; - res - .on('data', function(chunk) { - received += chunk.length; - }) - .on('end', function() { - assert.equal(received, UPLOAD.length); - server.close(); - }); - }); -}); - - diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js deleted file mode 100644 index 6f417f3e90f..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-auto-pause.js +++ /dev/null @@ -1,21 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testAutoPause() { - var source = new Stream(); - - fake.expect(source, 'pause', 1); - var delayedStream = DelayedStream.create(source); - fake.verify(); -})(); - -(function testDisableAutoPause() { - var source = new Stream(); - fake.expect(source, 'pause', 0); - - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - fake.verify(); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js deleted file mode 100644 index b50c39783a0..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream-pause.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testDelayEventsUntilResume() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - fake.expect(source, 'pause'); - delayedStream.pause(); - fake.verify(); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js deleted file mode 100644 index fc4047e08b2..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-delayed-stream.js +++ /dev/null @@ -1,48 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testDelayEventsUntilResume() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - // delayedStream must not emit until we resume - fake.expect(delayedStream, 'emit', 0); - - // but our original source must emit - var params = []; - source.on('foo', function(param) { - params.push(param); - }); - - source.emit('foo', 1); - source.emit('foo', 2); - - // Make sure delayedStream did not emit, and source did - assert.deepEqual(params, [1, 2]); - fake.verify(); - - // After resume, delayedStream must playback all events - fake - .stub(delayedStream, 'emit') - .times(Infinity) - .withArg(1, 'newListener'); - fake.expect(delayedStream, 'emit', ['foo', 1]); - fake.expect(delayedStream, 'emit', ['foo', 2]); - fake.expect(source, 'resume'); - - delayedStream.resume(); - fake.verify(); - - // Calling resume again will delegate to source - fake.expect(source, 'resume'); - delayedStream.resume(); - fake.verify(); - - // Emitting more events directly leads to them being emitted - fake.expect(delayedStream, 'emit', ['foo', 3]); - source.emit('foo', 3); - fake.verify(); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js deleted file mode 100644 index a9d35e72ca2..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-handle-source-errors.js +++ /dev/null @@ -1,15 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testHandleSourceErrors() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - // We deal with this by attaching a no-op listener to 'error' on the source - // when creating a new DelayedStream. This way error events on the source - // won't throw. - source.emit('error', new Error('something went wrong')); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js deleted file mode 100644 index 7638a2bf040..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-max-data-size.js +++ /dev/null @@ -1,18 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testMaxDataSize() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {maxDataSize: 1024, pauseStream: false}); - - source.emit('data', new Buffer(1024)); - - fake - .expect(delayedStream, 'emit') - .withArg(1, 'error'); - source.emit('data', new Buffer(1)); - fake.verify(); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js deleted file mode 100644 index 7d312ab1f88..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-pipe-resumes.js +++ /dev/null @@ -1,13 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testPipeReleases() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - fake.expect(delayedStream, 'resume'); - delayedStream.pipe(new Stream()); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js deleted file mode 100644 index d436163b7cd..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/integration/test-proxy-readable.js +++ /dev/null @@ -1,13 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var fake = common.fake.create(); -var DelayedStream = common.DelayedStream; -var Stream = require('stream').Stream; - -(function testProxyReadableProperty() { - var source = new Stream(); - var delayedStream = DelayedStream.create(source, {pauseStream: false}); - - source.readable = fake.value('source.readable'); - assert.strictEqual(delayedStream.readable, source.readable); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json deleted file mode 100644 index 0dd41416227..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "combined-stream", - "description": "A stream that emits multiple other streams one after another.", - "version": "0.0.4", - "homepage": "https://github.com/felixge/node-combined-stream", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-combined-stream.git" - }, - "main": "./lib/combined_stream", - "engines": { - "node": "*" - }, - "dependencies": { - "delayed-stream": "0.0.5" - }, - "devDependencies": { - "far": "0.0.1" - }, - "readme": "# combined-stream\n\nA stream that emits multiple other streams one after another.\n\n## Installation\n\n``` bash\nnpm install combined-stream\n```\n\n## Usage\n\nHere is a simple example that shows how you can use combined-stream to combine\ntwo files into one:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nWhile the example above works great, it will pause all source streams until\nthey are needed. If you don't want that to happen, you can set `pauseStreams`\nto `false`:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create({pauseStreams: false});\ncombinedStream.append(fs.createReadStream('file1.txt'));\ncombinedStream.append(fs.createReadStream('file2.txt'));\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\nHowever, what if you don't have all the source streams yet, or you don't want\nto allocate the resources (file descriptors, memory, etc.) for them right away?\nWell, in that case you can simply provide a callback that supplies the stream\nby calling a `next()` function:\n\n``` javascript\nvar CombinedStream = require('combined-stream');\nvar fs = require('fs');\n\nvar combinedStream = CombinedStream.create();\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file1.txt'));\n});\ncombinedStream.append(function(next) {\n next(fs.createReadStream('file2.txt'));\n});\n\ncombinedStream.pipe(fs.createWriteStream('combined.txt'));\n```\n\n## API\n\n### CombinedStream.create([options])\n\nReturns a new combined stream object. Available options are:\n\n* `maxDataSize`\n* `pauseStreams`\n\nThe effect of those options is described below.\n\n### combinedStream.pauseStreams = true\n\nWhether to apply back pressure to the underlaying streams. If set to `false`,\nthe underlaying streams will never be paused. If set to `true`, the\nunderlaying streams will be paused right after being appended, as well as when\n`delayedStream.pipe()` wants to throttle.\n\n### combinedStream.maxDataSize = 2 * 1024 * 1024\n\nThe maximum amount of bytes (or characters) to buffer for all source streams.\nIf this value is exceeded, `combinedStream` emits an `'error'` event.\n\n### combinedStream.dataSize = 0\n\nThe amount of bytes (or characters) currently buffered by `combinedStream`.\n\n### combinedStream.append(stream)\n\nAppends the given `stream` to the combinedStream object. If `pauseStreams` is\nset to `true, this stream will also be paused right away.\n\n`streams` can also be a function that takes one parameter called `next`. `next`\nis a function that must be invoked in order to provide the `next` stream, see\nexample above.\n\nRegardless of how the `stream` is appended, combined-stream always attaches an\n`'error'` listener to it, so you don't have to do that manually.\n\nSpecial case: `stream` can also be a String or Buffer.\n\n### combinedStream.write(data)\n\nYou should not call this, `combinedStream` takes care of piping the appended\nstreams into itself for you.\n\n### combinedStream.resume()\n\nCauses `combinedStream` to start drain the streams it manages. The function is\nidempotent, and also emits a `'resume'` event each time which usually goes to\nthe stream that is currently being drained.\n\n### combinedStream.pause();\n\nIf `combinedStream.pauseStreams` is set to `false`, this does nothing.\nOtherwise a `'pause'` event is emitted, this goes to the stream that is\ncurrently being drained, so you can use it to apply back pressure.\n\n### combinedStream.end();\n\nSets `combinedStream.writable` to false, emits an `'end'` event, and removes\nall streams from the queue.\n\n### combinedStream.destroy();\n\nSame as `combinedStream.end()`, except it emits a `'close'` event instead of\n`'end'`.\n\n## License\n\ncombined-stream is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-combined-stream/issues" - }, - "_id": "combined-stream@0.0.4", - "_from": "combined-stream@~0.0.4" -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js deleted file mode 100644 index 81543485e02..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/common.js +++ /dev/null @@ -1,23 +0,0 @@ -var common = module.exports; - -var path = require('path'); -var fs = require('fs'); -var root = path.join(__dirname, '..'); - -common.dir = { - fixture: root + '/test/fixture', - tmp: root + '/test/tmp', -}; - -// Create tmp directory if it does not exist -// Not using fs.exists so as to be node 0.6.x compatible -try { - fs.statSync(common.dir.tmp); -} -catch (e) { - // Dir does not exist - fs.mkdirSync(common.dir.tmp); -} - -common.CombinedStream = require(root); -common.assert = require('assert'); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt deleted file mode 100644 index 50e0218df4d..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file1.txt +++ /dev/null @@ -1,256 +0,0 @@ -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 -10101010101010101010101010101010101010101010101010101010101010101010101010101010 -01010101010101010101010101010101010101010101010101010101010101010101010101010101 diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt deleted file mode 100644 index da1d821fe80..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/fixture/file2.txt +++ /dev/null @@ -1,256 +0,0 @@ -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 -20202020202020202020202020202020202020202020202020202020202020202020202020202020 -02020202020202020202020202020202020202020202020202020202020202020202020202020202 diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js deleted file mode 100644 index 44ecabab69c..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-callback-streams.js +++ /dev/null @@ -1,27 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(function(next) { - next(fs.createReadStream(FILE1)); - }); - combinedStream.append(function(next) { - next(fs.createReadStream(FILE2)); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('end', function() { - var written = fs.readFileSync(tmpFile, 'utf8'); - assert.strictEqual(written, EXPECTED); - }); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js deleted file mode 100644 index e3fbd1842f8..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-data-size.js +++ /dev/null @@ -1,34 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; - -(function testDataSizeGetter() { - var combinedStream = CombinedStream.create(); - - assert.strictEqual(combinedStream.dataSize, 0); - - // Test one stream - combinedStream._streams.push({dataSize: 10}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 10); - - // Test two streams - combinedStream._streams.push({dataSize: 23}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); - - // Test currentStream - combinedStream._currentStream = {dataSize: 20}; - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 53); - - // Test currentStream without dataSize - combinedStream._currentStream = {}; - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); - - // Test stream function - combinedStream._streams.push(function() {}); - combinedStream._updateDataSize(); - assert.strictEqual(combinedStream.dataSize, 33); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js deleted file mode 100644 index c678575c07b..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams-and-buffers-and-strings.js +++ /dev/null @@ -1,38 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var BUFFER = new Buffer('Bacon is delicious'); -var FILE2 = common.dir.fixture + '/file2.txt'; -var STRING = 'The € kicks the $\'s ass!'; - -var EXPECTED = - fs.readFileSync(FILE1) - + BUFFER - + fs.readFileSync(FILE2) - + STRING; -var GOT; - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(BUFFER); - combinedStream.append(fs.createReadStream(FILE2)); - combinedStream.append(function(next) { - next(STRING); - }); - - var tmpFile = common.dir.tmp + '/combined-file1-buffer-file2-string.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('close', function() { - GOT = fs.readFileSync(tmpFile, 'utf8'); - }); -})(); - -process.on('exit', function() { - assert.strictEqual(GOT, EXPECTED); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js deleted file mode 100644 index 263cfdf7222..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-delayed-streams.js +++ /dev/null @@ -1,35 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); -var GOT; - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create(); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var stream1 = combinedStream._streams[0]; - var stream2 = combinedStream._streams[1]; - - stream1.on('end', function() { - assert.equal(stream2.dataSize, 0); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('close', function() { - GOT = fs.readFileSync(tmpFile, 'utf8'); - }); -})(); - -process.on('exit', function() { - console.error(GOT.length, EXPECTED.length); - assert.strictEqual(GOT, EXPECTED); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js deleted file mode 100644 index c3d288d013c..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-empty-string.js +++ /dev/null @@ -1,39 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var util = require('util'); -var Stream = require('stream').Stream; - -var s = CombinedStream.create(); - - -function StringStream(){ - this.writable=true; - this.str="" -} -util.inherits(StringStream,Stream); - -StringStream.prototype.write=function(chunk,encoding){ - this.str+=chunk.toString(); - this.emit('data',chunk); -} - -StringStream.prototype.end=function(chunk,encoding){ - this.emit('end'); -} - -StringStream.prototype.toString=function(){ - return this.str; -} - - -s.append("foo."); -s.append(""); -s.append("bar"); - -var ss = new StringStream(); - -s.pipe(ss); -s.resume(); - -assert.equal(ss.toString(),"foo.bar"); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js deleted file mode 100644 index aefa36e6b7a..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-is-stream-like.js +++ /dev/null @@ -1,17 +0,0 @@ -var fs = require('fs'); -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var FILE1 = common.dir.fixture + '/file1.txt'; -var fileStream = fs.createReadStream(FILE1); - -var foo = function(){}; - -(function testIsStreamLike() { - assert(! CombinedStream.isStreamLike(true)); - assert(! CombinedStream.isStreamLike("I am a string")); - assert(! CombinedStream.isStreamLike(7)); - assert(! CombinedStream.isStreamLike(foo)); - - assert(CombinedStream.isStreamLike(fileStream)); -})(); \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js deleted file mode 100644 index 25f47a47c3a..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-max-data-size.js +++ /dev/null @@ -1,24 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create({pauseStreams: false, maxDataSize: 20736}); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var gotErr = null; - combinedStream.on('error', function(err) { - gotErr = err; - }); - - process.on('exit', function() { - assert.ok(gotErr); - assert.ok(gotErr.message.match(/bytes/)); - }); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js deleted file mode 100644 index 30a3a6f84e5..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/integration/test-unpaused-streams.js +++ /dev/null @@ -1,30 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var CombinedStream = common.CombinedStream; -var fs = require('fs'); - -var FILE1 = common.dir.fixture + '/file1.txt'; -var FILE2 = common.dir.fixture + '/file2.txt'; -var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2); - -(function testDelayedStreams() { - var combinedStream = CombinedStream.create({pauseStreams: false}); - combinedStream.append(fs.createReadStream(FILE1)); - combinedStream.append(fs.createReadStream(FILE2)); - - var stream1 = combinedStream._streams[0]; - var stream2 = combinedStream._streams[1]; - - stream1.on('end', function() { - assert.ok(stream2.dataSize > 0); - }); - - var tmpFile = common.dir.tmp + '/combined.txt'; - var dest = fs.createWriteStream(tmpFile); - combinedStream.pipe(dest); - - dest.on('end', function() { - var written = fs.readFileSync(tmpFile, 'utf8'); - assert.strictEqual(written, EXPECTED); - }); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js b/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/node_modules/combined-stream/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/package.json b/frontend/express/node_modules/request/node_modules/form-data/package.json deleted file mode 100644 index 48236848166..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "author": { - "name": "Felix Geisendörfer", - "email": "felix@debuggable.com", - "url": "http://debuggable.com/" - }, - "name": "form-data", - "description": "A module to create readable `\"multipart/form-data\"` streams. Can be used to submit forms and file uploads to other web applications.", - "version": "0.0.8", - "repository": { - "type": "git", - "url": "git://github.com/felixge/node-form-data.git" - }, - "main": "./lib/form_data", - "scripts": { - "test": "node test/run.js" - }, - "engines": { - "node": ">= 0.6" - }, - "dependencies": { - "combined-stream": "~0.0.4", - "mime": "~1.2.2", - "async": "~0.2.7" - }, - "devDependencies": { - "fake": "~0.2.1", - "far": "~0.0.7", - "formidable": "~1.0.13", - "request": "~2.16.6" - }, - "readme": "# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data)\n\nA module to create readable `\"multipart/form-data\"` streams. Can be used to\nsubmit forms and file uploads to other web applications.\n\nThe API of this module is inspired by the\n[XMLHttpRequest-2 FormData Interface][xhr2-fd].\n\n[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface\n\n## Install\n\n```\nnpm install form-data\n```\n\n## Usage\n\nIn this example we are constructing a form with 3 fields that contain a string,\na buffer and a file stream.\n\n``` javascript\nvar FormData = require('form-data');\nvar fs = require('fs');\n\nvar form = new FormData();\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_file', fs.createReadStream('/foo/bar.jpg'));\n```\n\nAlso you can use http-response stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar http = require('http');\n\nvar form = new FormData();\n\nhttp.request('http://nodejs.org/images/logo.png', function(response) {\n form.append('my_field', 'my value');\n form.append('my_buffer', new Buffer(10));\n form.append('my_logo', response);\n});\n```\n\nOr @mikeal's request stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar request = require('request');\n\nvar form = new FormData();\n\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_logo', request('http://nodejs.org/images/logo.png'));\n```\n\nIn order to submit this form to a web application, you can use node's http\nclient interface:\n\n``` javascript\nvar http = require('http');\n\nvar request = http.request({\n method: 'post',\n host: 'example.org',\n path: '/upload',\n headers: form.getHeaders()\n});\n\nform.pipe(request);\n\nrequest.on('response', function(res) {\n console.log(res.statusCode);\n});\n```\n\nOr if you would prefer the `'Content-Length'` header to be set for you:\n\n``` javascript\nform.submit('example.org/upload', function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nTo use custom headers and pre-known length in parts:\n\n``` javascript\nvar CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});\n```\n\nForm-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide \"file\"-related information manually:\n\n``` javascript\nsomeModule.stream(function(err, stdout, stderr) {\n if (err) throw err;\n\n var form = new FormData();\n\n form.append('file', stdout, {\n filename: 'unicycle.jpg',\n contentType: 'image/jpg',\n knownLength: 19806\n });\n\n form.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n });\n});\n```\n\nFor edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/probably.php?extra=params',\n auth: 'username:password'\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\n## TODO\n\n- Add new streams (0.10) support and try really hard not to break it for 0.8.x.\n\n## License\n\nForm-Data is licensed under the MIT license.\n", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/felixge/node-form-data/issues" - }, - "_id": "form-data@0.0.8", - "_from": "form-data@0.0.8" -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/sftp-config.json b/frontend/express/node_modules/request/node_modules/form-data/sftp-config.json deleted file mode 100644 index ad9ed2623d5..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/sftp-config.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - // The tab key will cycle through the settings when first created - // Visit http://wbond.net/sublime_packages/sftp/settings for help - - // sftp, ftp or ftps - "type": "sftp", - - "save_before_upload": true, - "upload_on_save": true, - "sync_down_on_open": false, - "sync_skip_deletes": false, - "confirm_downloads": false, - "confirm_sync": true, - "confirm_overwrite_newer": false, - - "host": "amber.exposeapp.com", - "user": "alex", - //"password": "password", - //"port": "22", - - "remote_path": "/var/www/_playground/form-data/", - "ignore_regexes": [ - "node_modules", - "\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json", - "sftp-settings\\.json", "/venv/", "\\.svn", "\\.hg", "\\.git", - "\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini" - ], - //"file_permissions": "664", - //"dir_permissions": "775", - - //"extra_list_connections": 0, - - "connect_timeout": 30, - //"keepalive": 120, - //"ftp_passive_mode": true, - //"ssh_key_file": "~/.ssh/id_rsa", - //"sftp_flags": ["-F", "/path/to/ssh_config"], - - //"preserve_modification_times": false, - //"remote_time_offset_in_hours": 0, - //"remote_encoding": "utf-8", - //"remote_locale": "C", -} diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/common.js b/frontend/express/node_modules/request/node_modules/form-data/test/common.js deleted file mode 100644 index 8a26482e1ea..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/common.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = module.exports; -var path = require('path'); - -var rootDir = path.join(__dirname, '..'); -common.dir = { - lib: rootDir + '/lib', - fixture: rootDir + '/test/fixture', - tmp: rootDir + '/test/tmp', -}; - -common.assert = require('assert'); -common.fake = require('fake'); - -common.port = 8432; diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/fixture/bacon.txt b/frontend/express/node_modules/request/node_modules/form-data/test/fixture/bacon.txt deleted file mode 100644 index 9804bbdc63c..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/fixture/bacon.txt +++ /dev/null @@ -1 +0,0 @@ -Bacon is delicious. diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg b/frontend/express/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg deleted file mode 100644 index 7cea4dd71dc..00000000000 Binary files a/frontend/express/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg and /dev/null differ diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js deleted file mode 100644 index 05f3fc036ef..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js +++ /dev/null @@ -1,52 +0,0 @@ -/* -test custom filename and content-type: -re: https://github.com/felixge/node-form-data/issues/29 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var fs = require('fs'); - -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var options = { - filename: 'test.png', - contentType: 'image/gif' -}; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('file', function(name, file) { - assert.strictEqual(name, 'my_file'); - assert.strictEqual(file.name, options.filename); - assert.strictEqual(file.type, options.contentType); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - form.append('my_file', fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), options); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js deleted file mode 100644 index 1c9b6adad56..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* -test custom headers, added in pull request: -https://github.com/felixge/node-form-data/pull/17 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); - -var FormData = require(common.dir.lib + '/form_data'); - -var CRLF = '\r\n'; - -var testHeader = 'X-Test-Fake: 123'; - -var expectedLength; - - -var server = http.createServer(function(req, res) { - var data = ''; - req.setEncoding('utf8'); - - req.on('data', function(d) { - data += d; - }); - - req.on('end', function() { - assert.ok( data.indexOf( testHeader ) != -1 ); - - // content-length would be 1000+ w/actual buffer size, - // but smaller w/overridden size. - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); - assert.equal(req.headers['content-length'], expectedLength); - - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - var options = { - header: - CRLF + '--' + form.getBoundary() + CRLF + - testHeader + - CRLF + CRLF, - - // override content-length, - // much lower than actual buffer size (1000) - knownLength: 1 - }; - - var bufferData = []; - for (var z = 0; z < 1000; z++) { - bufferData.push(1); - } - var buffer = new Buffer(bufferData); - - form.append('my_buffer', buffer, options); - - // (available to req handler) - expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength; - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js deleted file mode 100644 index 44d3b4dc276..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js +++ /dev/null @@ -1,93 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var FormData = require(common.dir.lib + '/form_data'); -var fake = require('fake').create(); -var fs = require('fs'); - -(function testEmptyForm() { - var form = new FormData(); - var callback = fake.callback(arguments.callee.name + '-getLength'); - var calls = fake.expectAnytime(callback, [null, 0]).calls; - - form.getLength(callback); - - // Make sure our response is async - assert.strictEqual(calls.length, 0); -})(); - -(function testUtf8String() { - var FIELD = 'my_field'; - var VALUE = 'May the € be with you'; - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - Buffer.byteLength(VALUE) + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - -(function testBuffer() { - var FIELD = 'my_field'; - var VALUE = new Buffer(23); - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - VALUE.length + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - -(function testStringFileBufferFile() { - var fields = [ - { - name: 'my_field', - value: 'Test 123', - }, - { - name: 'my_image', - value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), - }, - { - name: 'my_buffer', - value: new Buffer('123'), - }, - { - name: 'my_txt', - value: fs.createReadStream(common.dir.fixture + '/bacon.txt'), - }, - ]; - - var form = new FormData(); - var expectedLength = 0; - - fields.forEach(function(field) { - form.append(field.name, field.value); - if (field.value.path) { - var stat = fs.statSync(field.value.path); - expectedLength += stat.size; - } else { - expectedLength += field.value.length; - } - }); - - expectedLength += form._overheadLength + form._lastBoundary().length; - - var callback = fake.callback(arguments.callee.name + '-getLength'); - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js deleted file mode 100644 index 6dc2fb2bdde..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js +++ /dev/null @@ -1,18 +0,0 @@ -var common = require('../common'); -var assert = common.assert; - -var FormData = require(common.dir.lib + '/form_data'); - -(function testOneBoundaryPerForm() { - var form = new FormData(); - var boundary = form.getBoundary(); - - assert.equal(boundary, form.getBoundary()); - assert.equal(boundary.length, 50); -})(); - -(function testUniqueBoundaryPerForm() { - var formA = new FormData(); - var formB = new FormData(); - assert.notEqual(formA.getBoundary(), formB.getBoundary()); -})(); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-http-response.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-http-response.js deleted file mode 100644 index bebb26b35f4..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-http-response.js +++ /dev/null @@ -1,83 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var parseUrl = require('url').parse; -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -var FIELDS; -var server; - -var parsedUrl = parseUrl(remoteFile) - , options = { - method: 'get', - port: parsedUrl.port || 80, - path: parsedUrl.pathname, - host: parsedUrl.hostname - } - ; - -http.request(options, function(res) { - - FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: new Buffer([1, 2, 3])}, - {name: 'remote_file', value: res } - ]; - - var form = new FormData(); - FIELDS.forEach(function(field) { - form.append(field.name, field.value); - }); - - server.listen(common.port, function() { - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - - }); - -}).end(); - -server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - // http response doesn't have path property - assert.strictEqual(file.name, path.basename(field.value.path || remoteFile)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-pipe.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-pipe.js deleted file mode 100644 index a9264f92ebc..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-pipe.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - var form = new FormData(); - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - var request = http.request({ - method: 'post', - port: common.port, - path: '/upload', - headers: form.getHeaders() - }); - - form.pipe(request); - - request.on('response', function(res) { - server.close(); - }); -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js deleted file mode 100644 index f0d8f088cd6..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js +++ /dev/null @@ -1,77 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - // custom params object passed to submit - form.submit({ - port: common.port, - path: '/' - }, function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit.js b/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit.js deleted file mode 100644 index f90cc7f285b..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/integration/test-submit.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/frontend/express/node_modules/request/node_modules/form-data/test/run.js b/frontend/express/node_modules/request/node_modules/form-data/test/run.js deleted file mode 100644 index 0bb8e822414..00000000000 --- a/frontend/express/node_modules/request/node_modules/form-data/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/frontend/express/node_modules/request/node_modules/hawk/.npmignore b/frontend/express/node_modules/request/node_modules/hawk/.npmignore deleted file mode 100644 index 77ba16cb055..00000000000 --- a/frontend/express/node_modules/request/node_modules/hawk/.npmignore +++ /dev/null @@ -1,18 +0,0 @@ -.idea -*.iml -npm-debug.log -dump.rdb -node_modules -results.tap -results.xml -npm-shrinkwrap.json -config.json -.DS_Store -*/.DS_Store -*/*/.DS_Store -._* -*/._* -*/*/._* -coverage.* -lib-cov - diff --git a/frontend/express/node_modules/request/node_modules/hawk/.travis.yml b/frontend/express/node_modules/request/node_modules/hawk/.travis.yml deleted file mode 100644 index 047f7e3d5e1..00000000000 --- a/frontend/express/node_modules/request/node_modules/hawk/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js - -node_js: - - 0.10 - diff --git a/frontend/express/node_modules/request/node_modules/hawk/LICENSE b/frontend/express/node_modules/request/node_modules/hawk/LICENSE deleted file mode 100644 index e699a7bdbaa..00000000000 --- a/frontend/express/node_modules/request/node_modules/hawk/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2012-2013, Eran Hammer. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Eran Hammer nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ERAN HAMMER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/frontend/express/node_modules/request/node_modules/hawk/Makefile b/frontend/express/node_modules/request/node_modules/hawk/Makefile deleted file mode 100644 index 9e7138c2a6f..00000000000 --- a/frontend/express/node_modules/request/node_modules/hawk/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -test: - @./node_modules/.bin/lab -test-cov: - @./node_modules/.bin/lab -r threshold -t 100 -test-cov-html: - @./node_modules/.bin/lab -r html -o coverage.html -complexity: - @./node_modules/.bin/cr -o complexity.md -f markdown lib - -.PHONY: test test-cov test-cov-html complexity - diff --git a/frontend/express/node_modules/request/node_modules/hawk/README.md b/frontend/express/node_modules/request/node_modules/hawk/README.md deleted file mode 100644 index 7061a706c1d..00000000000 --- a/frontend/express/node_modules/request/node_modules/hawk/README.md +++ /dev/null @@ -1,620 +0,0 @@ -![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png) - - **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial -HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz). - -Current version: **0.13** - -[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk) - -# Table of Content - -- [**Introduction**](#introduction) - - [Replay Protection](#replay-protection) - - [Usage Example](#usage-example) - - [Protocol Example](#protocol-example) - - [Payload Validation](#payload-validation) - - [Response Payload Validation](#response-payload-validation) - - [Browser Support and Considerations](#browser-support-and-considerations) -

    -- [**Single URI Authorization**](#single-uri-authorization) - - [Usage Example](#bewit-usage-example) -

    -- [**Security Considerations**](#security-considerations) - - [MAC Keys Transmission](#mac-keys-transmission) - - [Confidentiality of Requests](#confidentiality-of-requests) - - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers) - - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials) - - [Entropy of Keys](#entropy-of-keys) - - [Coverage Limitations](#coverage-limitations) - - [Future Time Manipulation](#future-time-manipulation) - - [Client Clock Poisoning](#client-clock-poisoning) - - [Bewit Limitations](#bewit-limitations) -

    -- [**Frequently Asked Questions**](#frequently-asked-questions) -

    -- [**Acknowledgements**](#acknowledgements) - -# Introduction - -**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with -partial cryptographic verification of the request and response, covering the HTTP method, request URI, host, -and optionally the request payload. - -Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of -client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme, -the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is -included in its place. - -However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of -replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less -"chattiness" (interaction with the server). - -Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because -the client and server must both have access to the key material in the clear. - -The primary design goals of this scheme are to: -* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources, -* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where - to send an authenticated request), and -* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client - failure to validate the server's identity as part of its TLS handshake. - -In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using -a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk). - -The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server, -which is beyond the scope of this module. Typically, the shared credentials are established via an initial -TLS-protected phase or derived from some other shared confidential information available to both the client -and the server. - - -## Replay Protection - -Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more -than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when -making requests. This gives the server enough information to prevent replay attacks. - -The nonce is generated by the client, and is a string unique across all requests with the same timestamp and -key identifier combination. - -The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards -are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks. -By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in -practice translates to a maximum of 2 minutes as the skew can be positive or negative). - -Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client -clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types -(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response -to a bad timestamp. - -There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a -potential attack vector). Instead, the client only uses the server's time to calculate an offset used only -for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing -the number of round trips required to authenticate the first request. - - -## Usage Example - -Server code: - -```javascript -var Http = require('http'); -var Hawk = require('hawk'); - - -// Credentials lookup function - -var credentialsFunc = function (id, callback) { - - var credentials = { - key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', - algorithm: 'sha256', - user: 'Steve' - }; - - return callback(null, credentials); -}; - -// Create HTTP server - -var handler = function (req, res) { - - // Authenticate incoming request - - Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { - - // Prepare response - - var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!'); - var headers = { 'Content-Type': 'text/plain' }; - - // Generate Server-Authorization response header - - var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] }); - headers['Server-Authorization'] = header; - - // Send the response back - - res.writeHead(!err ? 200 : 401, headers); - res.end(payload); - }); -}; - -// Start server - -Http.createServer(handler).listen(8000, 'example.com'); -``` - -Client code: - -```javascript -var Request = require('request'); -var Hawk = require('hawk'); - - -// Client credentials - -var credentials = { - id: 'dh37fgj492je', - key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', - algorithm: 'sha256' -} - -// Request options - -var requestOptions = { - uri: 'http://example.com:8000/resource/1?b=1&a=2', - method: 'GET', - headers: {} -}; - -// Generate Authorization request header - -var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' }); -requestOptions.headers.Authorization = header.field; - -// Send authenticated request - -Request(requestOptions, function (error, response, body) { - - // Authenticate the server's response - - var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body }); - - // Output results - - console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)')); -}); -``` - -**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local -machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method. - -```javascript -Hawk.sntp.start(); -``` - - -## Protocol Example - -The client attempts to access a protected resource without authentication, sending the following HTTP request to -the resource server: - -``` -GET /resource/1?b=1&a=2 HTTP/1.1 -Host: example.com:8000 -``` - -The resource server returns an authentication challenge. - -``` -HTTP/1.1 401 Unauthorized -WWW-Authenticate: Hawk -``` - -The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/" -server. The **Hawk** credentials issued to the client include the following attributes: - -* Key identifier: dh37fgj492je -* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn -* Algorithm: sha256 - -The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1, -1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline -character): - -``` -hawk.1.header -1353832234 -j4h3g2 -GET -/resource?a=1&b=2 -example.com -8000 - -some-app-ext-data - -``` - -The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string. -The result is base64-encoded to produce the request MAC: - -``` -6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE= -``` - -The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using -the HTTP `Authorization` request header field: - -``` -GET /resource/1?b=1&a=2 HTTP/1.1 -Host: example.com:8000 -Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=" -``` - -The server validates the request by calculating the request MAC again based on the request received and verifies the validity -and scope of the **Hawk** credentials. If valid, the server responds with the requested resource. - - -### Payload Validation - -**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash -using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character): -* `hawk.1.payload` -* the content-type in lowercase, without any parameters (e.g. `application/json`) -* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability) - -For example: - -* Payload: `Thank you for flying Hawk` -* Content Type: `text/plain` -* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=` - -Results in the following input to the payload hash function (newline terminated values): - -``` -hawk.1.payload -text/plain -Thank you for flying Hawk - -``` - -Which produces the following hash value: - -``` -Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= -``` - -The client constructs the normalized request string (newline terminated values): - -``` -hawk.1.header -1353832234 -j4h3g2 -POST -/resource?a=1&b=2 -example.com -8000 -Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= -some-app-ext-data - -``` - -Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data, -and request MAC, with the request using the HTTP `Authorization` request header field: - -``` -POST /resource/1 HTTP/1.1 -Host: example.com:8000 -Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=" -``` - -It is up to the server if and when it validates the payload for any given request, based solely on it's security policy -and the nature of the data included. - -If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct -the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value -with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash. - -However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed -at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value -provided by the client after validating the MAC. - -It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value -included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided -by the client, the payload may be modified by an attacker. - - -## Response Payload Validation - -**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the -client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header -as a response header using the exact same syntax as the `Authorization` request header field. - -The header is contructed using the same process as the client's request header. The server uses the same credentials and other -artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with -new values based on the server response. The rest as identical to those used by the client. - -The result MAC digest is included with the optional `hash` and `ext` values: - -``` -Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific" -``` - - -## Browser Support and Considerations - -A browser script is provided for including using a `'); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml('')); - expect(boom.response.payload.message).to.not.contain(''); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml(' -``` - -Or in node.js: - -``` -npm install node-uuid -``` - -```javascript -var uuid = require('node-uuid'); -``` - -Then create some ids ... - -```javascript -// Generate a v1 (time-based) id -uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' - -// Generate a v4 (random) id -uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' -``` - -## API - -### uuid.v1([`options` [, `buffer` [, `offset`]]]) - -Generate and return a RFC4122 v1 (timestamp-based) UUID. - -* `options` - (Object) Optional uuid state to apply. Properties may include: - - * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID. See note 1. - * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used. - * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used. - * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2. - -* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. -* `offset` - (Number) Starting index in `buffer` at which to begin writing. - -Returns `buffer`, if specified, otherwise the string form of the UUID - -Notes: - -1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.) - -Example: Generate string UUID with fully-specified options - -```javascript -uuid.v1({ - node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab], - clockseq: 0x1234, - msecs: new Date('2011-11-01').getTime(), - nsecs: 5678 -}); // -> "710b962e-041c-11e1-9234-0123456789ab" -``` - -Example: In-place generation of two binary IDs - -```javascript -// Generate two ids in an array -var arr = new Array(32); // -> [] -uuid.v1(null, arr, 0); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15] -uuid.v1(null, arr, 16); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15] - -// Optionally use uuid.unparse() to get stringify the ids -uuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115' -uuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115' -``` - -### uuid.v4([`options` [, `buffer` [, `offset`]]]) - -Generate and return a RFC4122 v4 UUID. - -* `options` - (Object) Optional uuid state to apply. Properties may include: - - * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values - * `rng` - (Function) Random # generator to use. Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values. - -* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. -* `offset` - (Number) Starting index in `buffer` at which to begin writing. - -Returns `buffer`, if specified, otherwise the string form of the UUID - -Example: Generate string UUID with fully-specified options - -```javascript -uuid.v4({ - random: [ - 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea, - 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36 - ] -}); -// -> "109156be-c4fb-41ea-b1b4-efe1671c5836" -``` - -Example: Generate two IDs in a single buffer - -```javascript -var buffer = new Array(32); // (or 'new Buffer' in node.js) -uuid.v4(null, buffer, 0); -uuid.v4(null, buffer, 16); -``` - -### uuid.parse(id[, buffer[, offset]]) -### uuid.unparse(buffer[, offset]) - -Parse and unparse UUIDs - - * `id` - (String) UUID(-like) string - * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used - * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0 - -Example parsing and unparsing a UUID string - -```javascript -var bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> -var string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10' -``` - -### uuid.noConflict() - -(Browsers only) Set `uuid` property back to it's previous value. - -Returns the node-uuid object. - -Example: - -```javascript -var myUuid = uuid.noConflict(); -myUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' -``` - -## Deprecated APIs - -Support for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version. - -### uuid([format [, buffer [, offset]]]) - -uuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary). - -### uuid.BufferClass - -The class of container created when generating binary uuid data if no buffer argument is specified. This is expected to go away, with no replacement API. - -## Testing - -In node.js - -``` -> cd test -> node test.js -``` - -In Browser - -``` -open test/test.html -``` - -### Benchmarking - -Requires node.js - -``` -npm install uuid uuid-js -node benchmark/benchmark.js -``` - -For a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark) - -For browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance). - -## Release notes - -v1.4 -* Improved module context detection -* Removed public RNG functions - -v1.3.2: -* Improve tests and handling of v1() options (Issue #24) -* Expose RNG option to allow for perf testing with different generators - -v1.3: -* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)! -* Support for node.js crypto API -* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/README.md b/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/README.md deleted file mode 100644 index aaeb2ea0132..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# node-uuid Benchmarks - -### Results - -To see the results of our benchmarks visit https://github.com/broofa/node-uuid/wiki/Benchmark - -### Run them yourself - -node-uuid comes with some benchmarks to measure performance of generating UUIDs. These can be run using node.js. node-uuid is being benchmarked against some other uuid modules, that are available through npm namely `uuid` and `uuid-js`. - -To prepare and run the benchmark issue; - -``` -npm install uuid uuid-js -node benchmark/benchmark.js -``` - -You'll see an output like this one: - -``` -# v4 -nodeuuid.v4(): 854700 uuids/second -nodeuuid.v4('binary'): 788643 uuids/second -nodeuuid.v4('binary', buffer): 1336898 uuids/second -uuid(): 479386 uuids/second -uuid('binary'): 582072 uuids/second -uuidjs.create(4): 312304 uuids/second - -# v1 -nodeuuid.v1(): 938086 uuids/second -nodeuuid.v1('binary'): 683060 uuids/second -nodeuuid.v1('binary', buffer): 1644736 uuids/second -uuidjs.create(1): 190621 uuids/second -``` - -* The `uuid()` entries are for Nikhil Marathe's [uuid module](https://bitbucket.org/nikhilm/uuidjs) which is a wrapper around the native libuuid library. -* The `uuidjs()` entries are for Patrick Negri's [uuid-js module](https://github.com/pnegri/uuid-js) which is a pure javascript implementation based on [UUID.js](https://github.com/LiosK/UUID.js) by LiosK. - -If you want to get more reliable results you can run the benchmark multiple times and write the output into a log file: - -``` -for i in {0..9}; do node benchmark/benchmark.js >> benchmark/bench_0.4.12.log; done; -``` - -If you're interested in how performance varies between different node versions, you can issue the above command multiple times. - -You can then use the shell script `bench.sh` provided in this directory to calculate the averages over all benchmark runs and draw a nice plot: - -``` -(cd benchmark/ && ./bench.sh) -``` - -This assumes you have [gnuplot](http://www.gnuplot.info/) and [ImageMagick](http://www.imagemagick.org/) installed. You'll find a nice `bench.png` graph in the `benchmark/` directory then. diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu b/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu deleted file mode 100644 index a342fbbe04e..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.gnu +++ /dev/null @@ -1,174 +0,0 @@ -#!/opt/local/bin/gnuplot -persist -# -# -# G N U P L O T -# Version 4.4 patchlevel 3 -# last modified March 2011 -# System: Darwin 10.8.0 -# -# Copyright (C) 1986-1993, 1998, 2004, 2007-2010 -# Thomas Williams, Colin Kelley and many others -# -# gnuplot home: http://www.gnuplot.info -# faq, bugs, etc: type "help seeking-assistance" -# immediate help: type "help" -# plot window: hit 'h' -set terminal postscript eps noenhanced defaultplex \ - leveldefault color colortext \ - solid linewidth 1.2 butt noclip \ - palfuncparam 2000,0.003 \ - "Helvetica" 14 -set output 'bench.eps' -unset clip points -set clip one -unset clip two -set bar 1.000000 front -set border 31 front linetype -1 linewidth 1.000 -set xdata -set ydata -set zdata -set x2data -set y2data -set timefmt x "%d/%m/%y,%H:%M" -set timefmt y "%d/%m/%y,%H:%M" -set timefmt z "%d/%m/%y,%H:%M" -set timefmt x2 "%d/%m/%y,%H:%M" -set timefmt y2 "%d/%m/%y,%H:%M" -set timefmt cb "%d/%m/%y,%H:%M" -set boxwidth -set style fill empty border -set style rectangle back fc lt -3 fillstyle solid 1.00 border lt -1 -set style circle radius graph 0.02, first 0, 0 -set dummy x,y -set format x "% g" -set format y "% g" -set format x2 "% g" -set format y2 "% g" -set format z "% g" -set format cb "% g" -set angles radians -unset grid -set key title "" -set key outside left top horizontal Right noreverse enhanced autotitles columnhead nobox -set key noinvert samplen 4 spacing 1 width 0 height 0 -set key maxcolumns 2 maxrows 0 -unset label -unset arrow -set style increment default -unset style line -set style line 1 linetype 1 linewidth 2.000 pointtype 1 pointsize default pointinterval 0 -unset style arrow -set style histogram clustered gap 2 title offset character 0, 0, 0 -unset logscale -set offsets graph 0.05, 0.15, 0, 0 -set pointsize 1.5 -set pointintervalbox 1 -set encoding default -unset polar -unset parametric -unset decimalsign -set view 60, 30, 1, 1 -set samples 100, 100 -set isosamples 10, 10 -set surface -unset contour -set clabel '%8.3g' -set mapping cartesian -set datafile separator whitespace -unset hidden3d -set cntrparam order 4 -set cntrparam linear -set cntrparam levels auto 5 -set cntrparam points 5 -set size ratio 0 1,1 -set origin 0,0 -set style data points -set style function lines -set xzeroaxis linetype -2 linewidth 1.000 -set yzeroaxis linetype -2 linewidth 1.000 -set zzeroaxis linetype -2 linewidth 1.000 -set x2zeroaxis linetype -2 linewidth 1.000 -set y2zeroaxis linetype -2 linewidth 1.000 -set ticslevel 0.5 -set mxtics default -set mytics default -set mztics default -set mx2tics default -set my2tics default -set mcbtics default -set xtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set xtics norangelimit -set xtics () -set ytics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set ytics autofreq norangelimit -set ztics border in scale 1,0.5 nomirror norotate offset character 0, 0, 0 -set ztics autofreq norangelimit -set nox2tics -set noy2tics -set cbtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0 -set cbtics autofreq norangelimit -set title "" -set title offset character 0, 0, 0 font "" norotate -set timestamp bottom -set timestamp "" -set timestamp offset character 0, 0, 0 font "" norotate -set rrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] ) -set autoscale rfixmin -set autoscale rfixmax -set trange [ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000] ) -set autoscale tfixmin -set autoscale tfixmax -set urange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale ufixmin -set autoscale ufixmax -set vrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale vfixmin -set autoscale vfixmax -set xlabel "" -set xlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate -set x2label "" -set x2label offset character 0, 0, 0 font "" textcolor lt -1 norotate -set xrange [ * : * ] noreverse nowriteback # (currently [-0.150000:3.15000] ) -set autoscale xfixmin -set autoscale xfixmax -set x2range [ * : * ] noreverse nowriteback # (currently [0.00000:3.00000] ) -set autoscale x2fixmin -set autoscale x2fixmax -set ylabel "" -set ylabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set y2label "" -set y2label offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set yrange [ 0.00000 : 1.90000e+06 ] noreverse nowriteback # (currently [:] ) -set autoscale yfixmin -set autoscale yfixmax -set y2range [ * : * ] noreverse nowriteback # (currently [0.00000:1.90000e+06] ) -set autoscale y2fixmin -set autoscale y2fixmax -set zlabel "" -set zlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate -set zrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] ) -set autoscale zfixmin -set autoscale zfixmax -set cblabel "" -set cblabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270 -set cbrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] ) -set autoscale cbfixmin -set autoscale cbfixmax -set zero 1e-08 -set lmargin -1 -set bmargin -1 -set rmargin -1 -set tmargin -1 -set pm3d explicit at s -set pm3d scansautomatic -set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean -set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB -set palette rgbformulae 7, 5, 15 -set colorbox default -set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 front bdefault -set loadpath -set fontpath -set fit noerrorvariables -GNUTERM = "aqua" -plot 'bench_results.txt' using 2:xticlabel(1) w lp lw 2, '' using 3:xticlabel(1) w lp lw 2, '' using 4:xticlabel(1) w lp lw 2, '' using 5:xticlabel(1) w lp lw 2, '' using 6:xticlabel(1) w lp lw 2, '' using 7:xticlabel(1) w lp lw 2, '' using 8:xticlabel(1) w lp lw 2, '' using 9:xticlabel(1) w lp lw 2 -# EOF diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.sh b/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.sh deleted file mode 100644 index d870a0cb098..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/bench.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# for a given node version run: -# for i in {0..9}; do node benchmark.js >> bench_0.6.2.log; done; - -PATTERNS=('nodeuuid.v1()' "nodeuuid.v1('binary'," 'nodeuuid.v4()' "nodeuuid.v4('binary'," "uuid()" "uuid('binary')" 'uuidjs.create(1)' 'uuidjs.create(4)' '140byte') -FILES=(node_uuid_v1_string node_uuid_v1_buf node_uuid_v4_string node_uuid_v4_buf libuuid_v4_string libuuid_v4_binary uuidjs_v1_string uuidjs_v4_string 140byte_es) -INDICES=(2 3 2 3 2 2 2 2 2) -VERSIONS=$( ls bench_*.log | sed -e 's/^bench_\([0-9\.]*\)\.log/\1/' | tr "\\n" " " ) -TMPJOIN="tmp_join" -OUTPUT="bench_results.txt" - -for I in ${!FILES[*]}; do - F=${FILES[$I]} - P=${PATTERNS[$I]} - INDEX=${INDICES[$I]} - echo "version $F" > $F - for V in $VERSIONS; do - (VAL=$( grep "$P" bench_$V.log | LC_ALL=en_US awk '{ sum += $'$INDEX' } END { print sum/NR }' ); echo $V $VAL) >> $F - done - if [ $I == 0 ]; then - cat $F > $TMPJOIN - else - join $TMPJOIN $F > $OUTPUT - cp $OUTPUT $TMPJOIN - fi - rm $F -done - -rm $TMPJOIN - -gnuplot bench.gnu -convert -density 200 -resize 800x560 -flatten bench.eps bench.png -rm bench.eps diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c b/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c deleted file mode 100644 index dbfc75f6d71..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark-native.c +++ /dev/null @@ -1,34 +0,0 @@ -/* -Test performance of native C UUID generation - -To Compile: cc -luuid benchmark-native.c -o benchmark-native -*/ - -#include -#include -#include -#include - -int main() { - uuid_t myid; - char buf[36+1]; - int i; - struct timeval t; - double start, finish; - - gettimeofday(&t, NULL); - start = t.tv_sec + t.tv_usec/1e6; - - int n = 2e5; - for (i = 0; i < n; i++) { - uuid_generate(myid); - uuid_unparse(myid, buf); - } - - gettimeofday(&t, NULL); - finish = t.tv_sec + t.tv_usec/1e6; - double dur = finish - start; - - printf("%d uuids/sec", (int)(n/dur)); - return 0; -} diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js b/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js deleted file mode 100644 index 40e6efbe762..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/benchmark/benchmark.js +++ /dev/null @@ -1,84 +0,0 @@ -try { - var nodeuuid = require('../uuid'); -} catch (e) { - console.error('node-uuid require failed - skipping tests'); -} - -try { - var uuid = require('uuid'); -} catch (e) { - console.error('uuid require failed - skipping tests'); -} - -try { - var uuidjs = require('uuid-js'); -} catch (e) { - console.error('uuid-js require failed - skipping tests'); -} - -var N = 5e5; - -function rate(msg, t) { - console.log(msg + ': ' + - (N / (Date.now() - t) * 1e3 | 0) + - ' uuids/second'); -} - -console.log('# v4'); - -// node-uuid - string form -if (nodeuuid) { - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4(); - rate('nodeuuid.v4() - using node.js crypto RNG', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4({rng: nodeuuid.mathRNG}); - rate('nodeuuid.v4() - using Math.random() RNG', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary'); - rate('nodeuuid.v4(\'binary\')', t); - - var buffer = new nodeuuid.BufferClass(16); - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary', buffer); - rate('nodeuuid.v4(\'binary\', buffer)', t); -} - -// libuuid - string form -if (uuid) { - for (var i = 0, t = Date.now(); i < N; i++) uuid(); - rate('uuid()', t); - - for (var i = 0, t = Date.now(); i < N; i++) uuid('binary'); - rate('uuid(\'binary\')', t); -} - -// uuid-js - string form -if (uuidjs) { - for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(4); - rate('uuidjs.create(4)', t); -} - -// 140byte.es -for (var i = 0, t = Date.now(); i < N; i++) 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(s,r){r=Math.random()*16|0;return (s=='x'?r:r&0x3|0x8).toString(16)}); -rate('140byte.es_v4', t); - -console.log(''); -console.log('# v1'); - -// node-uuid - v1 string form -if (nodeuuid) { - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1(); - rate('nodeuuid.v1()', t); - - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary'); - rate('nodeuuid.v1(\'binary\')', t); - - var buffer = new nodeuuid.BufferClass(16); - for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary', buffer); - rate('nodeuuid.v1(\'binary\', buffer)', t); -} - -// uuid-js - v1 string form -if (uuidjs) { - for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(1); - rate('uuidjs.create(1)', t); -} diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/package.json b/frontend/express/node_modules/request/node_modules/node-uuid/package.json deleted file mode 100644 index 11733e8f54d..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "node-uuid", - "description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.", - "url": "http://github.com/broofa/node-uuid", - "keywords": [ - "uuid", - "guid", - "rfc4122" - ], - "author": { - "name": "Robert Kieffer", - "email": "robert@broofa.com" - }, - "contributors": [ - { - "name": "Christoph Tavan", - "email": "dev@tavan.de" - } - ], - "lib": ".", - "main": "./uuid.js", - "repository": { - "type": "git", - "url": "https://github.com/broofa/node-uuid.git" - }, - "version": "1.4.0", - "readme": "# node-uuid\n\nSimple, fast generation of [RFC4122](http://www.ietf.org/rfc/rfc4122.txt) UUIDS.\n\nFeatures:\n\n* Generate RFC4122 version 1 or version 4 UUIDs\n* Runs in node.js and all browsers.\n* Cryptographically strong random # generation on supporting platforms\n* 1.1K minified and gzip'ed (Want something smaller? Check this [crazy shit](https://gist.github.com/982883) out! )\n* [Annotated source code](http://broofa.github.com/node-uuid/docs/uuid.html)\n\n## Getting Started\n\nInstall it in your browser:\n\n```html\n\n```\n\nOr in node.js:\n\n```\nnpm install node-uuid\n```\n\n```javascript\nvar uuid = require('node-uuid');\n```\n\nThen create some ids ...\n\n```javascript\n// Generate a v1 (time-based) id\nuuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'\n\n// Generate a v4 (random) id\nuuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'\n```\n\n## API\n\n### uuid.v1([`options` [, `buffer` [, `offset`]]])\n\nGenerate and return a RFC4122 v1 (timestamp-based) UUID.\n\n* `options` - (Object) Optional uuid state to apply. Properties may include:\n\n * `node` - (Array) Node id as Array of 6 bytes (per 4.1.6). Default: Randomly generated ID. See note 1.\n * `clockseq` - (Number between 0 - 0x3fff) RFC clock sequence. Default: An internally maintained clockseq is used.\n * `msecs` - (Number | Date) Time in milliseconds since unix Epoch. Default: The current time is used.\n * `nsecs` - (Number between 0-9999) additional time, in 100-nanosecond units. Ignored if `msecs` is unspecified. Default: internal uuid counter is used, as per 4.2.1.2.\n\n* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.\n* `offset` - (Number) Starting index in `buffer` at which to begin writing.\n\nReturns `buffer`, if specified, otherwise the string form of the UUID\n\nNotes:\n\n1. The randomly generated node id is only guaranteed to stay constant for the lifetime of the current JS runtime. (Future versions of this module may use persistent storage mechanisms to extend this guarantee.)\n\nExample: Generate string UUID with fully-specified options\n\n```javascript\nuuid.v1({\n node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],\n clockseq: 0x1234,\n msecs: new Date('2011-11-01').getTime(),\n nsecs: 5678\n}); // -> \"710b962e-041c-11e1-9234-0123456789ab\"\n```\n\nExample: In-place generation of two binary IDs\n\n```javascript\n// Generate two ids in an array\nvar arr = new Array(32); // -> []\nuuid.v1(null, arr, 0); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15]\nuuid.v1(null, arr, 16); // -> [02 a2 ce 90 14 32 11 e1 85 58 0b 48 8e 4f c1 15 02 a3 1c b0 14 32 11 e1 85 58 0b 48 8e 4f c1 15]\n\n// Optionally use uuid.unparse() to get stringify the ids\nuuid.unparse(buffer); // -> '02a2ce90-1432-11e1-8558-0b488e4fc115'\nuuid.unparse(buffer, 16) // -> '02a31cb0-1432-11e1-8558-0b488e4fc115'\n```\n\n### uuid.v4([`options` [, `buffer` [, `offset`]]])\n\nGenerate and return a RFC4122 v4 UUID.\n\n* `options` - (Object) Optional uuid state to apply. Properties may include:\n\n * `random` - (Number[16]) Array of 16 numbers (0-255) to use in place of randomly generated values\n * `rng` - (Function) Random # generator to use. Set to one of the built-in generators - `uuid.mathRNG` (all platforms), `uuid.nodeRNG` (node.js only), `uuid.whatwgRNG` (WebKit only) - or a custom function that returns an array[16] of byte values.\n\n* `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written.\n* `offset` - (Number) Starting index in `buffer` at which to begin writing.\n\nReturns `buffer`, if specified, otherwise the string form of the UUID\n\nExample: Generate string UUID with fully-specified options\n\n```javascript\nuuid.v4({\n random: [\n 0x10, 0x91, 0x56, 0xbe, 0xc4, 0xfb, 0xc1, 0xea,\n 0x71, 0xb4, 0xef, 0xe1, 0x67, 0x1c, 0x58, 0x36\n ]\n});\n// -> \"109156be-c4fb-41ea-b1b4-efe1671c5836\"\n```\n\nExample: Generate two IDs in a single buffer\n\n```javascript\nvar buffer = new Array(32); // (or 'new Buffer' in node.js)\nuuid.v4(null, buffer, 0);\nuuid.v4(null, buffer, 16);\n```\n\n### uuid.parse(id[, buffer[, offset]])\n### uuid.unparse(buffer[, offset])\n\nParse and unparse UUIDs\n\n * `id` - (String) UUID(-like) string\n * `buffer` - (Array | Buffer) Array or buffer where UUID bytes are to be written. Default: A new Array or Buffer is used\n * `offset` - (Number) Starting index in `buffer` at which to begin writing. Default: 0\n\nExample parsing and unparsing a UUID string\n\n```javascript\nvar bytes = uuid.parse('797ff043-11eb-11e1-80d6-510998755d10'); // -> \nvar string = uuid.unparse(bytes); // -> '797ff043-11eb-11e1-80d6-510998755d10'\n```\n\n### uuid.noConflict()\n\n(Browsers only) Set `uuid` property back to it's previous value.\n\nReturns the node-uuid object.\n\nExample:\n\n```javascript\nvar myUuid = uuid.noConflict();\nmyUuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'\n```\n\n## Deprecated APIs\n\nSupport for the following v1.2 APIs is available in v1.3, but is deprecated and will be removed in the next major version.\n\n### uuid([format [, buffer [, offset]]])\n\nuuid() has become uuid.v4(), and the `format` argument is now implicit in the `buffer` argument. (i.e. if you specify a buffer, the format is assumed to be binary).\n\n### uuid.BufferClass\n\nThe class of container created when generating binary uuid data if no buffer argument is specified. This is expected to go away, with no replacement API.\n\n## Testing\n\nIn node.js\n\n```\n> cd test\n> node test.js\n```\n\nIn Browser\n\n```\nopen test/test.html\n```\n\n### Benchmarking\n\nRequires node.js\n\n```\nnpm install uuid uuid-js\nnode benchmark/benchmark.js\n```\n\nFor a more complete discussion of node-uuid performance, please see the `benchmark/README.md` file, and the [benchmark wiki](https://github.com/broofa/node-uuid/wiki/Benchmark)\n\nFor browser performance [checkout the JSPerf tests](http://jsperf.com/node-uuid-performance).\n\n## Release notes\n\nv1.4\n* Improved module context detection\n* Removed public RNG functions\n\nv1.3.2:\n* Improve tests and handling of v1() options (Issue #24)\n* Expose RNG option to allow for perf testing with different generators\n\nv1.3:\n* Support for version 1 ids, thanks to [@ctavan](https://github.com/ctavan)!\n* Support for node.js crypto API\n* De-emphasizing performance in favor of a) cryptographic quality PRNGs where available and b) more manageable code\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/broofa/node-uuid/issues" - }, - "_id": "node-uuid@1.4.0", - "_from": "node-uuid@~1.4.0" -} diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/test/compare_v1.js b/frontend/express/node_modules/request/node_modules/node-uuid/test/compare_v1.js deleted file mode 100644 index 05af82215fd..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/test/compare_v1.js +++ /dev/null @@ -1,63 +0,0 @@ -var assert = require('assert'), - nodeuuid = require('../uuid'), - uuidjs = require('uuid-js'), - libuuid = require('uuid').generate, - util = require('util'), - exec = require('child_process').exec, - os = require('os'); - -// On Mac Os X / macports there's only the ossp-uuid package that provides uuid -// On Linux there's uuid-runtime which provides uuidgen -var uuidCmd = os.type() === 'Darwin' ? 'uuid -1' : 'uuidgen -t'; - -function compare(ids) { - console.log(ids); - for (var i = 0; i < ids.length; i++) { - var id = ids[i].split('-'); - id = [id[2], id[1], id[0]].join(''); - ids[i] = id; - } - var sorted = ([].concat(ids)).sort(); - - if (sorted.toString() !== ids.toString()) { - console.log('Warning: sorted !== ids'); - } else { - console.log('everything in order!'); - } -} - -// Test time order of v1 uuids -var ids = []; -while (ids.length < 10e3) ids.push(nodeuuid.v1()); - -var max = 10; -console.log('node-uuid:'); -ids = []; -for (var i = 0; i < max; i++) ids.push(nodeuuid.v1()); -compare(ids); - -console.log(''); -console.log('uuidjs:'); -ids = []; -for (var i = 0; i < max; i++) ids.push(uuidjs.create(1).toString()); -compare(ids); - -console.log(''); -console.log('libuuid:'); -ids = []; -var count = 0; -var last = function() { - compare(ids); -} -var cb = function(err, stdout, stderr) { - ids.push(stdout.substring(0, stdout.length-1)); - count++; - if (count < max) { - return next(); - } - last(); -}; -var next = function() { - exec(uuidCmd, cb); -}; -next(); diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/test/test.html b/frontend/express/node_modules/request/node_modules/node-uuid/test/test.html deleted file mode 100644 index d80326ec5a8..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/test/test.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/test/test.js b/frontend/express/node_modules/request/node_modules/node-uuid/test/test.js deleted file mode 100644 index 24692256161..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/test/test.js +++ /dev/null @@ -1,228 +0,0 @@ -if (!this.uuid) { - // node.js - uuid = require('../uuid'); -} - -// -// x-platform log/assert shims -// - -function _log(msg, type) { - type = type || 'log'; - - if (typeof(document) != 'undefined') { - document.write('
    ' + msg.replace(/\n/g, '
    ') + '
    '); - } - if (typeof(console) != 'undefined') { - var color = { - log: '\033[39m', - warn: '\033[33m', - error: '\033[31m' - }; - console[type](color[type] + msg + color.log); - } -} - -function log(msg) {_log(msg, 'log');} -function warn(msg) {_log(msg, 'warn');} -function error(msg) {_log(msg, 'error');} - -function assert(res, msg) { - if (!res) { - error('FAIL: ' + msg); - } else { - log('Pass: ' + msg); - } -} - -// -// Unit tests -// - -// Verify ordering of v1 ids created with explicit times -var TIME = 1321644961388; // 2011-11-18 11:36:01.388-08:00 - -function compare(name, ids) { - ids = ids.map(function(id) { - return id.split('-').reverse().join('-'); - }).sort(); - var sorted = ([].concat(ids)).sort(); - - assert(sorted.toString() == ids.toString(), name + ' have expected order'); -} - -// Verify ordering of v1 ids created using default behavior -compare('uuids with current time', [ - uuid.v1(), - uuid.v1(), - uuid.v1(), - uuid.v1(), - uuid.v1() -]); - -// Verify ordering of v1 ids created with explicit times -compare('uuids with time option', [ - uuid.v1({msecs: TIME - 10*3600*1000}), - uuid.v1({msecs: TIME - 1}), - uuid.v1({msecs: TIME}), - uuid.v1({msecs: TIME + 1}), - uuid.v1({msecs: TIME + 28*24*3600*1000}) -]); - -assert( - uuid.v1({msecs: TIME}) != uuid.v1({msecs: TIME}), - 'IDs created at same msec are different' -); - -// Verify throw if too many ids created -var thrown = false; -try { - uuid.v1({msecs: TIME, nsecs: 10000}); -} catch (e) { - thrown = true; -} -assert(thrown, 'Exception thrown when > 10K ids created in 1 ms'); - -// Verify clock regression bumps clockseq -var uidt = uuid.v1({msecs: TIME}); -var uidtb = uuid.v1({msecs: TIME - 1}); -assert( - parseInt(uidtb.split('-')[3], 16) - parseInt(uidt.split('-')[3], 16) === 1, - 'Clock regression by msec increments the clockseq' -); - -// Verify clock regression bumps clockseq -var uidtn = uuid.v1({msecs: TIME, nsecs: 10}); -var uidtnb = uuid.v1({msecs: TIME, nsecs: 9}); -assert( - parseInt(uidtnb.split('-')[3], 16) - parseInt(uidtn.split('-')[3], 16) === 1, - 'Clock regression by nsec increments the clockseq' -); - -// Verify explicit options produce expected id -var id = uuid.v1({ - msecs: 1321651533573, - nsecs: 5432, - clockseq: 0x385c, - node: [ 0x61, 0xcd, 0x3c, 0xbb, 0x32, 0x10 ] -}); -assert(id == 'd9428888-122b-11e1-b85c-61cd3cbb3210', 'Explicit options produce expected id'); - -// Verify adjacent ids across a msec boundary are 1 time unit apart -var u0 = uuid.v1({msecs: TIME, nsecs: 9999}); -var u1 = uuid.v1({msecs: TIME + 1, nsecs: 0}); - -var before = u0.split('-')[0], after = u1.split('-')[0]; -var dt = parseInt(after, 16) - parseInt(before, 16); -assert(dt === 1, 'Ids spanning 1ms boundary are 100ns apart'); - -// -// Test parse/unparse -// - -id = '00112233445566778899aabbccddeeff'; -assert(uuid.unparse(uuid.parse(id.substr(0,10))) == - '00112233-4400-0000-0000-000000000000', 'Short parse'); -assert(uuid.unparse(uuid.parse('(this is the uuid -> ' + id + id)) == - '00112233-4455-6677-8899-aabbccddeeff', 'Dirty parse'); - -// -// Perf tests -// - -var generators = { - v1: uuid.v1, - v4: uuid.v4 -}; - -var UUID_FORMAT = { - v1: /[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i, - v4: /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i -}; - -var N = 1e4; - -// Get %'age an actual value differs from the ideal value -function divergence(actual, ideal) { - return Math.round(100*100*(actual - ideal)/ideal)/100; -} - -function rate(msg, t) { - log(msg + ': ' + (N / (Date.now() - t) * 1e3 | 0) + ' uuids\/second'); -} - -for (var version in generators) { - var counts = {}, max = 0; - var generator = generators[version]; - var format = UUID_FORMAT[version]; - - log('\nSanity check ' + N + ' ' + version + ' uuids'); - for (var i = 0, ok = 0; i < N; i++) { - id = generator(); - if (!format.test(id)) { - throw Error(id + ' is not a valid UUID string'); - } - - if (id != uuid.unparse(uuid.parse(id))) { - assert(fail, id + ' is not a valid id'); - } - - // Count digits for our randomness check - if (version == 'v4') { - var digits = id.replace(/-/g, '').split(''); - for (var j = digits.length-1; j >= 0; j--) { - var c = digits[j]; - max = Math.max(max, counts[c] = (counts[c] || 0) + 1); - } - } - } - - // Check randomness for v4 UUIDs - if (version == 'v4') { - // Limit that we get worried about randomness. (Purely empirical choice, this!) - var limit = 2*100*Math.sqrt(1/N); - - log('\nChecking v4 randomness. Distribution of Hex Digits (% deviation from ideal)'); - - for (var i = 0; i < 16; i++) { - var c = i.toString(16); - var bar = '', n = counts[c], p = Math.round(n/max*100|0); - - // 1-3,5-8, and D-F: 1:16 odds over 30 digits - var ideal = N*30/16; - if (i == 4) { - // 4: 1:1 odds on 1 digit, plus 1:16 odds on 30 digits - ideal = N*(1 + 30/16); - } else if (i >= 8 && i <= 11) { - // 8-B: 1:4 odds on 1 digit, plus 1:16 odds on 30 digits - ideal = N*(1/4 + 30/16); - } else { - // Otherwise: 1:16 odds on 30 digits - ideal = N*30/16; - } - var d = divergence(n, ideal); - - // Draw bar using UTF squares (just for grins) - var s = n/max*50 | 0; - while (s--) bar += '='; - - assert(Math.abs(d) < limit, c + ' |' + bar + '| ' + counts[c] + ' (' + d + '% < ' + limit + '%)'); - } - } -} - -// Perf tests -for (var version in generators) { - log('\nPerformance testing ' + version + ' UUIDs'); - var generator = generators[version]; - var buf = new uuid.BufferClass(16); - - for (var i = 0, t = Date.now(); i < N; i++) generator(); - rate('uuid.' + version + '()', t); - - for (var i = 0, t = Date.now(); i < N; i++) generator('binary'); - rate('uuid.' + version + '(\'binary\')', t); - - for (var i = 0, t = Date.now(); i < N; i++) generator('binary', buf); - rate('uuid.' + version + '(\'binary\', buffer)', t); -} diff --git a/frontend/express/node_modules/request/node_modules/node-uuid/uuid.js b/frontend/express/node_modules/request/node_modules/node-uuid/uuid.js deleted file mode 100644 index 4795b9d8a68..00000000000 --- a/frontend/express/node_modules/request/node_modules/node-uuid/uuid.js +++ /dev/null @@ -1,245 +0,0 @@ -// uuid.js -// -// (c) 2010-2012 Robert Kieffer -// MIT License -// https://github.com/broofa/node-uuid -(function() { - var _global = this; - - // Unique ID creation requires a high quality random # generator. We feature - // detect to determine the best RNG source, normalizing to a function that - // returns 128-bits of randomness, since that's what's usually required - var _rng; - - // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html - // - // Moderately fast, high quality - if (typeof(require) == 'function') { - try { - var _rb = require('crypto').randomBytes; - _rng = _rb && function() {return _rb(16);}; - } catch(e) {} - } - - if (!_rng && _global.crypto && crypto.getRandomValues) { - // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto - // - // Moderately fast, high quality - var _rnds8 = new Uint8Array(16); - _rng = function whatwgRNG() { - crypto.getRandomValues(_rnds8); - return _rnds8; - }; - } - - if (!_rng) { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var _rnds = new Array(16); - _rng = function() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return _rnds; - }; - } - - // Buffer class to use - var BufferClass = typeof(Buffer) == 'function' ? Buffer : Array; - - // Maps for number <-> hex string conversion - var _byteToHex = []; - var _hexToByte = {}; - for (var i = 0; i < 256; i++) { - _byteToHex[i] = (i + 0x100).toString(16).substr(1); - _hexToByte[_byteToHex[i]] = i; - } - - // **`parse()` - Parse a UUID into it's component bytes** - function parse(s, buf, offset) { - var i = (buf && offset) || 0, ii = 0; - - buf = buf || []; - s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { - if (ii < 16) { // Don't overflow! - buf[i + ii++] = _hexToByte[oct]; - } - }); - - // Zero out remaining bytes if string was short - while (ii < 16) { - buf[i + ii++] = 0; - } - - return buf; - } - - // **`unparse()` - Convert UUID byte array (ala parse()) into a string** - function unparse(buf, offset) { - var i = offset || 0, bth = _byteToHex; - return bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]]; - } - - // **`v1()` - Generate time-based UUID** - // - // Inspired by https://github.com/LiosK/UUID.js - // and http://docs.python.org/library/uuid.html - - // random #'s we need to init node and clockseq - var _seedBytes = _rng(); - - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - var _nodeId = [ - _seedBytes[0] | 0x01, - _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] - ]; - - // Per 4.2.2, randomize (14 bit) clockseq - var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; - - // Previous uuid creation time - var _lastMSecs = 0, _lastNSecs = 0; - - // See https://github.com/broofa/node-uuid for API details - function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - - var clockseq = options.clockseq != null ? options.clockseq : _clockseq; - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs != null ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq == null) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - var node = options.node || _nodeId; - for (var n = 0; n < 6; n++) { - b[i + n] = node[n]; - } - - return buf ? buf : unparse(b); - } - - // **`v4()` - Generate random UUID** - - // See https://github.com/broofa/node-uuid for API details - function v4(options, buf, offset) { - // Deprecated - 'format' argument, as supported in v1.2 - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options == 'binary' ? new BufferClass(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || _rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ii++) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || unparse(rnds); - } - - // Export public API - var uuid = v4; - uuid.v1 = v1; - uuid.v4 = v4; - uuid.parse = parse; - uuid.unparse = unparse; - uuid.BufferClass = BufferClass; - - if (_global.define && define.amd) { - // Publish as AMD module - define(function() {return uuid;}); - } else if (typeof(module) != 'undefined' && module.exports) { - // Publish as node.js module - module.exports = uuid; - } else { - // Publish as global (in browsers) - var _previousRoot = _global.uuid; - - // **`noConflict()` - (browser only) to reset global 'uuid' var** - uuid.noConflict = function() { - _global.uuid = _previousRoot; - return uuid; - }; - - _global.uuid = uuid; - } -}()); diff --git a/frontend/express/node_modules/request/node_modules/oauth-sign/LICENSE b/frontend/express/node_modules/request/node_modules/oauth-sign/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/frontend/express/node_modules/request/node_modules/oauth-sign/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/oauth-sign/README.md b/frontend/express/node_modules/request/node_modules/oauth-sign/README.md deleted file mode 100644 index 34c4a85d2dd..00000000000 --- a/frontend/express/node_modules/request/node_modules/oauth-sign/README.md +++ /dev/null @@ -1,4 +0,0 @@ -oauth-sign -========== - -OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. diff --git a/frontend/express/node_modules/request/node_modules/oauth-sign/index.js b/frontend/express/node_modules/request/node_modules/oauth-sign/index.js deleted file mode 100644 index e35bfa67075..00000000000 --- a/frontend/express/node_modules/request/node_modules/oauth-sign/index.js +++ /dev/null @@ -1,43 +0,0 @@ -var crypto = require('crypto') - , qs = require('querystring') - ; - -function sha1 (key, body) { - return crypto.createHmac('sha1', key).update(body).digest('base64') -} - -function rfc3986 (str) { - return encodeURIComponent(str) - .replace(/!/g,'%21') - .replace(/\*/g,'%2A') - .replace(/\(/g,'%28') - .replace(/\)/g,'%29') - .replace(/'/g,'%27') - ; -} - -function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { - // adapted from https://dev.twitter.com/docs/auth/oauth and - // https://dev.twitter.com/docs/auth/creating-signature - - var querystring = Object.keys(params).sort().map(function(key){ - // big WTF here with the escape + encoding but it's what twitter wants - return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key])) - }).join('%26') - - var base = [ - httpMethod ? httpMethod.toUpperCase() : 'GET', - rfc3986(base_uri), - querystring - ].join('&') - - var key = [ - consumer_secret, - token_secret || '' - ].map(rfc3986).join('&') - - return sha1(key, base) -} - -exports.hmacsign = hmacsign -exports.rfc3986 = rfc3986 diff --git a/frontend/express/node_modules/request/node_modules/oauth-sign/package.json b/frontend/express/node_modules/request/node_modules/oauth-sign/package.json deleted file mode 100644 index f211ed34eb8..00000000000 --- a/frontend/express/node_modules/request/node_modules/oauth-sign/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "oauth-sign", - "description": "OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/oauth-sign" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "scripts": { - "test": "node test.js" - }, - "readme": "oauth-sign\n==========\n\nOAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. \n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/oauth-sign/issues" - }, - "_id": "oauth-sign@0.3.0", - "_from": "oauth-sign@~0.3.0" -} diff --git a/frontend/express/node_modules/request/node_modules/oauth-sign/test.js b/frontend/express/node_modules/request/node_modules/oauth-sign/test.js deleted file mode 100644 index 46955ff6939..00000000000 --- a/frontend/express/node_modules/request/node_modules/oauth-sign/test.js +++ /dev/null @@ -1,49 +0,0 @@ -var hmacsign = require('./index').hmacsign - , assert = require('assert') - , qs = require('querystring') - ; - -// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth - -var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', - { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_timestamp: '1272323042' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") - -console.log(reqsign) -console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') -assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') - -var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', - { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , oauth_timestamp: '1272323047' - , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") - -console.log(accsign) -console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') -assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') - -var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', - { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" - , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , oauth_signature_method: "HMAC-SHA1" - , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , oauth_timestamp: "1272325550" - , oauth_version: "1.0" - , status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") - -console.log(upsign) -console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') -assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') - - diff --git a/frontend/express/node_modules/request/node_modules/qs/.gitmodules b/frontend/express/node_modules/request/node_modules/qs/.gitmodules deleted file mode 100644 index 49e31dac7d7..00000000000 --- a/frontend/express/node_modules/request/node_modules/qs/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "support/expresso"] - path = support/expresso - url = git://github.com/visionmedia/expresso.git -[submodule "support/should"] - path = support/should - url = git://github.com/visionmedia/should.js.git diff --git a/frontend/express/node_modules/request/node_modules/qs/.npmignore b/frontend/express/node_modules/request/node_modules/qs/.npmignore deleted file mode 100644 index e85ce2afa21..00000000000 --- a/frontend/express/node_modules/request/node_modules/qs/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -test -.travis.yml -benchmark.js -component.json -examples.js -History.md -Makefile diff --git a/frontend/express/node_modules/request/node_modules/qs/Readme.md b/frontend/express/node_modules/request/node_modules/qs/Readme.md deleted file mode 100644 index 27e54a4af18..00000000000 --- a/frontend/express/node_modules/request/node_modules/qs/Readme.md +++ /dev/null @@ -1,58 +0,0 @@ -# node-querystring - - query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others. - -## Installation - - $ npm install qs - -## Examples - -```js -var qs = require('qs'); - -qs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com'); -// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } } - -qs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }}) -// => user[name]=Tobi&user[email]=tobi%40learnboost.com -``` - -## Testing - -Install dev dependencies: - - $ npm install -d - -and execute: - - $ make test - -browser: - - $ open test/browser/index.html - -## License - -(The MIT License) - -Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/qs/index.js b/frontend/express/node_modules/request/node_modules/qs/index.js deleted file mode 100644 index 590491e31ed..00000000000 --- a/frontend/express/node_modules/request/node_modules/qs/index.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * Object#toString() ref for stringify(). - */ - -var toString = Object.prototype.toString; - -/** - * Object#hasOwnProperty ref - */ - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Array#indexOf shim. - */ - -var indexOf = typeof Array.prototype.indexOf === 'function' - ? function(arr, el) { return arr.indexOf(el); } - : function(arr, el) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] === el) return i; - } - return -1; - }; - -/** - * Array.isArray shim. - */ - -var isArray = Array.isArray || function(arr) { - return toString.call(arr) == '[object Array]'; -}; - -/** - * Object.keys shim. - */ - -var objectKeys = Object.keys || function(obj) { - var ret = []; - for (var key in obj) ret.push(key); - return ret; -}; - -/** - * Array#forEach shim. - */ - -var forEach = typeof Array.prototype.forEach === 'function' - ? function(arr, fn) { return arr.forEach(fn); } - : function(arr, fn) { - for (var i = 0; i < arr.length; i++) fn(arr[i]); - }; - -/** - * Array#reduce shim. - */ - -var reduce = function(arr, fn, initial) { - if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); - var res = initial; - for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); - return res; -}; - -/** - * Create a nullary object if possible - */ - -function createObject() { - return Object.create - ? Object.create(null) - : {}; -} - -/** - * Cache non-integer test regexp. - */ - -var isint = /^[0-9]+$/; - -function promote(parent, key) { - if (parent[key].length == 0) return parent[key] = createObject(); - var t = createObject(); - for (var i in parent[key]) { - if (hasOwnProperty.call(parent[key], i)) { - t[i] = parent[key][i]; - } - } - parent[key] = t; - return t; -} - -function parse(parts, parent, key, val) { - var part = parts.shift(); - // end - if (!part) { - if (isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } - // array - } else { - var obj = parent[key] = parent[key] || []; - if (']' == part) { - if (isArray(obj)) { - if ('' != val) obj.push(val); - } else if ('object' == typeof obj) { - obj[objectKeys(obj).length] = val; - } else { - obj = parent[key] = [parent[key], val]; - } - // prop - } else if (~indexOf(part, ']')) { - part = part.substr(0, part.length - 1); - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - // key - } else { - if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); - parse(parts, obj, part, val); - } - } -} - -/** - * Merge parent key/val pair. - */ - -function merge(parent, key, val){ - if (~indexOf(key, ']')) { - var parts = key.split('[') - , len = parts.length - , last = len - 1; - parse(parts, parent, 'base', val); - // optimize - } else { - if (!isint.test(key) && isArray(parent.base)) { - var t = createObject(); - for (var k in parent.base) t[k] = parent.base[k]; - parent.base = t; - } - set(parent.base, key, val); - } - - return parent; -} - -/** - * Compact sparse arrays. - */ - -function compact(obj) { - if ('object' != typeof obj) return obj; - - if (isArray(obj)) { - var ret = []; - - for (var i in obj) { - if (hasOwnProperty.call(obj, i)) { - ret.push(obj[i]); - } - } - - return ret; - } - - for (var key in obj) { - obj[key] = compact(obj[key]); - } - - return obj; -} - -/** - * Restore Object.prototype. - * see pull-request #58 - */ - -function restoreProto(obj) { - if (!Object.create) return obj; - if (isArray(obj)) return obj; - if (obj && 'object' != typeof obj) return obj; - - for (var key in obj) { - if (hasOwnProperty.call(obj, key)) { - obj[key] = restoreProto(obj[key]); - } - } - - obj.__proto__ = Object.prototype; - return obj; -} - -/** - * Parse the given obj. - */ - -function parseObject(obj){ - var ret = { base: {} }; - - forEach(objectKeys(obj), function(name){ - merge(ret, name, obj[name]); - }); - - return compact(ret.base); -} - -/** - * Parse the given str. - */ - -function parseString(str){ - var ret = reduce(String(str).split('&'), function(ret, pair){ - var eql = indexOf(pair, '=') - , brace = lastBraceInKey(pair) - , key = pair.substr(0, brace || eql) - , val = pair.substr(brace || eql, pair.length) - , val = val.substr(indexOf(val, '=') + 1, val.length); - - // ?foo - if ('' == key) key = pair, val = ''; - if ('' == key) return ret; - - return merge(ret, decode(key), decode(val)); - }, { base: createObject() }).base; - - return restoreProto(compact(ret)); -} - -/** - * Parse the given query `str` or `obj`, returning an object. - * - * @param {String} str | {Object} obj - * @return {Object} - * @api public - */ - -exports.parse = function(str){ - if (null == str || '' == str) return {}; - return 'object' == typeof str - ? parseObject(str) - : parseString(str); -}; - -/** - * Turn the given `obj` into a query string - * - * @param {Object} obj - * @return {String} - * @api public - */ - -var stringify = exports.stringify = function(obj, prefix) { - if (isArray(obj)) { - return stringifyArray(obj, prefix); - } else if ('[object Object]' == toString.call(obj)) { - return stringifyObject(obj, prefix); - } else if ('string' == typeof obj) { - return stringifyString(obj, prefix); - } else { - return prefix + '=' + encodeURIComponent(String(obj)); - } -}; - -/** - * Stringify the given `str`. - * - * @param {String} str - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyString(str, prefix) { - if (!prefix) throw new TypeError('stringify expects an object'); - return prefix + '=' + encodeURIComponent(str); -} - -/** - * Stringify the given `arr`. - * - * @param {Array} arr - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyArray(arr, prefix) { - var ret = []; - if (!prefix) throw new TypeError('stringify expects an object'); - for (var i = 0; i < arr.length; i++) { - ret.push(stringify(arr[i], prefix + '[' + i + ']')); - } - return ret.join('&'); -} - -/** - * Stringify the given `obj`. - * - * @param {Object} obj - * @param {String} prefix - * @return {String} - * @api private - */ - -function stringifyObject(obj, prefix) { - var ret = [] - , keys = objectKeys(obj) - , key; - - for (var i = 0, len = keys.length; i < len; ++i) { - key = keys[i]; - if ('' == key) continue; - if (null == obj[key]) { - ret.push(encodeURIComponent(key) + '='); - } else { - ret.push(stringify(obj[key], prefix - ? prefix + '[' + encodeURIComponent(key) + ']' - : encodeURIComponent(key))); - } - } - - return ret.join('&'); -} - -/** - * Set `obj`'s `key` to `val` respecting - * the weird and wonderful syntax of a qs, - * where "foo=bar&foo=baz" becomes an array. - * - * @param {Object} obj - * @param {String} key - * @param {String} val - * @api private - */ - -function set(obj, key, val) { - var v = obj[key]; - if (undefined === v) { - obj[key] = val; - } else if (isArray(v)) { - v.push(val); - } else { - obj[key] = [v, val]; - } -} - -/** - * Locate last brace in `str` within the key. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function lastBraceInKey(str) { - var len = str.length - , brace - , c; - for (var i = 0; i < len; ++i) { - c = str[i]; - if (']' == c) brace = false; - if ('[' == c) brace = true; - if ('=' == c && !brace) return i; - } -} - -/** - * Decode `str`. - * - * @param {String} str - * @return {String} - * @api private - */ - -function decode(str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (err) { - return str; - } -} diff --git a/frontend/express/node_modules/request/node_modules/qs/package.json b/frontend/express/node_modules/request/node_modules/qs/package.json deleted file mode 100644 index d1475f93466..00000000000 --- a/frontend/express/node_modules/request/node_modules/qs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "qs", - "description": "querystring parser", - "version": "0.6.5", - "keywords": [ - "query string", - "parser", - "component" - ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/node-querystring.git" - }, - "devDependencies": { - "mocha": "*", - "expect.js": "*" - }, - "scripts": { - "test": "make test" - }, - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca", - "url": "http://tjholowaychuk.com" - }, - "main": "index", - "engines": { - "node": "*" - }, - "readme": "# node-querystring\n\n query string parser for node and the browser supporting nesting, as it was removed from `0.3.x`, so this library provides the previous and commonly desired behaviour (and twice as fast). Used by [express](http://expressjs.com), [connect](http://senchalabs.github.com/connect) and others.\n\n## Installation\n\n $ npm install qs\n\n## Examples\n\n```js\nvar qs = require('qs');\n\nqs.parse('user[name][first]=Tobi&user[email]=tobi@learnboost.com');\n// => { user: { name: { first: 'Tobi' }, email: 'tobi@learnboost.com' } }\n\nqs.stringify({ user: { name: 'Tobi', email: 'tobi@learnboost.com' }})\n// => user[name]=Tobi&user[email]=tobi%40learnboost.com\n```\n\n## Testing\n\nInstall dev dependencies:\n\n $ npm install -d\n\nand execute:\n\n $ make test\n\nbrowser:\n\n $ open test/browser/index.html\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", - "readmeFilename": "Readme.md", - "bugs": { - "url": "https://github.com/visionmedia/node-querystring/issues" - }, - "_id": "qs@0.6.5", - "_from": "qs@~0.6.0" -} diff --git a/frontend/express/node_modules/request/node_modules/tunnel-agent/LICENSE b/frontend/express/node_modules/request/node_modules/tunnel-agent/LICENSE deleted file mode 100644 index a4a9aee0c2f..00000000000 --- a/frontend/express/node_modules/request/node_modules/tunnel-agent/LICENSE +++ /dev/null @@ -1,55 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and - -You must cause any modified files to carry prominent notices stating that You changed the files; and - -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and - -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/frontend/express/node_modules/request/node_modules/tunnel-agent/README.md b/frontend/express/node_modules/request/node_modules/tunnel-agent/README.md deleted file mode 100644 index bb533d56b1a..00000000000 --- a/frontend/express/node_modules/request/node_modules/tunnel-agent/README.md +++ /dev/null @@ -1,4 +0,0 @@ -tunnel-agent -============ - -HTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module. diff --git a/frontend/express/node_modules/request/node_modules/tunnel-agent/index.js b/frontend/express/node_modules/request/node_modules/tunnel-agent/index.js deleted file mode 100644 index 3f7bbb909fd..00000000000 --- a/frontend/express/node_modules/request/node_modules/tunnel-agent/index.js +++ /dev/null @@ -1,227 +0,0 @@ -'use strict' - -var net = require('net') - , tls = require('tls') - , http = require('http') - , https = require('https') - , events = require('events') - , assert = require('assert') - , util = require('util') - ; - -exports.httpOverHttp = httpOverHttp -exports.httpsOverHttp = httpsOverHttp -exports.httpOverHttps = httpOverHttps -exports.httpsOverHttps = httpsOverHttps - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - return agent -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = http.request - agent.createSocket = createSecureSocket - return agent -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - return agent -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - agent.createSocket = createSecureSocket - return agent -} - - -function TunnelingAgent(options) { - var self = this - self.options = options || {} - self.proxyOptions = self.options.proxy || {} - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets - self.requests = [] - self.sockets = [] - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i] - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1) - pending.request.onSocket(socket) - return - } - } - socket.destroy() - self.removeSocket(socket) - }) -} -util.inherits(TunnelingAgent, events.EventEmitter) - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { - var self = this - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: host, port: port, request: req}) - return - } - - // If we are under maxSockets create a new one. - self.createSocket({host: host, port: port, request: req}, function(socket) { - socket.on('free', onFree) - socket.on('close', onCloseOrRemove) - socket.on('agentRemove', onCloseOrRemove) - req.onSocket(socket) - - function onFree() { - self.emit('free', socket, host, port) - } - - function onCloseOrRemove(err) { - self.removeSocket() - socket.removeListener('free', onFree) - socket.removeListener('close', onCloseOrRemove) - socket.removeListener('agentRemove', onCloseOrRemove) - } - }) -} - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this - var placeholder = {} - self.sockets.push(placeholder) - - var connectOptions = mergeOptions({}, self.proxyOptions, - { method: 'CONNECT' - , path: options.host + ':' + options.port - , agent: false - } - ) - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {} - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64') - } - - debug('making CONNECT request') - var connectReq = self.request(connectOptions) - connectReq.useChunkedEncodingByDefault = false // for v0.6 - connectReq.once('response', onResponse) // for v0.6 - connectReq.once('upgrade', onUpgrade) // for v0.6 - connectReq.once('connect', onConnect) // for v0.7 or later - connectReq.once('error', onError) - connectReq.end() - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head) - }) - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners() - socket.removeAllListeners() - - if (res.statusCode === 200) { - assert.equal(head.length, 0) - debug('tunneling connection has established') - self.sockets[self.sockets.indexOf(placeholder)] = socket - cb(socket) - } else { - debug('tunneling socket could not be established, statusCode=%d', res.statusCode) - var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } - } - - function onError(cause) { - connectReq.removeAllListeners() - - debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) - var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } -} - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) return - - this.sockets.splice(pos, 1) - - var pending = this.requests.shift() - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket) - }) - } -} - -function createSecureSocket(options, cb) { - var self = this - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, - { servername: options.host - , socket: socket - } - )) - cb(secureSocket) - }) -} - - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i] - if (typeof overrides === 'object') { - var keys = Object.keys(overrides) - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j] - if (overrides[k] !== undefined) { - target[k] = overrides[k] - } - } - } - } - return target -} - - -var debug -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments) - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0] - } else { - args.unshift('TUNNEL:') - } - console.error.apply(console, args) - } -} else { - debug = function() {} -} -exports.debug = debug // for test diff --git a/frontend/express/node_modules/request/node_modules/tunnel-agent/package.json b/frontend/express/node_modules/request/node_modules/tunnel-agent/package.json deleted file mode 100644 index 9b14d25863d..00000000000 --- a/frontend/express/node_modules/request/node_modules/tunnel-agent/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com", - "url": "http://www.futurealoof.com" - }, - "name": "tunnel-agent", - "description": "HTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module.", - "version": "0.3.0", - "repository": { - "url": "https://github.com/mikeal/tunnel-agent" - }, - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "readme": "tunnel-agent\n============\n\nHTTP proxy tunneling agent. Formerly part of mikeal/request, now a standalone module.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/mikeal/tunnel-agent/issues" - }, - "_id": "tunnel-agent@0.3.0", - "_from": "tunnel-agent@~0.3.0" -} diff --git a/frontend/express/node_modules/request/oauth.js b/frontend/express/node_modules/request/oauth.js deleted file mode 100644 index f6abae33c1d..00000000000 --- a/frontend/express/node_modules/request/oauth.js +++ /dev/null @@ -1,34 +0,0 @@ -var crypto = require('crypto') - , qs = require('querystring') - ; - -function sha1 (key, body) { - return crypto.createHmac('sha1', key).update(body).digest('base64') -} - -function rfc3986 (str) { - return encodeURIComponent(str) - .replace(/!/g,'%21') - .replace(/\*/g,'%2A') - .replace(/\(/g,'%28') - .replace(/\)/g,'%29') - .replace(/'/g,'%27') - ; -} - -function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret, body) { - // adapted from https://dev.twitter.com/docs/auth/oauth - var base = - (httpMethod || 'GET') + "&" + - encodeURIComponent( base_uri ) + "&" + - Object.keys(params).sort().map(function (i) { - // big WTF here with the escape + encoding but it's what twitter wants - return escape(rfc3986(i)) + "%3D" + escape(rfc3986(params[i])) - }).join("%26") - var key = consumer_secret + '&' - if (token_secret) key += token_secret - return sha1(key, base) -} - -exports.hmacsign = hmacsign -exports.rfc3986 = rfc3986 \ No newline at end of file diff --git a/frontend/express/node_modules/request/package.json b/frontend/express/node_modules/request/package.json deleted file mode 100644 index 0c5156fd305..00000000000 --- a/frontend/express/node_modules/request/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "request", - "description": "Simplified HTTP request client.", - "tags": [ - "http", - "simple", - "util", - "utility" - ], - "version": "2.21.0", - "author": { - "name": "Mikeal Rogers", - "email": "mikeal.rogers@gmail.com" - }, - "repository": { - "type": "git", - "url": "http://github.com/mikeal/request.git" - }, - "bugs": { - "url": "http://github.com/mikeal/request/issues" - }, - "engines": [ - "node >= 0.8.0" - ], - "main": "index.js", - "dependencies": { - "qs": "~0.6.0", - "json-stringify-safe": "~4.0.0", - "forever-agent": "~0.5.0", - "tunnel-agent": "~0.3.0", - "http-signature": "~0.9.11", - "hawk": "~0.13.0", - "aws-sign": "~0.3.0", - "oauth-sign": "~0.3.0", - "cookie-jar": "~0.3.0", - "node-uuid": "~1.4.0", - "mime": "~1.2.9", - "form-data": "0.0.8" - }, - "scripts": { - "test": "node tests/run.js" - }, - "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n
    \n  npm install request\n
    \n\nOr from source:\n\n
    \n  git clone git://github.com/mikeal/request.git \n  cd request\n  npm link\n
    \n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## Forms\n\n`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.\n\nUrl encoded forms are simple\n\n```javascript\nrequest.post('http://service.com/upload', {form:{key:'value'}})\n// or\nrequest.post('http://service.com/upload').form({key:'value'})\n```\n\nFor `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.\n\n```javascript\nvar r = request.post('http://service.com/upload')\nvar form = r.form()\nform.append('my_field', 'my_value')\nform.append('my_buffer', new Buffer([1, 2, 3]))\nform.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))\nform.append('remote_file', request('http://google.com/doodle.png'))\n```\n\n## HTTP Authentication\n\n```javascript\nrequest.auth('username', 'password', false).get('http://some.server.com/');\n// or\nrequest.get('http://some.server.com/', {\n 'auth': {\n 'user': 'username',\n 'pass': 'password',\n 'sendImmediately': false\n }\n});\n```\n\nIf passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`.\n\n`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method).\n\nDigest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail).\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Ideally, you would take the body in the response\n // and construct a URL that a user clicks on (like a sign in button).\n // The verifier is only available in the response after a user has \n // verified with twitter that they are authorizing your app.\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: access_token.oauth_verifier\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string.\n* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.\n* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example).\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)\n* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options.\n* `localAddress` - Local interface to bind for network connections.\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.patch\n\nSame as request() but defaults to `method: \"PATCH\"`.\n\n```javascript\nrequest.patch(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", - "readmeFilename": "README.md", - "_id": "request@2.21.0", - "_from": "request@2.21.0" -} diff --git a/frontend/express/node_modules/request/tests/googledoodle.jpg b/frontend/express/node_modules/request/tests/googledoodle.jpg deleted file mode 100644 index f80c9c52d3c..00000000000 Binary files a/frontend/express/node_modules/request/tests/googledoodle.jpg and /dev/null differ diff --git a/frontend/express/node_modules/request/tests/googledoodle.png b/frontend/express/node_modules/request/tests/googledoodle.png deleted file mode 100644 index f80c9c52d3c..00000000000 Binary files a/frontend/express/node_modules/request/tests/googledoodle.png and /dev/null differ diff --git a/frontend/express/node_modules/request/tests/run.js b/frontend/express/node_modules/request/tests/run.js deleted file mode 100644 index e717f02a31b..00000000000 --- a/frontend/express/node_modules/request/tests/run.js +++ /dev/null @@ -1,40 +0,0 @@ -var spawn = require('child_process').spawn - , exitCode = 0 - , timeout = 10000 - , fs = require('fs') - ; - -fs.readdir(__dirname, function (e, files) { - if (e) throw e - - var tests = files.filter(function (f) {return f.slice(0, 'test-'.length) === 'test-'}) - - var next = function () { - if (tests.length === 0) process.exit(exitCode); - - var file = tests.shift() - console.log(file) - var proc = spawn('node', [ 'tests/' + file ]) - - var killed = false - var t = setTimeout(function () { - proc.kill() - exitCode += 1 - console.error(file + ' timeout') - killed = true - }, timeout) - - proc.stdout.pipe(process.stdout) - proc.stderr.pipe(process.stderr) - proc.on('exit', function (code) { - if (code && !killed) console.error(file + ' failed') - exitCode += code || 0 - clearTimeout(t) - next() - }) - } - next() - -}) - - diff --git a/frontend/express/node_modules/request/tests/server.js b/frontend/express/node_modules/request/tests/server.js deleted file mode 100644 index b6eacbadc05..00000000000 --- a/frontend/express/node_modules/request/tests/server.js +++ /dev/null @@ -1,90 +0,0 @@ -var fs = require('fs') - , http = require('http') - , path = require('path') - , https = require('https') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - ; - -exports.createServer = function (port) { - port = port || 6767 - var s = http.createServer(function (req, resp) { - s.emit(req.url, req, resp); - }) - s.port = port - s.url = 'http://localhost:'+port - return s; -} - -exports.createSSLServer = function(port, opts) { - port = port || 16767 - - var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') - , 'cert': path.join(__dirname, 'ssl', 'test.crt') - } - if (opts) { - for (var i in opts) options[i] = opts[i] - } - - for (var i in options) { - options[i] = fs.readFileSync(options[i]) - } - - var s = https.createServer(options, function (req, resp) { - s.emit(req.url, req, resp); - }) - s.port = port - s.url = 'https://localhost:'+port - return s; -} - -exports.createPostStream = function (text) { - var postStream = new stream.Stream(); - postStream.writeable = true; - postStream.readable = true; - setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0); - return postStream; -} -exports.createPostValidator = function (text, reqContentType) { - var l = function (req, resp) { - var r = ''; - req.on('data', function (chunk) {r += chunk}) - req.on('end', function () { - if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) { - var boundary = req.headers['content-type'].split('boundary=')[1]; - text = text.replace(/__BOUNDARY__/g, boundary); - } - if (r !== text) console.log(r, text); - assert.equal(r, text) - if (reqContentType) { - assert.ok(req.headers['content-type']) - assert.ok(~req.headers['content-type'].indexOf(reqContentType)) - } - resp.writeHead(200, {'content-type':'text/plain'}) - resp.write('OK') - resp.end() - }) - } - return l; -} -exports.createGetResponse = function (text, contentType) { - var l = function (req, resp) { - contentType = contentType || 'text/plain' - resp.writeHead(200, {'content-type':contentType}) - resp.write(text) - resp.end() - } - return l; -} -exports.createChunkResponse = function (chunks, contentType) { - var l = function (req, resp) { - contentType = contentType || 'text/plain' - resp.writeHead(200, {'content-type':contentType}) - chunks.forEach(function (chunk) { - resp.write(chunk) - }) - resp.end() - } - return l; -} diff --git a/frontend/express/node_modules/request/tests/squid.conf b/frontend/express/node_modules/request/tests/squid.conf deleted file mode 100644 index 0d4a3b6fe7a..00000000000 --- a/frontend/express/node_modules/request/tests/squid.conf +++ /dev/null @@ -1,77 +0,0 @@ -# -# Recommended minimum configuration: -# -acl manager proto cache_object -acl localhost src 127.0.0.1/32 ::1 -acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 - -# Example rule allowing access from your local networks. -# Adapt to list your (internal) IP networks from where browsing -# should be allowed -acl localnet src 10.0.0.0/8 # RFC1918 possible internal network -acl localnet src 172.16.0.0/12 # RFC1918 possible internal network -acl localnet src 192.168.0.0/16 # RFC1918 possible internal network -acl localnet src fc00::/7 # RFC 4193 local private network range -acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines - -acl SSL_ports port 443 -acl Safe_ports port 80 # http -acl Safe_ports port 21 # ftp -acl Safe_ports port 443 # https -acl Safe_ports port 70 # gopher -acl Safe_ports port 210 # wais -acl Safe_ports port 1025-65535 # unregistered ports -acl Safe_ports port 280 # http-mgmt -acl Safe_ports port 488 # gss-http -acl Safe_ports port 591 # filemaker -acl Safe_ports port 777 # multiling http -acl CONNECT method CONNECT - -# -# Recommended minimum Access Permission configuration: -# -# Only allow cachemgr access from localhost -http_access allow manager localhost -http_access deny manager - -# Deny requests to certain unsafe ports -http_access deny !Safe_ports - -# Deny CONNECT to other than secure SSL ports -#http_access deny CONNECT !SSL_ports - -# We strongly recommend the following be uncommented to protect innocent -# web applications running on the proxy server who think the only -# one who can access services on "localhost" is a local user -#http_access deny to_localhost - -# -# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS -# - -# Example rule allowing access from your local networks. -# Adapt localnet in the ACL section to list your (internal) IP networks -# from where browsing should be allowed -http_access allow localnet -http_access allow localhost - -# And finally deny all other access to this proxy -http_access deny all - -# Squid normally listens to port 3128 -http_port 3128 - -# We recommend you to use at least the following line. -hierarchy_stoplist cgi-bin ? - -# Uncomment and adjust the following to add a disk cache directory. -#cache_dir ufs /usr/local/var/cache 100 16 256 - -# Leave coredumps in the first cache dir -coredump_dir /usr/local/var/cache - -# Add any of your own refresh_pattern entries above these. -refresh_pattern ^ftp: 1440 20% 10080 -refresh_pattern ^gopher: 1440 0% 1440 -refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 -refresh_pattern . 0 20% 4320 diff --git a/frontend/express/node_modules/request/tests/ssl/ca/ca.cnf b/frontend/express/node_modules/request/tests/ssl/ca/ca.cnf deleted file mode 100644 index 425a889156b..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/ca.cnf +++ /dev/null @@ -1,20 +0,0 @@ -[ req ] -default_bits = 1024 -days = 3650 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no -output_password = password - -[ req_distinguished_name ] -C = US -ST = CA -L = Oakland -O = request -OU = request Certificate Authority -CN = requestCA -emailAddress = mikeal@mikealrogers.com - -[ req_attributes ] -challengePassword = password challenge - diff --git a/frontend/express/node_modules/request/tests/ssl/ca/ca.crt b/frontend/express/node_modules/request/tests/ssl/ca/ca.crt deleted file mode 100644 index b4524e44baa..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/ca.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 -ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG -A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n -ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT -B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl -YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4 -5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ -5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD -xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB -ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm -D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo -88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj ------END CERTIFICATE----- diff --git a/frontend/express/node_modules/request/tests/ssl/ca/ca.csr b/frontend/express/node_modules/request/tests/ssl/ca/ca.csr deleted file mode 100644 index e48c56eefee..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/ca.csr +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE -BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD -ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG -SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0 -deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br -44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB -AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3 -DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj -bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia -SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X ------END CERTIFICATE REQUEST----- diff --git a/frontend/express/node_modules/request/tests/ssl/ca/ca.key b/frontend/express/node_modules/request/tests/ssl/ca/ca.key deleted file mode 100644 index a53e7f75d66..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/ca.key +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,C8B5887048377F02 - -nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q -nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+ -GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH -gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38 -VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3 -/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb -4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U -gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR -Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh -FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf -dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC -uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb -EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w== ------END RSA PRIVATE KEY----- diff --git a/frontend/express/node_modules/request/tests/ssl/ca/ca.srl b/frontend/express/node_modules/request/tests/ssl/ca/ca.srl deleted file mode 100644 index 17128db3ac4..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/ca.srl +++ /dev/null @@ -1 +0,0 @@ -ADF62016AA40C9C3 diff --git a/frontend/express/node_modules/request/tests/ssl/ca/server.cnf b/frontend/express/node_modules/request/tests/ssl/ca/server.cnf deleted file mode 100644 index cd1fd1e396b..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/server.cnf +++ /dev/null @@ -1,19 +0,0 @@ -[ req ] -default_bits = 1024 -days = 3650 -distinguished_name = req_distinguished_name -attributes = req_attributes -prompt = no - -[ req_distinguished_name ] -C = US -ST = CA -L = Oakland -O = request -OU = testing -CN = testing.request.mikealrogers.com -emailAddress = mikeal@mikealrogers.com - -[ req_attributes ] -challengePassword = password challenge - diff --git a/frontend/express/node_modules/request/tests/ssl/ca/server.crt b/frontend/express/node_modules/request/tests/ssl/ca/server.crt deleted file mode 100644 index efe96cefc3a..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/server.crt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICejCCAeMCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1 -ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG -A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n -ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGjMQswCQYD -VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT -B3JlcXVlc3QxEDAOBgNVBAsTB3Rlc3RpbmcxKTAnBgNVBAMTIHRlc3RpbmcucmVx -dWVzdC5taWtlYWxyb2dlcnMuY29tMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlr -ZWFscm9nZXJzLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgVl0jMumvOpmM -20W5v9yhGgZj8hPhEQF/N7yCBVBn/rWGYm70IHC8T/pR5c0LkWc5gdnCJEvKWQjh -DBKxZD8FAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEABShRkNgFbgs4vUWW9R9deNJj -7HJoiTmvkmoOC7QzcYkjdgHbOxsSq3rBnwxsVjY9PAtPwBn0GRspOeG7KzKRgySB -kb22LyrCFKbEOfKO/+CJc80ioK9zEPVjGsFMyAB+ftYRqM+s/4cQlTg/m89l01wC -yapjN3RxZbInGhWR+jA= ------END CERTIFICATE----- diff --git a/frontend/express/node_modules/request/tests/ssl/ca/server.csr b/frontend/express/node_modules/request/tests/ssl/ca/server.csr deleted file mode 100644 index a8e7595a561..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/server.csr +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBgjCCASwCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE -BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEQMA4GA1UECxMHdGVzdGluZzEp -MCcGA1UEAxMgdGVzdGluZy5yZXF1ZXN0Lm1pa2VhbHJvZ2Vycy5jb20xJjAkBgkq -hkiG9w0BCQEWF21pa2VhbEBtaWtlYWxyb2dlcnMuY29tMFwwDQYJKoZIhvcNAQEB -BQADSwAwSAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg -cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAaAjMCEGCSqGSIb3DQEJBzEU -ExJwYXNzd29yZCBjaGFsbGVuZ2UwDQYJKoZIhvcNAQEFBQADQQBD3E5WekQzCEJw -7yOcqvtPYIxGaX8gRKkYfLPoj3pm3GF5SGqtJKhylKfi89szHXgktnQgzff9FN+A -HidVJ/3u ------END CERTIFICATE REQUEST----- diff --git a/frontend/express/node_modules/request/tests/ssl/ca/server.js b/frontend/express/node_modules/request/tests/ssl/ca/server.js deleted file mode 100644 index 05e21c1162c..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/server.js +++ /dev/null @@ -1,28 +0,0 @@ -var fs = require("fs") -var https = require("https") -var options = { key: fs.readFileSync("./server.key") - , cert: fs.readFileSync("./server.crt") } - -var server = https.createServer(options, function (req, res) { - res.writeHead(200) - res.end() - server.close() -}) -server.listen(1337) - -var ca = fs.readFileSync("./ca.crt") -var agent = new https.Agent({ host: "localhost", port: 1337, ca: ca }) - -https.request({ host: "localhost" - , method: "HEAD" - , port: 1337 - , headers: { host: "testing.request.mikealrogers.com" } - , agent: agent - , ca: [ ca ] - , path: "/" }, function (res) { - if (res.client.authorized) { - console.log("node test: OK") - } else { - throw new Error(res.client.authorizationError) - } -}).end() diff --git a/frontend/express/node_modules/request/tests/ssl/ca/server.key b/frontend/express/node_modules/request/tests/ssl/ca/server.key deleted file mode 100644 index 72d86984f18..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/ca/server.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBOwIBAAJBAOBWXSMy6a86mYzbRbm/3KEaBmPyE+ERAX83vIIFUGf+tYZibvQg -cLxP+lHlzQuRZzmB2cIkS8pZCOEMErFkPwUCAwEAAQJAK+r8ZM2sze8s7FRo/ApB -iRBtO9fCaIdJwbwJnXKo4RKwZDt1l2mm+fzZ+/QaQNjY1oTROkIIXmnwRvZWfYlW -gQIhAPKYsG+YSBN9o8Sdp1DMyZ/rUifKX3OE6q9tINkgajDVAiEA7Ltqh01+cnt0 -JEnud/8HHcuehUBLMofeg0G+gCnSbXECIQCqDvkXsWNNLnS/3lgsnvH0Baz4sbeJ -rjIpuVEeg8eM5QIgbu0+9JmOV6ybdmmiMV4yAncoF35R/iKGVHDZCAsQzDECIQDZ -0jGz22tlo5YMcYSqrdD3U4sds1pwiAaWFRbCunoUJw== ------END RSA PRIVATE KEY----- diff --git a/frontend/express/node_modules/request/tests/ssl/npm-ca.crt b/frontend/express/node_modules/request/tests/ssl/npm-ca.crt deleted file mode 100644 index fde2fe933d8..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/npm-ca.crt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIChzCCAfACCQDauvz/KHp8ejANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMC -VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMQwwCgYDVQQKEwNucG0x -IjAgBgNVBAsTGW5wbSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxDjAMBgNVBAMTBW5w -bUNBMRcwFQYJKoZIhvcNAQkBFghpQGl6cy5tZTAeFw0xMTA5MDUwMTQ3MTdaFw0y -MTA5MDIwMTQ3MTdaMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNV -BAcTB09ha2xhbmQxDDAKBgNVBAoTA25wbTEiMCAGA1UECxMZbnBtIENlcnRpZmlj -YXRlIEF1dGhvcml0eTEOMAwGA1UEAxMFbnBtQ0ExFzAVBgkqhkiG9w0BCQEWCGlA -aXpzLm1lMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLI4tIqPpRW+ACw9GE -OgBlJZwK5f8nnKCLK629Pv5yJpQKs3DENExAyOgDcyaF0HD0zk8zTp+ZsLaNdKOz -Gn2U181KGprGKAXP6DU6ByOJDWmTlY6+Ad1laYT0m64fERSpHw/hjD3D+iX4aMOl -y0HdbT5m1ZGh6SJz3ZqxavhHLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAC4ySDbC -l7W1WpLmtLGEQ/yuMLUf6Jy/vr+CRp4h+UzL+IQpCv8FfxsYE7dhf/bmWTEupBkv -yNL18lipt2jSvR3v6oAHAReotvdjqhxddpe5Holns6EQd1/xEZ7sB1YhQKJtvUrl -ZNufy1Jf1r0ldEGeA+0ISck7s+xSh9rQD2Op ------END CERTIFICATE----- diff --git a/frontend/express/node_modules/request/tests/ssl/test.crt b/frontend/express/node_modules/request/tests/ssl/test.crt deleted file mode 100644 index b357f8641f3..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/test.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICQzCCAawCCQCO/XWtRFck1jANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJU -SDEQMA4GA1UECBMHQmFuZ2tvazEOMAwGA1UEBxMFU2lsb20xGzAZBgNVBAoTElRo -ZSBSZXF1ZXN0IE1vZHVsZTEYMBYGA1UEAxMPcmVxdWVzdC5leGFtcGxlMB4XDTEx -MTIwMzAyMjkyM1oXDTIxMTEzMDAyMjkyM1owZjELMAkGA1UEBhMCVEgxEDAOBgNV -BAgTB0Jhbmdrb2sxDjAMBgNVBAcTBVNpbG9tMRswGQYDVQQKExJUaGUgUmVxdWVz -dCBNb2R1bGUxGDAWBgNVBAMTD3JlcXVlc3QuZXhhbXBsZTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwmctddZqlA48+NXs0yOy92DijcQV1jf87zMiYAIlNUto -wghVbTWgJU5r0pdKrD16AptnWJTzKanhItEX8XCCPgsNkq1afgTtJP7rNkwu3xcj -eIMkhJg/ay4ZnkbnhYdsii5VTU5prix6AqWRAhbkBgoA+iVyHyof8wvZyKBoFTMC -AwEAATANBgkqhkiG9w0BAQUFAAOBgQB6BybMJbpeiABgihDfEVBcAjDoQ8gUMgwV -l4NulugfKTDmArqnR9aPd4ET5jX5dkMP4bwCHYsvrcYDeWEQy7x5WWuylOdKhua4 -L4cEi2uDCjqEErIG3cc1MCOk6Cl6Ld6tkIzQSf953qfdEACRytOeUqLNQcrXrqeE -c7U8F6MWLQ== ------END CERTIFICATE----- diff --git a/frontend/express/node_modules/request/tests/ssl/test.key b/frontend/express/node_modules/request/tests/ssl/test.key deleted file mode 100644 index b85810dda8b..00000000000 --- a/frontend/express/node_modules/request/tests/ssl/test.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXgIBAAKBgQDCZy111mqUDjz41ezTI7L3YOKNxBXWN/zvMyJgAiU1S2jCCFVt -NaAlTmvSl0qsPXoCm2dYlPMpqeEi0RfxcII+Cw2SrVp+BO0k/us2TC7fFyN4gySE -mD9rLhmeRueFh2yKLlVNTmmuLHoCpZECFuQGCgD6JXIfKh/zC9nIoGgVMwIDAQAB -AoGBALXFwfUf8vHTSmGlrdZS2AGFPvEtuvldyoxi9K5u8xmdFCvxnOcLsF2RsTHt -Mu5QYWhUpNJoG+IGLTPf7RJdj/kNtEs7xXqWy4jR36kt5z5MJzqiK+QIgiO9UFWZ -fjUb6oeDnTIJA9YFBdYi97MDuL89iU/UK3LkJN3hd4rciSbpAkEA+MCkowF5kSFb -rkOTBYBXZfiAG78itDXN6DXmqb9XYY+YBh3BiQM28oxCeQYyFy6pk/nstnd4TXk6 -V/ryA2g5NwJBAMgRKTY9KvxJWbESeMEFe2iBIV0c26/72Amgi7ZKUCLukLfD4tLF -+WSZdmTbbqI1079YtwaiOVfiLm45Q/3B0eUCQAaQ/0eWSGE+Yi8tdXoVszjr4GXb -G81qBi91DMu6U1It+jNfIba+MPsiHLcZJMVb4/oWBNukN7bD1nhwFWdlnu0CQQCf -Is9WHkdvz2RxbZDxb8verz/7kXXJQJhx5+rZf7jIYFxqX3yvTNv3wf2jcctJaWlZ -fVZwB193YSivcgt778xlAkEAprYUz3jczjF5r2hrgbizPzPDR94tM5BTO3ki2v3w -kbf+j2g7FNAx6kZiVN8XwfLc8xEeUGiPKwtq3ddPDFh17w== ------END RSA PRIVATE KEY----- diff --git a/frontend/express/node_modules/request/tests/test-basic-auth.js b/frontend/express/node_modules/request/tests/test-basic-auth.js deleted file mode 100644 index 3f4804883f7..00000000000 --- a/frontend/express/node_modules/request/tests/test-basic-auth.js +++ /dev/null @@ -1,143 +0,0 @@ -var assert = require('assert') - , http = require('http') - , request = require('../index') - ; - -var numBasicRequests = 0; - -var basicServer = http.createServer(function (req, res) { - console.error('Basic auth server: ', req.method, req.url); - numBasicRequests++; - - var ok; - - if (req.headers.authorization) { - if (req.headers.authorization == 'Basic ' + new Buffer('test:testing2').toString('base64')) { - ok = true; - } else if ( req.headers.authorization == 'Basic ' + new Buffer(':apassword').toString('base64')) { - ok = true; - } else { - // Bad auth header, don't send back WWW-Authenticate header - ok = false; - } - } else { - // No auth header, send back WWW-Authenticate header - ok = false; - res.setHeader('www-authenticate', 'Basic realm="Private"'); - } - - if (req.url == '/post/') { - var expectedContent = 'data_key=data_value'; - req.on('data', function(data) { - assert.equal(data, expectedContent); - console.log('received request data: ' + data); - }); - assert.equal(req.method, 'POST'); - assert.equal(req.headers['content-length'], '' + expectedContent.length); - assert.equal(req.headers['content-type'], 'application/x-www-form-urlencoded; charset=utf-8'); - } - - if (ok) { - console.log('request ok'); - res.end('ok'); - } else { - console.log('status=401'); - res.statusCode = 401; - res.end('401'); - } -}); - -basicServer.listen(6767); - -var tests = [ - function(next) { - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing2', - 'sendImmediately': false - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 2); - next(); - }); - }, - - function(next) { - // If we don't set sendImmediately = false, request will send basic auth - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test2/', - 'auth': { - 'user': 'test', - 'pass': 'testing2' - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 3); - next(); - }); - }, - - function(next) { - request({ - 'method': 'GET', - 'uri': 'http://test:testing2@localhost:6767/test2/' - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 4); - next(); - }); - }, - - function(next) { - request({ - 'method': 'POST', - 'form': { 'data_key': 'data_value' }, - 'uri': 'http://localhost:6767/post/', - 'auth': { - 'user': 'test', - 'pass': 'testing2', - 'sendImmediately': false - } - }, function(error, res, body) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 6); - next(); - }); - }, - - function(next) { - assert.doesNotThrow( function() { - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/allow_empty_user/', - 'auth': { - 'user': '', - 'pass': 'apassword', - 'sendImmediately': false - } - }, function(error, res, body ) { - assert.equal(res.statusCode, 200); - assert.equal(numBasicRequests, 8); - next(); - }); - }) - } -]; - -function runTest(i) { - if (i < tests.length) { - tests[i](function() { - runTest(i + 1); - }); - } else { - console.log('All tests passed'); - basicServer.close(); - } -} - -runTest(0); diff --git a/frontend/express/node_modules/request/tests/test-body.js b/frontend/express/node_modules/request/tests/test-body.js deleted file mode 100644 index 186de123f6f..00000000000 --- a/frontend/express/node_modules/request/tests/test-body.js +++ /dev/null @@ -1,122 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetBuffer : - { resp : server.createGetResponse(new Buffer("TESTING!")) - , encoding: null - , expectBody: new Buffer("TESTING!") - } - , testGetEncoding : - { resp : server.createGetResponse(new Buffer('efa3bfcea9e29883', 'hex')) - , encoding: 'hex' - , expectBody: "efa3bfcea9e29883" - } - , testGetUTF8: - { resp: server.createGetResponse(new Buffer([0xEF, 0xBB, 0xBF, 226, 152, 131])) - , encoding: "utf8" - , expectBody: "☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - , testPutMultipartPreambleCRLF : - { resp: server.createPostValidator( - '\r\n--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , preambleCRLF: true - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) - diff --git a/frontend/express/node_modules/request/tests/test-cookie.js b/frontend/express/node_modules/request/tests/test-cookie.js deleted file mode 100644 index 6c6a7a7798c..00000000000 --- a/frontend/express/node_modules/request/tests/test-cookie.js +++ /dev/null @@ -1,29 +0,0 @@ -var Cookie = require('../vendor/cookie') - , assert = require('assert'); - -var str = 'Sid="s543qactge.wKE61E01Bs%2BKhzmxrwrnug="; Path=/; httpOnly; Expires=Sat, 04 Dec 2010 23:27:28 GMT'; -var cookie = new Cookie(str); - -// test .toString() -assert.equal(cookie.toString(), str); - -// test .path -assert.equal(cookie.path, '/'); - -// test .httpOnly -assert.equal(cookie.httpOnly, true); - -// test .name -assert.equal(cookie.name, 'Sid'); - -// test .value -assert.equal(cookie.value, '"s543qactge.wKE61E01Bs%2BKhzmxrwrnug="'); - -// test .expires -assert.equal(cookie.expires instanceof Date, true); - -// test .path default -var cookie = new Cookie('foo=bar', { url: 'http://foo.com/bar' }); -assert.equal(cookie.path, '/bar'); - -console.log('All tests passed'); diff --git a/frontend/express/node_modules/request/tests/test-cookiejar.js b/frontend/express/node_modules/request/tests/test-cookiejar.js deleted file mode 100644 index 76fcd716122..00000000000 --- a/frontend/express/node_modules/request/tests/test-cookiejar.js +++ /dev/null @@ -1,90 +0,0 @@ -var Cookie = require('../vendor/cookie') - , Jar = require('../vendor/cookie/jar') - , assert = require('assert'); - -function expires(ms) { - return new Date(Date.now() + ms).toUTCString(); -} - -// test .get() expiration -(function() { - var jar = new Jar; - var cookie = new Cookie('sid=1234; path=/; expires=' + expires(1000)); - jar.add(cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], cookie); - setTimeout(function(){ - var cookies = jar.get({ url: 'http://foo.com/foo' }); - assert.equal(cookies.length, 0); - }, 1000); - }, 5); -})(); - -// test .get() path support -(function() { - var jar = new Jar; - var a = new Cookie('sid=1234; path=/'); - var b = new Cookie('sid=1111; path=/foo/bar'); - var c = new Cookie('sid=2222; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - - // should remove the duplicates - assert.equal(jar.cookies.length, 2); - - // same name, same path, latter prevails - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], c); - - // same name, diff path, path specifity prevails, latter prevails - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], a); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], b); - - var jar = new Jar; - var a = new Cookie('sid=1111; path=/foo/bar'); - var b = new Cookie('sid=3333; path=/foo/bar'); - var c = new Cookie('pid=3333; path=/foo/bar'); - var d = new Cookie('sid=2222; path=/foo/'); - var e = new Cookie('sid=1234; path=/'); - jar.add(a); - jar.add(b); - jar.add(c); - jar.add(d); - jar.add(e); - - var cookies = jar.get({ url: 'http://foo.com/foo/bar' }); - assert.equal(cookies.length, 2); - assert.equal(cookies[0], b); - assert.equal(cookies[1], c); - - var cookies = jar.get({ url: 'http://foo.com/foo/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], d); - - var cookies = jar.get({ url: 'http://foo.com/' }); - assert.equal(cookies.length, 1); - assert.equal(cookies[0], e); -})(); - -setTimeout(function() { - console.log('All tests passed'); -}, 1200); diff --git a/frontend/express/node_modules/request/tests/test-defaults.js b/frontend/express/node_modules/request/tests/test-defaults.js deleted file mode 100644 index f6c40246020..00000000000 --- a/frontend/express/node_modules/request/tests/test-defaults.js +++ /dev/null @@ -1,129 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -s.listen(s.port, function () { - var counter = 0; - s.on('/get', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'GET') - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end('TESTING!'); - }); - - // test get(string, function) - request.defaults({headers:{foo:"bar"}})(s.url + '/get', function (e, r, b){ - if (e) throw e; - assert.deepEqual("TESTING!", b); - counter += 1; - }); - - s.on('/post', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], null); - assert.equal(req.method, 'POST') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) - request.defaults({headers:{foo:"bar"}}).post(s.url + '/post', {json: true}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/patch', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], null); - assert.equal(req.method, 'PATCH') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) - request.defaults({headers:{foo:"bar"}}).patch(s.url + '/patch', {json: true}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/post-body', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers['content-type'], 'application/json'); - assert.equal(req.method, 'POST') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test post(string, object, function) with body - request.defaults({headers:{foo:"bar"}}).post(s.url + '/post-body', {json: true, body:{bar:"baz"}}, function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/del', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'DELETE') - resp.writeHead(200, {'Content-Type': 'application/json'}); - resp.end(JSON.stringify({foo:'bar'})); - }); - - // test .del(string, function) - request.defaults({headers:{foo:"bar"}, json:true}).del(s.url + '/del', function (e, r, b){ - if (e) throw e; - assert.deepEqual('bar', b.foo); - counter += 1; - }); - - s.on('/head', function (req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.method, 'HEAD') - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end(); - }); - - // test head.(object, function) - request.defaults({headers:{foo:"bar"}}).head({uri: s.url + '/head'}, function (e, r, b){ - if (e) throw e; - counter += 1; - }); - - s.on('/get_custom', function(req, resp) { - assert.equal(req.headers.foo, 'bar'); - assert.equal(req.headers.x, 'y'); - resp.writeHead(200, {'Content-Type': 'text/plain'}); - resp.end(); - }); - - // test custom request handler function - var defaultRequest = request.defaults({ - headers:{foo:"bar"} - , body: 'TESTING!' - }, function(uri, options, callback) { - var params = request.initParams(uri, options, callback); - options = params.options; - options.headers.x = 'y'; - - return request(params.uri, params.options, params.callback); - }); - - var msg = 'defaults test failed. head request should throw earlier'; - assert.throws(function() { - defaultRequest.head(s.url + '/get_custom', function(e, r, b) { - throw new Error(msg); - }); - counter+=1; - }, msg); - - defaultRequest.get(s.url + '/get_custom', function(e, r, b) { - if(e) throw e; - counter += 1; - console.log(counter.toString() + " tests passed."); - s.close(); - }); -}) diff --git a/frontend/express/node_modules/request/tests/test-digest-auth.js b/frontend/express/node_modules/request/tests/test-digest-auth.js deleted file mode 100644 index 5f2d6eb7dd0..00000000000 --- a/frontend/express/node_modules/request/tests/test-digest-auth.js +++ /dev/null @@ -1,69 +0,0 @@ -var assert = require('assert') - , http = require('http') - , request = require('../index') - ; - -// Test digest auth -// Using header values captured from interaction with Apache - -var numDigestRequests = 0; - -var digestServer = http.createServer(function (req, res) { - console.error('Digest auth server: ', req.method, req.url); - numDigestRequests++; - - var ok; - - if (req.headers.authorization) { - if (req.headers.authorization == 'Digest username="test", realm="Private", nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93", uri="/test/", qop="auth", response="54753ce37c10cb20b09b769f0bed730e", nc="1", cnonce=""') { - ok = true; - } else { - // Bad auth header, don't send back WWW-Authenticate header - ok = false; - } - } else { - // No auth header, send back WWW-Authenticate header - ok = false; - res.setHeader('www-authenticate', 'Digest realm="Private", nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93", algorithm=MD5, qop="auth"'); - } - - if (ok) { - console.log('request ok'); - res.end('ok'); - } else { - console.log('status=401'); - res.statusCode = 401; - res.end('401'); - } -}); - -digestServer.listen(6767); - -request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing', - 'sendImmediately': false - } -}, function(error, response, body) { - assert.equal(response.statusCode, 200); - assert.equal(numDigestRequests, 2); - - // If we don't set sendImmediately = false, request will send basic auth - request({ - 'method': 'GET', - 'uri': 'http://localhost:6767/test/', - 'auth': { - 'user': 'test', - 'pass': 'testing' - } - }, function(error, response, body) { - assert.equal(response.statusCode, 401); - assert.equal(numDigestRequests, 3); - - console.log('All tests passed'); - digestServer.close(); - }); -}); diff --git a/frontend/express/node_modules/request/tests/test-emptyBody.js b/frontend/express/node_modules/request/tests/test-emptyBody.js deleted file mode 100644 index 338c92e5e6b..00000000000 --- a/frontend/express/node_modules/request/tests/test-emptyBody.js +++ /dev/null @@ -1,20 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200 - resp.end('') -}).listen(8080, function () { - var r = request('http://localhost:8080', function (e, resp, body) { - assert.equal(resp.statusCode, 200) - assert.equal(body, "") - - var r2 = request({ url: 'http://localhost:8080', json: {} }, function (e, resp, body) { - assert.equal(resp.statusCode, 200) - assert.equal(body, undefined) - s.close() - }); - }) -}) diff --git a/frontend/express/node_modules/request/tests/test-errors.js b/frontend/express/node_modules/request/tests/test-errors.js deleted file mode 100644 index 4df1302a095..00000000000 --- a/frontend/express/node_modules/request/tests/test-errors.js +++ /dev/null @@ -1,37 +0,0 @@ -var server = require('./server') - , events = require('events') - , assert = require('assert') - , request = require('../index') - ; - -var local = 'http://localhost:8888/asdf' - -try { - request({uri:local, body:{}}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Argument error, options.body.') -} - -try { - request({uri:local, multipart: 'foo'}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Argument error, options.multipart.') -} - -try { - request({uri:local, multipart: [{}]}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Body attribute missing in multipart.') -} - -try { - request(local, {multipart: [{}]}) - assert.fail("Should have throw") -} catch(e) { - assert.equal(e.message, 'Body attribute missing in multipart.') -} - -console.log("All tests passed.") diff --git a/frontend/express/node_modules/request/tests/test-follow-all-303.js b/frontend/express/node_modules/request/tests/test-follow-all-303.js deleted file mode 100644 index 956e386d14b..00000000000 --- a/frontend/express/node_modules/request/tests/test-follow-all-303.js +++ /dev/null @@ -1,30 +0,0 @@ -var request = require('../index'); -var http = require('http'); -var requests = 0; -var assert = require('assert'); - -var server = http.createServer(function (req, res) { - console.error(req.method, req.url); - requests ++; - - if (req.method === 'POST') { - console.error('send 303'); - res.setHeader('location', req.url); - res.statusCode = 303; - res.end('try again, i guess\n'); - } else { - console.error('send 200') - res.end('ok: ' + requests); - } -}); -server.listen(6767); - -request.post({ url: 'http://localhost:6767/foo', - followAllRedirects: true, - form: { foo: 'bar' } }, function (er, req, body) { - if (er) throw er; - assert.equal(body, 'ok: 2'); - assert.equal(requests, 2); - console.error('ok - ' + process.version); - server.close(); -}); diff --git a/frontend/express/node_modules/request/tests/test-follow-all.js b/frontend/express/node_modules/request/tests/test-follow-all.js deleted file mode 100644 index 035d6326fa4..00000000000 --- a/frontend/express/node_modules/request/tests/test-follow-all.js +++ /dev/null @@ -1,35 +0,0 @@ -var request = require('../index'); -var http = require('http'); -var requests = 0; -var assert = require('assert'); - -var server = http.createServer(function (req, res) { - requests ++; - - // redirect everything 3 times, no matter what. - var c = req.headers.cookie; - - if (!c) c = 0; - else c = +c.split('=')[1] || 0; - - if (c > 3) { - res.end('ok: '+requests); - return; - } - - res.setHeader('set-cookie', 'c=' + (c + 1)); - res.setHeader('location', req.url); - res.statusCode = 302; - res.end('try again, i guess\n'); -}); -server.listen(6767); - -request.post({ url: 'http://localhost:6767/foo', - followAllRedirects: true, - form: { foo: 'bar' } }, function (er, req, body) { - if (er) throw er; - assert.equal(body, 'ok: 5'); - assert.equal(requests, 5); - console.error('ok - ' + process.version); - server.close(); -}); diff --git a/frontend/express/node_modules/request/tests/test-form.js b/frontend/express/node_modules/request/tests/test-form.js deleted file mode 100644 index 91b9230d42d..00000000000 --- a/frontend/express/node_modules/request/tests/test-form.js +++ /dev/null @@ -1,79 +0,0 @@ -var assert = require('assert') -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('../index'); -var fs = require('fs'); - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: new Buffer([1, 2, 3])}, - {name: 'my_file', value: fs.createReadStream(__dirname + '/unicycle.jpg')}, - {name: 'remote_file', value: request(remoteFile) } -]; - -var server = http.createServer(function(req, res) { - - // temp workaround - var data = ''; - req.setEncoding('utf8'); - - req.on('data', function(d) { - data += d; - }); - - req.on('end', function() { - // check for the fields' traces - - // 1st field : my_field - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf(field.value) != -1 ); - - // 2nd field : my_buffer - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf(field.value) != -1 ); - - // 3rd field : my_file - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 ); - // check for unicycle.jpg traces - assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 ); - assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 ); - - // 4th field : remote_file - var field = FIELDS.shift(); - assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 ); - assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 ); - // check for http://nodejs.org/images/logo.png traces - assert.ok( data.indexOf('ImageReady') != -1 ); - assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 ); - - res.writeHead(200); - res.end('done'); - - }); - - -}); - -server.listen(8080, function() { - - var req = request.post('http://localhost:8080/upload', function () { - server.close(); - }) - var form = req.form() - - FIELDS.forEach(function(field) { - form.append(field.name, field.value); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/frontend/express/node_modules/request/tests/test-hawk.js b/frontend/express/node_modules/request/tests/test-hawk.js deleted file mode 100644 index 84546258059..00000000000 --- a/frontend/express/node_modules/request/tests/test-hawk.js +++ /dev/null @@ -1,33 +0,0 @@ -var createServer = require('http').createServer - , request = require('../index') - , hawk = require('hawk') - , assert = require('assert') - ; - -var server = createServer(function (req, resp) { - - var getCred = function (id, callback) { - assert.equal(id, 'dh37fgj492je') - var credentials = - { key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn' - , algorithm: 'sha256' - , user: 'Steve' - } - return callback(null, credentials) - } - - hawk.server.authenticate(req, getCred, {}, function (err, credentials, attributes) { - resp.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' }) - resp.end(!err ? 'Hello ' + credentials.user : 'Shoosh!') - }) - -}) - -server.listen(8080, function () { - var creds = {key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', algorithm: 'sha256', id:'dh37fgj492je'} - request('http://localhost:8080', {hawk:{credentials:creds}}, function (e, r, b) { - assert.equal(200, r.statusCode) - assert.equal(b, 'Hello Steve') - server.close() - }) -}) \ No newline at end of file diff --git a/frontend/express/node_modules/request/tests/test-headers.js b/frontend/express/node_modules/request/tests/test-headers.js deleted file mode 100644 index 3982b9be0e5..00000000000 --- a/frontend/express/node_modules/request/tests/test-headers.js +++ /dev/null @@ -1,52 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , Cookie = require('cookie-jar') - , Jar = Cookie.Jar - , s = server.createServer() - -s.listen(s.port, function () { - var serverUri = 'http://localhost:' + s.port - , numTests = 0 - , numOutstandingTests = 0 - - function createTest(requestObj, serverAssertFn) { - var testNumber = numTests; - numTests += 1; - numOutstandingTests += 1; - s.on('/' + testNumber, function (req, res) { - serverAssertFn(req, res); - res.writeHead(200); - res.end(); - }); - requestObj.url = serverUri + '/' + testNumber - request(requestObj, function (err, res, body) { - assert.ok(!err) - assert.equal(res.statusCode, 200) - numOutstandingTests -= 1 - if (numOutstandingTests === 0) { - console.log(numTests + ' tests passed.') - s.close() - } - }) - } - - // Issue #125: headers.cookie shouldn't be replaced when a cookie jar isn't specified - createTest({headers: {cookie: 'foo=bar'}}, function (req, res) { - assert.ok(req.headers.cookie) - assert.equal(req.headers.cookie, 'foo=bar') - }) - - // Issue #125: headers.cookie + cookie jar - var jar = new Jar() - jar.add(new Cookie('quux=baz')); - createTest({jar: jar, headers: {cookie: 'foo=bar'}}, function (req, res) { - assert.ok(req.headers.cookie) - assert.equal(req.headers.cookie, 'foo=bar; quux=baz') - }) - - // There should be no cookie header when neither headers.cookie nor a cookie jar is specified - createTest({}, function (req, res) { - assert.ok(!req.headers.cookie) - }) -}) diff --git a/frontend/express/node_modules/request/tests/test-http-signature.js b/frontend/express/node_modules/request/tests/test-http-signature.js deleted file mode 100644 index 93004732011..00000000000 --- a/frontend/express/node_modules/request/tests/test-http-signature.js +++ /dev/null @@ -1,106 +0,0 @@ -var createServer = require('http').createServer - , request = require('../index') - , httpSignature = require('http-signature') - , assert = require('assert') - ; - -var privateKeyPEMs = {} - -privateKeyPEMs['key-1'] = - '-----BEGIN RSA PRIVATE KEY-----\n' + - 'MIIEpAIBAAKCAQEAzWSJl+Z9Bqv00FVL5N3+JCUoqmQPjIlya1BbeqQroNQ5yG1i\n' + - 'VbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9diDMnrzijAnYlTLOl84CK2vOxkj5b6\n' + - '8zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcuVi2lT9VjygFs1ILG4RyeX1BXUumu\n' + - 'Y8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u114wS7OQPigu6G99dpn/iPHa3zBm8\n' + - '7baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADPTdnO/SO+kvXy7fqd8atSn+HlQcx6\n' + - 'tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft2QIDAQABAoIBAG1exe3/LEBrPLfb\n' + - 'U8iRdY0lxFvHYIhDgIwohC3wUdMYb5SMurpNdEZn+7Sh/fkUVgp/GKJViu1mvh52\n' + - 'bKd2r52DwG9NQBQjVgkqY/auRYSglIPpr8PpYNSZlcneunCDGeqEY9hMmXc5Ssqs\n' + - 'PQYoEKKPN+IlDTg6PguDgAfLR4IUvt9KXVvmB/SSgV9tSeTy35LECt1Lq3ozbUgu\n' + - '30HZI3U6/7H+X22Pxxf8vzBtzkg5rRCLgv+OeNPo16xMnqbutt4TeqEkxRv5rtOo\n' + - '/A1i9khBeki0OJAFJsE82qnaSZodaRsxic59VnN8sWBwEKAt87tEu5A3K3j4XSDU\n' + - '/avZxAECgYEA+pS3DvpiQLtHlaO3nAH6MxHRrREOARXWRDe5nUQuUNpS1xq9wte6\n' + - 'DkFtba0UCvDLic08xvReTCbo9kH0y6zEy3zMpZuJlKbcWCkZf4S5miYPI0RTZtF8\n' + - 'yps6hWqzYFSiO9hMYws9k4OJLxX0x3sLK7iNZ32ujcSrkPBSiBr0gxkCgYEA0dWl\n' + - '637K41AJ/zy0FP0syq+r4eIkfqv+/t6y2aQVUBvxJYrj9ci6XHBqoxpDV8lufVYj\n' + - 'fUAfeI9/MZaWvQJRbnYLre0I6PJfLuCBIL5eflO77BGso165AF7QJZ+fwtgKv3zv\n' + - 'ZX75eudCSS/cFo0po9hlbcLMT4B82zEkgT8E2MECgYEAnz+3/wrdOmpLGiyL2dff\n' + - '3GjsqmJ2VfY8z+niSrI0BSpbD11tT9Ct67VlCBjA7hsOH6uRfpd6/kaUMzzDiFVq\n' + - 'VDAiFvV8QD6zNkwYalQ9aFvbrvwTTPrBpjl0vamMCiJ/YC0cjq1sGr2zh3sar1Ph\n' + - 'S43kP+s97dcZeelhaiJHVrECgYEAsx61q/loJ/LDFeYzs1cLTVn4V7I7hQY9fkOM\n' + - 'WM0AhInVqD6PqdfXfeFYpjJdGisQ7l0BnoGGW9vir+nkcyPvb2PFRIr6+B8tsU5j\n' + - '7BeVgjDoUfQkcrEBK5fEBtnj/ud9BUkY8oMZZBjVNLRuI7IMwZiPvMp0rcj4zAN/\n' + - 'LfUlpgECgYArBvFcBxSkNAzR3Rtteud1YDboSKluRM37Ey5plrn4BS0DD0jm++aD\n' + - '0pG2Hsik000hibw92lCkzvvBVAqF8BuAcnPlAeYfsOaa97PGEjSKEN5bJVWZ9/om\n' + - '9FV1axotRN2XWlwrhixZLEaagkREXhgQc540FS5O8IaI2Vpa80Atzg==\n' + - '-----END RSA PRIVATE KEY-----' - -var publicKeyPEMs = {} - -publicKeyPEMs['key-1'] = - '-----BEGIN PUBLIC KEY-----\n' + - 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzWSJl+Z9Bqv00FVL5N3+\n' + - 'JCUoqmQPjIlya1BbeqQroNQ5yG1iVbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9di\n' + - 'DMnrzijAnYlTLOl84CK2vOxkj5b68zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcu\n' + - 'Vi2lT9VjygFs1ILG4RyeX1BXUumuY8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u1\n' + - '14wS7OQPigu6G99dpn/iPHa3zBm87baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADP\n' + - 'TdnO/SO+kvXy7fqd8atSn+HlQcx6tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft\n' + - '2QIDAQAB\n' + - '-----END PUBLIC KEY-----' - -publicKeyPEMs['key-2'] = - '-----BEGIN PUBLIC KEY-----\n' + - 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqp04VVr9OThli9b35Omz\n' + - 'VqSfWbsoQuRrgyWsrNRn3XkFmbWw4FzZwQ42OgGMzQ84Ta4d9zGKKQyFriTiPjPf\n' + - 'xhhrsaJnDuybcpVhcr7UNKjSZ0S59tU3hpRiEz6hO+Nc/OSSLkvalG0VKrxOln7J\n' + - 'LK/h3rNS/l6wDZ5S/KqsI6CYtV2ZLpn3ahLrizvEYNY038Qcm38qMWx+VJAvZ4di\n' + - 'qqmW7RLIsLT59SWmpXdhFKnkYYGhxrk1Mwl22dBTJNY5SbriU5G3gWgzYkm8pgHr\n' + - '6CtrXch9ciJAcDJehPrKXNvNDOdUh8EW3fekNJerF1lWcwQg44/12v8sDPyfbaKB\n' + - 'dQIDAQAB\n' + - '-----END PUBLIC KEY-----' - -var server = createServer(function (req, res) { - var parsed = httpSignature.parseRequest(req) - var publicKeyPEM = publicKeyPEMs[parsed.keyId] - var verified = httpSignature.verifySignature(parsed, publicKeyPEM) - res.writeHead(verified ? 200 : 400) - res.end() -}) - -server.listen(8080, function () { - function correctKeyTest(callback) { - var options = { - httpSignature: { - keyId: 'key-1', - key: privateKeyPEMs['key-1'] - } - } - request('http://localhost:8080', options, function (e, r, b) { - assert.equal(200, r.statusCode) - callback() - }) - } - - function incorrectKeyTest(callback) { - var options = { - httpSignature: { - keyId: 'key-2', - key: privateKeyPEMs['key-1'] - } - } - request('http://localhost:8080', options, function (e, r, b) { - assert.equal(400, r.statusCode) - callback() - }) - } - - var tests = [correctKeyTest, incorrectKeyTest] - var todo = tests.length; - for(var i = 0; i < tests.length; ++i) { - tests[i](function() { - if(!--todo) { - server.close() - } - }) - } -}) diff --git a/frontend/express/node_modules/request/tests/test-httpModule.js b/frontend/express/node_modules/request/tests/test-httpModule.js deleted file mode 100644 index 2c19615f763..00000000000 --- a/frontend/express/node_modules/request/tests/test-httpModule.js +++ /dev/null @@ -1,94 +0,0 @@ -var http = require('http') - , https = require('https') - , server = require('./server') - , assert = require('assert') - , request = require('../index') - - -var faux_requests_made = {'http':0, 'https':0} -function wrap_request(name, module) { - // Just like the http or https module, but note when a request is made. - var wrapped = {} - Object.keys(module).forEach(function(key) { - var value = module[key]; - - if(key != 'request') - wrapped[key] = value; - else - wrapped[key] = function(options, callback) { - faux_requests_made[name] += 1 - return value.apply(this, arguments) - } - }) - - return wrapped; -} - - -var faux_http = wrap_request('http', http) - , faux_https = wrap_request('https', https) - , plain_server = server.createServer() - , https_server = server.createSSLServer() - - -plain_server.listen(plain_server.port, function() { - plain_server.on('/plain', function (req, res) { - res.writeHead(200) - res.end('plain') - }) - plain_server.on('/to_https', function (req, res) { - res.writeHead(301, {'location':'https://localhost:'+https_server.port + '/https'}) - res.end() - }) - - https_server.listen(https_server.port, function() { - https_server.on('/https', function (req, res) { - res.writeHead(200) - res.end('https') - }) - https_server.on('/to_plain', function (req, res) { - res.writeHead(302, {'location':'http://localhost:'+plain_server.port + '/plain'}) - res.end() - }) - - run_tests() - run_tests({}) - run_tests({'http:':faux_http}) - run_tests({'https:':faux_https}) - run_tests({'http:':faux_http, 'https:':faux_https}) - }) -}) - -function run_tests(httpModules) { - var to_https = 'http://localhost:'+plain_server.port+'/to_https' - var to_plain = 'https://localhost:'+https_server.port+'/to_plain' - - request(to_https, {'httpModules':httpModules, strictSSL:false}, function (er, res, body) { - if (er) throw er - assert.equal(body, 'https', 'Received HTTPS server body') - done() - }) - - request(to_plain, {'httpModules':httpModules, strictSSL:false}, function (er, res, body) { - if (er) throw er - assert.equal(body, 'plain', 'Received HTTPS server body') - done() - }) -} - - -var passed = 0; -function done() { - passed += 1 - var expected = 10 - - if(passed == expected) { - plain_server.close() - https_server.close() - - assert.equal(faux_requests_made.http, 4, 'Wrapped http module called appropriately') - assert.equal(faux_requests_made.https, 4, 'Wrapped https module called appropriately') - - console.log((expected+2) + ' tests passed.') - } -} diff --git a/frontend/express/node_modules/request/tests/test-https-strict.js b/frontend/express/node_modules/request/tests/test-https-strict.js deleted file mode 100644 index d49a9afcb90..00000000000 --- a/frontend/express/node_modules/request/tests/test-https-strict.js +++ /dev/null @@ -1,97 +0,0 @@ -// a test where we validate the siguature of the keys -// otherwise exactly the same as the ssl test - -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , fs = require('fs') - , path = require('path') - , opts = { key: path.resolve(__dirname, 'ssl/ca/server.key') - , cert: path.resolve(__dirname, 'ssl/ca/server.crt') } - , s = server.createSSLServer(null, opts) - , caFile = path.resolve(__dirname, 'ssl/ca/ca.crt') - , ca = fs.readFileSync(caFile) - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - test.strictSSL = true - test.ca = ca - test.headers = { host: 'testing.request.mikealrogers.com' } - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/frontend/express/node_modules/request/tests/test-https.js b/frontend/express/node_modules/request/tests/test-https.js deleted file mode 100644 index b6858d433be..00000000000 --- a/frontend/express/node_modules/request/tests/test-https.js +++ /dev/null @@ -1,87 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - -var s = server.createSSLServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - test.uri = s.url + '/' + i - test.rejectUnauthorized = false - request(test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - console.log(Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/frontend/express/node_modules/request/tests/test-localAddress.js b/frontend/express/node_modules/request/tests/test-localAddress.js deleted file mode 100644 index 11a1bd125ca..00000000000 --- a/frontend/express/node_modules/request/tests/test-localAddress.js +++ /dev/null @@ -1,15 +0,0 @@ -var request = require('../index') - , assert = require('assert') - ; - -request.get({ - uri: 'http://www.google.com', localAddress: '1.2.3.4' // some invalid address -}, function(err, res) { - assert(!res) // asserting that no response received -}) - -request.get({ - uri: 'http://www.google.com', localAddress: '127.0.0.1' -}, function(err, res) { - assert(!res) // asserting that no response received -}) diff --git a/frontend/express/node_modules/request/tests/test-oauth.js b/frontend/express/node_modules/request/tests/test-oauth.js deleted file mode 100644 index 3269483d8f2..00000000000 --- a/frontend/express/node_modules/request/tests/test-oauth.js +++ /dev/null @@ -1,117 +0,0 @@ -var hmacsign = require('oauth-sign').hmacsign - , assert = require('assert') - , qs = require('querystring') - , request = require('../index') - ; - -function getsignature (r) { - var sign - r.headers.Authorization.slice('OAuth '.length).replace(/,\ /g, ',').split(',').forEach(function (v) { - if (v.slice(0, 'oauth_signature="'.length) === 'oauth_signature="') sign = v.slice('oauth_signature="'.length, -1) - }) - return decodeURIComponent(sign) -} - -// Tests from Twitter documentation https://dev.twitter.com/docs/auth/oauth - -var reqsign = hmacsign('POST', 'https://api.twitter.com/oauth/request_token', - { oauth_callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_timestamp: '1272323042' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98") - -console.log(reqsign) -console.log('8wUi7m5HFQy76nowoCThusfgB+Q=') -assert.equal(reqsign, '8wUi7m5HFQy76nowoCThusfgB+Q=') - -var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', - { oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' - , oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , oauth_signature_method: 'HMAC-SHA1' - , oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , oauth_timestamp: '1272323047' - , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , oauth_version: '1.0' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") - -console.log(accsign) -console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') -assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') - -var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', - { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" - , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , oauth_signature_method: "HMAC-SHA1" - , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , oauth_timestamp: "1272325550" - , oauth_version: "1.0" - , status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹' - }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") - -console.log(upsign) -console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') -assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') - - -var rsign = request.post( - { url: 'https://api.twitter.com/oauth/request_token' - , oauth: - { callback: 'http://localhost:3005/the_dance/process_callback?service_provider_id=11' - , consumer_key: 'GDdmIQH6jhtmLUypg82g' - , nonce: 'QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk' - , timestamp: '1272323042' - , version: '1.0' - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - } - }) - -setTimeout(function () { - console.log(getsignature(rsign)) - assert.equal(reqsign, getsignature(rsign)) -}) - -var raccsign = request.post( - { url: 'https://api.twitter.com/oauth/access_token' - , oauth: - { consumer_key: 'GDdmIQH6jhtmLUypg82g' - , nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' - , signature_method: 'HMAC-SHA1' - , token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' - , timestamp: '1272323047' - , verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' - , version: '1.0' - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - , token_secret: "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA" - } - }) - -setTimeout(function () { - console.log(getsignature(raccsign)) - assert.equal(accsign, getsignature(raccsign)) -}, 1) - -var rupsign = request.post( - { url: 'http://api.twitter.com/1/statuses/update.json' - , oauth: - { consumer_key: "GDdmIQH6jhtmLUypg82g" - , nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" - , signature_method: "HMAC-SHA1" - , token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" - , timestamp: "1272325550" - , version: "1.0" - , consumer_secret: "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" - , token_secret: "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA" - } - , form: {status: 'setting up my twitter ç§ã®ã•ãˆãšã‚Šã‚’設定ã™ã‚‹'} - }) -setTimeout(function () { - console.log(getsignature(rupsign)) - assert.equal(upsign, getsignature(rupsign)) -}, 1) - - - - diff --git a/frontend/express/node_modules/request/tests/test-onelineproxy.js b/frontend/express/node_modules/request/tests/test-onelineproxy.js deleted file mode 100644 index c239f8921cf..00000000000 --- a/frontend/express/node_modules/request/tests/test-onelineproxy.js +++ /dev/null @@ -1,46 +0,0 @@ -var http = require('http') - , assert = require('assert') - , request = require('../index') - ; - -var server = http.createServer(function (req, resp) { - resp.statusCode = 200 - if (req.url === '/get') { - assert.equal(req.method, 'GET') - resp.write('content') - resp.end() - return - } - if (req.url === '/put') { - var x = '' - assert.equal(req.method, 'PUT') - req.on('data', function (chunk) { - x += chunk - }) - req.on('end', function () { - assert.equal(x, 'content') - resp.write('success') - resp.end() - }) - return - } - if (req.url === '/proxy') { - assert.equal(req.method, 'PUT') - return req.pipe(request('http://localhost:8080/put')).pipe(resp) - } - - if (req.url === '/test') { - return request('http://localhost:8080/get').pipe(request.put('http://localhost:8080/proxy')).pipe(resp) - } - throw new Error('Unknown url', req.url) -}).listen(8080, function () { - request('http://localhost:8080/test', function (e, resp, body) { - if (e) throw e - if (resp.statusCode !== 200) throw new Error('statusCode not 200 ' + resp.statusCode) - assert.equal(body, 'success') - server.close() - }) -}) - - - diff --git a/frontend/express/node_modules/request/tests/test-params.js b/frontend/express/node_modules/request/tests/test-params.js deleted file mode 100644 index a5831a14071..00000000000 --- a/frontend/express/node_modules/request/tests/test-params.js +++ /dev/null @@ -1,93 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); - -var tests = - { testGet : - { resp : server.createGetResponse("TESTING!") - , expectBody: "TESTING!" - } - , testGetChunkBreak : - { resp : server.createChunkResponse( - [ new Buffer([239]) - , new Buffer([163]) - , new Buffer([191]) - , new Buffer([206]) - , new Buffer([169]) - , new Buffer([226]) - , new Buffer([152]) - , new Buffer([131]) - ]) - , expectBody: "Ω☃" - } - , testGetBuffer : - { resp : server.createGetResponse(new Buffer("TESTING!")) - , encoding: null - , expectBody: new Buffer("TESTING!") - } - , testGetJSON : - { resp : server.createGetResponse('{"test":true}', 'application/json') - , json : true - , expectBody: {"test":true} - } - , testPutString : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : "PUTTINGDATA" - } - , testPutBuffer : - { resp : server.createPostValidator("PUTTINGDATA") - , method : "PUT" - , body : new Buffer("PUTTINGDATA") - } - , testPutJSON : - { resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) - , method: "PUT" - , json: {foo: 'bar'} - } - , testPutMultipart : - { resp: server.createPostValidator( - '--__BOUNDARY__\r\n' + - 'content-type: text/html\r\n' + - '\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__\r\n\r\n' + - 'Oh hi.' + - '\r\n--__BOUNDARY__--' - ) - , method: "PUT" - , multipart: - [ {'content-type': 'text/html', 'body': 'Oh hi.'} - , {'body': 'Oh hi.'} - ] - } - } - -s.listen(s.port, function () { - - var counter = 0 - - for (i in tests) { - (function () { - var test = tests[i] - s.on('/'+i, test.resp) - //test.uri = s.url + '/' + i - request(s.url + '/' + i, test, function (err, resp, body) { - if (err) throw err - if (test.expectBody) { - assert.deepEqual(test.expectBody, body) - } - counter = counter - 1; - if (counter === 0) { - assert.notEqual(typeof test.callback, 'function') - console.log(1 + Object.keys(tests).length+" tests passed.") - s.close() - } - }) - counter++ - })() - } -}) diff --git a/frontend/express/node_modules/request/tests/test-piped-redirect.js b/frontend/express/node_modules/request/tests/test-piped-redirect.js deleted file mode 100644 index e295ec7fa91..00000000000 --- a/frontend/express/node_modules/request/tests/test-piped-redirect.js +++ /dev/null @@ -1,42 +0,0 @@ -var http = require('http') - , assert = require('assert') - , request = require('../index') - ; - -var portOne = 8968 - , portTwo = 8969 - ; - - -// server one -var s1 = http.createServer(function (req, resp) { - if (req.url == '/original') { - resp.writeHeader(302, {'location': '/redirected'}) - resp.end() - } else if (req.url == '/redirected') { - resp.writeHeader(200, {'content-type': 'text/plain'}) - resp.write('OK') - resp.end() - } - -}).listen(portOne); - - -// server two -var s2 = http.createServer(function (req, resp) { - var x = request('http://localhost:'+portOne+'/original') - req.pipe(x) - x.pipe(resp) - -}).listen(portTwo, function () { - var r = request('http://localhost:'+portTwo+'/original', function (err, res, body) { - assert.equal(body, 'OK') - - s1.close() - s2.close() - }); - - // it hangs, so wait a second :) - r.timeout = 1000; - -}) diff --git a/frontend/express/node_modules/request/tests/test-pipes.js b/frontend/express/node_modules/request/tests/test-pipes.js deleted file mode 100644 index 52a15cc7e85..00000000000 --- a/frontend/express/node_modules/request/tests/test-pipes.js +++ /dev/null @@ -1,216 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , fs = require('fs') - , request = require('../index') - , path = require('path') - , util = require('util') - ; - -var s = server.createServer(3453); - -function ValidationStream(str) { - this.str = str - this.buf = '' - this.on('data', function (data) { - this.buf += data - }) - this.on('end', function () { - assert.equal(this.str, this.buf) - }) - this.writable = true -} -util.inherits(ValidationStream, stream.Stream) -ValidationStream.prototype.write = function (chunk) { - this.emit('data', chunk) -} -ValidationStream.prototype.end = function (chunk) { - if (chunk) emit('data', chunk) - this.emit('end') -} - -s.listen(s.port, function () { - counter = 0; - - var check = function () { - counter = counter - 1 - if (counter === 0) { - console.log('All tests passed.') - setTimeout(function () { - process.exit(); - }, 500) - } - } - - // Test pipeing to a request object - s.once('/push', server.createPostValidator("mydata")); - - var mydata = new stream.Stream(); - mydata.readable = true - - counter++ - var r1 = request.put({url:'http://localhost:3453/push'}, function () { - check(); - }) - mydata.pipe(r1) - - mydata.emit('data', 'mydata'); - mydata.emit('end'); - - // Test pipeing to a request object with a json body - s.once('/push-json', server.createPostValidator("{\"foo\":\"bar\"}", "application/json")); - - var mybodydata = new stream.Stream(); - mybodydata.readable = true - - counter++ - var r2 = request.put({url:'http://localhost:3453/push-json',json:true}, function () { - check(); - }) - mybodydata.pipe(r2) - - mybodydata.emit('data', JSON.stringify({foo:"bar"})); - mybodydata.emit('end'); - - // Test pipeing from a request object. - s.once('/pull', server.createGetResponse("mypulldata")); - - var mypulldata = new stream.Stream(); - mypulldata.writable = true - - counter++ - request({url:'http://localhost:3453/pull'}).pipe(mypulldata) - - var d = ''; - - mypulldata.write = function (chunk) { - d += chunk; - } - mypulldata.end = function () { - assert.equal(d, 'mypulldata'); - check(); - }; - - - s.on('/cat', function (req, resp) { - if (req.method === "GET") { - resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); - resp.end('asdf') - } else if (req.method === "PUT") { - assert.equal(req.headers['content-type'], 'text/plain-test'); - assert.equal(req.headers['content-length'], 4) - var validate = ''; - - req.on('data', function (chunk) {validate += chunk}) - req.on('end', function () { - resp.writeHead(201); - resp.end(); - assert.equal(validate, 'asdf'); - check(); - }) - } - }) - s.on('/pushjs', function (req, resp) { - if (req.method === "PUT") { - assert.equal(req.headers['content-type'], 'application/javascript'); - check(); - } - }) - s.on('/catresp', function (req, resp) { - request.get('http://localhost:3453/cat').pipe(resp) - }) - s.on('/doodle', function (req, resp) { - if (req.headers['x-oneline-proxy']) { - resp.setHeader('x-oneline-proxy', 'yup') - } - resp.writeHead('200', {'content-type':'image/jpeg'}) - fs.createReadStream(path.join(__dirname, 'googledoodle.jpg')).pipe(resp) - }) - s.on('/onelineproxy', function (req, resp) { - var x = request('http://localhost:3453/doodle') - req.pipe(x) - x.pipe(resp) - }) - - counter++ - fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) - - counter++ - request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) - - counter++ - request.get('http://localhost:3453/catresp', function (e, resp, body) { - assert.equal(resp.headers['content-type'], 'text/plain-test'); - assert.equal(resp.headers['content-length'], 4) - check(); - }) - - var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.jpg')) - - counter++ - request.get('http://localhost:3453/doodle').pipe(doodleWrite) - - doodleWrite.on('close', function () { - assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')), fs.readFileSync(path.join(__dirname, 'test.jpg'))) - check() - }) - - process.on('exit', function () { - fs.unlinkSync(path.join(__dirname, 'test.jpg')) - }) - - counter++ - request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { - assert.equal(resp.headers['x-oneline-proxy'], 'yup') - check() - }) - - s.on('/afterresponse', function (req, resp) { - resp.write('d') - resp.end() - }) - - counter++ - var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { - var v = new ValidationStream('d') - afterresp.pipe(v) - v.on('end', check) - }) - - s.on('/forward1', function (req, resp) { - resp.writeHead(302, {location:'/forward2'}) - resp.end() - }) - s.on('/forward2', function (req, resp) { - resp.writeHead('200', {'content-type':'image/png'}) - resp.write('d') - resp.end() - }) - - counter++ - var validateForward = new ValidationStream('d') - validateForward.on('end', check) - request.get('http://localhost:3453/forward1').pipe(validateForward) - - // Test pipe options - s.once('/opts', server.createGetResponse('opts response')); - - var optsStream = new stream.Stream(); - optsStream.writable = true - - var optsData = ''; - optsStream.write = function (buf) { - optsData += buf; - if (optsData === 'opts response') { - setTimeout(check, 10); - } - } - - optsStream.end = function () { - assert.fail('end called') - }; - - counter++ - request({url:'http://localhost:3453/opts'}).pipe(optsStream, { end : false }) -}) diff --git a/frontend/express/node_modules/request/tests/test-pool.js b/frontend/express/node_modules/request/tests/test-pool.js deleted file mode 100644 index 791ee8b9398..00000000000 --- a/frontend/express/node_modules/request/tests/test-pool.js +++ /dev/null @@ -1,16 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200; - resp.end('asdf'); -}).listen(8080, function () { - request({'url': 'http://localhost:8080', 'pool': false}, function (e, resp) { - var agent = resp.request.agent; - assert.strictEqual(typeof agent, 'boolean'); - assert.strictEqual(agent, false); - s.close(); - }); -}); \ No newline at end of file diff --git a/frontend/express/node_modules/request/tests/test-protocol-changing-redirect.js b/frontend/express/node_modules/request/tests/test-protocol-changing-redirect.js deleted file mode 100644 index 7e83a41bd90..00000000000 --- a/frontend/express/node_modules/request/tests/test-protocol-changing-redirect.js +++ /dev/null @@ -1,61 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - - -var s = server.createServer() -var ss = server.createSSLServer() -var sUrl = 'http://localhost:' + s.port -var ssUrl = 'https://localhost:' + ss.port - -s.listen(s.port, bouncy(s, ssUrl)) -ss.listen(ss.port, bouncy(ss, sUrl)) - -var hits = {} -var expect = {} -var pending = 0 -function bouncy (s, server) { return function () { - - var redirs = { a: 'b' - , b: 'c' - , c: 'd' - , d: 'e' - , e: 'f' - , f: 'g' - , g: 'h' - , h: 'end' } - - var perm = true - Object.keys(redirs).forEach(function (p) { - var t = redirs[p] - - // switch type each time - var type = perm ? 301 : 302 - perm = !perm - s.on('/' + p, function (req, res) { - res.writeHead(type, { location: server + '/' + t }) - res.end() - }) - }) - - s.on('/end', function (req, res) { - var h = req.headers['x-test-key'] - hits[h] = true - pending -- - if (pending === 0) done() - }) -}} - -for (var i = 0; i < 5; i ++) { - pending ++ - var val = 'test_' + i - expect[val] = true - request({ url: (i % 2 ? sUrl : ssUrl) + '/a' - , headers: { 'x-test-key': val } - , rejectUnauthorized: false }) -} - -function done () { - assert.deepEqual(hits, expect) - process.exit(0) -} diff --git a/frontend/express/node_modules/request/tests/test-proxy.js b/frontend/express/node_modules/request/tests/test-proxy.js deleted file mode 100644 index e183d68d172..00000000000 --- a/frontend/express/node_modules/request/tests/test-proxy.js +++ /dev/null @@ -1,39 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , fs = require('fs') - , request = require('../index') - , path = require('path') - , util = require('util') - ; - -var port = 6768 - , called = false - , proxiedHost = 'google.com' - ; - -var s = server.createServer(port) -s.listen(port, function () { - s.on('http://google.com/', function (req, res) { - called = true - assert.equal(req.headers.host, proxiedHost) - res.writeHeader(200) - res.end() - }) - request ({ - url: 'http://'+proxiedHost, - proxy: 'http://localhost:'+port - /* - //should behave as if these arguments where passed: - url: 'http://localhost:'+port, - headers: {host: proxiedHost} - //*/ - }, function (err, res, body) { - s.close() - }) -}) - -process.on('exit', function () { - assert.ok(called, 'the request must be made to the proxy server') -}) diff --git a/frontend/express/node_modules/request/tests/test-qs.js b/frontend/express/node_modules/request/tests/test-qs.js deleted file mode 100644 index 65958e6a322..00000000000 --- a/frontend/express/node_modules/request/tests/test-qs.js +++ /dev/null @@ -1,42 +0,0 @@ -var request = request = require('../index') - , assert = require('assert') - ; - - -// Test adding a querystring -var req1 = request.get({ uri: 'http://www.google.com', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?q=search', req1.path) -}, 1) - -// Test replacing a querystring value -var req2 = request.get({ uri: 'http://www.google.com?q=abc', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?q=search', req2.path) -}, 1) - -// Test appending a querystring value to the ones present in the uri -var req3 = request.get({ uri: 'http://www.google.com?x=y', qs: { q : 'search' }}) -setTimeout(function() { - assert.equal('/?x=y&q=search', req3.path) -}, 1) - -// Test leaving a querystring alone -var req4 = request.get({ uri: 'http://www.google.com?x=y'}) -setTimeout(function() { - assert.equal('/?x=y', req4.path) -}, 1) - -// Test giving empty qs property -var req5 = request.get({ uri: 'http://www.google.com', qs: {}}) -setTimeout(function(){ - assert.equal('/', req5.path) -}, 1) - - -// Test modifying the qs after creating the request -var req6 = request.get({ uri: 'http://www.google.com', qs: {}}); -req6.qs({ q: "test" }); -process.nextTick(function() { - assert.equal('/?q=test', req6.path); -}); diff --git a/frontend/express/node_modules/request/tests/test-redirect.js b/frontend/express/node_modules/request/tests/test-redirect.js deleted file mode 100644 index cdd46066695..00000000000 --- a/frontend/express/node_modules/request/tests/test-redirect.js +++ /dev/null @@ -1,155 +0,0 @@ -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , Cookie = require('cookie-jar') - , Jar = Cookie.Jar - ; - -var s = server.createServer() - -s.listen(s.port, function () { - var server = 'http://localhost:' + s.port; - var hits = {} - var passed = 0; - - bouncer(301, 'temp') - bouncer(302, 'perm') - bouncer(302, 'nope') - - function bouncer(code, label) { - var landing = label+'_landing'; - - s.on('/'+label, function (req, res) { - hits[label] = true; - res.writeHead(code, { - 'location':server + '/'+landing, - 'set-cookie': 'ham=eggs' - }) - res.end() - }) - - s.on('/'+landing, function (req, res) { - if (req.method !== 'GET') { // We should only accept GET redirects - console.error("Got a non-GET request to the redirect destination URL"); - res.writeHead(400); - res.end(); - return; - } - // Make sure the cookie doesn't get included twice, see #139: - // Make sure cookies are set properly after redirect - assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs'); - hits[landing] = true; - res.writeHead(200) - res.end(landing) - }) - } - - // Permanent bounce - var jar = new Jar() - jar.add(new Cookie('quux=baz')) - request({uri: server+'/perm', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.perm, 'Original request is to /perm') - assert.ok(hits.perm_landing, 'Forward to permanent landing URL') - assert.equal(body, 'perm_landing', 'Got permanent landing content') - passed += 1 - done() - }) - - // Temporary bounce - request({uri: server+'/temp', jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - // Prevent bouncing. - request({uri:server+'/nope', jar: jar, headers: {cookie: 'foo=bar'}, followRedirect:false}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 302) throw new Error('Status is not 302: '+res.statusCode) - assert.ok(hits.nope, 'Original request to /nope') - assert.ok(!hits.nope_landing, 'No chasing the redirect') - assert.equal(res.statusCode, 302, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow post redirects by default - request.post(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when post') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should follow post redirects when followAllRedirects true - request.post({uri:server+'/temp', followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - request.post({uri:server+'/temp', followAllRedirects:false, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow delete redirects by default - request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode < 301) throw new Error('Status is not a redirect.') - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should not follow delete redirects even if followRedirect is set to true - request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 301) throw new Error('Status is not 301: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') - assert.equal(res.statusCode, 301, 'Response is the bounce itself') - passed += 1 - done() - }) - - // Should follow delete redirects when followAllRedirects true - request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { - if (er) throw er - if (res.statusCode !== 200) throw new Error('Status is not 200: '+res.statusCode) - assert.ok(hits.temp, 'Original request is to /temp') - assert.ok(hits.temp_landing, 'Forward to temporary landing URL') - assert.equal(body, 'temp_landing', 'Got temporary landing content') - passed += 1 - done() - }) - - var reqs_done = 0; - function done() { - reqs_done += 1; - if(reqs_done == 9) { - console.log(passed + ' tests passed.') - s.close() - } - } -}) diff --git a/frontend/express/node_modules/request/tests/test-s3.js b/frontend/express/node_modules/request/tests/test-s3.js deleted file mode 100644 index 0f6a832b6da..00000000000 --- a/frontend/express/node_modules/request/tests/test-s3.js +++ /dev/null @@ -1,13 +0,0 @@ -var request = require('../index') - -var r = request.get('https://log.curlybracecast.com.s3.amazonaws.com/', - { aws: - { key: 'AKIAI6KIQRRVMGK3WK5Q' - , secret: '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' - , bucket: 'log.curlybracecast.com' - } - }, function (e, resp, body) { - console.log(r.headers) - console.log(body) - } -) \ No newline at end of file diff --git a/frontend/express/node_modules/request/tests/test-timeout.js b/frontend/express/node_modules/request/tests/test-timeout.js deleted file mode 100644 index 70363670ff8..00000000000 --- a/frontend/express/node_modules/request/tests/test-timeout.js +++ /dev/null @@ -1,87 +0,0 @@ -var server = require('./server') - , events = require('events') - , stream = require('stream') - , assert = require('assert') - , request = require('../index') - ; - -var s = server.createServer(); -var expectedBody = "waited"; -var remainingTests = 5; - -s.listen(s.port, function () { - // Request that waits for 200ms - s.on('/timeout', function (req, resp) { - setTimeout(function(){ - resp.writeHead(200, {'content-type':'text/plain'}) - resp.write(expectedBody) - resp.end() - }, 200); - }); - - // Scenario that should timeout - var shouldTimeout = { - url: s.url + "/timeout", - timeout:100 - } - - - request(shouldTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - - // Scenario that shouldn't timeout - var shouldntTimeout = { - url: s.url + "/timeout", - timeout:300 - } - - request(shouldntTimeout, function (err, resp, body) { - assert.equal(err, null); - assert.equal(expectedBody, body) - checkDone(); - }) - - // Scenario with no timeout set, so shouldn't timeout - var noTimeout = { - url: s.url + "/timeout" - } - - request(noTimeout, function (err, resp, body) { - assert.equal(err); - assert.equal(expectedBody, body) - checkDone(); - }) - - // Scenario with a negative timeout value, should be treated a zero or the minimum delay - var negativeTimeout = { - url: s.url + "/timeout", - timeout:-1000 - } - - request(negativeTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - // Scenario with a float timeout value, should be rounded by setTimeout anyway - var floatTimeout = { - url: s.url + "/timeout", - timeout: 100.76 - } - - request(floatTimeout, function (err, resp, body) { - assert.equal(err.code, "ETIMEDOUT"); - checkDone(); - }) - - function checkDone() { - if(--remainingTests == 0) { - s.close(); - console.log("All tests passed."); - } - } -}) - diff --git a/frontend/express/node_modules/request/tests/test-toJSON.js b/frontend/express/node_modules/request/tests/test-toJSON.js deleted file mode 100644 index 6d5f92aaa56..00000000000 --- a/frontend/express/node_modules/request/tests/test-toJSON.js +++ /dev/null @@ -1,14 +0,0 @@ -var request = require('../index') - , http = require('http') - , assert = require('assert') - ; - -var s = http.createServer(function (req, resp) { - resp.statusCode = 200 - resp.end('asdf') -}).listen(8080, function () { - var r = request('http://localhost:8080', function (e, resp) { - assert.equal(JSON.parse(JSON.stringify(r)).response.statusCode, 200) - s.close() - }) -}) \ No newline at end of file diff --git a/frontend/express/node_modules/request/tests/test-tunnel.js b/frontend/express/node_modules/request/tests/test-tunnel.js deleted file mode 100644 index 2ee3f393ed7..00000000000 --- a/frontend/express/node_modules/request/tests/test-tunnel.js +++ /dev/null @@ -1,75 +0,0 @@ -// test that we can tunnel a https request over an http proxy -// keeping all the CA and whatnot intact. -// -// Note: this requires that squid is installed. -// If the proxy fails to start, we'll just log a warning and assume success. - -var server = require('./server') - , assert = require('assert') - , request = require('../index') - , fs = require('fs') - , path = require('path') - , caFile = path.resolve(__dirname, 'ssl/npm-ca.crt') - , ca = fs.readFileSync(caFile) - , child_process = require('child_process') - , sqConf = path.resolve(__dirname, 'squid.conf') - , sqArgs = ['-f', sqConf, '-N', '-d', '5'] - , proxy = 'http://localhost:3128' - , hadError = null - -var squid = child_process.spawn('squid', sqArgs); -var ready = false - -squid.stderr.on('data', function (c) { - console.error('SQUIDERR ' + c.toString().trim().split('\n') - .join('\nSQUIDERR ')) - ready = c.toString().match(/ready to serve requests|Accepting HTTP Socket connections/i) -}) - -squid.stdout.on('data', function (c) { - console.error('SQUIDOUT ' + c.toString().trim().split('\n') - .join('\nSQUIDOUT ')) -}) - -squid.on('error', function (c) { - console.error('squid: error '+c) - if (c && !ready) { - notInstalled() - return - } -}) - -squid.on('exit', function (c) { - console.error('squid: exit '+c) - if (c && !ready) { - notInstalled() - return - } - - if (c) { - hadError = hadError || new Error('Squid exited with '+c) - } - if (hadError) throw hadError -}) - -setTimeout(function F () { - if (!ready) return setTimeout(F, 100) - request({ uri: 'https://registry.npmjs.org/' - , proxy: 'http://localhost:3128' - , strictSSL: true - , ca: ca - , json: true }, function (er, body) { - hadError = er - console.log(er || typeof body) - if (!er) console.log("ok") - squid.kill('SIGKILL') - }) -}, 100) - -function notInstalled() { - console.error('squid must be installed to run this test.') - console.error('skipping this test. please install squid and run again if you need to test tunneling.') - c = null - hadError = null - process.exit(0) -} diff --git a/frontend/express/node_modules/request/tests/unicycle.jpg b/frontend/express/node_modules/request/tests/unicycle.jpg deleted file mode 100644 index 7cea4dd71dc..00000000000 Binary files a/frontend/express/node_modules/request/tests/unicycle.jpg and /dev/null differ diff --git a/frontend/express/node_modules/request/tunnel.js b/frontend/express/node_modules/request/tunnel.js deleted file mode 100644 index 453786c5e7b..00000000000 --- a/frontend/express/node_modules/request/tunnel.js +++ /dev/null @@ -1,229 +0,0 @@ -'use strict'; - -var net = require('net'); -var tls = require('tls'); -var http = require('http'); -var https = require('https'); -var events = require('events'); -var assert = require('assert'); -var util = require('util'); - - -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - return agent; -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - return agent; -} - - -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } - } - socket.destroy(); - self.removeSocket(socket); - }); -} -util.inherits(TunnelingAgent, events.EventEmitter); - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) { - var self = this; - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: host, port: port, request: req}); - return; - } - - // If we are under maxSockets create a new one. - self.createSocket({host: host, port: port, request: req}, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); - - function onFree() { - self.emit('free', socket, host, port); - } - - function onCloseOrRemove(err) { - self.removeSocket(); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false - }); - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } - - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); - - if (res.statusCode === 200) { - assert.equal(head.length, 0); - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - cb(socket); - } else { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - var error = new Error('tunneling socket could not be established, ' + - 'sutatusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } - } - - function onError(cause) { - connectReq.removeAllListeners(); - - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; - } - this.sockets.splice(pos, 1); - - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); - } -}; - -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, { - socket: socket - })); - cb(secureSocket); - }); -} - - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; -} - - -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); - } - console.error.apply(console, args); - } -} else { - debug = function() {}; -} -exports.debug = debug; // for test diff --git a/frontend/express/node_modules/request/uuid.js b/frontend/express/node_modules/request/uuid.js deleted file mode 100644 index 1d83bd50a27..00000000000 --- a/frontend/express/node_modules/request/uuid.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = function () { - var s = [], itoh = '0123456789ABCDEF'; - - // Make array of random hex digits. The UUID only has 32 digits in it, but we - // allocate an extra items to make room for the '-'s we'll be inserting. - for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10); - - // Conform to RFC-4122, section 4.4 - s[14] = 4; // Set 4 high bits of time_high field to version - s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence - - // Convert to hex chars - for (var i = 0; i <36; i++) s[i] = itoh[s[i]]; - - // Insert '-'s - s[8] = s[13] = s[18] = s[23] = '-'; - - return s.join(''); -} diff --git a/frontend/express/node_modules/request/vendor/cookie/index.js b/frontend/express/node_modules/request/vendor/cookie/index.js deleted file mode 100644 index ff44b3e6292..00000000000 --- a/frontend/express/node_modules/request/vendor/cookie/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/*! - * Tobi - Cookie - * Copyright(c) 2010 LearnBoost - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var url = require('url'); - -/** - * Initialize a new `Cookie` with the given cookie `str` and `req`. - * - * @param {String} str - * @param {IncomingRequest} req - * @api private - */ - -var Cookie = exports = module.exports = function Cookie(str, req) { - this.str = str; - - // Map the key/val pairs - str.split(/ *; */).reduce(function(obj, pair){ - var p = pair.indexOf('='); - var key = p > 0 ? pair.substring(0, p).trim() : pair.trim(); - var lowerCasedKey = key.toLowerCase(); - var value = p > 0 ? pair.substring(p + 1).trim() : true; - - if (!obj.name) { - // First key is the name - obj.name = key; - obj.value = value; - } - else if (lowerCasedKey === 'httponly') { - obj.httpOnly = value; - } - else { - obj[lowerCasedKey] = value; - } - return obj; - }, this); - - // Expires - this.expires = this.expires - ? new Date(this.expires) - : Infinity; - - // Default or trim path - this.path = this.path - ? this.path.trim(): req - ? url.parse(req.url).pathname: '/'; -}; - -/** - * Return the original cookie string. - * - * @return {String} - * @api public - */ - -Cookie.prototype.toString = function(){ - return this.str; -}; diff --git a/frontend/express/node_modules/request/vendor/cookie/jar.js b/frontend/express/node_modules/request/vendor/cookie/jar.js deleted file mode 100644 index 34920e06201..00000000000 --- a/frontend/express/node_modules/request/vendor/cookie/jar.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! -* Tobi - CookieJar -* Copyright(c) 2010 LearnBoost -* MIT Licensed -*/ - -/** -* Module dependencies. -*/ - -var url = require('url'); - -/** -* Initialize a new `CookieJar`. -* -* @api private -*/ - -var CookieJar = exports = module.exports = function CookieJar() { - this.cookies = []; -}; - -/** -* Add the given `cookie` to the jar. -* -* @param {Cookie} cookie -* @api private -*/ - -CookieJar.prototype.add = function(cookie){ - this.cookies = this.cookies.filter(function(c){ - // Avoid duplication (same path, same name) - return !(c.name == cookie.name && c.path == cookie.path); - }); - this.cookies.push(cookie); -}; - -/** -* Get cookies for the given `req`. -* -* @param {IncomingRequest} req -* @return {Array} -* @api private -*/ - -CookieJar.prototype.get = function(req){ - var path = url.parse(req.url).pathname - , now = new Date - , specificity = {}; - return this.cookies.filter(function(cookie){ - if (0 == path.indexOf(cookie.path) && now < cookie.expires - && cookie.path.length > (specificity[cookie.name] || 0)) - return specificity[cookie.name] = cookie.path.length; - }); -}; - -/** -* Return Cookie string for the given `req`. -* -* @param {IncomingRequest} req -* @return {String} -* @api private -*/ - -CookieJar.prototype.cookieString = function(req){ - var cookies = this.get(req); - if (cookies.length) { - return cookies.map(function(cookie){ - return cookie.name + '=' + cookie.value; - }).join('; '); - } -}; diff --git a/frontend/express/package.json b/frontend/express/package.json new file mode 100644 index 00000000000..d996bf17edb --- /dev/null +++ b/frontend/express/package.json @@ -0,0 +1,14 @@ +{ + "name": "countly-server-frontend", + "dependencies": { + "connect-flash": "0.1.1", + "connect-mongoskin": "0.1.2", + "mongoskin": "1.4.4", + "ejs": "0.8.4", + "express":"3.2.6", + "express-expose":"0.3.3", + "imagemagick":"0.1.3", + "request":"2.51.0", + "string":"3.0.0" + } +} \ No newline at end of file diff --git a/frontend/express/public/appimages/.gitignore b/frontend/express/public/appimages/.gitignore index e69de29bb2d..86d0cb2726c 100644 --- a/frontend/express/public/appimages/.gitignore +++ b/frontend/express/public/appimages/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/frontend/express/public/crossdomain.xml b/frontend/express/public/crossdomain.xml index ddcffa13abe..7a876a7ce42 100644 --- a/frontend/express/public/crossdomain.xml +++ b/frontend/express/public/crossdomain.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/frontend/express/public/images/dashboard/analytics_icons.png b/frontend/express/public/images/dashboard/analytics_icons.png index c693530e224..dfc9a92f472 100644 Binary files a/frontend/express/public/images/dashboard/analytics_icons.png and b/frontend/express/public/images/dashboard/analytics_icons.png differ diff --git a/frontend/express/public/images/dashboard/anayltcs_header_icons.png b/frontend/express/public/images/dashboard/anayltcs_header_icons.png index 1927d95b37e..b89d2c46fa0 100644 Binary files a/frontend/express/public/images/dashboard/anayltcs_header_icons.png and b/frontend/express/public/images/dashboard/anayltcs_header_icons.png differ diff --git a/frontend/express/public/images/dashboard/blck_grain_trans_bg.png b/frontend/express/public/images/dashboard/blck_grain_trans_bg.png new file mode 100644 index 00000000000..888146625e5 Binary files /dev/null and b/frontend/express/public/images/dashboard/blck_grain_trans_bg.png differ diff --git a/frontend/express/public/images/reports/combo-arrow.png b/frontend/express/public/images/dashboard/combo-arrow.png similarity index 100% rename from frontend/express/public/images/reports/combo-arrow.png rename to frontend/express/public/images/dashboard/combo-arrow.png diff --git a/frontend/express/public/images/reports/date-time.png b/frontend/express/public/images/dashboard/date-time.png similarity index 100% rename from frontend/express/public/images/reports/date-time.png rename to frontend/express/public/images/dashboard/date-time.png diff --git a/frontend/express/public/images/favicon.png b/frontend/express/public/images/favicon.png index aadf62275fe..3ff9e4fd760 100644 Binary files a/frontend/express/public/images/favicon.png and b/frontend/express/public/images/favicon.png differ diff --git a/frontend/express/public/images/reports/checkbox.png b/frontend/express/public/images/management/checkbox.png similarity index 100% rename from frontend/express/public/images/reports/checkbox.png rename to frontend/express/public/images/management/checkbox.png diff --git a/frontend/express/public/javascripts/countly/countly.allapps.js b/frontend/express/public/javascripts/countly/countly.allapps.js index 92ff4d76354..6d6cf6e5cae 100644 --- a/frontend/express/public/javascripts/countly/countly.allapps.js +++ b/frontend/express/public/javascripts/countly/countly.allapps.js @@ -42,16 +42,13 @@ } _sessions["all"][i].data[j][0] = _sessions[appID][i].data[j][0]; _sessions["all"][i].data[j][1] += parseFloat(_sessions[appID][i].data[j][1]); - if(i == "#draw-total-users") - _appData["all"].users.total += _sessions[appID][i].data[j][1]; - else if(i == "#draw-new-users") - _appData["all"].newusers.total += _sessions[appID][i].data[j][1]; - else if(i == "#draw-total-sessions") - _appData["all"].sessions.total += _sessions[appID][i].data[j][1]; - else if(i == "#draw-total-time-spent") + if(i == "#draw-total-time-spent") _appData["all"].duration.total += parseFloat(_sessions[appID][i].data[j][1]); } } + _appData["all"].sessions.total += sessionData.usage['total-sessions'].total; + _appData["all"].users.total += sessionData.usage['total-users'].total; + _appData["all"].newusers.total += sessionData.usage['new-users'].total; _appData["all"].sessions.trend += fromShortNumber(sessionData.usage['total-sessions'].change); _appData["all"].users.trend += fromShortNumber(sessionData.usage['total-users'].change); _appData["all"].newusers.trend += fromShortNumber(sessionData.usage['new-users'].change); @@ -115,7 +112,7 @@ var loadApp = function(appID){ countlyCommon.setActiveApp(appID); - return $.when(countlySession.initialize()).done(function () { + return $.when(countlyUser.initialize()).done(function () { var sessionData = countlySession.getSessionData(); if(!_appIds[appID]){ _sessionData[appID] = sessionData; diff --git a/frontend/express/public/javascripts/countly/countly.app.version.js b/frontend/express/public/javascripts/countly/countly.app.version.js index d77498e57c6..6f6e056121c 100644 --- a/frontend/express/public/javascripts/countly/countly.app.version.js +++ b/frontend/express/public/javascripts/countly/countly.app.version.js @@ -1,71 +1,18 @@ (function (countlyAppVersion, $, undefined) { //Private Properties - var _periodObj = {}, - _appVersionsDb = {}, - _app_versions = [], - _activeAppKey = 0, - _initialized = false; + var _appVersionsDb = {}, + _app_versions = []; //Public Methods countlyAppVersion.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { - return countlyAppVersion.refresh(); - } - - if (!countlyCommon.DEBUG) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - _initialized = true; - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r || "/o", - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"app_versions" - }, - dataType:"jsonp", - success:function (json) { - _appVersionsDb = json; - setMeta(); - } - }); - } else { - _appVersionsDb = {"2012":{}}; - return true; - } + _appVersionsDb = countlyDeviceDetails.getDbObj(); + setMeta(); }; - countlyAppVersion.refresh = function () { - _periodObj = countlyCommon.periodObj; - - if (!countlyCommon.DEBUG) { - - if (_activeAppKey != countlyCommon.ACTIVE_APP_KEY) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - return countlyAppVersion.initialize(); - } - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r, - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"app_versions", - "action":"refresh" - }, - dataType:"jsonp", - success:function (json) { - countlyCommon.extendDbObj(_appVersionsDb, json); - setMeta(); - } - }); - } else { - _appVersionsDb = {"2012":{}}; - return true; - } + countlyAppVersion.refresh = function (newJSON) { + countlyCommon.extendDbObj(_appVersionsDb, newJSON); + extendMeta(); }; countlyAppVersion.reset = function () { @@ -147,4 +94,10 @@ } } + function extendMeta() { + if (_appVersionsDb['meta']) { + _app_versions = countlyCommon.union(_app_versions, _appVersionsDb['meta']['app_versions']); + } + } + }(window.countlyAppVersion = window.countlyAppVersion || {}, jQuery)); diff --git a/frontend/express/public/javascripts/countly/countly.carrier.js b/frontend/express/public/javascripts/countly/countly.carrier.js index 6f04b21f99c..b30170b4eb0 100644 --- a/frontend/express/public/javascripts/countly/countly.carrier.js +++ b/frontend/express/public/javascripts/countly/countly.carrier.js @@ -5,14 +5,17 @@ _carrierDb = {}, _carriers = [], _activeAppKey = 0, - _initialized = false; + _initialized = false, + _period = null; //Public Methods countlyCarrier.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + if (_initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { return countlyCarrier.refresh(); } + _period = countlyCommon.getPeriodForAjax(); + if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; _initialized = true; @@ -23,7 +26,8 @@ data:{ "api_key":countlyGlobal.member.api_key, "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"carriers" + "method":"carriers", + "period":_period }, dataType:"jsonp", success:function (json) { @@ -59,7 +63,7 @@ dataType:"jsonp", success:function (json) { countlyCommon.extendDbObj(_carrierDb, json); - setMeta(); + extendMeta(); } }); } else { @@ -149,4 +153,11 @@ _carriers = []; } } + + function extendMeta() { + if (_carrierDb['meta']) { + _carriers = countlyCommon.union(_carriers, _carrierDb['meta']['carriers']); + } + } + }(window.countlyCarrier = window.countlyCarrier || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.city.js b/frontend/express/public/javascripts/countly/countly.city.js index a415a69912c..1f9813bec1d 100644 --- a/frontend/express/public/javascripts/countly/countly.city.js +++ b/frontend/express/public/javascripts/countly/countly.city.js @@ -4,7 +4,7 @@ var _periodObj = {}, _locationsDb = {}, _activeAppKey = 0, - _countries = [], + _cities = [], _chart, _dataTable, _chartElementId = "geo-chart", @@ -18,8 +18,8 @@ datalessRegionColor:"#FFF", region:"TR" }, - _countryMap = {}, - _initialized = false; + _initialized = false, + _period = null; if (countlyCommon.CITY_DATA === false) { countlyCity.initialize = function() { return true; }; @@ -31,10 +31,12 @@ // Public Methods countlyCity.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + if (_initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { return countlyCity.refresh(); } + _period = countlyCommon.getPeriodForAjax(); + if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; _initialized = true; @@ -45,7 +47,8 @@ data:{ "api_key":countlyGlobal.member.api_key, "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"cities" + "method":"cities", + "period":_period }, dataType:"jsonp", success:function (json) { @@ -130,9 +133,9 @@ countlyCity.getLocationData = function (options) { - var locationData = countlyCommon.extractTwoLevelData(_locationsDb, _countries, countlyCity.clearLocationObject, [ + var locationData = countlyCommon.extractTwoLevelData(_locationsDb, _cities, countlyCity.clearLocationObject, [ { - "name":"country", + "name":"city", "func":function (rangeArr, dataObj) { return rangeArr; } @@ -171,9 +174,9 @@ _chart = new google.visualization.GeoChart(document.getElementById(_chartElementId)); - var tt = countlyCommon.extractTwoLevelData(_locationsDb, _countries, countlyCity.clearLocationObject, [ + var tt = countlyCommon.extractTwoLevelData(_locationsDb, _cities, countlyCity.clearLocationObject, [ { - "name":"country", + "name":"city", "func":function (rangeArr, dataObj) { return rangeArr; } @@ -187,11 +190,11 @@ ]; chartData.rows = _.map(tt.chartData, function (value, key, list) { - if (value.country == "European Union" || value.country == "Unknown") { + if (value.city == "Unknown") { return {c:[]}; } return {c:[ - {v:value.country}, + {v:value.city}, {v:value["t"]} ]}; }); @@ -211,9 +214,9 @@ function reDraw() { var chartData = {cols:[], rows:[]}; - var tt = countlyCommon.extractTwoLevelData(_locationsDb, _locationsDb["cities"], countlyCity.clearLocationObject, [ + var tt = countlyCommon.extractTwoLevelData(_locationsDb, _cities, countlyCity.clearLocationObject, [ { - "name":"country", + "name":"city", "func":function (rangeArr, dataObj) { return rangeArr; } @@ -222,18 +225,18 @@ ]); chartData.cols = [ - {id:'country', label:"City", type:'string'}, + {id:'city', label:"City", type:'string'}, {id:'total', label:jQuery.i18n.map["common.total"], type:'number'} ]; chartData.rows = _.map(tt.chartData, function (value, key, list) { - if (value.country == "European Union" || value.country == "Unknown") { + if (value.city == "Unknown") { return {c:[ {v:""}, {v:value["t"]} ]}; } return {c:[ - {v:value.country}, + {v:value.city}, {v:value["t"]} ]}; }); @@ -242,15 +245,11 @@ _chart.draw(_dataTable, _chartOptions); } - function geoDataSortHelper(a, b) { - return ((a["t"] > b["t"]) ? -1 : ((a["t"] < b["t"]) ? 1 : 0)); - } - function setMeta() { if (_locationsDb['meta']) { - _countries = (_locationsDb['meta']['cities']) ? _locationsDb['meta']['cities'] : []; + _cities = (_locationsDb['meta']['cities']) ? _locationsDb['meta']['cities'] : []; } else { - _countries = []; + _cities = []; } } diff --git a/frontend/express/public/javascripts/countly/countly.common.js b/frontend/express/public/javascripts/countly/countly.common.js index f202b135679..bf161660da6 100644 --- a/frontend/express/public/javascripts/countly/countly.common.js +++ b/frontend/express/public/javascripts/countly/countly.common.js @@ -36,6 +36,14 @@ return _period; }; + countlyCommon.getPeriodForAjax = function () { + if (Object.prototype.toString.call(_period) === '[object Array]'){ + return JSON.stringify(_period); + } else { + return _period; + } + }; + countlyCommon.setActiveApp = function (appId) { countlyCommon.ACTIVE_APP_KEY = countlyGlobal['apps'][appId].key; countlyCommon.ACTIVE_APP_ID = appId; @@ -69,268 +77,385 @@ }; // Fetches nested property values from an obj. - countlyCommon.getDescendantProp = function (obj, desc) { - desc = String(desc); - - if (desc.indexOf(".") === -1) { - return obj[desc]; + countlyCommon.getDescendantProp = function (obj, path, def) { + for (var i = 0, path = (path + "").split('.'), len = path.length; i < len; i++) { + if(!obj || typeof obj !== 'object') return def; + obj = obj[path[i]]; } - var arr = desc.split("."); - while (arr.length && (obj = obj[arr.shift()])); - + if(obj === undefined) return def; return obj; }; // Draws a graph with the given dataPoints to container. Used for drawing bar and pie charts. countlyCommon.drawGraph = function (dataPoints, container, graphType, inGraphProperties) { + _.defer(function(){ + if ((!dataPoints.dp || !dataPoints.dp.length) || (graphType == "bar" && !dataPoints.dp[0].data[0][1] && !dataPoints.dp[0].data[1][1])) { + $(container).hide(); + $(container).siblings(".no-data").show(); + return true; + } else { + $(container).show(); + $(container).siblings(".no-data").hide(); + } - var graphProperties = { - series:{ - lines:{ show:true, fill:true }, - points:{ show:true } - }, - grid:{ hoverable:true, borderColor:"null", color:"#999", borderWidth:0, minBorderMargin:10}, - xaxis:{ minTickSize:1, tickDecimals:"number", tickLength:0}, - yaxis:{ min:0, minTickSize:1, tickDecimals:"number" }, - legend:{ backgroundOpacity:0, margin:[5, -19] }, - colors:countlyCommon.GRAPH_COLORS - }; + var graphProperties = { + series:{ + lines:{ show:true, fill:true }, + points:{ show:true } + }, + grid:{ hoverable:true, borderColor:"null", color:"#999", borderWidth:0, minBorderMargin:10}, + xaxis:{ minTickSize:1, tickDecimals:"number", tickLength:0}, + yaxis:{ min:0, minTickSize:1, tickDecimals:"number", position:"right" }, + legend:{ backgroundOpacity:0, margin:[20, -19] }, + colors:countlyCommon.GRAPH_COLORS + }; - switch (graphType) { - case "line": - graphProperties.series = {lines:{ show:true, fill:true }, points:{ show:true }}; - break; - case "bar": - if (dataPoints.ticks.length > 20) { - graphProperties.xaxis.rotateTicks = 45; - } + switch (graphType) { + case "line": + graphProperties.series = {lines:{ show:true, fill:true }, points:{ show:true }}; + break; + case "bar": + if (dataPoints.ticks.length > 20) { + graphProperties.xaxis.rotateTicks = 45; + } - graphProperties.series = {stack:true, bars:{ show:true, align:"center", barWidth:0.6, tickLength:0 }}; - graphProperties.xaxis.ticks = dataPoints.ticks; - break; - case "pie": - graphProperties.series = { pie:{ - show:true, - lineWidth:0, - radius:115, - combine:{ - color:'#999', - threshold:0.05 - }, - label:{ + graphProperties.series = {stack:true, bars:{ show:true, align:"center", barWidth:0.6, tickLength:0 }}; + graphProperties.xaxis.ticks = dataPoints.ticks; + break; + case "pie": + graphProperties.series = { pie:{ show:true, - radius:160 - } - }}; - graphProperties.legend.show = false; - break; - default: - break; - } + lineWidth:0, + radius:115, + combine:{ + color:'#999', + threshold:0.05 + }, + label:{ + show:true, + radius:160 + } + }}; + graphProperties.legend.show = false; + break; + default: + break; + } - if (inGraphProperties) { - $.extend(true, graphProperties, inGraphProperties); - } + if (inGraphProperties) { + $.extend(true, graphProperties, inGraphProperties); + } - $.plot($(container), dataPoints.dp, graphProperties); + $.plot($(container), dataPoints.dp, graphProperties); - if (graphType == "bar" && !graphProperties.series.stack) { - var previousBar; + if (graphType == "bar") { + var previousBar; - $(container).bind("plothover", function (event, pos, item) { - if (item) { - var x = item.datapoint[0].toFixed(1).replace(".0", ""), - y = item.datapoint[1].toFixed(1).replace(".0", ""); + $(container).unbind("plothover"); + $(container).bind("plothover", function (event, pos, item) { + if (item) { + var x = item.datapoint[0].toFixed(1).replace(".0", ""), + y = item.datapoint[1].toFixed(1).replace(".0", "") - item.datapoint[2].toFixed(1).replace(".0", ""); - if (previousBar != y) { + if (previousBar != y) { + $("#graph-tooltip").remove(); + showTooltip(item.pageX, item.pageY - 40, y); + previousBar = y; + } + } else { $("#graph-tooltip").remove(); - showTooltip(item.pageX, item.pageY - 40, y); - previousBar = y; + previousBar = null; } - } else { - $("#graph-tooltip").remove(); - previousBar = null; - } - }); - } else { - $(container).unbind("plothover"); - } + }); + } else { + $(container).unbind("plothover"); + } + }, dataPoints, container, graphType, inGraphProperties); }; // Draws a line graph with the given dataPoints to container. countlyCommon.drawTimeGraph = function (dataPoints, container, bucket) { + _.defer(function(){ + if (!dataPoints.length) { + $(container).hide(); + $(container).siblings(".no-data").show(); + return true; + } else { + $(container).show(); + $(container).siblings(".no-data").hide(); + } - // Some data points start with [1, XXX] (should be [0, XXX]) and brakes the new tick logic - // Below loops converts the old structures to the new one - if (dataPoints[0].data[0][0] == 1) { - for (var i = 0; i < dataPoints.length; i++) { - for (var j = 0; j < dataPoints[i].data.length; j++) { - dataPoints[i].data[j][0] -= 1; + // Some data points start with [1, XXX] (should be [0, XXX]) and brakes the new tick logic + // Below loops converts the old structures to the new one + if (dataPoints[0].data[0][0] == 1) { + for (var i = 0; i < dataPoints.length; i++) { + for (var j = 0; j < dataPoints[i].data.length; j++) { + dataPoints[i].data[j][0] -= 1; + } } } - } - - var graphProperties = { - series:{ - lines:{ stack:false, show:true, fill:true, lineWidth:2, fillColor:{ colors:[ - { opacity:0 }, - { opacity:0.15 } - ] }, shadowSize:0 }, - points:{ show:true, radius:4, shadowSize:0 }, - shadowSize:0 - }, - grid:{ hoverable:true, borderColor:"null", color:"#BDBDBD", borderWidth:0, minBorderMargin:10, labelMargin:10}, - xaxis:{ tickDecimals:"number", tickSize:0, tickLength:0 }, - yaxis:{ min:0, minTickSize:1, tickDecimals:"number", ticks:3 }, - legend:{ show:false, margin:[-25, -44], noColumns:3, backgroundOpacity:0 }, - colors:countlyCommon.GRAPH_COLORS - }; - - graphProperties.series.points.show = (dataPoints[0].data.length <= 90); - var graphTicks = [], - tickObj = {}; + var graphProperties = { + series:{ + lines:{ stack:false, show:true, fill:true, lineWidth:2, fillColor:{ colors:[ + { opacity:0 }, + { opacity:0.15 } + ] }, shadowSize:0 }, + points:{ show:true, radius:4, shadowSize:0 }, + shadowSize:0 + }, + grid:{ hoverable:true, borderColor:"null", color:"#BDBDBD", borderWidth:0, minBorderMargin:10, labelMargin:10}, + xaxis:{ tickDecimals:"number", tickSize:0, tickLength:0 }, + yaxis:{ min:0, minTickSize:1, tickDecimals:"number", ticks:3, position:"right" }, + legend:{ show:false, margin:[-25, -44], noColumns:3, backgroundOpacity:0 }, + colors:countlyCommon.GRAPH_COLORS + }; - if (_period == "month" && !bucket) { - tickObj = countlyCommon.getTickObj("monthly"); - } else { - tickObj = countlyCommon.getTickObj(bucket); - } + graphProperties.series.points.show = (dataPoints[0].data.length <= 90); - graphProperties.xaxis.max = tickObj.max; - graphProperties.xaxis.min = tickObj.min; - graphProperties.xaxis.ticks = tickObj.ticks; + var graphTicks = [], + tickObj = {}; - graphTicks = tickObj.tickTexts; + if (_period == "month" && !bucket) { + tickObj = countlyCommon.getTickObj("monthly"); + } else { + tickObj = countlyCommon.getTickObj(bucket); + } - var graphObj = $.plot($(container), dataPoints, graphProperties), - keyEventCounter = "A", - keyEvents = [], - keyEventsIndex = 0; + graphProperties.xaxis.max = tickObj.max; + graphProperties.xaxis.min = tickObj.min; + graphProperties.xaxis.ticks = tickObj.ticks; - for (var k = 0; k < graphObj.getData().length; k++) { + graphTicks = tickObj.tickTexts; - var tmpMax = 0, - tmpMaxIndex = 0, - tmpMin = 999999999999, - tmpMinIndex = 0, - label = (graphObj.getData()[k].label + "").toLowerCase(); + var graphObj = $.plot($(container), dataPoints, graphProperties), + keyEventCounter = "A", + keyEvents = [], + keyEventsIndex = 0; - if (graphObj.getData()[k].mode === "ghost") { - keyEventsIndex += graphObj.getData()[k].data.length; - continue; - } + for (var k = 0; k < graphObj.getData().length; k++) { - $.each(graphObj.getData()[k].data, function (i, el) { + var tmpMax = 0, + tmpMaxIndex = 0, + tmpMin = 999999999999, + tmpMinIndex = 0, + label = (graphObj.getData()[k].label + "").toLowerCase(); - //data point is null - //this workaround is used to start drawing graph with a certain padding - if (!el[1] && el[1] !== 0) { - return true; + if (graphObj.getData()[k].mode === "ghost") { + keyEventsIndex += graphObj.getData()[k].data.length; + continue; } - el[1] = parseFloat(el[1]); - - if (el[1] >= tmpMax) { - tmpMax = el[1]; - tmpMaxIndex = el[0]; - } + $.each(graphObj.getData()[k].data, function (i, el) { - if (el[1] <= tmpMin) { - tmpMin = el[1]; - tmpMinIndex = el[0]; - } - }); + //data point is null + //this workaround is used to start drawing graph with a certain padding + if (!el[1] && el[1] !== 0) { + return true; + } - if (tmpMax == tmpMin) { - continue; - } + el[1] = parseFloat(el[1]); - keyEvents[k] = []; + if (el[1] >= tmpMax) { + tmpMax = el[1]; + tmpMaxIndex = el[0]; + } - keyEvents[k][keyEvents[k].length] = { - data:[tmpMinIndex, tmpMin], - code:keyEventCounter, - color:graphObj.getData()[k].color, - event:"min", - desc:jQuery.i18n.prop('common.graph-min', tmpMin, label, graphTicks[tmpMinIndex]) - }; + if (el[1] <= tmpMin) { + tmpMin = el[1]; + tmpMinIndex = el[0]; + } + }); - keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); + if (tmpMax == tmpMin) { + continue; + } - keyEvents[k][keyEvents[k].length] = { - data:[tmpMaxIndex, tmpMax], - code:keyEventCounter, - color:graphObj.getData()[k].color, - event:"max", - desc:jQuery.i18n.prop('common.graph-max', tmpMax, label, graphTicks[tmpMaxIndex]) - }; + keyEvents[k] = []; - keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); - } + keyEvents[k][keyEvents[k].length] = { + data:[tmpMinIndex, tmpMin], + code:keyEventCounter, + color:graphObj.getData()[k].color, + event:"min", + desc:jQuery.i18n.prop('common.graph-min', tmpMin, label, graphTicks[tmpMinIndex]) + }; - var graphWidth = graphObj.width(); + keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); - for (var k = 0; k < keyEvents.length; k++) { - var bgColor = graphObj.getData()[k].color; + keyEvents[k][keyEvents[k].length] = { + data:[tmpMaxIndex, tmpMax], + code:keyEventCounter, + color:graphObj.getData()[k].color, + event:"max", + desc:jQuery.i18n.prop('common.graph-max', tmpMax, label, graphTicks[tmpMaxIndex]) + }; - if (!keyEvents[k]) { - continue; + keyEventCounter = String.fromCharCode(keyEventCounter.charCodeAt() + 1); } - for (var l = 0; l < keyEvents[k].length; l++) { + var graphWidth = graphObj.width(); - var o = graphObj.pointOffset({x:keyEvents[k][l]["data"][0], y:keyEvents[k][l]["data"][1]}); + for (var k = 0; k < keyEvents.length; k++) { + var bgColor = graphObj.getData()[k].color; - if (o.left <= 15) { - o.left = 15; + if (!keyEvents[k]) { + continue; } - if (o.left >= (graphWidth - 15)) { - o.left = (graphWidth - 15); - } + for (var l = 0; l < keyEvents[k].length; l++) { + var o = graphObj.pointOffset({x:keyEvents[k][l]["data"][0], y:keyEvents[k][l]["data"][1]}); + var p = graphObj.pointOffset({x:keyEvents[k][l]["data"][0], y:keyEvents[k][l]["data"][1]}); + + if (o.left <= 15) { + o.left = 15; + } + + if (o.left >= (graphWidth - 15)) { + o.left = (graphWidth - 15); + } - if (true) { var keyEventLabel = $('
    ').text(keyEvents[k][l]["code"]); keyEventLabel.attr({ "title":keyEvents[k][l]["desc"], "data-points":"[" + keyEvents[k][l]["data"] + "]" }).css({ - "position":'absolute', - "left":o.left, - "top":o.top - 33, - "display":'none', - "background-color":bgColor - }).appendTo(graphObj.getPlaceholder()).show(); + "position":'absolute', + "left":o.left, + "top":o.top - 33, + "display":'none', + "background-color":bgColor + }).appendTo(graphObj.getPlaceholder()).show(); $(".tipsy").remove(); keyEventLabel.tipsy({gravity:$.fn.tipsy.autoWE, offset:3, html:true}); } } - } - var previousPoint; + // Add note labels to the graph + if (!(bucket == "hourly" && dataPoints[0].data.length > 24) && bucket != "weekly") { + var noteDateIds = countlyCommon.getNoteDateIds(bucket), + frontData = graphObj.getData()[graphObj.getData().length - 1], + startIndex = (!frontData.data[1] && frontData.data[1] !== 0)? 1 : 0; - $(container).bind("plothover", function (event, pos, item) { - if (item) { - if (previousPoint != item.dataIndex) { - previousPoint = item.dataIndex; + for (var k = 0, l = startIndex; k < frontData.data.length; k++, l++) { + if(frontData.data[l]){ + var graphPoint = graphObj.pointOffset({x:frontData.data[l][0], y:frontData.data[l][1]}); + + if (countlyCommon.getNotesForDateId(noteDateIds[k]).length) { + $('
    ').attr({ + "data-title":tickObj.tickTexts[k], + "data-notes":countlyCommon.getNotesForDateId(noteDateIds[k]), + "data-value":frontData.data[l][1].toFixed(1).replace(".0", "") + " " + frontData.label, + "data-points":"[" + frontData.data[l] + "]" + }).css({ + "position":'absolute', + "left":graphPoint.left, + "top":graphPoint.top, + "display":'none', + "border-color":frontData.color + }).appendTo(graphObj.getPlaceholder()).show(); + } + } + } + $(".graph-note-label").mouseenter(function() { $("#graph-tooltip").remove(); - var x = item.datapoint[0].toFixed(1).replace(".0", ""), - y = item.datapoint[1].toFixed(1).replace(".0", ""); - showTooltip(item.pageX, item.pageY - 40, y + " " + item.series.label); - } - } else { - $("#graph-tooltip").remove(); - previousPoint = null; + var noteLines = ($(this).data("notes") + "").split("==="), + contents = "
    " + '' + $(this).data("title") + '' + $(this).data("value") + "
    "; + + for (var i = 0; i < noteLines.length; i++) { + contents += "
    • " + noteLines[i] + "
    "; + } + + var tooltip = '
    ' + contents + '
    ', + x = $(this).offset().left, + y = $(this).offset().top, + widthVal, + heightVal; + + $("#content").append("
    " + tooltip + "
    "); + widthVal = $("#graph-tooltip").outerWidth(); + heightVal = $("#graph-tooltip").outerHeight(); + $("#tooltip-calc").remove(); + + var newLeft = x - widthVal, + xReach = x + widthVal; + + if (xReach > $(window).width()) { + newLeft = x - widthVal - 10; + } else if (xReach < 800) { + newLeft = x + $(this).outerWidth() + 10; + } else { + newLeft -= 10; + } + + $(tooltip).css({ + top: y - (heightVal / 2) + ($(this).height() / 2), + left: newLeft + }).appendTo("body").fadeIn(200); + }); + + $(".graph-note-label").mouseleave(function() { + $("#graph-tooltip").remove(); + }); } - }); - return keyEvents; + var previousPoint; + + $(container).unbind("plothover"); + $(container).bind("plothover", function (event, pos, item) { + if (item) { + if (previousPoint != item.dataIndex) { + previousPoint = item.dataIndex; + + $("#graph-tooltip").remove(); + var x = item.datapoint[0].toFixed(1).replace(".0", ""), + y = item.datapoint[1].toFixed(1).replace(".0", ""); + + // If this is the "ghost" graph don't add the date + if (item.series.color === "#DDDDDD") { + showTooltip(item.pageX, item.pageY - 40, y + " " + item.series.label); + } else { + showTooltip(item.pageX, item.pageY - 40, y + " " + item.series.label, tickObj.tickTexts[item.dataIndex]); + } + } + } else { + $("#graph-tooltip").remove(); + previousPoint = null; + } + }); + }, dataPoints, container, bucket); + }; + + countlyCommon.drawGauge = function(targetEl, value, maxValue, gaugeColor, textField) { + var opts = { + lines:12, + angle:0.15, + lineWidth:0.44, + pointer:{ + length:0.7, + strokeWidth:0.05, + color:'#000000' + }, + colorStart:gaugeColor, + colorStop:gaugeColor, + strokeColor:'#E0E0E0', + generateGradient:true + }; + + var gauge = new Gauge($(targetEl)[0]).setOptions(opts); + + if (textField) { + gauge.setTextField($(textField)[0]); + } + + gauge.maxValue = maxValue; + gauge.set(1); + gauge.set(value); }; countlyCommon.extractRangeData = function (db, propertyName, rangeArray, explainRange) { @@ -688,6 +813,8 @@ { "name":"t" } ]); + rangeData.chartData = _.sortBy(rangeData.chartData, function(obj) { return -obj.t; }); + var rangeNames = _.pluck(rangeData.chartData, 'range'), rangeTotal = _.pluck(rangeData.chartData, 't'), barData = [], @@ -722,6 +849,79 @@ return barData; }; + + countlyCommon.extractUserChartData = function (db, label, sec) { + var ret = {"data":[],"label":label}; + countlyCommon.periodObj = getPeriodObj(); + var periodMin, periodMax, dateob; + + if(countlyCommon.periodObj.isSpecialPeriod){ + periodMin = 0; + periodMax = (countlyCommon.periodObj.daysInPeriod); + var dateob1 = countlyCommon.processPeriod(countlyCommon.periodObj.currentPeriodArr[0].toString()); + var dateob2 = countlyCommon.processPeriod(countlyCommon.periodObj.currentPeriodArr[countlyCommon.periodObj.currentPeriodArr.length-1].toString()); + dateob = {timestart:dateob1.timestart, timeend:dateob2.timeend, range:"d"}; + } + else{ + periodMin = countlyCommon.periodObj.periodMin-1; + periodMax = countlyCommon.periodObj.periodMax; + dateob = countlyCommon.processPeriod(countlyCommon.periodObj.activePeriod.toString()); + } + var res = [], + ts; + //get all timestamps in that period + for(var i = 0, l = db.length; i < l; i++){ + ts = db[i]; + if(sec) + ts.ts = ts.ts*1000; + if(ts.ts > dateob.timestart && ts.ts <= dateob.timeend){ + res.push(ts); + } + } + var lastStart, + lastEnd = dateob.timestart, + total, + ts, + data = ret.data; + for(var i = periodMin; i < periodMax; i++){ + total = 0; + lastStart = lastEnd; + lastEnd = moment(lastStart).add(moment.duration(1, dateob.range)).valueOf(); + for(var j = 0, l = res.length; j < l; j++){ + ts = res[j]; + if(ts.ts > lastStart && ts.ts <= lastEnd) + if(ts.c) + total += ts.c; + else + total++; + } + data.push([i, total]); + } + return ret; + }; + + countlyCommon.processPeriod = function(period){ + var date = period.split("."); + var range, + timestart, + timeend; + if(date.length == 1){ + range = "M"; + timestart = moment(period, "YYYY").valueOf(); + timeend = moment(period, "YYYY").add(moment.duration(1, "y")).valueOf(); + } + else if(date.length == 2){ + range = "d"; + timestart = moment(period, "YYYY.MM").valueOf(); + timeend = moment(period, "YYYY.MM").add(moment.duration(1, "M")).valueOf(); + } + else if(date.length == 3){ + range = "h"; + timestart = moment(period, "YYYY.MM.DD").valueOf(); + timeend = moment(period, "YYYY.MM.DD").add(moment.duration(1, "d")).valueOf(); + } + return {timestart:timestart, timeend:timeend, range:range}; + } // Shortens the given number by adding K (thousand) or M (million) postfix. // K is added only if the number is bigger than 10000. @@ -767,7 +967,14 @@ formattedDateEnd = moment(countlyCommon.periodObj.currentPeriodArr[(countlyCommon.periodObj.currentPeriodArr.length - 1)], "YYYY.M.D"); } - return formattedDateStart.format(countlyCommon.periodObj.dateString) + " - " + formattedDateEnd.format(countlyCommon.periodObj.dateString); + var fromStr = formattedDateStart.format(countlyCommon.periodObj.dateString), + toStr = formattedDateEnd.format(countlyCommon.periodObj.dateString); + + if (fromStr == toStr) { + return fromStr; + } else { + return fromStr + " - " + toStr; + } }; // Function for merging updateObj object to dbObj. @@ -940,8 +1147,8 @@ }; countlyCommon.toFirstUpper = function(str) { - return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1);}); - } + return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); + }; countlyCommon.divide = function (val1, val2) { var temp = val1 / val2; @@ -951,15 +1158,16 @@ } return temp; - } + }; countlyCommon.getTickObj = function(bucket) { var days = parseInt(countlyCommon.periodObj.numberOfDays, 10), ticks = [], tickTexts = [], - skipReduction = false; + skipReduction = false, + limitAdjustment = 0; - if (days == 1) { + if ((days == 1 && _period != "month" && _period != "day") || (days == 1 && bucket == "hourly")) { for (var i = 0; i < 24; i++) { ticks.push([i, (i + ":00")]); tickTexts.push((i + ":00")); @@ -969,7 +1177,7 @@ } else { var start = moment().subtract('days', days); if (Object.prototype.toString.call(countlyCommon.getPeriod()) === '[object Array]'){ - start = moment(countlyCommon.periodObj.currentPeriodArr[countlyCommon.periodObj.currentPeriodArr.length - 1]).subtract('days',days); + start = moment(countlyCommon.periodObj.currentPeriodArr[countlyCommon.periodObj.currentPeriodArr.length - 1], "YYYY.MM.DD").subtract('days',days); } if (bucket == "monthly") { var allMonths = []; @@ -1025,7 +1233,25 @@ tickTexts = _.compact(tickTexts); } - if (!skipReduction && ticks.length > 10) { + if (ticks.length <= 2) { + limitAdjustment = 0.02; + var tmpTicks = [], + tmpTickTexts = []; + + tmpTickTexts[0] = ""; + tmpTicks[0] = [-0.02, ""]; + + for (var i = 0; i < ticks.length; i++) { + tmpTicks[i + 1] = [i, ticks[i][1]]; + tmpTickTexts[i + 1] = tickTexts[i]; + } + + tmpTickTexts.push(""); + tmpTicks.push([tmpTicks.length - 1 - 0.98, ""]); + + ticks = tmpTicks; + tickTexts = tmpTickTexts; + } else if (!skipReduction && ticks.length > 10) { var reducedTicks = [], step = (Math.floor(ticks.length / 10) < 1)? 1 : Math.floor(ticks.length / 10), pickStartIndex = (Math.floor(ticks.length / 30) < 1)? 1 : Math.floor(ticks.length / 30); @@ -1045,19 +1271,239 @@ } return { - min: 0, - max: tickTexts.length - 1, + min: 0 - limitAdjustment, + max: (limitAdjustment)? tickTexts.length - 3 + limitAdjustment : tickTexts.length - 1, tickTexts: tickTexts, ticks: _.compact(ticks) }; }; - - countlyCommon.formatNumber = function(x) { + + countlyCommon.union = function(x, y) { + if (!x) { + return y; + } else if (!y) { + return x; + } + + var needUnion = false; + + for (var i = 0; i < y.length; i++) { + if (x.indexOf(y[i]) === -1) { + needUnion = true; + break; + } + } + + if (!needUnion) { + return x; + } + + var obj = {}; + for (var i = x.length-1; i >= 0; -- i) { + obj[x[i]] = x[i]; + } + + for (var i = y.length-1; i >= 0; -- i) { + obj[y[i]] = y[i]; + } + + var res = []; + + for (var k in obj) { + res.push(obj[k]); + } + + return res; + }; + + countlyCommon.formatNumber = function(x) { x = parseFloat(parseFloat(x).toFixed(2)); var parts = x.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); }; + + countlyCommon.pad = function(n, width, z){ + z = z || '0'; + n = n + ''; + return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; + }; + + countlyCommon.getNoteDateIds = function(bucket) { + var _periodObj = countlyCommon.periodObj, + dateIds = [], + dotSplit = [], + tmpDateStr = ""; + + if (!_periodObj.isSpecialPeriod && !bucket) { + for (var i = _periodObj.periodMin; i < (_periodObj.periodMax + 1); i++) { + dotSplit = (_periodObj.activePeriod + "." + i).split("."); + tmpDateStr = ""; + + for (var j = 0; j < dotSplit.length; j++) { + if (dotSplit[j].length == 1) { + tmpDateStr += "0" + dotSplit[j]; + } else { + tmpDateStr += dotSplit[j]; + } + } + + dateIds.push(tmpDateStr); + } + } else { + if (!_periodObj.currentPeriodArr && bucket == "daily") { + var tmpDate = new Date(); + _periodObj.currentPeriodArr = []; + + if (countlyCommon.getPeriod() == "month") { + for (var i = 0; i < (tmpDate.getMonth() + 1); i++) { + var daysInMonth = moment().month(i).daysInMonth(); + + for (var j = 0; j < daysInMonth; j++) { + _periodObj.currentPeriodArr.push(_periodObj.activePeriod + "." + (i + 1) + "." + (j + 1)); + + // If current day of current month, just break + if ((i == tmpDate.getMonth()) && (j == (tmpDate.getDate() - 1))) { + break; + } + } + } + } else if(countlyCommon.getPeriod() == "day") { + for (var i = 0; i < tmpDate.getDate(); i++) { + _periodObj.currentPeriodArr.push(_periodObj.activePeriod + "." + (i + 1)); + } + } else{ + _periodObj.currentPeriodArr.push(_periodObj.activePeriod); + } + } + + for (var i = 0; i < (_periodObj.currentPeriodArr.length); i++) { + dotSplit = _periodObj.currentPeriodArr[i].split("."); + tmpDateStr = ""; + + for (var j = 0; j < dotSplit.length; j++) { + if (dotSplit[j].length == 1) { + tmpDateStr += "0" + dotSplit[j]; + } else { + tmpDateStr += dotSplit[j]; + } + } + + dateIds.push(tmpDateStr); + } + } + + switch (bucket) { + case "hourly": + var tmpDateIds = []; + + for (var i = 0; i < 25; i++) { + tmpDateIds.push(dateIds[0] + ((i < 10)? "0" + i : i)) + } + + dateIds = tmpDateIds; + break; + case "monthly": + var tmpDateIds = []; + + for (var i = 0; i < dateIds.length; i++) { + countlyCommon.arrayAddUniq(tmpDateIds, moment(dateIds[i], "YYYYMMDD").format("YYYYMM")) + } + + dateIds = tmpDateIds; + break; + } + + return dateIds; + }; + + countlyCommon.getNotesForDateId = function(dateId) { + var ret = []; + + if (countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID] && countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes) { + for (var date in countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes) { + if (date.indexOf(dateId) === 0) { + ret = ret.concat(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes[date]); + } + } + } + + return ret.join("==="); + }; + + countlyCommon.arrayAddUniq = function (arr, item) { + if (!arr) { + arr = []; + } + + if (toString.call(item) === "[object Array]") { + for (var i = 0; i < item.length; i++) { + if (arr.indexOf(item[i]) === -1) { + arr[arr.length] = item[i]; + } + } + } else { + if (arr.indexOf(item) === -1) { + arr[arr.length] = item; + } + } + }; + + countlyCommon.formatTimeAgo = function(timestamp) { + var target = new Date(timestamp*1000); + var now = new Date(); + var diff = Math.floor((now - target) / 1000); + if (diff <= 1) {return "just now";} + if (diff < 20) {return "" + diff + " seconds ago";} + if (diff < 40) {return "half a minute ago";} + if (diff < 60) {return "less than a minute ago";} + if (diff <= 90) {return "one minute ago";} + if (diff <= 3540) {return Math.round(diff / 60) + " minutes ago";} + if (diff <= 5400) {return "1 hour ago";} + if (diff <= 86400) {return Math.round(diff / 3600) + " hours ago";} + if (diff <= 129600) {return "1 day ago";} + if (diff < 604800) {return Math.round(diff / 86400) + " days ago";} + if (diff <= 777600) {return "1 week ago";} + return "on " + target.toString().split(" GMT")[0]; + }; + + countlyCommon.formatTime = function(timestamp) { + var str = ""; + var seconds = timestamp % 60; + str = str+leadingZero(seconds); + timestamp -= seconds; + var minutes = timestamp % (60*60); + str = leadingZero(minutes/60)+":"+str; + timestamp -= minutes; + var hours = timestamp % (60*60*24); + str = leadingZero(hours/(60*60))+":"+str; + timestamp -= hours; + if(timestamp > 0){ + var days = timestamp % (60*60*24*365); + str = (days/(60*60*24))+" day(s) "+str; + timestamp -= days; + if(timestamp > 0){ + str = (timestamp/(60*60*24*365))+" year(s) "+str; + } + } + return str; + }; + + countlyCommon.getDate = function(timestamp) { + var d = new Date(timestamp*1000); + return leadingZero(d.getDate())+"."+leadingZero(d.getMonth()+1)+"."+d.getFullYear(); + } + + countlyCommon.getTime = function(timestamp) { + var d = new Date(timestamp*1000); + return leadingZero(d.getHours())+":"+leadingZero(d.getMinutes()); + } + + function leadingZero(value){ + if(value > 9) + return value + return "0"+value; + } // Private Methods @@ -1477,8 +1923,15 @@ } // Function to show the tooltip when any data point in the graph is hovered on. - function showTooltip(x, y, contents) { - var tooltip = '
    ' + contents + '
    '; + function showTooltip(x, y, contents, title) { + var tooltip = ""; + + if (title) { + var tooltipTitle = '' + title + ''; + tooltip = '
    ' + tooltipTitle + contents + '
    ' + } else { + tooltip = '
    ' + contents + '
    ' + } $("#content").append("
    " + tooltip + "
    "); var widthVal = $("#graph-tooltip").outerWidth(); @@ -1499,4 +1952,36 @@ }).appendTo("body").fadeIn(200); } + function flattenObjUntilLastProp(ob) { + var toReturn = flattenObj(ob); + + for (var i in toReturn) { + var n = i.lastIndexOf('.'); + + if (n !== -1) { + toReturn[i.substring(0, n)] = toReturn[i]; + delete toReturn[i]; + } + } + + return toReturn + } + + function flattenObj(ob) { + var toReturn = {}; + + for (var i in ob) { + if ((typeof ob[i]) == 'object') { + var flatObject = flattenObj(ob[i]); + for (var x in flatObject) { + toReturn[i + '.' + x] = flatObject[x]; + } + } else { + toReturn[i] = ob; + } + } + + return toReturn; + } + }(window.countlyCommon = window.countlyCommon || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.config.sample.js b/frontend/express/public/javascripts/countly/countly.config.sample.js index 5e72a94aa5e..c5f6a70defb 100644 --- a/frontend/express/public/javascripts/countly/countly.config.sample.js +++ b/frontend/express/public/javascripts/countly/countly.config.sample.js @@ -1,5 +1,5 @@ countlyCommon.DEBUG = false; -countlyCommon.API_URL = ""; +countlyCommon.API_URL = countlyGlobal["path"] || ""; countlyCommon.API_PARTS = { data:{ "w":countlyCommon.API_URL + "/i", diff --git a/frontend/express/public/javascripts/countly/countly.device.detail.js b/frontend/express/public/javascripts/countly/countly.device.detail.js index 6a24d1c01b5..67824d076dd 100644 --- a/frontend/express/public/javascripts/countly/countly.device.detail.js +++ b/frontend/express/public/javascripts/countly/countly.device.detail.js @@ -6,16 +6,18 @@ _os = [], _resolutions = [], _os_versions = [], - _densities = [], _activeAppKey = 0, - _initialized = false; + _initialized = false, + _period = null; //Public Methods countlyDeviceDetails.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + if (_initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { return countlyDeviceDetails.refresh(); } + _period = countlyCommon.getPeriodForAjax(); + if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; _initialized = true; @@ -26,12 +28,15 @@ data:{ "api_key":countlyGlobal.member.api_key, "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"device_details" + "method":"device_details", + "period":_period }, dataType:"jsonp", success:function (json) { _deviceDetailsDb = json; setMeta(); + + countlyAppVersion.initialize(); } }); } else { @@ -62,7 +67,9 @@ dataType:"jsonp", success:function (json) { countlyCommon.extendDbObj(_deviceDetailsDb, json); - setMeta(); + extendMeta(); + + countlyAppVersion.refresh(json); } }); } else { @@ -273,81 +280,30 @@ return oSVersionData; }; - countlyDeviceDetails.getDensityBars = function () { - return countlyCommon.extractBarData(_deviceDetailsDb, _densities, countlyDeviceDetails.clearDeviceDetailsObject); - }; - - countlyDeviceDetails.getDensityData = function () { - var chartData = countlyCommon.extractTwoLevelData(_deviceDetailsDb, _densities, countlyDeviceDetails. - clearDeviceDetailsObject, [ - { - name:"densities", - func:function (rangeArr, dataObj) { - return rangeArr; - } - }, - { "name":"t" }, - { "name":"u" }, - { "name":"n" } - ]); - - var densities = _.pluck(chartData.chartData, 'densities'), - densityTotal = _.pluck(chartData.chartData, 'u'), - densityNew = _.pluck(chartData.chartData, 'n'), - chartData2 = [], - chartData3 = []; - - var sum = _.reduce(densityTotal, function (memo, num) { - return memo + num; - }, 0); - - for (var i = 0; i < densities.length; i++) { - var percent = (densityTotal[i] / sum) * 100; - chartData2[i] = {data:[ - [0, densityTotal[i]] - ], label:densities[i]}; - } - - var sum2 = _.reduce(densityNew, function (memo, num) { - return memo + num; - }, 0); - - for (var i = 0; i < densities.length; i++) { - var percent = (densityNew[i] / sum) * 100; - chartData3[i] = {data:[ - [0, densityNew[i]] - ], label:densities[i]}; - } - - chartData.chartDPTotal = {}; - chartData.chartDPTotal.dp = chartData2; - - chartData.chartDPNew = {}; - chartData.chartDPNew.dp = chartData3; - - return chartData; - }; - countlyDeviceDetails.fixOSVersion = function(osName) { return osName .replace(/:/g, ".") - .replace(/i/g, "iOS ") - .replace(/a/g, "Android ") - .replace(/b/g, "BlackBerry ") - .replace(/w/g, "Windows Phone ") - .replace(/m/g, "Mac "); + .replace(/^i/g, "iOS ") + .replace(/^a/g, "Android ") + .replace(/^b/g, "BlackBerry ") + .replace(/^w/g, "Windows Phone ") + .replace(/^o/g, "OS X ") + .replace(/^m/g, "Mac ") + .replace(/^t/g, "Tizen "); + }; + + countlyDeviceDetails.getDbObj = function() { + return _deviceDetailsDb; }; function setMeta() { if (_deviceDetailsDb['meta']) { _os = (_deviceDetailsDb['meta']['os']) ? _deviceDetailsDb['meta']['os'] : []; _resolutions = (_deviceDetailsDb['meta']['resolutions']) ? _deviceDetailsDb['meta']['resolutions'] : []; - _densities = (_deviceDetailsDb['meta']['densities']) ? _deviceDetailsDb['meta']['densities'] : []; _os_versions = (_deviceDetailsDb['meta']['os_versions']) ? _deviceDetailsDb['meta']['os_versions'] : []; } else { _os = []; _resolutions = []; - _densities = []; _os_versions = []; } @@ -356,4 +312,16 @@ } } + function extendMeta() { + if (_deviceDetailsDb['meta']) { + _os = countlyCommon.union(_os, _deviceDetailsDb['meta']['os']); + _resolutions = countlyCommon.union(_resolutions, _deviceDetailsDb['meta']['resolutions']); + _os_versions = countlyCommon.union(_os_versions, _deviceDetailsDb['meta']['os_versions']); + } + + if (_os_versions.length) { + _os_versions = _os_versions.join(",").replace(/\./g, ":").split(","); + } + } + }(window.countlyDeviceDetails = window.countlyDeviceDetails || {}, jQuery)); diff --git a/frontend/express/public/javascripts/countly/countly.device.js b/frontend/express/public/javascripts/countly/countly.device.js index 24371ff1103..8498bb2d0fb 100644 --- a/frontend/express/public/javascripts/countly/countly.device.js +++ b/frontend/express/public/javascripts/countly/countly.device.js @@ -5,14 +5,17 @@ _deviceDb = {}, _devices = [], _activeAppKey = 0, - _initialized = false; + _initialized = false, + _period = null; //Public Methods countlyDevice.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + if (_initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { return countlyDevice.refresh(); } + _period = countlyCommon.getPeriodForAjax(); + if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; _initialized = true; @@ -23,7 +26,8 @@ data:{ "api_key":countlyGlobal.member.api_key, "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"devices" + "method":"devices", + "period":_period }, dataType:"jsonp", success:function (json) { @@ -59,7 +63,7 @@ dataType:"jsonp", success:function (json) { countlyCommon.extendDbObj(_deviceDb, json); - setMeta(); + extendMeta(); } }); } else { @@ -109,7 +113,7 @@ }, 0); for (var i = 0; i < deviceNames.length; i++) { - var percent = (deviceNew[i] / sum) * 100; + var percent = (deviceNew[i] / sum2) * 100; chartData3[i] = {data:[ [0, deviceNew[i]] ], label:deviceNames[i]}; @@ -338,4 +342,10 @@ } } -}(window.countlyDevice = window.countlyDevice || {}, jQuery)); + function extendMeta() { + if (_deviceDb['meta']) { + _devices = countlyCommon.union(_devices, _deviceDb['meta']['devices']); + } + } + +}(window.countlyDevice = window.countlyDevice || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.event.js b/frontend/express/public/javascripts/countly/countly.event.js index 1b219e9b964..34ba28c537d 100644 --- a/frontend/express/public/javascripts/countly/countly.event.js +++ b/frontend/express/public/javascripts/countly/countly.event.js @@ -1,25 +1,24 @@ (function(countlyEvent, $, undefined) { //Private Properties - var _activeEventDbArr = [], - _activeEventDbIndex = [], - _activeEventDb = {}, + var _activeEventDb = {}, _activeEvents = {}, _activeEvent = "", _activeSegmentation = "", _activeSegmentations = [], _activeSegmentationValues = [], - _activeAppId = 0, + _activeSegmentationObj = {}, _activeAppKey = 0, - _initialized = false; + _initialized = false, + _period = null; //Public Methods - countlyEvent.initialize = function(eventChanged) { - if (!eventChanged && _initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + countlyEvent.initialize = function(forceReload) { + if (!forceReload && _initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { return countlyEvent.refresh(); } - _activeAppId = countlyCommon.ACTIVE_APP_ID; + _period = countlyCommon.getPeriodForAjax(); if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; @@ -32,7 +31,8 @@ data: { "api_key": countlyGlobal.member.api_key, "app_id" : countlyCommon.ACTIVE_APP_ID, - "method" : "get_events" + "method" : "get_events", + "period":_period }, dataType: "jsonp", success: function(json) { @@ -49,16 +49,13 @@ "api_key": countlyGlobal.member.api_key, "app_id" : countlyCommon.ACTIVE_APP_ID, "method" : "events", - "event": _activeEvent + "event": _activeEvent, + "segmentation": _activeSegmentation, + "period":_period }, dataType: "jsonp", success: function(json) { - if (json.length){ - _activeEventDbArr = json; - _activeEventDbIndex = _.pluck(json, "_id"); - _activeEventDb = _activeEventDbArr[_activeEventDbIndex.indexOf("no-segment")] || {}; - } - + _activeEventDb = json; setMeta(); } }) @@ -67,19 +64,12 @@ }); } else { _activeEventDb = {"2012":{}}; - _activeEvents = {}; return true; } }; countlyEvent.refresh = function() { if (!countlyCommon.DEBUG) { - - if (_activeAppId != countlyCommon.ACTIVE_APP_ID) { - _activeAppId = countlyCommon.ACTIVE_APP_ID; - return countlyEvent.initialize(); - } - return $.when( $.ajax({ type: "GET", @@ -105,46 +95,32 @@ "app_id" : countlyCommon.ACTIVE_APP_ID, "method" : "events", "action" : "refresh", - "event": _activeEvent + "event": _activeEvent, + "segmentation": _activeSegmentation }, dataType: "jsonp", success: function(json) { - for (var i=0; i < json.length; i++) { - var segIndex = _activeEventDbIndex.indexOf(json[i]["_id"]); - - if (segIndex == -1) { - _activeEventDbArr.push(json[i]); - _activeEventDbIndex.push(json[i]["_id"]); - } else { - _activeEventDbArr[segIndex] = $.extend(true, _activeEventDbArr[segIndex], json[i]); - } - } - - _activeEventDb = _activeEventDbArr[_activeEventDbIndex.indexOf(_activeSegmentation || "no-segment")] || {}; - - setMeta(); + countlyCommon.extendDbObj(_activeEventDb, json); + extendMeta(); } }) ).then(function(){ - return true; - }); + return true; + }); } else { _activeEventDb = {"2012":{}}; - _activeEvents = {}; return true; } }; countlyEvent.reset = function () { - _activeEventDbArr = []; - _activeEventDbIndex = []; _activeEventDb = {}; _activeEvents = {}; _activeEvent = ""; _activeSegmentation = ""; _activeSegmentations = []; _activeSegmentationValues = []; - _activeAppId = 0; + _activeSegmentationObj = {}; _activeAppKey = 0; _initialized = false; }; @@ -174,27 +150,28 @@ }; countlyEvent.setActiveEvent = function (activeEvent, callback) { - _activeEventDbArr = []; - _activeEventDbIndex = []; _activeEventDb = {}; _activeSegmentation = ""; _activeSegmentations = []; _activeSegmentationValues = []; - + _activeSegmentationObj = {}; _activeEvent = activeEvent; - $.when(countlyEvent.initialize()).then(callback); + $.when(countlyEvent.initialize(true)).then(callback); }; - countlyEvent.setActiveSegmentation = function (activeSegmentation) { + countlyEvent.setActiveSegmentation = function (activeSegmentation, callback) { + _activeEventDb = {}; _activeSegmentation = activeSegmentation; + + $.when(countlyEvent.initialize(true)).then(callback); }; countlyEvent.getActiveSegmentation = function () { return (_activeSegmentation) ? _activeSegmentation : jQuery.i18n.map["events.no-segmentation"]; }; - - countlyEvent.isSegmentedView = function() { + + countlyEvent.isSegmentedView = function() { return (_activeSegmentation) ? true : false; }; @@ -212,7 +189,7 @@ { name:"curr_segment", func:function (rangeArr, dataObj) { - return rangeArr.replace(/:/g, "."); + return rangeArr.replace(/:/g, ".").replace(/\[CLY\]/g,""); } }, { "name":"c" }, @@ -538,8 +515,6 @@ }; countlyEvent.getMultiEventData = function(eventKeysArr, callback) { - _activeAppId = countlyCommon.ACTIVE_APP_ID; - $.ajax({ type: "GET", url: countlyCommon.API_PARTS.data.r, @@ -606,21 +581,24 @@ }; function setMeta() { - var noSegIndex = _activeEventDbIndex.indexOf("no-segment"); + _activeSegmentationObj = _activeEventDb["meta"] || {}; + _activeSegmentations = _activeSegmentationObj["segments"] || []; + if (_activeSegmentations) { + _activeSegmentations.sort(); + } + _activeSegmentationValues = (_activeSegmentationObj[_activeSegmentation])? _activeSegmentationObj[_activeSegmentation]: []; + } - if (noSegIndex != -1 && _activeEventDbArr[noSegIndex]["meta"]) { - var tmpMeta = _activeEventDbArr[noSegIndex]["meta"]; - _activeSegmentations = tmpMeta["segments"] || []; + function extendMeta() { + for (var metaObj in _activeEventDb["meta"]) { + _activeSegmentationObj[metaObj] = countlyCommon.union(_activeSegmentationObj[metaObj], _activeEventDb["meta"][metaObj]); + } + _activeSegmentations = _activeSegmentationObj["segments"]; + if (_activeSegmentations) { _activeSegmentations.sort(); - - if (_activeSegmentation) { - _activeSegmentationValues = (tmpMeta[_activeSegmentation])? tmpMeta[_activeSegmentation]: []; - } - } else { - _activeSegmentations = []; - _activeSegmentationValues = []; } + _activeSegmentationValues = (_activeSegmentationObj[_activeSegmentation])? _activeSegmentationObj[_activeSegmentation]: []; } }(window.countlyEvent = window.countlyEvent || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.location.js b/frontend/express/public/javascripts/countly/countly.location.js index c70680b44c8..0bd31382e1d 100644 --- a/frontend/express/public/javascripts/countly/countly.location.js +++ b/frontend/express/public/javascripts/countly/countly.location.js @@ -3,7 +3,6 @@ // Private Properties var _periodObj = {}, _locationsDb = {}, - _activeAppKey = 0, _countries = [], _chart, _dataTable, @@ -17,73 +16,22 @@ backgroundColor:"transparent", datalessRegionColor:"#FFF" }, - _countryMap = {}, - _initialized = false; + _countryMap = {}; // Load local country names - $.get('/localization/countries/' + countlyCommon.BROWSER_LANG_SHORT + '/country.json', function (data) { + $.get('localization/countries/' + countlyCommon.BROWSER_LANG_SHORT + '/country.json', function (data) { _countryMap = data; }); // Public Methods countlyLocation.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { - return countlyLocation.refresh(); - } - - if (!countlyCommon.DEBUG) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - _initialized = true; - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r, - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"locations" - }, - dataType:"jsonp", - success:function (json) { - _locationsDb = json; - setMeta(); - } - }); - } else { - _locationsDb = {"2012":{}}; - return true; - } + _locationsDb = countlyUser.getDbObj(); + setMeta(); }; - countlyLocation.refresh = function () { - _periodObj = countlyCommon.periodObj; - - if (!countlyCommon.DEBUG) { - - if (_activeAppKey != countlyCommon.ACTIVE_APP_KEY) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - return countlyLocation.initialize(); - } - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r, - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"locations", - "action":"refresh" - }, - dataType:"jsonp", - success:function (json) { - countlyCommon.extendDbObj(_locationsDb, json); - setMeta(); - } - }); - } else { - _locationsDb = {"2012":{}}; - return true; - } + countlyLocation.refresh = function (newJSON) { + countlyCommon.extendDbObj(_locationsDb, newJSON); + extendMeta(); }; countlyLocation.reset = function () { @@ -143,19 +91,21 @@ { "name":"n" } ]); + locationData.chartData = _.sortBy(locationData.chartData, function(obj) { return -obj.t; }); + if (options && options.maxCountries && locationData.chartData) { if (locationData.chartData.length > options.maxCountries) { locationData.chartData = locationData.chartData.splice(0, options.maxCountries); } } - - for (var i = 0; i < locationData.chartData.length; i++) { + + for (var i = 0; i < locationData.chartData.length; i++) { locationData.chartData[i]['country_flag'] = - "
    " + + "
    " + locationData.chartData[i]['country']; } - return _.sortBy(locationData.chartData, function(obj) { return -obj.t; }); + return locationData.chartData; }; countlyLocation.clearLocationObject = function (obj) { @@ -183,7 +133,7 @@ countlyLocation.changeLanguage = function () { // Load local country names - return $.get('/localization/countries/' + countlyCommon.BROWSER_LANG_SHORT + '/country.json', function (data) { + return $.get('localization/countries/' + countlyCommon.BROWSER_LANG_SHORT + '/country.json', function (data) { _countryMap = data; }); }; @@ -248,7 +198,7 @@ function reDraw() { var chartData = {cols:[], rows:[]}; - var tt = countlyCommon.extractTwoLevelData(_locationsDb, _locationsDb["countries"], countlyLocation.clearLocationObject, [ + var tt = countlyCommon.extractTwoLevelData(_locationsDb, _countries, countlyLocation.clearLocationObject, [ { "name":"country", "func":function (rangeArr, dataObj) { @@ -279,10 +229,6 @@ _chart.draw(_dataTable, _chartOptions); } - function geoDataSortHelper(a, b) { - return ((a["t"] > b["t"]) ? -1 : ((a["t"] < b["t"]) ? 1 : 0)); - } - function setMeta() { if (_locationsDb['meta']) { _countries = (_locationsDb['meta']['countries']) ? _locationsDb['meta']['countries'] : []; @@ -291,4 +237,10 @@ } } + function extendMeta() { + if (_locationsDb['meta']) { + _countries = countlyCommon.union(_countries, _locationsDb['meta']['countries']); + } + } + }(window.countlyLocation = window.countlyLocation || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.map.helper.js b/frontend/express/public/javascripts/countly/countly.map.helper.js new file mode 100644 index 00000000000..276b5bb7255 --- /dev/null +++ b/frontend/express/public/javascripts/countly/countly.map.helper.js @@ -0,0 +1,81 @@ +(function (countlyMapHelper, $, undefined) { + + // Private Properties + var _chart, + _dataTable, + _chartElementId = "geo-chart", + _chartOptions = { + displayMode:'region', + colorAxis:{minValue:0, colors:['#D7F1D8', '#6BB96E']}, + resolution:'countries', + toolTip:{textStyle:{color:'#FF0000'}, showColorCode:false}, + legend:"none", + backgroundColor:"transparent", + datalessRegionColor:"#FFF" + }, + _mapData = [], + _countryMap = {}; + + $.get('localization/countries/en/country.json', function (data) { + _countryMap = data; + }); + + countlyMapHelper.drawGeoChart = function (options, locationData) { + if (options) { + if (options.chartElementId) { + _chartElementId = options.chartElementId; + } + + if (options.height) { + _chartOptions.height = options.height; + + //preserve the aspect ratio of the chart if height is given + _chartOptions.width = (options.height * 556 / 347); + } + } + + _mapData = locationData; + + if (google.visualization) { + draw(); + } else { + google.load('visualization', '1', {'packages':['geochart'], callback:draw}); + } + }; + + //Private Methods + function draw() { + var chartData = {cols:[], rows:[]}; + + _chart = new google.visualization.GeoChart(document.getElementById(_chartElementId)); + + chartData.cols = [ + {id:'country', label:jQuery.i18n.map["countries.table.country"], type:'string'}, + {id:'total', label:jQuery.i18n.map["common.total"], type:'number'} + ]; + + chartData.rows = _.map(_mapData, function (value, key, list) { + value.country = _countryMap[value.country] || "Unknown"; + + if (value.country == "European Union" || value.country == "Unknown") { + return {c:[ + {v:""}, + {v:value.value} + ]}; + } + return {c:[ + {v:value.country}, + {v:value.value} + ]}; + }); + + _dataTable = new google.visualization.DataTable(chartData); + + _chartOptions['region'] = "world"; + _chartOptions['resolution'] = 'countries'; + _chartOptions["displayMode"] = "region"; + + _chart.draw(_dataTable, _chartOptions); + } + +}(window.countlyMapHelper = window.countlyMapHelper || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.session.js b/frontend/express/public/javascripts/countly/countly.session.js index 39e2b202e55..b6059f8e995 100644 --- a/frontend/express/public/javascripts/countly/countly.session.js +++ b/frontend/express/public/javascripts/countly/countly.session.js @@ -3,67 +3,17 @@ //Private Properties var _periodObj = {}, _sessionDb = {}, - _durations = [], - _activeAppKey = 0, - _initialized = false; + _durations = []; //Public Methods countlySession.initialize = function () { - if (_initialized && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { - return countlySession.refresh(); - } - - if (!countlyCommon.DEBUG) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - _initialized = true; - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r, - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"sessions" - }, - dataType:"jsonp", - success:function (json) { - _sessionDb = json; - setMeta(); - } - }); - } else { - _sessionDb = {"2012":{}}; - return true; - } + _sessionDb = countlyUser.getDbObj(); + setMeta(); }; - countlySession.refresh = function () { - if (!countlyCommon.DEBUG) { - - if (_activeAppKey != countlyCommon.ACTIVE_APP_KEY) { - _activeAppKey = countlyCommon.ACTIVE_APP_KEY; - return countlySession.initialize(); - } - - return $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.data.r, - data:{ - "api_key":countlyGlobal.member.api_key, - "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"sessions", - "action":"refresh" - }, - dataType:"jsonp", - success:function (json) { - countlyCommon.extendDbObj(_sessionDb, json); - setMeta(); - } - }); - } else { - _sessionDb = {"2012":{}}; - return true; - } + countlySession.refresh = function (newJSON) { + countlyCommon.extendDbObj(_sessionDb, newJSON); + extendMeta(); }; countlySession.reset = function () { @@ -81,6 +31,10 @@ tmp_y, currentTotal = 0, previousTotal = 0, + currentPayingTotal = 0, + previousPayingTotal = 0, + currentMsgEnabledTotal = 0, + previousMsgEnabledTotal = 0, currentNew = 0, previousNew = 0, currentUnique = 0, @@ -99,40 +53,70 @@ tmp_x = countlyCommon.getDescendantProp(_sessionDb, _periodObj.uniquePeriodArr[i]); tmp_x = countlySession.clearSessionObject(tmp_x); currentUnique += tmp_x["u"]; + currentPayingTotal += tmp_x["p"]; + currentMsgEnabledTotal += tmp_x["m"]; } var tmpUniqObj, - tmpCurrentUniq = 0; + tmpCurrentUniq = 0, + tmpCurrentPaying = 0, + tmpCurrentMsgEnabled = 0; for (var i = 0; i < (_periodObj.uniquePeriodCheckArr.length); i++) { tmpUniqObj = countlyCommon.getDescendantProp(_sessionDb, _periodObj.uniquePeriodCheckArr[i]); tmpUniqObj = countlySession.clearSessionObject(tmpUniqObj); tmpCurrentUniq += tmpUniqObj["u"]; + tmpCurrentPaying += tmpUniqObj["p"]; + tmpCurrentMsgEnabled += tmpUniqObj["m"]; } + //console.log(currentPayingTotal + " " + tmpCurrentPaying) + if (currentUnique > tmpCurrentUniq) { currentUnique = tmpCurrentUniq; } + if (currentPayingTotal > tmpCurrentPaying) { + currentPayingTotal = tmpCurrentPaying; + } + + if (currentMsgEnabledTotal > tmpCurrentMsgEnabled) { + currentMsgEnabledTotal = tmpCurrentMsgEnabled; + } + for (var i = 0; i < (_periodObj.previousUniquePeriodArr.length); i++) { tmp_y = countlyCommon.getDescendantProp(_sessionDb, _periodObj.previousUniquePeriodArr[i]); tmp_y = countlySession.clearSessionObject(tmp_y); previousUnique += tmp_y["u"]; + previousPayingTotal += tmp_y["p"]; + previousMsgEnabledTotal += tmp_y["m"]; } var tmpUniqObj2, - tmpPreviousUniq = 0; + tmpPreviousUniq = 0, + tmpPreviousPaying = 0, + tmpPreviousMsgEnabled = 0; for (var i = 0; i < (_periodObj.previousUniquePeriodCheckArr.length); i++) { tmpUniqObj2 = countlyCommon.getDescendantProp(_sessionDb, _periodObj.previousUniquePeriodCheckArr[i]); tmpUniqObj2 = countlySession.clearSessionObject(tmpUniqObj2); tmpPreviousUniq += tmpUniqObj2["u"]; + tmpPreviousPaying += tmpUniqObj2["p"]; + tmpPreviousMsgEnabled += tmpUniqObj2["m"]; } if (previousUnique > tmpPreviousUniq) { previousUnique = tmpPreviousUniq; } + if (previousPayingTotal > tmpPreviousPaying) { + previousPayingTotal = tmpPreviousPaying; + } + + if (currentMsgEnabledTotal > tmpCurrentMsgEnabled) { + currentMsgEnabledTotal = tmpCurrentMsgEnabled; + } + for (var i = 0; i < (_periodObj.currentPeriodArr.length); i++) { tmp_x = countlyCommon.getDescendantProp(_sessionDb, _periodObj.currentPeriodArr[i]); tmp_y = countlyCommon.getDescendantProp(_sessionDb, _periodObj.previousPeriodArr[i]); @@ -160,11 +144,14 @@ previousNew = tmp_y["n"]; currentUnique = tmp_x["u"]; previousUnique = tmp_y["u"]; - currentDuration = tmp_x["d"]; previousDuration = tmp_y["d"]; currentEvents = tmp_x["e"]; previousEvents = tmp_y["e"]; + currentPayingTotal = tmp_x["p"]; + previousPayingTotal = tmp_y["p"]; + currentMsgEnabledTotal = tmp_x["m"]; + previousMsgEnabledTotal = tmp_y["m"]; } var sessionDuration = (currentDuration / 60), @@ -181,6 +168,8 @@ changeReturning = countlyCommon.getPercentChange((previousUnique - previousNew), (currentNew - currentNew)), changeEvents = countlyCommon.getPercentChange(previousEvents, currentEvents), changeEventsPerUser = countlyCommon.getPercentChange(previousEventsPerUser, eventsPerUser), + changePaying = countlyCommon.getPercentChange(previousPayingTotal, currentPayingTotal), + changeMsgEnabled = countlyCommon.getPercentChange(previousMsgEnabledTotal, currentMsgEnabledTotal), sparkLines = calcSparklineData(); var timeSpentString = (sessionDuration.toFixed(1)) + " " + jQuery.i18n.map["common.minute.abrv"]; @@ -202,13 +191,29 @@ "trend":changeTotal.trend, "sparkline":sparkLines.total }, + "paying-users":{ + "total":currentPayingTotal, + "prev-total":previousPayingTotal, + "change":changePaying.percent, + "trend":changePaying.trend, + "isEstimate":isEstimate + }, "total-users":{ "total":currentUnique, + "prev-total":previousUnique, "change":changeUnique.percent, "trend":changeUnique.trend, "sparkline":sparkLines.unique, "isEstimate":isEstimate }, + "messaging-users":{ + "total":currentMsgEnabledTotal, + "prev-total":previousMsgEnabledTotal, + "change":changeMsgEnabled.percent, + "trend":changeMsgEnabled.trend, + "sparkline":sparkLines.msg, + "isEstimate":isEstimate + }, "new-users":{ "total":currentNew, "change":changeNew.percent, @@ -384,6 +389,24 @@ return countlyCommon.extractChartData(_sessionDb, countlySession.clearSessionObject, chartData, dataProps); }; + countlySession.getMsgUserDPActive = function () { + + var chartData = [ + { data:[], label:jQuery.i18n.map["common.table.total-users"], color: countlyCommon.GRAPH_COLORS[0]}, + { data:[], label:jQuery.i18n.map["common.table.messaging-users"], color:countlyCommon.GRAPH_COLORS[1] } + ], + dataProps = [ + { + name:"u" + }, + { + name:"m" + } + ]; + + return countlyCommon.extractChartData(_sessionDb, countlySession.clearSessionObject, chartData, dataProps); + }; + countlySession.getDurationDP = function () { var chartData = [ @@ -488,9 +511,11 @@ if (!obj["u"]) obj["u"] = 0; if (!obj["d"]) obj["d"] = 0; if (!obj["e"]) obj["e"] = 0; + if (!obj["p"]) obj["p"] = 0; + if (!obj["m"]) obj["m"] = 0; } else { - obj = {"t":0, "n":0, "u":0, "d":0, "e":0}; + obj = {"t":0, "n":0, "u":0, "d":0, "e":0, "p":0, "m":0}; } return obj; @@ -514,8 +539,8 @@ return durationRange[index]; }; - - countlySession.getDurationIndex = function (duration) { + + countlySession.getDurationIndex = function (duration) { var sec = jQuery.i18n.map["common.seconds"], min = jQuery.i18n.map["common.minutes"], hr = jQuery.i18n.map["common.hour"]; @@ -589,7 +614,7 @@ //Private Methods function calcSparklineData() { - var sparkLines = {"total":[], "nev":[], "unique":[], "returning":[], "total-time":[], "avg-time":[], "events":[], "avg-events":[]}; + var sparkLines = {"total":[], "nev":[], "unique":[], "returning":[], "total-time":[], "avg-time":[], "events":[], "avg-events":[], "msg":[]}; if (!_periodObj.isSpecialPeriod) { for (var i = _periodObj.periodMin; i < (_periodObj.periodMax + 1); i++) { @@ -604,6 +629,7 @@ sparkLines["avg-time"][sparkLines["avg-time"].length] = (tmp_x["t"] == 0) ? 0 : (tmp_x["d"] / tmp_x["t"]); sparkLines["events"][sparkLines["events"].length] = tmp_x["e"]; sparkLines["avg-events"][sparkLines["avg-events"].length] = (tmp_x["u"] == 0) ? 0 : (tmp_x["e"] / tmp_x["u"]); + sparkLines["msg"][sparkLines["msg"].length] = tmp_x["m"]; } } else { for (var i = 0; i < (_periodObj.currentPeriodArr.length); i++) { @@ -618,6 +644,7 @@ sparkLines["avg-time"][sparkLines["avg-time"].length] = (tmp_x["t"] == 0) ? 0 : (tmp_x["d"] / tmp_x["t"]); sparkLines["events"][sparkLines["events"].length] = tmp_x["e"]; sparkLines["avg-events"][sparkLines["avg-events"].length] = (tmp_x["u"] == 0) ? 0 : (tmp_x["e"] / tmp_x["u"]); + sparkLines["msg"][sparkLines["msg"].length] = tmp_x["m"]; } } @@ -635,4 +662,11 @@ _durations = []; } } -}(window.countlySession = window.countlySession || {}, jQuery)); \ No newline at end of file + + function extendMeta() { + if (_sessionDb['meta']) { + _durations = countlyCommon.union(_durations, _sessionDb['meta']['d-ranges']); + } + } + +}(window.countlySession = window.countlySession || {}, jQuery)); diff --git a/frontend/express/public/javascripts/countly/countly.template.js b/frontend/express/public/javascripts/countly/countly.template.js index d0fdb6c826d..a1c8145fde3 100644 --- a/frontend/express/public/javascripts/countly/countly.template.js +++ b/frontend/express/public/javascripts/countly/countly.template.js @@ -11,7 +11,11 @@ var countlyView = Backbone.View.extend({ this.template = Handlebars.compile($("#template-analytics-common").html()); }, dateChanged:function () { //called when user changes the date selected - this.renderCommon(); + if (Backbone.history.fragment == "/") { + this.refresh(true); + } else { + this.refresh(); + } }, appChanged:function () { //called when user changes selected app from the sidebar countlyEvent.reset(); @@ -44,16 +48,14 @@ var countlyView = Backbone.View.extend({ return this; }, - renderCommon:function (isRefresh) { - }, // common render function of the view + renderCommon:function (isRefresh) {}, // common render function of the view refresh:function () { // resfresh function for the view called every 10 seconds by default return true; }, restart:function () { // triggered when user is active after idle period this.refresh(); }, - destroy:function () { - } + destroy:function () {} }); var initializeOnce = _.once(function() { @@ -112,13 +114,56 @@ $.extend(Template.prototype, { */ (function (CountlyHelpers, $, undefined) { - CountlyHelpers.popup = function (elementId, custClass) { + CountlyHelpers.parseAndShowMsg = function (msg) { + if (!msg || !msg.length) { + return true; + } + + if (_.isArray(msg)) { + msg = msg[0]; + } + + var type = "info", + message = "", + msgArr = msg.split("|"); + + if (msgArr.length > 1) { + type = msgArr[0]; + message = msgArr[1]; + } else { + message = msg; + } + + Messenger().post({ + message: message, + type: type, + hideAfter: 10, + showCloseButton: true + }); + + delete countlyGlobal["message"]; + }; + + CountlyHelpers.popup = function (element, custClass, isHTML) { var dialog = $("#cly-popup").clone(); dialog.removeAttr("id"); if (custClass) { dialog.addClass(custClass); } - dialog.find(".content").html($(elementId).html()); + + if (isHTML) { + dialog.find(".content").html(element); + } else { + dialog.find(".content").html($(element).html()); + } + + revealDialog(dialog); + }; + + CountlyHelpers.openResource = function(url) { + var dialog = $("#cly-resource").clone(); + dialog.removeAttr("id"); + dialog.find(".content").html(""); revealDialog(dialog); }; @@ -135,7 +180,7 @@ $.extend(Template.prototype, { CountlyHelpers.confirm = function (msg, type, callback, buttonText) { var dialog = $("#cly-confirm").clone(); dialog.removeAttr("id"); - dialog.find(".message").text(msg); + dialog.find(".message").html(msg); if (buttonText && buttonText.length == 2) { dialog.find("#dialog-cancel").text(buttonText[0]); @@ -154,7 +199,139 @@ $.extend(Template.prototype, { }); }; - CountlyHelpers.refreshTable = function(dTable, newDataArr) { + CountlyHelpers.loading = function (msg) { + var dialog = $("#cly-loading").clone(); + dialog.removeAttr("id"); + dialog.find(".message").html(msg); + dialog.addClass('cly-loading'); + revealDialog(dialog); + return dialog; + }; + + CountlyHelpers.setUpDateSelectors = function(self) { + $("#month").text(moment().year()); + $("#day").text(moment().format("MMM")); + $("#yesterday").text(moment().subtract("days",1).format("Do")); + + $("#date-selector").find(">.button").click(function () { + if ($(this).hasClass("selected")) { + return true; + } + + self.dateFromSelected = null; + self.dateToSelected = null; + + $(".date-selector").removeClass("selected").removeClass("active"); + $(this).addClass("selected"); + var selectedPeriod = $(this).attr("id"); + + if (countlyCommon.getPeriod() == selectedPeriod) { + return true; + } + + countlyCommon.setPeriod(selectedPeriod); + + self.dateChanged(selectedPeriod); + + $("#" + selectedPeriod).addClass("active"); + }); + + $("#date-selector").find(">.button").each(function(){ + if (countlyCommon.getPeriod() == $(this).attr("id")) { + $(this).addClass("active").addClass("selected"); + } + }); + }; + + CountlyHelpers.initializeSelect = function (element) { + element = element || $("#content-container"); + element.off("click", ".cly-select").on("click", ".cly-select", function (e) { + if ($(this).hasClass("disabled")) { + return true; + } + + $(this).removeClass("req"); + + var selectItems = $(this).find(".select-items"), + itemCount = selectItems.find(".item").length; + + if (!selectItems.length) { + return false; + } + + $(".cly-select").find(".search").remove(); + + if (selectItems.is(":visible")) { + $(this).removeClass("active"); + } else { + $(".cly-select").removeClass("active"); + $(".select-items").hide(); + $(this).addClass("active"); + + if (itemCount > 10 && !$(this).hasClass("centered")) { + $("").insertBefore($(this).find(".select-items")); + } + } + + if ($(this).hasClass("centered")) { + var height = $(this).find(".select-items").height(); + $(this).find(".select-items").css("margin-top", (-(height/2).toFixed(0) - ($(this).height()/2).toFixed(0)) + "px"); + } + + if ($(this).find(".select-items").is(":visible")) { + $(this).find(".select-items").hide(); + } else { + $(this).find(".select-items").show(); + $(this).find(".select-items>div").addClass("scroll-list"); + $(this).find(".scroll-list").slimScroll({ + height:'100%', + start:'top', + wheelStep:10, + position:'right', + disableFadeOut:true + }); + } + + $(this).find(".search input").focus(); + + $("#date-picker").hide(); + e.stopPropagation(); + }); + + element.off("click", ".select-items .item").on("click", ".select-items .item", function () { + var selectedItem = $(this).parents(".cly-select").find(".text"); + selectedItem.text($(this).text()); + selectedItem.data("value", $(this).data("value")); + }); + + element.off("click", ".cly-select .search").on("click", ".cly-select .search", function (e) { + e.stopPropagation(); + }); + + element.off("keyup", ".cly-select .search input").on("keyup", ".cly-select .search input", function(event) { + if (!$(this).val()) { + $(this).parents(".cly-select").find(".item").removeClass("hidden"); + } else { + $(this).parents(".cly-select").find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); + $(this).parents(".cly-select").find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); + } + }); + + element.off('mouseenter').on('mouseenter', ".cly-select .item", function () { + var item = $(this); + + if (this.offsetWidth < this.scrollWidth && !item.attr('title')) { + item.attr('title', item.text()); + } + }); + + $(window).click(function () { + $(".select-items").hide(); + $(".cly-select").find(".search").remove(); + }); + }; + + CountlyHelpers.refreshTable = function(dTable, newDataArr) { var oSettings = dTable.fnSettings(); dTable.fnClearTable(false); @@ -206,47 +383,94 @@ $.extend(Template.prototype, { }); } }; + + CountlyHelpers.appIdsToNames = function(context){ + var ret = ""; + + for (var i = 0; i < context.length; i++) { + if (!context[i]) { + continue; + } else if (!countlyGlobal['apps'][context[i]]) { + ret += 'deleted app'; + } else { + ret += countlyGlobal['apps'][context[i]]["name"]; + } + + if (context.length > 1 && i != context.length - 1) { + ret += ", "; + } + } + + return ret; + }; + + CountlyHelpers.messageText = function(messagePerLocale) { + if (!messagePerLocale) { + return ''; + } else if (messagePerLocale['default']) { + return messagePerLocale['default']; + } else if (messagePerLocale.en) { + return messagePerLocale.en; + } else { + for (var locale in messagePerLocale) return messagePerLocale[locale]; + } + return ''; + }; + + CountlyHelpers.clip = function(f) { + return function(opt) { + var res = f(opt); + return '
    ' + (res || jQuery.i18n.map['push.no-message']) + '
    '; + } + }; - CountlyHelpers.initializeSelect = function () { - $("#content-container").on("click", ".cly-select", function (e) { + CountlyHelpers.initializeTextSelect = function () { + $("#content-container").on("click", ".cly-text-select", function (e) { if ($(this).hasClass("disabled")) { return true; } - $(this).removeClass("req"); + initItems($(this)); - var selectItems = $(this).find(".select-items"), - itemCount = selectItems.find(".item").length; + $("#date-picker").hide(); + e.stopPropagation(); + }); - if (!selectItems.length) { - return false; - } + $("#content-container").on("click", ".select-items .item", function () { + var selectedItem = $(this).parents(".cly-text-select").find(".text"); + selectedItem.text($(this).text()); + selectedItem.data("value", $(this).data("value")); + selectedItem.val($(this).text()); + }); - $(".cly-select").find(".search").remove(); + $("#content-container").on("keyup", ".cly-text-select input", function(event) { + initItems($(this).parents(".cly-text-select"), true); - if (selectItems.is(":visible")) { - $(this).removeClass("active"); - } else { - $(".cly-select").removeClass("active"); - $(".select-items").hide(); - $(this).addClass("active"); + $(this).data("value", $(this).val()); - if (itemCount > 10 && !$(this).hasClass("centered")) { - $("").insertBefore($(this).find(".select-items")); - } + if (!$(this).val()) { + $(this).parents(".cly-text-select").find(".item").removeClass("hidden"); + } else { + $(this).parents(".cly-text-select").find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); + $(this).parents(".cly-text-select").find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); } + }); - if ($(this).hasClass("centered")) { - var height = $(this).find(".select-items").height(); - $(this).find(".select-items").css("margin-top", (-(height/2).toFixed(0) - ($(this).height()/2).toFixed(0)) + "px"); + function initItems(select, forceShow) { + select.removeClass("req"); + + var selectItems = select.find(".select-items"); + + if (!selectItems.length) { + return false; } - if ($(this).find(".select-items").is(":visible")) { - $(this).find(".select-items").hide(); + if (select.find(".select-items").is(":visible") && !forceShow) { + select.find(".select-items").hide(); } else { - $(this).find(".select-items").show(); - $(this).find(".select-items>div").addClass("scroll-list"); - $(this).find(".scroll-list").slimScroll({ + select.find(".select-items").show(); + select.find(".select-items>div").addClass("scroll-list"); + select.find(".scroll-list").slimScroll({ height:'100%', start:'top', wheelStep:10, @@ -254,43 +478,53 @@ $.extend(Template.prototype, { disableFadeOut:true }); } + } - $(this).find(".search input").focus(); - - $("#date-picker").hide(); - e.stopPropagation(); + $(window).click(function () { + $(".select-items").hide(); }); + }; - $("#content-container").on("click", ".select-items .item", function () { - var selectedItem = $(this).parents(".cly-select").find(".text"); - selectedItem.text($(this).text()); - selectedItem.data("value", $(this).data("value")); + CountlyHelpers.initializeHugeDropdown = function () { + var dropdownHideFunc; + + $("#content-container").on("mouseenter", ".cly-huge-dropdown-activator", function (e) { + clearInterval(dropdownHideFunc); + + var target = $(this).next(".cly-huge-dropdown"); + + target.trigger("huge-dropdown-init"); + target.find(".scroll").slimScroll({ + height:'100%', + start:'top', + wheelStep:10, + position:'right', + disableFadeOut:true + }); + + target.find(".button-container .title").text($(this).text()); + target.fadeIn("slow"); }); - $("#content-container").on("click", ".cly-select .search", function (e) { - e.stopPropagation(); + $("#content-container").on("mouseleave", ".cly-huge-dropdown", function (e) { + var target = $(this); + dropdownHideFunc = setTimeout(function() { target.fadeOut("fast") }, 500); }); - $("#content-container").on("keyup", ".cly-select .search input", function(event) { - if (!$(this).val()) { - $(this).parents(".cly-select").find(".item").removeClass("hidden"); - } else { - $(this).parents(".cly-select").find(".item:not(:contains('" + $(this).val() + "'))").addClass("hidden"); - $(this).parents(".cly-select").find(".item:contains('" + $(this).val() + "')").removeClass("hidden"); - } + $("#content-container").on("mouseenter", ".cly-huge-dropdown", function (e) { + clearInterval(dropdownHideFunc); }); - $(window).click(function () { - $(".select-items").hide(); - $(".cly-select").find(".search").remove(); + $("#content-container").on("close", ".cly-huge-dropdown", function (e) { + $(this).fadeOut("fast"); }); }; function revealDialog(dialog) { $("body").append(dialog); - var dialogHeight = dialog.height(), - dialogWidth = dialog.width(); + var dialogHeight = dialog.outerHeight() - 2, + dialogWidth = dialog.outerWidth(); dialog.css({ "height":dialogHeight, @@ -302,23 +536,57 @@ $.extend(Template.prototype, { $("#overlay").fadeIn(); dialog.fadeIn(); } + + function changeDialogHeight(dialog, height, animate) { + var dialogHeight = height || dialog.attr('data-height') || dialog.height() + 15, + dialogWidth = dialog.width(), + maxHeight = $("#sidebar").height() - 40; + + dialog.attr('data-height', height); + + if (dialogHeight > maxHeight) { + dialog[animate ? 'animate' : 'css']({ + "height":maxHeight, + "margin-top":Math.floor(-maxHeight / 2), + "width":dialogWidth, + "margin-left":Math.floor(-dialogWidth / 2), + "overflow-y": "auto" + }); + } else { + dialog[animate ? 'animate' : 'css']({ + "height":dialogHeight, + "margin-top":Math.floor(-dialogHeight / 2), + "width":dialogWidth, + "margin-left":Math.floor(-dialogWidth / 2) + }); + } + } + + CountlyHelpers.revealDialog = revealDialog; + CountlyHelpers.changeDialogHeight = changeDialogHeight; + + CountlyHelpers.removeDialog = function(dialog){ + dialog.remove(); + $("#overlay").fadeOut(); + }; $(document).ready(function () { $("#overlay").click(function () { - $(".dialog:visible").fadeOut().remove(); - $(this).hide(); + var dialog = $(".dialog:visible:not(.cly-loading)"); + if (dialog.length) { + dialog.fadeOut().remove(); + $(this).hide(); + } }); $("#dialog-ok, #dialog-cancel, #dialog-continue").live('click', function () { - $(".dialog:visible").fadeOut().remove(); - $("#overlay").hide(); + $(this).parents(".dialog:visible").fadeOut().remove(); + if (!$('.dialog:visible').length) $("#overlay").hide(); }); $(document).keyup(function (e) { // ESC if (e.keyCode == 27) { - var elTop = $(".dialog:visible").offset().top; - $(".dialog:visible").animate({ top:0, opacity:0 @@ -333,481 +601,844 @@ $.extend(Template.prototype, { $("#overlay").hide(); } }); - - $.fn.dataTableExt.oPagination.four_button = { - "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) - { - nFirst = document.createElement( 'span' ); - nPrevious = document.createElement( 'span' ); - nNext = document.createElement( 'span' ); - nLast = document.createElement( 'span' ); - - nFirst.innerHTML = ""; - nPrevious.innerHTML = ""; - nNext.innerHTML = ""; - nLast.innerHTML = ""; + }); - nFirst.className = "paginate_button first"; - nPrevious.className = "paginate_button previous"; - nNext.className="paginate_button next"; - nLast.className = "paginate_button last"; +}(window.CountlyHelpers = window.CountlyHelpers || {}, jQuery)); - nPaging.appendChild( nFirst ); - nPaging.appendChild( nPrevious ); - nPaging.appendChild( nNext ); - nPaging.appendChild( nLast ); +$.expr[":"].contains = $.expr.createPseudo(function(arg) { + return function( elem ) { + return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; + }; +}); - $(nFirst).click( function () { - oSettings.oApi._fnPageChange( oSettings, "first" ); - fnCallbackDraw( oSettings ); - } ); - - $(nPrevious).click( function() { - oSettings.oApi._fnPageChange( oSettings, "previous" ); - fnCallbackDraw( oSettings ); - } ); +window.DashboardView = countlyView.extend({ + selectedView:"#draw-total-sessions", + onlineUsersGauge:null, + newUsersGauge:null, + initialize:function () { + this.template = Handlebars.compile($("#dashboard-template").html()); + }, + beforeRender: function() { + return $.when(countlyUser.initialize(), countlyCarrier.initialize(), countlyDeviceDetails.initialize()).then(function () {}); + }, + afterRender: function() { + countlyLocation.drawGeoChart({height:290}); + }, + pageScript:function () { + $("#total-user-estimate-ind").on("click", function() { + CountlyHelpers.alert($("#total-user-estimate-exp").html(), "black"); + }); - $(nNext).click( function() { - oSettings.oApi._fnPageChange( oSettings, "next" ); - fnCallbackDraw( oSettings ); - } ); + $(".widget-content .inner").click(function () { + $(".big-numbers").removeClass("active"); + $(".big-numbers .select").removeClass("selected"); + $(this).parent(".big-numbers").addClass("active"); + $(this).find('.select').addClass("selected"); + }); - $(nLast).click( function() { - oSettings.oApi._fnPageChange( oSettings, "last" ); - fnCallbackDraw( oSettings ); - } ); + $(".bar-inner").on({ + mouseenter:function () { + var number = $(this).parent().next(); - $(nFirst).bind( 'selectstart', function () { return false; } ); - $(nPrevious).bind( 'selectstart', function () { return false; } ); - $(nNext).bind( 'selectstart', function () { return false; } ); - $(nLast).bind( 'selectstart', function () { return false; } ); + number.text($(this).data("item")); + number.css({"color":$(this).css("background-color")}); }, + mouseleave:function () { + var number = $(this).parent().next(); - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } + number.text(number.data("item")); + number.css({"color":$(this).parent().find(".bar-inner:first-child").css("background-color")}); + } + }); - var an = oSettings.aanFeatures.p; - for ( var i=0, iLen=an.length ; i y) ? 1 : 0)); - }; + var newPage = $("
    " + self.template(self.templateData) + "
    "); + $(".rev-container").replaceWith(newPage.find(".rev-container")); + $(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); + $(".widget-header .title").replaceWith(newPage.find(".widget-header .title")); - jQuery.fn.dataTableExt.oSort['customDate-desc'] = function(x, y) { - x = getCustomDateInt(x); - y = getCustomDateInt(y); + $("#big-numbers-container").find(".big-numbers").each(function(i, el) { + var newEl = $(newPage.find("#big-numbers-container .big-numbers")[i]); - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }; + if (isFromIdle) { + $(el).find(".number").replaceWith(newEl.find(".number")); + } else { + var currNumberEl = $(el).find(".number .value"), + currNumberVal = parseFloat(currNumberEl.text()) || 0, + currNumPost = currNumberEl.text().replace(currNumberVal, ''), + targetValue = parseFloat(newEl.find(".number .value").text()), + targetPost = newEl.find(".number .value").text().replace(targetValue, ''); + + if (targetValue != currNumberVal) { + if (targetValue < currNumberVal || (targetPost.length && targetPost != currNumPost)) { + $(el).find(".number").replaceWith(newEl.find(".number")); + } else { + jQuery({someValue: currNumberVal, currEl: currNumberEl}).animate({someValue: targetValue}, { + duration: 2000, + easing:'easeInOutQuint', + step: function() { + if ((targetValue + "").indexOf(".") == -1) { + this.currEl.text(Math.round(this.someValue) + targetPost); + } else { + this.currEl.text(parseFloat((this.someValue).toFixed(1)) + targetPost); + } + } + }); + } + } + } - function getDateRangeInt(s) { - s = s.split("-")[0]; - var mEnglish = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + $(el).find(".trend").replaceWith(newEl.find(".trend")); + $(el).find(".spark").replaceWith(newEl.find(".spark")); + }); - if (s.indexOf(":") != -1) { - var mName = (s.split(" ")[1]).split(",")[0]; + self.drawGraph(); - return s.replace(mName, parseInt(mEnglish.indexOf(mName))).replace(/[:, ]/g, ""); - } else { - var parts = s.split(" "); - if (parts.length > 1) { - return parseInt(mEnglish.indexOf(parts[1]) * 100) + parseInt(parts[0]); - } else { - return parts[0].replace(/[><]/g, ""); - } - } - } - - jQuery.fn.dataTableExt.oSort['dateRange-asc'] = function(x, y) { - x = getDateRangeInt(x); - y = getDateRangeInt(y); - - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; + $(".usparkline").peity("bar", { width:"100%", height:"30", colour:"#6BB96E", strokeColour:"#6BB96E", strokeWidth:2 }); + $(".dsparkline").peity("bar", { width:"100%", height:"30", colour:"#C94C4C", strokeColour:"#C94C4C", strokeWidth:2 }); - jQuery.fn.dataTableExt.oSort['dateRange-desc'] = function(x, y) { - x = getDateRangeInt(x); - y = getDateRangeInt(y); + if (newPage.find("#map-list-right").length == 0) { + $("#map-list-right").remove(); + } - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }; + if ($("#map-list-right").length) { + $("#map-list-right").replaceWith(newPage.find("#map-list-right")); + } else { + $(".widget.map-list").prepend(newPage.find("#map-list-right")); + } - jQuery.fn.dataTableExt.oSort['percent-asc'] = function(x, y) { - x = parseFloat($("
    ").html(x).text().replace("%","")); - y = parseFloat($("").html(y).text().replace("%","")); + self.pageScript(); + }); + }, + destroy:function () { + $("#content-top").html(""); + } +}); - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; +window.SessionView = countlyView.extend({ + beforeRender: function() { + return $.when(countlyUser.initialize()).then(function () {}); + }, + renderCommon:function (isRefresh) { - jQuery.fn.dataTableExt.oSort['percent-desc'] = function(x, y) { - x = parseFloat($("").html(x).text().replace("%","")); - y = parseFloat($("").html(y).text().replace("%","")); + var sessionData = countlySession.getSessionData(), + sessionDP = countlySession.getSessionDP(); - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + this.templateData = { + "page-title":jQuery.i18n.map["sessions.title"], + "logo-class":"sessions", + "big-numbers":{ + "count":3, + "items":[ + { + "title":jQuery.i18n.map["common.total-sessions"], + "total":sessionData.usage["total-sessions"].total, + "trend":sessionData.usage["total-sessions"].trend, + "help":"sessions.total-sessions" + }, + { + "title":jQuery.i18n.map["common.new-sessions"], + "total":sessionData.usage["new-users"].total, + "trend":sessionData.usage["new-users"].trend, + "help":"sessions.new-sessions" + }, + { + "title":jQuery.i18n.map["common.unique-sessions"], + "total":sessionData.usage["total-users"].total, + "trend":sessionData.usage["total-users"].trend, + "help":"sessions.unique-sessions" + } + ] + } }; - jQuery.fn.dataTableExt.oSort['formatted-num-asc'] = function (x, y) { - 'use strict'; - - // Define vars - var a = [], b = []; + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); + countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - // Match any character except: digits (0-9), dash (-), period (.), or backslash (/) and replace those characters with empty string. - x = x.replace(/[^\d\-\.\/]/g, ''); - y = y.replace(/[^\d\-\.\/]/g, ''); + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": sessionDP.chartData, + "aoColumns": [ + { "mData": "date", "sType":"customDate", "sTitle": jQuery.i18n.map["common.date"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.unique-sessions"] } + ] + })); - // Handle simple fractions - if (x.indexOf('/') >= 0) { - a = x.split("/"); - x = parseInt(a[0], 10) / parseInt(a[1], 10); - } - if (y.indexOf('/') >= 0) { - b = y.split("/"); - y = parseInt(b[0], 10) / parseInt(b[1], 10); + $(".d-table").stickyTableHeaders(); + } + }, + refresh:function () { + var self = this; + $.when(countlyUser.initialize()).then(function () { + if (app.activeView != self) { + return false; } + self.renderCommon(true); + newPage = $("
    " + self.template(self.templateData) + "
    "); + $(self.el).find("#big-numbers-container").html(newPage.find("#big-numbers-container").html()); - return x - y; - }; - - jQuery.fn.dataTableExt.oSort['formatted-num-desc'] = function (x, y) { - 'use strict'; + var sessionDP = countlySession.getSessionDP(); + countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); + CountlyHelpers.refreshTable(self.dtable, sessionDP.chartData); - // Define vars - var a = [], b = []; + app.localize(); + }); + } +}); - // Match any character except: digits (0-9), dash (-), period (.), or backslash (/) and replace those characters with empty string. - x = x.replace(/[^\d\-\.\/]/g, ''); - y = y.replace(/[^\d\-\.\/]/g, ''); +window.UserView = countlyView.extend({ + beforeRender: function() { + return $.when(countlyUser.initialize()).then(function () {}); + }, + renderCommon:function (isRefresh) { + var sessionData = countlySession.getSessionData(), + userDP = countlySession.getUserDP(); - // Handle simple fractions - if (x.indexOf('/') >= 0) { - a = x.split("/"); - x = parseInt(a[0], 10) / parseInt(a[1], 10); - } - if (y.indexOf('/') >= 0) { - b = y.split("/"); - y = parseInt(b[0], 10) / parseInt(b[1], 10); + this.templateData = { + "page-title":jQuery.i18n.map["users.title"], + "logo-class":"users", + "big-numbers":{ + "count":3, + "items":[ + { + "title":jQuery.i18n.map["common.total-users"], + "total":sessionData.usage["total-users"].total, + "trend":sessionData.usage["total-users"].trend, + "help":"users.total-users" + }, + { + "title":jQuery.i18n.map["common.new-users"], + "total":sessionData.usage["new-users"].total, + "trend":sessionData.usage["new-users"].trend, + "help":"users.new-users" + }, + { + "title":jQuery.i18n.map["common.returning-users"], + "total":sessionData.usage["returning-users"].total, + "trend":sessionData.usage["returning-users"].trend, + "help":"users.returning-users" + } + ] } - - return y - x; }; - jQuery.fn.dataTableExt.oSort['loyalty-asc'] = function(x, y) { - x = countlyUser.getLoyaltyIndex(x); - y = countlyUser.getLoyaltyIndex(y); - - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); + countlyCommon.drawTimeGraph(userDP.chartDP, "#dashboard-graph"); + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": userDP.chartData, + "aoColumns": [ + { "mData": "date", "sType":"customDate", "sTitle": jQuery.i18n.map["common.date"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] }, + { "mData": "returning", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.returning-users"] } + ] + })); - jQuery.fn.dataTableExt.oSort['loyalty-desc'] = function(x, y) { - x = countlyUser.getLoyaltyIndex(x); - y = countlyUser.getLoyaltyIndex(y); + $(".d-table").stickyTableHeaders(); + } + }, + refresh:function () { + var self = this; + $.when(countlyUser.initialize()).then(function () { + if (app.activeView != self) { + return false; + } + self.renderCommon(true); + newPage = $("
    " + self.template(self.templateData) + "
    "); - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }; + $(self.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container")); - jQuery.fn.dataTableExt.oSort['frequency-asc'] = function(x, y) { - x = countlyUser.getFrequencyIndex(x); - y = countlyUser.getFrequencyIndex(y); + var userDP = countlySession.getUserDP(); + countlyCommon.drawTimeGraph(userDP.chartDP, "#dashboard-graph"); + CountlyHelpers.refreshTable(self.dtable, userDP.chartData); - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; + app.localize(); + }); + } +}); - jQuery.fn.dataTableExt.oSort['frequency-desc'] = function(x, y) { - x = countlyUser.getFrequencyIndex(x); - y = countlyUser.getFrequencyIndex(y); +window.AllAppsView = countlyView.extend({ + selectedView:"#draw-total-sessions", + selectedApps: {"all":true}, + selectedCount: 0, + initialize:function () { + this.template = Handlebars.compile($("#template-allapps").html()); + }, + beforeRender: function() { + return $.when(countlyAllApps.initialize()).then(function () {}); + }, + pageScript:function () { + $(".widget-content .inner").click(function () { + $(".big-numbers").removeClass("active"); + $(".big-numbers .select").removeClass("selected"); + $(this).parent(".big-numbers").addClass("active"); + $(this).find('.select').addClass("selected"); + }); - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }; + var self = this; + $(".big-numbers .inner").click(function () { + var elID = $(this).find('.select').attr("id"); - jQuery.fn.dataTableExt.oSort['session-duration-asc'] = function(x, y) { - x = countlySession.getDurationIndex(x); - y = countlySession.getDurationIndex(y); + if (self.selectedView == "#" + elID) { + return true; + } - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }; + self.selectedView = "#" + elID; + self.drawGraph(); + }); - jQuery.fn.dataTableExt.oSort['session-duration-desc'] = function(x, y) { - x = countlySession.getDurationIndex(x); - y = countlySession.getDurationIndex(y); + app.localize(); + }, + drawGraph:function() { + var sessionDP = []; + var sessions = countlyAllApps.getSessionData(); + var data, color; + var cnt = 0; + for(var i in this.selectedApps){ + try{ + data = sessions[i][this.selectedView]; + color = countlyCommon.GRAPH_COLORS[cnt]; + if(i == "all") + sessionDP.push({data:data.data, label:data.label + " for All Apps", color:color}); + else + sessionDP.push({data:data.data, label:data.label + " for "+countlyGlobal["apps"][i].name, color:color}); + $("#"+i+" .color").css("background-color", color); + cnt++; + } + catch(err){ + + } + } + _.defer(function () { + countlyCommon.drawTimeGraph(sessionDP, "#dashboard-graph"); + + }); + }, + renderCommon:function (isRefresh) { + $("#sidebar-app-select").find(".text").text(jQuery.i18n.map["allapps.title"]); + $("#sidebar-app-select").find(".logo").css("background-image", "url('"+countlyGlobal["cdn"]+"images/favicon.png')"); + $("#sidebar-menu > .item").addClass("hide"); + $("#management-menu").removeClass("hide"); + $("#allapps-menu").removeClass("hide").css("display", "block"); + var appData = countlyAllApps.getData(); - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + this.templateData = { + "page-title":jQuery.i18n.map["allapps.title"], + "logo-class":"platforms", + "usage":[ + { + "title":jQuery.i18n.map["common.total-sessions"], + "data":0, + "id":"draw-total-sessions", + "help":"dashboard.total-sessions" + }, + { + "title":jQuery.i18n.map["common.total-users"], + "data":0, + "id":"draw-total-users", + "help":"dashboard.total-users" + }, + { + "title":jQuery.i18n.map["common.new-users"], + "data":0, + "id":"draw-new-users", + "help":"dashboard.new-users" + }, + { + "title":jQuery.i18n.map["dashboard.time-spent"], + "data":0, + "id":"draw-total-time-spent", + "help":"dashboard.total-time-spent" + }, + { + "title":jQuery.i18n.map["dashboard.avg-time-spent"], + "data":0, + "id":"draw-time-spent", + "help":"dashboard.avg-time-spent2" + }, + { + "title":jQuery.i18n.map["dashboard.avg-reqs-received"], + "data":0, + "id":"draw-avg-events-served", + "help":"dashboard.avg-reqs-received" + } + ] }; + var self = this; + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); + $(this.selectedView).parents(".big-numbers").addClass("active"); + this.pageScript(); + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": appData, + "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + $(nRow).attr("id", aData._id); + }, + "aoColumns": [ + { "mData": function(row, type){if(self.selectedApps[row._id]) return ""; else return "";}, "sWidth":"10px", "bSortable":false}, + { "mData": function(row, type){if(type == "display"){ var ret; if(row["_id"] == "all") ret = " "; else ret = " "; return ret+row.name+"
    ";} else return row.name;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.app-name"] }, + { "mData": function(row, type){if(type == "display") return "
    "+row.sessions.total; else return row.sessions.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-sessions"] }, + { "mData": function(row, type){if(type == "display") return "
    "+row.users.total; else return row.users.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-users"] }, + { "mData": function(row, type){if(type == "display") return "
    "+row.newusers.total; else return row.newusers.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.new-users"] }, + { "mData": function(row, type){if(type == "display") return "
    "+row.duration.total; else return row.duration.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-duration"] }, + { "mData": function(row, type){if(type == "display") return "
    "+row.avgduration.total; else return row.avgduration.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.average-duration"] } + ] + })); + this.drawGraph(); + $(".dataTable-bottom").append("
    Maximum number of applications to be compared (10)
    ") - $.extend($.fn.dataTable.defaults, { - "sDom": '<"dataTable-top"fpT>t<"dataTable-bottom"i>', - "bAutoWidth": false, - "sPaginationType": "four_button", - "iDisplayLength": 50, - "bDestroy": true, - "bDeferRender": true, - "oTableTools": { - "sSwfPath": "/javascripts/dom/dataTables/swf/copy_csv_xls.swf", - "aButtons": [ - { - "sExtends": "csv", - "sButtonText": "Save to CSV", - "fnClick": function (nButton, oConfig, flash) { - var tableCols = $(nButton).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, - tableData = this.fnGetTableData(oConfig).split(/\r\n|\r|\n/g).join('","').split('","'), - retStr = ""; + $(".d-table").stickyTableHeaders(); + + $('.allapps tbody').on("click", "tr", function (event){ + var td = $(event.target).closest("td"); + var row = $(this); + if(row.children().first().is(td)) + { + if(self.selectedApps[row.attr("id")]){ + row.find(".check").removeClass("icon-check").addClass("icon-unchecked"); + row.find(".color").css("background-color", "transparent"); + delete self.selectedApps[row.attr("id")]; + if(row.attr("id") != "all") + self.selectedCount--; + if(self.selectedCount==0){ + $("#empty-graph").show(); + $(".big-numbers").removeClass("active"); + $(".big-numbers .select").removeClass("selected"); + } + + } + else if(self.selectedCount < 10 || row.attr("id") == "all"){ + if(self.selectedCount==0){ + $("#empty-graph").hide(); + $(self.selectedView).parents(".big-numbers").addClass("active"); + } + if(row.attr("id") == "all"){ + $(".check.icon-check").removeClass("icon-check").addClass("icon-unchecked"); + $('.d-table').find(".color").css("background-color", "transparent"); + self.selectedApps = {}; + self.selectedCount = 0; + } + else{ + if(self.selectedApps["all"]){ + $(".d-table #all .check.icon-check").removeClass("icon-check").addClass("icon-unchecked"); + $('.d-table #all').find(".color").css("background-color", "transparent"); + delete self.selectedApps["all"]; + } + self.selectedCount++; + } + row.find(".check").removeClass("icon-unchecked").addClass("icon-check"); + self.selectedApps[row.attr("id")] = true; + } + self.drawGraph(); + } + else + { + if(row.attr("id") != "all"){ + var aData = self.dtable.fnGetData( this ); + countlyAllApps.setApp(row.attr("id")); + $("#sidebar-app-select").find(".logo").css("background-image", "url('"+countlyGlobal["cdn"]+"appimages/" + row.attr("id") + ".png')"); + $("#sidebar-app-select").find(".text").text(aData["name"]); + $("#sidebar-menu > .item").removeClass("hide"); + $("#allapps-menu").css("display", "none"); + window.location.hash = "#/"; + } + } + }); + } + }, + refresh:function () { + var self = this; + $.when(countlyAllApps.initialize()).then(function () { + if (app.activeView != self) { + return false; + } + self.renderCommon(true); + newPage = $("
    " + self.template(self.templateData) + "
    "); - for (var i = 0; i < tableData.length; i++) { - tableData[i] = tableData[i].replace("\"", ""); + var appData = countlyAllApps.getData(); + CountlyHelpers.refreshTable(self.dtable, appData); + self.drawGraph(); + app.localize(); + }); + } +}); - if (i >= tableCols.length) { - var colIndex = i % tableCols.length; +window.LoyaltyView = countlyView.extend({ + beforeRender: function() { + return $.when(countlyUser.initialize()).then(function () {}); + }, + renderCommon:function (isRefresh) { + var loyaltyData = countlyUser.getLoyaltyData(); - if (tableCols[colIndex].sType == "formatted-num") { - tableData[i] = tableData[i].replace(/,/g, ""); - } else if (tableCols[colIndex].sType == "percent") { - tableData[i] = tableData[i].replace("%", ""); - } - } + this.templateData = { + "page-title":jQuery.i18n.map["user-loyalty.title"], + "logo-class":"loyalty", + "chart-helper":"loyalty.chart", + "table-helper":"loyalty.table" + }; - if ((i + 1) % tableCols.length == 0) { - retStr += "\"" + tableData[i] + "\"\r\n"; - } else { - retStr += "\"" + tableData[i] + "\", "; - } - } + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); - this.fnSetText(flash, retStr); - } - }, - { - "sExtends": "xls", - "sButtonText": "Save for Excel", - "fnClick": function (nButton, oConfig, flash) { - var tableCols = $(nButton).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, - tableData = this.fnGetTableData(oConfig).split(/\r\n|\r|\n/g).join('\t').split('\t'), - retStr = ""; + countlyCommon.drawGraph(loyaltyData.chartDP, "#dashboard-graph", "bar"); - for (var i = 0; i < tableData.length; i++) { - if (i >= tableCols.length) { - var colIndex = i % tableCols.length; + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": loyaltyData.chartData, + "aoColumns": [ + { "mData": "l", sType:"loyalty", "sTitle": jQuery.i18n.map["user-loyalty.table.session-count"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.number-of-users"] }, + { "mData": "percent", "sType":"percent", "sTitle": jQuery.i18n.map["common.percent"] } + ] + })); - if (tableCols[colIndex].sType == "formatted-num") { - tableData[i] = parseFloat(tableData[i].replace(/,/g, "")).toLocaleString(); - } else if (tableCols[colIndex].sType == "percent") { - tableData[i] = parseFloat(tableData[i].replace("%", "")).toLocaleString(); - } else if (tableCols[colIndex].sType == "numeric") { - tableData[i] = parseFloat(tableData[i]).toLocaleString(); - } - } + $(".d-table").stickyTableHeaders(); + } + }, + refresh:function () { + var self = this; + $.when(countlyUser.initialize()).then(function () { + if (app.activeView != self) { + return false; + } - if ((i + 1) % tableCols.length == 0) { - retStr += tableData[i] + "\r\n"; - } else { - retStr += tableData[i] + "\t"; - } - } + var loyaltyData = countlyUser.getLoyaltyData(); + countlyCommon.drawGraph(loyaltyData.chartDP, "#dashboard-graph", "bar"); + CountlyHelpers.refreshTable(self.dtable, loyaltyData.chartData); + }); + } +}); - this.fnSetText(flash, retStr); - } - } - ] - }, - "fnInitComplete": function(oSettings, json) { - var saveHTML = "
    ", - searchHTML = "
    ", - tableWrapper = $("#" + oSettings.sTableId + "_wrapper"); +window.CountriesView = countlyView.extend({ + cityView: (store.get("countly_location_city")) ? store.get("countly_active_app") : false, + initialize:function () { + this.template = Handlebars.compile($("#template-analytics-countries").html()); + }, + beforeRender: function() { + return $.when(countlyUser.initialize(), countlyCity.initialize()).then(function () {}); + }, + drawTable: function() { + var tableFirstColTitle = (this.cityView) ? jQuery.i18n.map["countries.table.city"] : jQuery.i18n.map["countries.table.country"], + locationData, + firstCollData = "country_flag" - $(saveHTML).insertBefore(tableWrapper.find(".DTTT_container")); - $(searchHTML).insertBefore(tableWrapper.find(".dataTables_filter")); - tableWrapper.find(".dataTables_filter").html(tableWrapper.find(".dataTables_filter").find("input").attr("Placeholder","Search").clone(true)); + if (this.cityView) { + locationData = countlyCity.getLocationData(); + firstCollData = "city"; + } else { + locationData = countlyLocation.getLocationData(); + } - tableWrapper.find(".save-table-data").on("click", function() { - if ($(this).next(".DTTT_container").css('visibility') == 'hidden') { - $(this).next(".DTTT_container").css("visibility", 'visible'); - } else { - $(this).next(".DTTT_container").css("visibility", 'hidden'); + var activeApp = countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID]; + if (activeApp && activeApp.country) { + $("#toggle-map").text(countlyLocation.getCountryName(activeApp.country)); + } + + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": locationData, + "aoColumns": [ + { "mData": firstCollData, "sTitle": tableFirstColTitle }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } + ] + })); + + $(".d-table").stickyTableHeaders(); + }, + renderCommon:function (isRefresh) { + var sessionData = countlySession.getSessionData(); + + this.templateData = { + "page-title":jQuery.i18n.map["countries.title"], + "logo-class":"countries", + "big-numbers":{ + "count":3, + "items":[ + { + "title":jQuery.i18n.map["common.total-sessions"], + "total":sessionData.usage["total-sessions"].total, + "trend":sessionData.usage["total-sessions"].trend, + "help":"countries.total-sessions" + }, + { + "title":jQuery.i18n.map["common.total-users"], + "total":sessionData.usage["total-users"].total, + "trend":sessionData.usage["total-users"].trend, + "help":"countries.total-users" + }, + { + "title":jQuery.i18n.map["common.new-users"], + "total":sessionData.usage["new-users"].total, + "trend":sessionData.usage["new-users"].trend, + "help":"countries.new-users" } - }); + ] + }, + "chart-helper":"countries.chart", + "table-helper":"countries.table" + }; - tableWrapper.find(".search-table-data").on("click", function() { - $(this).next(".dataTables_filter").toggle(); - $(this).next(".dataTables_filter").find("input").focus(); - }); + var self = this; + $(document).bind('selectMapCountry', function () { + self.cityView = true; + store.set("countly_location_city", true); + $("#toggle-map").addClass("active"); - tableWrapper.css({"min-height": tableWrapper.height()}); - } + countlyCity.drawGeoChart({height:450}); + self.refresh(true); }); - $.fn.dataTableExt.sErrMode = 'throw'; - }); - -}(window.CountlyHelpers = window.CountlyHelpers || {}, jQuery)); + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); -$.expr[":"].contains = $.expr.createPseudo(function(arg) { - return function( elem ) { - return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; - }; -}); + if (this.cityView) { + countlyCity.drawGeoChart({height:450}); + $("#toggle-map").addClass("active"); + } else { + countlyLocation.drawGeoChart({height:450}); + } -function fillKeyEvents(keyEvents) { - if (!keyEvents.length) { - return true; - } + this.drawTable(); - $("#key-events").html(""); - for (var k = 0; k < keyEvents.length; k++) { + if (countlyCommon.CITY_DATA === false) { + $("#toggle-map").hide(); + store.set("countly_location_city", false); + } - if (!keyEvents[k]) { - continue; + $("#toggle-map").on('click', function () { + if ($(this).hasClass("active")) { + self.cityView = false; + countlyLocation.drawGeoChart({height:450}); + $(this).removeClass("active"); + self.refresh(true); + store.set("countly_location_city", false); + } else { + self.cityView = true; + countlyCity.drawGeoChart({height:450}); + $(this).addClass("active"); + self.refresh(true); + store.set("countly_location_city", true); + } + }); } + }, + refresh:function (isToggle) { + var self = this; + $.when(this.beforeRender()).then(function () { + if (app.activeView != self) { + return false; + } + self.renderCommon(true); + newPage = $("
    " + self.template(self.templateData) + "
    "); - for (var l = 0; l < keyEvents[k].length; l++) { - $("#key-events").append("
    \ - \ - "); - } + $(self.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container")); + + if (isToggle) { + self.drawTable(); + } else { + var locationData; + if (self.cityView) { + locationData = countlyCity.getLocationData(); + countlyCity.refreshGeoChart(); + } else { + locationData = countlyLocation.getLocationData(); + countlyLocation.refreshGeoChart(); + } + + CountlyHelpers.refreshTable(self.dtable, locationData); + } + + app.localize(); + }); } -} +}); -window.DashboardView = countlyView.extend({ - selectedView:"#draw-total-sessions", - initialize:function () { - this.template = Handlebars.compile($("#dashboard-template").html()); - }, +window.FrequencyView = countlyView.extend({ beforeRender: function() { - return $.when(countlySession.initialize(), countlyLocation.initialize(), countlyDevice.initialize(), countlyCarrier.initialize(), countlyDeviceDetails.initialize()).then(function () {}); - }, - afterRender: function() { - countlyLocation.drawGeoChart({height:290}); + return $.when(countlyUser.initialize()).then(function () {}); }, - dateChanged:function () { - this.renderCommon(false, true); - countlyLocation.drawGeoChart({height:290}); + renderCommon:function (isRefresh) { + var frequencyData = countlyUser.getFrequencyData(); - switch (this.selectedView) { - case "#draw-total-users": - _.defer(function () { - sessionDP = countlySession.getUserDPActive(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "#draw-new-users": - _.defer(function () { - sessionDP = countlySession.getUserDPNew(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "#draw-total-sessions": - _.defer(function () { - sessionDP = countlySession.getSessionDPTotal(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "#draw-time-spent": - _.defer(function () { - sessionDP = countlySession.getDurationDPAvg(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "#draw-total-time-spent": - _.defer(function () { - sessionDP = countlySession.getDurationDP(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "#draw-avg-events-served": - _.defer(function () { - sessionDP = countlySession.getEventsDPAvg(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; + this.templateData = { + "page-title":jQuery.i18n.map["session-frequency.title"], + "logo-class":"frequency", + "chart-helper":"frequency.chart", + "table-helper":"frequency.table" + }; + + if (!isRefresh) { + $(this.el).html(this.template(this.templateData)); + + countlyCommon.drawGraph(frequencyData.chartDP, "#dashboard-graph", "bar"); + + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": frequencyData.chartData, + "aoColumns": [ + { "mData": "f", sType:"frequency", "sTitle": jQuery.i18n.map["session-frequency.table.time-after"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.number-of-users"] }, + { "mData": "percent", "sType":"percent", "sTitle": jQuery.i18n.map["common.percent"] } + ] + })); + + $(".d-table").stickyTableHeaders(); } }, - pageScript:function () { - $("#total-user-estimate-ind").on("click", function() { - CountlyHelpers.alert($("#total-user-estimate-exp").html(), "black"); - }); + refresh:function () { + var self = this; + $.when(countlyUser.initialize()).then(function () { + if (app.activeView != self) { + return false; + } - $(".widget-content .inner").click(function () { - $(".big-numbers").removeClass("active"); - $(".big-numbers .select").removeClass("selected"); - $(this).parent(".big-numbers").addClass("active"); - $(this).find('.select').addClass("selected"); + var frequencyData = countlyUser.getFrequencyData(); + countlyCommon.drawGraph(frequencyData.chartDP, "#dashboard-graph", "bar"); + CountlyHelpers.refreshTable(self.dtable, frequencyData.chartData); }); + } +}); +window.DeviceView = countlyView.extend({ + beforeRender: function() { + return $.when(countlyDevice.initialize(), countlyDeviceDetails.initialize()).then(function () {}); + }, + pageScript:function () { $(".bar-inner").on({ mouseenter:function () { var number = $(this).parent().next(); @@ -823,148 +1454,61 @@ window.DashboardView = countlyView.extend({ } }); - var self = this; - $(".big-numbers .inner").click(function () { - var elID = $(this).find('.select').attr("id"); - - if (self.selectedView == "#" + elID) { - return true; - } + app.localize(); + }, + renderCommon:function (isRefresh) { + var deviceData = countlyDevice.getDeviceData(); - self.selectedView = "#" + elID; - var keyEvents; - - switch (elID) { - case "draw-total-users": - _.defer(function () { - sessionDP = countlySession.getUserDPActive(); - keyEvents = countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - fillKeyEvents(keyEvents); - }); - break; - case "draw-new-users": - _.defer(function () { - sessionDP = countlySession.getUserDPNew(); - keyEvents = countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - fillKeyEvents(keyEvents); - }); - break; - case "draw-total-sessions": - _.defer(function () { - sessionDP = countlySession.getSessionDPTotal(); - keyEvents = countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - fillKeyEvents(keyEvents); - }); - break; - case "draw-time-spent": - _.defer(function () { - sessionDP = countlySession.getDurationDPAvg(); - keyEvents = countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - fillKeyEvents(keyEvents); - }); - break; - case "draw-total-time-spent": - _.defer(function () { - sessionDP = countlySession.getDurationDP(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - case "draw-avg-events-served": - _.defer(function () { - sessionDP = countlySession.getEventsDPAvg(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - }); - break; - } - }); - - app.localize(); - }, - renderCommon:function (isRefresh, isDateChange) { - var sessionData = countlySession.getSessionData(), - locationData = countlyLocation.getLocationData({maxCountries:7}), - sessionDP = countlySession.getSessionDPTotal(); - - sessionData["country-data"] = locationData; - sessionData["page-title"] = countlyCommon.getDateRange(); - sessionData["usage"] = [ - { - "title":jQuery.i18n.map["common.total-sessions"], - "data":sessionData.usage['total-sessions'], - "id":"draw-total-sessions", - "help":"dashboard.total-sessions" - }, - { - "title":jQuery.i18n.map["common.total-users"], - "data":sessionData.usage['total-users'], - "id":"draw-total-users", - "help":"dashboard.total-users" - }, - { - "title":jQuery.i18n.map["common.new-users"], - "data":sessionData.usage['new-users'], - "id":"draw-new-users", - "help":"dashboard.new-users" - }, - { - "title":jQuery.i18n.map["dashboard.time-spent"], - "data":sessionData.usage['total-duration'], - "id":"draw-total-time-spent", - "help":"dashboard.total-time-spent" - }, - { - "title":jQuery.i18n.map["dashboard.avg-time-spent"], - "data":sessionData.usage['avg-duration-per-session'], - "id":"draw-time-spent", - "help":"dashboard.avg-time-spent2" - }, - { - "title":jQuery.i18n.map["dashboard.avg-reqs-received"], - "data":sessionData.usage['avg-events'], - "id":"draw-avg-events-served", - "help":"dashboard.avg-reqs-received" - } - ]; - sessionData["bars"] = [ - { - "title":jQuery.i18n.map["common.bar.top-platform"], - "data":countlyDeviceDetails.getPlatformBars(), - "help":"dashboard.top-platforms" - }, - { - "title":jQuery.i18n.map["common.bar.top-resolution"], - "data":countlyDeviceDetails.getResolutionBars(), - "help":"dashboard.top-resolutions" - }, - { - "title":jQuery.i18n.map["common.bar.top-carrier"], - "data":countlyCarrier.getCarrierBars(), - "help":"dashboard.top-carriers" + this.templateData = { + "page-title":jQuery.i18n.map["devices.title"], + "logo-class":"devices", + "graph-type-double-pie":true, + "pie-titles":{ + "left":jQuery.i18n.map["common.total-users"], + "right":jQuery.i18n.map["common.new-users"] }, - { - "title":jQuery.i18n.map["common.bar.top-users"], - "data":countlySession.getTopUserBars(), - "help":"dashboard.top-users" - } - ]; - - this.templateData = sessionData; + "bars":[ + { + "title":jQuery.i18n.map["common.bar.top-platform"], + "data":countlyDeviceDetails.getPlatformBars(), + "help":"dashboard.top-platforms" + }, + { + "title":jQuery.i18n.map["common.bar.top-platform-version"], + "data":countlyDeviceDetails.getOSVersionBars(), + "help":"devices.platform-versions2" + }, + { + "title":jQuery.i18n.map["common.bar.top-resolution"], + "data":countlyDeviceDetails.getResolutionBars(), + "help":"dashboard.top-resolutions" + } + ], + "chart-helper":"devices.chart", + "table-helper":"" + }; if (!isRefresh) { $(this.el).html(this.template(this.templateData)); - $(this.selectedView).parents(".big-numbers").addClass("active"); this.pageScript(); - if (!isDateChange) { - var keyEvents = countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - fillKeyEvents(keyEvents); - } + countlyCommon.drawGraph(deviceData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(deviceData.chartDPNew, "#dashboard-graph2", "pie"); + + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": deviceData.chartData, + "aoColumns": [ + { "mData": "device", "sTitle": jQuery.i18n.map["devices.table.device"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } + ] + })); + + $(".d-table").stickyTableHeaders(); } }, - restart:function () { - this.refresh(true); - }, - refresh:function (isFromIdle) { + refresh:function () { var self = this; $.when(this.beforeRender()).then(function () { if (app.activeView != self) { @@ -973,1217 +1517,796 @@ window.DashboardView = countlyView.extend({ self.renderCommon(true); newPage = $("
    " + self.template(self.templateData) + "
    "); - $("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container")); - $(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - $(".widget-header .title").replaceWith(newPage.find(".widget-header .title")); - $(self.selectedView).parents(".big-numbers").addClass("active"); - - switch (self.selectedView) { - case "#draw-total-users": - sessionDP = countlySession.getUserDPActive(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - case "#draw-new-users": - sessionDP = countlySession.getUserDPNew(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - case "#draw-total-sessions": - sessionDP = countlySession.getSessionDPTotal(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - case "#draw-time-spent": - sessionDP = countlySession.getDurationDPAvg(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - case "#draw-total-time-spent": - sessionDP = countlySession.getDurationDP(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - case "#draw-avg-events-served": - sessionDP = countlySession.getEventsDPAvg(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - break; - } - - $(".usparkline").peity("bar", { width:"100%", height:"30", colour:"#6BB96E", strokeColour:"#6BB96E", strokeWidth:2 }); - $(".dsparkline").peity("bar", { width:"100%", height:"30", colour:"#C94C4C", strokeColour:"#C94C4C", strokeWidth:2 }); + $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - if (newPage.find("#map-list-right").length == 0) { - $("#map-list-right").remove(); - } + var deviceData = countlyDevice.getDeviceData(); - if ($("#map-list-right").length) { - $("#map-list-right").replaceWith(newPage.find("#map-list-right")); - } else { - $(".widget.map-list").prepend(newPage.find("#map-list-right")); - } + countlyCommon.drawGraph(deviceData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(deviceData.chartDPNew, "#dashboard-graph2", "pie"); + CountlyHelpers.refreshTable(self.dtable, deviceData.chartData); self.pageScript(); }); - }, - destroy:function () { } }); -window.SessionView = countlyView.extend({ +window.PlatformView = countlyView.extend({ + activePlatform:null, beforeRender: function() { - return $.when(countlySession.initialize()).then(function () {}); + return $.when(countlyDeviceDetails.initialize()).then(function () {}); }, - renderCommon:function (isRefresh) { + pageScript:function () { + var self = this; - var sessionData = countlySession.getSessionData(), - sessionDP = countlySession.getSessionDP(); + if (self.activePlatform) { + $(".graph-segment[data-name='" + self.activePlatform + "']").addClass("active"); + } else { + $(".graph-segment:first-child").addClass("active"); + } + + $(".graph-segment").on("click", function () { + self.activePlatform = $(this).data("name"); + $(".graph-segment").removeClass("active"); + $(this).addClass("active"); + + self.refresh(); + }); + + app.localize(); + }, + renderCommon:function (isRefresh) { + var oSVersionData = countlyDeviceDetails.getOSVersionData(this.activePlatform), + platformData = countlyDeviceDetails.getPlatformData(); this.templateData = { - "page-title":jQuery.i18n.map["sessions.title"], - "logo-class":"sessions", - "big-numbers":{ - "count":3, - "items":[ - { - "title":jQuery.i18n.map["common.total-sessions"], - "total":sessionData.usage["total-sessions"].total, - "trend":sessionData.usage["total-sessions"].trend, - "help":"sessions.total-sessions" - }, - { - "title":jQuery.i18n.map["common.new-sessions"], - "total":sessionData.usage["new-users"].total, - "trend":sessionData.usage["new-users"].trend, - "help":"sessions.new-sessions" - }, - { - "title":jQuery.i18n.map["common.unique-sessions"], - "total":sessionData.usage["total-users"].total, - "trend":sessionData.usage["total-users"].trend, - "help":"sessions.unique-sessions" - } - ] - } + "page-title":jQuery.i18n.map["platforms.title"], + "logo-class":"platforms", + "graph-type-double-pie":true, + "pie-titles":{ + "left":jQuery.i18n.map["platforms.pie-left"], + "right":jQuery.i18n.map["platforms.pie-right"] + }, + "graph-segmentation":oSVersionData.os, + "chart-helper":"platform-versions.chart", + "table-helper":"", + "two-tables": true }; if (!isRefresh) { $(this.el).html(this.template(this.templateData)); + this.pageScript(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": sessionDP.chartData, + countlyCommon.drawGraph(platformData.chartDP, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(oSVersionData.chartDP, "#dashboard-graph2", "pie"); + + this.dtable = $('#dataTableOne').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": platformData.chartData, "aoColumns": [ - { "mData": "date", "sType":"customDate", "sTitle": jQuery.i18n.map["common.date"] }, + { "mData": "os_", "sTitle": jQuery.i18n.map["platforms.table.platform"] }, { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.unique-sessions"] } + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } ] })); - $(".d-table").stickyTableHeaders(); + this.dtableTwo = $('#dataTableTwo').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": oSVersionData.chartData, + "aoColumns": [ + { "mData": "os_version", "sTitle": jQuery.i18n.map["platforms.table.platform-version"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } + ] + })); + + $("#dataTableTwo").stickyTableHeaders(); } }, refresh:function () { var self = this; - $.when(countlySession.refresh()).then(function () { + $.when(this.beforeRender()).then(function () { if (app.activeView != self) { return false; } self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - $(self.el).find("#big-numbers-container").html(newPage.find("#big-numbers-container").html()); + var oSVersionData = countlyDeviceDetails.getOSVersionData(self.activePlatform), + platformData = countlyDeviceDetails.getPlatformData(), + newPage = $("
    " + self.template(self.templateData) + "
    "); - var sessionDP = countlySession.getSessionDP(); - countlyCommon.drawTimeGraph(sessionDP.chartDP, "#dashboard-graph"); - CountlyHelpers.refreshTable(self.dtable, sessionDP.chartData); - app.localize(); + $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); + $(self.el).find(".graph-segment-container").replaceWith(newPage.find(".graph-segment-container")); + + countlyCommon.drawGraph(platformData.chartDP, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(oSVersionData.chartDP, "#dashboard-graph2", "pie"); + + CountlyHelpers.refreshTable(self.dtable, platformData.chartData); + CountlyHelpers.refreshTable(self.dtableTwo, oSVersionData.chartData); + + self.pageScript(); }); } }); -window.UserView = countlyView.extend({ +window.AppVersionView = countlyView.extend({ beforeRender: function() { - return $.when(countlySession.initialize()).then(function () {}); + return $.when(countlyDeviceDetails.initialize()).then(function () {}); }, renderCommon:function (isRefresh) { - var loyaltyData = countlyUser.getLoyaltyData(), - sessionData = countlySession.getSessionData(), - durationData = countlySession.getDurationData(), - userDP = countlySession.getUserDP(); - - sessionData["chart-data"] = userDP.chartData; - sessionData["loyalty-data"] = loyaltyData; - sessionData["duration-data"] = durationData; + var appVersionData = countlyAppVersion.getAppVersionData(); this.templateData = { - "page-title":jQuery.i18n.map["users.title"], - "logo-class":"users", - "big-numbers":{ - "count":3, - "items":[ - { - "title":jQuery.i18n.map["common.total-users"], - "total":sessionData.usage["total-users"].total, - "trend":sessionData.usage["total-users"].trend, - "help":"users.total-users" - }, - { - "title":jQuery.i18n.map["common.new-users"], - "total":sessionData.usage["new-users"].total, - "trend":sessionData.usage["new-users"].trend, - "help":"users.new-users" - }, - { - "title":jQuery.i18n.map["common.returning-users"], - "total":sessionData.usage["returning-users"].total, - "trend":sessionData.usage["returning-users"].trend, - "help":"users.returning-users" - } - ] - } + "page-title":jQuery.i18n.map["app-versions.title"], + "logo-class":"app-versions", + "chart-helper":"app-versions.chart", + "table-helper":"" }; if (!isRefresh) { $(this.el).html(this.template(this.templateData)); + countlyCommon.drawGraph(appVersionData.chartDP, "#dashboard-graph", "bar"); this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": userDP.chartData, + "aaData": appVersionData.chartData, "aoColumns": [ - { "mData": "date", "sType":"customDate", "sTitle": jQuery.i18n.map["common.date"] }, + { "mData": "app_version", "sTitle": jQuery.i18n.map["app-versions.table.app-version"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] }, - { "mData": "returning", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.returning-users"] } + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } ] })); $(".d-table").stickyTableHeaders(); - - countlyCommon.drawTimeGraph(userDP.chartDP, "#dashboard-graph"); } }, refresh:function () { var self = this; - $.when(countlySession.refresh()).then(function () { + $.when(this.beforeRender()).then(function () { if (app.activeView != self) { return false; } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - $(self.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container")); - - var userDP = countlySession.getUserDP(); - countlyCommon.drawTimeGraph(userDP.chartDP, "#dashboard-graph"); - CountlyHelpers.refreshTable(self.dtable, userDP.chartData); - - app.localize(); + var appVersionData = countlyAppVersion.getAppVersionData(); + countlyCommon.drawGraph(appVersionData.chartDP, "#dashboard-graph", "bar"); + CountlyHelpers.refreshTable(self.dtable, appVersionData.chartData); }); } }); -window.LoyaltyView = countlyView.extend({ +window.CarrierView = countlyView.extend({ beforeRender: function() { - return $.when(countlyUser.initialize()).then(function () {}); + return $.when(countlyCarrier.initialize()).then(function () {}); }, renderCommon:function (isRefresh) { - var loyaltyData = countlyUser.getLoyaltyData(), - sessionData = countlySession.getSessionData(), - userDP = countlySession.getUserDP(); + var carrierData = countlyCarrier.getCarrierData(); this.templateData = { - "page-title":jQuery.i18n.map["user-loyalty.title"], - "logo-class":"loyalty", - "chart-helper":"loyalty.chart", - "table-helper":"loyalty.table" + "page-title":jQuery.i18n.map["carriers.title"], + "logo-class":"carriers", + "graph-type-double-pie":true, + "pie-titles":{ + "left":jQuery.i18n.map["common.total-users"], + "right":jQuery.i18n.map["common.new-users"] + }, + "chart-helper":"carriers.chart", + "table-helper":"" }; if (!isRefresh) { $(this.el).html(this.template(this.templateData)); - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": loyaltyData.chartData, + countlyCommon.drawGraph(carrierData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(carrierData.chartDPNew, "#dashboard-graph2", "pie"); + + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": carrierData.chartData, "aoColumns": [ - { "mData": "l", sType:"loyalty", "sTitle": jQuery.i18n.map["user-loyalty.table.session-count"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.number-of-users"] }, - { "mData": "percent", "sType":"percent", "sTitle": jQuery.i18n.map["common.percent"] } + { "mData": "carrier", "sTitle": jQuery.i18n.map["carriers.table.carrier"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } ] })); $(".d-table").stickyTableHeaders(); - countlyCommon.drawGraph(loyaltyData.chartDP, "#dashboard-graph", "bar"); } }, refresh:function () { - var loyaltyData = countlyUser.getLoyaltyData(); var self = this; - $.when(countlyUser.refresh()).then(function () { + $.when(this.beforeRender()).then(function () { if (app.activeView != self) { return false; } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - - var frequencyData = countlyUser.getLoyaltyData(); - countlyCommon.drawGraph(loyaltyData.chartDP, "#dashboard-graph", "bar"); - CountlyHelpers.refreshTable(self.dtable, loyaltyData.chartData); - app.localize(); + var carrierData = countlyCarrier.getCarrierData(); + countlyCommon.drawGraph(carrierData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(carrierData.chartDPNew, "#dashboard-graph2", "pie"); + CountlyHelpers.refreshTable(self.dtable, carrierData.chartData); }); } }); -window.CountriesView = countlyView.extend({ - cityView: (store.get("countly_location_city")) ? store.get("countly_active_app") : false, - initialize:function () { - this.template = Handlebars.compile($("#template-analytics-countries").html()); - }, +window.ResolutionView = countlyView.extend({ beforeRender: function() { - return $.when(countlySession.initialize(), countlyLocation.initialize(), countlyCity.initialize()).then(function () {}); - }, - drawTable: function() { - var tableFirstColTitle = (this.cityView) ? jQuery.i18n.map["countries.table.city"] : jQuery.i18n.map["countries.table.country"], - locationData, - firstCollData = "country_flag" - - if (this.cityView) { - locationData = countlyCity.getLocationData(); - firstCollData = "city"; - } else { - locationData = countlyLocation.getLocationData(); - } - - var activeApp = countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID]; - if (activeApp && activeApp.country) { - $("#toggle-map").text(countlyLocation.getCountryName(activeApp.country)); - } - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": locationData, - "aoColumns": [ - { "mData": firstCollData, "sTitle": tableFirstColTitle }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); - - $(".d-table").stickyTableHeaders(); - }, - dateChanged:function () { - this.renderCommon(); - //countlyLocation.drawGeoChart({height: 450}); + return $.when(countlyDeviceDetails.initialize()).then(function () {}); }, renderCommon:function (isRefresh) { - var sessionData = countlySession.getSessionData(), - tableFirstColTitle = (this.cityView) ? jQuery.i18n.map["countries.table.city"] : jQuery.i18n.map["countries.table.country"]; + var resolutionData = countlyDeviceDetails.getResolutionData(); this.templateData = { - "page-title":jQuery.i18n.map["countries.title"], - "logo-class":"countries", - "big-numbers":{ - "count":3, - "items":[ - { - "title":jQuery.i18n.map["common.total-sessions"], - "total":sessionData.usage["total-sessions"].total, - "trend":sessionData.usage["total-sessions"].trend, - "help":"countries.total-sessions" - }, - { - "title":jQuery.i18n.map["common.total-users"], - "total":sessionData.usage["total-users"].total, - "trend":sessionData.usage["total-users"].trend, - "help":"countries.total-users" - }, - { - "title":jQuery.i18n.map["common.new-users"], - "total":sessionData.usage["new-users"].total, - "trend":sessionData.usage["new-users"].trend, - "help":"countries.new-users" - } - ] + "page-title":jQuery.i18n.map["resolutions.title"], + "logo-class":"resolutions", + "graph-type-double-pie":true, + "pie-titles":{ + "left":jQuery.i18n.map["common.total-users"], + "right":jQuery.i18n.map["common.new-users"] }, - "chart-helper":"countries.chart", - "table-helper":"countries.table" + "chart-helper":"resolutions.chart" }; - var self = this; - $(document).bind('selectMapCountry', function () { - self.cityView = true; - store.set("countly_location_city", true); - $("#toggle-map").addClass("active"); - - countlyCity.drawGeoChart({height:450}); - self.refresh(true); - }); - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - var activeApp = countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID]; - if (activeApp && activeApp.country) { - $("#toggle-map").text(countlyLocation.getCountryName(activeApp.country)); - } - - this.drawTable(); - - if (this.cityView) { - countlyCity.drawGeoChart({height:450}); - $("#toggle-map").addClass("active"); - } else { - countlyLocation.drawGeoChart({height:450}); - } + countlyCommon.drawGraph(resolutionData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(resolutionData.chartDPNew, "#dashboard-graph2", "pie"); - if (countlyCommon.CITY_DATA === false) { - $("#toggle-map").hide(); - store.set("countly_location_city", false); - } + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": resolutionData.chartData, + "aoColumns": [ + { "mData": "resolution", "sTitle": jQuery.i18n.map["resolutions.table.resolution"] }, + { "mData": "width", "sTitle": jQuery.i18n.map["resolutions.table.width"] }, + { "mData": "height", "sTitle": jQuery.i18n.map["resolutions.table.height"] }, + { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, + { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, + { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } + ] + })); - $("#toggle-map").on('click', function () { - if ($(this).hasClass("active")) { - self.cityView = false; - countlyLocation.drawGeoChart({height:450}); - $(this).removeClass("active"); - self.refresh(true); - store.set("countly_location_city", false); - } else { - self.cityView = true; - countlyCity.drawGeoChart({height:450}); - $(this).addClass("active"); - self.refresh(true); - store.set("countly_location_city", true); - } - }); + $(".d-table").stickyTableHeaders(); } }, - refresh:function (isToggle) { + refresh:function () { var self = this; - $.when(this.beforeRender()).then(function () { + $.when(countlyDeviceDetails.initialize()).then(function () { if (app.activeView != self) { return false; } self.renderCommon(true); newPage = $("
    " + self.template(self.templateData) + "
    "); + $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - $(self.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container")); - - if (isToggle) { - self.drawTable(); - } else { - var locationData; - if (self.cityView) { - locationData = countlyCity.getLocationData(); - countlyCity.refreshGeoChart(); - } else { - locationData = countlyLocation.getLocationData(); - countlyLocation.refreshGeoChart(); - } + var resolutionData = countlyDeviceDetails.getResolutionData(); - CountlyHelpers.refreshTable(self.dtable, locationData); - } - - app.localize(); + countlyCommon.drawGraph(resolutionData.chartDPTotal, "#dashboard-graph", "pie"); + countlyCommon.drawGraph(resolutionData.chartDPNew, "#dashboard-graph2", "pie"); + CountlyHelpers.refreshTable(self.dtable, resolutionData.chartData); }); } }); -window.FrequencyView = countlyView.extend({ +window.DurationView = countlyView.extend({ beforeRender: function() { return $.when(countlyUser.initialize()).then(function () {}); }, renderCommon:function (isRefresh) { - var loyaltyData = countlyUser.getLoyaltyData(), - sessionData = countlySession.getSessionData(), - durationData = countlySession.getDurationData(), - userDP = countlySession.getUserDP(), - frequencyData = countlyUser.getFrequencyData(); + var durationData = countlySession.getDurationData(); this.templateData = { - "page-title":jQuery.i18n.map["session-frequency.title"], - "logo-class":"frequency", - "chart-helper":"frequency.chart", - "table-helper":"frequency.table" - }; - - if (!isRefresh) { + "page-title":jQuery.i18n.map["session-duration.title"], + "logo-class":"durations", + "chart-helper":"durations.chart", + "table-helper":"durations.table" + }; + + if (!isRefresh) { $(this.el).html(this.template(this.templateData)); - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": frequencyData.chartData, + countlyCommon.drawGraph(durationData.chartDP, "#dashboard-graph", "bar"); + + this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { + "aaData": durationData.chartData, "aoColumns": [ - { "mData": "f", sType:"frequency", "sTitle": jQuery.i18n.map["session-frequency.table.time-after"] }, + { "mData": "ds", sType:"session-duration", "sTitle": jQuery.i18n.map["session-duration.table.duration"] }, { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.number-of-users"] }, { "mData": "percent", "sType":"percent", "sTitle": jQuery.i18n.map["common.percent"] } ] })); $(".d-table").stickyTableHeaders(); - - countlyCommon.drawGraph(frequencyData.chartDP, "#dashboard-graph", "bar"); } }, refresh:function () { var self = this; - $.when(countlyUser.refresh()).then(function () { + $.when(countlyUser.initialize()).then(function () { if (app.activeView != self) { return false; } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - var frequencyData = countlyUser.getFrequencyData(); - countlyCommon.drawGraph(frequencyData.chartDP, "#dashboard-graph", "bar"); - CountlyHelpers.refreshTable(self.dtable, frequencyData.chartData); - app.localize(); + var durationData = countlySession.getDurationData(); + countlyCommon.drawGraph(durationData.chartDP, "#dashboard-graph", "bar"); + CountlyHelpers.refreshTable(self.dtable, durationData.chartData); }); } }); -window.DeviceView = countlyView.extend({ - beforeRender: function() { - return $.when(countlyDevice.initialize(), countlyDeviceDetails.initialize()).then(function () {}); +window.ManageAppsView = countlyView.extend({ + initialize:function () { + this.template = Handlebars.compile($("#template-management-applications").html()); }, - pageScript:function () { - $(".bar-inner").on({ - mouseenter:function () { - var number = $(this).parent().next(); + renderCommon:function () { + $(this.el).html(this.template({ + admin_apps:countlyGlobal['admin_apps'] + })); - number.text($(this).data("item")); - number.css({"color":$(this).css("background-color")}); - }, - mouseleave:function () { - var number = $(this).parent().next(); + var appCategories = { 1:jQuery.i18n.map["application-category.books"], 2:jQuery.i18n.map["application-category.business"], 3:jQuery.i18n.map["application-category.education"], 4:jQuery.i18n.map["application-category.entertainment"], 5:jQuery.i18n.map["application-category.finance"], 6:jQuery.i18n.map["application-category.games"], 7:jQuery.i18n.map["application-category.health-fitness"], 8:jQuery.i18n.map["application-category.lifestyle"], 9:jQuery.i18n.map["application-category.medical"], 10:jQuery.i18n.map["application-category.music"], 11:jQuery.i18n.map["application-category.navigation"], 12:jQuery.i18n.map["application-category.news"], 13:jQuery.i18n.map["application-category.photography"], 14:jQuery.i18n.map["application-category.productivity"], 15:jQuery.i18n.map["application-category.reference"], 16:jQuery.i18n.map["application-category.social-networking"], 17:jQuery.i18n.map["application-category.sports"], 18:jQuery.i18n.map["application-category.travel"], 19:jQuery.i18n.map["application-category.utilities"], 20:jQuery.i18n.map["application-category.weather"]}, + timezones = { "AF":{"n":"Afghanistan","z":[{"(GMT+04:30) Kabul":"Asia/Kabul"}]}, "AL":{"n":"Albania","z":[{"(GMT+01:00) Tirane":"Europe/Tirane"}]}, "DZ":{"n":"Algeria","z":[{"(GMT+01:00) Algiers":"Africa/Algiers"}]}, "AS":{"n":"American Samoa","z":[{"(GMT-11:00) Pago Pago":"Pacific/Pago_Pago"}]}, "AD":{"n":"Andorra","z":[{"(GMT+01:00) Andorra":"Europe/Andorra"}]}, "AO":{"n":"Angola","z":[{"(GMT+01:00) Luanda":"Africa/Luanda"}]}, "AI":{"n":"Anguilla","z":[{"(GMT-04:00) Anguilla":"America/Anguilla"}]}, "AQ":{"n":"Antarctica","z":[{"(GMT-04:00) Palmer":"Antarctica/Palmer"},{"(GMT-03:00) Rothera":"Antarctica/Rothera"},{"(GMT+03:00) Syowa":"Antarctica/Syowa"},{"(GMT+05:00) Mawson":"Antarctica/Mawson"},{"(GMT+06:00) Vostok":"Antarctica/Vostok"},{"(GMT+07:00) Davis":"Antarctica/Davis"},{"(GMT+08:00) Casey":"Antarctica/Casey"},{"(GMT+10:00) Dumont D'Urville":"Antarctica/DumontDUrville"}]}, "AG":{"n":"Antigua and Barbuda","z":[{"(GMT-04:00) Antigua":"America/Antigua"}]}, "AR":{"n":"Argentina","z":[{"(GMT-03:00) Buenos Aires":"America/Buenos_Aires"}]}, "AM":{"n":"Armenia","z":[{"(GMT+04:00) Yerevan":"Asia/Yerevan"}]}, "AW":{"n":"Aruba","z":[{"(GMT-04:00) Aruba":"America/Aruba"}]}, "AU":{"n":"Australia","z":[{"(GMT+08:00) Western Time - Perth":"Australia/Perth"},{"(GMT+09:30) Central Time - Adelaide":"Australia/Adelaide"},{"(GMT+09:30) Central Time - Darwin":"Australia/Darwin"},{"(GMT+10:00) Eastern Time - Brisbane":"Australia/Brisbane"},{"(GMT+10:00) Eastern Time - Hobart":"Australia/Hobart"},{"(GMT+10:00) Eastern Time - Melbourne, Sydney":"Australia/Sydney"}]}, "AT":{"n":"Austria","z":[{"(GMT+01:00) Vienna":"Europe/Vienna"}]}, "AZ":{"n":"Azerbaijan","z":[{"(GMT+04:00) Baku":"Asia/Baku"}]}, "BS":{"n":"Bahamas","z":[{"(GMT-05:00) Nassau":"America/Nassau"}]}, "BH":{"n":"Bahrain","z":[{"(GMT+03:00) Bahrain":"Asia/Bahrain"}]}, "BD":{"n":"Bangladesh","z":[{"(GMT+06:00) Dhaka":"Asia/Dhaka"}]}, "BB":{"n":"Barbados","z":[{"(GMT-04:00) Barbados":"America/Barbados"}]}, "BY":{"n":"Belarus","z":[{"(GMT+03:00) Minsk":"Europe/Minsk"}]}, "BE":{"n":"Belgium","z":[{"(GMT+01:00) Brussels":"Europe/Brussels"}]}, "BZ":{"n":"Belize","z":[{"(GMT-06:00) Belize":"America/Belize"}]}, "BJ":{"n":"Benin","z":[{"(GMT+01:00) Porto-Novo":"Africa/Porto-Novo"}]}, "BM":{"n":"Bermuda","z":[{"(GMT-04:00) Bermuda":"Atlantic/Bermuda"}]}, "BT":{"n":"Bhutan","z":[{"(GMT+06:00) Thimphu":"Asia/Thimphu"}]}, "BO":{"n":"Bolivia","z":[{"(GMT-04:00) La Paz":"America/La_Paz"}]}, "BA":{"n":"Bosnia and Herzegovina","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Sarajevo"}]}, "BW":{"n":"Botswana","z":[{"(GMT+02:00) Gaborone":"Africa/Gaborone"}]}, "BR":{"n":"Brazil","z":[{"(GMT-04:00) Boa Vista":"America/Boa_Vista"},{"(GMT-04:00) Campo Grande":"America/Campo_Grande"},{"(GMT-04:00) Cuiaba":"America/Cuiaba"},{"(GMT-04:00) Manaus":"America/Manaus"},{"(GMT-04:00) Porto Velho":"America/Porto_Velho"},{"(GMT-04:00) Rio Branco":"America/Rio_Branco"},{"(GMT-03:00) Araguaina":"America/Araguaina"},{"(GMT-03:00) Belem":"America/Belem"},{"(GMT-03:00) Fortaleza":"America/Fortaleza"},{"(GMT-03:00) Maceio":"America/Maceio"},{"(GMT-03:00) Recife":"America/Recife"},{"(GMT-03:00) Salvador":"America/Bahia"},{"(GMT-03:00) Sao Paulo":"America/Sao_Paulo"},{"(GMT-02:00) Noronha":"America/Noronha"}]}, "IO":{"n":"British Indian Ocean Territory","z":[{"(GMT+06:00) Chagos":"Indian/Chagos"}]}, "VG":{"n":"British Virgin Islands","z":[{"(GMT-04:00) Tortola":"America/Tortola"}]}, "BN":{"n":"Brunei","z":[{"(GMT+08:00) Brunei":"Asia/Brunei"}]}, "BG":{"n":"Bulgaria","z":[{"(GMT+02:00) Sofia":"Europe/Sofia"}]}, "BF":{"n":"Burkina Faso","z":[{"(GMT+00:00) Ouagadougou":"Africa/Ouagadougou"}]}, "BI":{"n":"Burundi","z":[{"(GMT+02:00) Bujumbura":"Africa/Bujumbura"}]}, "KH":{"n":"Cambodia","z":[{"(GMT+07:00) Phnom Penh":"Asia/Phnom_Penh"}]}, "CM":{"n":"Cameroon","z":[{"(GMT+01:00) Douala":"Africa/Douala"}]}, "CA":{"n":"Canada","z":[{"(GMT-07:00) Mountain Time - Dawson Creek":"America/Dawson_Creek"},{"(GMT-08:00) Pacific Time - Vancouver":"America/Vancouver"},{"(GMT-08:00) Pacific Time - Whitehorse":"America/Whitehorse"},{"(GMT-06:00) Central Time - Regina":"America/Regina"},{"(GMT-07:00) Mountain Time - Edmonton":"America/Edmonton"},{"(GMT-07:00) Mountain Time - Yellowknife":"America/Yellowknife"},{"(GMT-06:00) Central Time - Winnipeg":"America/Winnipeg"},{"(GMT-05:00) Eastern Time - Iqaluit":"America/Iqaluit"},{"(GMT-05:00) Eastern Time - Montreal":"America/Montreal"},{"(GMT-05:00) Eastern Time - Toronto":"America/Toronto"},{"(GMT-04:00) Atlantic Time - Halifax":"America/Halifax"},{"(GMT-03:30) Newfoundland Time - St. Johns":"America/St_Johns"}]}, "CV":{"n":"Cape Verde","z":[{"(GMT-01:00) Cape Verde":"Atlantic/Cape_Verde"}]}, "KY":{"n":"Cayman Islands","z":[{"(GMT-05:00) Cayman":"America/Cayman"}]}, "CF":{"n":"Central African Republic","z":[{"(GMT+01:00) Bangui":"Africa/Bangui"}]}, "TD":{"n":"Chad","z":[{"(GMT+01:00) Ndjamena":"Africa/Ndjamena"}]}, "CL":{"n":"Chile","z":[{"(GMT-06:00) Easter Island":"Pacific/Easter"},{"(GMT-04:00) Santiago":"America/Santiago"}]}, "CN":{"n":"China","z":[{"(GMT+08:00) China Time - Beijing":"Asia/Shanghai"}]}, "CX":{"n":"Christmas Island","z":[{"(GMT+07:00) Christmas":"Indian/Christmas"}]}, "CC":{"n":"Cocos [Keeling] Islands","z":[{"(GMT+06:30) Cocos":"Indian/Cocos"}]}, "CO":{"n":"Colombia","z":[{"(GMT-05:00) Bogota":"America/Bogota"}]}, "KM":{"n":"Comoros","z":[{"(GMT+03:00) Comoro":"Indian/Comoro"}]}, "CD":{"n":"Congo [DRC]","z":[{"(GMT+01:00) Kinshasa":"Africa/Kinshasa"},{"(GMT+02:00) Lubumbashi":"Africa/Lubumbashi"}]}, "CG":{"n":"Congo [Republic]","z":[{"(GMT+01:00) Brazzaville":"Africa/Brazzaville"}]}, "CK":{"n":"Cook Islands","z":[{"(GMT-10:00) Rarotonga":"Pacific/Rarotonga"}]}, "CR":{"n":"Costa Rica","z":[{"(GMT-06:00) Costa Rica":"America/Costa_Rica"}]}, "CI":{"n":"Côte d’Ivoire","z":[{"(GMT+00:00) Abidjan":"Africa/Abidjan"}]}, "HR":{"n":"Croatia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Zagreb"}]}, "CU":{"n":"Cuba","z":[{"(GMT-05:00) Havana":"America/Havana"}]}, "CW":{"n":"Curaçao","z":[{"(GMT-04:00) Curacao":"America/Curacao"}]}, "CY":{"n":"Cyprus","z":[{"(GMT+02:00) Nicosia":"Asia/Nicosia"}]}, "CZ":{"n":"Czech Republic","z":[{"(GMT+01:00) Central European Time - Prague":"Europe/Prague"}]}, "DK":{"n":"Denmark","z":[{"(GMT+01:00) Copenhagen":"Europe/Copenhagen"}]}, "DJ":{"n":"Djibouti","z":[{"(GMT+03:00) Djibouti":"Africa/Djibouti"}]}, "DM":{"n":"Dominica","z":[{"(GMT-04:00) Dominica":"America/Dominica"}]}, "DO":{"n":"Dominican Republic","z":[{"(GMT-04:00) Santo Domingo":"America/Santo_Domingo"}]}, "EC":{"n":"Ecuador","z":[{"(GMT-06:00) Galapagos":"Pacific/Galapagos"},{"(GMT-05:00) Guayaquil":"America/Guayaquil"}]}, "EG":{"n":"Egypt","z":[{"(GMT+02:00) Cairo":"Africa/Cairo"}]}, "SV":{"n":"El Salvador","z":[{"(GMT-06:00) El Salvador":"America/El_Salvador"}]}, "GQ":{"n":"Equatorial Guinea","z":[{"(GMT+01:00) Malabo":"Africa/Malabo"}]}, "ER":{"n":"Eritrea","z":[{"(GMT+03:00) Asmera":"Africa/Asmera"}]}, "EE":{"n":"Estonia","z":[{"(GMT+02:00) Tallinn":"Europe/Tallinn"}]}, "ET":{"n":"Ethiopia","z":[{"(GMT+03:00) Addis Ababa":"Africa/Addis_Ababa"}]}, "FK":{"n":"Falkland Islands [Islas Malvinas]","z":[{"(GMT-03:00) Stanley":"Atlantic/Stanley"}]}, "FO":{"n":"Faroe Islands","z":[{"(GMT+00:00) Faeroe":"Atlantic/Faeroe"}]}, "FJ":{"n":"Fiji","z":[{"(GMT+12:00) Fiji":"Pacific/Fiji"}]}, "FI":{"n":"Finland","z":[{"(GMT+02:00) Helsinki":"Europe/Helsinki"}]}, "FR":{"n":"France","z":[{"(GMT+01:00) Paris":"Europe/Paris"}]}, "GF":{"n":"French Guiana","z":[{"(GMT-03:00) Cayenne":"America/Cayenne"}]}, "PF":{"n":"French Polynesia","z":[{"(GMT-10:00) Tahiti":"Pacific/Tahiti"},{"(GMT-09:30) Marquesas":"Pacific/Marquesas"},{"(GMT-09:00) Gambier":"Pacific/Gambier"}]}, "TF":{"n":"French Southern Territories","z":[{"(GMT+05:00) Kerguelen":"Indian/Kerguelen"}]}, "GA":{"n":"Gabon","z":[{"(GMT+01:00) Libreville":"Africa/Libreville"}]}, "GM":{"n":"Gambia","z":[{"(GMT+00:00) Banjul":"Africa/Banjul"}]}, "GE":{"n":"Georgia","z":[{"(GMT+04:00) Tbilisi":"Asia/Tbilisi"}]}, "DE":{"n":"Germany","z":[{"(GMT+01:00) Berlin":"Europe/Berlin"}]}, "GH":{"n":"Ghana","z":[{"(GMT+00:00) Accra":"Africa/Accra"}]}, "GI":{"n":"Gibraltar","z":[{"(GMT+01:00) Gibraltar":"Europe/Gibraltar"}]}, "GR":{"n":"Greece","z":[{"(GMT+02:00) Athens":"Europe/Athens"}]}, "GL":{"n":"Greenland","z":[{"(GMT-04:00) Thule":"America/Thule"},{"(GMT-03:00) Godthab":"America/Godthab"},{"(GMT-01:00) Scoresbysund":"America/Scoresbysund"},{"(GMT+00:00) Danmarkshavn":"America/Danmarkshavn"}]}, "GD":{"n":"Grenada","z":[{"(GMT-04:00) Grenada":"America/Grenada"}]}, "GP":{"n":"Guadeloupe","z":[{"(GMT-04:00) Guadeloupe":"America/Guadeloupe"}]}, "GU":{"n":"Guam","z":[{"(GMT+10:00) Guam":"Pacific/Guam"}]}, "GT":{"n":"Guatemala","z":[{"(GMT-06:00) Guatemala":"America/Guatemala"}]}, "GN":{"n":"Guinea","z":[{"(GMT+00:00) Conakry":"Africa/Conakry"}]}, "GW":{"n":"Guinea-Bissau","z":[{"(GMT+00:00) Bissau":"Africa/Bissau"}]}, "GY":{"n":"Guyana","z":[{"(GMT-04:00) Guyana":"America/Guyana"}]}, "HT":{"n":"Haiti","z":[{"(GMT-05:00) Port-au-Prince":"America/Port-au-Prince"}]}, "HN":{"n":"Honduras","z":[{"(GMT-06:00) Central Time - Tegucigalpa":"America/Tegucigalpa"}]}, "HK":{"n":"Hong Kong","z":[{"(GMT+08:00) Hong Kong":"Asia/Hong_Kong"}]}, "HU":{"n":"Hungary","z":[{"(GMT+01:00) Budapest":"Europe/Budapest"}]}, "IS":{"n":"Iceland","z":[{"(GMT+00:00) Reykjavik":"Atlantic/Reykjavik"}]}, "IN":{"n":"India","z":[{"(GMT+05:30) India Standard Time":"Asia/Calcutta"}]}, "ID":{"n":"Indonesia","z":[{"(GMT+07:00) Jakarta":"Asia/Jakarta"},{"(GMT+08:00) Makassar":"Asia/Makassar"},{"(GMT+09:00) Jayapura":"Asia/Jayapura"}]}, "IR":{"n":"Iran","z":[{"(GMT+03:30) Tehran":"Asia/Tehran"}]}, "IQ":{"n":"Iraq","z":[{"(GMT+03:00) Baghdad":"Asia/Baghdad"}]}, "IE":{"n":"Ireland","z":[{"(GMT+00:00) Dublin":"Europe/Dublin"}]}, "IL":{"n":"Israel","z":[{"(GMT+02:00) Jerusalem":"Asia/Jerusalem"}]}, "IT":{"n":"Italy","z":[{"(GMT+01:00) Rome":"Europe/Rome"}]}, "JM":{"n":"Jamaica","z":[{"(GMT-05:00) Jamaica":"America/Jamaica"}]}, "JP":{"n":"Japan","z":[{"(GMT+09:00) Tokyo":"Asia/Tokyo"}]}, "JO":{"n":"Jordan","z":[{"(GMT+02:00) Amman":"Asia/Amman"}]}, "KZ":{"n":"Kazakhstan","z":[{"(GMT+05:00) Aqtau":"Asia/Aqtau"},{"(GMT+05:00) Aqtobe":"Asia/Aqtobe"},{"(GMT+06:00) Almaty":"Asia/Almaty"}]}, "KE":{"n":"Kenya","z":[{"(GMT+03:00) Nairobi":"Africa/Nairobi"}]}, "KI":{"n":"Kiribati","z":[{"(GMT+12:00) Tarawa":"Pacific/Tarawa"},{"(GMT+13:00) Enderbury":"Pacific/Enderbury"},{"(GMT+14:00) Kiritimati":"Pacific/Kiritimati"}]}, "KW":{"n":"Kuwait","z":[{"(GMT+03:00) Kuwait":"Asia/Kuwait"}]}, "KG":{"n":"Kyrgyzstan","z":[{"(GMT+06:00) Bishkek":"Asia/Bishkek"}]}, "LA":{"n":"Laos","z":[{"(GMT+07:00) Vientiane":"Asia/Vientiane"}]}, "LV":{"n":"Latvia","z":[{"(GMT+02:00) Riga":"Europe/Riga"}]}, "LB":{"n":"Lebanon","z":[{"(GMT+02:00) Beirut":"Asia/Beirut"}]}, "LS":{"n":"Lesotho","z":[{"(GMT+02:00) Maseru":"Africa/Maseru"}]}, "LR":{"n":"Liberia","z":[{"(GMT+00:00) Monrovia":"Africa/Monrovia"}]}, "LY":{"n":"Libya","z":[{"(GMT+02:00) Tripoli":"Africa/Tripoli"}]}, "LI":{"n":"Liechtenstein","z":[{"(GMT+01:00) Vaduz":"Europe/Vaduz"}]}, "LT":{"n":"Lithuania","z":[{"(GMT+02:00) Vilnius":"Europe/Vilnius"}]}, "LU":{"n":"Luxembourg","z":[{"(GMT+01:00) Luxembourg":"Europe/Luxembourg"}]}, "MO":{"n":"Macau","z":[{"(GMT+08:00) Macau":"Asia/Macau"}]}, "MK":{"n":"Macedonia [FYROM]","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Skopje"}]}, "MG":{"n":"Madagascar","z":[{"(GMT+03:00) Antananarivo":"Indian/Antananarivo"}]}, "MW":{"n":"Malawi","z":[{"(GMT+02:00) Blantyre":"Africa/Blantyre"}]}, "MY":{"n":"Malaysia","z":[{"(GMT+08:00) Kuala Lumpur":"Asia/Kuala_Lumpur"}]}, "MV":{"n":"Maldives","z":[{"(GMT+05:00) Maldives":"Indian/Maldives"}]}, "ML":{"n":"Mali","z":[{"(GMT+00:00) Bamako":"Africa/Bamako"}]}, "MT":{"n":"Malta","z":[{"(GMT+01:00) Malta":"Europe/Malta"}]}, "MH":{"n":"Marshall Islands","z":[{"(GMT+12:00) Kwajalein":"Pacific/Kwajalein"},{"(GMT+12:00) Majuro":"Pacific/Majuro"}]}, "MQ":{"n":"Martinique","z":[{"(GMT-04:00) Martinique":"America/Martinique"}]}, "MR":{"n":"Mauritania","z":[{"(GMT+00:00) Nouakchott":"Africa/Nouakchott"}]}, "MU":{"n":"Mauritius","z":[{"(GMT+04:00) Mauritius":"Indian/Mauritius"}]}, "YT":{"n":"Mayotte","z":[{"(GMT+03:00) Mayotte":"Indian/Mayotte"}]}, "MX":{"n":"Mexico","z":[{"(GMT-07:00) Mountain Time - Hermosillo":"America/Hermosillo"},{"(GMT-08:00) Pacific Time - Tijuana":"America/Tijuana"},{"(GMT-07:00) Mountain Time - Chihuahua, Mazatlan":"America/Mazatlan"},{"(GMT-06:00) Central Time - Mexico City":"America/Mexico_City"}]}, "FM":{"n":"Micronesia","z":[{"(GMT+10:00) Truk":"Pacific/Truk"},{"(GMT+11:00) Kosrae":"Pacific/Kosrae"},{"(GMT+11:00) Ponape":"Pacific/Ponape"}]}, "MD":{"n":"Moldova","z":[{"(GMT+02:00) Chisinau":"Europe/Chisinau"}]}, "MC":{"n":"Monaco","z":[{"(GMT+01:00) Monaco":"Europe/Monaco"}]}, "MN":{"n":"Mongolia","z":[{"(GMT+07:00) Hovd":"Asia/Hovd"},{"(GMT+08:00) Choibalsan":"Asia/Choibalsan"},{"(GMT+08:00) Ulaanbaatar":"Asia/Ulaanbaatar"}]}, "MS":{"n":"Montserrat","z":[{"(GMT-04:00) Montserrat":"America/Montserrat"}]}, "MA":{"n":"Morocco","z":[{"(GMT+00:00) Casablanca":"Africa/Casablanca"}]}, "MZ":{"n":"Mozambique","z":[{"(GMT+02:00) Maputo":"Africa/Maputo"}]}, "MM":{"n":"Myanmar [Burma]","z":[{"(GMT+06:30) Rangoon":"Asia/Rangoon"}]}, "NA":{"n":"Namibia","z":[{"(GMT+01:00) Windhoek":"Africa/Windhoek"}]}, "NR":{"n":"Nauru","z":[{"(GMT+12:00) Nauru":"Pacific/Nauru"}]}, "NP":{"n":"Nepal","z":[{"(GMT+05:45) Katmandu":"Asia/Katmandu"}]}, "NL":{"n":"Netherlands","z":[{"(GMT+01:00) Amsterdam":"Europe/Amsterdam"}]}, "NC":{"n":"New Caledonia","z":[{"(GMT+11:00) Noumea":"Pacific/Noumea"}]}, "NZ":{"n":"New Zealand","z":[{"(GMT+12:00) Auckland":"Pacific/Auckland"}]}, "NI":{"n":"Nicaragua","z":[{"(GMT-06:00) Managua":"America/Managua"}]}, "NE":{"n":"Niger","z":[{"(GMT+01:00) Niamey":"Africa/Niamey"}]}, "NG":{"n":"Nigeria","z":[{"(GMT+01:00) Lagos":"Africa/Lagos"}]}, "NU":{"n":"Niue","z":[{"(GMT-11:00) Niue":"Pacific/Niue"}]}, "NF":{"n":"Norfolk Island","z":[{"(GMT+11:30) Norfolk":"Pacific/Norfolk"}]}, "KP":{"n":"North Korea","z":[{"(GMT+09:00) Pyongyang":"Asia/Pyongyang"}]}, "MP":{"n":"Northern Mariana Islands","z":[{"(GMT+10:00) Saipan":"Pacific/Saipan"}]}, "NO":{"n":"Norway","z":[{"(GMT+01:00) Oslo":"Europe/Oslo"}]}, "OM":{"n":"Oman","z":[{"(GMT+04:00) Muscat":"Asia/Muscat"}]}, "PK":{"n":"Pakistan","z":[{"(GMT+05:00) Karachi":"Asia/Karachi"}]}, "PW":{"n":"Palau","z":[{"(GMT+09:00) Palau":"Pacific/Palau"}]}, "PS":{"n":"Palestinian Territories","z":[{"(GMT+02:00) Gaza":"Asia/Gaza"}]}, "PA":{"n":"Panama","z":[{"(GMT-05:00) Panama":"America/Panama"}]}, "PG":{"n":"Papua New Guinea","z":[{"(GMT+10:00) Port Moresby":"Pacific/Port_Moresby"}]}, "PY":{"n":"Paraguay","z":[{"(GMT-04:00) Asuncion":"America/Asuncion"}]}, "PE":{"n":"Peru","z":[{"(GMT-05:00) Lima":"America/Lima"}]}, "PH":{"n":"Philippines","z":[{"(GMT+08:00) Manila":"Asia/Manila"}]}, "PN":{"n":"Pitcairn Islands","z":[{"(GMT-08:00) Pitcairn":"Pacific/Pitcairn"}]}, "PL":{"n":"Poland","z":[{"(GMT+01:00) Warsaw":"Europe/Warsaw"}]}, "PT":{"n":"Portugal","z":[{"(GMT-01:00) Azores":"Atlantic/Azores"},{"(GMT+00:00) Lisbon":"Europe/Lisbon"}]}, "PR":{"n":"Puerto Rico","z":[{"(GMT-04:00) Puerto Rico":"America/Puerto_Rico"}]}, "QA":{"n":"Qatar","z":[{"(GMT+03:00) Qatar":"Asia/Qatar"}]}, "RE":{"n":"Réunion","z":[{"(GMT+04:00) Reunion":"Indian/Reunion"}]}, "RO":{"n":"Romania","z":[{"(GMT+02:00) Bucharest":"Europe/Bucharest"}]}, "RU":{"n":"Russia","z":[{"(GMT+03:00) Moscow-01 - Kaliningrad":"Europe/Kaliningrad"},{"(GMT+04:00) Moscow+00":"Europe/Moscow"},{"(GMT+04:00) Moscow+00 - Samara":"Europe/Samara"},{"(GMT+06:00) Moscow+02 - Yekaterinburg":"Asia/Yekaterinburg"},{"(GMT+07:00) Moscow+03 - Omsk, Novosibirsk":"Asia/Omsk"},{"(GMT+08:00) Moscow+04 - Krasnoyarsk":"Asia/Krasnoyarsk"},{"(GMT+09:00) Moscow+05 - Irkutsk":"Asia/Irkutsk"},{"(GMT+10:00) Moscow+06 - Yakutsk":"Asia/Yakutsk"},{"(GMT+11:00) Moscow+07 - Yuzhno-Sakhalinsk":"Asia/Vladivostok"},{"(GMT+12:00) Moscow+08 - Magadan":"Asia/Magadan"},{"(GMT+12:00) Moscow+08 - Petropavlovsk-Kamchatskiy":"Asia/Kamchatka"}]}, "RW":{"n":"Rwanda","z":[{"(GMT+02:00) Kigali":"Africa/Kigali"}]}, "SH":{"n":"Saint Helena","z":[{"(GMT+00:00) St Helena":"Atlantic/St_Helena"}]}, "KN":{"n":"Saint Kitts and Nevis","z":[{"(GMT-04:00) St. Kitts":"America/St_Kitts"}]}, "LC":{"n":"Saint Lucia","z":[{"(GMT-04:00) St. Lucia":"America/St_Lucia"}]}, "PM":{"n":"Saint Pierre and Miquelon","z":[{"(GMT-03:00) Miquelon":"America/Miquelon"}]}, "VC":{"n":"Saint Vincent and the Grenadines","z":[{"(GMT-04:00) St. Vincent":"America/St_Vincent"}]}, "WS":{"n":"Samoa","z":[{"(GMT+13:00) Apia":"Pacific/Apia"}]}, "SM":{"n":"San Marino","z":[{"(GMT+01:00) Rome":"Europe/San_Marino"}]}, "ST":{"n":"São Tomé and Príncipe","z":[{"(GMT+00:00) Sao Tome":"Africa/Sao_Tome"}]}, "SA":{"n":"Saudi Arabia","z":[{"(GMT+03:00) Riyadh":"Asia/Riyadh"}]}, "SN":{"n":"Senegal","z":[{"(GMT+00:00) Dakar":"Africa/Dakar"}]}, "RS":{"n":"Serbia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Belgrade"}]}, "SC":{"n":"Seychelles","z":[{"(GMT+04:00) Mahe":"Indian/Mahe"}]}, "SL":{"n":"Sierra Leone","z":[{"(GMT+00:00) Freetown":"Africa/Freetown"}]}, "SG":{"n":"Singapore","z":[{"(GMT+08:00) Singapore":"Asia/Singapore"}]}, "SK":{"n":"Slovakia","z":[{"(GMT+01:00) Central European Time - Prague":"Europe/Bratislava"}]}, "SI":{"n":"Slovenia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Ljubljana"}]}, "SB":{"n":"Solomon Islands","z":[{"(GMT+11:00) Guadalcanal":"Pacific/Guadalcanal"}]}, "SO":{"n":"Somalia","z":[{"(GMT+03:00) Mogadishu":"Africa/Mogadishu"}]}, "ZA":{"n":"South Africa","z":[{"(GMT+02:00) Johannesburg":"Africa/Johannesburg"}]}, "GS":{"n":"South Georgia and the South Sandwich Islands","z":[{"(GMT-02:00) South Georgia":"Atlantic/South_Georgia"}]}, "KR":{"n":"South Korea","z":[{"(GMT+09:00) Seoul":"Asia/Seoul"}]}, "ES":{"n":"Spain","z":[{"(GMT+00:00) Canary Islands":"Atlantic/Canary"},{"(GMT+01:00) Ceuta":"Africa/Ceuta"},{"(GMT+01:00) Madrid":"Europe/Madrid"}]}, "LK":{"n":"Sri Lanka","z":[{"(GMT+05:30) Colombo":"Asia/Colombo"}]}, "SD":{"n":"Sudan","z":[{"(GMT+03:00) Khartoum":"Africa/Khartoum"}]}, "SR":{"n":"Suriname","z":[{"(GMT-03:00) Paramaribo":"America/Paramaribo"}]}, "SJ":{"n":"Svalbard and Jan Mayen","z":[{"(GMT+01:00) Oslo":"Arctic/Longyearbyen"}]}, "SZ":{"n":"Swaziland","z":[{"(GMT+02:00) Mbabane":"Africa/Mbabane"}]}, "SE":{"n":"Sweden","z":[{"(GMT+01:00) Stockholm":"Europe/Stockholm"}]}, "CH":{"n":"Switzerland","z":[{"(GMT+01:00) Zurich":"Europe/Zurich"}]}, "SY":{"n":"Syria","z":[{"(GMT+02:00) Damascus":"Asia/Damascus"}]}, "TW":{"n":"Taiwan","z":[{"(GMT+08:00) Taipei":"Asia/Taipei"}]}, "TJ":{"n":"Tajikistan","z":[{"(GMT+05:00) Dushanbe":"Asia/Dushanbe"}]}, "TZ":{"n":"Tanzania","z":[{"(GMT+03:00) Dar es Salaam":"Africa/Dar_es_Salaam"}]}, "TH":{"n":"Thailand","z":[{"(GMT+07:00) Bangkok":"Asia/Bangkok"}]}, "TL":{"n":"Timor-Leste","z":[{"(GMT+09:00) Dili":"Asia/Dili"}]}, "TG":{"n":"Togo","z":[{"(GMT+00:00) Lome":"Africa/Lome"}]}, "TK":{"n":"Tokelau","z":[{"(GMT+14:00) Fakaofo":"Pacific/Fakaofo"}]}, "TO":{"n":"Tonga","z":[{"(GMT+13:00) Tongatapu":"Pacific/Tongatapu"}]}, "TT":{"n":"Trinidad and Tobago","z":[{"(GMT-04:00) Port of Spain":"America/Port_of_Spain"}]}, "TN":{"n":"Tunisia","z":[{"(GMT+01:00) Tunis":"Africa/Tunis"}]}, "TR":{"n":"Turkey","z":[{"(GMT+02:00) Istanbul":"Europe/Istanbul"}]}, "TM":{"n":"Turkmenistan","z":[{"(GMT+05:00) Ashgabat":"Asia/Ashgabat"}]}, "TC":{"n":"Turks and Caicos Islands","z":[{"(GMT-05:00) Grand Turk":"America/Grand_Turk"}]}, "TV":{"n":"Tuvalu","z":[{"(GMT+12:00) Funafuti":"Pacific/Funafuti"}]}, "UM":{"n":"U.S. Minor Outlying Islands","z":[{"(GMT-11:00) Midway":"Pacific/Midway"},{"(GMT-10:00) Johnston":"Pacific/Johnston"},{"(GMT+12:00) Wake":"Pacific/Wake"}]}, "VI":{"n":"U.S. Virgin Islands","z":[{"(GMT-04:00) St. Thomas":"America/St_Thomas"}]}, "UG":{"n":"Uganda","z":[{"(GMT+03:00) Kampala":"Africa/Kampala"}]}, "UA":{"n":"Ukraine","z":[{"(GMT+02:00) Kiev":"Europe/Kiev"}]}, "AE":{"n":"United Arab Emirates","z":[{"(GMT+04:00) Dubai":"Asia/Dubai"}]}, "GB":{"n":"United Kingdom","z":[{"(GMT+00:00) GMT (no daylight saving)":"Etc/GMT"},{"(GMT+00:00) London":"Europe/London"}]}, "US":{"n":"United States","z":[{"(GMT-10:00) Hawaii Time":"Pacific/Honolulu"},{"(GMT-09:00) Alaska Time":"America/Anchorage"},{"(GMT-07:00) Mountain Time - Arizona":"America/Phoenix"},{"(GMT-08:00) Pacific Time":"America/Los_Angeles"},{"(GMT-07:00) Mountain Time":"America/Denver"},{"(GMT-06:00) Central Time":"America/Chicago"},{"(GMT-05:00) Eastern Time":"America/New_York"}]}, "UY":{"n":"Uruguay","z":[{"(GMT-03:00) Montevideo":"America/Montevideo"}]}, "UZ":{"n":"Uzbekistan","z":[{"(GMT+05:00) Tashkent":"Asia/Tashkent"}]}, "VU":{"n":"Vanuatu","z":[{"(GMT+11:00) Efate":"Pacific/Efate"}]}, "VA":{"n":"Vatican City","z":[{"(GMT+01:00) Rome":"Europe/Vatican"}]}, "VE":{"n":"Venezuela","z":[{"(GMT-04:30) Caracas":"America/Caracas"}]}, "VN":{"n":"Vietnam","z":[{"(GMT+07:00) Hanoi":"Asia/Saigon"}]}, "WF":{"n":"Wallis and Futuna","z":[{"(GMT+12:00) Wallis":"Pacific/Wallis"}]}, "EH":{"n":"Western Sahara","z":[{"(GMT+00:00) El Aaiun":"Africa/El_Aaiun"}]}, "YE":{"n":"Yemen","z":[{"(GMT+03:00) Aden":"Asia/Aden"}]}, "ZM":{"n":"Zambia","z":[{"(GMT+02:00) Lusaka":"Africa/Lusaka"}]}, "ZW":{"n":"Zimbabwe","z":[{"(GMT+02:00) Harare":"Africa/Harare"}]} }; - number.text(number.data("item")); - number.css({"color":$(this).parent().find(".bar-inner:first-child").css("background-color")}); - } - }); + var appId = countlyCommon.ACTIVE_APP_ID; + $("#app-management-bar .app-container").removeClass("active"); + $("#app-management-bar .app-container[data-id='" + appId + "']").addClass("active"); - app.localize(); - }, - renderCommon:function (isRefresh) { - var deviceData = countlyDevice.getDeviceData(); + function initAppManagement(appId) { + if (jQuery.isEmptyObject(countlyGlobal['apps'])) { + showAdd(); + $("#no-app-warning").show(); + return false; + } else if (jQuery.isEmptyObject(countlyGlobal['admin_apps'])) { + showAdd(); + return false; + } else { + hideAdd(); - this.templateData = { - "page-title":jQuery.i18n.map["devices.title"], - "logo-class":"devices", - "graph-type-double-pie":true, - "pie-titles":{ - "left":jQuery.i18n.map["common.total-users"], - "right":jQuery.i18n.map["common.new-users"] - }, - "bars":[ - { - "title":jQuery.i18n.map["common.bar.top-platform"], - "data":countlyDeviceDetails.getPlatformBars(), - "help":"dashboard.top-platforms" - }, - { - "title":jQuery.i18n.map["common.bar.top-platform-version"], - "data":countlyDeviceDetails.getOSVersionBars(), - "help":"devices.platform-versions2" - }, - { - "title":jQuery.i18n.map["common.bar.top-resolution"], - "data":countlyDeviceDetails.getResolutionBars(), - "help":"dashboard.top-resolutions" + if (countlyGlobal['admin_apps'][appId]) { + $("#delete-app").show(); + } else { + $("#delete-app").hide(); } - ], - "chart-helper":"devices.chart", - "table-helper":"" - }; + } - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - this.pageScript(); + if ($("#new-install-overlay").is(":visible")) { + $("#no-app-warning").hide(); + $("#first-app-success").show(); + $("#new-install-overlay").fadeOut(); + countlyCommon.setActiveApp(appId); + $("#sidebar-app-select").find(".logo").css("background-image", "url('"+countlyGlobal["cdn"]+"appimages/" + appId + ".png')"); + $("#sidebar-app-select").find(".text").text(countlyGlobal['apps'][appId].name); + } - countlyCommon.drawGraph(deviceData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(deviceData.chartDPNew, "#dashboard-graph2", "pie"); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": deviceData.chartData, - "aoColumns": [ - { "mData": "device", "sTitle": jQuery.i18n.map["devices.table.device"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + $("#app-edit-id").val(appId); + $("#view-app").find(".widget-header .title").text(countlyGlobal['apps'][appId].name); + $("#app-edit-name").find(".read").text(countlyGlobal['apps'][appId].name); + $("#app-edit-name").find(".edit input").val(countlyGlobal['apps'][appId].name); + $("#view-app-key").text(countlyGlobal['apps'][appId].key); + $("#view-app-id").text(appId); + $("#app-edit-category").find(".cly-select .text").text(appCategories[countlyGlobal['apps'][appId].category]); + $("#app-edit-category").find(".cly-select .text").data("value", countlyGlobal['apps'][appId].category); + $("#app-edit-timezone").find(".cly-select .text").data("value", countlyGlobal['apps'][appId].timezone); + $("#app-edit-category").find(".read").text(appCategories[countlyGlobal['apps'][appId].category]); + $("#app-edit-image").find(".read .logo").css({"background-image":'url("'+countlyGlobal["cdn"]+'appimages/' + appId + '.png")'}); + var appTimezone = timezones[countlyGlobal['apps'][appId].country]; - $(".d-table").stickyTableHeaders(); - } - }, - refresh:function () { - var self = this; - $.when(this.beforeRender()).then(function () { - if (app.activeView != self) { - return false; + for (var i = 0; i < appTimezone.z.length; i++) { + for (var tzone in appTimezone.z[i]) { + if (appTimezone.z[i][tzone] == countlyGlobal['apps'][appId].timezone) { + var appEditTimezone = $("#app-edit-timezone").find(".read"), + appCountryCode = countlyGlobal['apps'][appId].country; + appEditTimezone.find(".flag").css({"background-image":"url("+countlyGlobal["cdn"]+"images/flags/" + appCountryCode.toLowerCase() + ".png)"}); + appEditTimezone.find(".country").text(appTimezone.n); + appEditTimezone.find(".timezone").text(tzone); + initCountrySelect("#app-edit-timezone", appCountryCode, tzone, appTimezone.z[i][tzone]); + break; + } + } } - self.renderCommon(true); + } - newPage = $("
    " + self.template(self.templateData) + "
    "); - $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); + function initCountrySelect(parent, countryCode, timezoneText, timezone) { + $(parent + " #timezone-select").hide(); + $(parent + " #selected").hide(); + $(parent + " #timezone-items").html(""); + $(parent + " #country-items").html(""); - var deviceData = countlyDevice.getDeviceData(); + var countrySelect = $(parent + " #country-items"); + var timezoneSelect = $(parent + " #timezone-items"); - countlyCommon.drawGraph(deviceData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(deviceData.chartDPNew, "#dashboard-graph2", "pie"); - CountlyHelpers.refreshTable(self.dtable, deviceData.chartData); - self.pageScript(); - }); - } -}); + for (var key in timezones) { + countrySelect.append("
    " + timezones[key].n + "
    ") + } -window.PlatformView = countlyView.extend({ - activePlatform:null, - beforeRender: function() { - return $.when(countlyDevice.initialize(), countlyDeviceDetails.initialize()).then(function () {}); - }, - pageScript:function () { - var self = this; + if (countryCode && timezoneText && timezone) { + var country = timezones[countryCode]; - if (self.activePlatform) { - $(".graph-segment[data-name='" + self.activePlatform + "']").addClass("active"); - } else { - $(".graph-segment:first-child").addClass("active"); - } + if (country.z.length == 1) { + for (var prop in country.z[0]) { + $(parent + " #selected").show(); + $(parent + " #selected").text(prop); + $(parent + " #app-timezone").val(country.z[0][prop]); + $(parent + " #app-country").val(countryCode); + $(parent + " #country-select .text").html("
    " + country.n); + } + } else { + $(parent + " #timezone-select").find(".text").text(prop); + var countryTimezones = country.z; - $(".graph-segment").on("click", function () { - self.activePlatform = $(this).data("name"); - $(".graph-segment").removeClass("active"); - $(this).addClass("active"); + for (var i = 0; i < countryTimezones.length; i++) { + for (var prop in countryTimezones[i]) { + timezoneSelect.append("
    " + prop + "
    ") + } + } - self.refresh(); - }); + $(parent + " #app-timezone").val(timezone); + $(parent + " #app-country").val(countryCode); + $(parent + " #country-select .text").html("
    " + country.n); + $(parent + " #timezone-select .text").text(timezoneText); + $(parent + " #timezone-select").show(); + } - app.localize(); - }, - renderCommon:function (isRefresh) { - var oSVersionData = countlyDeviceDetails.getOSVersionData(this.activePlatform), - platformData = countlyDeviceDetails.getPlatformData(); + $(parent + " .select-items .item").click(function () { + var selectedItem = $(this).parents(".cly-select").find(".text"); + selectedItem.html($(this).html()); + selectedItem.data("value", $(this).data("value")); + }); + $(parent + " #timezone-items .item").click(function () { + $(parent + " #app-timezone").val($(this).data("value")); + }); + } - this.templateData = { - "page-title":jQuery.i18n.map["platforms.title"], - "logo-class":"platforms", - "graph-type-double-pie":true, - "pie-titles":{ - "left":jQuery.i18n.map["platforms.pie-left"], - "right":jQuery.i18n.map["platforms.pie-right"] - }, - "graph-segmentation":oSVersionData.os, - "chart-helper":"platform-versions.chart", - "table-helper":"", - "two-tables": true - }; + $(parent + " #country-items .item").click(function () { + $(parent + " #selected").text(""); + $(parent + " #timezone-select").hide(); + timezoneSelect.html(""); + var attr = $(this).data("value"); + var countryTimezones = timezones[attr].z; - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - this.pageScript(); + if (countryTimezones.length == 1) { + for (var prop in timezones[attr].z[0]) { + $(parent + " #selected").show(); + $(parent + " #selected").text(prop); + $(parent + " #app-timezone").val(timezones[attr].z[0][prop]); + $(parent + " #app-country").val(attr); + } + } else { - countlyCommon.drawGraph(platformData.chartDP, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(oSVersionData.chartDP, "#dashboard-graph2", "pie"); - - this.dtable = $('#dataTableOne').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": platformData.chartData, - "aoColumns": [ - { "mData": "os_", "sTitle": jQuery.i18n.map["platforms.table.platform"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + var firstTz = ""; - this.dtableTwo = $('#dataTableTwo').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": oSVersionData.chartData, - "aoColumns": [ - { "mData": "os_version", "sTitle": jQuery.i18n.map["platforms.table.platform-version"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + for (var i = 0; i < timezones[attr].z.length; i++) { + for (var prop in timezones[attr].z[i]) { + if (i == 0) { + $(parent + " #timezone-select").find(".text").text(prop); + firstTz = timezones[attr].z[0][prop]; + $(parent + " #app-country").val(attr); + } - $("#dataTableTwo").stickyTableHeaders(); + timezoneSelect.append("
    " + prop + "
    ") + } + } + + $(parent + " #timezone-select").show(); + $(parent + " #app-timezone").val(firstTz); + $(parent + " .select-items .item").click(function () { + var selectedItem = $(this).parents(".cly-select").find(".text"); + selectedItem.html($(this).html()); + selectedItem.data("value", $(this).data("value")); + }); + $(parent + " #timezone-items .item").click(function () { + $(parent + " #app-timezone").val($(this).data("value")); + }); + } + }); } - }, - refresh:function () { - var self = this; - $.when(this.beforeRender()).then(function () { - if (app.activeView != self) { - return false; - } - self.renderCommon(true); - var oSVersionData = countlyDeviceDetails.getOSVersionData(self.activePlatform), - platformData = countlyDeviceDetails.getPlatformData(); + function hideEdit() { + $("#edit-app").removeClass("active"); + $(".edit").hide(); + $(".read").show(); + $(".table-edit").hide(); + $(".required").hide(); + } - newPage = $("
    " + self.template(self.templateData) + "
    "); - - $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - $(self.el).find(".graph-segment-container").replaceWith(newPage.find(".graph-segment-container")); + function resetAdd() { + $("#app-add-name").val(""); + $("#app-add-category").text(jQuery.i18n.map["management-applications.category.tip"]); + $("#app-add-category").data("value", ""); + $("#app-add-timezone #selected").text(""); + $("#app-add-timezone #selected").hide(); + $("#app-add-timezone .text").html(jQuery.i18n.map["management-applications.time-zone.tip"]); + $("#app-add-timezone .text").data("value", ""); + $("#app-add-timezone #app-timezone").val(""); + $("#app-add-timezone #app-country").val(""); + $("#app-add-timezone #timezone-select").hide(); + $(".required").hide(); + } - countlyCommon.drawGraph(countlyDeviceDetails.getPlatformData().chartDP, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(oSVersionData.chartDP, "#dashboard-graph2", "pie"); + function showAdd() { + if ($("#app-container-new").is(":visible")) { + return false; + } + $(".app-container").removeClass("active"); + $("#first-app-success").hide(); + hideEdit(); + var manageBarApp = $("#manage-new-app>div").clone(); + manageBarApp.attr("id", "app-container-new"); + manageBarApp.addClass("active"); - CountlyHelpers.refreshTable(self.dtable, platformData.chartData); - CountlyHelpers.refreshTable(self.dtableTwo, oSVersionData.chartData); - - self.pageScript(); - }); - } -}); + if (jQuery.isEmptyObject(countlyGlobal['apps'])) { + $("#cancel-app-add").hide(); + } else { + $("#cancel-app-add").show(); + } -window.AppVersionView = countlyView.extend({ - beforeRender: function() { - return $.when(countlyAppVersion.initialize()).then(function () {}); - }, - renderCommon:function (isRefresh) { - var appVersionData = countlyAppVersion.getAppVersionData(); + $("#app-management-bar .scrollable").append(manageBarApp); + $("#add-new-app").show(); + $("#view-app").hide(); - this.templateData = { - "page-title":jQuery.i18n.map["app-versions.title"], - "logo-class":"app-versions", - "chart-helper":"app-versions.chart", - "table-helper":"" - }; + var userTimezone = jstz.determine().name(); - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - countlyCommon.drawGraph(appVersionData.chartDP, "#dashboard-graph", "bar"); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": appVersionData.chartData, - "aoColumns": [ - { "mData": "app_version", "sTitle": jQuery.i18n.map["app-versions.table.app-version"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + // Set timezone selection defaults to user's current timezone + for (var countryCode in timezones) { + for (var i = 0; i < timezones[countryCode].z.length; i++) { + for (var countryTimezone in timezones[countryCode].z[i]) { + if (timezones[countryCode].z[i][countryTimezone] == userTimezone) { + initCountrySelect("#app-add-timezone", countryCode, countryTimezone, userTimezone); + break; + } + } + } + } + } - $(".d-table").stickyTableHeaders(); + function hideAdd() { + $("#app-container-new").remove(); + $("#add-new-app").hide(); + resetAdd(); + $("#view-app").show(); } - }, - refresh:function () { - var self = this; - $.when(this.beforeRender()).then(function () { - if (app.activeView != self) { - return false; - } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - var appVersionData = countlyAppVersion.getAppVersionData(); - countlyCommon.drawGraph(appVersionData.chartDP, "#dashboard-graph", "bar"); - CountlyHelpers.refreshTable(self.dtable, appVersionData.chartData); - app.localize(); - }); - } -}); + initAppManagement(appId); + initCountrySelect("#app-add-timezone"); -window.CarrierView = countlyView.extend({ - beforeRender: function() { - return $.when(countlyCarrier.initialize()).then(function () {}); - }, - renderCommon:function (isRefresh) { - var carrierData = countlyCarrier.getCarrierData(); + $("#clear-app-data").click(function () { + CountlyHelpers.confirm(jQuery.i18n.map["management-applications.clear-confirm"], "red", function (result) { + if (!result) { + return true; + } - this.templateData = { - "page-title":jQuery.i18n.map["carriers.title"], - "logo-class":"carriers", - "graph-type-double-pie":true, - "pie-titles":{ - "left":jQuery.i18n.map["common.total-users"], - "right":jQuery.i18n.map["common.new-users"] - }, - "chart-helper":"carriers.chart", - "table-helper":"" - }; + var appId = $("#app-edit-id").val(); - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); + $.ajax({ + type:"GET", + url:countlyCommon.API_PARTS.apps.w + '/reset', + data:{ + args:JSON.stringify({ + app_id:appId + }), + api_key:countlyGlobal['member'].api_key + }, + dataType:"jsonp", + success:function (result) { - countlyCommon.drawGraph(carrierData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(carrierData.chartDPNew, "#dashboard-graph2", "pie"); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": carrierData.chartData, - "aoColumns": [ - { "mData": "carrier", "sTitle": jQuery.i18n.map["carriers.table.carrier"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + if (!result) { + CountlyHelpers.alert(jQuery.i18n.map["management-applications.clear-admin"], "red"); + return false; + } else { + countlySession.reset(); + countlyLocation.reset(); + countlyCity.reset(); + countlyUser.reset(); + countlyDevice.reset(); + countlyCarrier.reset(); + countlyDeviceDetails.reset(); + countlyAppVersion.reset(); + countlyEvent.reset(); + CountlyHelpers.alert(jQuery.i18n.map["management-applications.clear-success"], "black"); + } + } + }); + }); + }); - $(".d-table").stickyTableHeaders(); - } - }, - refresh:function () { - var self = this; - $.when(this.beforeRender()).then(function () { - if (app.activeView != self) { - return false; - } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); + $("#delete-app").click(function () { + CountlyHelpers.confirm(jQuery.i18n.map["management-applications.delete-confirm"], "red", function (result) { - var carrierData = countlyCarrier.getCarrierData(); - countlyCommon.drawGraph(carrierData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(carrierData.chartDPNew, "#dashboard-graph2", "pie"); - CountlyHelpers.refreshTable(self.dtable, carrierData.chartData); - - app.localize(); - }); - } -}); + if (!result) { + return true; + } -window.ResolutionView = countlyView.extend({ - beforeRender: function() { - return $.when(countlyDeviceDetails.initialize()).then(function () {}); - }, - renderCommon:function (isRefresh) { - var resolutionData = countlyDeviceDetails.getResolutionData(); + var appId = $("#app-edit-id").val(); - this.templateData = { - "page-title":jQuery.i18n.map["resolutions.title"], - "logo-class":"resolutions", - "graph-type-double-pie":true, - "pie-titles":{ - "left":jQuery.i18n.map["common.total-users"], - "right":jQuery.i18n.map["common.new-users"] - }, - "chart-helper":"resolutions.chart" - }; + $.ajax({ + type:"GET", + url:countlyCommon.API_PARTS.apps.w + '/delete', + data:{ + args:JSON.stringify({ + app_id:appId + }), + api_key:countlyGlobal['member'].api_key + }, + dataType:"jsonp", + success:function () { + delete countlyGlobal['apps'][appId]; + delete countlyGlobal['admin_apps'][appId]; + var activeApp = $(".app-container").filter(function () { + return $(this).data("id") && $(this).data("id") == appId; + }); - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); + var changeApp = (activeApp.prev().length) ? activeApp.prev() : activeApp.next(); + initAppManagement(changeApp.data("id")); + activeApp.fadeOut("slow").remove(); - countlyCommon.drawGraph(resolutionData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(resolutionData.chartDPNew, "#dashboard-graph2", "pie"); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": resolutionData.chartData, - "aoColumns": [ - { "mData": "resolution", "sTitle": jQuery.i18n.map["resolutions.table.resolution"] }, - { "mData": "width", "sTitle": jQuery.i18n.map["resolutions.table.width"] }, - { "mData": "height", "sTitle": jQuery.i18n.map["resolutions.table.height"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); + if (_.isEmpty(countlyGlobal['apps'])) { + $("#new-install-overlay").show(); + $("#sidebar-app-select .logo").css("background-image", ""); + $("#sidebar-app-select .text").text(""); + } + }, + error:function () { + CountlyHelpers.alert(jQuery.i18n.map["management-applications.delete-admin"], "red"); + } + }); + }); + }); - $(".d-table").stickyTableHeaders(); - } - }, - refresh:function () { - var self = this; - $.when(countlyDeviceDetails.refresh()).then(function () { - if (app.activeView != self) { - return false; + $("#edit-app").click(function () { + if ($(".table-edit").is(":visible")) { + hideEdit(); + } else { + $(".edit").show(); + $("#edit-app").addClass("active"); + $(".read").hide(); + $(".table-edit").show(); } - self.renderCommon(true); - - newPage = $("
    " + self.template(self.templateData) + "
    "); - $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - - var resolutionData = countlyDeviceDetails.getResolutionData(); - - countlyCommon.drawGraph(resolutionData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(resolutionData.chartDPNew, "#dashboard-graph2", "pie"); - CountlyHelpers.refreshTable(self.dtable, resolutionData.chartData); }); - } -}); - -window.DurationView = countlyView.extend({ - beforeRender: function() { - return $.when(countlySession.initialize()).then(function () {}); - }, - renderCommon:function (isRefresh) { - var durationData = countlySession.getDurationData(); - - this.templateData = { - "page-title":jQuery.i18n.map["session-duration.title"], - "logo-class":"durations", - "chart-helper":"durations.chart", - "table-helper":"durations.table" - }; - - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - - countlyCommon.drawGraph(durationData.chartDP, "#dashboard-graph", "bar"); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": durationData.chartData, - "aoColumns": [ - { "mData": "ds", sType:"session-duration", "sTitle": jQuery.i18n.map["session-duration.table.duration"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.number-of-users"] }, - { "mData": "percent", "sType":"percent", "sTitle": jQuery.i18n.map["common.percent"] } - ] - })); - $(".d-table").stickyTableHeaders(); - } - }, - refresh:function () { - var self = this; - $.when(countlySession.refresh()).then(function () { - if (app.activeView != self) { + $("#save-app-edit").click(function () { + if ($(this).hasClass("disabled")) { return false; } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - var durationData = countlySession.getDurationData(); - countlyCommon.drawGraph(durationData.chartDP, "#dashboard-graph", "bar"); - CountlyHelpers.refreshTable(self.dtable, durationData.chartData); - app.localize(); - }); - } -}); + var appId = $("#app-edit-id").val(), + appName = $("#app-edit-name .edit input").val(); -window.ManageAppsView = countlyView.extend({ - initialize:function () { - this.template = Handlebars.compile($("#template-management-applications").html()); - }, - renderCommon:function () { - $(this.el).html(this.template({ - admin_apps:countlyGlobal['admin_apps'] - })); + $(".required").fadeOut().remove(); + var reqSpan = $("").addClass("required").text("*"); - var appCategories = { 1:jQuery.i18n.map["application-category.books"], 2:jQuery.i18n.map["application-category.business"], 3:jQuery.i18n.map["application-category.education"], 4:jQuery.i18n.map["application-category.entertainment"], 5:jQuery.i18n.map["application-category.finance"], 6:jQuery.i18n.map["application-category.games"], 7:jQuery.i18n.map["application-category.health-fitness"], 8:jQuery.i18n.map["application-category.lifestyle"], 9:jQuery.i18n.map["application-category.medical"], 10:jQuery.i18n.map["application-category.music"], 11:jQuery.i18n.map["application-category.navigation"], 12:jQuery.i18n.map["application-category.news"], 13:jQuery.i18n.map["application-category.photography"], 14:jQuery.i18n.map["application-category.productivity"], 15:jQuery.i18n.map["application-category.reference"], 16:jQuery.i18n.map["application-category.social-networking"], 17:jQuery.i18n.map["application-category.sports"], 18:jQuery.i18n.map["application-category.travel"], 19:jQuery.i18n.map["application-category.utilities"], 20:jQuery.i18n.map["application-category.weather"]}, - timezones = { "AF":{"n":"Afghanistan","z":[{"(GMT+04:30) Kabul":"Asia/Kabul"}]}, "AL":{"n":"Albania","z":[{"(GMT+01:00) Tirane":"Europe/Tirane"}]}, "DZ":{"n":"Algeria","z":[{"(GMT+01:00) Algiers":"Africa/Algiers"}]}, "AS":{"n":"American Samoa","z":[{"(GMT-11:00) Pago Pago":"Pacific/Pago_Pago"}]}, "AD":{"n":"Andorra","z":[{"(GMT+01:00) Andorra":"Europe/Andorra"}]}, "AO":{"n":"Angola","z":[{"(GMT+01:00) Luanda":"Africa/Luanda"}]}, "AI":{"n":"Anguilla","z":[{"(GMT-04:00) Anguilla":"America/Anguilla"}]}, "AQ":{"n":"Antarctica","z":[{"(GMT-04:00) Palmer":"Antarctica/Palmer"},{"(GMT-03:00) Rothera":"Antarctica/Rothera"},{"(GMT+03:00) Syowa":"Antarctica/Syowa"},{"(GMT+05:00) Mawson":"Antarctica/Mawson"},{"(GMT+06:00) Vostok":"Antarctica/Vostok"},{"(GMT+07:00) Davis":"Antarctica/Davis"},{"(GMT+08:00) Casey":"Antarctica/Casey"},{"(GMT+10:00) Dumont D'Urville":"Antarctica/DumontDUrville"}]}, "AG":{"n":"Antigua and Barbuda","z":[{"(GMT-04:00) Antigua":"America/Antigua"}]}, "AR":{"n":"Argentina","z":[{"(GMT-03:00) Buenos Aires":"America/Buenos_Aires"}]}, "AM":{"n":"Armenia","z":[{"(GMT+04:00) Yerevan":"Asia/Yerevan"}]}, "AW":{"n":"Aruba","z":[{"(GMT-04:00) Aruba":"America/Aruba"}]}, "AU":{"n":"Australia","z":[{"(GMT+08:00) Western Time - Perth":"Australia/Perth"},{"(GMT+09:30) Central Time - Adelaide":"Australia/Adelaide"},{"(GMT+09:30) Central Time - Darwin":"Australia/Darwin"},{"(GMT+10:00) Eastern Time - Brisbane":"Australia/Brisbane"},{"(GMT+10:00) Eastern Time - Hobart":"Australia/Hobart"},{"(GMT+10:00) Eastern Time - Melbourne, Sydney":"Australia/Sydney"}]}, "AT":{"n":"Austria","z":[{"(GMT+01:00) Vienna":"Europe/Vienna"}]}, "AZ":{"n":"Azerbaijan","z":[{"(GMT+04:00) Baku":"Asia/Baku"}]}, "BS":{"n":"Bahamas","z":[{"(GMT-05:00) Nassau":"America/Nassau"}]}, "BH":{"n":"Bahrain","z":[{"(GMT+03:00) Bahrain":"Asia/Bahrain"}]}, "BD":{"n":"Bangladesh","z":[{"(GMT+06:00) Dhaka":"Asia/Dhaka"}]}, "BB":{"n":"Barbados","z":[{"(GMT-04:00) Barbados":"America/Barbados"}]}, "BY":{"n":"Belarus","z":[{"(GMT+03:00) Minsk":"Europe/Minsk"}]}, "BE":{"n":"Belgium","z":[{"(GMT+01:00) Brussels":"Europe/Brussels"}]}, "BZ":{"n":"Belize","z":[{"(GMT-06:00) Belize":"America/Belize"}]}, "BJ":{"n":"Benin","z":[{"(GMT+01:00) Porto-Novo":"Africa/Porto-Novo"}]}, "BM":{"n":"Bermuda","z":[{"(GMT-04:00) Bermuda":"Atlantic/Bermuda"}]}, "BT":{"n":"Bhutan","z":[{"(GMT+06:00) Thimphu":"Asia/Thimphu"}]}, "BO":{"n":"Bolivia","z":[{"(GMT-04:00) La Paz":"America/La_Paz"}]}, "BA":{"n":"Bosnia and Herzegovina","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Sarajevo"}]}, "BW":{"n":"Botswana","z":[{"(GMT+02:00) Gaborone":"Africa/Gaborone"}]}, "BR":{"n":"Brazil","z":[{"(GMT-04:00) Boa Vista":"America/Boa_Vista"},{"(GMT-04:00) Campo Grande":"America/Campo_Grande"},{"(GMT-04:00) Cuiaba":"America/Cuiaba"},{"(GMT-04:00) Manaus":"America/Manaus"},{"(GMT-04:00) Porto Velho":"America/Porto_Velho"},{"(GMT-04:00) Rio Branco":"America/Rio_Branco"},{"(GMT-03:00) Araguaina":"America/Araguaina"},{"(GMT-03:00) Belem":"America/Belem"},{"(GMT-03:00) Fortaleza":"America/Fortaleza"},{"(GMT-03:00) Maceio":"America/Maceio"},{"(GMT-03:00) Recife":"America/Recife"},{"(GMT-03:00) Salvador":"America/Bahia"},{"(GMT-03:00) Sao Paulo":"America/Sao_Paulo"},{"(GMT-02:00) Noronha":"America/Noronha"}]}, "IO":{"n":"British Indian Ocean Territory","z":[{"(GMT+06:00) Chagos":"Indian/Chagos"}]}, "VG":{"n":"British Virgin Islands","z":[{"(GMT-04:00) Tortola":"America/Tortola"}]}, "BN":{"n":"Brunei","z":[{"(GMT+08:00) Brunei":"Asia/Brunei"}]}, "BG":{"n":"Bulgaria","z":[{"(GMT+02:00) Sofia":"Europe/Sofia"}]}, "BF":{"n":"Burkina Faso","z":[{"(GMT+00:00) Ouagadougou":"Africa/Ouagadougou"}]}, "BI":{"n":"Burundi","z":[{"(GMT+02:00) Bujumbura":"Africa/Bujumbura"}]}, "KH":{"n":"Cambodia","z":[{"(GMT+07:00) Phnom Penh":"Asia/Phnom_Penh"}]}, "CM":{"n":"Cameroon","z":[{"(GMT+01:00) Douala":"Africa/Douala"}]}, "CA":{"n":"Canada","z":[{"(GMT-07:00) Mountain Time - Dawson Creek":"America/Dawson_Creek"},{"(GMT-08:00) Pacific Time - Vancouver":"America/Vancouver"},{"(GMT-08:00) Pacific Time - Whitehorse":"America/Whitehorse"},{"(GMT-06:00) Central Time - Regina":"America/Regina"},{"(GMT-07:00) Mountain Time - Edmonton":"America/Edmonton"},{"(GMT-07:00) Mountain Time - Yellowknife":"America/Yellowknife"},{"(GMT-06:00) Central Time - Winnipeg":"America/Winnipeg"},{"(GMT-05:00) Eastern Time - Iqaluit":"America/Iqaluit"},{"(GMT-05:00) Eastern Time - Montreal":"America/Montreal"},{"(GMT-05:00) Eastern Time - Toronto":"America/Toronto"},{"(GMT-04:00) Atlantic Time - Halifax":"America/Halifax"},{"(GMT-03:30) Newfoundland Time - St. Johns":"America/St_Johns"}]}, "CV":{"n":"Cape Verde","z":[{"(GMT-01:00) Cape Verde":"Atlantic/Cape_Verde"}]}, "KY":{"n":"Cayman Islands","z":[{"(GMT-05:00) Cayman":"America/Cayman"}]}, "CF":{"n":"Central African Republic","z":[{"(GMT+01:00) Bangui":"Africa/Bangui"}]}, "TD":{"n":"Chad","z":[{"(GMT+01:00) Ndjamena":"Africa/Ndjamena"}]}, "CL":{"n":"Chile","z":[{"(GMT-06:00) Easter Island":"Pacific/Easter"},{"(GMT-04:00) Santiago":"America/Santiago"}]}, "CN":{"n":"China","z":[{"(GMT+08:00) China Time - Beijing":"Asia/Shanghai"}]}, "CX":{"n":"Christmas Island","z":[{"(GMT+07:00) Christmas":"Indian/Christmas"}]}, "CC":{"n":"Cocos [Keeling] Islands","z":[{"(GMT+06:30) Cocos":"Indian/Cocos"}]}, "CO":{"n":"Colombia","z":[{"(GMT-05:00) Bogota":"America/Bogota"}]}, "KM":{"n":"Comoros","z":[{"(GMT+03:00) Comoro":"Indian/Comoro"}]}, "CD":{"n":"Congo [DRC]","z":[{"(GMT+01:00) Kinshasa":"Africa/Kinshasa"},{"(GMT+02:00) Lubumbashi":"Africa/Lubumbashi"}]}, "CG":{"n":"Congo [Republic]","z":[{"(GMT+01:00) Brazzaville":"Africa/Brazzaville"}]}, "CK":{"n":"Cook Islands","z":[{"(GMT-10:00) Rarotonga":"Pacific/Rarotonga"}]}, "CR":{"n":"Costa Rica","z":[{"(GMT-06:00) Costa Rica":"America/Costa_Rica"}]}, "CI":{"n":"Côte d’Ivoire","z":[{"(GMT+00:00) Abidjan":"Africa/Abidjan"}]}, "HR":{"n":"Croatia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Zagreb"}]}, "CU":{"n":"Cuba","z":[{"(GMT-05:00) Havana":"America/Havana"}]}, "CW":{"n":"Curaçao","z":[{"(GMT-04:00) Curacao":"America/Curacao"}]}, "CY":{"n":"Cyprus","z":[{"(GMT+02:00) Nicosia":"Asia/Nicosia"}]}, "CZ":{"n":"Czech Republic","z":[{"(GMT+01:00) Central European Time - Prague":"Europe/Prague"}]}, "DK":{"n":"Denmark","z":[{"(GMT+01:00) Copenhagen":"Europe/Copenhagen"}]}, "DJ":{"n":"Djibouti","z":[{"(GMT+03:00) Djibouti":"Africa/Djibouti"}]}, "DM":{"n":"Dominica","z":[{"(GMT-04:00) Dominica":"America/Dominica"}]}, "DO":{"n":"Dominican Republic","z":[{"(GMT-04:00) Santo Domingo":"America/Santo_Domingo"}]}, "EC":{"n":"Ecuador","z":[{"(GMT-06:00) Galapagos":"Pacific/Galapagos"},{"(GMT-05:00) Guayaquil":"America/Guayaquil"}]}, "EG":{"n":"Egypt","z":[{"(GMT+02:00) Cairo":"Africa/Cairo"}]}, "SV":{"n":"El Salvador","z":[{"(GMT-06:00) El Salvador":"America/El_Salvador"}]}, "GQ":{"n":"Equatorial Guinea","z":[{"(GMT+01:00) Malabo":"Africa/Malabo"}]}, "ER":{"n":"Eritrea","z":[{"(GMT+03:00) Asmera":"Africa/Asmera"}]}, "EE":{"n":"Estonia","z":[{"(GMT+02:00) Tallinn":"Europe/Tallinn"}]}, "ET":{"n":"Ethiopia","z":[{"(GMT+03:00) Addis Ababa":"Africa/Addis_Ababa"}]}, "FK":{"n":"Falkland Islands [Islas Malvinas]","z":[{"(GMT-03:00) Stanley":"Atlantic/Stanley"}]}, "FO":{"n":"Faroe Islands","z":[{"(GMT+00:00) Faeroe":"Atlantic/Faeroe"}]}, "FJ":{"n":"Fiji","z":[{"(GMT+12:00) Fiji":"Pacific/Fiji"}]}, "FI":{"n":"Finland","z":[{"(GMT+02:00) Helsinki":"Europe/Helsinki"}]}, "FR":{"n":"France","z":[{"(GMT+01:00) Paris":"Europe/Paris"}]}, "GF":{"n":"French Guiana","z":[{"(GMT-03:00) Cayenne":"America/Cayenne"}]}, "PF":{"n":"French Polynesia","z":[{"(GMT-10:00) Tahiti":"Pacific/Tahiti"},{"(GMT-09:30) Marquesas":"Pacific/Marquesas"},{"(GMT-09:00) Gambier":"Pacific/Gambier"}]}, "TF":{"n":"French Southern Territories","z":[{"(GMT+05:00) Kerguelen":"Indian/Kerguelen"}]}, "GA":{"n":"Gabon","z":[{"(GMT+01:00) Libreville":"Africa/Libreville"}]}, "GM":{"n":"Gambia","z":[{"(GMT+00:00) Banjul":"Africa/Banjul"}]}, "GE":{"n":"Georgia","z":[{"(GMT+04:00) Tbilisi":"Asia/Tbilisi"}]}, "DE":{"n":"Germany","z":[{"(GMT+01:00) Berlin":"Europe/Berlin"}]}, "GH":{"n":"Ghana","z":[{"(GMT+00:00) Accra":"Africa/Accra"}]}, "GI":{"n":"Gibraltar","z":[{"(GMT+01:00) Gibraltar":"Europe/Gibraltar"}]}, "GR":{"n":"Greece","z":[{"(GMT+02:00) Athens":"Europe/Athens"}]}, "GL":{"n":"Greenland","z":[{"(GMT-04:00) Thule":"America/Thule"},{"(GMT-03:00) Godthab":"America/Godthab"},{"(GMT-01:00) Scoresbysund":"America/Scoresbysund"},{"(GMT+00:00) Danmarkshavn":"America/Danmarkshavn"}]}, "GD":{"n":"Grenada","z":[{"(GMT-04:00) Grenada":"America/Grenada"}]}, "GP":{"n":"Guadeloupe","z":[{"(GMT-04:00) Guadeloupe":"America/Guadeloupe"}]}, "GU":{"n":"Guam","z":[{"(GMT+10:00) Guam":"Pacific/Guam"}]}, "GT":{"n":"Guatemala","z":[{"(GMT-06:00) Guatemala":"America/Guatemala"}]}, "GN":{"n":"Guinea","z":[{"(GMT+00:00) Conakry":"Africa/Conakry"}]}, "GW":{"n":"Guinea-Bissau","z":[{"(GMT+00:00) Bissau":"Africa/Bissau"}]}, "GY":{"n":"Guyana","z":[{"(GMT-04:00) Guyana":"America/Guyana"}]}, "HT":{"n":"Haiti","z":[{"(GMT-05:00) Port-au-Prince":"America/Port-au-Prince"}]}, "HN":{"n":"Honduras","z":[{"(GMT-06:00) Central Time - Tegucigalpa":"America/Tegucigalpa"}]}, "HK":{"n":"Hong Kong","z":[{"(GMT+08:00) Hong Kong":"Asia/Hong_Kong"}]}, "HU":{"n":"Hungary","z":[{"(GMT+01:00) Budapest":"Europe/Budapest"}]}, "IS":{"n":"Iceland","z":[{"(GMT+00:00) Reykjavik":"Atlantic/Reykjavik"}]}, "IN":{"n":"India","z":[{"(GMT+05:30) India Standard Time":"Asia/Calcutta"}]}, "ID":{"n":"Indonesia","z":[{"(GMT+07:00) Jakarta":"Asia/Jakarta"},{"(GMT+08:00) Makassar":"Asia/Makassar"},{"(GMT+09:00) Jayapura":"Asia/Jayapura"}]}, "IR":{"n":"Iran","z":[{"(GMT+03:30) Tehran":"Asia/Tehran"}]}, "IQ":{"n":"Iraq","z":[{"(GMT+03:00) Baghdad":"Asia/Baghdad"}]}, "IE":{"n":"Ireland","z":[{"(GMT+00:00) Dublin":"Europe/Dublin"}]}, "IL":{"n":"Israel","z":[{"(GMT+02:00) Jerusalem":"Asia/Jerusalem"}]}, "IT":{"n":"Italy","z":[{"(GMT+01:00) Rome":"Europe/Rome"}]}, "JM":{"n":"Jamaica","z":[{"(GMT-05:00) Jamaica":"America/Jamaica"}]}, "JP":{"n":"Japan","z":[{"(GMT+09:00) Tokyo":"Asia/Tokyo"}]}, "JO":{"n":"Jordan","z":[{"(GMT+02:00) Amman":"Asia/Amman"}]}, "KZ":{"n":"Kazakhstan","z":[{"(GMT+05:00) Aqtau":"Asia/Aqtau"},{"(GMT+05:00) Aqtobe":"Asia/Aqtobe"},{"(GMT+06:00) Almaty":"Asia/Almaty"}]}, "KE":{"n":"Kenya","z":[{"(GMT+03:00) Nairobi":"Africa/Nairobi"}]}, "KI":{"n":"Kiribati","z":[{"(GMT+12:00) Tarawa":"Pacific/Tarawa"},{"(GMT+13:00) Enderbury":"Pacific/Enderbury"},{"(GMT+14:00) Kiritimati":"Pacific/Kiritimati"}]}, "KW":{"n":"Kuwait","z":[{"(GMT+03:00) Kuwait":"Asia/Kuwait"}]}, "KG":{"n":"Kyrgyzstan","z":[{"(GMT+06:00) Bishkek":"Asia/Bishkek"}]}, "LA":{"n":"Laos","z":[{"(GMT+07:00) Vientiane":"Asia/Vientiane"}]}, "LV":{"n":"Latvia","z":[{"(GMT+02:00) Riga":"Europe/Riga"}]}, "LB":{"n":"Lebanon","z":[{"(GMT+02:00) Beirut":"Asia/Beirut"}]}, "LS":{"n":"Lesotho","z":[{"(GMT+02:00) Maseru":"Africa/Maseru"}]}, "LR":{"n":"Liberia","z":[{"(GMT+00:00) Monrovia":"Africa/Monrovia"}]}, "LY":{"n":"Libya","z":[{"(GMT+02:00) Tripoli":"Africa/Tripoli"}]}, "LI":{"n":"Liechtenstein","z":[{"(GMT+01:00) Vaduz":"Europe/Vaduz"}]}, "LT":{"n":"Lithuania","z":[{"(GMT+02:00) Vilnius":"Europe/Vilnius"}]}, "LU":{"n":"Luxembourg","z":[{"(GMT+01:00) Luxembourg":"Europe/Luxembourg"}]}, "MO":{"n":"Macau","z":[{"(GMT+08:00) Macau":"Asia/Macau"}]}, "MK":{"n":"Macedonia [FYROM]","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Skopje"}]}, "MG":{"n":"Madagascar","z":[{"(GMT+03:00) Antananarivo":"Indian/Antananarivo"}]}, "MW":{"n":"Malawi","z":[{"(GMT+02:00) Blantyre":"Africa/Blantyre"}]}, "MY":{"n":"Malaysia","z":[{"(GMT+08:00) Kuala Lumpur":"Asia/Kuala_Lumpur"}]}, "MV":{"n":"Maldives","z":[{"(GMT+05:00) Maldives":"Indian/Maldives"}]}, "ML":{"n":"Mali","z":[{"(GMT+00:00) Bamako":"Africa/Bamako"}]}, "MT":{"n":"Malta","z":[{"(GMT+01:00) Malta":"Europe/Malta"}]}, "MH":{"n":"Marshall Islands","z":[{"(GMT+12:00) Kwajalein":"Pacific/Kwajalein"},{"(GMT+12:00) Majuro":"Pacific/Majuro"}]}, "MQ":{"n":"Martinique","z":[{"(GMT-04:00) Martinique":"America/Martinique"}]}, "MR":{"n":"Mauritania","z":[{"(GMT+00:00) Nouakchott":"Africa/Nouakchott"}]}, "MU":{"n":"Mauritius","z":[{"(GMT+04:00) Mauritius":"Indian/Mauritius"}]}, "YT":{"n":"Mayotte","z":[{"(GMT+03:00) Mayotte":"Indian/Mayotte"}]}, "MX":{"n":"Mexico","z":[{"(GMT-07:00) Mountain Time - Hermosillo":"America/Hermosillo"},{"(GMT-08:00) Pacific Time - Tijuana":"America/Tijuana"},{"(GMT-07:00) Mountain Time - Chihuahua, Mazatlan":"America/Mazatlan"},{"(GMT-06:00) Central Time - Mexico City":"America/Mexico_City"}]}, "FM":{"n":"Micronesia","z":[{"(GMT+10:00) Truk":"Pacific/Truk"},{"(GMT+11:00) Kosrae":"Pacific/Kosrae"},{"(GMT+11:00) Ponape":"Pacific/Ponape"}]}, "MD":{"n":"Moldova","z":[{"(GMT+02:00) Chisinau":"Europe/Chisinau"}]}, "MC":{"n":"Monaco","z":[{"(GMT+01:00) Monaco":"Europe/Monaco"}]}, "MN":{"n":"Mongolia","z":[{"(GMT+07:00) Hovd":"Asia/Hovd"},{"(GMT+08:00) Choibalsan":"Asia/Choibalsan"},{"(GMT+08:00) Ulaanbaatar":"Asia/Ulaanbaatar"}]}, "MS":{"n":"Montserrat","z":[{"(GMT-04:00) Montserrat":"America/Montserrat"}]}, "MA":{"n":"Morocco","z":[{"(GMT+00:00) Casablanca":"Africa/Casablanca"}]}, "MZ":{"n":"Mozambique","z":[{"(GMT+02:00) Maputo":"Africa/Maputo"}]}, "MM":{"n":"Myanmar [Burma]","z":[{"(GMT+06:30) Rangoon":"Asia/Rangoon"}]}, "NA":{"n":"Namibia","z":[{"(GMT+01:00) Windhoek":"Africa/Windhoek"}]}, "NR":{"n":"Nauru","z":[{"(GMT+12:00) Nauru":"Pacific/Nauru"}]}, "NP":{"n":"Nepal","z":[{"(GMT+05:45) Katmandu":"Asia/Katmandu"}]}, "NL":{"n":"Netherlands","z":[{"(GMT+01:00) Amsterdam":"Europe/Amsterdam"}]}, "NC":{"n":"New Caledonia","z":[{"(GMT+11:00) Noumea":"Pacific/Noumea"}]}, "NZ":{"n":"New Zealand","z":[{"(GMT+12:00) Auckland":"Pacific/Auckland"}]}, "NI":{"n":"Nicaragua","z":[{"(GMT-06:00) Managua":"America/Managua"}]}, "NE":{"n":"Niger","z":[{"(GMT+01:00) Niamey":"Africa/Niamey"}]}, "NG":{"n":"Nigeria","z":[{"(GMT+01:00) Lagos":"Africa/Lagos"}]}, "NU":{"n":"Niue","z":[{"(GMT-11:00) Niue":"Pacific/Niue"}]}, "NF":{"n":"Norfolk Island","z":[{"(GMT+11:30) Norfolk":"Pacific/Norfolk"}]}, "KP":{"n":"North Korea","z":[{"(GMT+09:00) Pyongyang":"Asia/Pyongyang"}]}, "MP":{"n":"Northern Mariana Islands","z":[{"(GMT+10:00) Saipan":"Pacific/Saipan"}]}, "NO":{"n":"Norway","z":[{"(GMT+01:00) Oslo":"Europe/Oslo"}]}, "OM":{"n":"Oman","z":[{"(GMT+04:00) Muscat":"Asia/Muscat"}]}, "PK":{"n":"Pakistan","z":[{"(GMT+05:00) Karachi":"Asia/Karachi"}]}, "PW":{"n":"Palau","z":[{"(GMT+09:00) Palau":"Pacific/Palau"}]}, "PS":{"n":"Palestinian Territories","z":[{"(GMT+02:00) Gaza":"Asia/Gaza"}]}, "PA":{"n":"Panama","z":[{"(GMT-05:00) Panama":"America/Panama"}]}, "PG":{"n":"Papua New Guinea","z":[{"(GMT+10:00) Port Moresby":"Pacific/Port_Moresby"}]}, "PY":{"n":"Paraguay","z":[{"(GMT-04:00) Asuncion":"America/Asuncion"}]}, "PE":{"n":"Peru","z":[{"(GMT-05:00) Lima":"America/Lima"}]}, "PH":{"n":"Philippines","z":[{"(GMT+08:00) Manila":"Asia/Manila"}]}, "PN":{"n":"Pitcairn Islands","z":[{"(GMT-08:00) Pitcairn":"Pacific/Pitcairn"}]}, "PL":{"n":"Poland","z":[{"(GMT+01:00) Warsaw":"Europe/Warsaw"}]}, "PT":{"n":"Portugal","z":[{"(GMT-01:00) Azores":"Atlantic/Azores"},{"(GMT+00:00) Lisbon":"Europe/Lisbon"}]}, "PR":{"n":"Puerto Rico","z":[{"(GMT-04:00) Puerto Rico":"America/Puerto_Rico"}]}, "QA":{"n":"Qatar","z":[{"(GMT+03:00) Qatar":"Asia/Qatar"}]}, "RE":{"n":"Réunion","z":[{"(GMT+04:00) Reunion":"Indian/Reunion"}]}, "RO":{"n":"Romania","z":[{"(GMT+02:00) Bucharest":"Europe/Bucharest"}]}, "RU":{"n":"Russia","z":[{"(GMT+03:00) Moscow-01 - Kaliningrad":"Europe/Kaliningrad"},{"(GMT+04:00) Moscow+00":"Europe/Moscow"},{"(GMT+04:00) Moscow+00 - Samara":"Europe/Samara"},{"(GMT+06:00) Moscow+02 - Yekaterinburg":"Asia/Yekaterinburg"},{"(GMT+07:00) Moscow+03 - Omsk, Novosibirsk":"Asia/Omsk"},{"(GMT+08:00) Moscow+04 - Krasnoyarsk":"Asia/Krasnoyarsk"},{"(GMT+09:00) Moscow+05 - Irkutsk":"Asia/Irkutsk"},{"(GMT+10:00) Moscow+06 - Yakutsk":"Asia/Yakutsk"},{"(GMT+11:00) Moscow+07 - Yuzhno-Sakhalinsk":"Asia/Vladivostok"},{"(GMT+12:00) Moscow+08 - Magadan":"Asia/Magadan"},{"(GMT+12:00) Moscow+08 - Petropavlovsk-Kamchatskiy":"Asia/Kamchatka"}]}, "RW":{"n":"Rwanda","z":[{"(GMT+02:00) Kigali":"Africa/Kigali"}]}, "SH":{"n":"Saint Helena","z":[{"(GMT+00:00) St Helena":"Atlantic/St_Helena"}]}, "KN":{"n":"Saint Kitts and Nevis","z":[{"(GMT-04:00) St. Kitts":"America/St_Kitts"}]}, "LC":{"n":"Saint Lucia","z":[{"(GMT-04:00) St. Lucia":"America/St_Lucia"}]}, "PM":{"n":"Saint Pierre and Miquelon","z":[{"(GMT-03:00) Miquelon":"America/Miquelon"}]}, "VC":{"n":"Saint Vincent and the Grenadines","z":[{"(GMT-04:00) St. Vincent":"America/St_Vincent"}]}, "WS":{"n":"Samoa","z":[{"(GMT+13:00) Apia":"Pacific/Apia"}]}, "SM":{"n":"San Marino","z":[{"(GMT+01:00) Rome":"Europe/San_Marino"}]}, "ST":{"n":"São Tomé and Príncipe","z":[{"(GMT+00:00) Sao Tome":"Africa/Sao_Tome"}]}, "SA":{"n":"Saudi Arabia","z":[{"(GMT+03:00) Riyadh":"Asia/Riyadh"}]}, "SN":{"n":"Senegal","z":[{"(GMT+00:00) Dakar":"Africa/Dakar"}]}, "RS":{"n":"Serbia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Belgrade"}]}, "SC":{"n":"Seychelles","z":[{"(GMT+04:00) Mahe":"Indian/Mahe"}]}, "SL":{"n":"Sierra Leone","z":[{"(GMT+00:00) Freetown":"Africa/Freetown"}]}, "SG":{"n":"Singapore","z":[{"(GMT+08:00) Singapore":"Asia/Singapore"}]}, "SK":{"n":"Slovakia","z":[{"(GMT+01:00) Central European Time - Prague":"Europe/Bratislava"}]}, "SI":{"n":"Slovenia","z":[{"(GMT+01:00) Central European Time - Belgrade":"Europe/Ljubljana"}]}, "SB":{"n":"Solomon Islands","z":[{"(GMT+11:00) Guadalcanal":"Pacific/Guadalcanal"}]}, "SO":{"n":"Somalia","z":[{"(GMT+03:00) Mogadishu":"Africa/Mogadishu"}]}, "ZA":{"n":"South Africa","z":[{"(GMT+02:00) Johannesburg":"Africa/Johannesburg"}]}, "GS":{"n":"South Georgia and the South Sandwich Islands","z":[{"(GMT-02:00) South Georgia":"Atlantic/South_Georgia"}]}, "KR":{"n":"South Korea","z":[{"(GMT+09:00) Seoul":"Asia/Seoul"}]}, "ES":{"n":"Spain","z":[{"(GMT+00:00) Canary Islands":"Atlantic/Canary"},{"(GMT+01:00) Ceuta":"Africa/Ceuta"},{"(GMT+01:00) Madrid":"Europe/Madrid"}]}, "LK":{"n":"Sri Lanka","z":[{"(GMT+05:30) Colombo":"Asia/Colombo"}]}, "SD":{"n":"Sudan","z":[{"(GMT+03:00) Khartoum":"Africa/Khartoum"}]}, "SR":{"n":"Suriname","z":[{"(GMT-03:00) Paramaribo":"America/Paramaribo"}]}, "SJ":{"n":"Svalbard and Jan Mayen","z":[{"(GMT+01:00) Oslo":"Arctic/Longyearbyen"}]}, "SZ":{"n":"Swaziland","z":[{"(GMT+02:00) Mbabane":"Africa/Mbabane"}]}, "SE":{"n":"Sweden","z":[{"(GMT+01:00) Stockholm":"Europe/Stockholm"}]}, "CH":{"n":"Switzerland","z":[{"(GMT+01:00) Zurich":"Europe/Zurich"}]}, "SY":{"n":"Syria","z":[{"(GMT+02:00) Damascus":"Asia/Damascus"}]}, "TW":{"n":"Taiwan","z":[{"(GMT+08:00) Taipei":"Asia/Taipei"}]}, "TJ":{"n":"Tajikistan","z":[{"(GMT+05:00) Dushanbe":"Asia/Dushanbe"}]}, "TZ":{"n":"Tanzania","z":[{"(GMT+03:00) Dar es Salaam":"Africa/Dar_es_Salaam"}]}, "TH":{"n":"Thailand","z":[{"(GMT+07:00) Bangkok":"Asia/Bangkok"}]}, "TL":{"n":"Timor-Leste","z":[{"(GMT+09:00) Dili":"Asia/Dili"}]}, "TG":{"n":"Togo","z":[{"(GMT+00:00) Lome":"Africa/Lome"}]}, "TK":{"n":"Tokelau","z":[{"(GMT+14:00) Fakaofo":"Pacific/Fakaofo"}]}, "TO":{"n":"Tonga","z":[{"(GMT+13:00) Tongatapu":"Pacific/Tongatapu"}]}, "TT":{"n":"Trinidad and Tobago","z":[{"(GMT-04:00) Port of Spain":"America/Port_of_Spain"}]}, "TN":{"n":"Tunisia","z":[{"(GMT+01:00) Tunis":"Africa/Tunis"}]}, "TR":{"n":"Turkey","z":[{"(GMT+02:00) Istanbul":"Europe/Istanbul"}]}, "TM":{"n":"Turkmenistan","z":[{"(GMT+05:00) Ashgabat":"Asia/Ashgabat"}]}, "TC":{"n":"Turks and Caicos Islands","z":[{"(GMT-05:00) Grand Turk":"America/Grand_Turk"}]}, "TV":{"n":"Tuvalu","z":[{"(GMT+12:00) Funafuti":"Pacific/Funafuti"}]}, "UM":{"n":"U.S. Minor Outlying Islands","z":[{"(GMT-11:00) Midway":"Pacific/Midway"},{"(GMT-10:00) Johnston":"Pacific/Johnston"},{"(GMT+12:00) Wake":"Pacific/Wake"}]}, "VI":{"n":"U.S. Virgin Islands","z":[{"(GMT-04:00) St. Thomas":"America/St_Thomas"}]}, "UG":{"n":"Uganda","z":[{"(GMT+03:00) Kampala":"Africa/Kampala"}]}, "UA":{"n":"Ukraine","z":[{"(GMT+02:00) Kiev":"Europe/Kiev"}]}, "AE":{"n":"United Arab Emirates","z":[{"(GMT+04:00) Dubai":"Asia/Dubai"}]}, "GB":{"n":"United Kingdom","z":[{"(GMT+00:00) GMT (no daylight saving)":"Etc/GMT"},{"(GMT+00:00) London":"Europe/London"}]}, "US":{"n":"United States","z":[{"(GMT-10:00) Hawaii Time":"Pacific/Honolulu"},{"(GMT-09:00) Alaska Time":"America/Anchorage"},{"(GMT-07:00) Mountain Time - Arizona":"America/Phoenix"},{"(GMT-08:00) Pacific Time":"America/Los_Angeles"},{"(GMT-07:00) Mountain Time":"America/Denver"},{"(GMT-06:00) Central Time":"America/Chicago"},{"(GMT-05:00) Eastern Time":"America/New_York"}]}, "UY":{"n":"Uruguay","z":[{"(GMT-03:00) Montevideo":"America/Montevideo"}]}, "UZ":{"n":"Uzbekistan","z":[{"(GMT+05:00) Tashkent":"Asia/Tashkent"}]}, "VU":{"n":"Vanuatu","z":[{"(GMT+11:00) Efate":"Pacific/Efate"}]}, "VA":{"n":"Vatican City","z":[{"(GMT+01:00) Rome":"Europe/Vatican"}]}, "VE":{"n":"Venezuela","z":[{"(GMT-04:30) Caracas":"America/Caracas"}]}, "VN":{"n":"Vietnam","z":[{"(GMT+07:00) Hanoi":"Asia/Saigon"}]}, "WF":{"n":"Wallis and Futuna","z":[{"(GMT+12:00) Wallis":"Pacific/Wallis"}]}, "EH":{"n":"Western Sahara","z":[{"(GMT+00:00) El Aaiun":"Africa/El_Aaiun"}]}, "YE":{"n":"Yemen","z":[{"(GMT+03:00) Aden":"Asia/Aden"}]}, "ZM":{"n":"Zambia","z":[{"(GMT+02:00) Lusaka":"Africa/Lusaka"}]}, "ZW":{"n":"Zimbabwe","z":[{"(GMT+02:00) Harare":"Africa/Harare"}]} }; - - var appId = countlyCommon.ACTIVE_APP_ID; - $("#app-management-bar .app-container").removeClass("active"); - $("#app-management-bar .app-container[data-id='" + appId + "']").addClass("active"); + if (!appName) { + $("#app-edit-name .edit input").after(reqSpan.clone()); + } - function initAppManagement(appId) { - if (jQuery.isEmptyObject(countlyGlobal['apps'])) { - showAdd(); - $("#no-app-warning").show(); - return false; - } else if (jQuery.isEmptyObject(countlyGlobal['admin_apps'])) { - showAdd(); + if ($(".required").length) { + $(".required").fadeIn(); return false; - } else { - hideAdd(); - - if (countlyGlobal['admin_apps'][appId]) { - $("#delete-app").show(); - } else { - $("#delete-app").hide(); - } } - if ($("#new-install-overlay").is(":visible")) { - $("#no-app-warning").hide(); - $("#first-app-success").show(); - $("#new-install-overlay").fadeOut(); - countlyCommon.setActiveApp(appId); - $("#sidebar-app-select").find(".logo").css("background-image", "url('/appimages/" + appId + ".png')"); - $("#sidebar-app-select").find(".text").text(countlyGlobal['apps'][appId].name); + var ext = $('#add-edit-image-form').find("#app_image").val().split('.').pop().toLowerCase(); + if (ext && $.inArray(ext, ['gif', 'png', 'jpg', 'jpeg']) == -1) { + CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"], "red"); + return false; } - $("#app-edit-id").val(appId); - $("#view-app").find(".widget-header .title").text(countlyGlobal['apps'][appId].name); - $("#app-edit-name").find(".read").text(countlyGlobal['apps'][appId].name); - $("#app-edit-name").find(".edit input").val(countlyGlobal['apps'][appId].name); - $("#view-app-key").text(countlyGlobal['apps'][appId].key); - $("#view-app-id").text(appId); - $("#app-edit-category").find(".cly-select .text").text(appCategories[countlyGlobal['apps'][appId].category]); - $("#app-edit-category").find(".cly-select .text").data("value", countlyGlobal['apps'][appId].category); - $("#app-edit-timezone").find(".cly-select .text").data("value", countlyGlobal['apps'][appId].timezone); - $("#app-edit-category").find(".read").text(appCategories[countlyGlobal['apps'][appId].category]); - $("#app-edit-image").find(".read .logo").css({"background-image":'url("/appimages/' + appId + '.png")'}); - var appTimezone = timezones[countlyGlobal['apps'][appId].country]; + $(this).addClass("disabled"); - for (var i = 0; i < appTimezone.z.length; i++) { - for (var tzone in appTimezone.z[i]) { - if (appTimezone.z[i][tzone] == countlyGlobal['apps'][appId].timezone) { - var appEditTimezone = $("#app-edit-timezone").find(".read"), - appCountryCode = countlyGlobal['apps'][appId].country; - appEditTimezone.find(".flag").css({"background-image":"url(/images/flags/" + appCountryCode.toLowerCase() + ".png)"}); - appEditTimezone.find(".country").text(appTimezone.n); - appEditTimezone.find(".timezone").text(tzone); - initCountrySelect("#app-edit-timezone", appCountryCode, tzone, appTimezone.z[i][tzone]); - break; + $.ajax({ + type:"GET", + url:countlyCommon.API_PARTS.apps.w + '/update', + data:{ + args:JSON.stringify({ + app_id:appId, + name:appName, + category:$("#app-edit-category .cly-select .text").data("value") + '', + timezone:$("#app-edit-timezone #app-timezone").val(), + country:$("#app-edit-timezone #app-country").val() + }), + api_key:countlyGlobal['member'].api_key + }, + dataType:"jsonp", + success:function (data) { + for (var modAttr in data) { + countlyGlobal['apps'][appId][modAttr] = data[modAttr]; + countlyGlobal['admin_apps'][appId][modAttr] = data[modAttr]; } - } - } - } - - function initCountrySelect(parent, countryCode, timezoneText, timezone) { - $(parent + " #timezone-select").hide(); - $(parent + " #selected").hide(); - $(parent + " #timezone-items").html(""); - $(parent + " #country-items").html(""); - - var countrySelect = $(parent + " #country-items"); - var timezoneSelect = $(parent + " #timezone-items"); - - for (var key in timezones) { - countrySelect.append("
    " + timezones[key].n + "
    ") - } - - if (countryCode && timezoneText && timezone) { - var country = timezones[countryCode]; - if (country.z.length == 1) { - for (var prop in country.z[0]) { - $(parent + " #selected").show(); - $(parent + " #selected").text(prop); - $(parent + " #app-timezone").val(country.z[0][prop]); - $(parent + " #app-country").val(countryCode); - $(parent + " #country-select .text").html("
    " + country.n); - } - } else { - $(parent + " #timezone-select").find(".text").text(prop); - var countryTimezones = country.z; + if (!ext) { + $("#save-app-edit").removeClass("disabled"); + initAppManagement(appId); + hideEdit(); + $(".app-container").filter(function () { + return $(this).data("id") && $(this).data("id") == appId; + }).find(".name").text(appName); - for (var i = 0; i < countryTimezones.length; i++) { - for (var prop in countryTimezones[i]) { - timezoneSelect.append("
    " + prop + "
    ") + var sidebarLogo = $("#sidebar-app-select .logo").attr("style"); + if (sidebarLogo.indexOf(appId) !== -1) { + $("#sidebar-app-select .text").text(appName); } + return true; } - $(parent + " #app-timezone").val(timezone); - $(parent + " #app-country").val(countryCode); - $(parent + " #country-select .text").html("
    " + country.n); - $(parent + " #timezone-select .text").text(timezoneText); - $(parent + " #timezone-select").show(); - } - - $(parent + " .select-items .item").click(function () { - var selectedItem = $(this).parents(".cly-select").find(".text"); - selectedItem.html($(this).html()); - selectedItem.data("value", $(this).data("value")); - }); - $(parent + " #timezone-items .item").click(function () { - $(parent + " #app-timezone").val($(this).data("value")); - }); - } - - $(parent + " #country-items .item").click(function () { - $(parent + " #selected").text(""); - $(parent + " #timezone-select").hide(); - timezoneSelect.html(""); - var attr = $(this).data("value"); - var countryTimezones = timezones[attr].z; - - if (countryTimezones.length == 1) { - for (var prop in timezones[attr].z[0]) { - $(parent + " #selected").show(); - $(parent + " #selected").text(prop); - $(parent + " #app-timezone").val(timezones[attr].z[0][prop]); - $(parent + " #app-country").val(attr); - } - } else { - - var firstTz = ""; + $('#add-edit-image-form').find("#app_image_id").val(appId); + $('#add-edit-image-form').ajaxSubmit({ + resetForm:true, + beforeSubmit:function (formData, jqForm, options) { + formData.push({ name:'_csrf', value:countlyGlobal['csrf_token'] }); + }, + success:function (file) { + $("#save-app-edit").removeClass("disabled"); + var updatedApp = $(".app-container").filter(function () { + return $(this).data("id") && $(this).data("id") == appId; + }); - for (var i = 0; i < timezones[attr].z.length; i++) { - for (var prop in timezones[attr].z[i]) { - if (i == 0) { - $(parent + " #timezone-select").find(".text").text(prop); - firstTz = timezones[attr].z[0][prop]; - $(parent + " #app-country").val(attr); + if (!file) { + CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"], "red"); + } else { + updatedApp.find(".logo").css({ + "background-image":"url(" + file + "?v" + (new Date().getTime()) + ")" + }); + $("#sidebar-app-select .logo").css("background-image", $("#sidebar-app-select .logo").css("background-image").replace(")","") + "?v" + (new Date().getTime()) + ")"); } - timezoneSelect.append("
    " + prop + "
    ") + initAppManagement(appId); + hideEdit(); + updatedApp.find(".name").text(appName); } - } - - $(parent + " #timezone-select").show(); - $(parent + " #app-timezone").val(firstTz); - $(parent + " .select-items .item").click(function () { - var selectedItem = $(this).parents(".cly-select").find(".text"); - selectedItem.html($(this).html()); - selectedItem.data("value", $(this).data("value")); - }); - $(parent + " #timezone-items .item").click(function () { - $(parent + " #app-timezone").val($(this).data("value")); }); } }); - } - - function hideEdit() { - $("#edit-app").removeClass("active"); - $(".edit").hide(); - $(".read").show(); - $(".table-edit").hide(); - $(".required").hide(); - } - - function resetAdd() { - $("#app-add-name").val(""); - $("#app-add-category").text(jQuery.i18n.map["management-applications.category.tip"]); - $("#app-add-category").data("value", ""); - $("#app-add-timezone #selected").text(""); - $("#app-add-timezone #selected").hide(); - $("#app-add-timezone .text").html(jQuery.i18n.map["management-applications.time-zone.tip"]); - $("#app-add-timezone .text").data("value", ""); - $("#app-add-timezone #app-timezone").val(""); - $("#app-add-timezone #app-country").val(""); - $("#app-add-timezone #timezone-select").hide(); - $(".required").hide(); - } + }); - function showAdd() { - if ($("#app-container-new").is(":visible")) { - return false; - } - $(".app-container").removeClass("active"); - $("#first-app-success").hide(); + $("#cancel-app-edit").click(function () { hideEdit(); - var manageBarApp = $("#manage-new-app>div").clone(); - manageBarApp.attr("id", "app-container-new"); - manageBarApp.addClass("active"); - - if (jQuery.isEmptyObject(countlyGlobal['apps'])) { - $("#cancel-app-add").hide(); - } else { - $("#cancel-app-add").show(); - } - - $("#app-management-bar .scrollable").append(manageBarApp); - $("#add-new-app").show(); - $("#view-app").hide(); + var appId = $("#app-edit-id").val(); + initAppManagement(appId); + }); - var userTimezone = jstz.determine().name(); + $(".app-container:not(#app-container-new)").live("click", function () { + var appId = $(this).data("id"); + hideEdit(); + $(".app-container").removeClass("active"); + $(this).addClass("active"); + initAppManagement(appId); + }); - // Set timezone selection defaults to user's current timezone - for (var countryCode in timezones) { - for (var i = 0; i < timezones[countryCode].z.length; i++) { - for (var countryTimezone in timezones[countryCode].z[i]) { - if (timezones[countryCode].z[i][countryTimezone] == userTimezone) { - initCountrySelect("#app-add-timezone", countryCode, countryTimezone, userTimezone); - break; - } - } - } - } - } + $("#add-app-button").click(function () { + showAdd(); + }); - function hideAdd() { + $("#cancel-app-add").click(function () { $("#app-container-new").remove(); $("#add-new-app").hide(); - resetAdd(); $("#view-app").show(); - } - - initAppManagement(appId); - initCountrySelect("#app-add-timezone"); - - $("#clear-app-data").click(function () { - CountlyHelpers.confirm(jQuery.i18n.map["management-applications.clear-confirm"], "red", function (result) { - if (!result) { - return true; - } - - var appId = $("#app-edit-id").val(); - - $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.apps.w + '/reset', - data:{ - args:JSON.stringify({ - app_id:appId - }), - api_key:countlyGlobal['member'].api_key - }, - dataType:"jsonp", - success:function (result) { - - if (!result) { - CountlyHelpers.alert(jQuery.i18n.map["management-applications.clear-admin"], "red"); - return false; - } else { - countlySession.reset(); - countlyLocation.reset(); - countlyUser.reset(); - countlyDevice.reset(); - countlyCarrier.reset(); - countlyDeviceDetails.reset(); - countlyAppVersion.reset(); - countlyEvent.reset(); - CountlyHelpers.alert(jQuery.i18n.map["management-applications.clear-success"], "black"); - } - } - }); - }); + $(".new-app-name").text(jQuery.i18n.map["management-applications.my-new-app"]); + resetAdd(); }); - $("#delete-app").click(function () { - CountlyHelpers.confirm(jQuery.i18n.map["management-applications.delete-confirm"], "red", function (result) { - - if (!result) { - return true; - } - - var appId = $("#app-edit-id").val(); - - $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.apps.w + '/delete', - data:{ - args:JSON.stringify({ - app_id:appId - }), - api_key:countlyGlobal['member'].api_key - }, - dataType:"jsonp", - success:function () { - delete countlyGlobal['apps'][appId]; - delete countlyGlobal['admin_apps'][appId]; - var activeApp = $(".app-container").filter(function () { - return $(this).data("id") && $(this).data("id") == appId; - }); - - var changeApp = (activeApp.prev().length) ? activeApp.prev() : activeApp.next(); - initAppManagement(changeApp.data("id")); - activeApp.fadeOut("slow").remove(); - - if (_.isEmpty(countlyGlobal['apps'])) { - $("#new-install-overlay").show(); - $("#sidebar-app-select .logo").css("background-image", ""); - $("#sidebar-app-select .text").text(""); - } - }, - error:function () { - CountlyHelpers.alert(jQuery.i18n.map["management-applications.delete-admin"], "red"); - } - }); - }); + $("#app-add-name").keyup(function () { + var newAppName = $(this).val(); + $("#app-container-new .name").text(newAppName); + $(".new-app-name").text(newAppName); }); - $("#edit-app").click(function () { - if ($(".table-edit").is(":visible")) { - hideEdit(); - } else { - $(".edit").show(); - $("#edit-app").addClass("active"); - $(".read").hide(); - $(".table-edit").show(); - } - }); + $("#save-app-add").click(function () { - $("#save-app-edit").click(function () { if ($(this).hasClass("disabled")) { return false; } - var appId = $("#app-edit-id").val(), - appName = $("#app-edit-name .edit input").val(); + var appName = $("#app-add-name").val(), + category = $("#app-add-category").data("value") + "", + timezone = $("#app-add-timezone #app-timezone").val(), + country = $("#app-add-timezone #app-country").val(); $(".required").fadeOut().remove(); var reqSpan = $("").addClass("required").text("*"); if (!appName) { - $("#app-edit-name .edit input").after(reqSpan.clone()); + $("#app-add-name").after(reqSpan.clone()); + } + + if (!category) { + $("#app-add-category").parents(".cly-select").after(reqSpan.clone()); + } + + if (!timezone) { + $("#app-add-timezone #app-timezone").after(reqSpan.clone()); } if ($(".required").length) { @@ -2191,7 +2314,7 @@ window.ManageAppsView = countlyView.extend({ return false; } - var ext = $('#add-edit-image-form').find("#app_image").val().split('.').pop().toLowerCase(); + var ext = $('#add-app-image-form').find("#app_image").val().split('.').pop().toLowerCase(); if (ext && $.inArray(ext, ['gif', 'png', 'jpg', 'jpeg']) == -1) { CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"], "red"); return false; @@ -2201,138 +2324,7 @@ window.ManageAppsView = countlyView.extend({ $.ajax({ type:"GET", - url:countlyCommon.API_PARTS.apps.w + '/update', - data:{ - args:JSON.stringify({ - app_id:appId, - name:appName, - category:$("#app-edit-category .cly-select .text").data("value") + '', - timezone:$("#app-edit-timezone #app-timezone").val(), - country:$("#app-edit-timezone #app-country").val() - }), - api_key:countlyGlobal['member'].api_key - }, - dataType:"jsonp", - success:function (data) { - for (var modAttr in data) { - countlyGlobal['apps'][appId][modAttr] = data[modAttr]; - countlyGlobal['admin_apps'][appId][modAttr] = data[modAttr]; - } - - if (!ext) { - $("#save-app-edit").removeClass("disabled"); - initAppManagement(appId); - hideEdit(); - $(".app-container").filter(function () { - return $(this).data("id") && $(this).data("id") == appId; - }).find(".name").text(appName); - return true; - } - - $('#add-edit-image-form').find("#app_image_id").val(appId); - $('#add-edit-image-form').ajaxSubmit({ - resetForm:true, - beforeSubmit:function (formData, jqForm, options) { - formData.push({ name:'_csrf', value:countlyGlobal['csrf_token'] }); - }, - success:function (file) { - $("#save-app-edit").removeClass("disabled"); - var updatedApp = $(".app-container").filter(function () { - return $(this).data("id") && $(this).data("id") == appId; - }); - - if (!file) { - CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"], "red"); - } else { - updatedApp.find(".logo").css({ - "background-image":"url(" + file + ")" - }); - $("#sidebar-app-select .logo").css("background-image", $("#sidebar-app-select .logo").css("background-image")); - } - - initAppManagement(appId); - hideEdit(); - updatedApp.find(".name").text(appName); - } - }); - } - }); - }); - - $("#cancel-app-edit").click(function () { - hideEdit(); - var appId = $("#app-edit-id").val(); - initAppManagement(appId); - }); - - $(".app-container:not(#app-container-new)").live("click", function () { - var appId = $(this).data("id"); - hideEdit(); - $(".app-container").removeClass("active"); - $(this).addClass("active"); - initAppManagement(appId); - }); - - $("#add-app-button").click(function () { - showAdd(); - }); - - $("#cancel-app-add").click(function () { - $("#app-container-new").remove(); - $("#add-new-app").hide(); - $("#view-app").show(); - $(".new-app-name").text(jQuery.i18n.map["management-applications.my-new-app"]); - resetAdd(); - }); - - $("#app-add-name").keyup(function () { - var newAppName = $(this).val(); - $("#app-container-new .name").text(newAppName); - $(".new-app-name").text(newAppName); - }); - - $("#save-app-add").click(function () { - - if ($(this).hasClass("disabled")) { - return false; - } - - var appName = $("#app-add-name").val(), - category = $("#app-add-category").data("value") + "", - timezone = $("#app-add-timezone #app-timezone").val(), - country = $("#app-add-timezone #app-country").val(); - - $(".required").fadeOut().remove(); - var reqSpan = $("").addClass("required").text("*"); - - if (!appName) { - $("#app-add-name").after(reqSpan.clone()); - } - - if (!category) { - $("#app-add-category").parents(".cly-select").after(reqSpan.clone()); - } - - if (!timezone) { - $("#app-add-timezone #app-timezone").after(reqSpan.clone()); - } - - if ($(".required").length) { - $(".required").fadeIn(); - return false; - } - - var ext = $('#add-app-image-form').find("#app_image").val().split('.').pop().toLowerCase(); - if (ext && $.inArray(ext, ['gif', 'png', 'jpg', 'jpeg']) == -1) { - CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"], "red"); - return false; - } - - $(this).addClass("disabled"); - - $.ajax({ - type:"GET", - url:countlyCommon.API_PARTS.apps.w + '/create', + url:countlyCommon.API_PARTS.apps.w + '/create', data:{ args:JSON.stringify({ name:appName, @@ -2435,66 +2427,17 @@ window.ManageUsersView = countlyView.extend({ } }); -window.ManageExportView = countlyView.extend({ - initialize:function () { - this.template = Handlebars.compile($("#template-management-export").html()); - }, - pageScript:function () { - $("#export-select-all").on('click', function () { - $("#export-checkbox-container .checkbox").addClass("checked"); - $(this).hide(); - $("#export-deselect-all").show(); - }); - - $("#export-deselect-all").on('click', function () { - $("#export-checkbox-container .checkbox").removeClass("checked"); - $(this).hide(); - $("#export-select-all").show(); - }); - - $("#export-checkbox-container .checkbox").on('click', function () { - - var checkCount = 1; - - if ($(this).hasClass("checked")) { - checkCount = -1; - } - - var checkboxCount = $("#export-checkbox-container .checkbox").length, - checkedCount = $("#export-checkbox-container .checkbox.checked").length + checkCount; - - if (checkboxCount == checkedCount) { - $("#export-deselect-all").show(); - $("#export-select-all").hide(); - } else { - $("#export-select-all").show(); - $("#export-deselect-all").hide(); - } - }); - }, - renderCommon:function () { - $(this.el).html(this.template({ - events:countlyEvent.getEventsWithSegmentations(), - app_name:app.activeAppName, - exports:[] - })); - - this.pageScript(); - }, - appChanged:function () { - this.renderCommon(); - } -}); - window.EventsView = countlyView.extend({ showOnGraph: 2, - beforeRender: function() { - return $.when(countlyEvent.initialize()).then(function () {}); - }, + beforeRender: function() {}, initialize:function () { this.template = Handlebars.compile($("#template-events").html()); }, pageScript:function () { + $(".event-container").unbind("click"); + $(".segmentation-option").unbind("click"); + $(".big-numbers").unbind("click"); + var self = this; $(".event-container").on("click", function () { var tmpCurrEvent = $(this).data("key"); @@ -2507,8 +2450,25 @@ window.EventsView = countlyView.extend({ $(".segmentation-option").on("click", function () { var tmpCurrSegmentation = $(this).data("value"); - countlyEvent.setActiveSegmentation(tmpCurrSegmentation); - self.refresh(false, true); + countlyEvent.setActiveSegmentation(tmpCurrSegmentation, function() { + self.renderCommon(true); + newPage = $("
    " + self.template(self.templateData) + "
    "); + + $(self.el).find("#event-nav .scrollable").html(function () { + return newPage.find("#event-nav .scrollable").html(); + }); + + $(self.el).find(".widget-footer").html(newPage.find(".widget-footer").html()); + $(self.el).find("#edit-event-container").replaceWith(newPage.find("#edit-event-container")); + + var eventData = countlyEvent.getEventData(); + self.drawGraph(eventData); + self.pageScript(); + + self.drawTable(eventData); + + app.localize(); + }); }); $(".big-numbers").on("click", function () { @@ -2578,12 +2538,13 @@ window.EventsView = countlyView.extend({ $(".d-table").stickyTableHeaders(); }, - getColumnCount:function(){ + getColumnCount:function(){ return $(".dataTable").find("thead th").length; }, renderCommon:function (isRefresh) { var eventData = countlyEvent.getEventData(), - eventSummary = countlyEvent.getEventSummary(); + eventSummary = countlyEvent.getEventSummary(), + self = this; this.templateData = { "page-title":eventData.eventName.toUpperCase(), @@ -2593,7 +2554,7 @@ window.EventsView = countlyView.extend({ "segmentations":countlyEvent.getEventSegmentations(), "active-segmentation":countlyEvent.getActiveSegmentation(), "big-numbers":eventSummary, - "chart-data":{ + "chart-data":{ "columnCount":eventData.tableColumns.length, "columns":eventData.tableColumns, "rows":eventData.chartData @@ -2610,11 +2571,12 @@ window.EventsView = countlyView.extend({ $(this.el).html(this.template(this.templateData)); this.drawGraph(eventData); - this.drawTable(eventData); + this.drawTable(eventData); this.pageScript(); $("#edit-events-button").on("click", function () { CountlyHelpers.popup("#edit-event-container", "events"); + $(".dialog #edit-event-table-container").slimScroll({ height:'100%', start:'top', @@ -2683,7 +2645,7 @@ window.EventsView = countlyView.extend({ $.ajax({ type:"POST", - url:"/events/map/edit", + url:countlyGlobal["path"]+"/events/map/edit", data:{ "app_id":countlyCommon.ACTIVE_APP_ID, "event_map":eventMap, @@ -2704,7 +2666,7 @@ window.EventsView = countlyView.extend({ if (result) { $.ajax({ type:"POST", - url:"/events/delete", + url:countlyGlobal["path"]+"/events/delete", data:{ "event_key":eventKey, "app_id":countlyCommon.ACTIVE_APP_ID, @@ -2712,7 +2674,9 @@ window.EventsView = countlyView.extend({ }, success:function (result) { countlyEvent.reset(); - self.render(); + $.when(countlyEvent.initialize(true)).then(function () { + self.render(); + }); } }); } @@ -2745,6 +2709,15 @@ window.EventsView = countlyView.extend({ return newPage.find("#event-update-area .select-items").html(); }); + $("#event-update-area .select-items>div").addClass("scroll-list"); + $("#event-update-area .select-items").find(".scroll-list").slimScroll({ + height:'100%', + start:'top', + wheelStep:10, + position:'right', + disableFadeOut:true + }); + $(".select-items .item").click(function () { var selectedItem = $(this).parents(".cly-select").find(".text"); selectedItem.text($(this).text()); @@ -2760,7 +2733,7 @@ window.EventsView = countlyView.extend({ $(self.el).find(".widget-footer").html(newPage.find(".widget-footer").html()); $(self.el).find("#edit-event-container").replaceWith(newPage.find("#edit-event-container")); - var eventData = countlyEvent.getEventData(); + var eventData = countlyEvent.getEventData(); self.drawGraph(eventData); self.pageScript(); @@ -2771,343 +2744,45 @@ window.EventsView = countlyView.extend({ } else { CountlyHelpers.refreshTable(self.dtable, eventData.chartData); } - + app.localize(); }); } }); -window.DensityView = countlyView.extend({ - beforeRender: function() { - return $.when(countlyDeviceDetails.initialize()).then(function () {}); +var AppRouter = Backbone.Router.extend({ + routes:{ + "/":"dashboard", + "/analytics/sessions":"sessions", + "/analytics/countries":"countries", + "/analytics/users":"users", + "/analytics/loyalty":"loyalty", + "/analytics/devices":"devices", + "/analytics/platforms":"platforms", + "/analytics/versions":"versions", + "/analytics/carriers":"carriers", + "/analytics/frequency":"frequency", + "/analytics/events":"events", + "/analytics/resolutions":"resolutions", + "/analytics/durations":"durations", + "/all":"allapps", + "/manage/apps":"manageApps", + "/manage/users":"manageUsers", + "*path":"main" }, - renderCommon:function (isRefresh) { - var densityData = countlyDeviceDetails.getDensityData(); - - this.templateData = { - "page-title":jQuery.i18n.map["density.title"], - "logo-class":"densities", - "graph-type-double-pie":true, - "pie-titles":{ - "left":jQuery.i18n.map["common.total-users"], - "right":jQuery.i18n.map["common.new-users"] - }, - "chart-helper":"resolutions.chart" - }; - - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": densityData.chartData, - "aoColumns": [ - { "mData": "densities", sType:"session-duration", "sTitle": jQuery.i18n.map["density.table.density"] }, - { "mData": "t", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-sessions"] }, - { "mData": "u", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.total-users"] }, - { "mData": "n", sType:"formatted-num", "mRender":function(d) { return countlyCommon.formatNumber(d); }, "sTitle": jQuery.i18n.map["common.table.new-users"] } - ] - })); - - $(".d-table").stickyTableHeaders(); - - countlyCommon.drawGraph(densityData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(densityData.chartDPNew, "#dashboard-graph2", "pie"); - } + activeView:null, //current view + dateToSelected:null, //date to selected from the date picker + dateFromSelected:null, //date from selected from the date picker + activeAppName:'', + activeAppKey:'', + main:function () { + this.navigate("/", true); }, - refresh:function () { - var self = this; - $.when(countlyDeviceDetails.refresh()).then(function () { - if (app.activeView != self) { - return false; - } - self.renderCommon(true); - - newPage = $("
    " + self.template(self.templateData) + "
    "); - - $(self.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); - - var densityData = countlyDeviceDetails.getDensityData(); - - countlyCommon.drawGraph(densityData.chartDPTotal, "#dashboard-graph", "pie"); - countlyCommon.drawGraph(densityData.chartDPNew, "#dashboard-graph2", "pie"); - CountlyHelpers.refreshTable(self.dtable, densityData.chartData); - }); - } -}); - -window.EnterpriseView = countlyView.extend({ - initialize:function () { - this.template = Handlebars.compile($("#template-enterprise").html()); + dashboard:function () { + this.renderWhenReady(this.dashboardView); }, - pageScript:function () { - var titles = { - "drill":"Game changer for data analytics", - "funnels":"Track completion rates step by step", - "retention":"See how engaging your application is", - "revenue":"Calculate your customer's lifetime value", - "scalability": "Tens of millions of users? No problem", - "support":"Enterprise support and SLA", - "raw-data": "Your data, your rules" - } - - $("#enterprise-sections").find(".app-container").on("click", function() { - var section = $(this).data("section"); - - $(".enterprise-content").hide(); - $(".enterprise-content." + section).show(); - - $("#enterprise-sections").find(".app-container").removeClass("active"); - $(this).addClass("active"); - - $(".widget-header .title").text(titles[section] || ""); - }); - }, - renderCommon:function () { - $(this.el).html(this.template(this.templateData)); - this.pageScript(); - } -}); - -window.AllAppsView = countlyView.extend({ - selectedView:"#draw-total-sessions", - selectedApps: {"all":true}, - selectedCount: 0, - initialize:function () { - this.template = Handlebars.compile($("#template-allapps").html()); - }, - beforeRender: function() { - return $.when(countlyAllApps.initialize()).then(function () {}); - }, - pageScript:function () { - $(".widget-content .inner").click(function () { - $(".big-numbers").removeClass("active"); - $(".big-numbers .select").removeClass("selected"); - $(this).parent(".big-numbers").addClass("active"); - $(this).find('.select').addClass("selected"); - }); - - var self = this; - $(".big-numbers .inner").click(function () { - var elID = $(this).find('.select').attr("id"); - - if (self.selectedView == "#" + elID) { - return true; - } - - self.selectedView = "#" + elID; - self.drawGraph(); - }); - - app.localize(); - }, - drawGraph:function() { - var sessionDP = []; - var sessions = countlyAllApps.getSessionData(); - var data, color; - var cnt = 0; - for(var i in this.selectedApps){ - try{ - data = sessions[i][this.selectedView]; - color = countlyCommon.GRAPH_COLORS[cnt]; - if(i == "all") - sessionDP.push({data:data.data, label:data.label + " for All Apps", color:color}); - else - sessionDP.push({data:data.data, label:data.label + " for "+countlyGlobal["apps"][i].name, color:color}); - $("#"+i+" .color").css("background-color", color); - cnt++; - } - catch(err){ - - } - } - _.defer(function () { - countlyCommon.drawTimeGraph(sessionDP, "#dashboard-graph"); - - }); - }, - renderCommon:function (isRefresh) { - $("#sidebar-app-select").find(".text").text(jQuery.i18n.map["allapps.title"]); - $("#sidebar-app-select").find(".logo").css("background-image", "url('/images/favicon.png')"); - $("#sidebar-menu > .item").addClass("hide"); - $("#management-menu").removeClass("hide"); - $("#enterprise-menu").removeClass("hide"); - $("#allapps-menu").removeClass("hide").css("display", "block"); - var appData = countlyAllApps.getData(); - - this.templateData = { - "page-title":jQuery.i18n.map["allapps.title"], - "logo-class":"platforms", - "usage":[ - { - "title":jQuery.i18n.map["common.total-sessions"], - "data":0, - "id":"draw-total-sessions", - "help":"dashboard.total-sessions" - }, - { - "title":jQuery.i18n.map["common.total-users"], - "data":0, - "id":"draw-total-users", - "help":"dashboard.total-users" - }, - { - "title":jQuery.i18n.map["common.new-users"], - "data":0, - "id":"draw-new-users", - "help":"dashboard.new-users" - }, - { - "title":jQuery.i18n.map["dashboard.time-spent"], - "data":0, - "id":"draw-total-time-spent", - "help":"dashboard.total-time-spent" - }, - { - "title":jQuery.i18n.map["dashboard.avg-time-spent"], - "data":0, - "id":"draw-time-spent", - "help":"dashboard.avg-time-spent2" - }, - { - "title":jQuery.i18n.map["dashboard.avg-reqs-received"], - "data":0, - "id":"draw-avg-events-served", - "help":"dashboard.avg-reqs-received" - } - ] - }; - var self = this; - if (!isRefresh) { - $(this.el).html(this.template(this.templateData)); - $(this.selectedView).parents(".big-numbers").addClass("active"); - this.pageScript(); - this.dtable = $('.d-table').dataTable($.extend({}, $.fn.dataTable.defaults, { - "aaData": appData, - "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { - $(nRow).attr("id", aData._id); - }, - "aoColumns": [ - { "mData": function(row, type){if(self.selectedApps[row._id]) return ""; else return "";}, "sWidth":"10px", "bSortable":false}, - { "mData": function(row, type){if(type == "display"){ var ret; if(row["_id"] == "all") ret = " "; else ret = " "; return ret+row.name+"
    ";} else return row.name;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.app-name"] }, - { "mData": function(row, type){if(type == "display") return "
    "+row.sessions.total; else return row.sessions.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-sessions"] }, - { "mData": function(row, type){if(type == "display") return "
    "+row.users.total; else return row.users.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-users"] }, - { "mData": function(row, type){if(type == "display") return "
    "+row.newusers.total; else return row.newusers.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.new-users"] }, - { "mData": function(row, type){if(type == "display") return "
    "+row.duration.total; else return row.duration.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.total-duration"] }, - { "mData": function(row, type){if(type == "display") return "
    "+row.avgduration.total; else return row.avgduration.total;}, "sType":"string", "sTitle": jQuery.i18n.map["allapps.average-duration"] } - ] - })); - this.drawGraph(); - $(".dataTable-bottom").append("
    Maximum number of applications to be compared (10)
    ") - - $(".d-table").stickyTableHeaders(); - - $('.allapps tbody').on("click", "tr", function (event){ - var td = $(event.target).closest("td"); - var row = $(this); - if(row.children().first().is(td)) - { - if(self.selectedApps[row.attr("id")]){ - row.find(".check").removeClass("icon-check").addClass("icon-unchecked"); - row.find(".color").css("background-color", "transparent"); - delete self.selectedApps[row.attr("id")]; - if(row.attr("id") != "all") - self.selectedCount--; - if(self.selectedCount==0){ - $("#empty-graph").show(); - $(".big-numbers").removeClass("active"); - $(".big-numbers .select").removeClass("selected"); - } - - } - else if(self.selectedCount < 10 || row.attr("id") == "all"){ - if(self.selectedCount==0){ - $("#empty-graph").hide(); - $(self.selectedView).parents(".big-numbers").addClass("active"); - } - if(row.attr("id") == "all"){ - $(".check.icon-check").removeClass("icon-check").addClass("icon-unchecked"); - $('.d-table').find(".color").css("background-color", "transparent"); - self.selectedApps = {}; - self.selectedCount = 0; - } - else{ - if(self.selectedApps["all"]){ - $(".d-table #all .check.icon-check").removeClass("icon-check").addClass("icon-unchecked"); - $('.d-table #all').find(".color").css("background-color", "transparent"); - delete self.selectedApps["all"]; - } - self.selectedCount++; - } - row.find(".check").removeClass("icon-unchecked").addClass("icon-check"); - self.selectedApps[row.attr("id")] = true; - } - self.drawGraph(); - } - else - { - var aData = self.dtable.fnGetData( this ); - countlyAllApps.setApp(row.attr("id")); - $("#sidebar-app-select").find(".logo").css("background-image", "url('/appimages/" + row.attr("id") + ".png')"); - $("#sidebar-app-select").find(".text").text(aData["name"]); - $("#sidebar-menu > .item").removeClass("hide"); - $("#allapps-menu").css("display", "none"); - window.location.hash = "#/"; - } - }); - } - }, - refresh:function () { - var self = this; - $.when(countlyAllApps.initialize()).then(function () { - if (app.activeView != self) { - return false; - } - self.renderCommon(true); - newPage = $("
    " + self.template(self.templateData) + "
    "); - - var appData = countlyAllApps.getData(); - CountlyHelpers.refreshTable(self.dtable, appData); - self.drawGraph(); - app.localize(); - }); - } -}); - -var AppRouter = Backbone.Router.extend({ - routes:{ - "/":"dashboard", - "/analytics/sessions":"sessions", - "/analytics/countries":"countries", - "/analytics/users":"users", - "/analytics/loyalty":"loyalty", - "/analytics/devices":"devices", - "/analytics/platforms":"platforms", - "/analytics/versions":"versions", - "/analytics/carriers":"carriers", - "/analytics/frequency":"frequency", - "/analytics/events":"events", - "/analytics/resolutions":"resolutions", - "/analytics/density":"density", - "/analytics/durations":"durations", - "/all":"allapps", - "/manage/apps":"manageApps", - "/manage/users":"manageUsers", - "/enterprise": "enterprise", - "*path":"main" - }, - activeView:null, //current view - dateToSelected:null, //date to selected from the date picker - dateFromSelected:null, //date from selected from the date picker - activeAppName:'', - activeAppKey:'', - main:function () { - this.navigate("/", true); - }, - dashboard:function () { - this.renderWhenReady(this.dashboardView); - }, - sessions:function () { - this.renderWhenReady(this.sessionView); + sessions:function () { + this.renderWhenReady(this.sessionView); }, countries:function () { this.renderWhenReady(this.countriesView); @@ -3123,6 +2798,9 @@ var AppRouter = Backbone.Router.extend({ }, users:function () { this.renderWhenReady(this.userView); + }, + allapps:function () { + this.renderWhenReady(this.allAppsView); }, loyalty:function () { this.renderWhenReady(this.loyaltyView); @@ -3145,552 +2823,1112 @@ var AppRouter = Backbone.Router.extend({ resolutions:function () { this.renderWhenReady(this.resolutionsView); }, - density:function () { - this.renderWhenReady(this.densityView); - }, durations:function () { this.renderWhenReady(this.durationsView); }, - enterprise:function () { - this.renderWhenReady(this.enterpriseView); - }, - allapps:function () { - this.renderWhenReady(this.allAppsView); - }, refreshActiveView:function () { }, //refresh interval function renderWhenReady:function (viewName) { //all view renders end up here - // If there is an active view call its destroy function to perform cleanups before a new view renders - if (this.activeView) { - this.activeView.destroy(); - } + // If there is an active view call its destroy function to perform cleanups before a new view renders + if (this.activeView) { + this.activeView.destroy(); + } + + this.activeView = viewName; + clearInterval(this.refreshActiveView); + + if (_.isEmpty(countlyGlobal['apps'])) { + if (Backbone.history.fragment != "/manage/apps") { + this.navigate("/manage/apps", true); + } else { + viewName.render(); + } + return false; + } + + viewName.render(); + + var self = this; + this.refreshActiveView = setInterval(function () { + self.activeView.refresh(); + if(self.refreshScripts[Backbone.history.fragment]) + for(var i = 0, l = self.refreshScripts[Backbone.history.fragment].length; i < l; i++) + self.refreshScripts[Backbone.history.fragment][i](); + if(self.refreshScripts["#"]) + for(var i = 0, l = self.refreshScripts["#"].length; i < l; i++) + self.refreshScripts["#"][i](); + }, countlyCommon.DASHBOARD_REFRESH_MS); + }, + initialize:function () { //initialize the dashboard, register helpers etc. + this.pageScripts = {}; + this.refreshScripts = {}; + this.dashboardView = new DashboardView(); + this.sessionView = new SessionView(); + this.countriesView = new CountriesView(); + this.userView = new UserView(); + this.allAppsView = new AllAppsView(); + this.loyaltyView = new LoyaltyView(); + this.deviceView = new DeviceView(); + this.platformView = new PlatformView(); + this.appVersionView = new AppVersionView(); + this.frequencyView = new FrequencyView(); + this.carrierView = new CarrierView(); + this.manageAppsView = new ManageAppsView(); + this.manageUsersView = new ManageUsersView(); + this.eventsView = new EventsView(); + this.resolutionsView = new ResolutionView(); + this.durationsView = new DurationView(); + + Handlebars.registerPartial("date-selector", $("#template-date-selector").html()); + Handlebars.registerPartial("timezones", $("#template-timezones").html()); + Handlebars.registerPartial("app-categories", $("#template-app-categories").html()); + Handlebars.registerHelper('eachOfObject', function (context, options) { + var ret = ""; + for (var prop in context) { + ret = ret + options.fn({property:prop, value:context[prop]}); + } + return ret; + }); + Handlebars.registerHelper('eachOfObjectValue', function (context, options) { + var ret = ""; + for (var prop in context) { + ret = ret + options.fn(context[prop]); + } + return ret; + }); + Handlebars.registerHelper('eachOfArray', function (context, options) { + var ret = ""; + for (var i = 0; i < context.length; i++) { + ret = ret + options.fn({value:context[i]}); + } + return ret; + }); + Handlebars.registerHelper('prettyJSON', function (context, options) { + return JSON.stringify(context, undefined, 4); + }); + Handlebars.registerHelper('getShortNumber', function (context, options) { + return countlyCommon.getShortNumber(context); + }); + Handlebars.registerHelper('getFormattedNumber', function (context, options) { + if (isNaN(context)) { + return context; + } + + ret = parseFloat((parseFloat(context).toFixed(2)).toString()).toString(); + return ret.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); + }); + Handlebars.registerHelper('toUpperCase', function (context, options) { + return context.toUpperCase(); + }); + Handlebars.registerHelper('appIdsToNames', function (context, options) { + return CountlyHelpers.appIdsToNames(context); + }); + Handlebars.registerHelper('forNumberOfTimes', function (context, options) { + var ret = ""; + for (var i = 0; i < context; i++) { + ret = ret + options.fn({count:i + 1}); + } + return ret; + }); + Handlebars.registerHelper('include', function (templatename, options) { + var partial = Handlebars.partials[templatename]; + var context = $.extend({}, this, options.hash); + return partial(context); + }); + Handlebars.registerHelper('for', function(from, to, incr, block) { + var accum = ''; + for(var i = from; i < to; i += incr) + accum += block.fn(i); + return accum; + }); + Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { + switch (operator) { + case '==': + return (v1 == v2) ? options.fn(this) : options.inverse(this); + case '===': + return (v1 === v2) ? options.fn(this) : options.inverse(this); + case '<': + return (v1 < v2) ? options.fn(this) : options.inverse(this); + case '<=': + return (v1 <= v2) ? options.fn(this) : options.inverse(this); + case '>': + return (v1 > v2) ? options.fn(this) : options.inverse(this); + case '>=': + return (v1 >= v2) ? options.fn(this) : options.inverse(this); + case '&&': + return (v1 && v2) ? options.fn(this) : options.inverse(this); + case '||': + return (v1 || v2) ? options.fn(this) : options.inverse(this); + default: + return options.inverse(this); + } + }); + + + jQuery.i18n.properties({ + name:'help', + cache:true, + language:countlyCommon.BROWSER_LANG_SHORT, + path:[countlyGlobal["cdn"]+'localization/help/'], + mode:'map', + callback:function () { + countlyCommon.HELP_MAP = jQuery.i18n.map; + jQuery.i18n.map = {}; + + var names = ["dashboard"], + paths = [countlyGlobal["cdn"]+'localization/dashboard/']; + + if(countlyGlobal["plugins"]){ + for(var i = 0, l = countlyGlobal["plugins"].length; i < l; i++){ + names.push(countlyGlobal["plugins"][i]); + paths.push(countlyGlobal["cdn"]+countlyGlobal["plugins"][i]+"/localization/"); + } + } + + jQuery.i18n.properties({ + name:names, + cache:true, + language:countlyCommon.BROWSER_LANG_SHORT, + path:paths, + mode:'map' + }); + } + }); + + var self = this; + $(document).ready(function () { + + CountlyHelpers.initializeSelect(); + CountlyHelpers.initializeTextSelect(); + CountlyHelpers.initializeHugeDropdown(); + + // If date range is selected initialize the calendar with these + var periodObj = countlyCommon.getPeriod(); + if (Object.prototype.toString.call(periodObj) === '[object Array]' && periodObj.length == 2) { + self.dateFromSelected = countlyCommon.getPeriod()[0]; + self.dateToSelected = countlyCommon.getPeriod()[1]; + } + + // Initialize localization related stuff + + // Localization test + /* + $.each(jQuery.i18n.map, function (key, value) { + jQuery.i18n.map[key] = key; + }); + */ + + try { + moment.lang(countlyCommon.BROWSER_LANG_SHORT); + } catch(e) { + moment.lang("en"); + } + + $(".reveal-language-menu").text(countlyCommon.BROWSER_LANG_SHORT.toUpperCase()); + + $(".apps-scrollable").sortable({ + items:".app-container.app-navigate", + revert:true, + forcePlaceholderSize:true, + handle:".drag", + containment:"parent", + tolerance:"pointer", + stop:function () { + var orderArr = []; + $(".app-container.app-navigate").each(function () { + if ($(this).data("id")) { + orderArr.push($(this).data("id")) + } + }); + + $.ajax({ + type:"POST", + url:countlyGlobal["path"]+"/dashboard/settings", + data:{ + "app_sort_list":orderArr, + _csrf:countlyGlobal['csrf_token'] + }, + success:function (result) { + } + }); + } + }); + + $("#sort-app-button").click(function () { + $(".app-container.app-navigate .drag").fadeToggle(); + }); + + $(".app-navigate").live("click", function () { + var appKey = $(this).data("key"), + appId = $(this).data("id"), + appName = $(this).find(".name").text(), + appImage = $(this).find(".logo").css("background-image"), + sidebarApp = $("#sidebar-app-select"); + + if (appId == "allapps") { + window.location.hash = "/all"; + sidebarApp.removeClass("active"); + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); + self.activeAppKey = appKey; + return false; + } + else{ + $("#sidebar-menu > .item").removeClass("hide"); + $("#allapps-menu").css("display", "none"); + } + + if(window.location.hash.toString() == "#/all") + window.location.hash = "/"; + + if (self.activeAppKey == appKey) { + sidebarApp.removeClass("active"); + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); + return false; + } + + self.activeAppName = appName; + self.activeAppKey = appKey; + + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack', complete:function () { + countlyCommon.setActiveApp(appId); + sidebarApp.find(".text").text(appName); + sidebarApp.find(".logo").css("background-image", appImage); + sidebarApp.removeClass("active"); + self.activeView.appChanged(); + }}); + }); + + $("#sidebar-events").click(function (e) { + $.when(countlyEvent.refreshEvents()).then(function () { + if (countlyEvent.getEvents().length == 0) { + CountlyHelpers.alert(jQuery.i18n.map["events.no-event"], "black"); + e.stopImmediatePropagation(); + e.preventDefault(); + } + }); + }); + + $("#sidebar-menu").on("click", ".item", function () { + var elNext = $(this).next(), + isElActive = $(this).hasClass("active"); + + if (isElActive) { + $(".sidebar-submenu").not(elNext).slideUp(); + } + + if (elNext.hasClass("sidebar-submenu") && !(isElActive)) { + elNext.slideToggle(); + } else { + $("#sidebar-menu>.item").removeClass("active"); + $(this).addClass("active"); + + if ($("#app-nav").offset().left == 201) { + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); + $("#sidebar-app-select").removeClass("active"); + } + } + }); + + $(".sidebar-submenu").on("click", ".item", function () { + + if ($(this).hasClass("disabled")) { + return true; + } + + if ($("#app-nav").offset().left == 201) { + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); + $("#sidebar-app-select").removeClass("active"); + } + + $(".sidebar-submenu .item").removeClass("active"); + $(this).addClass("active"); + $(this).parent().prev(".item").addClass("active"); + }); + + $("#sidebar-app-select").click(function () { + + if ($(this).hasClass("disabled")) { + return true; + } + + if ($(this).hasClass("active")) { + $(this).removeClass("active"); + } else { + $(this).addClass("active"); + } + + $("#app-nav").show(); + var left = $("#app-nav").offset().left; + + if (left == 201) { + $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); + } else { + $("#app-nav").animate({left:'201px'}, {duration:500, easing:'easeOutBack'}); + } + + }); + + $("#sidebar-bottom-container .reveal-menu").click(function () { + $("#language-menu").hide(); + $("#sidebar-bottom-container .menu").toggle(); + }); + + $("#sidebar-bottom-container .reveal-language-menu").click(function () { + $("#sidebar-bottom-container .menu").hide(); + $("#language-menu").toggle(); + }); + + $("#sidebar-bottom-container .item").click(function () { + $("#sidebar-bottom-container .menu").hide(); + $("#language-menu").hide(); + }); + + $("#language-menu .item").click(function () { + var langCode = $(this).data("language-code"), + langCodeUpper = langCode.toUpperCase(); + + store.set("countly_lang", langCode); + $(".reveal-language-menu").text(langCodeUpper); + + countlyCommon.BROWSER_LANG_SHORT = langCode; + countlyCommon.BROWSER_LANG = langCode; + + try { + moment.lang(countlyCommon.BROWSER_LANG_SHORT); + } catch(e) { + moment.lang("en"); + } + + $("#date-to").datepicker("option", $.datepicker.regional[countlyCommon.BROWSER_LANG]); + $("#date-from").datepicker("option", $.datepicker.regional[countlyCommon.BROWSER_LANG]); + + jQuery.i18n.properties({ + name:'help', + cache:true, + language:countlyCommon.BROWSER_LANG_SHORT, + path:[countlyGlobal["cdn"]+'localization/help/'], + mode:'map', + callback:function () { + countlyCommon.HELP_MAP = jQuery.i18n.map; + jQuery.i18n.map = {}; + + var names = ["dashboard"], + paths = [countlyGlobal["cdn"]+'localization/dashboard/']; + + if(countlyGlobal["plugins"]){ + for(var i = 0, l = countlyGlobal["plugins"].length; i < l; i++){ + names.push(countlyGlobal["plugins"][i]); + paths.push(countlyGlobal["cdn"]+countlyGlobal["plugins"][i]+"/localization/"); + } + } + jQuery.i18n.properties({ + name:names, + cache:true, + language:countlyCommon.BROWSER_LANG_SHORT, + path:paths, + mode:'map', + callback:function () { + $.when(countlyLocation.changeLanguage()).then(function () { + self.activeView.render(); + self.pageScript(); + }); + } + }); + } + }); + }); + + $("#account-settings").click(function () { + CountlyHelpers.popup("#edit-account-details"); + $(".dialog #username").val($("#menu-username").text()); + $(".dialog #api-key").val($("#user-api-key").val()); + }); + + $("#save-account-details:not(.disabled)").live('click', function () { + var username = $(".dialog #username").val(), + old_pwd = $(".dialog #old_pwd").val(), + new_pwd = $(".dialog #new_pwd").val(), + re_new_pwd = $(".dialog #re_new_pwd").val(); + + if (new_pwd != re_new_pwd) { + $(".dialog #settings-save-result").addClass("red").text(jQuery.i18n.map["user-settings.password-match"]); + return true; + } + + $(this).addClass("disabled"); + + $.ajax({ + type:"POST", + url:countlyGlobal["path"]+"/user/settings", + data:{ + "username":username, + "old_pwd":old_pwd, + "new_pwd":new_pwd, + _csrf:countlyGlobal['csrf_token'] + }, + success:function (result) { + var saveResult = $(".dialog #settings-save-result"); + + if (result == "username-exists") { + saveResult.removeClass("green").addClass("red").text(jQuery.i18n.map["management-users.username.exists"]); + } else if (!result) { + saveResult.removeClass("green").addClass("red").text(jQuery.i18n.map["user-settings.alert"]); + } else { + saveResult.removeClass("red").addClass("green").text(jQuery.i18n.map["user-settings.success"]); + $(".dialog #old_pwd").val(""); + $(".dialog #new_pwd").val(""); + $(".dialog #re_new_pwd").val(""); + $("#menu-username").text(username); + } + + $(".dialog #save-account-details").removeClass("disabled"); + } + }); + }); + + $('.apps-scrollable').slimScroll({ + height:'100%', + start:'top', + wheelStep:10, + position:'right', + disableFadeOut:true + }); + + var help = _.once(function () { + CountlyHelpers.alert(countlyCommon.HELP_MAP["help-mode-welcome"], "black"); + }); + $(".help-toggle, #help-toggle").click(function (e) { + + $('.help-zone-vb').tipsy({gravity:$.fn.tipsy.autoNS, trigger:'manual', title:function () { + return ($(this).data("help")) ? $(this).data("help") : ""; + }, fade:true, offset:5, cssClass:'yellow', opacity:1, html:true}); + $('.help-zone-vs').tipsy({gravity:$.fn.tipsy.autoNS, trigger:'manual', title:function () { + return ($(this).data("help")) ? $(this).data("help") : ""; + }, fade:true, offset:5, cssClass:'yellow narrow', opacity:1, html:true}); + + $("#help-toggle").toggleClass("active"); + if ($("#help-toggle").hasClass("active")) { + help(); + $.idleTimer('destroy'); + clearInterval(self.refreshActiveView); + + $(".help-zone-vs, .help-zone-vb").hover( + function () { + $(this).tipsy("show"); + }, + function () { + $(this).tipsy("hide"); + } + ); + } else { + self.refreshActiveView = setInterval(function () { + self.activeView.refresh(); + }, countlyCommon.DASHBOARD_REFRESH_MS); + $.idleTimer(countlyCommon.DASHBOARD_IDLE_MS); + $(".help-zone-vs, .help-zone-vb").unbind('mouseenter mouseleave'); + } + e.stopPropagation(); + }); + + $("#user-logout").click(function () { + store.remove('countly_active_app'); + store.remove('countly_date'); + store.remove('countly_location_city'); + }); + + $(".beta-button").click(function () { + CountlyHelpers.alert("This feature is currently in beta so the data you see in this view might change or disappear into thin air.

    If you find any bugs or have suggestions please let us know!

    Captain Obvious: You can use the message box that appears when you click the question mark on the bottom right corner of this page.", "black"); + }); + + $("#content").on("click", "#graph-note", function () { + CountlyHelpers.popup("#graph-note-popup"); + + $(".note-date:visible").datepicker({ + numberOfMonths:1, + showOtherMonths:true, + onSelect:function () { + dateText(); + } + }); + + $.datepicker.setDefaults($.datepicker.regional[""]); + $(".note-date:visible").datepicker("option", $.datepicker.regional[countlyCommon.BROWSER_LANG]); + + $('.note-popup:visible .time-picker, .note-popup:visible .note-list').slimScroll({ + height:'100%', + start:'top', + wheelStep:10, + position:'right', + disableFadeOut:true + }); + + $(".note-popup:visible .time-picker span").on("click", function() { + $(".note-popup:visible .time-picker span").removeClass("selected"); + $(this).addClass("selected"); + dateText(); + }); + + + $(".note-popup:visible .manage-notes-button").on("click", function() { + $(".note-popup:visible .note-create").hide(); + $(".note-popup:visible .note-manage").show(); + $(".note-popup:visible .create-note-button").show(); + $(this).hide(); + $(".note-popup:visible .create-note").hide(); + }); + + $(".note-popup:visible .create-note-button").on("click", function() { + $(".note-popup:visible .note-create").show(); + $(".note-popup:visible .note-manage").hide(); + $(".note-popup:visible .manage-notes-button").show(); + $(this).hide(); + $(".note-popup:visible .create-note").show(); + }); + + dateText(); + + function dateText() { + var selectedDate = $(".note-date:visible").val(), + instance = $(".note-date:visible").data("datepicker"), + date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings); + + $(".selected-date:visible").text(moment(date).format("D MMM YYYY") + ", " + $(".time-picker:visible span.selected").text()); + } + + if (countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID] && countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes) { + var noteDateIds = _.sortBy(_.keys(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes), function(el) { return -parseInt(el); }); + + for (var i = 0; i < noteDateIds.length; i++) { + var currNotes = countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes[noteDateIds[i]]; + + for (var j = 0; j < currNotes.length; j++) { + $(".note-popup:visible .note-list").append( + '
    ' + + '
    ' + moment(noteDateIds[i], "YYYYMMDDHH").format("D MMM YYYY, HH:mm") + '
    ' + + '
    ' + currNotes[j] + '
    ' + + '
    ' + + '
    ' + ); + } + } + } + + if (!$(".note-popup:visible .note").length) { + $(".note-popup:visible .manage-notes-button").hide(); + } + + $('.note-popup:visible .note-content').textcounter({ + max: 50, + countDown: true, + countDownText: "remaining " + }); + + $(".note-popup:visible .note .delete-note").on("click", function() { + var dateId = $(this).siblings(".date").data("dateid"), + note = $(this).siblings(".content").text(); + + $(this).parents(".note").fadeOut().remove(); + + $.ajax({ + type:"POST", + url:countlyGlobal["path"]+'/graphnotes/delete', + data:{ + "app_id":countlyCommon.ACTIVE_APP_ID, + "date_id":dateId, + "note":note, + _csrf:countlyGlobal['csrf_token'] + }, + success:function (result) { + if (result == false) { + return false; + } else { + updateGlobalNotes({date_id: dateId, note:note}, "delete"); + app.activeView.refresh(); + } + } + }); + + if (!$(".note-popup:visible .note").length) { + $(".note-popup:visible .create-note-button").trigger("click"); + $(".note-popup:visible .manage-notes-button").hide(); + } + }); + + $(".note-popup:visible .create-note").on("click", function() { + if ($(this).hasClass("disabled")) { + return true; + } + + $(this).addClass("disabled"); + + var selectedDate = $(".note-date:visible").val(), + instance = $(".note-date:visible").data("datepicker"), + date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings), + dateId = moment(moment(date).format("D MMM YYYY") + ", " + $(".time-picker:visible span.selected").text(), "D MMM YYYY, HH:mm").format("YYYYMMDDHH"), + note = $(".note-popup:visible .note-content").val(); + + if (!note.length) { + $(".note-popup:visible .note-content").addClass("required-border"); + $(this).removeClass("disabled"); + return true; + } else { + $(".note-popup:visible .note-content").removeClass("required-border"); + } + + $.ajax({ + type:"POST", + url:countlyGlobal["path"]+'/graphnotes/create', + data:{ + "app_id":countlyCommon.ACTIVE_APP_ID, + "date_id":dateId, + "note":note, + _csrf:countlyGlobal['csrf_token'] + }, + success:function (result) { + if (result == false) { + return false; + } else { + updateGlobalNotes({date_id: dateId, note:result}, "create"); + app.activeView.refresh(); + } + } + }); + + $("#overlay").trigger("click"); + }); - this.activeView = viewName; - clearInterval(this.refreshActiveView); + function updateGlobalNotes(noteObj, operation) { + var globalNotes = countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes; - if (_.isEmpty(countlyGlobal['apps'])) { - if (Backbone.history.fragment != "/manage/apps") { - this.navigate("/manage/apps", true); + if (operation == "create") { + if (globalNotes) { + if (globalNotes[noteObj.date_id]) { + countlyCommon.arrayAddUniq(globalNotes[noteObj.date_id], noteObj.note); + } else { + globalNotes[noteObj.date_id] = [noteObj.note]; + } + } else { + var tmpNote = {}; + tmpNote[noteObj.date_id] = [noteObj.note]; + + countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes = tmpNote; + } + } else if (operation == "delete") { + if (globalNotes) { + if (globalNotes[noteObj.date_id]) { + globalNotes[noteObj.date_id] = _.without(globalNotes[noteObj.date_id], noteObj.note); + } + } + } + } + }); + }); + + if (!_.isEmpty(countlyGlobal['apps'])) { + if (!countlyCommon.ACTIVE_APP_ID) { + for (var appId in countlyGlobal['apps']) { + countlyCommon.setActiveApp(appId); + self.activeAppName = countlyGlobal['apps'][appId].name; + break; + } } else { - viewName.render(); + $("#sidebar-app-select").find(".logo").css("background-image", "url('"+countlyGlobal["cdn"]+"appimages/" + countlyCommon.ACTIVE_APP_ID + ".png')"); + $("#sidebar-app-select .text").text(countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID].name); + self.activeAppName = countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID].name; } - return false; + } else { + $("#new-install-overlay").show(); } - viewName.render(); - - var self = this; - this.refreshActiveView = setInterval(function () { - self.activeView.refresh(); - }, countlyCommon.DASHBOARD_REFRESH_MS); - }, - initialize:function () { //initialize the dashboard, register helpers etc. - - this.dashboardView = new DashboardView(); - this.sessionView = new SessionView(); - this.countriesView = new CountriesView(); - this.userView = new UserView(); - this.loyaltyView = new LoyaltyView(); - this.deviceView = new DeviceView(); - this.platformView = new PlatformView(); - this.appVersionView = new AppVersionView(); - this.frequencyView = new FrequencyView(); - this.carrierView = new CarrierView(); - this.manageAppsView = new ManageAppsView(); - this.manageUsersView = new ManageUsersView(); - this.eventsView = new EventsView(); - this.resolutionsView = new ResolutionView(); - this.densityView = new DensityView(); - this.durationsView = new DurationView(); - this.enterpriseView = new EnterpriseView(); - this.allAppsView = new AllAppsView(); + $.idleTimer(countlyCommon.DASHBOARD_IDLE_MS); - Handlebars.registerPartial("date-selector", $("#template-date-selector").html()); - Handlebars.registerPartial("timezones", $("#template-timezones").html()); - Handlebars.registerPartial("app-categories", $("#template-app-categories").html()); - Handlebars.registerHelper('eachOfObject', function (context, options) { - var ret = ""; - for (var prop in context) { - ret = ret + options.fn({property:prop, value:context[prop]}); - } - return ret; - }); - Handlebars.registerHelper('eachOfObjectValue', function (context, options) { - var ret = ""; - for (var prop in context) { - ret = ret + options.fn(context[prop]); - } - return ret; - }); - Handlebars.registerHelper('eachOfArray', function (context, options) { - var ret = ""; - for (var i = 0; i < context.length; i++) { - ret = ret + options.fn({value:context[i]}); - } - return ret; - }); - Handlebars.registerHelper('getShortNumber', function (context, options) { - return countlyCommon.getShortNumber(context); + $(document).bind("idle.idleTimer", function () { + clearInterval(self.refreshActiveView); }); - Handlebars.registerHelper('getFormattedNumber', function (context, options) { - if (!_.isNumber(context)) { - return context; - } - ret = parseFloat((parseFloat(context).toFixed(2)).toString()).toString(); - return ret.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); - }); - Handlebars.registerHelper('toUpperCase', function (context, options) { - return context.toUpperCase(); + $(document).bind("active.idleTimer", function () { + self.activeView.restart(); + self.refreshActiveView = setInterval(function () { + self.activeView.refresh(); + }, countlyCommon.DASHBOARD_REFRESH_MS); }); - Handlebars.registerHelper('appIdsToNames', function (context, options) { - var ret = ""; - for (var i = 0; i < context.length; i++) { - if (!countlyGlobal['apps'][context[i]]) { - continue; - } + $.fn.dataTableExt.oPagination.four_button = { + "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) + { + nFirst = document.createElement( 'span' ); + nPrevious = document.createElement( 'span' ); + nNext = document.createElement( 'span' ); + nLast = document.createElement( 'span' ); - ret += countlyGlobal['apps'][context[i]]["name"]; + nFirst.innerHTML = ""; + nPrevious.innerHTML = ""; + nNext.innerHTML = ""; + nLast.innerHTML = ""; - if (context.length > 1 && i != context.length - 1) { - ret += ", "; - } - } + nFirst.className = "paginate_button first"; + nPrevious.className = "paginate_button previous"; + nNext.className="paginate_button next"; + nLast.className = "paginate_button last"; - return ret; - }); - Handlebars.registerHelper('forNumberOfTimes', function (context, options) { - var ret = ""; - for (var i = 0; i < context; i++) { - ret = ret + options.fn({count:i + 1}); - } - return ret; - }); - Handlebars.registerHelper('include', function (templatename, options) { - var partial = Handlebars.partials[templatename]; - var context = $.extend({}, this, options.hash); - return partial(context); - }); + nPaging.appendChild( nFirst ); + nPaging.appendChild( nPrevious ); + nPaging.appendChild( nNext ); + nPaging.appendChild( nLast ); - $.tablesorter.addParser({ - id:'customDate', - is:function (s) { - return false; + $(nFirst).click( function () { + oSettings.oApi._fnPageChange( oSettings, "first" ); + fnCallbackDraw( oSettings ); + } ); + + $(nPrevious).click( function() { + oSettings.oApi._fnPageChange( oSettings, "previous" ); + fnCallbackDraw( oSettings ); + } ); + + $(nNext).click( function() { + oSettings.oApi._fnPageChange( oSettings, "next" ); + fnCallbackDraw( oSettings ); + } ); + + $(nLast).click( function() { + oSettings.oApi._fnPageChange( oSettings, "last" ); + fnCallbackDraw( oSettings ); + } ); + + $(nFirst).bind( 'selectstart', function () { return false; } ); + $(nPrevious).bind( 'selectstart', function () { return false; } ); + $(nNext).bind( 'selectstart', function () { return false; } ); + $(nLast).bind( 'selectstart', function () { return false; } ); }, - format:function (s) { - if (s.indexOf(":") != -1) { - if (s.indexOf(",") != -1) { - var dateParts = s.split(" "); - return dateParts[2].replace(':', ''); - } else { - return s.replace(':', ''); - } - } else if (s.length == 3) { - return moment.monthsShort.indexOf(s); - } else { - var dateParts = s.split(" "); - return parseInt(moment.monthsShort.indexOf(dateParts[1]) * 100) + parseInt(dateParts[0]); + + "fnUpdate": function ( oSettings, fnCallbackDraw ) + { + if ( !oSettings.aanFeatures.p ) + { + return; } - }, - type:'numeric' - }); - jQuery.i18n.properties({ - name:'help', - cache:true, - language:countlyCommon.BROWSER_LANG_SHORT, - path:'/localization/help/', - mode:'map', - callback:function () { - countlyCommon.HELP_MAP = jQuery.i18n.map; - jQuery.i18n.map = {}; + var an = oSettings.aanFeatures.p; + for ( var i=0, iLen=an.length ; i y) ? 1 : 0)); + }; - $.ajax({ - type:"POST", - url:"/dashboard/settings", - data:{ - "app_sort_list":orderArr, - _csrf:countlyGlobal['csrf_token'] - }, - success:function (result) { - } - }); - } - }); + jQuery.fn.dataTableExt.oSort['customDate-desc'] = function(x, y) { + x = getCustomDateInt(x); + y = getCustomDateInt(y); - $("#sort-app-button").click(function () { - $(".app-container.app-navigate .drag").fadeToggle(); - }); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - $(".app-navigate").live("click", function () { - var appKey = $(this).data("key"), - appId = $(this).data("id"), - appName = $(this).find(".name").text(), - appImage = $(this).find(".logo").css("background-image"), - sidebarApp = $("#sidebar-app-select"); - - if (appId == "allapps") { - window.location.hash = "/all"; - sidebarApp.removeClass("active"); - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); - return false; - } - else{ - $("#sidebar-menu > .item").removeClass("hide"); - $("#allapps-menu").css("display", "none"); - } + function getDateRangeInt(s) { + s = s.split("-")[0]; + var mEnglish = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - if(window.location.hash.toString() == "#/all") - window.location.hash = "/"; + if (s.indexOf(":") != -1) { + var mName = (s.split(" ")[1]).split(",")[0]; - if (self.activeAppKey == appKey) { - sidebarApp.removeClass("active"); - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); - return false; + return s.replace(mName, parseInt(mEnglish.indexOf(mName))).replace(/[:, ]/g, ""); + } else { + var parts = s.split(" "); + if (parts.length > 1) { + return parseInt(mEnglish.indexOf(parts[1]) * 100) + parseInt(parts[0]); + } else { + return parts[0].replace(/[><]/g, ""); } + } + } - self.activeAppName = appName; - self.activeAppKey = appKey; - - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack', complete:function () { - countlyCommon.setActiveApp(appId); - sidebarApp.find(".text").text(appName); - sidebarApp.find(".logo").css("background-image", appImage); - sidebarApp.removeClass("active"); - self.activeView.appChanged(); - }}); - }); + jQuery.fn.dataTableExt.oSort['dateRange-asc'] = function(x, y) { + x = getDateRangeInt(x); + y = getDateRangeInt(y); - $("#sidebar-events").click(function (e) { - $.when(countlyEvent.refreshEvents()).then(function () { - if (countlyEvent.getEvents().length == 0) { - CountlyHelpers.alert(jQuery.i18n.map["events.no-event"], "black"); - e.stopImmediatePropagation(); - e.preventDefault(); - } - }); - }); + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }; - $("#sidebar-menu>.item").click(function () { - var elNext = $(this).next(), - elNextSubmenuItems = elNext.find(".item"), - isElActive = $(this).hasClass("active"); + jQuery.fn.dataTableExt.oSort['dateRange-desc'] = function(x, y) { + x = getDateRangeInt(x); + y = getDateRangeInt(y); - if (!isElActive) { - $(".sidebar-submenu").not(elNext).slideUp(); - } + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - if (elNext.hasClass("sidebar-submenu") && !(isElActive)) { - elNext.slideToggle(); - } else { - $("#sidebar-menu>.item").removeClass("active"); - $(this).addClass("active"); + jQuery.fn.dataTableExt.oSort['percent-asc'] = function(x, y) { + x = parseFloat($("").html(x).text().replace("%","")); + y = parseFloat($("").html(y).text().replace("%","")); - if ($("#app-nav").offset().left == 201) { - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); - $("#sidebar-app-select").removeClass("active"); - } - } + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }; - if ($(this).attr("href")) { - $("#sidebar-app-select").removeClass("disabled"); - } - }); + jQuery.fn.dataTableExt.oSort['percent-desc'] = function(x, y) { + x = parseFloat($("").html(x).text().replace("%","")); + y = parseFloat($("").html(y).text().replace("%","")); - $(".sidebar-submenu .item").click(function () { + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - if ($(this).hasClass("disabled")) { - return true; - } + jQuery.fn.dataTableExt.oSort['formatted-num-asc'] = function (x, y) { + 'use strict'; - if ($(this).attr("href") == "#/manage/apps") { - $("#sidebar-app-select").addClass("disabled"); - $("#sidebar-app-select").removeClass("active"); - } else { - $("#sidebar-app-select").removeClass("disabled"); - } + // Define vars + var a = [], b = []; - if ($("#app-nav").offset().left == 201) { - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); - $("#sidebar-app-select").removeClass("active"); - } + // Match any character except: digits (0-9), dash (-), period (.), or backslash (/) and replace those characters with empty string. + x = x.replace(/[^\d\-\.\/]/g, ''); + y = y.replace(/[^\d\-\.\/]/g, ''); - $(".sidebar-submenu .item").removeClass("active"); - $(this).addClass("active"); - $(this).parent().prev(".item").addClass("active"); - }); + // Handle simple fractions + if (x.indexOf('/') >= 0) { + a = x.split("/"); + x = parseInt(a[0], 10) / parseInt(a[1], 10); + } + if (y.indexOf('/') >= 0) { + b = y.split("/"); + y = parseInt(b[0], 10) / parseInt(b[1], 10); + } - $("#sidebar-app-select").click(function () { + return x - y; + }; - if ($(this).hasClass("disabled")) { - return true; - } + jQuery.fn.dataTableExt.oSort['formatted-num-desc'] = function (x, y) { + 'use strict'; - if ($(this).hasClass("active")) { - $(this).removeClass("active"); - } else { - $(this).addClass("active"); - } + // Define vars + var a = [], b = []; - $("#app-nav").show(); - var left = $("#app-nav").offset().left; + // Match any character except: digits (0-9), dash (-), period (.), or backslash (/) and replace those characters with empty string. + x = x.replace(/[^\d\-\.\/]/g, ''); + y = y.replace(/[^\d\-\.\/]/g, ''); - if (left == 201) { - $("#app-nav").animate({left:'31px'}, {duration:500, easing:'easeInBack'}); - } else { - $("#app-nav").animate({left:'201px'}, {duration:500, easing:'easeOutBack'}); - } + // Handle simple fractions + if (x.indexOf('/') >= 0) { + a = x.split("/"); + x = parseInt(a[0], 10) / parseInt(a[1], 10); + } + if (y.indexOf('/') >= 0) { + b = y.split("/"); + y = parseInt(b[0], 10) / parseInt(b[1], 10); + } - }); + return y - x; + }; - $("#sidebar-bottom-container .reveal-menu").click(function () { - $("#language-menu").hide(); - $("#sidebar-bottom-container .menu").toggle(); - }); + jQuery.fn.dataTableExt.oSort['loyalty-asc'] = function(x, y) { + x = countlyUser.getLoyaltyIndex(x); + y = countlyUser.getLoyaltyIndex(y); - $("#sidebar-bottom-container .reveal-language-menu").click(function () { - $("#sidebar-bottom-container .menu").hide(); - $("#language-menu").toggle(); - }); + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }; - $("#sidebar-bottom-container .item").click(function () { - $("#sidebar-bottom-container .menu").hide(); - $("#language-menu").hide(); - }); + jQuery.fn.dataTableExt.oSort['loyalty-desc'] = function(x, y) { + x = countlyUser.getLoyaltyIndex(x); + y = countlyUser.getLoyaltyIndex(y); - $("#language-menu .item").click(function () { - var langCode = $(this).data("language-code"), - langCodeUpper = langCode.toUpperCase(); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - store.set("countly_lang", langCode); - $(".reveal-language-menu").text(langCodeUpper); + jQuery.fn.dataTableExt.oSort['frequency-asc'] = function(x, y) { + x = countlyUser.getFrequencyIndex(x); + y = countlyUser.getFrequencyIndex(y); - countlyCommon.BROWSER_LANG_SHORT = langCode; - countlyCommon.BROWSER_LANG = langCode; + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }; - try { - moment.lang(countlyCommon.BROWSER_LANG_SHORT); - } catch(e) { - moment.lang("en"); - } + jQuery.fn.dataTableExt.oSort['frequency-desc'] = function(x, y) { + x = countlyUser.getFrequencyIndex(x); + y = countlyUser.getFrequencyIndex(y); - $("#date-to").datepicker("option", $.datepicker.regional[countlyCommon.BROWSER_LANG]); - $("#date-from").datepicker("option", $.datepicker.regional[countlyCommon.BROWSER_LANG]); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - jQuery.i18n.properties({ - name:'help', - cache:true, - language:countlyCommon.BROWSER_LANG_SHORT, - path:'/localization/help/', - mode:'map', - callback:function () { - countlyCommon.HELP_MAP = jQuery.i18n.map; - jQuery.i18n.map = {}; + jQuery.fn.dataTableExt.oSort['session-duration-asc'] = function(x, y) { + x = countlySession.getDurationIndex(x); + y = countlySession.getDurationIndex(y); - jQuery.i18n.properties({ - name:'dashboard', - cache:true, - language:countlyCommon.BROWSER_LANG_SHORT, - path:'/localization/dashboard/', - mode:'map', - callback:function () { - $.when(countlyLocation.changeLanguage()).then(function () { - self.activeView.render(); - self.pageScript(); - }); - } - }); - } - }); - }); + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }; - $("#account-settings").click(function () { - CountlyHelpers.popup("#edit-account-details"); - $(".dialog #username").val($("#menu-username").text()); - $(".dialog #api-key").val($("#user-api-key").val()); - }); + jQuery.fn.dataTableExt.oSort['session-duration-desc'] = function(x, y) { + x = countlySession.getDurationIndex(x); + y = countlySession.getDurationIndex(y); - $("#save-account-details:not(.disabled)").live('click', function () { - var username = $(".dialog #username").val(), - old_pwd = $(".dialog #old_pwd").val(), - new_pwd = $(".dialog #new_pwd").val(), - re_new_pwd = $(".dialog #re_new_pwd").val(); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }; - if (new_pwd != re_new_pwd) { - $(".dialog #settings-save-result").addClass("red").text(jQuery.i18n.map["user-settings.password-match"]); - return true; - } + $.extend($.fn.dataTable.defaults, { + "sDom": '<"dataTable-top"fpT>t<"dataTable-bottom"i>', + "bAutoWidth": false, + "sPaginationType": "four_button", + "iDisplayLength": 50, + "bDestroy": true, + "bDeferRender": true, + "oTableTools": { + "sSwfPath": countlyGlobal["cdn"]+"javascripts/dom/dataTables/swf/copy_csv_xls.swf", + "aButtons": [ + { + "sExtends": "csv", + "sButtonText": "Save to CSV", + "fnClick": function (nButton, oConfig, flash) { + var tableCols = $(nButton).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, + tableData = this.fnGetTableData(oConfig).split(/\r\n|\r|\n/g).join('","').split('","'), + retStr = ""; - $(this).addClass("disabled"); + for (var i = 0; i < tableData.length; i++) { + tableData[i] = tableData[i].replace("\"", ""); - $.ajax({ - type:"POST", - url:"/user/settings", - data:{ - "username":username, - "old_pwd":old_pwd, - "new_pwd":new_pwd, - _csrf:countlyGlobal['csrf_token'] - }, - success:function (result) { - var saveResult = $(".dialog #settings-save-result"); + if (i >= tableCols.length) { + var colIndex = i % tableCols.length; - if (result == "username-exists") { - saveResult.removeClass("green").addClass("red").text(jQuery.i18n.map["management-users.username.exists"]); - } else if (!result) { - saveResult.removeClass("green").addClass("red").text(jQuery.i18n.map["user-settings.alert"]); - } else { - saveResult.removeClass("red").addClass("green").text(jQuery.i18n.map["user-settings.success"]); - $(".dialog #old_pwd").val(""); - $(".dialog #new_pwd").val(""); - $(".dialog #re_new_pwd").val(""); - $("#menu-username").text(username); - } + if (tableCols[colIndex].sType == "formatted-num") { + tableData[i] = tableData[i].replace(/,/g, ""); + } else if (tableCols[colIndex].sType == "percent") { + tableData[i] = tableData[i].replace("%", ""); + } + } - $(".dialog #save-account-details").removeClass("disabled"); - } - }); - }); + if ((i + 1) % tableCols.length == 0) { + retStr += "\"" + tableData[i] + "\"\r\n"; + } else { + retStr += "\"" + tableData[i] + "\", "; + } + } - $('.apps-scrollable').slimScroll({ - height:'100%', - start:'top', - wheelStep:10, - position:'right', - disableFadeOut:true - }); + this.fnSetText(flash, retStr); + } + }, + { + "sExtends": "xls", + "sButtonText": "Save for Excel", + "fnClick": function (nButton, oConfig, flash) { + var tableCols = $(nButton).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, + tableData = this.fnGetTableData(oConfig).split(/\r\n|\r|\n/g).join('\t').split('\t'), + retStr = ""; - var help = _.once(function () { - CountlyHelpers.alert(countlyCommon.HELP_MAP["help-mode-welcome"], "black"); - }); - $(".help-toggle, #help-toggle").click(function (e) { + for (var i = 0; i < tableData.length; i++) { + if (i >= tableCols.length) { + var colIndex = i % tableCols.length; - $('.help-zone-vb').tipsy({gravity:$.fn.tipsy.autoNS, trigger:'manual', title:function () { - return ($(this).data("help")) ? $(this).data("help") : ""; - }, fade:true, offset:5, cssClass:'yellow', opacity:1, html:true}); - $('.help-zone-vs').tipsy({gravity:$.fn.tipsy.autoNS, trigger:'manual', title:function () { - return ($(this).data("help")) ? $(this).data("help") : ""; - }, fade:true, offset:5, cssClass:'yellow narrow', opacity:1, html:true}); + if (tableCols[colIndex].sType == "formatted-num") { + tableData[i] = parseFloat(tableData[i].replace(/,/g, "")).toLocaleString(); + } else if (tableCols[colIndex].sType == "percent") { + tableData[i] = parseFloat(tableData[i].replace("%", "")).toLocaleString(); + } else if (tableCols[colIndex].sType == "numeric") { + tableData[i] = parseFloat(tableData[i]).toLocaleString(); + } + } - $("#help-toggle").toggleClass("active"); - if ($("#help-toggle").hasClass("active")) { - help(); - $.idleTimer('destroy'); - clearInterval(self.refreshActiveView); + if ((i + 1) % tableCols.length == 0) { + retStr += tableData[i] + "\r\n"; + } else { + retStr += tableData[i] + "\t"; + } + } - $(".help-zone-vs, .help-zone-vb").hover( - function () { - $(this).tipsy("show"); - }, - function () { - $(this).tipsy("hide"); + this.fnSetText(flash, retStr); } - ); - } else { - self.refreshActiveView = setInterval(function () { - self.activeView.refresh(); - }, countlyCommon.DASHBOARD_REFRESH_MS); - $.idleTimer(countlyCommon.DASHBOARD_IDLE_MS); - $(".help-zone-vs, .help-zone-vb").unbind('mouseenter mouseleave'); - } - e.stopPropagation(); - }); + } + ] + }, + "fnInitComplete": function(oSettings, json) { + var saveHTML = "
    ", + searchHTML = "
    ", + tableWrapper = $("#" + oSettings.sTableId + "_wrapper"); - $("#user-logout").click(function () { - store.remove('countly_active_app'); - store.remove('countly_date'); - store.remove('countly_location_city'); - }); - - $(".beta-button").click(function () { - CountlyHelpers.alert("This feature is currently in beta so the data you see in this view might change or disappear into thin air.

    If you find any bugs or have suggestions please let us know!

    Captain Obvious: You can use the message box that appears when you click the question mark on the bottom right corner of this page.", "black"); - }) - }); + $(saveHTML).insertBefore(tableWrapper.find(".DTTT_container")); + $(searchHTML).insertBefore(tableWrapper.find(".dataTables_filter")); + tableWrapper.find(".dataTables_filter").html(tableWrapper.find(".dataTables_filter").find("input").attr("Placeholder","Search").clone(true)); - if (!_.isEmpty(countlyGlobal['apps'])) { - if (!countlyCommon.ACTIVE_APP_ID) { - for (var appId in countlyGlobal['apps']) { - countlyCommon.setActiveApp(appId); - self.activeAppName = countlyGlobal['apps'][appId].name; - break; - } - } else { - $("#sidebar-app-select").find(".logo").css("background-image", "url('/appimages/" + countlyCommon.ACTIVE_APP_ID + ".png')"); - $("#sidebar-app-select .text").text(countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID].name); - self.activeAppName = countlyGlobal['apps'][countlyCommon.ACTIVE_APP_ID].name; - } - } else { - $("#new-install-overlay").show(); - } + tableWrapper.find(".save-table-data").on("click", function() { + if ($(this).next(".DTTT_container").css('visibility') == 'hidden') { + $(this).next(".DTTT_container").css("visibility", 'visible'); + } else { + $(this).next(".DTTT_container").css("visibility", 'hidden'); + } + }); - $.idleTimer(countlyCommon.DASHBOARD_IDLE_MS); + tableWrapper.find(".search-table-data").on("click", function() { + $(this).next(".dataTables_filter").toggle(); + $(this).next(".dataTables_filter").find("input").focus(); + }); - $(document).bind("idle.idleTimer", function () { - clearInterval(self.refreshActiveView); + tableWrapper.css({"min-height": tableWrapper.height()}); + } }); - $(document).bind("active.idleTimer", function () { - self.activeView.restart(); - self.refreshActiveView = setInterval(function () { - self.activeView.refresh(); - }, countlyCommon.DASHBOARD_REFRESH_MS); - }); + $.fn.dataTableExt.sErrMode = 'throw'; }, localize:function () { @@ -3727,7 +3965,7 @@ var AppRouter = Backbone.Router.extend({ localizedValue = jQuery.i18n.map[elem.data("localize")]; } - if (elem.is("input[type=text]") || elem.is("input[type=password]")) { + if (elem.is("input[type=text]") || elem.is("input[type=password]") || elem.is("textarea")) { elem.attr("placeholder", localizedValue); } else if (elem.is("input[type=button]") || elem.is("input[type=submit]")) { elem.attr("value", localizedValue); @@ -3736,6 +3974,16 @@ var AppRouter = Backbone.Router.extend({ } }); }, + addPageScript:function(view, callback){ + if(!this.pageScripts[view]) + this.pageScripts[view] = []; + this.pageScripts[view].push(callback); + }, + addRefreshScript:function(view, callback){ + if(!this.refreshScripts[view]) + this.refreshScripts[view] = []; + this.refreshScripts[view].push(callback); + }, pageScript:function () { //scripts to be executed on each view change $("#month").text(moment().year()); $("#day").text(moment().format("MMM")); @@ -3779,6 +4027,8 @@ var AppRouter = Backbone.Router.extend({ subMenu.slideDown(); } + $(".sidebar-submenu").not(subMenu).slideUp(); + var selectedDateID = countlyCommon.getPeriod(); if (Object.prototype.toString.call(selectedDateID) !== '[object Array]') { @@ -3788,28 +4038,7 @@ var AppRouter = Backbone.Router.extend({ $(".usparkline").peity("bar", { width:"100%", height:"30", colour:"#6BB96E", strokeColour:"#6BB96E", strokeWidth:2 }); $(".dsparkline").peity("bar", { width:"100%", height:"30", colour:"#C94C4C", strokeColour:"#C94C4C", strokeWidth:2 }); - $("#date-selector").find(">.button").click(function () { - if ($(this).hasClass("selected")) { - return true; - } - - self.dateFromSelected = null; - self.dateToSelected = null; - - $(".date-selector").removeClass("selected").removeClass("active"); - $(this).addClass("selected"); - var selectedPeriod = $(this).attr("id"); - - if (countlyCommon.getPeriod() == selectedPeriod) { - return true; - } - - countlyCommon.setPeriod(selectedPeriod); - - self.activeView.dateChanged(); - $("#" + selectedPeriod).addClass("active"); - self.pageScript(); - }); + CountlyHelpers.setUpDateSelectors(self.activeView); $(window).click(function () { $("#date-picker").hide(); @@ -3900,7 +4129,7 @@ var AppRouter = Backbone.Router.extend({ countlyCommon.setPeriod([self.dateFromSelected, self.dateToSelected]); self.activeView.dateChanged(); - self.pageScript(); + $(".date-selector").removeClass("selected").removeClass("active"); }); @@ -3923,9 +4152,29 @@ var AppRouter = Backbone.Router.extend({ $(this).toggleClass("checked"); }); + $(".resource-link").on('click', function() { + if ($(this).data("link")) { + CountlyHelpers.openResource($(this).data("link")); + } + }); + + if (Backbone.history.fragment == "/manage/apps" || + Backbone.history.fragment == "/manage/account" || + Backbone.history.fragment == "/manage/users") { + $("#sidebar-app-select").addClass("disabled"); + $("#sidebar-app-select").removeClass("active"); + } else { + $("#sidebar-app-select").removeClass("disabled"); + } + + if(self.pageScripts[Backbone.history.fragment]) + for(var i = 0, l = self.pageScripts[Backbone.history.fragment].length; i < l; i++) + self.pageScripts[Backbone.history.fragment][i](); + if(self.pageScripts["#"]) + for(var i = 0, l = self.pageScripts["#"].length; i < l; i++) + self.pageScripts["#"][i](); }); } }); -var app = new AppRouter(); -Backbone.history.start(); \ No newline at end of file +var app = new AppRouter(); \ No newline at end of file diff --git a/frontend/express/public/javascripts/countly/countly.user.js b/frontend/express/public/javascripts/countly/countly.user.js index 982ef438a71..1bef53aa401 100644 --- a/frontend/express/public/javascripts/countly/countly.user.js +++ b/frontend/express/public/javascripts/countly/countly.user.js @@ -3,13 +3,20 @@ //Private Properties var _periodObj = {}, _userDb = {}, - _lolayties = [], + _loyalties = [], _frequencies = [], _activeAppKey = 0, - _initialized = false; + _initialized = false, + _period = null; //Public Methods countlyUser.initialize = function () { + if (_initialized && _period == countlyCommon.getPeriodForAjax() && _activeAppKey == countlyCommon.ACTIVE_APP_KEY) { + return countlyUser.refresh(); + } + + _period = countlyCommon.getPeriodForAjax(); + if (!countlyCommon.DEBUG) { _activeAppKey = countlyCommon.ACTIVE_APP_KEY; _initialized = true; @@ -20,21 +27,53 @@ data:{ "api_key":countlyGlobal.member.api_key, "app_id":countlyCommon.ACTIVE_APP_ID, - "method":"users" + "method":"users", + "period":_period }, dataType:"jsonp", success:function (json) { _userDb = json; setMeta(); + + countlySession.initialize(); + countlyLocation.initialize(); } }); } else { - _userDb = {"2012":{}}; return true; } }; - countlyUser.refresh = countlyUser.initialize; + countlyUser.refresh = function () { + if (!countlyCommon.DEBUG) { + + if (_activeAppKey != countlyCommon.ACTIVE_APP_KEY) { + _activeAppKey = countlyCommon.ACTIVE_APP_KEY; + return countlyUser.initialize(); + } + + return $.ajax({ + type:"GET", + url:countlyCommon.API_PARTS.data.r, + data:{ + "api_key":countlyGlobal.member.api_key, + "app_id":countlyCommon.ACTIVE_APP_ID, + "method":"users", + "action":"refresh" + }, + dataType:"jsonp", + success:function (json) { + countlyCommon.extendDbObj(_userDb, json); + extendMeta(); + + countlySession.refresh(json); + countlyLocation.refresh(json); + } + }); + } else { + return true; + } + }; countlyUser.reset = function () { _userDb = {}; @@ -77,7 +116,7 @@ var chartData = {chartData:{}, chartDP:{dp:[], ticks:[]}}; - chartData.chartData = countlyCommon.extractRangeData(_userDb, "l", _lolayties, countlyUser.explainLoyaltyRange); + chartData.chartData = countlyCommon.extractRangeData(_userDb, "l", _loyalties, countlyUser.explainLoyaltyRange); var loyalties = _.pluck(chartData.chartData, "l"), loyaltyTotals = _.pluck(chartData.chartData, 't'), @@ -116,7 +155,7 @@ ticks = [], rangeUsers; - for (var j = 0; j < _lolayties.length; j++) { + for (var j = 0; j < _loyalties.length; j++) { rangeUsers = 0; @@ -126,12 +165,12 @@ var tmp_x = countlyCommon.getDescendantProp(_userDb, _periodObj.activePeriod + "." + i + "." + "l"); tmp_x = clearLoyaltyObject(tmp_x); - rangeUsers += tmp_x[_lolayties[j]]; + rangeUsers += tmp_x[_loyalties[j]]; } if (rangeUsers != 0) { dataArr[0]["data"][dataArr[0]["data"].length] = [j, rangeUsers]; - ticks[j] = [j, _lolayties[j]]; + ticks[j] = [j, _loyalties[j]]; } } else { for (var i = 0; i < (_periodObj.currentPeriodArr.length); i++) { @@ -139,12 +178,12 @@ var tmp_x = countlyCommon.getDescendantProp(_userDb, _periodObj.currentPeriodArr[i] + "." + "l"); tmp_x = clearLoyaltyObject(tmp_x); - rangeUsers += tmp_x[_lolayties[j]]; + rangeUsers += tmp_x[_loyalties[j]]; } if (rangeUsers != 0) { dataArr[0]["data"][dataArr[0]["data"].length] = [j, rangeUsers]; - ticks[j] = [j, _lolayties[j]]; + ticks[j] = [j, _loyalties[j]]; } } } @@ -177,8 +216,8 @@ return frequencyRange[index]; }; - - countlyUser.getFrequencyIndex = function (frequency) { + + countlyUser.getFrequencyIndex = function (frequency) { var localHours = jQuery.i18n.map["user-loyalty.range.hours"], localDay = jQuery.i18n.map["user-loyalty.range.day"], localDays = jQuery.i18n.map["user-loyalty.range.days"]; @@ -216,8 +255,8 @@ return loyaltyRange[index]; }; - - countlyUser.getLoyaltyIndex = function (loyalty) { + + countlyUser.getLoyaltyIndex = function (loyalty) { var loyaltyRange = [ "1", "2", @@ -233,13 +272,29 @@ return loyaltyRange.indexOf(loyalty); }; + countlyUser.isInitialized = function() { + return _initialized; + }; + + countlyUser.getDbObj = function() { + return _userDb; + }; + function setMeta() { if (_userDb['meta']) { - _lolayties = (_userDb['meta']['l-ranges']) ? _userDb['meta']['l-ranges'] : []; + _loyalties = (_userDb['meta']['l-ranges']) ? _userDb['meta']['l-ranges'] : []; _frequencies = (_userDb['meta']['f-ranges']) ? _userDb['meta']['f-ranges'] : []; } else { - _lolayties = []; + _loyalties = []; _frequencies = []; } } + + function extendMeta() { + if (_userDb['meta']) { + _loyalties = countlyCommon.union(_loyalties, _userDb['meta']['l-ranges']); + _frequencies = countlyCommon.union(_frequencies, _userDb['meta']['f-ranges']); + } + } + }(window.countlyUser = window.countlyUser || {}, jQuery)); \ No newline at end of file diff --git a/frontend/express/public/javascripts/dom/jquery.sticky.headers.js b/frontend/express/public/javascripts/dom/jquery.sticky.headers.js index a1562725105..4fca3f5ca8a 100644 --- a/frontend/express/public/javascripts/dom/jquery.sticky.headers.js +++ b/frontend/express/public/javascripts/dom/jquery.sticky.headers.js @@ -1,17 +1,14 @@ (function ($) { $.StickyTableHeaders = function (el) { - var base = this; base.table = $(el); var headerCells = base.table.find('thead th'); base.stickyHeader = $('
    ').addClass('sticky-header hide'); - base.tableHeight = base.table.height(); base.headerCellHeight = $(headerCells[0]).height(); base.init = function () { - base.table = $(el); var theadClone = base.table.find('thead').clone(true); @@ -25,17 +22,15 @@ }; base.setWidths = function() { - - //base.table = $(el); - - var headerCells = base.table.find('thead th'); - stickyHeaderCells = base.stickyHeader.find('th'); + var headerCells = base.table.find('thead th'); + stickyHeaderCells = base.stickyHeader.find('th'); base.stickyHeader.css({'width': base.table.outerWidth()}); for (i = 0; i < headerCells.length; i++) { var cellWidth = $(headerCells[i]).css("width"), cell = $(stickyHeaderCells[i]); + cell.css({'width': cellWidth, 'border-radius':0}); } }; @@ -45,21 +40,17 @@ }; base.updateStickyHeader = function () { - - //base.table = $(el); - - if (base.table.length == 0) { + if (base.table.length == 0) { return false; } var cutoffTop = base.table.offset().top, - cutoffBottom = base.tableHeight + cutoffTop - base.headerCellHeight, + cutoffBottom = base.table.height() + cutoffTop - base.headerCellHeight, currentPosition = $(window).scrollTop(); - + if (currentPosition > cutoffTop && currentPosition < cutoffBottom) { base.stickyHeader.removeClass('hide'); - } - else { + } else { base.stickyHeader.addClass('hide'); } }; @@ -71,4 +62,4 @@ return (new $.StickyTableHeaders(this)); }; -})(jQuery); +})(jQuery); \ No newline at end of file diff --git a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js b/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js index a231f527aac..05e680507dd 100644 --- a/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js +++ b/frontend/express/public/javascripts/dom/jqueryui/jquery-ui-i18n.js @@ -1,4 +1,4 @@ -/*! jQuery UI - v1.8.22 - 2012-07-24 +/*! jQuery UI - v1.8.22 - 2012-07-24 * https://github.com/jquery/jquery-ui * Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js * Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ diff --git a/frontend/express/public/javascripts/dom/jqueryui/jquery.ui.all.css b/frontend/express/public/javascripts/dom/jqueryui/jquery.ui.all.css index bd6fb2eaa4d..1b317040e7f 100644 --- a/frontend/express/public/javascripts/dom/jqueryui/jquery.ui.all.css +++ b/frontend/express/public/javascripts/dom/jqueryui/jquery.ui.all.css @@ -7,5 +7,5 @@ * * http://docs.jquery.com/UI/Theming */ -@import "/javascripts/dom/jqueryui/jquery.ui.base.css"; -@import "/javascripts/dom/jqueryui/jquery.ui.theme.css"; +@import "jquery.ui.base.css"; +@import "jquery.ui.theme.css"; diff --git a/frontend/express/public/javascripts/dom/jsonlite.js b/frontend/express/public/javascripts/dom/jsonlite.js new file mode 100644 index 00000000000..c72bd21f067 --- /dev/null +++ b/frontend/express/public/javascripts/dom/jsonlite.js @@ -0,0 +1,186 @@ +var jsonlite; +(function (jsonlite) { + function parse(source, jsonObjectFormat) { + if (typeof jsonObjectFormat === "undefined") { jsonObjectFormat = true; } + var object_start = jsonObjectFormat ? '{' : '('; + var object_end = jsonObjectFormat ? '}' : ')'; + var pair_seperator = jsonObjectFormat ? ':' : '='; + var at = 0; + var ch = ' '; + var escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }; + var text = source; + var result = readValue(); + skipWhitespace(); + if(ch) { + raiseError("Syntax error"); + } + return result; + function raiseError(m) { + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + } + function next(c) { + if(c && c !== ch) { + raiseError("Expected '" + c + "' instead of '" + ch + "'"); + } + ch = text.charAt(at); + at += 1; + return ch; + } + function readString() { + var s = ''; + if(ch === '"') { + while(next()) { + if(ch === '"') { + next(); + return s; + } + if(ch === '\\') { + next(); + if(ch === 'u') { + var uffff = 0; + for(var i = 0; i < 4; i += 1) { + var hex = parseInt(next(), 16); + if(!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + s += String.fromCharCode(uffff); + } else if(typeof escapee[ch] === 'string') { + s += escapee[ch]; + } else { + break; + } + } else { + s += ch; + } + } + } + raiseError("Bad string"); + } + function skipWhitespace() { + while(ch && ch <= ' ') { + next(); + } + } + function readWord() { + var s = ''; + while(allowedInWord()) { + s += ch; + next(); + } + if(s === "true") { + return true; + } + if(s === "false") { + return false; + } + if(s === "null") { + return null; + } + if(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) { + return parseFloat(s); + } + return s; + } + function readArray() { + var array = []; + if(ch === '[') { + next('['); + skipWhitespace(); + if(ch === ']') { + next(']'); + return array; + } + while(ch) { + array.push(readValue()); + skipWhitespace(); + if(ch === ']') { + next(']'); + return array; + } + next(','); + skipWhitespace(); + } + } + raiseError("Bad array"); + } + function readObject() { + var o = { + }; + if(ch === object_start) { + next(object_start); + skipWhitespace(); + if(ch === object_end) { + next(object_end); + return o; + } + while(ch) { + var key = ch === '"' ? readString() : readWord(); + if(typeof key !== 'string') { + raiseError('Bad object key: ' + key); + } + skipWhitespace(); + next(pair_seperator); + if(Object.hasOwnProperty.call(o, key)) { + raiseError('Duplicate key: "' + key + '"'); + } + o[key] = readValue(); + skipWhitespace(); + if(ch === object_end) { + next(object_end); + return o; + } + next(','); + skipWhitespace(); + } + } + raiseError("Bad object"); + } + function readValue() { + skipWhitespace(); + switch(ch) { + case object_start: + return readObject(); + case '[': + return readArray(); + case '"': + return readString(); + default: + return readWord(); + } + } + function allowedInWord() { + switch(ch) { + case '"': + case '\\': + case '\t': + case '\n': + case '\r': + case ',': + case '[': + case ']': + case object_start: + case object_end: + case pair_seperator: + return false; + } + return ch > ' '; + } + } + jsonlite.parse = parse; +})(jsonlite || (jsonlite = {})); \ No newline at end of file diff --git a/frontend/express/public/javascripts/min/countly.dom.js b/frontend/express/public/javascripts/min/countly.dom.js index 5c701a354b5..08061cd1332 100755 --- a/frontend/express/public/javascripts/min/countly.dom.js +++ b/frontend/express/public/javascripts/min/countly.dom.js @@ -1,208 +1,208 @@ (function(a,e){function d(a,b,c){if(c===e&&1===a.nodeType)if(c="data-"+b.replace(Da,"-$1").toLowerCase(),c=a.getAttribute(c),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:gb.test(c)?h.parseJSON(c):c}catch(f){}h.data(a,b,c)}else c=e;return c}function c(a){for(var b in a)if(!("data"===b&&h.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function b(){return!1}function j(){return!0}function g(a){return!a||!a.parentNode||11===a.parentNode.nodeType}function f(a, -b){do a=a[b];while(a&&1!==a.nodeType);return a}function k(a,b,c){b=b||0;if(h.isFunction(b))return h.grep(a,function(a,I){return!!b.call(a,I,a)===c});if(b.nodeType)return h.grep(a,function(a){return a===b===c});if("string"==typeof b){var e=h.grep(a,function(a){return 1===a.nodeType});if(Ic.test(b))return h.filter(b,e,!c);b=h.filter(b,e)}return h.grep(a,function(a){return 0<=h.inArray(a,b)===c})}function m(a){var b=ec.split("|"),a=a.createDocumentFragment();if(a.createElement)for(;b.length;)a.createElement(b.pop()); -return a}function q(a,b){if(1===b.nodeType&&h.hasData(a)){var c,e,f;e=h._data(a);var l=h._data(b,e),d=e.events;if(d)for(c in delete l.handle,l.events={},d){e=0;for(f=d[c].length;eb;b+=2)"margin"===c&&(f+=h.css(a,c+Ka[b],!0)),e?("content"===c&&(f-=parseFloat(ha(a,"padding"+Ka[b]))||0),"margin"!==c&&(f-=parseFloat(ha(a,"border"+Ka[b]+"Width"))||0)):(f+= -parseFloat(ha(a,"padding"+Ka[b]))||0,"padding"!==c&&(f+=parseFloat(ha(a,"border"+Ka[b]+"Width"))||0));return f}function A(a,b,c){var f="width"===b?a.offsetWidth:a.offsetHeight,e=!0,l=h.support.boxSizing&&"border-box"===h.css(a,"boxSizing");if(0>=f||null==f){f=ha(a,b);if(0>f||null==f)f=a.style[b];if(sb.test(f))return f;e=l&&(h.support.boxSizingReliable||f===a.style[b]);f=parseFloat(f)||0}return f+t(a,b,c||(l?"border":"content"),e)+"px"}function C(a){if(Mb[a])return Mb[a];var b=h("<"+a+">").appendTo(z.body), -c=b.css("display");b.remove();if("none"===c||""===c){Wa=z.body.appendChild(Wa||h.extend(z.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Xa||!Wa.createElement)Xa=(Wa.contentWindow||Wa.contentDocument).document,Xa.write(""),Xa.close();b=Xa.body.appendChild(Xa.createElement(a));c=ha(b,"display");z.body.removeChild(Wa)}return Mb[a]=c,c}function B(a,b,c,f){var e;if(h.isArray(b))h.each(b,function(b,e){c||Kc.test(a)?f(a,e):B(a+"["+("object"==typeof e?b:"")+"]", -e,c,f)});else if(!c&&"object"===h.type(b))for(e in b)B(a+"["+e+"]",b[e],c,f);else f(a,b)}function L(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var f,e,l=b.toLowerCase().split(ya),d=0,g=l.length;if(h.isFunction(c))for(;dc&&e?b:(d.resolveWith(a,[j]),!1)},j=d.promise({elem:a,props:h.extend({},b),opts:h.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Ya||P(),duration:c.duration,tweens:[],createTween:function(b,c){var f=h.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(f),f},stop:function(b){for(var c=0,f=b?j.tweens.length:0;ce;e+=2-b)c=Ka[e],f["margin"+c]=f["padding"+c]=a;return b&&(f.opacity=f.width=a),f}function la(a){return h.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}var oa,ia,z=a.document,R=a.location,M=a.navigator,N=a.jQuery,H=a.$,J=Array.prototype.push, -$=Array.prototype.slice,ua=Array.prototype.indexOf,pa=Object.prototype.toString,ma=Object.prototype.hasOwnProperty,za=String.prototype.trim,h=function(a,b){return new h.fn.init(a,b,oa)},La=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,ub=/\S/,ya=/\s+/,ib=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,jb=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,Za=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,vb=/^[\],:{}\s]*$/,kb=/(?:^|:|,)(?:\s*\[)+/g,wb=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,xb=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, -lb=/^-ms-/,$a=/-([\da-z])/gi,ab=function(a,b){return(b+"").toUpperCase()},Ea=function(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",Ea,!1),h.ready()):"complete"===z.readyState&&(z.detachEvent("onreadystatechange",Ea),h.ready())},mb={};h.fn=h.prototype={constructor:h,init:function(a,b,c){var f,l;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if("string"==typeof a){"<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&3<=a.length?f=[null,a,null]:f=jb.exec(a); -if(f&&(f[1]||!b)){if(f[1])return b=b instanceof h?b[0]:b,l=b&&b.nodeType?b.ownerDocument||b:z,a=h.parseHTML(f[1],l,!0),Za.test(f[1])&&h.isPlainObject(b)&&this.attr.call(a,b,!0),h.merge(this,a);if((b=z.getElementById(f[2]))&&b.parentNode){if(b.id!==f[2])return c.find(a);this.length=1;this[0]=b}return this.context=z,this.selector=a,this}return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a)}return h.isFunction(a)?c.ready(a):(a.selector!==e&&(this.selector=a.selector,this.context=a.context),h.makeArray(a, +b){do a=a[b];while(a&&1!==a.nodeType);return a}function k(a,b,c){b=b||0;if(h.isFunction(b))return h.grep(a,function(a,P){return!!b.call(a,P,a)===c});if(b.nodeType)return h.grep(a,function(a){return a===b===c});if("string"==typeof b){var e=h.grep(a,function(a){return 1===a.nodeType});if(Hc.test(b))return h.filter(b,e,!c);b=h.filter(b,e)}return h.grep(a,function(a){return 0<=h.inArray(a,b)===c})}function l(a){var b=ec.split("|"),a=a.createDocumentFragment();if(a.createElement)for(;b.length;)a.createElement(b.pop()); +return a}function n(a,b){if(1===b.nodeType&&h.hasData(a)){var c,e,f;e=h._data(a);var d=h._data(b,e),m=e.events;if(m)for(c in delete d.handle,d.events={},m){e=0;for(f=m[c].length;eb;b+=2)"margin"===c&&(f+=h.css(a,c+La[b],!0)),e?("content"===c&&(f-=parseFloat(pa(a,"padding"+La[b]))||0),"margin"!==c&&(f-=parseFloat(pa(a,"border"+La[b]+"Width"))||0)):(f+= +parseFloat(pa(a,"padding"+La[b]))||0,"padding"!==c&&(f+=parseFloat(pa(a,"border"+La[b]+"Width"))||0));return f}function C(a,b,c){var e="width"===b?a.offsetWidth:a.offsetHeight,f=!0,d=h.support.boxSizing&&"border-box"===h.css(a,"boxSizing");if(0>=e||null==e){e=pa(a,b);if(0>e||null==e)e=a.style[b];if(sb.test(e))return e;f=d&&(h.support.boxSizingReliable||e===a.style[b]);e=parseFloat(e)||0}return e+t(a,b,c||(d?"border":"content"),f)+"px"}function B(a){if(Mb[a])return Mb[a];var b=h("<"+a+">").appendTo(z.body), +c=b.css("display");b.remove();if("none"===c||""===c){Wa=z.body.appendChild(Wa||h.extend(z.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Xa||!Wa.createElement)Xa=(Wa.contentWindow||Wa.contentDocument).document,Xa.write(""),Xa.close();b=Xa.body.appendChild(Xa.createElement(a));c=pa(b,"display");z.body.removeChild(Wa)}return Mb[a]=c,c}function A(a,b,c,e){var f;if(h.isArray(b))h.each(b,function(b,f){c||Jc.test(a)?e(a,f):A(a+"["+("object"==typeof f?b:"")+"]", +f,c,e)});else if(!c&&"object"===h.type(b))for(f in b)A(a+"["+f+"]",b[f],c,e);else e(a,b)}function N(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var e,f,d=b.toLowerCase().split(Aa),m=0,g=d.length;if(h.isFunction(c))for(;mc&&f?b:(m.resolveWith(a,[j]),!1)},j=m.promise({elem:a,props:h.extend({},b),opts:h.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Ya||K(),duration:c.duration,tweens:[],createTween:function(b,c){var e=h.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){for(var c=0,e=b?j.tweens.length:0;cf;f+=2-b)c=La[f],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Q(a){return h.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}var M,V,z=a.document,S=a.location,R=a.navigator,T=a.jQuery,H=a.$,I=Array.prototype.push, +$=Array.prototype.slice,ca=Array.prototype.indexOf,ea=Object.prototype.toString,la=Object.prototype.hasOwnProperty,ba=String.prototype.trim,h=function(a,b){return new h.fn.init(a,b,M)},wa=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,Ma=/\S/,Aa=/\s+/,ib=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,jb=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,Za=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ub=/^[\],:{}\s]*$/,kb=/(?:^|:|,)(?:\s*\[)+/g,vb=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,wb=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, +lb=/^-ms-/,$a=/-([\da-z])/gi,ab=function(a,b){return(b+"").toUpperCase()},Ea=function(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",Ea,!1),h.ready()):"complete"===z.readyState&&(z.detachEvent("onreadystatechange",Ea),h.ready())},mb={};h.fn=h.prototype={constructor:h,init:function(a,b,c){var f,d;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if("string"==typeof a){"<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&3<=a.length?f=[null,a,null]:f=jb.exec(a); +if(f&&(f[1]||!b)){if(f[1])return b=b instanceof h?b[0]:b,d=b&&b.nodeType?b.ownerDocument||b:z,a=h.parseHTML(f[1],d,!0),Za.test(f[1])&&h.isPlainObject(b)&&this.attr.call(a,b,!0),h.merge(this,a);if((b=z.getElementById(f[2]))&&b.parentNode){if(b.id!==f[2])return c.find(a);this.length=1;this[0]=b}return this.context=z,this.selector=a,this}return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a)}return h.isFunction(a)?c.ready(a):(a.selector!==e&&(this.selector=a.selector,this.context=a.context),h.makeArray(a, this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return $.call(this)},get:function(a){return null==a?this.toArray():0>a?this[this.length+a]:this[a]},pushStack:function(a,b,c){a=h.merge(this.constructor(),a);return a.prevObject=this,a.context=this.context,"find"===b?a.selector=this.selector+(this.selector?" ":"")+c:b&&(a.selector=this.selector+"."+b+"("+c+")"),a},each:function(a,b){return h.each(this,a,b)},ready:function(a){return h.ready.promise().done(a), -this},eq:function(a){return a=+a,-1===a?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack($.apply(this,arguments),"slice",$.call(arguments).join(","))},map:function(a){return this.pushStack(h.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:J,sort:[].sort,splice:[].splice};h.fn.init.prototype=h.fn;h.extend=h.fn.extend=function(){var a,b,c, -f,l,d,g=arguments[0]||{},j=1,k=arguments.length,v=!1;"boolean"==typeof g&&(v=g,g=arguments[1]||{},j=2);"object"!=typeof g&&!h.isFunction(g)&&(g={});for(k===j&&(g=this,--j);jc?Math.max(0,f+c):c:0;c
    \ -
    " + keyEvents[k][l].code + "
    \ -
    " + keyEvents[k][l].desc + "
    \ -
    a"; -ja=O.getElementsByTagName("*");va=O.getElementsByTagName("a")[0];if(!ja||!va||!ja.length)Ma={};else{Na=z.createElement("select");fa=Na.appendChild(z.createElement("option"));ea=O.getElementsByTagName("input")[0];va.style.cssText="top:1px;float:left;opacity:.5";V={leadingWhitespace:3===O.firstChild.nodeType,tbody:!O.getElementsByTagName("tbody").length,htmlSerialize:!!O.getElementsByTagName("link").length,style:/top/.test(va.getAttribute("style")),hrefNormalized:"/a"===va.getAttribute("href"),opacity:/^0.5/.test(va.style.opacity), -cssFloat:!!va.style.cssFloat,checkOn:"on"===ea.value,optSelected:fa.selected,getSetAttribute:"t"!==O.className,enctype:!!z.createElement("form").enctype,html5Clone:"<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===z.compatMode,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1};ea.checked=!0;V.noCloneChecked=ea.cloneNode(!0).checked; -Na.disabled=!0;V.optDisabled=!fa.disabled;try{delete O.test}catch(Pa){V.deleteExpando=!1}!O.addEventListener&&O.attachEvent&&O.fireEvent&&(O.attachEvent("onclick",F=function(){V.noCloneEvent=!1}),O.cloneNode(!0).fireEvent("onclick"),O.detachEvent("onclick",F));ea=z.createElement("input");ea.value="t";ea.setAttribute("type","radio");V.radioValue="t"===ea.value;ea.setAttribute("checked","checked");ea.setAttribute("name","t");O.appendChild(ea);wa=z.createDocumentFragment();wa.appendChild(O.lastChild); -V.checkClone=wa.cloneNode(!0).cloneNode(!0).lastChild.checked;V.appendChecked=ea.checked;wa.removeChild(ea);wa.appendChild(O);if(O.attachEvent)for(bb in{submit:!0,change:!0,focusin:!0})Oa="on"+bb,(Fa=Oa in O)||(O.setAttribute(Oa,"return;"),Fa="function"==typeof O[Oa]),V[bb+"Bubbles"]=Fa;Ma=(h(function(){var b,c,f,e,l=z.getElementsByTagName("body")[0];l&&(b=z.createElement("div"),b.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",l.insertBefore(b,l.firstChild), -c=z.createElement("div"),b.appendChild(c),c.innerHTML="
    t
    ",f=c.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",Fa=0===f[0].offsetHeight,f[0].style.display="",f[1].style.display="none",V.reliableHiddenOffsets=Fa&&0===f[0].offsetHeight,c.innerHTML="",c.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;", -V.boxSizing=4===c.offsetWidth,V.doesNotIncludeMarginInBodyOffset=1!==l.offsetTop,a.getComputedStyle&&(V.pixelPosition="1%"!==(a.getComputedStyle(c,null)||{}).top,V.boxSizingReliable="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width,e=z.createElement("div"),e.style.cssText=c.style.cssText="padding:0;margin:0;border:0;display:block;overflow:hidden;",e.style.marginRight=e.style.width="0",c.style.width="1px",c.appendChild(e),V.reliableMarginRight=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight)), -"undefined"!=typeof c.style.zoom&&(c.innerHTML="",c.style.cssText="padding:0;margin:0;border:0;display:block;overflow:hidden;width:1px;padding:1px;display:inline;zoom:1",V.inlineBlockNeedsLayout=3===c.offsetWidth,c.style.display="block",c.style.overflow="visible",c.innerHTML="
    ",c.firstChild.style.width="5px",V.shrinkWrapBlocks=3!==c.offsetWidth,b.style.zoom=1),l.removeChild(b))}),wa.removeChild(O),ja=va=Na=fa=ea=wa=O=null,V)}yb.support=Ma;var gb=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,Da=/([A-Z])/g; -h.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(h.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?h.cache[a[h.expando]]:a[h.expando],!!a&&!c(a)},data:function(a,b,c,f){if(h.acceptData(a)){var l,d,g=h.expando,j="string"==typeof b,k=a.nodeType,v=k?h.cache:a,m=k?a[g]:a[g]&&g;if(m&&v[m]&&(f||v[m].data)||!(j&&c===e)){m||(k?a[g]=m=h.deletedIds.pop()||h.guid++:m=g);v[m]||(v[m]={}, -k||(v[m].toJSON=h.noop));if("object"==typeof b||"function"==typeof b)f?v[m]=h.extend(v[m],b):v[m].data=h.extend(v[m].data,b);return l=v[m],f||(l.data||(l.data={}),l=l.data),c!==e&&(l[h.camelCase(b)]=c),j?(d=l[b],null==d&&(d=l[h.camelCase(b)])):d=l,d}}},removeData:function(a,b,f){if(h.acceptData(a)){var e,l,d,g=a.nodeType,j=g?h.cache:a,k=g?a[h.expando]:h.expando;if(j[k]){if(b&&(e=f?j[k]:j[k].data)){h.isArray(b)||(b in e?b=[b]:(b=h.camelCase(b),b in e?b=[b]:b=b.split(" ")));l=0;for(d=b.length;ll.indexOf(" "+b[d]+" ")&&(l+=b[d]+" ");e.className=h.trim(l)}}return this},removeClass:function(a){var b, -c,f,l,d,g,j;if(h.isFunction(a))return this.each(function(b){h(this).removeClass(a.call(this,b,this.className))});if(a&&"string"==typeof a||a===e){b=(a||"").split(ya);g=0;for(j=this.length;gf)?null:[],l=a?f+1:c.length,d=0>f?l:a?f:0;dc?Math.max(0,e+c):c:0;c
    a"; +qa=W.getElementsByTagName("*");xa=W.getElementsByTagName("a")[0];if(!qa||!xa||!qa.length)Na={};else{Oa=z.createElement("select");ma=Oa.appendChild(z.createElement("option"));ja=W.getElementsByTagName("input")[0];xa.style.cssText="top:1px;float:left;opacity:.5";aa={leadingWhitespace:3===W.firstChild.nodeType,tbody:!W.getElementsByTagName("tbody").length,htmlSerialize:!!W.getElementsByTagName("link").length,style:/top/.test(xa.getAttribute("style")),hrefNormalized:"/a"===xa.getAttribute("href"),opacity:/^0.5/.test(xa.style.opacity), +cssFloat:!!xa.style.cssFloat,checkOn:"on"===ja.value,optSelected:ma.selected,getSetAttribute:"t"!==W.className,enctype:!!z.createElement("form").enctype,html5Clone:"<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===z.compatMode,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1};ja.checked=!0;aa.noCloneChecked=ja.cloneNode(!0).checked; +Oa.disabled=!0;aa.optDisabled=!ma.disabled;try{delete W.test}catch(Qa){aa.deleteExpando=!1}!W.addEventListener&&W.attachEvent&&W.fireEvent&&(W.attachEvent("onclick",F=function(){aa.noCloneEvent=!1}),W.cloneNode(!0).fireEvent("onclick"),W.detachEvent("onclick",F));ja=z.createElement("input");ja.value="t";ja.setAttribute("type","radio");aa.radioValue="t"===ja.value;ja.setAttribute("checked","checked");ja.setAttribute("name","t");W.appendChild(ja);ya=z.createDocumentFragment();ya.appendChild(W.lastChild); +aa.checkClone=ya.cloneNode(!0).cloneNode(!0).lastChild.checked;aa.appendChecked=ja.checked;ya.removeChild(ja);ya.appendChild(W);if(W.attachEvent)for(bb in{submit:!0,change:!0,focusin:!0})Pa="on"+bb,(Fa=Pa in W)||(W.setAttribute(Pa,"return;"),Fa="function"==typeof W[Pa]),aa[bb+"Bubbles"]=Fa;Na=(h(function(){var b,c,f,e,d=z.getElementsByTagName("body")[0];d&&(b=z.createElement("div"),b.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",d.insertBefore(b, +d.firstChild),c=z.createElement("div"),b.appendChild(c),c.innerHTML="
    t
    ",f=c.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",Fa=0===f[0].offsetHeight,f[0].style.display="",f[1].style.display="none",aa.reliableHiddenOffsets=Fa&&0===f[0].offsetHeight,c.innerHTML="",c.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;", +aa.boxSizing=4===c.offsetWidth,aa.doesNotIncludeMarginInBodyOffset=1!==d.offsetTop,a.getComputedStyle&&(aa.pixelPosition="1%"!==(a.getComputedStyle(c,null)||{}).top,aa.boxSizingReliable="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width,e=z.createElement("div"),e.style.cssText=c.style.cssText="padding:0;margin:0;border:0;display:block;overflow:hidden;",e.style.marginRight=e.style.width="0",c.style.width="1px",c.appendChild(e),aa.reliableMarginRight=!parseFloat((a.getComputedStyle(e,null)|| +{}).marginRight)),"undefined"!=typeof c.style.zoom&&(c.innerHTML="",c.style.cssText="padding:0;margin:0;border:0;display:block;overflow:hidden;width:1px;padding:1px;display:inline;zoom:1",aa.inlineBlockNeedsLayout=3===c.offsetWidth,c.style.display="block",c.style.overflow="visible",c.innerHTML="
    ",c.firstChild.style.width="5px",aa.shrinkWrapBlocks=3!==c.offsetWidth,b.style.zoom=1),d.removeChild(b))}),ya.removeChild(W),qa=xa=Oa=ma=ja=ya=W=null,aa)}xb.support=Na;var gb=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/, +Da=/([A-Z])/g;h.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(h.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?h.cache[a[h.expando]]:a[h.expando],!!a&&!c(a)},data:function(a,b,c,f){if(h.acceptData(a)){var d,m,g=h.expando,j="string"==typeof b,k=a.nodeType,w=k?h.cache:a,l=k?a[g]:a[g]&&g;if(l&&w[l]&&(f||w[l].data)||!(j&&c===e)){l||(k?a[g]=l=h.deletedIds.pop()||h.guid++:l=g);w[l]|| +(w[l]={},k||(w[l].toJSON=h.noop));if("object"==typeof b||"function"==typeof b)f?w[l]=h.extend(w[l],b):w[l].data=h.extend(w[l].data,b);return d=w[l],f||(d.data||(d.data={}),d=d.data),c!==e&&(d[h.camelCase(b)]=c),j?(m=d[b],null==m&&(m=d[h.camelCase(b)])):m=d,m}}},removeData:function(a,b,f){if(h.acceptData(a)){var e,d,m,g=a.nodeType,j=g?h.cache:a,k=g?a[h.expando]:h.expando;if(j[k]){if(b&&(e=f?j[k]:j[k].data)){h.isArray(b)||(b in e?b=[b]:(b=h.camelCase(b),b in e?b=[b]:b=b.split(" ")));d=0;for(m=b.length;d< +m;d++)delete e[b[d]];if(!(f?c:h.isEmptyObject)(e))return}if(!f&&(delete j[k].data,!c(j[k])))return;g?h.cleanData([a],!0):h.support.deleteExpando||j!=j.window?delete j[k]:j[k]=null}}},_data:function(a,b,c){return h.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&h.noData[a.nodeName.toLowerCase()];return!b||!0!==b&&a.getAttribute("classid")===b}});h.fn.extend({data:function(a,b){var c,f,m,g,j,k=this[0],w=0,l=null;if(a===e){if(this.length&&(l=h.data(k),1===k.nodeType&&!h._data(k,"parsedAttrs"))){m= +k.attributes;for(j=m.length;wd.indexOf(" "+b[m]+" ")&&(d+=b[m]+" ");e.className=h.trim(d)}}return this},removeClass:function(a){var b, +c,f,d,m,g,j;if(h.isFunction(a))return this.each(function(b){h(this).removeClass(a.call(this,b,this.className))});if(a&&"string"==typeof a||a===e){b=(a||"").split(Aa);g=0;for(j=this.length;gf)?null:[],d=a?f+1:c.length,m=0>f?d:a?f:0;mn.indexOf(":")?"on"+n:"",f){if(b.result=e,b.target||(b.target=f),c=null!=c?h.makeArray(c):[],c.unshift(b),v=h.event.special[n]||{},!(v.trigger&&!1===v.trigger.apply(f,c))){x=[[f,v.bindType||n]];if(!l&&!v.noBubble&&!h.isWindow(f)){g=v.delegateType||n;d=cb.test(g+n)?f:f.parentNode;for(j=f;d;d=d.parentNode)x.push([d,g]), -j=d;j===(f.ownerDocument||z)&&x.push([j.defaultView||j.parentWindow||a,g])}for(g=0;gv&&s.push({elem:this,matches:k.slice(v)});for(c=0;cp.indexOf(":")?"on"+p:"",f){if(b.result=e,b.target||(b.target=f),c=null!=c?h.makeArray(c):[],c.unshift(b),w=h.event.special[p]||{},!(w.trigger&&!1===w.trigger.apply(f,c))){x=[[f,w.bindType||p]];if(!d&&!w.noBubble&&!h.isWindow(f)){g=w.delegateType||p;m=cb.test(g+p)?f:f.parentNode;for(j=f;m;m=m.parentNode)x.push([m,g]), +j=m;j===(f.ownerDocument||z)&&x.push([j.defaultView||j.parentWindow||a,g])}for(g=0;gw&&v.push({elem:this,matches:k.slice(w)});for(c=0;cT.cacheLength&&delete a[b.shift()],a[c+" "]=f},a)},nc=Xb(),jc=Xb(),oc=Xb(),pc="\\[[\\x20\\t\\r\\n\\f]*((?:\\\\.|[-\\w]|[^\\x00-\\xa0])+)[\\x20\\t\\r\\n\\f]*(?:([*^$|!~]?=)[\\x20\\t\\r\\n\\f]*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+ -"(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+".replace("w","w#")+")|)|)[\\x20\\t\\r\\n\\f]*\\]",Yb=":((?:\\\\.|[-\\w]|[^\\x00-\\xa0])+)(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+pc+")|[^:]|\\\\.)*|.*))\\)|)",Db=RegExp("^[\\x20\\t\\r\\n\\f]+|((?:^|[^\\\\])(?:\\\\.)*)[\\x20\\t\\r\\n\\f]+$","g"),Nc=/^[\x20\t\r\n\f]*,[\x20\t\r\n\f]*/,Oc=/^[\x20\t\r\n\f]*([\x20\t\r\n\f>+~])[\x20\t\r\n\f]*/,Rc=RegExp(Yb),Mc=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Tb=/[\x20\t\r\n\f]*[+~]/,Sc=/h\d/i,Tc=/input|select|textarea|button/i, -Ta=/\\(?!\\)/g,Eb={ID:/^#((?:\\.|[-\w]|[^\x00-\xa0])+)/,CLASS:/^\.((?:\\.|[-\w]|[^\x00-\xa0])+)/,NAME:/^\[name=['"]?((?:\\.|[-\w]|[^\x00-\xa0])+)['"]?\]/,TAG:RegExp("^("+"(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+".replace("w","w*")+")"),ATTR:RegExp("^"+pc),PSEUDO:RegExp("^"+Yb),POS:/:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i,CHILD:RegExp("^:(only|nth|first|last)-child(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)", -"i"),needsContext:RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},Ha=function(a){var b=Aa.createElement("div");try{return a(b)}catch(c){return!1}finally{}},Uc=Ha(function(a){return a.appendChild(Aa.createComment("")),!a.getElementsByTagName("*").length}),Vc=Ha(function(a){return a.innerHTML="",a.firstChild&&"undefined"!==typeof a.firstChild.getAttribute&&"#"===a.firstChild.getAttribute("href")}), -Wc=Ha(function(a){a.innerHTML="";a=typeof a.lastChild.getAttribute("multiple");return"boolean"!==a&&"string"!==a}),ic=Ha(function(a){return a.innerHTML="",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",2===a.getElementsByClassName("e").length)}),Xc=Ha(function(a){a.id=Z+0;a.innerHTML="
    ";sa.insertBefore(a,sa.firstChild);var b=Aa.getElementsByName&& -Aa.getElementsByName(Z).length===2+Aa.getElementsByName(Z+0).length;return Vb=!Aa.getElementById(Z),sa.removeChild(a),b});try{eb.call(sa.childNodes,0)[0].nodeType}catch(Fd){eb=function(a){for(var b,c=[];b=this[a];a++)c.push(b);return c}}v.matches=function(a,b){return v(a,null,null,b)};v.matchesSelector=function(a,b){return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(Ta,""),a[3]=(a[4]||a[5]||"").replace(Ta,""),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1]?(a[2]||v.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1): -2*("even"===a[2]||"odd"===a[2])),a[4]=+(a[6]+a[7]||"odd"===a[2])):a[2]&&v.error(a[0]),a},PSEUDO:function(a){var b,c;if(Eb.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])Rc.test(b)&&(c=ga(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:Vb?function(a){return a=a.replace(Ta,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(Ta,""),function(b){return(b="undefined"!==typeof b.getAttributeNode&& -b.getAttributeNode("id"))&&b.value===a}},TAG:function(a){return"*"===a?function(){return!0}:(a=a.replace(Ta,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=nc[Z][a+" "];return b||(b=RegExp("(^|[\\x20\\t\\r\\n\\f])"+a+"([\\x20\\t\\r\\n\\f]|$)"))&&nc(a,function(a){return b.test(a.className||"undefined"!==typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(f){f=v.attr(f,a);return null==f?"!="===b:b?(f+="", -"="===b?f===c:"!="===b?f!==c:"^="===b?c&&0===f.indexOf(c):"*="===b?c&&-1c?c+b:c]}),even:da(function(a,b){for(var c=0;cc?c+b:c;0<=--b;)a.push(b);return a}),gt:da(function(a,b,c){for(c=0>c?c+b:c;++c";a.querySelectorAll(":enabled").length|| -Ia.push(":enabled",":disabled")});Ia=RegExp(Ia.join("|"));Ob=function(a,b,c,f,l){if(!f&&!l&&!Ia.test(a)){var e,d,g=!0,j=Z;d=b;e=9===b.nodeType&&a;if(1===b.nodeType&&"object"!==b.nodeName.toLowerCase()){e=ga(a);(g=b.getAttribute("id"))?j=g.replace(Zc,"\\$&"):b.setAttribute("id",j);j="[id='"+j+"'] ";for(d=e.length;d--;)e[d]=j+e[d].join("");d=Tb.test(a)&&b.parentNode||b;e=e.join(",")}if(e)try{return db.apply(c,eb.call(d.querySelectorAll(e),0)),c}catch(k){}finally{g||b.removeAttribute("id")}}return Yc(a, -b,c,f,l)};Ib&&(Ha(function(a){qc=Ib.call(a,"div");try{Ib.call(a,"[test!='']:sizzle"),Hb.push("!=",Yb)}catch(b){}}),Hb=RegExp(Hb.join("|")),v.matchesSelector=function(a,b){b=b.replace($c,"='$1']");if(!Cb(a)&&!Hb.test(b)&&!Ia.test(b))try{var c=Ib.call(a,b);if(c||qc||a.document&&11!==a.document.nodeType)return c}catch(f){}return 0]*)\/>/gi,tc=/<([\w:]+)/,ed=/]","i"),fc=/^(?:checkbox|radio)$/, -uc=/checked\s*(?:[^=]|=\s*.checked.)/i,id=/\/(java|ecma)script/i,jd=/^\s*\s*$/g,na={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},vc=m(z),ac=vc.appendChild(z.createElement("div"));na.optgroup= -na.option;na.tbody=na.tfoot=na.colgroup=na.caption=na.thead;na.th=na.td;h.support.htmlSerialize||(na._default=[1,"X
    ","
    "]);h.fn.extend({text:function(a){return h.access(this,function(a){return a===e?h.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(h.isFunction(a))return this.each(function(b){h(this).wrapAll(a.call(this,b))});if(this[0]){var b=h(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&& -b.insertBefore(this[0]);b.map(function(){for(var a=this;a.firstChild&&1===a.firstChild.nodeType;)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return h.isFunction(a)?this.each(function(b){h(this).wrapInner(a.call(this,b))}):this.each(function(){var b=h(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=h.isFunction(a);return this.each(function(c){h(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){h.nodeName(this, -"body")||h(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!g(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=h.clean(arguments);return this.pushStack(h.merge(a, -this),"before",this.selector)}},after:function(){if(!g(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=h.clean(arguments);return this.pushStack(h.merge(this,a),"after",this.selector)}},remove:function(a,b){for(var c,f=0;null!=(c=this[f]);f++)if(!a||h.filter(a,[c]).length)!b&&1===c.nodeType&&(h.cleanData(c.getElementsByTagName("*")),h.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){for(var a, -b=0;null!=(a=this[b]);b++)for(1===a.nodeType&&h.cleanData(a.getElementsByTagName("*"));a.firstChild;)a.removeChild(a.firstChild);return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return h.clone(this,a,b)})},html:function(a){return h.access(this,function(a){var b=this[0]||{},c=0,f=this.length;if(a===e)return 1===b.nodeType?b.innerHTML.replace(dd,""):e;if("string"==typeof a&&!gd.test(a)&&(h.support.htmlSerialize||!$b.test(a))&&(h.support.leadingWhitespace||!Zb.test(a))&& -!na[(tc.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(sc,"<$1>");try{for(;cg.length&&b===z&&"<"===g.charAt(0)&&!hd.test(g)&&(h.support.checkClone||!uc.test(g))&&(h.support.html5Clone||!$b.test(g))&&(l=!0,f=h.fragments[g],d=f!==e),f||(f=b.createDocumentFragment(),h.clean(a,b,f,c),l&&(h.fragments[g]=d&&f)),{fragment:f,cacheable:l}};h.fragments={};h.each({appendTo:"append", -prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){h.fn[a]=function(c){var f,l=0,e=[],c=h(c),d=c.length;f=1===this.length&&this[0].parentNode;if((null==f||f&&11===f.nodeType&&1===f.childNodes.length)&&1===d)return c[b](this[0]),this;for(;l")?d=a.cloneNode(!0):(ac.innerHTML=a.outerHTML,ac.removeChild(d=ac.firstChild));if((!h.support.noCloneEvent||!h.support.noCloneChecked)&&(1===a.nodeType||11===a.nodeType)&&!h.isXMLDoc(a)){n(a,d);f=s(a);l=s(d);for(e=0;f[e];++e)l[e]&&n(f[e],l[e])}if(b&&(q(a,d),c)){f=s(a);l=s(d);for(e=0;f[e];++e)q(f[e],l[e])}return d},clean:function(a,b,c,f){var l,e,d,g,j,k,v,x=b===z&&vc,n=[];if(!b||"undefined"==typeof b.createDocumentFragment)b=z;for(l=0;null!=(d=a[l]);l++)if("number"==typeof d&&(d+=""),d){if("string"== -typeof d)if(fd.test(d)){x=x||m(b);k=b.createElement("div");x.appendChild(k);d=d.replace(sc,"<$1>");e=(tc.exec(d)||["",""])[1].toLowerCase();g=na[e]||na._default;j=g[0];for(k.innerHTML=g[1]+d+g[2];j--;)k=k.lastChild;if(!h.support.tbody){j=ed.test(d);g="table"===e&&!j?k.firstChild&&k.firstChild.childNodes:""===g[1]&&!j?k.childNodes:[];for(e=g.length-1;0<=e;--e)h.nodeName(g[e],"tbody")&&!g[e].childNodes.length&&g[e].parentNode.removeChild(g[e])}!h.support.leadingWhitespace&&Zb.test(d)&&k.insertBefore(b.createTextNode(Zb.exec(d)[0]), -k.firstChild);d=k.childNodes;k.parentNode.removeChild(k)}else d=b.createTextNode(d);d.nodeType?n.push(d):h.merge(n,d)}k&&(d=k=x=null);if(!h.support.appendChecked)for(l=0;null!=(d=n[l]);l++)h.nodeName(d,"input")?r(d):"undefined"!=typeof d.getElementsByTagName&&h.grep(d.getElementsByTagName("input"),r);if(c){a=function(a){if(!a.type||id.test(a.type))return f?f.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(l=0;null!=(d=n[l]);l++)if(!h.nodeName(d,"script")||!a(d))c.appendChild(d), -"undefined"!=typeof d.getElementsByTagName&&(v=h.grep(h.merge([],d.getElementsByTagName("script")),a),n.splice.apply(n,[l+1,0].concat(v)),l+=v.length)}return n},cleanData:function(a,b){for(var c,f,l,e,d=0,g=h.expando,j=h.cache,k=h.support.deleteExpando,v=h.event.special;null!=(l=a[d]);d++)if(b||h.acceptData(l))if(c=(f=l[g])&&j[f]){if(c.events)for(e in c.events)v[e]?h.event.remove(l,e):h.removeEvent(l,e,c.handle);j[f]&&(delete j[f],k?delete l[g]:l.removeAttribute?l.removeAttribute(g):l[g]=null,h.deletedIds.push(f))}}}); -var Jb,Ja;h.uaMatch=function(a){a=a.toLowerCase();a=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||0>a.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};Jb=h.uaMatch(M.userAgent);Ja={};Jb.browser&&(Ja[Jb.browser]=!0,Ja.version=Jb.version);Ja.chrome?Ja.webkit=!0:Ja.webkit&&(Ja.safari=!0);h.browser=Ja;h.sub=function(){function a(b,c){return new a.fn.init(b, -c)}h.extend(!0,a,this);a.superclass=this;a.fn=a.prototype=this();a.fn.constructor=a;a.sub=this.sub;a.fn.init=function(c,f){return f&&f instanceof h&&!(f instanceof a)&&(f=a(f)),h.fn.init.call(this,c,f,b)};a.fn.init.prototype=a.fn;var b=a(z);return a};var ha,Wa,Xa,bc=/alpha\([^)]*\)/i,kd=/opacity=([^)]*)/,ld=/^(top|right|bottom|left)$/,md=/^(none|table(?!-c[ea]).+)/,wc=/^margin/,Jc=RegExp("^("+La+")(.*)$","i"),sb=RegExp("^("+La+")(?!px)[a-z%]+$","i"),nd=RegExp("^([-+])=("+La+")","i"),Mb={BODY:"block"}, -od={position:"absolute",visibility:"hidden",display:"block"},xc={letterSpacing:0,fontWeight:400},Ka=["Top","Right","Bottom","Left"],gc=["Webkit","O","Moz","ms"],pd=h.fn.toggle;h.fn.extend({css:function(a,b){return h.access(this,function(a,b,c){return c!==e?h.style(a,b,c):h.css(a,b)},a,b,1c;c++)l[a+Ka[c]+b]=f[c]||f[c-2]||f[0];return l}};wc.test(a)||(h.cssHooks[a+b].set=w)});var qd=/%20/g,Kc=/\[\]$/,yc=/\r?\n/g,rd=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, -sd=/^(?:select|textarea)/i;h.fn.extend({serialize:function(){return h.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?h.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sd.test(this.nodeName)||rd.test(this.type))}).map(function(a,b){var c=h(this).val();return null==c?null:h.isArray(c)?h.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}); -h.param=function(a,b){var c,f=[],l=function(a,b){b=h.isFunction(b)?b():null==b?"":b;f[f.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};b===e&&(b=h.ajaxSettings&&h.ajaxSettings.traditional);if(h.isArray(a)||a.jquery&&!h.isPlainObject(a))h.each(a,function(){l(this.name,this.value)});else for(c in a)B(c,a[c],b,l);return f.join("&").replace(qd,"+")};var Ua,Va,td=/#.*$/,ud=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,vd=/^(?:GET|HEAD)$/,wd=/^\/\//,zc=/\?/,xd=/)<[^<]*)*<\/script>/gi, -yd=/([?&])_=[^&]*/,Ac=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Bc=h.fn.load,Nb={},Cc={},Dc=["*/"]+["*"];try{Va=R.href}catch(Gd){Va=z.createElement("a"),Va.href="",Va=Va.href}Ua=Ac.exec(Va.toLowerCase())||[];h.fn.load=function(a,b,c){if("string"!=typeof a&&Bc)return Bc.apply(this,arguments);if(!this.length)return this;var f,l,d,g=this,j=a.indexOf(" ");return 0<=j&&(f=a.slice(j,a.length),a=a.slice(0,j)),h.isFunction(b)?(c=b,b=e):b&&"object"==typeof b&&(l="POST"),h.ajax({url:a,type:l,dataType:"html", -data:b,complete:function(a,b){c&&g.each(c,d||[a.responseText,b,a])}}).done(function(a){d=arguments;g.html(f?h("
    ").append(a.replace(xd,"")).find(f):a)}),this};h.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){h.fn[b]=function(a){return this.on(b,a)}});h.each(["get","post"],function(a,b){h[b]=function(a,c,f,l){return h.isFunction(c)&&(l=l||f,f=c,c=e),h.ajax({type:b,url:a,data:c,success:f,dataType:l})}});h.extend({getScript:function(a,b){return h.get(a, -e,b,"script")},getJSON:function(a,b,c){return h.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?U(a,h.ajaxSettings):(b=a,a=h.ajaxSettings),U(a,b),a},ajaxSettings:{url:Va,isLocal:/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/.test(Ua[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Dc},contents:{xml:/xml/, -html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":h.parseJSON,"text xml":h.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:L(Nb),ajaxTransport:L(Cc),ajax:function(a,b){function c(a,b,d,k){var m,S,r,u,I,W=b;if(2!==ga){ga=2;j&&clearTimeout(j);g=e;l=k||"";p.readyState=0a||304===a)if(x.ifModified&&(I=p.getResponseHeader("Last-Modified"),I&&(h.lastModified[f]=I),I=p.getResponseHeader("Etag"),I&&(h.etag[f]=I)),304===a)W="notmodified",m=!0;else{var X;a:{m=x;S=u;var C,W=m.dataTypes.slice(), -d=W[0];y={};t=0;m.dataFilter&&(S=m.dataFilter(S,m.dataType));if(W[1])for(X in m.converters)y[X.toLowerCase()]=m.converters[X];for(;r=W[++t];)if("*"!==r){if("*"!==d&&d!==r){X=y[d+" "+r]||y["* "+r];if(!X)for(C in y)if(I=C.split(" "),I[1]===r&&(X=y[d+" "+I[0]]||y["* "+I[0]])){!0===X?X=y[C]:!0!==y[C]&&(r=I[0],W.splice(t--,0,r));break}if(!0!==X)if(X&&m["throws"])S=X(S);else try{S=X(S)}catch(Gc){X={state:"parsererror",error:X?Gc:"No conversion from "+d+" to "+r};break a}}d=r}X={state:"success",data:S}}m= -X;W=m.state;S=m.data;r=m.error;m=!r}else if(r=W,!W||a)W="error",0>a&&(a=0);p.status=a;p.statusText=(b||W)+"";m?G.resolveWith(n,[S,W,p]):G.rejectWith(n,[p,W,r]);p.statusCode(da);da=e;v&&s.trigger("ajax"+(m?"Success":"Error"),[p,x,m?S:r]);q.fireWith(n,[p,W]);v&&(s.trigger("ajaxComplete",[p,x]),--h.active||h.event.trigger("ajaxStop"))}}"object"==typeof a&&(b=a,a=e);var b=b||{},f,l,d,g,j,k,v,m,x=h.ajaxSetup({},b),n=x.context||x,s=n!==x&&(n.nodeType||n instanceof h)?h(n):h.event,G=h.Deferred(),q=h.Callbacks("once memory"), -da=x.statusCode||{},S={},r={},ga=0,u="canceled",p={readyState:0,setRequestHeader:function(a,b){if(!ga){var c=a.toLowerCase(),a=r[c]=r[c]||a;S[a]=b}return this},getAllResponseHeaders:function(){return 2===ga?l:null},getResponseHeader:function(a){var b;if(2===ga){if(!d)for(d={};b=ud.exec(l);)d[b[1].toLowerCase()]=b[2];b=d[a.toLowerCase()]}return b===e?null:b},overrideMimeType:function(a){return ga||(x.mimeType=a),this},abort:function(a){return a=a||u,g&&g.abort(a),c(0,a),this}};G.promise(p);p.success= -p.done;p.error=p.fail;p.complete=q.add;p.statusCode=function(a){if(a){var b;if(2>ga)for(b in a)da[b]=[da[b],a[b]];else b=a[p.status],p.always(b)}return this};x.url=((a||x.url)+"").replace(td,"").replace(wd,Ua[1]+"//");x.dataTypes=h.trim(x.dataType||"*").toLowerCase().split(ya);null==x.crossDomain&&(k=Ac.exec(x.url.toLowerCase()),x.crossDomain=!(!k||k[1]===Ua[1]&&k[2]===Ua[2]&&(k[3]||("http:"===k[1]?80:443))==(Ua[3]||("http:"===Ua[1]?80:443))));x.data&&x.processData&&"string"!=typeof x.data&&(x.data= -h.param(x.data,x.traditional));D(Nb,x,b,p);if(2===ga)return p;v=x.global;x.type=x.type.toUpperCase();x.hasContent=!vd.test(x.type);v&&0===h.active++&&h.event.trigger("ajaxStart");if(!x.hasContent&&(x.data&&(x.url+=(zc.test(x.url)?"&":"?")+x.data,delete x.data),f=x.url,!1===x.cache)){k=h.now();var W=x.url.replace(yd,"$1_="+k);x.url=W+(W===x.url?(zc.test(x.url)?"&":"?")+"_="+k:"")}(x.data&&x.hasContent&&!1!==x.contentType||b.contentType)&&p.setRequestHeader("Content-Type",x.contentType);x.ifModified&& -(f=f||x.url,h.lastModified[f]&&p.setRequestHeader("If-Modified-Since",h.lastModified[f]),h.etag[f]&&p.setRequestHeader("If-None-Match",h.etag[f]));p.setRequestHeader("Accept",x.dataTypes[0]&&x.accepts[x.dataTypes[0]]?x.accepts[x.dataTypes[0]]+("*"!==x.dataTypes[0]?", "+Dc+"; q=0.01":""):x.accepts["*"]);for(m in x.headers)p.setRequestHeader(m,x.headers[m]);if(!x.beforeSend||!1!==x.beforeSend.call(n,p,x)&&2!==ga){u="abort";for(m in{success:1,error:1,complete:1})p[m](x[m]);if(g=D(Cc,x,b,p)){p.readyState= -1;v&&s.trigger("ajaxSend",[p,x]);x.async&&0ga))throw y;c(-1,y)}}else c(-1,"No Transport");return p}return p.abort()},active:0,lastModified:{},etag:{}});var Ec=[],zd=/\?/,Kb=/(=)\?(?=&|$)|\?\?/,Ad=h.now();h.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Ec.pop()||h.expando+"_"+Ad++;return this[a]=!0,a}});h.ajaxPrefilter("json jsonp",function(b,c,f){var l,d,g,j=b.data,k=b.url,v=!1!== -b.jsonp,m=v&&Kb.test(k),x=v&&!m&&"string"==typeof j&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kb.test(j);if("jsonp"===b.dataTypes[0]||m||x)return l=b.jsonpCallback=h.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,d=a[l],m?b.url=k.replace(Kb,"$1"+l):x?b.data=j.replace(Kb,"$1"+l):v&&(b.url+=(zd.test(k)?"&":"?")+b.jsonp+"="+l),b.converters["script json"]=function(){return g||h.error(l+" was not called"),g[0]},b.dataTypes[0]="json",a[l]=function(){g=arguments}, -f.always(function(){a[l]=d;b[l]&&(b.jsonpCallback=c.jsonpCallback,Ec.push(l));g&&h.isFunction(d)&&d(g[0]);g=d=e}),"script"});h.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return h.globalEval(a),a}}});h.ajaxPrefilter("script",function(a){a.cache===e&&(a.cache=!1);a.crossDomain&&(a.type="GET",a.global=!1)});h.ajaxTransport("script",function(a){if(a.crossDomain){var b, -c=z.head||z.getElementsByTagName("head")[0]||z.documentElement;return{send:function(f,l){b=z.createElement("script");b.async="async";a.scriptCharset&&(b.charset=a.scriptCharset);b.src=a.url;b.onload=b.onreadystatechange=function(a,f){if(f||!b.readyState||/loaded|complete/.test(b.readyState))b.onload=b.onreadystatechange=null,c&&b.parentNode&&c.removeChild(b),b=e,f||l(200,"success")};c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(0,1)}}}});var fb,cc=a.ActiveXObject?function(){for(var a in fb)fb[a](0, -1)}:!1,Bd=0;h.ajaxSettings.xhr=a.ActiveXObject?function(){var b;if(!(b=!this.isLocal&&K()))a:{try{b=new a.ActiveXObject("Microsoft.XMLHTTP");break a}catch(c){}b=void 0}return b}:K;var dc=h.ajaxSettings.xhr();h.extend(h.support,{ajax:!!dc,cors:!!dc&&"withCredentials"in dc});h.support.ajax&&h.ajaxTransport(function(b){if(!b.crossDomain||h.support.cors){var c;return{send:function(f,l){var d,g,j=b.xhr();b.username?j.open(b.type,b.url,b.async,b.username,b.password):j.open(b.type,b.url,b.async);if(b.xhrFields)for(g in b.xhrFields)j[g]= -b.xhrFields[g];b.mimeType&&j.overrideMimeType&&j.overrideMimeType(b.mimeType);!b.crossDomain&&!f["X-Requested-With"]&&(f["X-Requested-With"]="XMLHttpRequest");try{for(g in f)j.setRequestHeader(g,f[g])}catch(k){}j.send(b.hasContent&&b.data||null);c=function(a,f){var g,k,v,m,x;try{if(c&&(f||4===j.readyState))if(c=e,d&&(j.onreadystatechange=h.noop,cc&&delete fb[d]),f)4!==j.readyState&&j.abort();else{g=j.status;v=j.getAllResponseHeaders();m={};(x=j.responseXML)&&x.documentElement&&(m.xml=x);try{m.text= -j.responseText}catch(n){}try{k=j.statusText}catch(s){k=""}!g&&b.isLocal&&!b.crossDomain?g=m.text?200:404:1223===g&&(g=204)}}catch(G){f||l(-1,G)}m&&l(g,k,m,v)};b.async?4===j.readyState?setTimeout(c,0):(d=++Bd,cc&&(fb||(fb={},h(a).unload(cc)),fb[d]=c),j.onreadystatechange=c):c()},abort:function(){c&&c(0,1)}}}});var Ya,Lb,Cd=/^(?:toggle|show|hide)$/,Dd=RegExp("^(?:([-+])=|)("+La+")([a-z%]*)$","i"),Ed=/queueHooks$/,tb=[function(a,b,c){var f,l,d,e,g,j,k=this,v=a.style,m={},x=[],n=a.nodeType&&p(a);c.queue|| -(g=h._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,j=g.empty.fire,g.empty.fire=function(){g.unqueued||j()}),g.unqueued++,k.always(function(){k.always(function(){g.unqueued--;h.queue(a,"fx").length||g.empty.fire()})}));1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[v.overflow,v.overflowX,v.overflowY],"inline"===h.css(a,"display")&&"none"===h.css(a,"float")&&(!h.support.inlineBlockNeedsLayout||"inline"===C(a.nodeName)?v.display="inline-block":v.zoom=1));c.overflow&&(v.overflow="hidden", -h.support.shrinkWrapBlocks||k.done(function(){v.overflow=c.overflow[0];v.overflowX=c.overflow[1];v.overflowY=c.overflow[2]}));for(f in b)d=b[f],Cd.exec(d)&&(delete b[f],l=l||"toggle"===d,d!==(n?"hide":"show")&&x.push(f));if(b=x.length){d=h._data(a,"fxshow")||h._data(a,"fxshow",{});"hidden"in d&&(n=d.hidden);l&&(d.hidden=!n);n?h(a).show():k.done(function(){h(a).hide()});k.done(function(){var b;h.removeData(a,"fxshow",!0);for(b in m)h.style(a,b,m[b])});for(f=0;f").get(0).files;j=void 0!==window.FormData;a.fn.ajaxSubmit=function(d){function f(b){function f(){function b(){try{var a=(t.contentWindow?t.contentWindow.document:t.contentDocument?t.contentDocument:t.document).readyState; -c("state = "+a);a&&"uninitialized"==a.toLowerCase()&&setTimeout(b,50)}catch(f){c("Server abort: ",f," (",f.name,")"),j(M),z&&clearTimeout(z),z=void 0}}var d=q.attr("target"),g=q.attr("action");m.setAttribute("target",p);e||m.setAttribute("method","POST");g!=r.url&&m.setAttribute("action",r.url);!r.skipEncodingOverride&&(!e||/post/i.test(e))&&q.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"});r.timeout&&(z=setTimeout(function(){ia=!0;j(R)},r.timeout));var n=[];try{if(r.extraData)for(var s in r.extraData)r.extraData.hasOwnProperty(s)&& -n.push(a('').attr("value",r.extraData[s]).appendTo(m)[0]);r.iframeTarget||(y.appendTo("body"),t.attachEvent?t.attachEvent("onload",j):t.addEventListener("load",j,!1));setTimeout(b,15);m.submit()}finally{m.setAttribute("action",g),d?m.setAttribute("target",d):q.removeAttr("target"),a(n).remove()}}function j(b){if(!w.aborted&&!$){try{H=t.contentWindow?t.contentWindow.document:t.contentDocument?t.contentDocument:t.document}catch(f){c("cannot access response document: ", -f),b=M}if(b===R&&w)w.abort("timeout");else if(b==M&&w)w.abort("server abort");else if(H&&H.location.href!=r.iframeSrc||ia){t.detachEvent?t.detachEvent("onload",j):t.removeEventListener("load",j,!1);var b="success",d;try{if(ia)throw"timeout";var e="xml"==r.dataType||H.XMLDocument||a.isXMLDoc(H);c("isXml="+e);if(!e&&(window.opera&&(null===H.body||!H.body.innerHTML))&&--J){c("requeing onLoad callback, DOM not available");setTimeout(j,250);return}var g=H.body?H.body:H.documentElement;w.responseText=g? -g.innerHTML:null;w.responseXML=H.XMLDocument?H.XMLDocument:H;e&&(r.dataType="xml");w.getResponseHeader=function(a){return{"content-type":r.dataType}[a]};g&&(w.status=Number(g.getAttribute("status"))||w.status,w.statusText=g.getAttribute("statusText")||w.statusText);var k=(r.dataType||"").toLowerCase(),m=/(json|script|text)/.test(k);if(m||r.textarea){var n=H.getElementsByTagName("textarea")[0];if(n)w.responseText=n.value,w.status=Number(n.getAttribute("status"))||w.status,w.statusText=n.getAttribute("statusText")|| -w.statusText;else if(m){var s=H.getElementsByTagName("pre")[0],q=H.getElementsByTagName("body")[0];s?w.responseText=s.textContent?s.textContent:s.innerText:q&&(w.responseText=q.textContent?q.textContent:q.innerText)}}else"xml"==k&&(!w.responseXML&&w.responseText)&&(w.responseXML=ua(w.responseText));try{var e=w,g=r,p=e.getResponseHeader("content-type")||"",B="xml"===k||!k&&0<=p.indexOf("xml"),A=B?e.responseXML:e.responseText;B&&"parsererror"===A.documentElement.nodeName&&a.error&&a.error("parsererror"); -g&&g.dataFilter&&(A=g.dataFilter(A,k));"string"===typeof A&&("json"===k||!k&&0<=p.indexOf("json")?A=pa(A):("script"===k||!k&&0<=p.indexOf("javascript"))&&a.globalEval(A));N=A}catch(C){b="parsererror",w.error=d=C||b}}catch(D){c("error caught: ",D),b="error",w.error=d=D||b}w.aborted&&(c("upload aborted"),b=null);w.status&&(b=200<=w.status&&300>w.status||304===w.status?"success":"error");"success"===b?(r.success&&r.success.call(r.context,N,"success",w),u&&a.event.trigger("ajaxSuccess",[w,r])):b&&(void 0=== -d&&(d=w.statusText),r.error&&r.error.call(r.context,w,b,d),u&&a.event.trigger("ajaxError",[w,r,d]));u&&a.event.trigger("ajaxComplete",[w,r]);u&&!--a.active&&a.event.trigger("ajaxStop");r.complete&&r.complete.call(r.context,w,b);$=!0;r.timeout&&clearTimeout(z);setTimeout(function(){r.iframeTarget||y.remove();w.responseXML=null},100)}}}var m=q[0],n,r,u,p,y,t,w,A,ia,z;A=!!a.fn.prop;if(a(":input[name=submit],:input[id=submit]",m).length)alert('Error: Form elements must not have name or id of "submit".'); -else{if(b)for(n=0;n'),y.css({position:"absolute",top:"-1000px",left:"-1000px"}));t=y[0];w={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){}, -setRequestHeader:function(){},abort:function(b){var f="timeout"===b?"timeout":"aborted";c("aborting upload... "+f);this.aborted=1;y.attr("src",r.iframeSrc);w.error=f;r.error&&r.error.call(r.context,w,f,b);u&&a.event.trigger("ajaxError",[w,r,f]);r.complete&&r.complete.call(r.context,w,f)}};(u=r.global)&&0===a.active++&&a.event.trigger("ajaxStart");u&&a.event.trigger("ajaxSend",[w,r]);if(r.beforeSend&&!1===r.beforeSend.call(r.context,w,r))r.global&&a.active--;else if(!w.aborted){if(A=m.clk)if((b=A.name)&& -!A.disabled)r.extraData=r.extraData||{},r.extraData[b]=A.value,"image"==A.type&&(r.extraData[b+".x"]=m.clk_x,r.extraData[b+".y"]=m.clk_y);var R=1,M=2;A=a("meta[name=csrf-token]").attr("content");if((b=a("meta[name=csrf-param]").attr("content"))&&A)r.extraData=r.extraData||{},r.extraData[b]=A;r.forceSync?f():setTimeout(f,10);var N,H,J=50,$,ua=a.parseXML||function(a,b){window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"); -return b&&b.documentElement&&"parsererror"!=b.documentElement.nodeName?b:null},pa=a.parseJSON||function(a){return window.eval("("+a+")")}}}}if(!this.length)return c("ajaxSubmit: skipping submit process - no element selected"),this;var e,m,q=this;"function"==typeof d&&(d={success:d});e=this.attr("method");m=this.attr("action");(m=(m="string"===typeof m?a.trim(m):"")||window.location.href||"")&&(m=(m.match(/^([^#]+)/)||[])[1]);d=a.extend(!0,{url:m,success:a.ajaxSettings.success,type:e||"GET",iframeSrc:/^https/i.test(window.location.href|| -"")?"javascript:false":"about:blank"},d);m={};this.trigger("form-pre-serialize",[this,d,m]);if(m.veto)return c("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(d.beforeSerialize&&!1===d.beforeSerialize(this,d))return c("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var n=d.traditional;void 0===n&&(n=a.ajaxSettings.traditional);var s=[],r,u=this.formToArray(d.semantic,s);d.data&&(d.extraData=d.data,r=a.param(d.data,n));if(d.beforeSubmit&&!1===d.beforeSubmit(u,this, -d))return c("ajaxSubmit: submit aborted via beforeSubmit callback"),this;this.trigger("form-submit-validate",[u,this,d,m]);if(m.veto)return c("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;m=a.param(u,n);r&&(m=m?m+"&"+r:r);"GET"==d.type.toUpperCase()?(d.url+=(0<=d.url.indexOf("?")?"&":"?")+m,d.data=null):d.data=m;var p=[];d.resetForm&&p.push(function(){q.resetForm()});d.clearForm&&p.push(function(){q.clearForm(d.includeHidden)});if(!d.dataType&&d.target){var y=d.success||function(){}; -p.push(function(b){var c=d.replaceTarget?"replaceWith":"html";a(d.target)[c](b).each(y,arguments)})}else d.success&&p.push(d.success);d.success=function(a,b,c){for(var f=d.context||d,e=0,j=p.length;eZ.cacheLength&&delete a[b.shift()],a[c+" "]=f},a)},nc=Xb(), +jc=Xb(),oc=Xb(),pc="\\[[\\x20\\t\\r\\n\\f]*((?:\\\\.|[-\\w]|[^\\x00-\\xa0])+)[\\x20\\t\\r\\n\\f]*(?:([*^$|!~]?=)[\\x20\\t\\r\\n\\f]*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+"(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+".replace("w","w#")+")|)|)[\\x20\\t\\r\\n\\f]*\\]",Yb=":((?:\\\\.|[-\\w]|[^\\x00-\\xa0])+)(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+pc+")|[^:]|\\\\.)*|.*))\\)|)",Cb=RegExp("^[\\x20\\t\\r\\n\\f]+|((?:^|[^\\\\])(?:\\\\.)*)[\\x20\\t\\r\\n\\f]+$","g"),Mc=/^[\x20\t\r\n\f]*,[\x20\t\r\n\f]*/, +Nc=/^[\x20\t\r\n\f]*([\x20\t\r\n\f>+~])[\x20\t\r\n\f]*/,Qc=RegExp(Yb),Lc=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Tb=/[\x20\t\r\n\f]*[+~]/,Rc=/h\d/i,Sc=/input|select|textarea|button/i,Ta=/\\(?!\\)/g,Db={ID:/^#((?:\\.|[-\w]|[^\x00-\xa0])+)/,CLASS:/^\.((?:\\.|[-\w]|[^\x00-\xa0])+)/,NAME:/^\[name=['"]?((?:\\.|[-\w]|[^\x00-\xa0])+)['"]?\]/,TAG:RegExp("^("+"(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+".replace("w","w*")+")"),ATTR:RegExp("^"+pc),PSEUDO:RegExp("^"+Yb),POS:/:(even|odd|eq|gt|lt|nth|first|last)(?:\([\x20\t\r\n\f]*((?:-\d)?\d*)[\x20\t\r\n\f]*\)|)(?=[^-]|$)/i, +CHILD:RegExp("^:(only|nth|first|last)-child(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)","i"),needsContext:RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},Ia=function(a){var b=Ba.createElement("div");try{return a(b)}catch(c){return!1}finally{}},Tc=Ia(function(a){return a.appendChild(Ba.createComment("")), +!a.getElementsByTagName("*").length}),Uc=Ia(function(a){return a.innerHTML="",a.firstChild&&"undefined"!==typeof a.firstChild.getAttribute&&"#"===a.firstChild.getAttribute("href")}),Vc=Ia(function(a){a.innerHTML="";a=typeof a.lastChild.getAttribute("multiple");return"boolean"!==a&&"string"!==a}),ic=Ia(function(a){return a.innerHTML="",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className= +"e",2===a.getElementsByClassName("e").length)}),Wc=Ia(function(a){a.id=da+0;a.innerHTML="
    ";va.insertBefore(a,va.firstChild);var b=Ba.getElementsByName&&Ba.getElementsByName(da).length===2+Ba.getElementsByName(da+0).length;return Vb=!Ba.getElementById(da),va.removeChild(a),b});try{eb.call(va.childNodes,0)[0].nodeType}catch(Ed){eb=function(a){for(var b,c=[];b=this[a];a++)c.push(b);return c}}w.matches=function(a,b){return w(a,null,null,b)};w.matchesSelector= +function(a,b){return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(Ta,""),a[3]=(a[4]|| +a[5]||"").replace(Ta,""),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1]?(a[2]||w.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*("even"===a[2]||"odd"===a[2])),a[4]=+(a[6]+a[7]||"odd"===a[2])):a[2]&&w.error(a[0]),a},PSEUDO:function(a){var b,c;if(Db.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])Qc.test(b)&&(c=oa(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:Vb? +function(a){return a=a.replace(Ta,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(Ta,""),function(b){return(b="undefined"!==typeof b.getAttributeNode&&b.getAttributeNode("id"))&&b.value===a}},TAG:function(a){return"*"===a?function(){return!0}:(a=a.replace(Ta,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=nc[da][a+" "];return b||(b=RegExp("(^|[\\x20\\t\\r\\n\\f])"+a+"([\\x20\\t\\r\\n\\f]|$)"))&&nc(a,function(a){return b.test(a.className|| +"undefined"!==typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(f){f=w.attr(f,a);return null==f?"!="===b:b?(f+="","="===b?f===c:"!="===b?f!==c:"^="===b?c&&0===f.indexOf(c):"*="===b?c&&-1c?c+b:c]}),even:ia(function(a,b){for(var c=0;cc?c+b:c;0<=--b;)a.push(b);return a}),gt:ia(function(a,b,c){for(c=0>c?c+b:c;++c";a.querySelectorAll("[selected]").length||Ja.push("\\[[\\x20\\t\\r\\n\\f]*(?:checked|disabled|ismap|multiple|readonly|selected|value)");a.querySelectorAll(":checked").length||Ja.push(":checked")});Ia(function(a){a.innerHTML= +"

    ";a.querySelectorAll("[test^='']").length&&Ja.push("[*^$]=[\\x20\\t\\r\\n\\f]*(?:\"\"|'')");a.innerHTML="";a.querySelectorAll(":enabled").length||Ja.push(":enabled",":disabled")});Ja=RegExp(Ja.join("|"));Ob=function(a,b,c,f,d){if(!f&&!d&&!Ja.test(a)){var e,m,g=!0,j=da;m=b;e=9===b.nodeType&&a;if(1===b.nodeType&&"object"!==b.nodeName.toLowerCase()){e=oa(a);(g=b.getAttribute("id"))?j=g.replace(Yc,"\\$&"):b.setAttribute("id",j);j="[id='"+j+"'] ";for(m=e.length;m--;)e[m]= +j+e[m].join("");m=Tb.test(a)&&b.parentNode||b;e=e.join(",")}if(e)try{return db.apply(c,eb.call(m.querySelectorAll(e),0)),c}catch(k){}finally{g||b.removeAttribute("id")}}return Xc(a,b,c,f,d)};Ib&&(Ia(function(a){qc=Ib.call(a,"div");try{Ib.call(a,"[test!='']:sizzle"),Hb.push("!=",Yb)}catch(b){}}),Hb=RegExp(Hb.join("|")),w.matchesSelector=function(a,b){b=b.replace(Zc,"='$1']");if(!Bb(a)&&!Hb.test(b)&&!Ja.test(b))try{var c=Ib.call(a,b);if(c||qc||a.document&&11!==a.document.nodeType)return c}catch(f){}return 0< +w(b,null,null,[a]).length})}Z.pseudos.nth=Z.pseudos.eq;Z.filters=lc.prototype=Z.pseudos;Z.setFilters=new lc;w.attr=h.attr;h.find=w;h.expr=w.selectors;h.expr[":"]=h.expr.pseudos;h.unique=w.uniqueSort;h.text=w.getText;h.isXMLDoc=w.isXML;h.contains=w.contains;var $c=/Until$/,ad=/^(?:parents|prev(?:Until|All))/,Hc=/^.[^:#\[\.,]*$/,rc=h.expr.match.needsContext,bd={children:!0,contents:!0,next:!0,prev:!0};h.fn.extend({find:function(a){var b,c,f,d,e,m,g=this;if("string"!=typeof a)return h(a).filter(function(){b= +0;for(c=g.length;b]*)\/>/gi, +tc=/<([\w:]+)/,dd=/
    ]","i"),fc=/^(?:checkbox|radio)$/,uc=/checked\s*(?:[^=]|=\s*.checked.)/i,hd=/\/(java|ecma)script/i,id=/^\s*\s*$/g,ra={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"
    ","
    "],tr:[2,"","
    "],td:[3,"","
    "], +col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},vc=l(z),ac=vc.appendChild(z.createElement("div"));ra.optgroup=ra.option;ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead;ra.th=ra.td;h.support.htmlSerialize||(ra._default=[1,"X
    ","
    "]);h.fn.extend({text:function(a){return h.access(this,function(a){return a===e?h.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(h.isFunction(a))return this.each(function(b){h(this).wrapAll(a.call(this, +b))});if(this[0]){var b=h(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var a=this;a.firstChild&&1===a.firstChild.nodeType;)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return h.isFunction(a)?this.each(function(b){h(this).wrapInner(a.call(this,b))}):this.each(function(){var b=h(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=h.isFunction(a);return this.each(function(c){h(this).wrapAll(b? +a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){h.nodeName(this,"body")||h(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!g(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a, +this)});if(arguments.length){var a=h.clean(arguments);return this.pushStack(h.merge(a,this),"before",this.selector)}},after:function(){if(!g(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=h.clean(arguments);return this.pushStack(h.merge(this,a),"after",this.selector)}},remove:function(a,b){for(var c,f=0;null!=(c=this[f]);f++)if(!a||h.filter(a,[c]).length)!b&&1===c.nodeType&&(h.cleanData(c.getElementsByTagName("*")), +h.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)for(1===a.nodeType&&h.cleanData(a.getElementsByTagName("*"));a.firstChild;)a.removeChild(a.firstChild);return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return h.clone(this,a,b)})},html:function(a){return h.access(this,function(a){var b=this[0]||{},c=0,f=this.length;if(a===e)return 1===b.nodeType?b.innerHTML.replace(cd,""):e;if("string"== +typeof a&&!fd.test(a)&&(h.support.htmlSerialize||!$b.test(a))&&(h.support.leadingWhitespace||!Zb.test(a))&&!ra[(tc.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(sc,"<$1>");try{for(;cg.length&&b===z&&"<"===g.charAt(0)&&!gd.test(g)&&(h.support.checkClone||!uc.test(g))&&(h.support.html5Clone||!$b.test(g))&&(d=!0,f=h.fragments[g],m=f!==e),f||(f=b.createDocumentFragment(), +h.clean(a,b,f,c),d&&(h.fragments[g]=m&&f)),{fragment:f,cacheable:d}};h.fragments={};h.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){h.fn[a]=function(c){var f,d=0,e=[],c=h(c),m=c.length;f=1===this.length&&this[0].parentNode;if((null==f||f&&11===f.nodeType&&1===f.childNodes.length)&&1===m)return c[b](this[0]),this;for(;d")?m=a.cloneNode(!0):(ac.innerHTML=a.outerHTML,ac.removeChild(m=ac.firstChild));if((!h.support.noCloneEvent||!h.support.noCloneChecked)&&(1===a.nodeType||11===a.nodeType)&&!h.isXMLDoc(a)){p(a,m);f=v(a);d=v(m);for(e=0;f[e];++e)d[e]&&p(f[e],d[e])}if(b&&(n(a,m),c)){f=v(a);d=v(m);for(e=0;f[e];++e)n(f[e],d[e])}return m},clean:function(a,b,c,f){var d,e,m,g,j,k,w,x=b===z&&vc,p=[];if(!b||"undefined"== +typeof b.createDocumentFragment)b=z;for(d=0;null!=(m=a[d]);d++)if("number"==typeof m&&(m+=""),m){if("string"==typeof m)if(ed.test(m)){x=x||l(b);k=b.createElement("div");x.appendChild(k);m=m.replace(sc,"<$1>");e=(tc.exec(m)||["",""])[1].toLowerCase();g=ra[e]||ra._default;j=g[0];for(k.innerHTML=g[1]+m+g[2];j--;)k=k.lastChild;if(!h.support.tbody){j=dd.test(m);g="table"===e&&!j?k.firstChild&&k.firstChild.childNodes:""===g[1]&&!j?k.childNodes:[];for(e=g.length-1;0<=e;--e)h.nodeName(g[e],"tbody")&& +!g[e].childNodes.length&&g[e].parentNode.removeChild(g[e])}!h.support.leadingWhitespace&&Zb.test(m)&&k.insertBefore(b.createTextNode(Zb.exec(m)[0]),k.firstChild);m=k.childNodes;k.parentNode.removeChild(k)}else m=b.createTextNode(m);m.nodeType?p.push(m):h.merge(p,m)}k&&(m=k=x=null);if(!h.support.appendChecked)for(d=0;null!=(m=p[d]);d++)h.nodeName(m,"input")?s(m):"undefined"!=typeof m.getElementsByTagName&&h.grep(m.getElementsByTagName("input"),s);if(c){a=function(a){if(!a.type||hd.test(a.type))return f? +f.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(d=0;null!=(m=p[d]);d++)if(!h.nodeName(m,"script")||!a(m))c.appendChild(m),"undefined"!=typeof m.getElementsByTagName&&(w=h.grep(h.merge([],m.getElementsByTagName("script")),a),p.splice.apply(p,[d+1,0].concat(w)),d+=w.length)}return p},cleanData:function(a,b){for(var c,f,d,e,m=0,g=h.expando,j=h.cache,k=h.support.deleteExpando,w=h.event.special;null!=(d=a[m]);m++)if(b||h.acceptData(d))if(c=(f=d[g])&&j[f]){if(c.events)for(e in c.events)w[e]? +h.event.remove(d,e):h.removeEvent(d,e,c.handle);j[f]&&(delete j[f],k?delete d[g]:d.removeAttribute?d.removeAttribute(g):d[g]=null,h.deletedIds.push(f))}}});var Jb,Ka;h.uaMatch=function(a){a=a.toLowerCase();a=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||0>a.indexOf("compatible")&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};Jb=h.uaMatch(R.userAgent);Ka={};Jb.browser&& +(Ka[Jb.browser]=!0,Ka.version=Jb.version);Ka.chrome?Ka.webkit=!0:Ka.webkit&&(Ka.safari=!0);h.browser=Ka;h.sub=function(){function a(b,c){return new a.fn.init(b,c)}h.extend(!0,a,this);a.superclass=this;a.fn=a.prototype=this();a.fn.constructor=a;a.sub=this.sub;a.fn.init=function(c,f){return f&&f instanceof h&&!(f instanceof a)&&(f=a(f)),h.fn.init.call(this,c,f,b)};a.fn.init.prototype=a.fn;var b=a(z);return a};var pa,Wa,Xa,bc=/alpha\([^)]*\)/i,jd=/opacity=([^)]*)/,kd=/^(top|right|bottom|left)$/,ld=/^(none|table(?!-c[ea]).+)/, +wc=/^margin/,Ic=RegExp("^("+wa+")(.*)$","i"),sb=RegExp("^("+wa+")(?!px)[a-z%]+$","i"),md=RegExp("^([-+])=("+wa+")","i"),Mb={BODY:"block"},nd={position:"absolute",visibility:"hidden",display:"block"},xc={letterSpacing:0,fontWeight:400},La=["Top","Right","Bottom","Left"],gc=["Webkit","O","Moz","ms"],od=h.fn.toggle;h.fn.extend({css:function(a,b){return h.access(this,function(a,b,c){return c!==e?h.style(a,b,c):h.css(a,b)},a,b,1c;c++)d[a+La[c]+ +b]=f[c]||f[c-2]||f[0];return d}};wc.test(a)||(h.cssHooks[a+b].set=u)});var pd=/%20/g,Jc=/\[\]$/,yc=/\r?\n/g,qd=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,rd=/^(?:select|textarea)/i;h.fn.extend({serialize:function(){return h.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?h.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked|| +rd.test(this.nodeName)||qd.test(this.type))}).map(function(a,b){var c=h(this).val();return null==c?null:h.isArray(c)?h.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}});h.param=function(a,b){var c,f=[],d=function(a,b){b=h.isFunction(b)?b():null==b?"":b;f[f.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};b===e&&(b=h.ajaxSettings&&h.ajaxSettings.traditional);if(h.isArray(a)||a.jquery&&!h.isPlainObject(a))h.each(a,function(){d(this.name, +this.value)});else for(c in a)A(c,a[c],b,d);return f.join("&").replace(pd,"+")};var Ua,Va,sd=/#.*$/,td=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,ud=/^(?:GET|HEAD)$/,vd=/^\/\//,zc=/\?/,wd=/)<[^<]*)*<\/script>/gi,xd=/([?&])_=[^&]*/,Ac=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Bc=h.fn.load,Nb={},Cc={},Dc=["*/"]+["*"];try{Va=S.href}catch(Fd){Va=z.createElement("a"),Va.href="",Va=Va.href}Ua=Ac.exec(Va.toLowerCase())||[];h.fn.load=function(a,b,c){if("string"!=typeof a&&Bc)return Bc.apply(this, +arguments);if(!this.length)return this;var f,d,m,g=this,j=a.indexOf(" ");return 0<=j&&(f=a.slice(j,a.length),a=a.slice(0,j)),h.isFunction(b)?(c=b,b=e):b&&"object"==typeof b&&(d="POST"),h.ajax({url:a,type:d,dataType:"html",data:b,complete:function(a,b){c&&g.each(c,m||[a.responseText,b,a])}}).done(function(a){m=arguments;g.html(f?h("
    ").append(a.replace(wd,"")).find(f):a)}),this};h.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){h.fn[b]=function(a){return this.on(b, +a)}});h.each(["get","post"],function(a,b){h[b]=function(a,c,f,d){return h.isFunction(c)&&(d=d||f,f=c,c=e),h.ajax({type:b,url:a,data:c,success:f,dataType:d})}});h.extend({getScript:function(a,b){return h.get(a,e,b,"script")},getJSON:function(a,b,c){return h.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?X(a,h.ajaxSettings):(b=a,a=h.ajaxSettings),X(a,b),a},ajaxSettings:{url:Va,isLocal:/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/.test(Ua[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8", +processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Dc},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":h.parseJSON,"text xml":h.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:N(Nb),ajaxTransport:N(Cc),ajax:function(a,b){function c(a,b,m,k){var l,q,s,oa,u,y=b;if(2!==na){na=2;j&&clearTimeout(j); +g=e;d=k||"";r.readyState=0a||304===a)if(x.ifModified&&(u=r.getResponseHeader("Last-Modified"), +u&&(h.lastModified[f]=u),u=r.getResponseHeader("Etag"),u&&(h.etag[f]=u)),304===a)y="notmodified",l=!0;else{var ka;a:{l=x;q=oa;var Ha,y=l.dataTypes.slice(),m=y[0];t={};P=0;l.dataFilter&&(q=l.dataFilter(q,l.dataType));if(y[1])for(ka in l.converters)t[ka.toLowerCase()]=l.converters[ka];for(;s=y[++P];)if("*"!==s){if("*"!==m&&m!==s){ka=t[m+" "+s]||t["* "+s];if(!ka)for(Ha in t)if(u=Ha.split(" "),u[1]===s&&(ka=t[m+" "+u[0]]||t["* "+u[0]])){!0===ka?ka=t[Ha]:!0!==t[Ha]&&(s=u[0],y.splice(P--,0,s));break}if(!0!== +ka)if(ka&&l["throws"])q=ka(q);else try{q=ka(q)}catch(D){ka={state:"parsererror",error:ka?D:"No conversion from "+m+" to "+s};break a}}m=s}ka={state:"success",data:q}}l=ka;y=l.state;q=l.data;s=l.error;l=!s}else if(s=y,!y||a)y="error",0>a&&(a=0);r.status=a;r.statusText=(b||y)+"";l?J.resolveWith(p,[q,y,r]):J.rejectWith(p,[r,y,s]);r.statusCode(ia);ia=e;w&&v.trigger("ajax"+(l?"Success":"Error"),[r,x,l?q:s]);n.fireWith(p,[r,y]);w&&(v.trigger("ajaxComplete",[r,x]),--h.active||h.event.trigger("ajaxStop"))}} +"object"==typeof a&&(b=a,a=e);var b=b||{},f,d,m,g,j,k,w,l,x=h.ajaxSetup({},b),p=x.context||x,v=p!==x&&(p.nodeType||p instanceof h)?h(p):h.event,J=h.Deferred(),n=h.Callbacks("once memory"),ia=x.statusCode||{},q={},s={},na=0,oa="canceled",r={readyState:0,setRequestHeader:function(a,b){if(!na){var c=a.toLowerCase(),a=s[c]=s[c]||a;q[a]=b}return this},getAllResponseHeaders:function(){return 2===na?d:null},getResponseHeader:function(a){var b;if(2===na){if(!m)for(m={};b=td.exec(d);)m[b[1].toLowerCase()]= +b[2];b=m[a.toLowerCase()]}return b===e?null:b},overrideMimeType:function(a){return na||(x.mimeType=a),this},abort:function(a){return a=a||oa,g&&g.abort(a),c(0,a),this}};J.promise(r);r.success=r.done;r.error=r.fail;r.complete=n.add;r.statusCode=function(a){if(a){var b;if(2>na)for(b in a)ia[b]=[ia[b],a[b]];else b=a[r.status],r.always(b)}return this};x.url=((a||x.url)+"").replace(sd,"").replace(vd,Ua[1]+"//");x.dataTypes=h.trim(x.dataType||"*").toLowerCase().split(Aa);null==x.crossDomain&&(k=Ac.exec(x.url.toLowerCase()), +x.crossDomain=!(!k||k[1]===Ua[1]&&k[2]===Ua[2]&&(k[3]||("http:"===k[1]?80:443))==(Ua[3]||("http:"===Ua[1]?80:443))));x.data&&x.processData&&"string"!=typeof x.data&&(x.data=h.param(x.data,x.traditional));D(Nb,x,b,r);if(2===na)return r;w=x.global;x.type=x.type.toUpperCase();x.hasContent=!ud.test(x.type);w&&0===h.active++&&h.event.trigger("ajaxStart");if(!x.hasContent&&(x.data&&(x.url+=(zc.test(x.url)?"&":"?")+x.data,delete x.data),f=x.url,!1===x.cache)){k=h.now();var u=x.url.replace(xd,"$1_="+k);x.url= +u+(u===x.url?(zc.test(x.url)?"&":"?")+"_="+k:"")}(x.data&&x.hasContent&&!1!==x.contentType||b.contentType)&&r.setRequestHeader("Content-Type",x.contentType);x.ifModified&&(f=f||x.url,h.lastModified[f]&&r.setRequestHeader("If-Modified-Since",h.lastModified[f]),h.etag[f]&&r.setRequestHeader("If-None-Match",h.etag[f]));r.setRequestHeader("Accept",x.dataTypes[0]&&x.accepts[x.dataTypes[0]]?x.accepts[x.dataTypes[0]]+("*"!==x.dataTypes[0]?", "+Dc+"; q=0.01":""):x.accepts["*"]);for(l in x.headers)r.setRequestHeader(l, +x.headers[l]);if(!x.beforeSend||!1!==x.beforeSend.call(p,r,x)&&2!==na){oa="abort";for(l in{success:1,error:1,complete:1})r[l](x[l]);if(g=D(Cc,x,b,r)){r.readyState=1;w&&v.trigger("ajaxSend",[r,x]);x.async&&0na))throw y;c(-1,y)}}else c(-1,"No Transport");return r}return r.abort()},active:0,lastModified:{},etag:{}});var Ec=[],yd=/\?/,Kb=/(=)\?(?=&|$)|\?\?/,zd=h.now();h.ajaxSetup({jsonp:"callback", +jsonpCallback:function(){var a=Ec.pop()||h.expando+"_"+zd++;return this[a]=!0,a}});h.ajaxPrefilter("json jsonp",function(b,c,f){var d,m,g,j=b.data,k=b.url,w=!1!==b.jsonp,l=w&&Kb.test(k),x=w&&!l&&"string"==typeof j&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kb.test(j);if("jsonp"===b.dataTypes[0]||l||x)return d=b.jsonpCallback=h.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,m=a[d],l?b.url=k.replace(Kb,"$1"+d):x?b.data=j.replace(Kb,"$1"+d):w&&(b.url+=(yd.test(k)? +"&":"?")+b.jsonp+"="+d),b.converters["script json"]=function(){return g||h.error(d+" was not called"),g[0]},b.dataTypes[0]="json",a[d]=function(){g=arguments},f.always(function(){a[d]=m;b[d]&&(b.jsonpCallback=c.jsonpCallback,Ec.push(d));g&&h.isFunction(m)&&m(g[0]);g=m=e}),"script"});h.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return h.globalEval(a), +a}}});h.ajaxPrefilter("script",function(a){a.cache===e&&(a.cache=!1);a.crossDomain&&(a.type="GET",a.global=!1)});h.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||z.getElementsByTagName("head")[0]||z.documentElement;return{send:function(f,d){b=z.createElement("script");b.async="async";a.scriptCharset&&(b.charset=a.scriptCharset);b.src=a.url;b.onload=b.onreadystatechange=function(a,f){if(f||!b.readyState||/loaded|complete/.test(b.readyState))b.onload=b.onreadystatechange=null, +c&&b.parentNode&&c.removeChild(b),b=e,f||d(200,"success")};c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(0,1)}}}});var fb,cc=a.ActiveXObject?function(){for(var a in fb)fb[a](0,1)}:!1,Ad=0;h.ajaxSettings.xhr=a.ActiveXObject?function(){var b;if(!(b=!this.isLocal&&G()))a:{try{b=new a.ActiveXObject("Microsoft.XMLHTTP");break a}catch(c){}b=void 0}return b}:G;var dc=h.ajaxSettings.xhr();h.extend(h.support,{ajax:!!dc,cors:!!dc&&"withCredentials"in dc});h.support.ajax&&h.ajaxTransport(function(b){if(!b.crossDomain|| +h.support.cors){var c;return{send:function(f,d){var m,g,j=b.xhr();b.username?j.open(b.type,b.url,b.async,b.username,b.password):j.open(b.type,b.url,b.async);if(b.xhrFields)for(g in b.xhrFields)j[g]=b.xhrFields[g];b.mimeType&&j.overrideMimeType&&j.overrideMimeType(b.mimeType);!b.crossDomain&&!f["X-Requested-With"]&&(f["X-Requested-With"]="XMLHttpRequest");try{for(g in f)j.setRequestHeader(g,f[g])}catch(k){}j.send(b.hasContent&&b.data||null);c=function(a,f){var g,k,w,l,x;try{if(c&&(f||4===j.readyState))if(c= +e,m&&(j.onreadystatechange=h.noop,cc&&delete fb[m]),f)4!==j.readyState&&j.abort();else{g=j.status;w=j.getAllResponseHeaders();l={};(x=j.responseXML)&&x.documentElement&&(l.xml=x);try{l.text=j.responseText}catch(p){}try{k=j.statusText}catch(v){k=""}!g&&b.isLocal&&!b.crossDomain?g=l.text?200:404:1223===g&&(g=204)}}catch(J){f||d(-1,J)}l&&d(g,k,l,w)};b.async?4===j.readyState?setTimeout(c,0):(m=++Ad,cc&&(fb||(fb={},h(a).unload(cc)),fb[m]=c),j.onreadystatechange=c):c()},abort:function(){c&&c(0,1)}}}}); +var Ya,Lb,Bd=/^(?:toggle|show|hide)$/,Cd=RegExp("^(?:([-+])=|)("+wa+")([a-z%]*)$","i"),Dd=/queueHooks$/,tb=[function(a,b,c){var f,d,e,m,g,j,k=this,w=a.style,l={},x=[],p=a.nodeType&&q(a);c.queue||(g=h._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,j=g.empty.fire,g.empty.fire=function(){g.unqueued||j()}),g.unqueued++,k.always(function(){k.always(function(){g.unqueued--;h.queue(a,"fx").length||g.empty.fire()})}));1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[w.overflow,w.overflowX,w.overflowY], +"inline"===h.css(a,"display")&&"none"===h.css(a,"float")&&(!h.support.inlineBlockNeedsLayout||"inline"===B(a.nodeName)?w.display="inline-block":w.zoom=1));c.overflow&&(w.overflow="hidden",h.support.shrinkWrapBlocks||k.done(function(){w.overflow=c.overflow[0];w.overflowX=c.overflow[1];w.overflowY=c.overflow[2]}));for(f in b)e=b[f],Bd.exec(e)&&(delete b[f],d=d||"toggle"===e,e!==(p?"hide":"show")&&x.push(f));if(b=x.length){e=h._data(a,"fxshow")||h._data(a,"fxshow",{});"hidden"in e&&(p=e.hidden);d&&(e.hidden= +!p);p?h(a).show():k.done(function(){h(a).hide()});k.done(function(){var b;h.removeData(a,"fxshow",!0);for(b in l)h.style(a,b,l[b])});for(f=0;f").get(0).files;j=void 0!==window.FormData;a.fn.ajaxSubmit=function(d){function f(b){function f(){function b(){try{var a=(y.contentWindow?y.contentWindow.document:y.contentDocument?y.contentDocument:y.document).readyState; +c("state = "+a);a&&"uninitialized"==a.toLowerCase()&&setTimeout(b,50)}catch(f){c("Server abort: ",f," (",f.name,")"),j(R),z&&clearTimeout(z),z=void 0}}var d=n.attr("target"),g=n.attr("action");l.setAttribute("target",r);e||l.setAttribute("method","POST");g!=q.url&&l.setAttribute("action",q.url);!q.skipEncodingOverride&&(!e||/post/i.test(e))&&n.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"});q.timeout&&(z=setTimeout(function(){V=!0;j(S)},q.timeout));var p=[];try{if(q.extraData)for(var v in q.extraData)q.extraData.hasOwnProperty(v)&& +p.push(a('').attr("value",q.extraData[v]).appendTo(l)[0]);q.iframeTarget||(u.appendTo("body"),y.attachEvent?y.attachEvent("onload",j):y.addEventListener("load",j,!1));setTimeout(b,15);l.submit()}finally{l.setAttribute("action",g),d?l.setAttribute("target",d):n.removeAttr("target"),a(p).remove()}}function j(b){if(!t.aborted&&!$){try{H=y.contentWindow?y.contentWindow.document:y.contentDocument?y.contentDocument:y.document}catch(f){c("cannot access response document: ", +f),b=R}if(b===S&&t)t.abort("timeout");else if(b==R&&t)t.abort("server abort");else if(H&&H.location.href!=q.iframeSrc||V){y.detachEvent?y.detachEvent("onload",j):y.removeEventListener("load",j,!1);var b="success",d;try{if(V)throw"timeout";var e="xml"==q.dataType||H.XMLDocument||a.isXMLDoc(H);c("isXml="+e);if(!e&&(window.opera&&(null===H.body||!H.body.innerHTML))&&--I){c("requeing onLoad callback, DOM not available");setTimeout(j,250);return}var g=H.body?H.body:H.documentElement;t.responseText=g?g.innerHTML: +null;t.responseXML=H.XMLDocument?H.XMLDocument:H;e&&(q.dataType="xml");t.getResponseHeader=function(a){return{"content-type":q.dataType}[a]};g&&(t.status=Number(g.getAttribute("status"))||t.status,t.statusText=g.getAttribute("statusText")||t.statusText);var k=(q.dataType||"").toLowerCase(),l=/(json|script|text)/.test(k);if(l||q.textarea){var p=H.getElementsByTagName("textarea")[0];if(p)t.responseText=p.value,t.status=Number(p.getAttribute("status"))||t.status,t.statusText=p.getAttribute("statusText")|| +t.statusText;else if(l){var v=H.getElementsByTagName("pre")[0],n=H.getElementsByTagName("body")[0];v?t.responseText=v.textContent?v.textContent:v.innerText:n&&(t.responseText=n.textContent?n.textContent:n.innerText)}}else"xml"==k&&(!t.responseXML&&t.responseText)&&(t.responseXML=ca(t.responseText));try{var e=t,g=q,r=e.getResponseHeader("content-type")||"",C="xml"===k||!k&&0<=r.indexOf("xml"),B=C?e.responseXML:e.responseText;C&&"parsererror"===B.documentElement.nodeName&&a.error&&a.error("parsererror"); +g&&g.dataFilter&&(B=g.dataFilter(B,k));"string"===typeof B&&("json"===k||!k&&0<=r.indexOf("json")?B=ea(B):("script"===k||!k&&0<=r.indexOf("javascript"))&&a.globalEval(B));T=B}catch(A){b="parsererror",t.error=d=A||b}}catch(D){c("error caught: ",D),b="error",t.error=d=D||b}t.aborted&&(c("upload aborted"),b=null);t.status&&(b=200<=t.status&&300>t.status||304===t.status?"success":"error");"success"===b?(q.success&&q.success.call(q.context,T,"success",t),s&&a.event.trigger("ajaxSuccess",[t,q])):b&&(void 0=== +d&&(d=t.statusText),q.error&&q.error.call(q.context,t,b,d),s&&a.event.trigger("ajaxError",[t,q,d]));s&&a.event.trigger("ajaxComplete",[t,q]);s&&!--a.active&&a.event.trigger("ajaxStop");q.complete&&q.complete.call(q.context,t,b);$=!0;q.timeout&&clearTimeout(z);setTimeout(function(){q.iframeTarget||u.remove();t.responseXML=null},100)}}}var l=n[0],p,q,s,r,u,y,t,C,V,z;C=!!a.fn.prop;if(a(":input[name=submit],:input[id=submit]",l).length)alert('Error: Form elements must not have name or id of "submit".'); +else{if(b)for(p=0;p'),u.css({position:"absolute",top:"-1000px",left:"-1000px"}));y=u[0];t={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){}, +setRequestHeader:function(){},abort:function(b){var f="timeout"===b?"timeout":"aborted";c("aborting upload... "+f);this.aborted=1;u.attr("src",q.iframeSrc);t.error=f;q.error&&q.error.call(q.context,t,f,b);s&&a.event.trigger("ajaxError",[t,q,f]);q.complete&&q.complete.call(q.context,t,f)}};(s=q.global)&&0===a.active++&&a.event.trigger("ajaxStart");s&&a.event.trigger("ajaxSend",[t,q]);if(q.beforeSend&&!1===q.beforeSend.call(q.context,t,q))q.global&&a.active--;else if(!t.aborted){if(C=l.clk)if((b=C.name)&& +!C.disabled)q.extraData=q.extraData||{},q.extraData[b]=C.value,"image"==C.type&&(q.extraData[b+".x"]=l.clk_x,q.extraData[b+".y"]=l.clk_y);var S=1,R=2;C=a("meta[name=csrf-token]").attr("content");if((b=a("meta[name=csrf-param]").attr("content"))&&C)q.extraData=q.extraData||{},q.extraData[b]=C;q.forceSync?f():setTimeout(f,10);var T,H,I=50,$,ca=a.parseXML||function(a,b){window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"); +return b&&b.documentElement&&"parsererror"!=b.documentElement.nodeName?b:null},ea=a.parseJSON||function(a){return window.eval("("+a+")")}}}}if(!this.length)return c("ajaxSubmit: skipping submit process - no element selected"),this;var e,l,n=this;"function"==typeof d&&(d={success:d});e=this.attr("method");l=this.attr("action");(l=(l="string"===typeof l?a.trim(l):"")||window.location.href||"")&&(l=(l.match(/^([^#]+)/)||[])[1]);d=a.extend(!0,{url:l,success:a.ajaxSettings.success,type:e||"GET",iframeSrc:/^https/i.test(window.location.href|| +"")?"javascript:false":"about:blank"},d);l={};this.trigger("form-pre-serialize",[this,d,l]);if(l.veto)return c("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(d.beforeSerialize&&!1===d.beforeSerialize(this,d))return c("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var p=d.traditional;void 0===p&&(p=a.ajaxSettings.traditional);var v=[],s,r=this.formToArray(d.semantic,v);d.data&&(d.extraData=d.data,s=a.param(d.data,p));if(d.beforeSubmit&&!1===d.beforeSubmit(r,this, +d))return c("ajaxSubmit: submit aborted via beforeSubmit callback"),this;this.trigger("form-submit-validate",[r,this,d,l]);if(l.veto)return c("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;l=a.param(r,p);s&&(l=l?l+"&"+s:s);"GET"==d.type.toUpperCase()?(d.url+=(0<=d.url.indexOf("?")?"&":"?")+l,d.data=null):d.data=l;var q=[];d.resetForm&&q.push(function(){n.resetForm()});d.clearForm&&q.push(function(){n.clearForm(d.includeHidden)});if(!d.dataType&&d.target){var y=d.success||function(){}; +q.push(function(b){var c=d.replaceTarget?"replaceWith":"html";a(d.target)[c](b).each(y,arguments)})}else d.success&&q.push(d.success);d.success=function(a,b,c){for(var f=d.context||d,e=0,j=q.length;en)return null;for(var d=[],j=b.options,s=(e="select-one"==e)?n+1:j.length,n=e?n:0;np)return null;for(var d=[],j=b.options,v=(e="select-one"==e)?p+1:j.length,p=e?p:0;p
    ').html('
    '));return this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(),this.options=this.$element=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}};a.fn.tipsy=function(d){function c(b){var c=a.data(b,"tipsy");c||(c=new e(b,a.fn.tipsy.elementOptions(b,d)),a.data(b, "tipsy",c));return c}function b(){var a=c(this);a.hoverState="in";0==d.delayIn?a.show():(a.fixTitle(),setTimeout(function(){"in"==a.hoverState&&a.show()},d.delayIn))}function j(){var a=c(this);a.hoverState="out";0==d.delayOut?a.hide():setTimeout(function(){"out"==a.hoverState&&a.hide()},d.delayOut)}if(!0===d)return this.data("tipsy");if("string"==typeof d){var g=this.data("tipsy");if(g)g[d]();return this}d=a.extend({},a.fn.tipsy.defaults,d);d.live||this.each(function(){c(this)});if("manual"!=d.trigger){var g= d.live?"live":"bind",f="hover"==d.trigger?"mouseleave":"blur";this[g]("hover"==d.trigger?"mouseenter":"focus",b)[g](f,j)}return this};a.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:0.8,title:"title",trigger:"hover",cssClass:""};a.fn.tipsy.elementOptions=function(d,c){return a.metadata?a.extend({},c,a(d).metadata()):c};a.fn.tipsy.autoNS=function(){return a(this).offset().top>a(document).scrollTop()+a(window).height()/2?"s": -"n"};a.fn.tipsy.autoWE=function(){return a(this).offset().left>a(document).scrollLeft()+a(window).width()/2?"e":"w"};a.fn.tipsy.autoBounds=function(d,c){return function(){var b=c[0],e=1a.browser.version.substr(0,1)&&32768").addClass("sticky-header hide");d.tableHeight=d.table.height();d.headerCellHeight=a(c[0]).height();d.init=function(){d.table=a(e);var b=d.table.find("thead").clone(!0);d.stickyHeader.append(a('
    ')).find("table").append(b);d.table.after(d.stickyHeader);d.setWidths();a(window).scroll(d.updateStickyHeader);a(window).resize(d.updateTableWidth)}; -d.setWidths=function(){var b=d.table.find("thead th");stickyHeaderCells=d.stickyHeader.find("th");d.stickyHeader.css({width:d.table.outerWidth()});for(i=0;ib&&ea(document).scrollLeft()+a(window).width()/2?"e":"w"};a.fn.tipsy.autoBounds=function(d,c){return function(){var b=c[0],e=1a.browser.version.substr(0,1)&&32768").addClass("sticky-header hide");d.headerCellHeight=a(c[0]).height();d.init=function(){d.table=a(e);var b=d.table.find("thead").clone(!0);d.stickyHeader.append(a('
    ')).find("table").append(b);d.table.after(d.stickyHeader);d.setWidths();a(window).scroll(d.updateStickyHeader);a(window).resize(d.updateTableWidth)}; +d.setWidths=function(){var b=d.table.find("thead th");stickyHeaderCells=d.stickyHeader.find("th");d.stickyHeader.css({width:d.table.outerWidth()});for(i=0;ib&&e").outerWidth(1).jquery||a.each(["Width","Height"],function(b,c){function d(b,c,e,g){return a.each(f,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0;e&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0);g&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var f="Width"===c?["Left","Right"]:["Top","Bottom"],k=c.toLowerCase(),m={innerWidth:a.fn.innerWidth, -innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+c]=function(b){return b===e?m["inner"+c].call(this):this.each(function(){a(this).css(k,d(this,b)+"px")})};a.fn["outer"+c]=function(b,f){return"number"!=typeof b?m["outer"+c].call(this,b):this.each(function(){a(this).css(k,d(this,b,!0,f)+"px")})}}),a.extend(a.expr[":"],{data:a.expr.createPseudo?a.expr.createPseudo(function(b){return function(c){return!!a.data(c,b)}}):function(b,c,d){return!!a.data(b, +".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a("").outerWidth(1).jquery||a.each(["Width","Height"],function(b,c){function d(b,c,e,g){return a.each(f,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0;e&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0);g&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var f="Width"===c?["Left","Right"]:["Top","Bottom"],k=c.toLowerCase(),l={innerWidth:a.fn.innerWidth, +innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+c]=function(b){return b===e?l["inner"+c].call(this):this.each(function(){a(this).css(k,d(this,b)+"px")})};a.fn["outer"+c]=function(b,f){return"number"!=typeof b?l["outer"+c].call(this,b):this.each(function(){a(this).css(k,d(this,b,!0,f)+"px")})}}),a.extend(a.expr[":"],{data:a.expr.createPseudo?a.expr.createPseudo(function(b){return function(c){return!!a.data(c,b)}}):function(b,c,d){return!!a.data(b, d[3])},focusable:function(b){return d(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var c=a.attr(b,"tabindex"),e=isNaN(c);return(e||0<=c)&&d(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight;a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=100===c.offsetHeight;a.support.selectstart="onselectstart"in c;b.removeChild(c).style.display="none"}),a.curCSS||(a.curCSS=a.css),a.extend(a.ui,{plugin:{add:function(b, c,d){var b=a.ui[b].prototype,f;for(f in d)b.plugins[f]=b.plugins[f]||[],b.plugins[f].push([c,d[f]])},call:function(a,c,d){if((c=a.plugins[c])&&a.element[0].parentNode)for(var f=0;fc&&ac&&a=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery); -(function(a){a.ui=a.ui||{};var e=/left|center|right/,d=/top|center|bottom/,c={},b=a.fn.position,j=a.fn.offset;a.fn.position=function(f){if(!f||!f.of)return b.apply(this,arguments);var f=a.extend({},f),g=a(f.of),j=g[0],k=(f.collision||"flip").split(" "),m=f.offset?f.offset.split(" "):[0,0],q,w,t;return 9===j.nodeType?(q=g.width(),w=g.height(),t={top:0,left:0}):j.setTimeout?(q=g.width(),w=g.height(),t={top:g.scrollTop(),left:g.scrollLeft()}):j.preventDefault?(f.at="left top",q=w=0,t={top:f.of.pageY, -left:f.of.pageX}):(q=g.outerWidth(),w=g.outerHeight(),t=g.offset()),a.each(["my","at"],function(){var a=(f[this]||"").split(" ");1===a.length&&(a=e.test(a[0])?a.concat(["center"]):d.test(a[0])?["center"].concat(a):["center","center"]);a[0]=e.test(a[0])?a[0]:"center";a[1]=d.test(a[1])?a[1]:"center";f[this]=a}),1===k.length&&(k[1]=k[0]),m[0]=parseInt(m[0],10)||0,1===m.length&&(m[1]=m[0]),m[1]=parseInt(m[1],10)||0,"right"===f.at[0]?t.left+=q:"center"===f.at[0]&&(t.left+=q/2),"bottom"===f.at[1]?t.top+= -w:"center"===f.at[1]&&(t.top+=w/2),t.left+=m[0],t.top+=m[1],this.each(function(){var b=a(this),d=b.outerWidth(),e=b.outerHeight(),g=parseInt(a.curCSS(this,"marginLeft",!0))||0,j=parseInt(a.curCSS(this,"marginTop",!0))||0,s=d+g+(parseInt(a.curCSS(this,"marginRight",!0))||0),r=e+j+(parseInt(a.curCSS(this,"marginBottom",!0))||0),P=a.extend({},t),ka;"right"===f.my[0]?P.left-=d:"center"===f.my[0]&&(P.left-=d/2);"bottom"===f.my[1]?P.top-=e:"center"===f.my[1]&&(P.top-=e/2);c.fractions||(P.left=Math.round(P.left), -P.top=Math.round(P.top));ka={left:P.left-g,top:P.top-j};a.each(["left","top"],function(b,c){a.ui.position[k[b]]&&a.ui.position[k[b]][c](P,{targetWidth:q,targetHeight:w,elemWidth:d,elemHeight:e,collisionPosition:ka,collisionWidth:s,collisionHeight:r,offset:m,my:f.my,at:f.at})});a.fn.bgiframe&&b.bgiframe();b.offset(a.extend(P,{using:f.using}))})};a.ui.position={fit:{left:function(b,c){var f=a(window),f=c.collisionPosition.left+c.collisionWidth-f.width()-f.scrollLeft();b.left=0c.collisionPosition.left?d+ e+g:0c.collisionPosition.top?d+e+g:0g})(jQuery); +!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,d={top:c.top-d.top+e,left:c.left-d.left+g};"using"in c?c.using.call(b,d):f.css(d)},a.fn.offset=function(b){var c=this[0];return!c||!c.ownerDocument?null:b?a.isFunction(b)?this.each(function(c){a(this).offset(b.call(this,c,a(this).offset()))}):this.each(function(){a.offset.setOffset(this,b)}):j.call(this)});var g=document.getElementsByTagName("body")[0],f=document.createElement("div"),k,l;k=document.createElement(g?"div":"body");l={visibility:"hidden", +width:0,height:0,border:0,margin:0,background:"none"};g&&a.extend(l,{position:"absolute",left:"-1000px",top:"-1000px"});for(var n in l)k.style[n]=l[n];k.appendChild(f);l=g||document.documentElement;l.insertBefore(k,l.firstChild);f.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";f=a(f).offset(function(a,b){return b}).offset();k.innerHTML="";l.removeChild(k);g=f.top+f.left+(g?2E3:0);c.fractions=21g})(jQuery); (function(a){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){"original"==this.options.helper&&!/^(?:r|a|f)/.test(this.element.css("position"))&& (this.element[0].style.position="relative");this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable"))return this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy(),this},_mouseCapture:function(e){var d=this.options;return this.helper||d.disabled||a(e.target).is(".ui-resizable-handle")? !1:(this.handle=this._getHandle(e),this.handle?(d.iframeFix&&a(!0===d.iframeFix?"iframe":d.iframeFix).each(function(){a('
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(a(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var d=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(), @@ -275,18 +275,18 @@ e.css("cursor")&&(d._cursor=e.css("cursor"));e.css("cursor",d.cursor)},stop:func c.scrollSensitivity&&(d.scrollParent[0].scrollTop=b=d.scrollParent[0].scrollTop-c.scrollSpeed);if(!c.axis||"y"!=c.axis)d.overflowOffset.left+d.scrollParent[0].offsetWidth-e.pageX=q&&g<=n||f>=q&&f<=n||gn)&&(b>=k&&b<=m||j>=k&&j<=m||bm);default:return!1}}; +this.element):!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});a.extend(a.ui.droppable,{version:"1.8.22"});a.ui.intersect=function(e,d,c){if(!d.offset)return!1;var b=(e.positionAbs||e.position.absolute).left,j=b+e.helperProportions.width,g=(e.positionAbs||e.position.absolute).top,f=g+e.helperProportions.height,k=d.offset.left,l=k+d.proportions.width,n=d.offset.top,p=n+d.proportions.height;switch(c){case "fit":return k<=b&&j<= +l&&n<=g&&f<=p;case "intersect":return k=n&&g<=p||f>=n&&f<=p||gp)&&(b>=k&&b<=l||j>=k&&j<=l||bl);default:return!1}}; a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,d){var c=a.ui.ddmanager.droppables[e.options.scope]||[],b=d?d.type:null,j=(e.currentItem||e.element).find(":data(droppable)").andSelf(),g=0;a:for(;gb.minWidth&&(b.minWidth=a),g>b.minHeight&&(b.minHeight=g),ea.width,m=d(a.height)&&b.minHeight&&b.minHeight>a.height;k&&(a.width=b.minWidth);m&&(a.height=b.minHeight);g&&(a.width=b.maxWidth);f&&(a.height=b.maxHeight);var q=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height,s=/sw|nw|w/.test(e),e=/nw|ne|n/.test(e);k&&s&&(a.left=q-b.minWidth);g&&s&&(a.left=q-b.maxWidth); -m&&e&&(a.top=n-b.minHeight);f&&e&&(a.top=n-b.maxHeight);b=!a.width&&!a.height;return b&&!a.left&&a.top?a.top=null:b&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c=this.helper||this.element,b=0;ba.width,l=d(a.height)&&b.minHeight&&b.minHeight>a.height;k&&(a.width=b.minWidth);l&&(a.height=b.minHeight);g&&(a.width=b.maxWidth);f&&(a.height=b.maxHeight);var n=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height,v=/sw|nw|w/.test(e),e=/nw|ne|n/.test(e);k&&v&&(a.left=n-b.minWidth);g&&v&&(a.left=n-b.maxWidth); +l&&e&&(a.top=p-b.minHeight);f&&e&&(a.top=p-b.maxHeight);b=!a.width&&!a.height;return b&&!a.left&&a.top?a.top=null:b&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c=this.helper||this.element,b=0;b'); var b=a.browser.msie&&7>a.browser.version,d=b?1:0,b=b?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+b,height:this.element.outerHeight()+b,position:"absolute",left:this.elementOffset.left-d+"px",top:this.elementOffset.top-d+"px",zIndex:++c.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b){return{width:this.originalSize.width+b}},w:function(a,b){return{left:this.originalPosition.left+b,width:this.originalSize.width- b}},n:function(a,b,d){return{top:this.originalPosition.top+d,height:this.originalSize.height-d}},s:function(a,b,d){return{height:this.originalSize.height+d}},se:function(c,b,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[c,b,d]))},sw:function(c,b,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[c,b,d]))},ne:function(c,b,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[c,b,d]))},nw:function(c,b, d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[c,b,d]))}},_propagate:function(c,b){a.ui.plugin.call(this,c,[b,this.ui()]);"resize"!=c&&this._trigger(c,b,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});a.extend(a.ui.resizable,{version:"1.8.22"});a.ui.plugin.add("resizable","alsoResize", {start:function(){var c=a(this).data("resizable").options,b=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};"object"==typeof c.alsoResize&&!c.alsoResize.parentNode?c.alsoResize.length?(c.alsoResize=c.alsoResize[0],b(c.alsoResize)):a.each(c.alsoResize,function(a){b(a)}):b(c.alsoResize)},resize:function(c,b){var d=a(this).data("resizable"),e=d.options, -f=d.originalSize,k=d.originalPosition,m={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-k.top||0,left:d.position.left-k.left||0},q=function(c,f){a(c).each(function(){var c=a(this),d=a(this).data("resizable-alsoresize"),e={},g=f&&f.length?f:c.parents(b.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(d[b]||0)+(m[b]||0);c&&0<=c&&(e[b]=c||null)});c.css(e)})};"object"==typeof e.alsoResize&&!e.alsoResize.nodeType? -a.each(e.alsoResize,function(a,b){q(a,b)}):q(e.alsoResize)},stop:function(){a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(c){var b=a(this).data("resizable"),d=b.options,e=b._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),k=f&&a.ui.hasScroll(e[0],"left")?0:b.sizeDiff.height,f={width:b.size.width-(f?0:b.sizeDiff.width),height:b.size.height-k},k=parseInt(b.element.css("left"),10)+(b.position.left-b.originalPosition.left)|| -null,m=parseInt(b.element.css("top"),10)+(b.position.top-b.originalPosition.top)||null;b.element.animate(a.extend(f,m&&k?{top:m,left:k}:{}),{duration:d.animateDuration,easing:d.animateEasing,step:function(){var f={width:parseInt(b.element.css("width"),10),height:parseInt(b.element.css("height"),10),top:parseInt(b.element.css("top"),10),left:parseInt(b.element.css("left"),10)};e&&e.length&&a(e[0]).css({width:f.width,height:f.height});b._updateCache(f);b._propagate("resize",c)}})}});a.ui.plugin.add("resizable", +f=d.originalSize,k=d.originalPosition,l={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-k.top||0,left:d.position.left-k.left||0},n=function(c,d){a(c).each(function(){var c=a(this),f=a(this).data("resizable-alsoresize"),e={},g=d&&d.length?d:c.parents(b.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(f[b]||0)+(l[b]||0);c&&0<=c&&(e[b]=c||null)});c.css(e)})};"object"==typeof e.alsoResize&&!e.alsoResize.nodeType? +a.each(e.alsoResize,function(a,b){n(a,b)}):n(e.alsoResize)},stop:function(){a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(c){var b=a(this).data("resizable"),d=b.options,e=b._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),k=f&&a.ui.hasScroll(e[0],"left")?0:b.sizeDiff.height,f={width:b.size.width-(f?0:b.sizeDiff.width),height:b.size.height-k},k=parseInt(b.element.css("left"),10)+(b.position.left-b.originalPosition.left)|| +null,l=parseInt(b.element.css("top"),10)+(b.position.top-b.originalPosition.top)||null;b.element.animate(a.extend(f,l&&k?{top:l,left:k}:{}),{duration:d.animateDuration,easing:d.animateEasing,step:function(){var d={width:parseInt(b.element.css("width"),10),height:parseInt(b.element.css("height"),10),top:parseInt(b.element.css("top"),10),left:parseInt(b.element.css("left"),10)};e&&e.length&&a(e[0]).css({width:d.width,height:d.height});b._updateCache(d);b._propagate("resize",c)}})}});a.ui.plugin.add("resizable", "containment",{start:function(){var c=a(this).data("resizable"),b=c.element,d=c.options.containment;if(b=d instanceof a?d.get(0):/parent/.test(d)?b.parent().get(0):d)if(c.containerElement=a(b),/document/.test(d)||d==document)c.containerOffset={left:0,top:0},c.containerPosition={left:0,top:0},c.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var g=a(b),f=[];a(["Top","Right","Left","Bottom"]).each(function(a, -b){f[a]=e(g.css("padding"+b))});c.containerOffset=g.offset();c.containerPosition=g.position();c.containerSize={height:g.innerHeight()-f[3],width:g.innerWidth()-f[1]};var d=c.containerOffset,k=c.containerSize.height,m=c.containerSize.width,m=a.ui.hasScroll(b,"left")?b.scrollWidth:m,k=a.ui.hasScroll(b)?b.scrollHeight:k;c.parentData={element:b,left:d.left,top:d.top,width:m,height:k}}},resize:function(c){var b=a(this).data("resizable"),d=b.options,e=b.containerOffset,f=b.position,c=b._aspectRatio||c.shiftKey, -k={top:0,left:0},m=b.containerElement;m[0]!=document&&/static/.test(m.css("position"))&&(k=e);f.left<(b._helper?e.left:0)&&(b.size.width+=b._helper?b.position.left-e.left:b.position.left-k.left,c&&(b.size.height=b.size.width/b.aspectRatio),b.position.left=d.helper?e.left:0);f.top<(b._helper?e.top:0)&&(b.size.height+=b._helper?b.position.top-e.top:b.position.top,c&&(b.size.width=b.size.height*b.aspectRatio),b.position.top=b._helper?e.top:0);b.offset.left=b.parentData.left+b.position.left;b.offset.top= +b){f[a]=e(g.css("padding"+b))});c.containerOffset=g.offset();c.containerPosition=g.position();c.containerSize={height:g.innerHeight()-f[3],width:g.innerWidth()-f[1]};var d=c.containerOffset,k=c.containerSize.height,l=c.containerSize.width,l=a.ui.hasScroll(b,"left")?b.scrollWidth:l,k=a.ui.hasScroll(b)?b.scrollHeight:k;c.parentData={element:b,left:d.left,top:d.top,width:l,height:k}}},resize:function(c){var b=a(this).data("resizable"),d=b.options,e=b.containerOffset,f=b.position,c=b._aspectRatio||c.shiftKey, +k={top:0,left:0},l=b.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=e);f.left<(b._helper?e.left:0)&&(b.size.width+=b._helper?b.position.left-e.left:b.position.left-k.left,c&&(b.size.height=b.size.width/b.aspectRatio),b.position.left=d.helper?e.left:0);f.top<(b._helper?e.top:0)&&(b.size.height+=b._helper?b.position.top-e.top:b.position.top,c&&(b.size.width=b.size.height*b.aspectRatio),b.position.top=b._helper?e.top:0);b.offset.left=b.parentData.left+b.position.left;b.offset.top= b.parentData.top+b.position.top;d=Math.abs(b.offset.left-k.left+b.sizeDiff.width);e=Math.abs((b._helper?b.offset.top-k.top:b.offset.top-e.top)+b.sizeDiff.height);f=b.containerElement.get(0)==b.element.parent().get(0);k=/relative|absolute/.test(b.containerElement.css("position"));f&&k&&(d-=b.parentData.left);d+b.size.width>=b.parentData.width&&(b.size.width=b.parentData.width-d,c&&(b.size.height=b.size.width/b.aspectRatio));e+b.size.height>=b.parentData.height&&(b.size.height=b.parentData.height-e, -c&&(b.size.width=b.size.height*b.aspectRatio))},stop:function(){var c=a(this).data("resizable"),b=c.options,d=c.containerOffset,e=c.containerPosition,f=c.containerElement,k=a(c.helper),m=k.offset(),q=k.outerWidth()-c.sizeDiff.width,k=k.outerHeight()-c.sizeDiff.height;c._helper&&!b.animate&&/relative/.test(f.css("position"))&&a(this).css({left:m.left-e.left-d.left,width:q,height:k});c._helper&&!b.animate&&/static/.test(f.css("position"))&&a(this).css({left:m.left-e.left-d.left,width:q,height:k})}}); +c&&(b.size.width=b.size.height*b.aspectRatio))},stop:function(){var c=a(this).data("resizable"),b=c.options,d=c.containerOffset,e=c.containerPosition,f=c.containerElement,k=a(c.helper),l=k.offset(),n=k.outerWidth()-c.sizeDiff.width,k=k.outerHeight()-c.sizeDiff.height;c._helper&&!b.animate&&/relative/.test(f.css("position"))&&a(this).css({left:l.left-e.left-d.left,width:n,height:k});c._helper&&!b.animate&&/static/.test(f.css("position"))&&a(this).css({left:l.left-e.left-d.left,width:n,height:k})}}); a.ui.plugin.add("resizable","ghost",{start:function(){var c=a(this).data("resizable"),b=c.options,d=c.size;c.ghost=c.originalElement.clone();c.ghost.css({opacity:0.25,display:"block",position:"relative",height:d.height,width:d.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof b.ghost?b.ghost:"");c.ghost.appendTo(c.helper)},resize:function(){var c=a(this).data("resizable");c.ghost&&c.ghost.css({position:"relative",height:c.size.height,width:c.size.width})},stop:function(){var c= -a(this).data("resizable");c.ghost&&c.helper&&c.helper.get(0).removeChild(c.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var c=a(this).data("resizable"),b=c.options,d=c.size,e=c.originalSize,f=c.originalPosition,k=c.axis;b.grid="number"==typeof b.grid?[b.grid,b.grid]:b.grid;var m=Math.round((d.width-e.width)/(b.grid[0]||1))*(b.grid[0]||1),b=Math.round((d.height-e.height)/(b.grid[1]||1))*(b.grid[1]||1);/^(se|s|e)$/.test(k)?(c.size.width=e.width+m,c.size.height=e.height+b): -/^(ne)$/.test(k)?(c.size.width=e.width+m,c.size.height=e.height+b,c.position.top=f.top-b):/^(sw)$/.test(k)?(c.size.width=e.width+m,c.size.height=e.height+b,c.position.left=f.left-m):(c.size.width=e.width+m,c.size.height=e.height+b,c.position.top=f.top-b,c.position.left=f.left-m)}});var e=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery); +a(this).data("resizable");c.ghost&&c.helper&&c.helper.get(0).removeChild(c.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var c=a(this).data("resizable"),b=c.options,d=c.size,e=c.originalSize,f=c.originalPosition,k=c.axis;b.grid="number"==typeof b.grid?[b.grid,b.grid]:b.grid;var l=Math.round((d.width-e.width)/(b.grid[0]||1))*(b.grid[0]||1),b=Math.round((d.height-e.height)/(b.grid[1]||1))*(b.grid[1]||1);/^(se|s|e)$/.test(k)?(c.size.width=e.width+l,c.size.height=e.height+b): +/^(ne)$/.test(k)?(c.size.width=e.width+l,c.size.height=e.height+b,c.position.top=f.top-b):/^(sw)$/.test(k)?(c.size.width=e.width+l,c.size.height=e.height+b,c.position.left=f.left-l):(c.size.width=e.width+l,c.size.height=e.height+b,c.position.top=f.top-b,c.position.left=f.left-l)}});var e=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery); (function(a){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var e=this;this.element.addClass("ui-selectable");this.dragged=!1;var d;this.refresh=function(){d=a(e.options.filter,e.element[0]);d.addClass("ui-selectee");d.each(function(){var c=a(this),b=c.offset();a.data(this,"selectable-item",{element:this,$element:c,left:b.left,top:b.top,right:b.left+c.outerWidth(),bottom:b.top+c.outerHeight(),startselected:!1, selected:c.hasClass("ui-selected"),selecting:c.hasClass("ui-selecting"),unselecting:c.hasClass("ui-unselecting")})})};this.refresh();this.selectees=d.addClass("ui-selectee");this._mouseInit();this.helper=a("
    ")},destroy:function(){return this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy(),this},_mouseStart:function(e){var d= this;this.opos=[e.pageX,e.pageY];if(!this.options.disabled){var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",e);a(c.appendTo).append(this.helper);this.helper.css({left:e.clientX,top:e.clientY,width:0,height:0});c.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=a.data(this,"selectable-item");b.startselected=!0;!e.metaKey&&!e.ctrlKey&&(b.$element.removeClass("ui-selected"),b.selected=!1,b.$element.addClass("ui-unselecting"), b.unselecting=!0,d._trigger("unselecting",e,{unselecting:b.element}))});a(e.target).parents().andSelf().each(function(){var b=a.data(this,"selectable-item");if(b){var c=!e.metaKey&&!e.ctrlKey||!b.$element.hasClass("ui-selected");return b.$element.removeClass(c?"ui-unselecting":"ui-selected").addClass(c?"ui-selecting":"ui-unselecting"),b.unselecting=!c,b.selecting=c,b.selected=c,c?d._trigger("selecting",e,{selecting:b.element}):d._trigger("unselecting",e,{unselecting:b.element}),!1}})}},_mouseDrag:function(e){var d= -this;this.dragged=!0;if(!this.options.disabled){var c=this.options,b=this.opos[0],j=this.opos[1],g=e.pageX,f=e.pageY;if(b>g)var k=g,g=b,b=k;j>f&&(k=f,f=j,j=k);return this.helper.css({left:b,top:j,width:g-b,height:f-j}),this.selectees.each(function(){var k=a.data(this,"selectable-item");if(k&&k.element!=d.element[0]){var q=!1;"touch"==c.tolerance?q=!(k.left>g||k.rightf||k.bottomb&&k.rightj&&k.bottomg)var k=g,g=b,b=k;j>f&&(k=f,f=j,j=k);return this.helper.css({left:b,top:j,width:g-b,height:f-j}),this.selectees.each(function(){var k=a.data(this,"selectable-item");if(k&&k.element!=d.element[0]){var n=!1;"touch"==c.tolerance?n=!(k.left>g||k.rightf||k.bottomb&&k.rightj&&k.bottoma[this.floating?"width":"height"]?b+q>k&&b+qg&&d+na[this.floating?"width":"height"]?b+n>k&&b+ng&&d+pthis.headers.index(b[0]);this.active=j?a([]):b;this._toggle(f,k,m,j,q);g.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(c.icons.headerSelected).addClass(c.icons.header); +d),j=b[0]===this.active[0];c.active=c.collapsible&&j?!1:this.headers.index(b);if(!(this.running||!c.collapsible&&j)){var g=this.active,f=b.next(),k=this.active.next(),l={options:c,newHeader:j&&c.collapsible?a([]):b,oldHeader:this.active,newContent:j&&c.collapsible?a([]):f,oldContent:k},n=this.headers.index(this.active[0])>this.headers.index(b[0]);this.active=j?a([]):b;this._toggle(f,k,l,j,n);g.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(c.icons.headerSelected).addClass(c.icons.header); j||(b.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(c.icons.header).addClass(c.icons.headerSelected),b.next().addClass("ui-accordion-content-active"))}}else if(c.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(c.icons.headerSelected).addClass(c.icons.header);this.active.next().addClass("ui-accordion-content-active");var k=this.active.next(), -m={options:c,newHeader:a([]),oldHeader:c.active,newContent:a([]),oldContent:k},f=this.active=a([]);this._toggle(f,k,m)}},_toggle:function(e,d,c,b,j){var g=this,f=g.options;g.toShow=e;g.toHide=d;g.data=c;var k=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=0===d.size()?e.size():d.size();if(f.animated){c={};f.collapsible&&b?c={toShow:a([]),toHide:d,complete:k,down:j,autoHeight:f.autoHeight||f.fillSpace}:c={toShow:e,toHide:d,complete:k,down:j, -autoHeight:f.autoHeight||f.fillSpace};f.proxied||(f.proxied=f.animated);f.proxiedDuration||(f.proxiedDuration=f.duration);f.animated=a.isFunction(f.proxied)?f.proxied(c):f.proxied;f.duration=a.isFunction(f.proxiedDuration)?f.proxiedDuration(c):f.proxiedDuration;var b=a.ui.accordion.animations,m=f.duration,q=f.animated;q&&!b[q]&&!a.easing[q]&&(q="slide");b[q]||(b[q]=function(a){this.slide(a,{easing:q,duration:m||700})});b[q](c)}else f.collapsible&&b?e.toggle():(d.hide(),e.show()),k(!0);d.prev().attr({"aria-expanded":"false", +l={options:c,newHeader:a([]),oldHeader:c.active,newContent:a([]),oldContent:k},f=this.active=a([]);this._toggle(f,k,l)}},_toggle:function(e,d,c,b,j){var g=this,f=g.options;g.toShow=e;g.toHide=d;g.data=c;var k=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=0===d.size()?e.size():d.size();if(f.animated){c={};f.collapsible&&b?c={toShow:a([]),toHide:d,complete:k,down:j,autoHeight:f.autoHeight||f.fillSpace}:c={toShow:e,toHide:d,complete:k,down:j, +autoHeight:f.autoHeight||f.fillSpace};f.proxied||(f.proxied=f.animated);f.proxiedDuration||(f.proxiedDuration=f.duration);f.animated=a.isFunction(f.proxied)?f.proxied(c):f.proxied;f.duration=a.isFunction(f.proxiedDuration)?f.proxiedDuration(c):f.proxiedDuration;var b=a.ui.accordion.animations,l=f.duration,n=f.animated;n&&!b[n]&&!a.easing[n]&&(n="slide");b[n]||(b[n]=function(a){this.slide(a,{easing:n,duration:l||700})});b[n](c)}else f.collapsible&&b?e.toggle():(d.hide(),e.show()),k(!0);d.prev().attr({"aria-expanded":"false", "aria-selected":"false",tabIndex:-1}).blur();e.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}});a.extend(a.ui.accordion,{version:"1.8.22", -animations:{slide:function(e,d){e=a.extend({easing:"swing",duration:300},e,d);if(e.toHide.size())if(e.toShow.size()){var c=e.toShow.css("overflow"),b=0,j={},g={},f,k=e.toShow;f=k[0].style.width;k.width(k.parent().width()-parseFloat(k.css("paddingLeft"))-parseFloat(k.css("paddingRight"))-(parseFloat(k.css("borderLeftWidth"))||0)-(parseFloat(k.css("borderRightWidth"))||0));a.each(["height","paddingTop","paddingBottom"],function(b,c){g[c]="hide";var f=(""+a.css(e.toShow[0],c)).match(/^([\d+-.]+)(.*)$/); -j[c]={value:f[1],unit:f[2]||"px"}});e.toShow.css({height:0,overflow:"hidden"}).show();e.toHide.filter(":hidden").each(e.complete).end().filter(":visible").animate(g,{step:function(a,c){"height"==c.prop&&(b=0===c.end-c.start?0:(c.now-c.start)/(c.end-c.start));e.toShow[0].style[c.prop]=b*j[c.prop].value+j[c.prop].unit},duration:e.duration,easing:e.easing,complete:function(){e.autoHeight||e.toShow.css("height","");e.toShow.css({width:f,overflow:c});e.complete()}})}else e.toHide.animate({height:"hide", +animations:{slide:function(e,d){e=a.extend({easing:"swing",duration:300},e,d);if(e.toHide.size())if(e.toShow.size()){var c=e.toShow.css("overflow"),b=0,j={},g={},f,k=e.toShow;f=k[0].style.width;k.width(k.parent().width()-parseFloat(k.css("paddingLeft"))-parseFloat(k.css("paddingRight"))-(parseFloat(k.css("borderLeftWidth"))||0)-(parseFloat(k.css("borderRightWidth"))||0));a.each(["height","paddingTop","paddingBottom"],function(b,c){g[c]="hide";var d=(""+a.css(e.toShow[0],c)).match(/^([\d+-.]+)(.*)$/); +j[c]={value:d[1],unit:d[2]||"px"}});e.toShow.css({height:0,overflow:"hidden"}).show();e.toHide.filter(":hidden").each(e.complete).end().filter(":visible").animate(g,{step:function(a,c){"height"==c.prop&&(b=0===c.end-c.start?0:(c.now-c.start)/(c.end-c.start));e.toShow[0].style[c.prop]=b*j[c.prop].value+j[c.prop].unit},duration:e.duration,easing:e.easing,complete:function(){e.autoHeight||e.toShow.css("height","");e.toShow.css({width:f,overflow:c});e.complete()}})}else e.toHide.animate({height:"hide", paddingTop:"hide",paddingBottom:"hide"},e);else e.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},e)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); (function(a){var e=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var d=this,c=this.element[0].ownerDocument,b;this.isMultiLine=this.element.is("textarea");this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!d.options.disabled&& !d.element.propAttr("readOnly")){b=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:d._move("previousPage",c);break;case e.PAGE_DOWN:d._move("nextPage",c);break;case e.UP:d._keyEvent("previous",c);break;case e.DOWN:d._keyEvent("next",c);break;case e.ENTER:case e.NUMPAD_ENTER:d.menu.active&&(b=!0,c.preventDefault());case e.TAB:if(!d.menu.active)break;d.menu.select(c);break;case e.ESCAPE:d.element.val(d.term);d.close(c);break;default:clearTimeout(d.searching),d.searching=setTimeout(function(){d.term!= @@ -415,8 +415,8 @@ a):this.activate(c,this.element.children(d))):this.activate(c,this.element.child this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var d=this.active.offset().top,c=this.element.height(),b=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-d+c-a(this).height();return 10>b&&-10",this.element[0].ownerDocument).addClass("ui-button-text").ht this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); a.Widget.prototype.destroy.call(this)}})})(jQuery); (function(a,e){var d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},c={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},b=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c= -a(this).css(b).offset().top;0>c&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");"string"!=typeof this.originalTitle&&(this.originalTitle="");this.options.title=this.options.title||this.originalTitle;var b=this,c=b.options,f=c.title||" ",d=a.ui.dialog.getTitleId(b.element),e=(b.uiDialog=a("
    ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ -c.dialogClass).css({zIndex:c.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(f){c.closeOnEscape&&!f.isDefaultPrevented()&&f.keyCode&&f.keyCode===a.ui.keyCode.ESCAPE&&(b.close(f),f.preventDefault())}).attr({role:"dialog","aria-labelledby":d}).mousedown(function(a){b.moveToTop(!1,a)});b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(e);var q=(b.uiDialogTitlebar=a("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(e), -n=a('
    ').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){n.addClass("ui-state-hover")},function(){n.removeClass("ui-state-hover")}).focus(function(){n.addClass("ui-state-focus")}).blur(function(){n.removeClass("ui-state-focus")}).click(function(a){return b.close(a),!1}).appendTo(q);(b.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(c.closeText).appendTo(n);a("").addClass("ui-dialog-title").attr("id", -d).html(f).prependTo(q);a.isFunction(c.beforeclose)&&!a.isFunction(c.beforeClose)&&(c.beforeClose=c.beforeclose);q.find("*").add(q).disableSelection();c.draggable&&a.fn.draggable&&b._makeDraggable();c.resizable&&a.fn.resizable&&b._makeResizable();b._createButtons(c.buttons);b._isOpen=!1;a.fn.bgiframe&&e.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){return this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"), -this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),this},widget:function(){return this.uiDialog},close:function(b){var c=this,f,d;if(!1!==c._trigger("beforeClose",b))return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(f=0,a(".ui-dialog").each(function(){this!== -c.uiDialog[0]&&(d=a(this).css("z-index"),isNaN(d)||(f=Math.max(f,d)))}),a.ui.dialog.maxZ=f),c},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var f=this.options,d;return f.modal&&!b||!f.stack&&!f.modal?this._trigger("focus",c):(f.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=f.zIndex),this.overlay&&(a.ui.dialog.maxZ+=1,this.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),d={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},a.ui.dialog.maxZ+= -1,this.uiDialog.css("z-index",a.ui.dialog.maxZ),this.element.attr(d),this._trigger("focus",c),this)},open:function(){if(!this._isOpen){var b=this.options,c=this.uiDialog;return this.overlay=b.modal?new a.ui.dialog.overlay(this):null,this._size(),this._position(b.position),c.show(b.show),this.moveToTop(!0),b.modal&&c.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),c=c.filter(":last");if(b.target===c[0]&&!b.shiftKey)return d.focus(1), -!1;if(b.target===d[0]&&b.shiftKey)return c.focus(1),!1}}),a(this.element.find(":tabbable").get().concat(c.find(".ui-dialog-buttonpane :tabbable").get().concat(c.get()))).eq(0).focus(),this._isOpen=!0,this._trigger("open"),this}},_createButtons:function(c){var d=this,f=!1,e=a("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),m=a("
    ").addClass("ui-dialog-buttonset").appendTo(e);d.uiDialog.find(".ui-dialog-buttonpane").remove();"object"==typeof c&&null!== -c&&a.each(c,function(){return!(f=!0)});f&&(a.each(c,function(c,f){var f=a.isFunction(f)?{click:f,text:c}:f,e=a('').click(function(){f.click.apply(d.element[0],arguments)}).appendTo(m);a.each(f,function(a,c){"click"!==a&&(a in b?e[a](c):e.attr(a,c))});a.fn.button&&e.button()}),e.appendTo(d.uiDialog))},_makeDraggable:function(){function b(a){return{position:a.position,offset:a.offset}}var c=this,f=c.options,d=a(document),e;c.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", -handle:".ui-dialog-titlebar",containment:"document",start:function(d,k){e="auto"===f.height?"auto":a(this).height();a(this).height(a(this).height()).addClass("ui-dialog-dragging");c._trigger("dragStart",d,b(k))},drag:function(a,f){c._trigger("drag",a,b(f))},stop:function(q,n){f.position=[n.position.left-d.scrollLeft(),n.position.top-d.scrollTop()];a(this).removeClass("ui-dialog-dragging").height(e);c._trigger("dragStop",q,b(n));a.ui.dialog.overlay.resize()}})},_makeResizable:function(b){function c(a){return{originalPosition:a.originalPosition, -originalSize:a.originalSize,position:a.position,size:a.size}}var b=b===e?this.options.resizable:b,f=this,d=f.options,m=f.uiDialog.css("position"),b="string"==typeof b?b:"n,e,s,w,se,sw,ne,nw";f.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:f.element,maxWidth:d.maxWidth,maxHeight:d.maxHeight,minWidth:d.minWidth,minHeight:f._minHeight(),handles:b,start:function(b,d){a(this).addClass("ui-dialog-resizing");f._trigger("resizeStart",b,c(d))},resize:function(a,b){f._trigger("resize", -a,c(b))},stop:function(b,e){a(this).removeClass("ui-dialog-resizing");d.height=a(this).height();d.width=a(this).width();f._trigger("resizeStop",b,c(e));a.ui.dialog.overlay.resize()}}).css("position",m).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return"auto"===a.height?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],f=[0,0],d;if(b){if("string"==typeof b||"object"==typeof b&&"0"in b)c=b.split?b.split(" "): -[b[0],b[1]],1===c.length&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(f[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:f.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;(d=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b));d||this.uiDialog.hide()},_setOptions:function(b){var e=this,f={},k=!1;a.each(b,function(a,b){e._setOption(a,b);a in -d&&(k=!0);a in c&&(f[a]=b)});k&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,c){var f=this.uiDialog;switch(b){case "beforeclose":b="beforeClose";break;case "buttons":this._createButtons(c);break;case "closeText":this.uiDialogTitlebarCloseText.text(""+c);break;case "dialogClass":f.removeClass(this.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+c);break;case "disabled":c?f.addClass("ui-dialog-disabled"): -f.removeClass("ui-dialog-disabled");break;case "draggable":var d=f.is(":data(draggable)");d&&!c&&f.draggable("destroy");!d&&c&&this._makeDraggable();break;case "position":this._position(c);break;case "resizable":(d=f.is(":data(resizable)"))&&!c&&f.resizable("destroy");d&&"string"==typeof c&&f.resizable("option","handles",c);!d&&!1!==c&&this._makeResizable(c);break;case "title":a(".ui-dialog-title",this.uiDialogTitlebar).html(""+(c||" "))}a.Widget.prototype._setOption.apply(this,arguments)},_size:function(){var b= -this.options,c,f,d=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});b.minWidth>b.width&&(b.width=b.minWidth);c=this.uiDialog.css({height:"auto",width:b.width}).height();f=Math.max(0,b.minHeight-c);"auto"===b.height?a.support.minHeight?this.element.css({minHeight:f,height:"auto"}):(this.uiDialog.show(),b=this.element.css("height","auto").height(),d||this.uiDialog.hide(),this.element.height(Math.max(b,f))):this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&& +a(this).css(b).offset().top;0>c&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");"string"!=typeof this.originalTitle&&(this.originalTitle="");this.options.title=this.options.title||this.originalTitle;var b=this,c=b.options,d=c.title||" ",e=a.ui.dialog.getTitleId(b.element),l=(b.uiDialog=a("
    ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +c.dialogClass).css({zIndex:c.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(d){c.closeOnEscape&&!d.isDefaultPrevented()&&d.keyCode&&d.keyCode===a.ui.keyCode.ESCAPE&&(b.close(d),d.preventDefault())}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(a){b.moveToTop(!1,a)});b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(l);var n=(b.uiDialogTitlebar=a("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(l), +p=a('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){p.addClass("ui-state-hover")},function(){p.removeClass("ui-state-hover")}).focus(function(){p.addClass("ui-state-focus")}).blur(function(){p.removeClass("ui-state-focus")}).click(function(a){return b.close(a),!1}).appendTo(n);(b.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(c.closeText).appendTo(p);a("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(n);a.isFunction(c.beforeclose)&&!a.isFunction(c.beforeClose)&&(c.beforeClose=c.beforeclose);n.find("*").add(n).disableSelection();c.draggable&&a.fn.draggable&&b._makeDraggable();c.resizable&&a.fn.resizable&&b._makeResizable();b._createButtons(c.buttons);b._isOpen=!1;a.fn.bgiframe&&l.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){return this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"), +this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),this},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b))return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!== +c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d),c},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this.options,e;return d.modal&&!b||!d.stack&&!d.modal?this._trigger("focus",c):(d.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=d.zIndex),this.overlay&&(a.ui.dialog.maxZ+=1,this.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),e={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},a.ui.dialog.maxZ+= +1,this.uiDialog.css("z-index",a.ui.dialog.maxZ),this.element.attr(e),this._trigger("focus",c),this)},open:function(){if(!this._isOpen){var b=this.options,c=this.uiDialog;return this.overlay=b.modal?new a.ui.dialog.overlay(this):null,this._size(),this._position(b.position),c.show(b.show),this.moveToTop(!0),b.modal&&c.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),c=c.filter(":last");if(b.target===c[0]&&!b.shiftKey)return d.focus(1), +!1;if(b.target===d[0]&&b.shiftKey)return c.focus(1),!1}}),a(this.element.find(":tabbable").get().concat(c.find(".ui-dialog-buttonpane :tabbable").get().concat(c.get()))).eq(0).focus(),this._isOpen=!0,this._trigger("open"),this}},_createButtons:function(c){var d=this,f=!1,e=a("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),l=a("
    ").addClass("ui-dialog-buttonset").appendTo(e);d.uiDialog.find(".ui-dialog-buttonpane").remove();"object"==typeof c&&null!== +c&&a.each(c,function(){return!(f=!0)});f&&(a.each(c,function(c,f){var f=a.isFunction(f)?{click:f,text:c}:f,e=a('').click(function(){f.click.apply(d.element[0],arguments)}).appendTo(l);a.each(f,function(a,c){"click"!==a&&(a in b?e[a](c):e.attr(a,c))});a.fn.button&&e.button()}),e.appendTo(d.uiDialog))},_makeDraggable:function(){function b(a){return{position:a.position,offset:a.offset}}var c=this,d=c.options,e=a(document),l;c.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", +handle:".ui-dialog-titlebar",containment:"document",start:function(e,k){l="auto"===d.height?"auto":a(this).height();a(this).height(a(this).height()).addClass("ui-dialog-dragging");c._trigger("dragStart",e,b(k))},drag:function(a,d){c._trigger("drag",a,b(d))},stop:function(n,p){d.position=[p.position.left-e.scrollLeft(),p.position.top-e.scrollTop()];a(this).removeClass("ui-dialog-dragging").height(l);c._trigger("dragStop",n,b(p));a.ui.dialog.overlay.resize()}})},_makeResizable:function(b){function c(a){return{originalPosition:a.originalPosition, +originalSize:a.originalSize,position:a.position,size:a.size}}var b=b===e?this.options.resizable:b,d=this,k=d.options,l=d.uiDialog.css("position"),b="string"==typeof b?b:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:k.maxWidth,maxHeight:k.maxHeight,minWidth:k.minWidth,minHeight:d._minHeight(),handles:b,start:function(b,e){a(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",b,c(e))},resize:function(a,b){d._trigger("resize", +a,c(b))},stop:function(b,e){a(this).removeClass("ui-dialog-resizing");k.height=a(this).height();k.width=a(this).width();d._trigger("resizeStop",b,c(e));a.ui.dialog.overlay.resize()}}).css("position",l).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return"auto"===a.height?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if("string"==typeof b||"object"==typeof b&&"0"in b)c=b.split?b.split(" "): +[b[0],b[1]],1===c.length&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b));e||this.uiDialog.hide()},_setOptions:function(b){var e=this,f={},k=!1;a.each(b,function(a,b){e._setOption(a,b);a in +d&&(k=!0);a in c&&(f[a]=b)});k&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,c){var d=this.uiDialog;switch(b){case "beforeclose":b="beforeClose";break;case "buttons":this._createButtons(c);break;case "closeText":this.uiDialogTitlebarCloseText.text(""+c);break;case "dialogClass":d.removeClass(this.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+c);break;case "disabled":c?d.addClass("ui-dialog-disabled"): +d.removeClass("ui-dialog-disabled");break;case "draggable":var e=d.is(":data(draggable)");e&&!c&&d.draggable("destroy");!e&&c&&this._makeDraggable();break;case "position":this._position(c);break;case "resizable":(e=d.is(":data(resizable)"))&&!c&&d.resizable("destroy");e&&"string"==typeof c&&d.resizable("option","handles",c);!e&&!1!==c&&this._makeResizable(c);break;case "title":a(".ui-dialog-title",this.uiDialogTitlebar).html(""+(c||" "))}a.Widget.prototype._setOption.apply(this,arguments)},_size:function(){var b= +this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});b.minWidth>b.width&&(b.width=b.minWidth);c=this.uiDialog.css({height:"auto",width:b.width}).height();d=Math.max(0,b.minHeight-c);"auto"===b.height?a.support.minHeight?this.element.css({minHeight:d,height:"auto"}):(this.uiDialog.show(),b=this.element.css("height","auto").height(),e||this.uiDialog.hide(),this.element.height(Math.max(b,d))):this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&& this.uiDialog.resizable("option","minHeight",this._minHeight())}});a.extend(a.ui.dialog,{version:"1.8.22",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");return a||(this.uuid+=1,a=this.uuid),"ui-dialog-title-"+a},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}});a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus mousedown mouseup keydown keypress click".split(" "),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){0===this.instances.length&& (setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), -height:this.height()});return a.fn.bgiframe&&c.bgiframe(),this.instances.push(c),c},destroy:function(b){var c=a.inArray(b,this.instances);-1!=c&&this.oldInstances.push(this.instances.splice(c,1)[0]);0===this.instances.length&&a([document,window]).unbind(".dialog-overlay");b.remove();var f=0;a.each(this.instances,function(){f=Math.max(f,this.css("z-index"))});this.maxZ=f},height:function(){var b,c;return a.browser.msie&&7>a.browser.version?(b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight), +height:this.height()});return a.fn.bgiframe&&c.bgiframe(),this.instances.push(c),c},destroy:function(b){var c=a.inArray(b,this.instances);-1!=c&&this.oldInstances.push(this.instances.splice(c,1)[0]);0===this.instances.length&&a([document,window]).unbind(".dialog-overlay");b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var b,c;return a.browser.msie&&7>a.browser.version?(b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight), c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),bd&&(j=d,g=a(this),k=c)}),!0===d.range&&this.values(1)===d.min&&(k+=1,g=a(this.handles[k])),m=this._start(e,k),!1===m?!1:(this._mouseSliding= -!0,f._handleIndex=k,g.addClass("ui-state-active").focus(),q=g.offset(),n=!a(e.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=n?{left:0,top:0}:{left:e.pageX-q.left-g.width()/2,top:e.pageY-q.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,k,b),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(a){var d= +_mouseCapture:function(e){var d=this.options,c,b,j,g,f,k,l,n,p;return d.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),c={x:e.pageX,y:e.pageY},b=this._normValueFromMouse(c),j=this._valueMax()-this._valueMin()+1,f=this,this.handles.each(function(c){var d=Math.abs(b-f.values(c));j>d&&(j=d,g=a(this),k=c)}),!0===d.range&&this.values(1)===d.min&&(k+=1,g=a(this.handles[k])),l=this._start(e,k),!1===l?!1:(this._mouseSliding= +!0,f._handleIndex=k,g.addClass("ui-state-active").focus(),n=g.offset(),p=!a(e.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=p?{left:0,top:0}:{left:e.pageX-n.left-g.width()/2,top:e.pageY-n.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,k,b),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(a){var d= this._normValueFromMouse({x:a.pageX,y:a.pageY});return this._slide(a,this._handleIndex,d),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(a){var d,c,b,j,g;return"horizontal"=== this.orientation?(d=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(d=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),b=c/d,1b&&(b=0),"vertical"===this.orientation&&(b=1-b),j=this._valueMax()-this._valueMin(),g=this._valueMin()+b*j,this._trimAlignValue(g)},_start:function(a,d){var c={handle:this.handles[d],value:this.value()};return this.options.values&&this.options.values.length&&(c.value= this.values(d),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,d,c){var b,j,g;this.options.values&&this.options.values.length?(b=this.values(d?0:1),2===this.options.values.length&&!0===this.options.range&&(0===d&&c>b||1===d&&c=this._valueMax())return this._valueMax();var d=0=d&&(a+=0",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(!0)},_setOption:function(a,c){"selected"==a?this.options.collapsible&&c==this.options.selected||this.select(c): (this.options[a]=c,this._tabify())},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+ ++d},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++c);return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,c){return{tab:a,panel:c,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= -a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function c(b,f){b.css("display","");!a.support.opacity&&f.opacity&&b[0].style.removeAttribute("filter")}var d=this,f=this.options,k=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(b,c){var e=a(c).attr("href"),j=e.split("#")[0],m;j&&(j===location.toString().split("#")[0]|| -(m=a("base")[0])&&j===m.href)&&(e=c.hash,c.href=e);k.test(e)?d.panels=d.panels.add(d.element.find(d._sanitizeSelector(e))):e&&"#"!==e?(a.data(c,"href.tabs",e),a.data(c,"load.tabs",e.replace(/#.*$/,"")),e=d._tabId(c),c.href="#"+e,j=d.element.find("#"+e),j.length||(j=a(f.panelTemplate).attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),j.data("destroy.tabs",!0)),d.panels=d.panels.add(j)):f.disabled.push(b)});b?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"), +a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function c(b,d){b.css("display","");!a.support.opacity&&d.opacity&&b[0].style.removeAttribute("filter")}var d=this,f=this.options,k=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(b,c){var e=a(c).attr("href"),j=e.split("#")[0],l;j&&(j===location.toString().split("#")[0]|| +(l=a("base")[0])&&j===l.href)&&(e=c.hash,c.href=e);k.test(e)?d.panels=d.panels.add(d.element.find(d._sanitizeSelector(e))):e&&"#"!==e?(a.data(c,"href.tabs",e),a.data(c,"load.tabs",e.replace(/#.*$/,"")),e=d._tabId(c),c.href="#"+e,j=d.element.find("#"+e),j.length||(j=a(f.panelTemplate).attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),j.data("destroy.tabs",!0)),d.panels=d.panels.add(j)):f.disabled.push(b)});b?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"), this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),f.selected===e?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash)return f.selected=a,!1}),"number"!=typeof f.selected&&f.cookie&&(f.selected=parseInt(d._cookie(),10)),"number"!=typeof f.selected&&this.lis.filter(".ui-tabs-selected").length&&(f.selected= this.lis.index(this.lis.filter(".ui-tabs-selected"))),f.selected=f.selected||(this.lis.length?0:-1)):null===f.selected&&(f.selected=-1),f.selected=0<=f.selected&&this.anchors[f.selected]||0>f.selected?f.selected:0,f.disabled=a.unique(f.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a){return d.lis.index(a)}))).sort(),-1!=a.inArray(f.selected,f.disabled)&&f.disabled.splice(a.inArray(f.selected,f.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"), 0<=f.selected&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[f.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(f.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[f.selected],d.element.find(d._sanitizeSelector(d.anchors[f.selected].hash))[0]))}),this.load(f.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs");d.lis=d.anchors=d.panels=null})):f.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); -this.element[f.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");f.cookie&&this._cookie(f.selected,f.cookie);for(var b=0,m;m=this.lis[b];b++)a(m)[-1!=a.inArray(b,f.disabled)&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");!1===f.cache&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if("mouseover"!==f.event){var q=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)};this.lis.bind("mouseover.tabs", -function(){q("hover",a(this))});this.lis.bind("mouseout.tabs",function(){a(this).removeClass("ui-state-hover")});this.anchors.bind("focus.tabs",function(){q("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){a(this).closest("li").removeClass("ui-state-focus")})}var n,s;f.fx&&(a.isArray(f.fx)?(n=f.fx[0],s=f.fx[1]):n=s=f.fx);var r=s?function(b,f){a(b).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(s,s.duration||"normal", -function(){c(f,s);d._trigger("show",null,d._ui(b,f[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active");c.removeClass("ui-tabs-hide");d._trigger("show",null,d._ui(b,c[0]))},u=n?function(a,b){b.animate(n,n.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active");b.addClass("ui-tabs-hide");c(b,n);d.element.dequeue("tabs")})}:function(a,b){d.lis.removeClass("ui-tabs-selected ui-state-active");b.addClass("ui-tabs-hide");d.element.dequeue("tabs")}; +this.element[f.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");f.cookie&&this._cookie(f.selected,f.cookie);for(var b=0,l;l=this.lis[b];b++)a(l)[-1!=a.inArray(b,f.disabled)&&!a(l).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");!1===f.cache&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if("mouseover"!==f.event){var n=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)};this.lis.bind("mouseover.tabs", +function(){n("hover",a(this))});this.lis.bind("mouseout.tabs",function(){a(this).removeClass("ui-state-hover")});this.anchors.bind("focus.tabs",function(){n("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){a(this).closest("li").removeClass("ui-state-focus")})}var p,v;f.fx&&(a.isArray(f.fx)?(p=f.fx[0],v=f.fx[1]):p=v=f.fx);var s=v?function(b,f){a(b).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(v,v.duration||"normal", +function(){c(f,v);d._trigger("show",null,d._ui(b,f[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active");c.removeClass("ui-tabs-hide");d._trigger("show",null,d._ui(b,c[0]))},r=p?function(a,b){b.animate(p,p.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active");b.addClass("ui-tabs-hide");c(b,p);d.element.dequeue("tabs")})}:function(a,b){d.lis.removeClass("ui-tabs-selected ui-state-active");b.addClass("ui-tabs-hide");d.element.dequeue("tabs")}; this.anchors.bind(f.event+".tabs",function(){var b=this,c=a(b).closest("li"),e=d.panels.filter(":not(.ui-tabs-hide)"),k=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!f.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||!1===d._trigger("select",null,d._ui(this,k[0])))return this.blur(),!1;f.selected=d.anchors.index(this);d.abort();if(f.collapsible){if(c.hasClass("ui-tabs-selected"))return f.selected= --1,f.cookie&&d._cookie(f.selected,f.cookie),d.element.queue("tabs",function(){u(b,e)}).dequeue("tabs"),this.blur(),!1;if(!e.length)return f.cookie&&d._cookie(f.selected,f.cookie),d.element.queue("tabs",function(){r(b,k)}),d.load(d.anchors.index(this)),this.blur(),!1}f.cookie&&d._cookie(f.selected,f.cookie);if(k.length)e.length&&d.element.queue("tabs",function(){u(b,e)}),d.element.queue("tabs",function(){r(b,k)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier."; +-1,f.cookie&&d._cookie(f.selected,f.cookie),d.element.queue("tabs",function(){r(b,e)}).dequeue("tabs"),this.blur(),!1;if(!e.length)return f.cookie&&d._cookie(f.selected,f.cookie),d.element.queue("tabs",function(){s(b,k)}),d.load(d.anchors.index(this)),this.blur(),!1}f.cookie&&d._cookie(f.selected,f.cookie);if(k.length)e.length&&d.element.queue("tabs",function(){r(b,e)}),d.element.queue("tabs",function(){s(b,k)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier."; a.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){return"string"==typeof a&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},destroy:function(){var b=this.options;return this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b= a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")}),b.cookie&&this._cookie(null,b.cookie),this},add:function(b, -c,d){d===e&&(d=this.anchors.length);var f=this,k=this.options,c=a(k.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,c)),b=b.indexOf("#")?this._tabId(a("a",c)[0]):b.replace("#","");c.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var m=f.element.find("#"+b);return m.length||(m=a(k.panelTemplate).attr("id",b).data("destroy.tabs",!0)),m.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),d>=this.lis.length?(c.appendTo(this.list),m.appendTo(this.list[0].parentNode)): -(c.insertBefore(this.lis[d]),m.insertBefore(this.panels[d])),k.disabled=a.map(k.disabled,function(a){return a>=d?++a:a}),this._tabify(),1==this.anchors.length&&(k.selected=0,c.addClass("ui-tabs-selected ui-state-active"),m.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[d],this.panels[d])),this},remove:function(b){var b=this._getIndex(b),c=this.options,d=this.lis.eq(b).remove(), +c,d){d===e&&(d=this.anchors.length);var f=this,k=this.options,c=a(k.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,c)),b=b.indexOf("#")?this._tabId(a("a",c)[0]):b.replace("#","");c.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var l=f.element.find("#"+b);return l.length||(l=a(k.panelTemplate).attr("id",b).data("destroy.tabs",!0)),l.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),d>=this.lis.length?(c.appendTo(this.list),l.appendTo(this.list[0].parentNode)): +(c.insertBefore(this.lis[d]),l.insertBefore(this.panels[d])),k.disabled=a.map(k.disabled,function(a){return a>=d?++a:a}),this._tabify(),1==this.anchors.length&&(k.selected=0,c.addClass("ui-tabs-selected ui-state-active"),l.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[d],this.panels[d])),this},remove:function(b){var b=this._getIndex(b),c=this.options,d=this.lis.eq(b).remove(), f=this.panels.eq(b).remove();return d.hasClass("ui-tabs-selected")&&1=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],f[0])),this},enable:function(b){var b=this._getIndex(b),c=this.options;if(-1!=a.inArray(b,c.disabled))return this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a){return a!= b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b])),this},disable:function(a){var a=this._getIndex(a),c=this.options;return a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))),this},select:function(a){a=this._getIndex(a);if(-1==a)if(this.options.collapsible&&-1!=this.options.selected)a=this.options.selected;else return this;return this.anchors.eq(a).trigger(this.options.event+ -".tabs"),this},load:function(b){var b=this._getIndex(b),c=this,d=this.options,f=this.anchors.eq(b)[0],e=a.data(f,"load.tabs");this.abort();if(!e||0!==this.element.queue("tabs").length&&a.data(f,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var m=a("span",f);m.data("label.tabs",m.html()).html(d.spinner)}return this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:e,success:function(e,k){c.element.find(c._sanitizeSelector(f.hash)).html(e);c._cleanup(); -d.cache&&a.data(f,"cache.tabs",!0);c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(e,k)}catch(m){}},error:function(a,e){c._cleanup();c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,e,b,f)}catch(k){}}})),c.element.dequeue("tabs"),this}},abort:function(){return this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup(), -this},url:function(a,c){return this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",c),this},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.8.22"});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,c){var d=this,f=this.options,e=d._rotate||(d._rotate=function(c){clearTimeout(d.rotation);d.rotation=setTimeout(function(){var a=f.selected;d.select(++a'))}function c(b){return b.bind("mouseout",function(b){b=a(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"); b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){c=a(c.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!a.datepicker._isDisabledDatepicker(g.inline?b.parent()[0]:g.input[0])&&c.length)c.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),c.addClass("ui-state-hover"),c.hasClass("ui-datepicker-prev")&&c.addClass("ui-datepicker-prev-hover"),c.hasClass("ui-datepicker-next")&& c.addClass("ui-datepicker-next-hover")})}function b(b,c){a.extend(b,c);for(var d in c)if(null==c[d]||c[d]==e)b[d]=c[d];return b}a.extend(a.ui,{datepicker:{version:"1.8.22"}});var j=(new Date).getTime(),g;a.extend(d.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){return b(this._defaults,a||{}),this},_attachDatepicker:function(b,c){var d=null,e;for(e in this._defaults){var g= -b.getAttribute("date:"+e);if(g){d=d||{};try{d[e]=eval(g)}catch(j){d[e]=g}}}e=b.nodeName.toLowerCase();g="div"==e||"span"==e;b.id||(this.uuid+=1,b.id="dp"+this.uuid);var r=this._newInst(a(b),g);r.settings=a.extend({},c||{},d||{});"input"==e?this._connectDatepicker(b,r):g&&this._inlineDatepicker(b,r)},_newInst:function(b,d){return{id:b[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:b,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:d,dpDiv:d?c(a('
    ')):this.dpDiv}},_connectDatepicker:function(b,c){var d=a(b);c.append=a([]);c.trigger=a([]);d.hasClass(this.markerClassName)||(this._attachments(d,c),d.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,b,d){c.settings[b]=d}).bind("getData.datepicker",function(a,b){return this._get(c,b)}),this._autoSize(c),a.data(b,"datepicker", c),c.settings.disabled&&this._disableDatepicker(b))},_attachments:function(b,c){var d=this._get(c,"appendText"),e=this._get(c,"isRTL");c.append&&c.append.remove();d&&(c.append=a(''+d+""),b[e?"before":"after"](c.append));b.unbind("focus",this._showDatepicker);c.trigger&&c.trigger.remove();d=this._get(c,"showOn");("focus"==d||"both"==d)&&b.focus(this._showDatepicker);if("button"==d||"both"==d){var d=this._get(c,"buttonText"),g=this._get(c,"buttonImage");c.trigger= a(this._get(c,"buttonImageOnly")?a("").addClass(this._triggerClass).attr({src:g,alt:d,title:d}):a('').addClass(this._triggerClass).html(""==g?d:a("").attr({src:g,alt:d,title:d})));b[e?"before":"after"](c.trigger);c.trigger.click(function(){return a.datepicker._datepickerShowing&&a.datepicker._lastInput==b[0]?a.datepicker._hideDatepicker():a.datepicker._datepickerShowing&&a.datepicker._lastInput!=b[0]?(a.datepicker._hideDatepicker(),a.datepicker._showDatepicker(b[0])): @@ -508,8 +508,8 @@ document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document. b.nodeName.toLowerCase();a.removeData(b,"datepicker");"input"==e?(d.append.remove(),d.trigger.remove(),c.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"==e||"span"==e)&&c.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(b){var c=a(b),d=a.data(b,"datepicker");if(c.hasClass(this.markerClassName)){var e=b.nodeName.toLowerCase();if("input"==e)b.disabled= !1,d.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass),c.children().removeClass("ui-state-disabled"),c.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled");this._disabledInputs=a.map(this._disabledInputs,function(a){return a==b?null:a})}},_disableDatepicker:function(b){var c=a(b),d=a.data(b,"datepicker");if(c.hasClass(this.markerClassName)){var e= b.nodeName.toLowerCase();if("input"==e)b.disabled=!0,d.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass),c.children().addClass("ui-state-disabled"),c.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled");this._disabledInputs=a.map(this._disabledInputs,function(a){return a==b?null:a});this._disabledInputs[this._disabledInputs.length]= -b}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;bu&&u>e?Math.abs(c.left+e-u):0),c.top-=Math.min(c.top,c.top+g>p&&p>g?Math.abs(g+r):0),c},_findPos:function(b){for(var c=this._getInst(b),c=this._get(c, +b.input.focus();if(b.yearshtml){var e=b.yearshtml;setTimeout(function(){e===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml);e=b.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(b,c,d){var e=b.dpDiv.outerWidth(),g=b.dpDiv.outerHeight(),j=b.input?b.input.outerWidth():0,s=b.input?b.input.outerHeight(): +0,r=document.documentElement.clientWidth+(d?0:a(document).scrollLeft()),q=document.documentElement.clientHeight+(d?0:a(document).scrollTop());return c.left-=this._get(b,"isRTL")?e-j:0,c.left-=d&&c.left==b.input.offset().left?a(document).scrollLeft():0,c.top-=d&&c.top==b.input.offset().top+s?a(document).scrollTop():0,c.left-=Math.min(c.left,c.left+e>r&&r>e?Math.abs(c.left+e-r):0),c.top-=Math.min(c.top,c.top+g>q&&q>g?Math.abs(g+s):0),c},_findPos:function(b){for(var c=this._getInst(b),c=this._get(c, "isRTL");b&&("hidden"==b.type||1!=b.nodeType||a.expr.filters.hidden(b));)b=b[c?"previousSibling":"nextSibling"];b=a(b).offset();return[b.left,b.top]},_hideDatepicker:function(b){var c=this._curInst;if(c&&!(b&&c!=a.data(b,"datepicker"))&&this._datepickerShowing){var b=this._get(c,"showAnim"),d=this._get(c,"duration"),e=function(){a.datepicker._tidyDialog(c)};a.effects&&a.effects[b]?c.dpDiv.hide(b,a.datepicker._get(c,"showOptions"),d,e):c.dpDiv["slideDown"==b?"slideUp":"fadeIn"==b?"fadeOut":"hide"](b? d:null,e);b||e();this._datepickerShowing=!1;(b=this._get(c,"onClose"))&&b.apply(c.input?c.input[0]:null,[c.input?c.input.val():"",c]);this._lastInput=null;this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),a.blockUI&&(a.unblockUI(),a("body").append(this.dpDiv)));this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(b){if(a.datepicker._curInst){var b=a(b.target),c=a.datepicker._getInst(b[0]); (b[0].id!=a.datepicker._mainDivId&&0==b.parents("#"+a.datepicker._mainDivId).length&&!b.hasClass(a.datepicker.markerClassName)&&!b.closest("."+a.datepicker._triggerClass).length&&a.datepicker._datepickerShowing&&(!a.datepicker._inDialog||!a.blockUI)||b.hasClass(a.datepicker.markerClassName)&&a.datepicker._curInst!=c)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,c,d){var b=a(b),e=this._getInst(b[0]);this._isDisabledDatepicker(b[0])||(this._adjustInstDate(e,c+("M"==d?this._get(e,"showCurrentAtPos"): @@ -530,33 +530,33 @@ d:null,e);b||e();this._datepickerShowing=!1;(b=this._get(c,"onClose"))&&b.apply( d?"Month":"Year")]=e["draw"+("M"==d?"Month":"Year")]=parseInt(c.options[c.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(b)},_selectDay:function(b,c,d,e){var g=a(b);!a(e).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(g[0])&&(g=this._getInst(g[0]),g.selectedDay=g.currentDay=a("a",e).html(),g.selectedMonth=g.currentMonth=c,g.selectedYear=g.currentYear=d,this._selectDate(b,this._formatDate(g,g.currentDay,g.currentMonth,g.currentYear)))},_clearDate:function(b){b=a(b); this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(b,c){var d=a(b),d=this._getInst(d[0]),c=null!=c?c:this._formatDate(d);d.input&&d.input.val(c);this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[c,d]):d.input&&d.input.trigger("change");d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],"object"!=typeof d.input[0]&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(b){var c=this._get(b,"altField"); if(c){var d=this._get(b,"altFormat")||this._get(b,"dateFormat"),e=this._getDate(b),g=this.formatDate(d,e,this._getFormatConfig(b));a(c).each(function(){a(this).val(g)})}},noWeekends:function(a){a=a.getDay();return[0a,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();return a.setMonth(0),a.setDate(1),Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(b,c,d){if(null==b||null==c)throw"Invalid arguments";c="object"==typeof c? -c.toString():c+"";if(""==c)return null;for(var e=(d?d.shortYearCutoff:null)||this._defaults.shortYearCutoff,e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),g=(d?d.dayNamesShort:null)||this._defaults.dayNamesShort,j=(d?d.dayNames:null)||this._defaults.dayNames,r=(d?d.monthNamesShort:null)||this._defaults.monthNamesShort,u=(d?d.monthNames:null)||this._defaults.monthNames,p=d=-1,y=-1,w=-1,t=!1,A=function(a){a=U+1d&&(d+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d<=e?0:-100));if(-1b.getYear()%100?"0":"")+b.getYear()%100;break;case "@":p+=b.getTime();break;case "!":p+=1E4*b.getTime()+this._ticksTo1970;break;case "'":j("'")?p+="'":y=!0;break;default:p+=a.charAt(w)}return p},_possibleChars:function(a){for(var b="",c=!1,d=function(b){b=e+1d&&(d+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d<=e?0:-100));if(-1b.getYear()%100?"0":"")+b.getYear()%100;break;case "@":q+=b.getTime();break;case "!":q+=1E4*b.getTime()+this._ticksTo1970;break;case "'":j("'")?q+="'":y=!0;break;default:q+=a.charAt(u)}return q},_possibleChars:function(a){for(var b="",c=!1,d=function(b){b=e+1u&&(u+=12,C--);if(A)for(var B=this._daylightSavingAdjust(new Date(A.getFullYear(),A.getMonth()-r[0]*r[1]+1,A.getDate())),B=t&&BB;)u--,0>u&&(u=11,C--);b.drawMonth=u;b.drawYear=C;var B=this._get(b,"prevText"),B=j?this.formatDate(B,this._daylightSavingAdjust(new Date(C, -u-p,1)),this._getFormatConfig(b)):B,B=this._canAdjustMonth(b,-1,C,u)?''+B+"":g?"":''+B+"",L=this._get(b,"nextText"),L=j?this.formatDate(L,this._daylightSavingAdjust(new Date(C,u+p,1)), -this._getFormatConfig(b)):L,g=this._canAdjustMonth(b,1,C,u)?''+L+"":g?"":''+L+"",p=this._get(b,"currentText"),L=this._get(b,"gotoCurrent")&&b.currentDay?w:c,p=j?this.formatDate(p,L,this._getFormatConfig(b)): -p,j=b.inline?"":'",e=e?'
    '+(d?j:"")+(this._isInRange(b,L)?'":"")+(d?"":j)+"
    ":"",j=parseInt(this._get(b,"firstDay"), -10),j=isNaN(j)?0:j,p=this._get(b,"showWeek"),L=this._get(b,"dayNames");this._get(b,"dayNamesShort");var D=this._get(b,"dayNamesMin"),U=this._get(b,"monthNames"),K=this._get(b,"monthNamesShort"),P=this._get(b,"beforeShowDay"),ka=this._get(b,"showOtherMonths"),Y=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var ta=this._getDefaultDate(b),la="",oa=0;oa'+(/all|left/.test(M)&&0==oa?d?g:B:"")+(/all|right/.test(M)&&0==oa?d?B:g:"")+this._generateMonthYearHeader(b,u,C,t,A,0'),H=p?'":"",M=0;7>M;M++)var J=(M+j)%7,H=H+("'+D[J]+"");N+=H+"";H=this._getDaysInMonth(C,u);C==b.selectedYear&&u==b.selectedMonth&&(b.selectedDay=Math.min(b.selectedDay,H));M=(this._getFirstDayOfMonth(C,u)-j+7)%7;H=Math.ceil((M+H)/7);this.maxRows=H=y?this.maxRows> -H?this.maxRows:H:H;for(var J=this._daylightSavingAdjust(new Date(C,u,1-M)),$=0;$",ua=p?'":"",M=0;7>M;M++){var pa=P?P.apply(b.input?b.input[0]:null,[J]):[!0,""],ma=J.getMonth()!=u,za=ma&&!Y||!pa[0]||t&&JA,ua=ua+('");J.setDate(J.getDate()+1);J=this._daylightSavingAdjust(J)}N+=ua+""}u++;11
    '+this._get(b,"weekHeader")+"
    '+this._get(b,"calculateWeek")(J)+""+(ma&&!ka?" ":za?''+J.getDate()+"":''+J.getDate()+"")+"
    "+(y?""+(0':""):"");ia+=N}la+=ia}return la+=e+(a.browser.msie&&7>parseInt(a.browser.version,10)&&!b.inline?'': -""),b._keyEvent=!1,la},_generateMonthYearHeader:function(a,b,c,d,e,g,j,u){var p=this._get(a,"changeMonth"),y=this._get(a,"changeYear"),w=this._get(a,"showMonthAfterYear"),t='
    ',A="";if(g||!p)A+=''+j[b]+"";else{for(var j=d&&d.getFullYear()==c,C=e&&e.getFullYear()==c,A=A+'"}w||(t+=A+(g||!p||!y?" ":""));if(!a.yearshtml)if(a.yearshtml="",g||!y)t+=''+c+"";else{var u=this._get(a,"yearRange").split(":"),L=(new Date).getFullYear(),j=function(a){a=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?L+parseInt(a,10):parseInt(a,10);return isNaN(a)?L:a},b=j(u[0]),u=Math.max(b,j(u[1]||"")),b=d?Math.max(b,d.getFullYear()):b,u=e?Math.min(u,e.getFullYear()): -u;for(a.yearshtml+='";t+=a.yearshtml;a.yearshtml=null}return t+=this._get(a,"yearSuffix"),w&&(t+=(g||!p||!y?" ":"")+A),t+="
    ",t},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"==c?b:0),e=a.drawMonth+("M"==c?b:0),b=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"==c?b:0),d=this._restrictMinMax(a, +this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+j].datepicker._selectMonthYear(d,this,"Y"),!1}}[this.getAttribute("data-handler")])})},_generateHTML:function(b){var c=new Date,c=this._daylightSavingAdjust(new Date(c.getFullYear(),c.getMonth(),c.getDate())),d=this._get(b,"isRTL"),e=this._get(b,"showButtonPanel"),g=this._get(b,"hideIfNoPrevNext"),j=this._get(b,"navigationAsDateFormat"),s=this._getNumberOfMonths(b),r=this._get(b,"showCurrentAtPos"),q=this._get(b,"stepMonths"),y=1!=s[0]|| +1!=s[1],u=this._daylightSavingAdjust(b.currentDay?new Date(b.currentYear,b.currentMonth,b.currentDay):new Date(9999,9,9)),t=this._getMinMaxDate(b,"min"),C=this._getMinMaxDate(b,"max"),r=b.drawMonth-r,B=b.drawYear;0>r&&(r+=12,B--);if(C)for(var A=this._daylightSavingAdjust(new Date(C.getFullYear(),C.getMonth()-s[0]*s[1]+1,C.getDate())),A=t&&AA;)r--,0>r&&(r=11,B--);b.drawMonth=r;b.drawYear=B;var A=this._get(b,"prevText"),A=j?this.formatDate(A,this._daylightSavingAdjust(new Date(B, +r-q,1)),this._getFormatConfig(b)):A,A=this._canAdjustMonth(b,-1,B,r)?''+A+"":g?"":''+A+"",N=this._get(b,"nextText"),N=j?this.formatDate(N,this._daylightSavingAdjust(new Date(B,r+q,1)), +this._getFormatConfig(b)):N,g=this._canAdjustMonth(b,1,B,r)?''+N+"":g?"":''+N+"",q=this._get(b,"currentText"),N=this._get(b,"gotoCurrent")&&b.currentDay?u:c,q=j?this.formatDate(q,N,this._getFormatConfig(b)): +q,j=b.inline?"":'",e=e?'
    '+(d?j:"")+(this._isInRange(b,N)?'":"")+(d?"":j)+"
    ":"",j=parseInt(this._get(b,"firstDay"), +10),j=isNaN(j)?0:j,q=this._get(b,"showWeek"),N=this._get(b,"dayNames");this._get(b,"dayNamesShort");var D=this._get(b,"dayNamesMin"),X=this._get(b,"monthNames"),G=this._get(b,"monthNamesShort"),K=this._get(b,"beforeShowDay"),O=this._get(b,"showOtherMonths"),L=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var U=this._getDefaultDate(b),Q="",M=0;M'+(/all|left/.test(R)&&0==M?d?g:A:"")+(/all|right/.test(R)&&0==M?d?A:g:"")+this._generateMonthYearHeader(b,r,B,t,C,0'),H=q?'":"",R=0;7>R;R++)var I=(R+j)%7,H=H+("'+D[I]+"");T+=H+"";H=this._getDaysInMonth(B,r);B==b.selectedYear&&r==b.selectedMonth&&(b.selectedDay=Math.min(b.selectedDay,H));R=(this._getFirstDayOfMonth(B,r)-j+7)%7;H=Math.ceil((R+H)/7);this.maxRows=H=y?this.maxRows> +H?this.maxRows:H:H;for(var I=this._daylightSavingAdjust(new Date(B,r,1-R)),$=0;$",ca=q?'":"",R=0;7>R;R++){var ea=K?K.apply(b.input?b.input[0]:null,[I]):[!0,""],la=I.getMonth()!=r,ba=la&&!L||!ea[0]||t&&IC,ca=ca+('");I.setDate(I.getDate()+1);I=this._daylightSavingAdjust(I)}T+=ca+""}r++;11
    '+this._get(b,"weekHeader")+"
    '+this._get(b,"calculateWeek")(I)+""+(la&&!O?" ":ba?''+I.getDate()+"":''+I.getDate()+"")+"
    "+(y?""+(0':""):"");V+=T}Q+=V}return Q+=e+(a.browser.msie&&7>parseInt(a.browser.version,10)&&!b.inline?'': +""),b._keyEvent=!1,Q},_generateMonthYearHeader:function(a,b,c,d,e,g,j,r){var q=this._get(a,"changeMonth"),y=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),t='
    ',C="";if(g||!q)C+=''+j[b]+"";else{for(var j=d&&d.getFullYear()==c,B=e&&e.getFullYear()==c,C=C+'"}u||(t+=C+(g||!q||!y?" ":""));if(!a.yearshtml)if(a.yearshtml="",g||!y)t+=''+c+"";else{var r=this._get(a,"yearRange").split(":"),N=(new Date).getFullYear(),j=function(a){a=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?N+parseInt(a,10):parseInt(a,10);return isNaN(a)?N:a},b=j(r[0]),r=Math.max(b,j(r[1]||"")),b=d?Math.max(b,d.getFullYear()):b,r=e?Math.min(r,e.getFullYear()): +r;for(a.yearshtml+='";t+=a.yearshtml;a.yearshtml=null}return t+=this._get(a,"yearSuffix"),u&&(t+=(g||!q||!y?" ":"")+C),t+="
    ",t},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"==c?b:0),e=a.drawMonth+("M"==c?b:0),b=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"==c?b:0),d=this._restrictMinMax(a, this._daylightSavingAdjust(new Date(d,e,b)));a.selectedDay=d.getDate();a.drawMonth=a.selectedMonth=d.getMonth();a.drawYear=a.selectedYear=d.getFullYear();("M"==c||"Y"==c)&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),c=c&&bd?d:c,c},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a, "numberOfMonths");return null==a?[1,1]:"number"==typeof a?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),c=this._daylightSavingAdjust(new Date(c,d+(0>b?b:e[0]*e[1]),1));return 0>b&&c.setDate(this._getDaysInMonth(c.getFullYear(), c.getMonth())),this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b="string"!=typeof b?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a, @@ -568,12 +568,12 @@ this.valueDiv.remove();a.Widget.prototype.destroy.apply(this,arguments)},value:f this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change"));this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});a.extend(a.ui.progressbar,{version:"1.8.22"})})(jQuery); jQuery.effects||function(a,e){function d(b){var c;return b&&b.constructor==Array&&3==b.length?b:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))?[2.55*parseFloat(c[1]),2.55*parseFloat(c[2]),2.55*parseFloat(c[3])]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))?[parseInt(c[1],16),parseInt(c[2], 16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:/rgba\(0, 0, 0, 0\)/.exec(b)?k.transparent:k[a.trim(b).toLowerCase()]}function c(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]])for(var e=a.length;e--;)c=a[e],"string"==typeof a[c]&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c]);else for(c in a)"string"== -typeof a[c]&&(b[c]=a[c]);return b}function b(b){var c,d;for(c in b)d=b[c],(null==d||a.isFunction(d)||c in q||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function g(b,c,d,e){"object"==typeof b&&(e=c,d=null,c=b,b=c.effect);a.isFunction(c)&&(e=c,d=null,c={});if("number"==typeof c||a.fx.speeds[c])e=d,d=c,c={};return a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:"number"== +typeof a[c]&&(b[c]=a[c]);return b}function b(b){var c,d;for(c in b)d=b[c],(null==d||a.isFunction(d)||c in n||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function g(b,c,d,e){"object"==typeof b&&(e=c,d=null,c=b,b=c.effect);a.isFunction(c)&&(e=c,d=null,c={});if("number"==typeof c||a.fx.speeds[c])e=d,d=c,c={};return a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:"number"== typeof d?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete,[b,c,d,e]}function f(b){return!b||"number"==typeof b||a.fx.speeds[b]?!0:"string"==typeof b&&!a.effects[b]?!0:!1}a.effects={};a.each("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor borderColor color outlineColor".split(" "),function(b,c){a.fx.step[c]=function(b){if(!b.colorInit){var e;e=b.elem;var f=c,g;do{g=(a.curCSS||a.css)(e,f);if(""!=g&&"transparent"!=g||a.nodeName(e,"body"))break; f="backgroundColor"}while(e=e.parentNode);e=d(g);b.start=e;b.end=d(b.end);b.colorInit=!0}b.elem.style[c]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var k={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0, 0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0, -255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},m=["add","remove","toggle"],q={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(d,e,f,g){return a.isFunction(f)&&(g=f,f=null),this.queue(function(){var k= -a(this),q=k.attr("style")||" ",w=b(c.call(this)),t,A=k.attr("class")||"";a.each(m,function(a,b){d[b]&&k[b+"Class"](d[b])});t=b(c.call(this));k.attr("class",A);k.animate(j(w,t),{queue:!1,duration:e,easing:f,complete:function(){a.each(m,function(a,b){d[b]&&k[b+"Class"](d[b])});"object"==typeof k.attr("style")?(k.attr("style").cssText="",k.attr("style").cssText=q):k.attr("style",q);g&&g.apply(this,arguments);a.dequeue(this)}})})};a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c? +255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},l=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(d,e,f,g){return a.isFunction(f)&&(g=f,f=null),this.queue(function(){var k= +a(this),y=k.attr("style")||" ",u=b(c.call(this)),t,n=k.attr("class")||"";a.each(l,function(a,b){d[b]&&k[b+"Class"](d[b])});t=b(c.call(this));k.attr("class",n);k.animate(j(u,t),{queue:!1,duration:e,easing:f,complete:function(){a.each(l,function(a,b){d[b]&&k[b+"Class"](d[b])});"object"==typeof k.attr("style")?(k.attr("style").cssText="",k.attr("style").cssText=y):k.attr("style",y);g&&g.apply(this,arguments);a.dequeue(this)}})})};a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c? a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(b,c,d,f,g){return"boolean"==typeof c||c===e?d?a.effects.animateClass.apply(this,[c?{add:b}:{remove:b},d,f,g]):this._toggleClass(b,c):a.effects.animateClass.apply(this,[{toggle:b},c,d,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this, [{add:c,remove:b},d,e,f])}});a.extend(a.effects,{version:"1.8.22",save:function(a,b){for(var c=0;c").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;try{e.id}catch(f){e=document.body}return b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(), @@ -589,31 +589,31 @@ b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return e)<1/2.75?7.5625*d*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+0.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+0.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+0.984375)+c},easeInOutBounce:function(b,c,d,e,f){return c").css({position:"absolute",visibility:"visible",left:-m*(g/c),top:-k*(f/d)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/c,height:f/d,left:j.left+m*(g/c)+("show"==e.options.mode?(m-Math.floor(c/2))*(g/c):0),top:j.top+k*(f/d)+("show"==e.options.mode?(k-Math.floor(d/2))*(f/d):0),opacity:"show"==e.options.mode?0:1}).animate({left:j.left+m*(g/c)+("show"==e.options.mode?0:(m-Math.floor(c/2))*(g/c)),top:j.top+ +(function(a){a.effects.explode=function(e){return this.queue(function(){var d=e.options.pieces?Math.round(Math.sqrt(e.options.pieces)):3,c=e.options.pieces?Math.round(Math.sqrt(e.options.pieces)):3;e.options.mode="toggle"==e.options.mode?a(this).is(":visible")?"hide":"show":e.options.mode;var b=a(this).show().css("visibility","hidden"),j=b.offset();j.top-=parseInt(b.css("marginTop"),10)||0;j.left-=parseInt(b.css("marginLeft"),10)||0;for(var g=b.outerWidth(!0),f=b.outerHeight(!0),k=0;k").css({position:"absolute",visibility:"visible",left:-l*(g/c),top:-k*(f/d)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/c,height:f/d,left:j.left+l*(g/c)+("show"==e.options.mode?(l-Math.floor(c/2))*(g/c):0),top:j.top+k*(f/d)+("show"==e.options.mode?(k-Math.floor(d/2))*(f/d):0),opacity:"show"==e.options.mode?0:1}).animate({left:j.left+l*(g/c)+("show"==e.options.mode?0:(l-Math.floor(c/2))*(g/c)),top:j.top+ k*(f/d)+("show"==e.options.mode?0:(k-Math.floor(d/2))*(f/d)),opacity:"show"==e.options.mode?1:0},e.duration||500);setTimeout(function(){"show"==e.options.mode?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();e.callback&&e.callback.apply(b[0]);b.dequeue();a("div.ui-effects-explode").remove()},e.duration||500)})}})(jQuery); (function(a){a.effects.fade=function(e){return this.queue(function(){var d=a(this),c=a.effects.setMode(d,e.options.mode||"hide");d.animate({opacity:c},{queue:!1,duration:e.duration,easing:e.options.easing,complete:function(){e.callback&&e.callback.apply(this,arguments);d.dequeue()}})})}})(jQuery); -(function(a){a.effects.fold=function(e){return this.queue(function(){var d=a(this),c=["position","top","bottom","left","right"],b=a.effects.setMode(d,e.options.mode||"hide"),j=e.options.size||15,g=!!e.options.horizFirst,f=e.duration?e.duration/2:a.fx.speeds._default/2;a.effects.save(d,c);d.show();var k=a.effects.createWrapper(d).css({overflow:"hidden"}),m="show"==b!=g,q=m?["width","height"]:["height","width"],m=m?[k.width(),k.height()]:[k.height(),k.width()],n=/([0-9]+)%/.exec(j);n&&(j=parseInt(n[1], -10)/100*m["hide"==b?0:1]);"show"==b&&k.css(g?{height:0,width:j}:{height:j,width:0});g={};n={};g[q[0]]="show"==b?m[0]:j;n[q[1]]="show"==b?m[1]:0;k.animate(g,f,e.options.easing).animate(n,f,e.options.easing,function(){"hide"==b&&d.hide();a.effects.restore(d,c);a.effects.removeWrapper(d);e.callback&&e.callback.apply(d[0],arguments);d.dequeue()})})}})(jQuery); +(function(a){a.effects.fold=function(e){return this.queue(function(){var d=a(this),c=["position","top","bottom","left","right"],b=a.effects.setMode(d,e.options.mode||"hide"),j=e.options.size||15,g=!!e.options.horizFirst,f=e.duration?e.duration/2:a.fx.speeds._default/2;a.effects.save(d,c);d.show();var k=a.effects.createWrapper(d).css({overflow:"hidden"}),l="show"==b!=g,n=l?["width","height"]:["height","width"],l=l?[k.width(),k.height()]:[k.height(),k.width()],p=/([0-9]+)%/.exec(j);p&&(j=parseInt(p[1], +10)/100*l["hide"==b?0:1]);"show"==b&&k.css(g?{height:0,width:j}:{height:j,width:0});g={};p={};g[n[0]]="show"==b?l[0]:j;p[n[1]]="show"==b?l[1]:0;k.animate(g,f,e.options.easing).animate(p,f,e.options.easing,function(){"hide"==b&&d.hide();a.effects.restore(d,c);a.effects.removeWrapper(d);e.callback&&e.callback.apply(d[0],arguments);d.dequeue()})})}})(jQuery); (function(a){a.effects.highlight=function(e){return this.queue(function(){var d=a(this),c=["backgroundImage","backgroundColor","opacity"],b=a.effects.setMode(d,e.options.mode||"show"),j={backgroundColor:d.css("backgroundColor")};"hide"==b&&(j.opacity=0);a.effects.save(d,c);d.show().css({backgroundImage:"none",backgroundColor:e.options.color||"#ffff99"}).animate(j,{queue:!1,duration:e.duration,easing:e.options.easing,complete:function(){"hide"==b&&d.hide();a.effects.restore(d,c);"show"==b&&!a.support.opacity&& this.style.removeAttribute("filter");e.callback&&e.callback.apply(this,arguments);d.dequeue()}})})}})(jQuery); (function(a){a.effects.pulsate=function(e){return this.queue(function(){var d=a(this),c=a.effects.setMode(d,e.options.mode||"show"),b=2*(e.options.times||5)-1,j=e.duration?e.duration/2:a.fx.speeds._default/2,g=d.is(":visible"),f=0;g||(d.css("opacity",0).show(),f=1);("hide"==c&&g||"show"==c&&!g)&&b--;for(c=0;c').appendTo(document.body).addClass(e.options.className).css({top:b.top,left:b.left,height:d.innerHeight(),width:d.innerWidth(),position:"absolute"}).animate(c,e.duration,e.options.easing,function(){j.remove();e.callback&&e.callback.apply(d[0],arguments);d.dequeue()})})}})(jQuery);jQuery(function(a){a.datepicker.regional.af={closeText:"Selekteer",prevText:"Vorige",nextText:"Volgende",currentText:"Vandag",monthNames:"Januarie Februarie Maart April Mei Junie Julie Augustus September Oktober November Desember".split(" "),monthNamesShort:"Jan Feb Mrt Apr Mei Jun Jul Aug Sep Okt Nov Des".split(" "),dayNames:"Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag".split(" "),dayNamesShort:"Son Maa Din Woe Don Vry Sat".split(" "),dayNamesMin:"So Ma Di Wo Do Vr Sa".split(" "),weekHeader:"Wk", @@ -772,130 +772,134 @@ dayNamesShort:"\u5468\u65e5 \u5468\u4e00 \u5468\u4e8c \u5468\u4e09 \u5468\u56db jQuery(function(a){a.datepicker.regional["zh-HK"]={closeText:"\u95dc\u9589",prevText:"<\u4e0a\u6708",nextText:"\u4e0b\u6708>",currentText:"\u4eca\u5929",monthNames:"\u4e00\u6708 \u4e8c\u6708 \u4e09\u6708 \u56db\u6708 \u4e94\u6708 \u516d\u6708 \u4e03\u6708 \u516b\u6708 \u4e5d\u6708 \u5341\u6708 \u5341\u4e00\u6708 \u5341\u4e8c\u6708".split(" "),monthNamesShort:"\u4e00 \u4e8c \u4e09 \u56db \u4e94 \u516d \u4e03 \u516b \u4e5d \u5341 \u5341\u4e00 \u5341\u4e8c".split(" "),dayNames:"\u661f\u671f\u65e5 \u661f\u671f\u4e00 \u661f\u671f\u4e8c \u661f\u671f\u4e09 \u661f\u671f\u56db \u661f\u671f\u4e94 \u661f\u671f\u516d".split(" "), dayNamesShort:"\u5468\u65e5 \u5468\u4e00 \u5468\u4e8c \u5468\u4e09 \u5468\u56db \u5468\u4e94 \u5468\u516d".split(" "),dayNamesMin:"\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".split(""),weekHeader:"\u5468",dateFormat:"dd-mm-yy",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"\u5e74"};a.datepicker.setDefaults(a.datepicker.regional["zh-HK"])}); jQuery(function(a){a.datepicker.regional["zh-TW"]={closeText:"\u95dc\u9589",prevText:"<\u4e0a\u6708",nextText:"\u4e0b\u6708>",currentText:"\u4eca\u5929",monthNames:"\u4e00\u6708 \u4e8c\u6708 \u4e09\u6708 \u56db\u6708 \u4e94\u6708 \u516d\u6708 \u4e03\u6708 \u516b\u6708 \u4e5d\u6708 \u5341\u6708 \u5341\u4e00\u6708 \u5341\u4e8c\u6708".split(" "),monthNamesShort:"\u4e00 \u4e8c \u4e09 \u56db \u4e94 \u516d \u4e03 \u516b \u4e5d \u5341 \u5341\u4e00 \u5341\u4e8c".split(" "),dayNames:"\u661f\u671f\u65e5 \u661f\u671f\u4e00 \u661f\u671f\u4e8c \u661f\u671f\u4e09 \u661f\u671f\u56db \u661f\u671f\u4e94 \u661f\u671f\u516d".split(" "), -dayNamesShort:"\u5468\u65e5 \u5468\u4e00 \u5468\u4e8c \u5468\u4e09 \u5468\u56db \u5468\u4e94 \u5468\u516d".split(" "),dayNamesMin:"\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".split(""),weekHeader:"\u5468",dateFormat:"yy/mm/dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"\u5e74"};a.datepicker.setDefaults(a.datepicker.regional["zh-TW"])});(function(a){jQuery.fn.extend({slimScroll:function(e){var d={wheelStep:20,width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:0.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:"0.2",railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,scroll:0,touchScrollStep:200},c=a.extend(d,e);this.each(function(){function b(a,b,d){var e=a;b&&(e=parseInt(B.css("top"))+a*parseInt(c.wheelStep)/ -100*B.outerHeight(),b=t.outerHeight()-B.outerHeight(),e=Math.min(Math.max(e,0),b),B.css({top:e+"px"}));u=parseInt(B.css("top"))/(t.outerHeight()-B.outerHeight());e=u*(t[0].scrollHeight-t.outerHeight());d&&(e=a,a=e/t[0].scrollHeight*t.outerHeight(),B.css({top:a+"px"}));t.scrollTop(e);g();f()}function e(){r=Math.max(t.outerHeight()/t[0].scrollHeight*t.outerHeight(),y);B.css({height:r+"px"})}function g(){e();clearTimeout(n);u==~~u&&(w=c.allowPageScroll,p!=u&&t.trigger("slimscroll",0==~~u?"top":"bottom")); -p=u;r>=t.outerHeight()?w=!1:(B.stop(!0,!0).fadeIn("fast"),c.railVisible&&C.stop(!0,!0).fadeIn("fast"))}function f(){c.alwaysVisible||(n=setTimeout(function(){if((!c.disableFadeOut||!k)&&!m&&!q)B.fadeOut("slow"),C.fadeOut("slow")},1E3))}var k,m,q,n,s,r,u,p,y=30,w=!1,t=a(this);if(t.parent().hasClass("slimScrollDiv"))scroll&&(B=t.parent().find(".slimScrollBar"),C=t.parent().find(".slimScrollRail"),b(t.scrollTop()+parseInt(scroll),!1,!0));else{var A=a("
    ").addClass(c.wrapperClass).css({position:"relative", -overflow:"hidden",width:c.width,height:c.height});t.css({overflow:"hidden",width:c.width,height:c.height});var C=a("
    ").addClass(c.railClass).css({width:c.size,height:"100%",position:"absolute",top:0,display:c.alwaysVisible&&c.railVisible?"block":"none","border-radius":c.size,background:c.railColor,opacity:c.railOpacity,zIndex:90}),B=a("
    ").addClass(c.barClass).css({background:c.color,width:c.size,position:"absolute",top:0,opacity:c.opacity,display:c.alwaysVisible?"block":"none", -"border-radius":c.size,BorderRadius:c.size,MozBorderRadius:c.size,WebkitBorderRadius:c.size,zIndex:99}),L="right"==c.position?{right:c.distance}:{left:c.distance};C.css(L);B.css(L);t.wrap(A);t.parent().append(B);t.parent().append(C);B.draggable({axis:"y",containment:"parent",start:function(){q=!0},stop:function(){q=!1;f();m||(B.animate({width:d.size},100),C.animate({width:d.size},100))},drag:function(){b(0,a(this).position().top,!1)}});C.hover(function(){g()},function(){f()});B.hover(function(){m= -!0;B.animate({width:"12px"},100);C.animate({width:"12px"},100)},function(){m=!1;q||(B.animate({width:d.size},100),C.animate({width:d.size},100))});t.hover(function(){k=!0;g();f()},function(){k=!1;f()});t.bind("touchstart",function(a){a.originalEvent.touches.length&&(s=a.originalEvent.touches[0].pageY)});t.bind("touchmove",function(a){a.originalEvent.preventDefault();a.originalEvent.touches.length&&b((s-a.originalEvent.touches[0].pageY)/c.touchScrollStep,!0)});var D=function(a){if(k){var a=a||window.event, -c=0;a.wheelDelta&&(c=-a.wheelDelta/120);a.detail&&(c=a.detail/3);b(c,!0);a.preventDefault&&!w&&a.preventDefault();w||(a.returnValue=!1)}};(function(){window.addEventListener?(this.addEventListener("DOMMouseScroll",D,!1),this.addEventListener("mousewheel",D,!1)):document.attachEvent("onmousewheel",D)})();e();"bottom"==c.start?(B.css({top:t.outerHeight()-B.outerHeight()}),b(0,!0)):"object"==typeof c.start&&(b(a(c.start).position().top,null,!0),c.alwaysVisible||B.hide())}});return this}});jQuery.fn.extend({slimscroll:jQuery.fn.slimScroll})})(jQuery);jQuery.easing.jswing=jQuery.easing.swing; +dayNamesShort:"\u5468\u65e5 \u5468\u4e00 \u5468\u4e8c \u5468\u4e09 \u5468\u56db \u5468\u4e94 \u5468\u516d".split(" "),dayNamesMin:"\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".split(""),weekHeader:"\u5468",dateFormat:"yy/mm/dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"\u5e74"};a.datepicker.setDefaults(a.datepicker.regional["zh-TW"])});(function(a){jQuery.fn.extend({slimScroll:function(e){var d={wheelStep:20,width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:0.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:"0.2",railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,scroll:0,touchScrollStep:200},c=a.extend(d,e);this.each(function(){function b(a,b,d){var e=a;b&&(e=parseInt(A.css("top"))+a*parseInt(c.wheelStep)/ +100*A.outerHeight(),b=t.outerHeight()-A.outerHeight(),e=Math.min(Math.max(e,0),b),A.css({top:e+"px"}));r=parseInt(A.css("top"))/(t.outerHeight()-A.outerHeight());e=r*(t[0].scrollHeight-t.outerHeight());d&&(e=a,a=e/t[0].scrollHeight*t.outerHeight(),A.css({top:a+"px"}));t.scrollTop(e);g();f()}function e(){s=Math.max(t.outerHeight()/t[0].scrollHeight*t.outerHeight(),y);A.css({height:s+"px"})}function g(){e();clearTimeout(p);r==~~r&&(u=c.allowPageScroll,q!=r&&t.trigger("slimscroll",0==~~r?"top":"bottom")); +q=r;s>=t.outerHeight()?u=!1:(A.stop(!0,!0).fadeIn("fast"),c.railVisible&&B.stop(!0,!0).fadeIn("fast"))}function f(){c.alwaysVisible||(p=setTimeout(function(){if((!c.disableFadeOut||!k)&&!l&&!n)A.fadeOut("slow"),B.fadeOut("slow")},1E3))}var k,l,n,p,v,s,r,q,y=30,u=!1,t=a(this);if(t.parent().hasClass("slimScrollDiv"))scroll&&(A=t.parent().find(".slimScrollBar"),B=t.parent().find(".slimScrollRail"),b(t.scrollTop()+parseInt(scroll),!1,!0));else{var C=a("
    ").addClass(c.wrapperClass).css({position:"relative", +overflow:"hidden",width:c.width,height:c.height});t.css({overflow:"hidden",width:c.width,height:c.height});var B=a("
    ").addClass(c.railClass).css({width:c.size,height:"100%",position:"absolute",top:0,display:c.alwaysVisible&&c.railVisible?"block":"none","border-radius":c.size,background:c.railColor,opacity:c.railOpacity,zIndex:90}),A=a("
    ").addClass(c.barClass).css({background:c.color,width:c.size,position:"absolute",top:0,opacity:c.opacity,display:c.alwaysVisible?"block":"none", +"border-radius":c.size,BorderRadius:c.size,MozBorderRadius:c.size,WebkitBorderRadius:c.size,zIndex:99}),N="right"==c.position?{right:c.distance}:{left:c.distance};B.css(N);A.css(N);t.wrap(C);t.parent().append(A);t.parent().append(B);A.draggable({axis:"y",containment:"parent",start:function(){n=!0},stop:function(){n=!1;f();l||(A.animate({width:d.size},100),B.animate({width:d.size},100))},drag:function(){b(0,a(this).position().top,!1)}});B.hover(function(){g()},function(){f()});A.hover(function(){l= +!0;A.animate({width:"12px"},100);B.animate({width:"12px"},100)},function(){l=!1;n||(A.animate({width:d.size},100),B.animate({width:d.size},100))});t.hover(function(){k=!0;g();f()},function(){k=!1;f()});t.bind("touchstart",function(a){a.originalEvent.touches.length&&(v=a.originalEvent.touches[0].pageY)});t.bind("touchmove",function(a){a.originalEvent.preventDefault();a.originalEvent.touches.length&&b((v-a.originalEvent.touches[0].pageY)/c.touchScrollStep,!0)});var D=function(a){if(k){var a=a||window.event, +c=0;a.wheelDelta&&(c=-a.wheelDelta/120);a.detail&&(c=a.detail/3);b(c,!0);a.preventDefault&&!u&&a.preventDefault();u||(a.returnValue=!1)}};(function(){window.addEventListener?(this.addEventListener("DOMMouseScroll",D,!1),this.addEventListener("mousewheel",D,!1)):document.attachEvent("onmousewheel",D)})();e();"bottom"==c.start?(A.css({top:t.outerHeight()-A.outerHeight()}),b(0,!0)):"object"==typeof c.start&&(b(a(c.start).position().top,null,!0),c.alwaysVisible||A.hide())}});return this}});jQuery.fn.extend({slimscroll:jQuery.fn.slimScroll})})(jQuery);jQuery.easing.jswing=jQuery.easing.swing; jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,e,d,c,b){return jQuery.easing[jQuery.easing.def](a,e,d,c,b)},easeInQuad:function(a,e,d,c,b){return c*(e/=b)*e+d},easeOutQuad:function(a,e,d,c,b){return-c*(e/=b)*(e-2)+d},easeInOutQuad:function(a,e,d,c,b){return 1>(e/=b/2)?c/2*e*e+d:-c/2*(--e*(e-2)-1)+d},easeInCubic:function(a,e,d,c,b){return c*(e/=b)*e*e+d},easeOutCubic:function(a,e,d,c,b){return c*((e=e/b-1)*e*e+1)+d},easeInOutCubic:function(a,e,d,c,b){return 1>(e/=b/2)?c/2*e*e*e+d: c/2*((e-=2)*e*e+2)+d},easeInQuart:function(a,e,d,c,b){return c*(e/=b)*e*e*e+d},easeOutQuart:function(a,e,d,c,b){return-c*((e=e/b-1)*e*e*e-1)+d},easeInOutQuart:function(a,e,d,c,b){return 1>(e/=b/2)?c/2*e*e*e*e+d:-c/2*((e-=2)*e*e*e-2)+d},easeInQuint:function(a,e,d,c,b){return c*(e/=b)*e*e*e*e+d},easeOutQuint:function(a,e,d,c,b){return c*((e=e/b-1)*e*e*e*e+1)+d},easeInOutQuint:function(a,e,d,c,b){return 1>(e/=b/2)?c/2*e*e*e*e*e+d:c/2*((e-=2)*e*e*e*e+2)+d},easeInSine:function(a,e,d,c,b){return-c*Math.cos(e/ b*(Math.PI/2))+c+d},easeOutSine:function(a,e,d,c,b){return c*Math.sin(e/b*(Math.PI/2))+d},easeInOutSine:function(a,e,d,c,b){return-c/2*(Math.cos(Math.PI*e/b)-1)+d},easeInExpo:function(a,e,d,c,b){return 0==e?d:c*Math.pow(2,10*(e/b-1))+d},easeOutExpo:function(a,e,d,c,b){return e==b?d+c:c*(-Math.pow(2,-10*e/b)+1)+d},easeInOutExpo:function(a,e,d,c,b){return 0==e?d:e==b?d+c:1>(e/=b/2)?c/2*Math.pow(2,10*(e-1))+d:c/2*(-Math.pow(2,-10*--e)+2)+d},easeInCirc:function(a,e,d,c,b){return-c*(Math.sqrt(1-(e/=b)* e)-1)+d},easeOutCirc:function(a,e,d,c,b){return c*Math.sqrt(1-(e=e/b-1)*e)+d},easeInOutCirc:function(a,e,d,c,b){return 1>(e/=b/2)?-c/2*(Math.sqrt(1-e*e)-1)+d:c/2*(Math.sqrt(1-(e-=2)*e)+1)+d},easeInElastic:function(a,e,d,c,b){var a=1.70158,j=0,g=c;if(0==e)return d;if(1==(e/=b))return d+c;j||(j=0.3*b);ge?-0.5*g*Math.pow(2,10*(e-=1))*Math.sin((e*b-a)*2*Math.PI/j)+d:0.5*g*Math.pow(2,-10*(e-=1))*Math.sin((e*b-a)*2*Math.PI/j)+c+d},easeInBack:function(a,e,d,c,b,j){void 0== j&&(j=1.70158);return c*(e/=b)*e*((j+1)*e-j)+d},easeOutBack:function(a,e,d,c,b,j){void 0==j&&(j=1.70158);return c*((e=e/b-1)*e*((j+1)*e+j)+1)+d},easeInOutBack:function(a,e,d,c,b,j){void 0==j&&(j=1.70158);return 1>(e/=b/2)?c/2*e*e*(((j*=1.525)+1)*e-j)+d:c/2*((e-=2)*e*(((j*=1.525)+1)*e+j)+2)+d},easeInBounce:function(a,e,d,c,b){return c-jQuery.easing.easeOutBounce(a,b-e,0,c,b)+d},easeOutBounce:function(a,e,d,c,b){return(e/=b)<1/2.75?c*7.5625*e*e+d:e<2/2.75?c*(7.5625*(e-=1.5/2.75)*e+0.75)+d:e<2.5/2.75? -c*(7.5625*(e-=2.25/2.75)*e+0.9375)+d:c*(7.5625*(e-=2.625/2.75)*e+0.984375)+d},easeInOutBounce:function(a,e,d,c,b){return en[j])e(a.aoColumns.length+n[j],c[g]);else if("string"===typeof n[j]){k=0;for(m=a.aoColumns.length;kb&&a[d]--; -1!=c&&a.splice(c,1)}function la(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mData},D(a,b,c,"display"))}function oa(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=e.createElement("tr");c.nTr._DT_RowIndex=b;c._aData.DT_RowId&&(c.nTr.id=c._aData.DT_RowId);c._aData.DT_RowClass&& -(c.nTr.className=c._aData.DT_RowClass);for(var f=0,g=a.aoColumns.length;fe;e+=1){var f=parseInt(b(),16);if(!isFinite(f))break;d=16*d+f}a+=String.fromCharCode(d)}else if("string"===typeof q[r])a+=q[r];else break;else a+=r}c("Bad string")}function g(){for(;r&&" ">=r;)b()} +function f(){for(var a="";l();)a+=r,b();return"true"===a?!0:"false"===a?!1:"null"===a?null:/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(a)?parseFloat(a):a}function k(){g();switch(r){case n:var a;a:{a={};if(r===n){b(n);g();if(r===p){b(p);break a}for(;r;){var d='"'===r?j():f();"string"!==typeof d&&c("Bad object key: "+d);g();b(v);Object.hasOwnProperty.call(a,d)&&c('Duplicate key: "'+d+'"');a[d]=k();g();if(r===p){b(p);break a}b(",");g()}}c("Bad object");a=void 0}return a;case "[":a:{a=[];if("["=== +r){b("[");g();if("]"===r){b("]");break a}for(;r;){a.push(k());g();if("]"===r){b("]");break a}b(",");g()}}c("Bad array");a=void 0}return a;case '"':return j();default:return f()}}function l(){switch(r){case '"':case "\\":case "\t":case "\n":case "\r":case ",":case "[":case "]":case n:case p:case v:return!1}return" "q[j])e(a.aoColumns.length+q[j],c[g]);else if("string"===typeof q[j]){k=0;for(l=a.aoColumns.length;kb&&a[d]--; -1!=c&&a.splice(c,1)}function Q(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mData},D(a,b,c,"display"))}function M(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=e.createElement("tr");c.nTr._DT_RowIndex=b;c._aData.DT_RowId&&(c.nTr.id=c._aData.DT_RowId);c._aData.DT_RowClass&& +(c.nTr.className=c._aData.DT_RowClass);for(var f=0,g=a.aoColumns.length;f=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,aa(a));if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!$(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var k= -a._iDisplayStart;g=a._iDisplayEnd;a.oFeatures.bServerSide&&(k=0,g=a.aoData.length);for(;k")[0];a.nTable.parentNode.insertBefore(d,a.nTable);a.nTableWrapper=b('
    ')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var e=a.nTableWrapper,f=a.sDom.split(""),g,h,k,m,n,q,r,p=0;p")[0]; -n=f[p+1];if("'"==n||'"'==n){q="";for(r=2;f[p+r]!=n;)q+=f[p+r],r++;"H"==q?q=a.oClasses.sJUIHeader:"F"==q&&(q=a.oClasses.sJUIFooter);-1!=q.indexOf(".")?(n=q.split("."),m.id=n[0].substr(1,n[0].length-1),m.className=n[1]):"#"==q.charAt(0)?m.id=q.substr(1,q.length-1):m.className=q;p+=r}e.appendChild(m);e=m}else if(">"==k)e=e.parentNode;else if("l"==k&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)g=mb(a),h=1;else if("f"==k&&a.oFeatures.bFilter)g=za(a),h=1;else if("r"==k&&a.oFeatures.bProcessing)g=V(a), -h=1;else if("t"==k)g=va(a),h=1;else if("i"==k&&a.oFeatures.bInfo)g=wb(a),h=1;else if("p"==k&&a.oFeatures.bPaginate)g=yb(a),h=1;else if(0!==c.ext.aoFeatures.length){m=c.ext.aoFeatures;r=0;for(n=m.length;r=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,fa(a));if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!$(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var k= +a._iDisplayStart;g=a._iDisplayEnd;a.oFeatures.bServerSide&&(k=0,g=a.aoData.length);for(;k")[0];a.nTable.parentNode.insertBefore(d,a.nTable);a.nTableWrapper=b('
    ')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var e=a.nTableWrapper,f=a.sDom.split(""),g,h,k,l,q,u,t,p=0;p")[0]; +q=f[p+1];if("'"==q||'"'==q){u="";for(t=2;f[p+t]!=q;)u+=f[p+t],t++;"H"==u?u=a.oClasses.sJUIHeader:"F"==u&&(u=a.oClasses.sJUIFooter);-1!=u.indexOf(".")?(q=u.split("."),l.id=q[0].substr(1,q[0].length-1),l.className=q[1]):"#"==u.charAt(0)?l.id=u.substr(1,u.length-1):l.className=u;p+=t}e.appendChild(l);e=l}else if(">"==k)e=e.parentNode;else if("l"==k&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)g=mb(a),h=1;else if("f"==k&&a.oFeatures.bFilter)g=ba(a),h=1;else if("r"==k&&a.oFeatures.bProcessing)g=aa(a), +h=1;else if("t"==k)g=xa(a),h=1;else if("i"==k&&a.oFeatures.bInfo)g=vb(a),h=1;else if("p"==k&&a.oFeatures.bPaginate)g=xb(a),h=1;else if(0!==c.ext.aoFeatures.length){l=c.ext.aoFeatures;t=0;for(q=l.length;t'):""===d?'':d+' ',f=e.createElement("div");f.className=a.oClasses.sFilter;f.innerHTML="";a.aanFeatures.f||(f.id=a.sTableId+"_filter");d=b('input[type="text"]',f);f._DT_Input=d[0];d.val(c.sSearch.replace('"',"""));d.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,e=""===this.value?"":this.value, +a.oFeatures.bSort){var j=0;d=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(f=0;f'):""===d?'':d+' ',f=e.createElement("div");f.className=a.oClasses.sFilter;f.innerHTML="";a.aanFeatures.f||(f.id=a.sTableId+"_filter");d=b('input[type="text"]',f);f._DT_Input=d[0];d.val(c.sSearch.replace('"',"""));d.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,e=""===this.value?"":this.value, f=0,g=d.length;f=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||f.sSearch.length>b.length||1==d||0!==b.indexOf(f.sSearch)){a.aiDisplay.splice(0, -a.aiDisplay.length);ib(a,1);for(b=0;b").html(d).text()); -return d.replace(/[\n\r]/g," ")}function Za(a,b,c,d){if(c)return a=b?a.split(" "):kb(a).split(" "),a="^(?=.*?"+a.join(")(?=.*?")+").*$",RegExp(a,d?"i":"");a=b?a:kb(a);return RegExp(a,d?"i":"")}function vb(a,b){return"function"===typeof c.ext.ofnSearch[b]?c.ext.ofnSearch[b](a):null===a?"":"html"==b?a.replace(/[\r\n]/g," ").replace(/<.*?>/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):a}function kb(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"), -"\\$1")}function wb(a){var b=e.createElement("div");b.className=a.oClasses.sInfo;a.aanFeatures.i||(a.aoDrawCallback.push({fn:xb,sName:"information"}),b.id=a.sTableId+"_info");a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function xb(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),j;j=0===g?c.sInfoEmpty:c.sInfo;g!=f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=lb(a,j); +else{Aa(a,c.sSearch,d,c.bRegex,c.bSmart,c.bCaseInsensitive);g(c);for(c=0;c=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||f.sSearch.length>b.length||1==d||0!==b.indexOf(f.sSearch)){a.aiDisplay.splice(0, +a.aiDisplay.length);ib(a,1);for(b=0;b").html(d).text()); +return d.replace(/[\n\r]/g," ")}function Za(a,b,c,d){if(c)return a=b?a.split(" "):kb(a).split(" "),a="^(?=.*?"+a.join(")(?=.*?")+").*$",RegExp(a,d?"i":"");a=b?a:kb(a);return RegExp(a,d?"i":"")}function ub(a,b){return"function"===typeof c.ext.ofnSearch[b]?c.ext.ofnSearch[b](a):null===a?"":"html"==b?a.replace(/[\r\n]/g," ").replace(/<.*?>/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):a}function kb(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"), +"\\$1")}function vb(a){var b=e.createElement("div");b.className=a.oClasses.sInfo;a.aanFeatures.i||(a.aoDrawCallback.push({fn:wb,sName:"information"}),b.id=a.sTableId+"_info");a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function wb(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),j;j=0===g?c.sInfoEmpty:c.sInfo;g!=f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=lb(a,j); null!==c.fnInfoCallback&&(j=c.fnInfoCallback.call(a.oInstance,a,d,e,f,g,j));a=a.aanFeatures.i;c=0;for(d=a.length;c",d,f,g=a.aLengthMenu;if(2==g.length&&"object"===typeof g[0]&&"object"===typeof g[1]){d=0;for(f=g[0].length;d'+g[1][d]+""}else{d=0;for(f=g.length;d'+g[d]+""}c+="";g=e.createElement("div");a.aanFeatures.l|| -(g.id=a.sTableId+"_length");g.className=a.oClasses.sLength;g.innerHTML="";b('select option[value="'+a._iDisplayLength+'"]',g).attr("selected",!0);b("select",g).bind("change.DT",function(){var c=b(this).val(),e=a.aanFeatures.l;d=0;for(f=e.length;da._iDisplayStart&& -(a._iDisplayStart=0));-1==a._iDisplayLength&&(a._iDisplayStart=0);R(a)});b("select",g).attr("aria-controls",a.sTableId);return g}function aa(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function yb(a){if(a.oScroll.bInfinite)return null;var b=e.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;c.ext.oPagination[a.sPaginationType].fnInit(a, -b,function(a){aa(a);R(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){c.ext.oPagination[a.sPaginationType].fnUpdate(a,function(a){aa(a);R(a)})},sName:"pagination"});return b}function Ma(a,c){var d=a._iDisplayStart;if("number"===typeof c)a._iDisplayStart=c*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay()&&(a._iDisplayStart=0);else if("first"==c)a._iDisplayStart=0;else if("previous"==c)a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart&& -(a._iDisplayStart=0);else if("next"==c)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLengthb(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()e.offsetHeight||"scroll"==b(e).css("overflow-y")))a.nTable.style.width=F(b(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else""!==a.oScroll.sXInner?a.nTable.style.width= -F(a.oScroll.sXInner):f==b(e).width()&&b(e).height()f-a.oScroll.iBarWidth&&(a.nTable.style.width=F(f))):a.nTable.style.width=F(f);f=b(a.nTable).outerWidth();fa(y,h);fa(function(a){p.push(F(b(a).width()))},h);fa(function(a,b){a.style.width=p[b]},j);b(h).height(0);null!==a.nTFoot&&(fa(y,k),fa(function(a){s.push(F(b(a).width()))},k),fa(function(a,b){a.style.width=s[b]},m),b(k).height(0));fa(function(a,b){a.innerHTML= -"";a.style.width=p[b]},h);null!==a.nTFoot&&fa(function(a,b){a.innerHTML="";a.style.width=s[b]},k);if(b(a.nTable).outerWidth()e.offsetHeight||"scroll"==b(e).css("overflow-y")?f+a.oScroll.iBarWidth:f;if(w&&(e.scrollHeight>e.offsetHeight||"scroll"==b(e).css("overflow-y")))a.nTable.style.width=F(j-a.oScroll.iBarWidth);e.style.width=F(j);a.nScrollHead.style.width=F(j);null!==a.nTFoot&&(a.nScrollFoot.style.width=F(j));""===a.oScroll.sX?ra(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."): -""!==a.oScroll.sXInner&&ra(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else e.style.width=F("100%"),a.nScrollHead.style.width=F("100%"),null!==a.nTFoot&&(a.nScrollFoot.style.width=F("100%"));""===a.oScroll.sY&&w&&(e.style.height=F(a.nTable.offsetHeight+a.oScroll.iBarWidth));""!==a.oScroll.sY&&a.oScroll.bCollapse&&(e.style.height=F(a.oScroll.sY),w=""!==a.oScroll.sX&&a.nTable.offsetWidth> -e.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeighte.clientHeight||"scroll"==b(e).css("overflow-y");c.style.paddingRight=d?a.oScroll.iBarWidth+"px":"0px";null!==a.nTFoot&&(u.style.width=F(w),t.style.width=F(w),t.style.paddingRight=d?a.oScroll.iBarWidth+"px":"0px");b(e).scroll();if(a.bSorted||a.bFiltered)e.scrollTop=0}function fa(a,b,c){for(var d= -0,e=0,f=b.length,g,j;etd",c));k=J(a,j);for(j=f=0;jc)return null;if(null===a.aoData[c].nTr){var d=e.createElement("td");d.innerHTML=D(a,c,b,"");return d}return Ba(a,c)[b]}function Fa(a,b){for(var c=-1,d=-1,e=0;e/g,"");f.length>c&&(c=f.length,d=e)}return d}function F(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1); -return 48>b||57/g,""),k=w[f].nTh,k.removeAttribute("aria-sort"),k.removeAttribute("aria-label"),w[f].bSortable?0e&&e++;g=RegExp(g+"[123]");var k;c=0;for(d=a.length;c
    ')[0];e.body.appendChild(c);a.oBrowser.bScrollOversize= -100===b("#DT_BrowserTest",c)[0].offsetWidth?!0:!1;e.body.removeChild(c)}function Ab(a){return function(){var b=[Q(this[c.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return c.ext.oApi[a].apply(this,b)}}var Qa=/\[.*?\]$/,Bb=a.JSON?JSON.stringify:function(a){var c=typeof a;if("object"!==c||null===a)return"string"===c&&(a='"'+a+'"'),a+"";var d,e,f=[],g=b.isArray(a);for(d in a)e=a[d],c=typeof e,"string"===c?e='"'+e+'"':"object"===c&&null!==e&&(e=Bb(e)),f.push((g?"":'"'+d+'":')+e);return(g? -"[":"{")+f+(g?"]":"}")};this.$=function(a,d){var e,f,g=[],h;f=Q(this[c.ext.iApiIndex]);var k=f.aoData,m=f.aiDisplay,n=f.aiDisplayMaster;d||(d={});d=b.extend({},{filter:"none",order:"current",page:"all"},d);if("current"==d.page){e=f._iDisplayStart;for(f=f.fnDisplayEnd();e=g.fnRecordsDisplay()&&(g._iDisplayStart-=g._iDisplayLength,0>g._iDisplayStart&&(g._iDisplayStart=0));if(f===d||f)aa(g),R(g);return m};this.fnDestroy=function(a){var e=Q(this[c.ext.iApiIndex]),f=e.nTableWrapper.parentNode,h=e.nTBody,k,m,a=a===d?!1:a;e.bDestroying=!0;ca(e,"aoDestroyCallback","destroy",[e]);if(!a){k=0;for(m=e.aoColumns.length;k"+a.oLanguage.sLengthMenu.replace("_MENU_",c)+"";b('select option[value="'+a._iDisplayLength+'"]',g).attr("selected",!0);b("select",g).bind("change.DT",function(){var c=b(this).val(),e=a.aanFeatures.l;d=0;for(f=e.length;da._iDisplayStart&& +(a._iDisplayStart=0));-1==a._iDisplayLength&&(a._iDisplayStart=0);S(a)});b("select",g).attr("aria-controls",a.sTableId);return g}function fa(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function xb(a){if(a.oScroll.bInfinite)return null;var b=e.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;c.ext.oPagination[a.sPaginationType].fnInit(a, +b,function(a){fa(a);S(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){c.ext.oPagination[a.sPaginationType].fnUpdate(a,function(a){fa(a);S(a)})},sName:"pagination"});return b}function Na(a,c){var d=a._iDisplayStart;if("number"===typeof c)a._iDisplayStart=c*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay()&&(a._iDisplayStart=0);else if("first"==c)a._iDisplayStart=0;else if("previous"==c)a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart&& +(a._iDisplayStart=0);else if("next"==c)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLengthb(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()e.offsetHeight||"scroll"==b(e).css("overflow-y")))a.nTable.style.width=F(b(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else""!==a.oScroll.sXInner?a.nTable.style.width= +F(a.oScroll.sXInner):f==b(e).width()&&b(e).height()f-a.oScroll.iBarWidth&&(a.nTable.style.width=F(f))):a.nTable.style.width=F(f);f=b(a.nTable).outerWidth();ma(v,h);ma(function(a){t.push(F(b(a).width()))},h);ma(function(a,b){a.style.width=t[b]},j);b(h).height(0);null!==a.nTFoot&&(ma(v,k),ma(function(a){p.push(F(b(a).width()))},k),ma(function(a,b){a.style.width=p[b]},l),b(k).height(0));ma(function(a,b){a.innerHTML= +"";a.style.width=t[b]},h);null!==a.nTFoot&&ma(function(a,b){a.innerHTML="";a.style.width=p[b]},k);if(b(a.nTable).outerWidth()e.offsetHeight||"scroll"==b(e).css("overflow-y")?f+a.oScroll.iBarWidth:f;if(s&&(e.scrollHeight>e.offsetHeight||"scroll"==b(e).css("overflow-y")))a.nTable.style.width=F(j-a.oScroll.iBarWidth);e.style.width=F(j);a.nScrollHead.style.width=F(j);null!==a.nTFoot&&(a.nScrollFoot.style.width=F(j));""===a.oScroll.sX?ta(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."): +""!==a.oScroll.sXInner&&ta(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else e.style.width=F("100%"),a.nScrollHead.style.width=F("100%"),null!==a.nTFoot&&(a.nScrollFoot.style.width=F("100%"));""===a.oScroll.sY&&s&&(e.style.height=F(a.nTable.offsetHeight+a.oScroll.iBarWidth));""!==a.oScroll.sY&&a.oScroll.bCollapse&&(e.style.height=F(a.oScroll.sY),s=""!==a.oScroll.sX&&a.nTable.offsetWidth> +e.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeighte.clientHeight||"scroll"==b(e).css("overflow-y");c.style.paddingRight=d?a.oScroll.iBarWidth+"px":"0px";null!==a.nTFoot&&(r.style.width=F(s),y.style.width=F(s),y.style.paddingRight=d?a.oScroll.iBarWidth+"px":"0px");b(e).scroll();if(a.bSorted||a.bFiltered)e.scrollTop=0}function ma(a,b,c){for(var d= +0,e=0,f=b.length,g,j;etd",c));k=I(a,j);for(j=f=0;jc)return null;if(null===a.aoData[c].nTr){var d=e.createElement("td");d.innerHTML=D(a,c,b,"");return d}return Ca(a,c)[b]}function Fa(a,b){for(var c=-1,d=-1,e=0;e/g,"");f.length>c&&(c=f.length,d=e)}return d}function F(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1); +return 48>b||57/g,""),k=s[f].nTh,k.removeAttribute("aria-sort"),k.removeAttribute("aria-label"),s[f].bSortable?0e&&e++;g=RegExp(g+"[123]");var k;c=0;for(d=a.length;c
    ')[0];e.body.appendChild(c);a.oBrowser.bScrollOversize= +100===b("#DT_BrowserTest",c)[0].offsetWidth?!0:!1;e.body.removeChild(c)}function zb(a){return function(){var b=[Y(this[c.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return c.ext.oApi[a].apply(this,b)}}var Ra=/\[.*?\]$/,Ab=a.JSON?JSON.stringify:function(a){var c=typeof a;if("object"!==c||null===a)return"string"===c&&(a='"'+a+'"'),a+"";var d,e,f=[],g=b.isArray(a);for(d in a)e=a[d],c=typeof e,"string"===c?e='"'+e+'"':"object"===c&&null!==e&&(e=Ab(e)),f.push((g?"":'"'+d+'":')+e);return(g? +"[":"{")+f+(g?"]":"}")};this.$=function(a,d){var e,f,g=[],h;f=Y(this[c.ext.iApiIndex]);var k=f.aoData,l=f.aiDisplay,q=f.aiDisplayMaster;d||(d={});d=b.extend({},{filter:"none",order:"current",page:"all"},d);if("current"==d.page){e=f._iDisplayStart;for(f=f.fnDisplayEnd();e=g.fnRecordsDisplay()&&(g._iDisplayStart-=g._iDisplayLength,0>g._iDisplayStart&&(g._iDisplayStart=0));if(f===d||f)fa(g),S(g);return l};this.fnDestroy=function(a){var e=Y(this[c.ext.iApiIndex]),f=e.nTableWrapper.parentNode,h=e.nTBody,k,l,a=a===d?!1:a;e.bDestroying=!0;ha(e,"aoDestroyCallback","destroy",[e]);if(!a){k=0;for(l=e.aoColumns.length;ktr>td."+e.oClasses.sRowEmpty,e.nTable).parent().remove();e.nTable!=e.nTHead.parentNode&&(b(e.nTable).children("thead").remove(),e.nTable.appendChild(e.nTHead));e.nTFoot&&e.nTable!=e.nTFoot.parentNode&&(b(e.nTable).children("tfoot").remove(),e.nTable.appendChild(e.nTFoot));e.nTable.parentNode.removeChild(e.nTable);b(e.nTableWrapper).remove();e.aaSorting=[];e.aaSortingFixed=[];Da(e);b(Ga(e)).removeClass(e.asStripeClasses.join(" "));b("th, td",e.nTHead).removeClass([e.oClasses.sSortable,e.oClasses.sSortableAsc, -e.oClasses.sSortableDesc,e.oClasses.sSortableNone].join(" "));e.bJUI&&(b("th span."+e.oClasses.sSortIcon+", td span."+e.oClasses.sSortIcon,e.nTHead).remove(),b("th, td",e.nTHead).each(function(){var a=b("div."+e.oClasses.sSortJUIWrapper,this),c=a.contents();b(this).append(c);a.remove()}));!a&&e.nTableReinsertBefore?f.insertBefore(e.nTable,e.nTableReinsertBefore):a||f.appendChild(e.nTable);k=0;for(m=e.aoData.length;k=s(f);if(!r)for(g=a;gt<"F"ip>')):b.extend(p.oClasses,c.ext.oStdClasses);b(this).addClass(p.oClasses.sTable);if(""!==p.oScroll.sX|| -""!==p.oScroll.sY)p.oScroll.iBarWidth=O();p.iInitDisplayStart===d&&(p.iInitDisplayStart=g.iDisplayStart,p._iDisplayStart=g.iDisplayStart);g.bStateSave&&(p.oFeatures.bStateSave=!0,nb(p,g),ba(p,"aoDrawCallback",qa,"state_save"));null!==g.iDeferLoading&&(p.bDeferLoading=!0,a=b.isArray(g.iDeferLoading),p._iRecordsDisplay=a?g.iDeferLoading[0]:g.iDeferLoading,p._iRecordsTotal=a?g.iDeferLoading[1]:g.iDeferLoading);null!==g.aaData&&(r=!0);""!==g.oLanguage.sUrl?(p.oLanguage.sUrl=g.oLanguage.sUrl,b.getJSON(p.oLanguage.sUrl, -null,function(a){Ea(a);b.extend(!0,p.oLanguage,g.oLanguage,a);$a(p)}),q=!0):b.extend(!0,p.oLanguage,g.oLanguage);null===g.asStripeClasses&&(p.asStripeClasses=[p.oClasses.sStripeOdd,p.oClasses.sStripeEven]);h=p.asStripeClasses.length;p.asDestroyStripes=[];if(h){m=!1;n=b(this).children("tbody").children("tr:lt("+h+")");for(a=0;a=p.aoColumns.length&&(p.aaSorting[a][0]=0);var s=p.aoColumns[p.aaSorting[a][0]];p.aaSorting[a][2]===d&&(p.aaSorting[a][2]= -0);g.aaSorting===d&&p.saved_aaSorting===d&&(p.aaSorting[a][1]=s.asSorting[0]);m=0;for(n=s.asSorting.length;m=parseInt(q,10)};c.fnIsDataTable=function(a){for(var b=c.settings,d=0;d=v(f);if(!t)for(g=a;gt<"F"ip>')):b.extend(n.oClasses,c.ext.oStdClasses);b(this).addClass(n.oClasses.sTable);if(""!==n.oScroll.sX|| +""!==n.oScroll.sY)n.oScroll.iBarWidth=W();n.iInitDisplayStart===d&&(n.iInitDisplayStart=g.iDisplayStart,n._iDisplayStart=g.iDisplayStart);g.bStateSave&&(n.oFeatures.bStateSave=!0,nb(n,g),ga(n,"aoDrawCallback",sa,"state_save"));null!==g.iDeferLoading&&(n.bDeferLoading=!0,a=b.isArray(g.iDeferLoading),n._iRecordsDisplay=a?g.iDeferLoading[0]:g.iDeferLoading,n._iRecordsTotal=a?g.iDeferLoading[1]:g.iDeferLoading);null!==g.aaData&&(y=!0);""!==g.oLanguage.sUrl?(n.oLanguage.sUrl=g.oLanguage.sUrl,b.getJSON(n.oLanguage.sUrl, +null,function(a){Ea(a);b.extend(!0,n.oLanguage,g.oLanguage,a);$a(n)}),p=!0):b.extend(!0,n.oLanguage,g.oLanguage);null===g.asStripeClasses&&(n.asStripeClasses=[n.oClasses.sStripeOdd,n.oClasses.sStripeEven]);h=n.asStripeClasses.length;n.asDestroyStripes=[];if(h){l=!1;q=b(this).children("tbody").children("tr:lt("+h+")");for(a=0;a=n.aoColumns.length&&(n.aaSorting[a][0]=0);var r=n.aoColumns[n.aaSorting[a][0]];n.aaSorting[a][2]===d&&(n.aaSorting[a][2]= +0);g.aaSorting===d&&n.saved_aaSorting===d&&(n.aaSorting[a][1]=r.asSorting[0]);l=0;for(q=r.asSorting.length;l=parseInt(n,10)};c.fnIsDataTable=function(a){for(var b=c.settings,d=0;da)return a;for(var b=a+"",a=b.split(""),c="",b=b.length,d=0;d'+e.sPrevious+''+e.sNext+"":'';b(c).append(e);var n=b("a",c),e=n[0],n=n[1];a.oApi._fnBindAction(e,{action:"previous"},j);a.oApi._fnBindAction(n,{action:"next"},j);a.aanFeatures.p||(c.id=a.sTableId+"_paginate",e.id=a.sTableId+"_previous",n.id=a.sTableId+"_next",e.setAttribute("aria-controls",a.sTableId),n.setAttribute("aria-controls",a.sTableId))},fnUpdate:function(a){if(a.aanFeatures.p)for(var b=a.oClasses, -c=a.aanFeatures.p,d,e=0,j=c.length;e'+e.sFirst+ -''+e.sPrevious+''+e.sNext+''+e.sLast+"");var s=b("a",c),e=s[0],j=s[1],r=s[2],s=s[3];a.oApi._fnBindAction(e,{action:"first"},n);a.oApi._fnBindAction(j,{action:"previous"},n);a.oApi._fnBindAction(r,{action:"next"},n);a.oApi._fnBindAction(s,{action:"last"}, -n);a.aanFeatures.p||(c.id=a.sTableId+"_paginate",e.id=a.sTableId+"_first",j.id=a.sTableId+"_previous",r.id=a.sTableId+"_next",s.id=a.sTableId+"_last")},fnUpdate:function(a,d){if(a.aanFeatures.p){var e=c.ext.oPagination.iFullNumbersShowPages,m=Math.floor(e/2),q=Math.ceil(a.fnRecordsDisplay()/a._iDisplayLength),n=Math.ceil(a._iDisplayStart/a._iDisplayLength)+1,s="",r,u=a.oClasses,p,y=a.aanFeatures.p,w=function(b){a.oApi._fnBindAction(this,{page:b+r-1},function(b){a.oApi._fnPageChange(a,b.data.page); -d(a);b.preventDefault()})};-1===a._iDisplayLength?n=m=r=1:q=q-m?(r=q-e+1,m=q):(r=n-Math.ceil(e/2)+1,m=r+e-1);for(e=r;e<=m;e++)s+=n!==e?''+a.fnFormatNumber(e)+"":''+a.fnFormatNumber(e)+"";e=0;for(m=y.length;eb?1:0},"string-desc":function(a,b){return a< +a.oClasses.sPageNextDisabled+'" tabindex="'+a.iTabIndex+'" role="button">';b(c).append(e);var p=b("a",c),e=p[0],p=p[1];a.oApi._fnBindAction(e,{action:"previous"},j);a.oApi._fnBindAction(p,{action:"next"},j);a.aanFeatures.p||(c.id=a.sTableId+"_paginate",e.id=a.sTableId+"_previous",p.id=a.sTableId+"_next",e.setAttribute("aria-controls",a.sTableId),p.setAttribute("aria-controls",a.sTableId))},fnUpdate:function(a){if(a.aanFeatures.p)for(var b=a.oClasses, +c=a.aanFeatures.p,d,e=0,j=c.length;e'+e.sFirst+ +''+e.sPrevious+''+e.sNext+''+e.sLast+"");var v=b("a",c),e=v[0],j=v[1],s=v[2],v=v[3];a.oApi._fnBindAction(e,{action:"first"},p);a.oApi._fnBindAction(j,{action:"previous"},p);a.oApi._fnBindAction(s,{action:"next"},p);a.oApi._fnBindAction(v,{action:"last"}, +p);a.aanFeatures.p||(c.id=a.sTableId+"_paginate",e.id=a.sTableId+"_first",j.id=a.sTableId+"_previous",s.id=a.sTableId+"_next",v.id=a.sTableId+"_last")},fnUpdate:function(a,d){if(a.aanFeatures.p){var e=c.ext.oPagination.iFullNumbersShowPages,l=Math.floor(e/2),n=Math.ceil(a.fnRecordsDisplay()/a._iDisplayLength),p=Math.ceil(a._iDisplayStart/a._iDisplayLength)+1,v="",s,r=a.oClasses,q,y=a.aanFeatures.p,u=function(b){a.oApi._fnBindAction(this,{page:b+s-1},function(b){a.oApi._fnPageChange(a,b.data.page); +d(a);b.preventDefault()})};-1===a._iDisplayLength?p=l=s=1:n=n-l?(s=n-e+1,l=n):(s=p-Math.ceil(e/2)+1,l=s+e-1);for(e=s;e<=l;e++)v+=p!==e?''+a.fnFormatNumber(e)+"":''+a.fnFormatNumber(e)+"";e=0;for(l=y.length;eb?1:0},"string-desc":function(a,b){return a< b?1:a>b?-1:0},"html-pre":function(a){return a.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(a,b){return ab?1:0},"html-desc":function(a,b){return ab?-1:0},"date-pre":function(a){a=Date.parse(a);if(isNaN(a)||""===a)a=Date.parse("01/01/1970 00:00:00");return a},"date-asc":function(a,b){return a-b},"date-desc":function(a,b){return b-a},"numeric-pre":function(a){return"-"==a||""===a?0:1*a},"numeric-asc":function(a,b){return a-b},"numeric-desc":function(a,b){return b-a}});b.extend(c.ext.aTypes, [function(a){if("number"===typeof a)return"numeric";if("string"!==typeof a)return null;var b,c=!1;b=a.charAt(0);if(-1=="0123456789-".indexOf(b))return null;for(var d=1;d")?"html":null}]);b.fn.DataTable= c;b.fn.dataTable=c;b.fn.dataTableSettings=c.settings;b.fn.dataTableExt=c.ext};"function"===typeof define&&define.amd?define(["jquery"],c):jQuery&&!jQuery.fn.dataTable&&c(jQuery)})(window,document);var ZeroClipboard_TableTools={version:"1.0.4-TableTools2",clients:{},moviePath:"",nextId:1,$:function(a){"string"==typeof a&&(a=document.getElementById(a));a.addClass||(a.hide=function(){this.style.display="none"},a.show=function(){this.style.display=""},a.addClass=function(a){this.removeClass(a);this.className+=" "+a},a.removeClass=function(a){this.className=this.className.replace(RegExp("\\s*"+a+"\\s*")," ").replace(/^\s+/,"").replace(/\s+$/,"")},a.hasClass=function(a){return!!this.className.match(RegExp("\\s*"+ @@ -939,16 +943,16 @@ break;case "mouseover":this.domElement&&this.cssEffects&&this.recoverActive&&thi background:null}};this.classes=a.extend(!0,{},TableTools.classes);this.s.dt.bJUI&&a.extend(!0,this.classes,TableTools.classes_themeroller);this.fnSettings=function(){return this.s};"undefined"==typeof b&&(b={});this._fnConstruct(b);return this};TableTools.prototype={fnGetSelected:function(a){var b=[],d=this.s.dt.aoData,e=this.s.dt.aiDisplay,f;if(a){a=0;for(f=e.length;a"\u00a1".toString().length?b.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g,""):b.replace(/[^a-zA-Z0-9_\.,\-_ !\(\)]/g,"")},fnCalcColRatios:function(a){var b=this.s.dt.aoColumns, -a=this._fnColumnTargets(a.mColumns),d=[],e=0,f=0,k,m;k=0;for(m=a.length;kq?m:q)+"px";r.style.width=(n>s?n:s)+"px";r.className=this.classes.collection.background;a(r).css("opacity",0);d.body.appendChild(r);d.body.appendChild(f);m=a(f).outerWidth();n=a(f).outerHeight();k+m>s&&(f.style.left=s-m+"px");g+n>q&&(f.style.top=g-n-a(c).outerHeight()+ -"px");this.dom.collection.collection=f;this.dom.collection.background=r;setTimeout(function(){a(f).animate({opacity:1},500);a(r).animate({opacity:0.25},500)},10);this.fnResizeButtons();a(r).click(function(){j._fnCollectionHide.call(j,null,null)})},_fnCollectionHide:function(c,b){!(null!==b&&"collection"==b.sExtends)&&null!==this.dom.collection.collection&&(a(this.dom.collection.collection).animate({opacity:0},500,function(){this.style.display="none"}),a(this.dom.collection.background).animate({opacity:0}, +for(var a=TableTools._aInstances,b=0,d=a.length;bn?l:n)+"px";s.style.width=(p>v?p:v)+"px";s.className=this.classes.collection.background;a(s).css("opacity",0);d.body.appendChild(s);d.body.appendChild(f);l=a(f).outerWidth();p=a(f).outerHeight();k+l>v&&(f.style.left=v-l+"px");g+p>n&&(f.style.top=g-p-a(c).outerHeight()+ +"px");this.dom.collection.collection=f;this.dom.collection.background=s;setTimeout(function(){a(f).animate({opacity:1},500);a(s).animate({opacity:0.25},500)},10);this.fnResizeButtons();a(s).click(function(){j._fnCollectionHide.call(j,null,null)})},_fnCollectionHide:function(c,b){!(null!==b&&"collection"==b.sExtends)&&null!==this.dom.collection.collection&&(a(this.dom.collection.collection).animate({opacity:0},500,function(){this.style.display="none"}),a(this.dom.collection.background).animate({opacity:0}, 500,function(){this.parentNode.removeChild(this)}),this.dom.collection.collection=null,this.dom.collection.background=null)},_fnRowSelectConfig:function(){if(this.s.master){var c=this,b=this.s.dt;a(b.nTable).addClass(this.classes.select.table);a("tr",b.nTBody).live("click",function(a){this.parentNode==b.nTBody&&null!==b.oInstance.fnGetData(this)&&(c.fnIsSelected(this)?c._fnRowDeselect(this,a):"single"==c.s.select.type?(c.fnSelectNone(),c._fnRowSelect(this,a)):"multi"==c.s.select.type&&c._fnRowSelect(this, a))});b.oApi._fnCallbackReg(b,"aoRowCreatedCallback",function(d,e,f){b.aoData[f]._DTTT_selected&&a(d).addClass(c.classes.select.row)},"TableTools-SelectAll")}},_fnRowSelect:function(c,b){var d=this._fnSelectData(c),e=[],f,k;f=0;for(k=d.length;f/g,"").replace(/^\s+|\s+$/g,""),q=this._fnHtmlDecode(q), -k.push(this._fnBoundData(q,c.sFieldBoundary,r)));m.push(k.join(c.sFieldSeperator))}var p=n.aiDisplay;f=this.fnGetSelected();if("none"!==this.s.select.type&&e&&0!==f.length){p=[];b=0;for(d=f.length;b]+)).*?>/gi, -"$1$2$3"),q=q.replace(/<.*?>/g,"")):q+="",q=q.replace(/^\s+/,"").replace(/\s+$/,""),q=this._fnHtmlDecode(q),k.push(this._fnBoundData(q,c.sFieldBoundary,r)));m.push(k.join(c.sFieldSeperator));c.bOpenRows&&(b=a.grep(n.aoOpenRows,function(a){return a.nParent===s}),1===b.length&&(q=this._fnBoundData(a("td",b[0].nTr).html(),c.sFieldBoundary,r),m.push(q)))}if(c.bFooter&&null!==n.nTFoot){k=[];b=0;for(d=n.aoColumns.length;b/g,""),q=this._fnHtmlDecode(q),k.push(this._fnBoundData(q,c.sFieldBoundary,r)));m.push(k.join(c.sFieldSeperator))}return _sLastData=m.join(this._fnNewline(c))},_fnBoundData:function(a,b,d){return""===b?a:b+a.replace(d,b+b)+b},_fnChunkData:function(a,b){for(var d=[],e=a.length,f=0;f/g,"").replace(/^\s+|\s+$/g,""),n=this._fnHtmlDecode(n), +k.push(this._fnBoundData(n,c.sFieldBoundary,s)));l.push(k.join(c.sFieldSeperator))}var q=p.aiDisplay;f=this.fnGetSelected();if("none"!==this.s.select.type&&e&&0!==f.length){q=[];b=0;for(d=f.length;b]+)).*?>/gi, +"$1$2$3"),n=n.replace(/<.*?>/g,"")):n+="",n=n.replace(/^\s+/,"").replace(/\s+$/,""),n=this._fnHtmlDecode(n),k.push(this._fnBoundData(n,c.sFieldBoundary,s)));l.push(k.join(c.sFieldSeperator));c.bOpenRows&&(b=a.grep(p.aoOpenRows,function(a){return a.nParent===v}),1===b.length&&(n=this._fnBoundData(a("td",b[0].nTr).html(),c.sFieldBoundary,s),l.push(n)))}if(c.bFooter&&null!==p.nTFoot){k=[];b=0;for(d=p.aoColumns.length;b/g,""),n=this._fnHtmlDecode(n),k.push(this._fnBoundData(n,c.sFieldBoundary,s)));l.push(k.join(c.sFieldSeperator))}return _sLastData=l.join(this._fnNewline(c))},_fnBoundData:function(a,b,d){return""===b?a:b+a.replace(d,b+b)+b},_fnChunkData:function(a,b){for(var d=[],e=a.length,f=0;fTable copied

    Copied "+a+" row"+(1==a?"":"s")+" to the clipboard.

    ",1500)}}),pdf:a.extend({},TableTools.buttonBase,{sAction:"flash_pdf",sNewLine:"\n",sFileName:"*.pdf",sButtonClass:"DTTT_button_pdf", sButtonText:"PDF",sPdfOrientation:"portrait",sPdfSize:"A4",sPdfMessage:"",fnClick:function(a,b,d){this.fnSetText(d,"title:"+this.fnGetTitle(b)+"\nmessage:"+b.sPdfMessage+"\ncolWidth:"+this.fnCalcColRatios(b)+"\norientation:"+b.sPdfOrientation+"\nsize:"+b.sPdfSize+"\n--/TableToolsOpts--\n"+this.fnGetTableData(b))}}),print:a.extend({},TableTools.buttonBase,{sInfo:"
    Print view

    Please use your browser's print function to print this table. Press escape when finished.",sMessage:null,bShowAll:!0, @@ -978,4 +982,39 @@ TableTools.buttonBase,{sButtonText:"Deselect all",fnClick:function(){this.fnSele dataType:"json",type:"POST",cache:!1,error:function(){alert("Error detected when sending table data to server")}})},fnAjaxComplete:function(){alert("Ajax complete")}}),div:a.extend({},TableTools.buttonBase,{sAction:"div",sTag:"div",sButtonClass:"DTTT_nonbutton",sButtonText:"Text button"}),collection:a.extend({},TableTools.buttonBase,{sAction:"collection",sButtonClass:"DTTT_button_collection",sButtonText:"Collection",fnClick:function(a,b){this._fnCollectionShow(a,b)}})};TableTools.classes={container:"DTTT_container", buttons:{normal:"DTTT_button",disabled:"DTTT_disabled"},collection:{container:"DTTT_collection",background:"DTTT_collection_background",buttons:{normal:"DTTT_button",disabled:"DTTT_disabled"}},select:{table:"DTTT_selectable",row:"DTTT_selected"},print:{body:"DTTT_Print",info:"DTTT_print_info",message:"DTTT_PrintMessage"}};TableTools.classes_themeroller={container:"DTTT_container ui-buttonset ui-buttonset-multi",buttons:{normal:"DTTT_button ui-button ui-state-default"},collection:{container:"DTTT_collection ui-buttonset ui-buttonset-multi"}}; TableTools.DEFAULTS={sSwfPath:"media/swf/copy_csv_xls_pdf.swf",sRowSelect:"none",sSelectedClass:null,fnPreRowSelect:null,fnRowSelected:null,fnRowDeselected:null,aButtons:["copy","csv","xls","pdf","print"],oTags:{container:"div",button:"a",liner:"span",collection:{container:"div",button:"a",liner:"span"}}};TableTools.prototype.CLASS="TableTools";TableTools.VERSION="2.1.4";TableTools.prototype.VERSION=TableTools.VERSION;"function"==typeof a.fn.dataTable&&"function"==typeof a.fn.dataTableExt.fnVersionCheck&& -a.fn.dataTableExt.fnVersionCheck("1.9.0")?a.fn.dataTableExt.aoFeatures.push({fnInit:function(a){a=new TableTools(a.oInstance,"undefined"!=typeof a.oInit.oTableTools?a.oInit.oTableTools:{});TableTools._aInstances.push(a);return a.dom.container},cFeature:"T",sFeature:"TableTools"}):alert("Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download");a.fn.DataTable.TableTools=TableTools})(jQuery,window,document); +a.fn.dataTableExt.fnVersionCheck("1.9.0")?a.fn.dataTableExt.aoFeatures.push({fnInit:function(a){a=new TableTools(a.oInstance,"undefined"!=typeof a.oInit.oTableTools?a.oInit.oTableTools:{});TableTools._aInstances.push(a);return a.dom.container},cFeature:"T",sFeature:"TableTools"}):alert("Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download");a.fn.DataTable.TableTools=TableTools})(jQuery,window,document);!function(a){a.extend({tablesorter:new function(){function d(a){"undefined"!==typeof console&&"undefined"!==typeof console.log?console.log(a):alert(a)}function c(a,b){d(a+" ("+((new Date).getTime()-b.getTime())+"ms)")}function b(b,c,d){if(!c)return"";var e=b.config,f=e.textExtraction,g="",g="simple"===f?e.supportsTextContent?c.textContent:a(c).text():"function"===typeof f?f(c,b,d):"object"===typeof f&&f.hasOwnProperty(d)?f[d](c,b,d):e.supportsTextContent?c.textContent:a(c).text();return a.trim(g)} +function e(c,f){var g=c.config,j=a(c.tBodies).filter(":not(."+g.cssInfoBlock+")"),k=a.tablesorter,l,n,p,r,v,G,K="";if(0!==j.length){j=j[0].rows;if(j[0]){l=[];n=j[0].cells.length;for(p=0;p thead th",selectorRemove:"tr.remove-me",debug:!1,headerList:[],empties:{},strings:{},parsers:[]};this.benchmark=c;this.hasInitialized=!1;this.construct=function(q){return this.each(function(){if(this.tHead&& +0!==this.tBodies.length){var r,u,t,s,B,A,N,D,X,G=a.metadata;this.config={};u=a.extend(!0,this.config,a.tablesorter.defaults,q);u.debug&&a.data(this,"startoveralltimer",new Date);r=a(this).addClass(u.tableClass);a.data(this,"tablesorter",u);u.supportsTextContent="x"===a("x")[0].textContent;u.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:!0,bottom:!1};var K=[],O={},L=a(this).find("thead:eq(0) tr"),U,Q,M,V,z,S,R,T,H,I;for(U=0;U'+ +this.innerHTML+"";h.onRenderHeader&&h.onRenderHeader.apply(ca,[b]);this.column=O[this.parentNode.rowIndex+"-"+this.cellIndex];var c=wa.getData(ca,$,"sortInitialOrder")||h.sortInitialOrder;this.order=/^d/i.test(c)||1===c?[1,0,2]:[0,1,2];this.count=-1;"false"===wa.getData(ca,$,"sorter")&&(this.sortDisabled=!0);this.lockedOrder=!1;ea=wa.getData(ca,$,"lockedOrder")||!1;"undefined"!==typeof ea&&!1!==ea&&(this.order=this.lockedOrder=/^d/i.test(ea)||1===ea?[1,1,1]:[0,0,0]);this.sortDisabled||ca.addClass(h.cssHeader); +h.headerList[b]=this;ca.parent().addClass(h.cssHeader)});this.config.debug&&(c("Built headers:",la),d(ba));u.parsers=e(this,ba);u.delayInit||g(this);if(this.config.widthFixed){var Ma=a("");a("tr:first td",this.tBodies[0]).each(function(){Ma.append(a("").css("width",a(this).width()))});a(this).prepend(Ma)}ba.bind("mousedown.tablesorter mouseup.tablesorter",function(b,c){if("mousedown"===b.type)return X=(new Date).getTime(),!u.cancelSelection;if(!0!==c&&500<(new Date).getTime()-X)return!1; +u.delayInit&&!u.cache&&g(r[0]);if(!this.sortDisabled){r.trigger("sortStart",r[0]);a(this);B=!b[u.sortMultiSortKey];this.count=(this.count+1)%(u.sortReset?3:2);u.sortRestart&&(t=this,ba.each(function(){if(this!==t&&(B||!a(this).is("."+u.cssDesc+",."+u.cssAsc)))this.count=-1}));t=this.column;if(B){u.sortList=[];if(null!==u.sortForce){A=u.sortForce;for(s=0;sD&&(u.sortList.push([t,D]),1D&&(u.sortList.push([t,D]),1 +d)return 1}g=Math.max(b.length,e.length);for(f=0;fc)return 1}return 0};this.sortTextDesc=function(a,b,c,d){if(b===c)return 0;var e=a.config,f=e.string[e.empties[d]||e.emptyTo];return""===b&&0!==f?"boolean"===typeof f?f?-1:1:f||1:""===c&&0!==f?"boolean"===typeof f?f?1:-1:-f||-1:"function"=== +typeof e.textSorter?e.textSorter(c,b,a,d):this.sortText(a,c,b)};this.getTextValue=function(a,b,c){if(b){for(var d=a.length,e=b+c,b=0;bc&&(p=c);for(s=0;sc&&(t=c);for(s=0;s"+ -b.chartData[g].percent+"%";return b};a.getSessionDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-sessions"]},{data:[],label:jQuery.i18n.map["common.table.new-sessions"]},{data:[],label:jQuery.i18n.map["common.table.unique-sessions"]}],[{name:"t"},{name:"n"},{name:"u"}])};a.getSessionDPTotal=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-sessions"], -color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.total-sessions"],color:"#333933"}],[{name:"pt",func:function(a){return a.t},period:"previous"},{name:"t"}])};a.getUserDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"]},{data:[],label:jQuery.i18n.map["common.table.new-users"]},{data:[],label:jQuery.i18n.map["common.table.returning-users"]}],[{name:"u"},{name:"n"},{name:"returning",func:function(a){return a.u- -a.n}}])};a.getUserDPActive=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.total-users"],color:"#333933"}],[{name:"pt",func:function(a){return a.u},period:"previous"},{name:"t",func:function(a){return a.u}}])};a.getUserDPNew=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.new-users"], -color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.new-users"],color:"#333933"}],[{name:"pn",func:function(a){return a.n},period:"previous"},{name:"n"}])};a.getDurationDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.time-spent"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.time-spent"],color:"#333933"}],[{name:"previous_t",func:function(a){return(a.d/60).toFixed(1)},period:"previous"}, -{name:"t",func:function(a){return(a.d/60).toFixed(1)}}])};a.getDurationDPAvg=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.average-time"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.average-time"],color:"#333933"}],[{name:"previous_average",func:function(a){return 0==a.t?0:(a.d/a.t/60).toFixed(1)},period:"previous"},{name:"average",func:function(a){return 0==a.t?0:(a.d/a.t/60).toFixed(1)}}])};a.getEventsDP= -function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.reqs-received"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.reqs-received"],color:"#333933"}],[{name:"pe",func:function(a){return a.e},period:"previous"},{name:"e"}])};a.getEventsDPAvg=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.avg-reqs-received"],color:"#DDDDDD",mode:"ghost"}, -{data:[],label:jQuery.i18n.map["common.graph.avg-reqs-received"],color:"#333933"}],[{name:"previous_average",func:function(a){return 0==a.u?0:(a.e/a.u).toFixed(1)},period:"previous"},{name:"average",func:function(a){return 0==a.u?0:(a.e/a.u).toFixed(1)}}])};a.clearSessionObject=function(a){a?(a.t||(a.t=0),a.n||(a.n=0),a.u||(a.u=0),a.d||(a.d=0),a.e||(a.e=0)):a={t:0,n:0,u:0,d:0,e:0};return a};a.explainDurationRange=function(a){var b=jQuery.i18n.map["common.seconds"],d=jQuery.i18n.map["common.minutes"]; -return["0-10 "+b,"11-30 "+b,"31-60 "+b,"1-3 "+d,"3-10 "+d,"10-30 "+d,"30-60 "+d,"> 1 "+jQuery.i18n.map["common.hour"]][a]};a.getDurationIndex=function(a){var b=jQuery.i18n.map["common.seconds"],d=jQuery.i18n.map["common.minutes"];return["0-10 "+b,"11-30 "+b,"31-60 "+b,"1-3 "+d,"3-10 "+d,"10-30 "+d,"30-60 "+d,"> 1 "+jQuery.i18n.map["common.hour"]].indexOf(a)};a.getTopUserBars=function(){var b=[],d=0,c=3,f=0,h=countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"]}], -[{name:"t",func:function(a){return a.u}}]),h=_.sortBy(_.reject(h.chartData,function(a){return 0==a.t}),function(a){return-a.t});3>h.length&&(c=h.length);for(var g=0;gb.maxCountries&& -(d.chartData=d.chartData.splice(0,b.maxCountries));return d.chartData});a.clearLocationObject=function(a){a?(a.t||(a.t=0),a.n||(a.n=0),a.u||(a.u=0)):a={t:0,n:0,u:0};return a}})(window.countlyCity=window.countlyCity||{},jQuery);(function(a,b){function c(){var d={cols:[],rows:[]};g=new google.visualization.GeoChart(document.getElementById(j));var c=countlyCommon.extractTwoLevelData(e,h,a.clearLocationObject,[{name:"country",func:function(b){return a.getCountryName(b)}},{name:"t"}]);d.cols=[{id:"country",label:jQuery.i18n.map["countries.table.country"],type:"string"},{id:"total",label:jQuery.i18n.map["common.total"],type:"number"}];d.rows=_.map(c.chartData,function(a){return"European Union"==a.country||"Unknown"==a.country? -{c:[{v:""},{v:a.t}]}:{c:[{v:a.country},{v:a.t}]}});i=new google.visualization.DataTable(d);m.region="world";m.resolution="countries";m.displayMode="region";!1!==countlyCommon.CITY_DATA&&300b.maxCountries&&(d.chartData=d.chartData.splice(0,b.maxCountries));for(b=0;b"+ -d.chartData[b].country;return _.sortBy(d.chartData,function(a){return-a.t})};a.clearLocationObject=function(a){a?(a.t||(a.t=0),a.n||(a.n=0),a.u||(a.u=0)):a={t:0,n:0,u:0};return a};a.getCountryName=function(a){return(a=k[a.toUpperCase()])?a:"Unknown"};a.changeLanguage=function(){return b.get("/localization/countries/"+countlyCommon.BROWSER_LANG_SHORT+"/country.json",function(a){k=a})}})(window.countlyLocation=window.countlyLocation||{},jQuery);(function(a,b){function c(){e.meta?(d=e.meta["l-ranges"]?e.meta["l-ranges"]:[],h=e.meta["f-ranges"]?e.meta["f-ranges"]:[]):(d=[],h=[])}var f={},e={},d=[],h=[];a.initialize=function(){return countlyCommon.DEBUG?(e={2012:{}},!0):b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"users"},dataType:"jsonp",success:function(a){e=a;c()}})};a.refresh=a.initialize;a.reset=function(){e={};c()};a.getFrequencyData=function(){var b= -{chartData:{},chartDP:{dp:[],ticks:[]}};b.chartData=countlyCommon.extractRangeData(e,"f",h,a.explainFrequencyRange);var d=_.pluck(b.chartData,"f"),c=_.pluck(b.chartData,"t"),f=[{data:[]}];f[0].data[0]=[-1,null];f[0].data[d.length+1]=[d.length,null];b.chartDP.ticks.push([-1,""]);b.chartDP.ticks.push([d.length,""]);for(var k=0;k"+b.chartData[k].percent+"%";return b};a.getLoyaltyData=function(){var b={chartData:{},chartDP:{dp:[],ticks:[]}};b.chartData=countlyCommon.extractRangeData(e,"l",d,a.explainLoyaltyRange);var c=_.pluck(b.chartData,"l"),f=_.pluck(b.chartData,"t"),h=[{data:[]}];h[0].data[0]=[-1,null];h[0].data[c.length+1]=[c.length,null];b.chartDP.ticks.push([-1,""]);b.chartDP.ticks.push([c.length,""]);for(var k=0;k"+b.chartData[k].percent+"%";return b};a.getLoyaltyDP=function(){f=countlyCommon.periodObj;for(var a=[{data:[],label:jQuery.i18n.map["user-loyalty.loyalty"]}],b=[],c,h=0;h 500".split(";")[a]};a.getLoyaltyIndex=function(a){return"1;2;3-5;6-9;10-19;20-49;50-99;100-499;> 500".split(";").indexOf(a)}})(window.countlyUser= -window.countlyUser||{},jQuery);(function(a,b){function c(){d=e.meta?e.meta.devices?e.meta.devices:[]:[]}var f={},e={},d=[],h=0,g=!1;a.initialize=function(){if(g&&h==countlyCommon.ACTIVE_APP_KEY)return a.refresh();if(countlyCommon.DEBUG)return e={2012:{}},!0;h=countlyCommon.ACTIVE_APP_KEY;g=!0;return b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"devices"},dataType:"jsonp",success:function(a){e=a;c()}})};a.refresh=function(){f=countlyCommon.periodObj; -return countlyCommon.DEBUG?(e={2012:{}},!0):h!=countlyCommon.ACTIVE_APP_KEY?(h=countlyCommon.ACTIVE_APP_KEY,a.initialize()):b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"devices",action:"refresh"},dataType:"jsonp",success:function(a){countlyCommon.extendDbObj(e,a);c()}})};a.reset=function(){e={};c()};a.getDeviceData=function(){var b=countlyCommon.extractTwoLevelData(e,d,a.clearDeviceObject,[{name:"device", -func:function(b){return a.getDeviceFullName(b)}},{name:"t"},{name:"u"},{name:"n"}]),c=_.pluck(b.chartData,"device"),f=_.pluck(b.chartData,"u"),h=_.pluck(b.chartData,"n"),g=[],n=[];_.reduce(f,function(a,b){return a+b},0);for(var p=0;p"+a.split("x")[0]+""}},{name:"height",func:function(a){return""+ -a.split("x")[1]+""}},{name:"t"},{name:"u"},{name:"n"}]),c=_.pluck(b.chartData,"resolution"),e=_.pluck(b.chartData,"u"),h=_.pluck(b.chartData,"n"),g=[],i=[];_.reduce(e,function(a,b){return a+b},0);for(var j=0;jc.all[f].trend?"d":"u";c.all.avgduration.total=0==c.all.sessions.total?0:c.all.duration.total/ -c.all.sessions.total;a=c.all.duration.total.toFixed(1)+" "+jQuery.i18n.map["common.minute.abrv"];142560<=c.all.duration.total?a=(c.all.duration.total/525600).toFixed(1)+" "+jQuery.i18n.map["common.year.abrv"]:1440<=c.all.duration.total?a=(c.all.duration.total/1440).toFixed(1)+" "+jQuery.i18n.map["common.day.abrv"]:60<=c.all.duration.total&&(a=(c.all.duration.total/60).toFixed(1)+" "+jQuery.i18n.map["common.hour.abrv"]);c.all.duration.total=a;a=c.all.avgduration.total.toFixed(1)+" "+jQuery.i18n.map["common.minute.abrv"]; -142560<=c.all.avgduration.total?a=(c.all.avgduration.total/525600).toFixed(1)+" "+jQuery.i18n.map["common.year.abrv"]:1440<=c.all.avgduration.total?a=(c.all.avgduration.total/1440).toFixed(1)+" "+jQuery.i18n.map["common.day.abrv"]:60<=c.all.avgduration.total&&(a=(c.all.avgduration.total/60).toFixed(1)+" "+jQuery.i18n.map["common.hour.abrv"]);c.all.avgduration.total=a})};a.reset=function(){f={}};a.getData=function(){var a=[],b;for(b in c)a.push(c[b]);return a};a.getSessionData=function(){return e}; -a.setApp=function(a){h=a;countlyCommon.setActiveApp(h)};var g=function(a){countlyCommon.setActiveApp(a);return b.when(countlySession.initialize()).done(function(){var b=countlySession.getSessionData();f[a]||(d[a]=b,e[a]={"#draw-total-users":countlySession.getUserDPActive().chartDP[1],"#draw-new-users":countlySession.getUserDPNew().chartDP[1],"#draw-total-sessions":countlySession.getSessionDPTotal().chartDP[1],"#draw-time-spent":countlySession.getDurationDPAvg().chartDP[1],"#draw-total-time-spent":countlySession.getDurationDP().chartDP[1], -"#draw-avg-events-served":countlySession.getEventsDPAvg().chartDP[1]},c[a]={_id:a,name:countlyGlobal.apps[a].name,sessions:b.usage["total-sessions"],users:b.usage["total-users"],newusers:b.usage["new-users"],duration:b.usage["total-duration"],avgduration:b.usage["avg-duration-per-session"]},f[a]=!0)})},i=function(a){if("NA"==a||"\u221e"==a)return 0;var a=a.slice(0,-1),b=1;"K"==a.slice(-1)?(a=a.slice(0,-1),b=1E3):"M"==a.slice(-1)&&(a=a.slice(0,-1),b=1E6);return parseFloat(a)*b}})(window.countlyAllApps= -window.countlyAllApps||{},jQuery);var countlyView=Backbone.View.extend({template:null,templateData:{},el:$("#content"),initialize:function(){this.template=Handlebars.compile($("#template-analytics-common").html())},dateChanged:function(){this.renderCommon()},appChanged:function(){countlyEvent.reset();var a=this;$.when(countlyEvent.initialize()).then(function(){a.render()})},beforeRender:function(){return!0},afterRender:function(){},render:function(){$("#content-top").html("");this.el.html('

    ');if(countlyCommon.ACTIVE_APP_ID){var a= -this;$.when(this.beforeRender(),initializeOnce()).then(function(){a.renderCommon();a.afterRender();app.pageScript()})}else this.renderCommon(),this.afterRender(),app.pageScript();return this},renderCommon:function(){},refresh:function(){return!0},restart:function(){this.refresh()},destroy:function(){}}),initializeOnce=_.once(function(){return $.when(countlyEvent.initialize()).then(function(){})}),Template=function(){this.cached={}},T=new Template; -$.extend(Template.prototype,{render:function(a,b){T.isCached(a)?b(T.cached[a]):$.get(T.urlFor(a),function(c){T.store(a,c);T.render(a,b)})},renderSync:function(a,b){T.isCached(a)||T.fetch(a);T.render(a,b)},prefetch:function(a){$.get(T.urlFor(a),function(b){T.store(a,b)})},fetch:function(a){if(!T.isCached(a)){var b=$.ajax({url:T.urlFor(a),async:!1}).responseText;T.store(a,b)}},isCached:function(a){return!!T.cached[a]},store:function(a,b){T.cached[a]=Handlebars.compile(b)},urlFor:function(a){return a+ -".html"}}); -(function(a,b){function c(a){b("body").append(a);var c=a.height(),d=a.width();a.css({height:c,"margin-top":Math.floor(-c/2),width:d,"margin-left":Math.floor(-d/2)});b("#overlay").fadeIn();a.fadeIn()}a.popup=function(a,e){var d=b("#cly-popup").clone();d.removeAttr("id");e&&d.addClass(e);d.find(".content").html(b(a).html());c(d)};a.alert=function(a,e){var d=b("#cly-alert").clone();d.removeAttr("id");d.find(".message").html(a);d.addClass(e);c(d)};a.confirm=function(a,e,d,h){var g=b("#cly-confirm").clone();g.removeAttr("id"); -g.find(".message").text(a);h&&2==h.length&&(g.find("#dialog-cancel").text(h[0]),g.find("#dialog-continue").text(h[1]));g.addClass(e);c(g);g.find("#dialog-cancel").on("click",function(){d(!1)});g.find("#dialog-continue").on("click",function(){d(!0)})};a.refreshTable=function(a,b){var d=a.fnSettings();a.fnClearTable(!1);for(var c=0;c
    ").insertBefore(b(this).find(".select-items"))); -b(this).hasClass("centered")&&(c=b(this).find(".select-items").height(),b(this).find(".select-items").css("margin-top",-(c/2).toFixed(0)-(b(this).height()/2).toFixed(0)+"px"));b(this).find(".select-items").is(":visible")?b(this).find(".select-items").hide():(b(this).find(".select-items").show(),b(this).find(".select-items>div").addClass("scroll-list"),b(this).find(".scroll-list").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0}));b(this).find(".search input").focus(); -b("#date-picker").hide();a.stopPropagation()});b("#content-container").on("click",".select-items .item",function(){var a=b(this).parents(".cly-select").find(".text");a.text(b(this).text());a.data("value",b(this).data("value"))});b("#content-container").on("click",".cly-select .search",function(a){a.stopPropagation()});b("#content-container").on("keyup",".cly-select .search input",function(){b(this).val()?(b(this).parents(".cly-select").find(".item:not(:contains('"+b(this).val()+"'))").addClass("hidden"), -b(this).parents(".cly-select").find(".item:contains('"+b(this).val()+"')").removeClass("hidden")):b(this).parents(".cly-select").find(".item").removeClass("hidden")});b(window).click(function(){b(".select-items").hide();b(".cly-select").find(".search").remove()})};b(document).ready(function(){function a(b){if(-1!=b.indexOf(":"))return-1!=b.indexOf(",")?(b=b.replace(/,|:/g,""),b=b.split(" "),parseInt(1E6*(moment.monthsShort.indexOf(b[1])+1))+1E4*parseInt(b[0])+parseInt(b[2])):parseInt(b.replace(":", -""));if(3==b.length)return moment.monthsShort.indexOf(b);b=b.replace(",","");b=b.split(" ");return 3==b.length?1E4*parseInt(b[2])+parseInt(100*moment.monthsShort.indexOf(b[1]))+parseInt(b[0]):parseInt(100*moment.monthsShort.indexOf(b[1]))+parseInt(b[0])}function c(a){var a=a.split("-")[0],b="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");if(-1!=a.indexOf(":")){var f=a.split(" ")[1].split(",")[0];return a.replace(f,parseInt(b.indexOf(f))).replace(/[:, ]/g,"")}a=a.split(" ");return 1<]/g,"")}b("#overlay").click(function(){b(".dialog:visible").fadeOut().remove();b(this).hide()});b("#dialog-ok, #dialog-cancel, #dialog-continue").live("click",function(){b(".dialog:visible").fadeOut().remove();b("#overlay").hide()});b(document).keyup(function(a){27==a.keyCode&&(b(".dialog:visible").offset(),b(".dialog:visible").animate({top:0,opacity:0},{duration:1E3,easing:"easeOutQuart",complete:function(){b(this).remove()}}),b("#overlay").hide())}); -b.fn.dataTableExt.oPagination.four_button={fnInit:function(a,c,f){nFirst=document.createElement("span");nPrevious=document.createElement("span");nNext=document.createElement("span");nLast=document.createElement("span");nFirst.innerHTML="";nPrevious.innerHTML="";nNext.innerHTML="";nLast.innerHTML="";nFirst.className="paginate_button first";nPrevious.className= -"paginate_button previous";nNext.className="paginate_button next";nLast.className="paginate_button last";c.appendChild(nFirst);c.appendChild(nPrevious);c.appendChild(nNext);c.appendChild(nLast);b(nFirst).click(function(){a.oApi._fnPageChange(a,"first");f(a)});b(nPrevious).click(function(){a.oApi._fnPageChange(a,"previous");f(a)});b(nNext).click(function(){a.oApi._fnPageChange(a,"next");f(a)});b(nLast).click(function(){a.oApi._fnPageChange(a,"last");f(a)});b(nFirst).bind("selectstart",function(){return!1}); -b(nPrevious).bind("selectstart",function(){return!1});b(nNext).bind("selectstart",function(){return!1});b(nLast).bind("selectstart",function(){return!1})},fnUpdate:function(a){if(a.aanFeatures.p)for(var b=a.aanFeatures.p,c=0,f=b.length;cc?1:0};jQuery.fn.dataTableExt.oSort["customDate-desc"]= -function(b,c){b=a(b);c=a(c);return bc?-1:0};jQuery.fn.dataTableExt.oSort["dateRange-asc"]=function(a,b){a=c(a);b=c(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["dateRange-desc"]=function(a,b){a=c(a);b=c(b);return ab?-1:0};jQuery.fn.dataTableExt.oSort["percent-asc"]=function(a,c){a=parseFloat(b("").html(a).text().replace("%",""));c=parseFloat(b("").html(c).text().replace("%",""));return ac?1:0};jQuery.fn.dataTableExt.oSort["percent-desc"]=function(a,c){a= -parseFloat(b("").html(a).text().replace("%",""));c=parseFloat(b("").html(c).text().replace("%",""));return ac?-1:0};jQuery.fn.dataTableExt.oSort["formatted-num-asc"]=function(a,b){var c=[],c=[],a=a.replace(/[^\d\-\.\/]/g,""),b=b.replace(/[^\d\-\.\/]/g,"");0<=a.indexOf("/")&&(c=a.split("/"),a=parseInt(c[0],10)/parseInt(c[1],10));0<=b.indexOf("/")&&(c=b.split("/"),b=parseInt(c[0],10)/parseInt(c[1],10));return a-b};jQuery.fn.dataTableExt.oSort["formatted-num-desc"]=function(a,b){var c= -[],c=[],a=a.replace(/[^\d\-\.\/]/g,""),b=b.replace(/[^\d\-\.\/]/g,"");0<=a.indexOf("/")&&(c=a.split("/"),a=parseInt(c[0],10)/parseInt(c[1],10));0<=b.indexOf("/")&&(c=b.split("/"),b=parseInt(c[0],10)/parseInt(c[1],10));return b-a};jQuery.fn.dataTableExt.oSort["loyalty-asc"]=function(a,b){a=countlyUser.getLoyaltyIndex(a);b=countlyUser.getLoyaltyIndex(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["loyalty-desc"]=function(a,b){a=countlyUser.getLoyaltyIndex(a);b=countlyUser.getLoyaltyIndex(b); -return ab?-1:0};jQuery.fn.dataTableExt.oSort["frequency-asc"]=function(a,b){a=countlyUser.getFrequencyIndex(a);b=countlyUser.getFrequencyIndex(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["frequency-desc"]=function(a,b){a=countlyUser.getFrequencyIndex(a);b=countlyUser.getFrequencyIndex(b);return ab?-1:0};jQuery.fn.dataTableExt.oSort["session-duration-asc"]=function(a,b){a=countlySession.getDurationIndex(a);b=countlySession.getDurationIndex(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["session-duration-desc"]= -function(a,b){a=countlySession.getDurationIndex(a);b=countlySession.getDurationIndex(b);return ab?-1:0};b.extend(b.fn.dataTable.defaults,{sDom:'<"dataTable-top"fpT>t<"dataTable-bottom"i>',bAutoWidth:!1,sPaginationType:"four_button",iDisplayLength:50,bDestroy:!0,bDeferRender:!0,oTableTools:{sSwfPath:"/javascripts/dom/dataTables/swf/copy_csv_xls.swf",aButtons:[{sExtends:"csv",sButtonText:"Save to CSV",fnClick:function(a,c,f){for(var a=b(a).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, -c=this.fnGetTableData(c).split(/\r\n|\r|\n/g).join('","').split('","'),e="",j=0;j=a.length){var m=j%a.length;"formatted-num"==a[m].sType?c[j]=c[j].replace(/,/g,""):"percent"==a[m].sType&&(c[j]=c[j].replace("%",""))}e=0==(j+1)%a.length?e+('"'+c[j]+'"\r\n'):e+('"'+c[j]+'", ')}this.fnSetText(f,e)}},{sExtends:"xls",sButtonText:"Save for Excel",fnClick:function(a,c,f){for(var a=b(a).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns, -c=this.fnGetTableData(c).split(/\r\n|\r|\n/g).join("\t").split("\t"),e="",j=0;j=a.length){var m=j%a.length;"formatted-num"==a[m].sType?c[j]=parseFloat(c[j].replace(/,/g,"")).toLocaleString():"percent"==a[m].sType?c[j]=parseFloat(c[j].replace("%","")).toLocaleString():"numeric"==a[m].sType&&(c[j]=parseFloat(c[j]).toLocaleString())}e=0==(j+1)%a.length?e+(c[j]+"\r\n"):e+(c[j]+"\t")}this.fnSetText(f,e)}}]},fnInitComplete:function(a){a=b("#"+a.sTableId+"_wrapper");b("
    ").insertBefore(a.find(".DTTT_container")); -b("
    ").insertBefore(a.find(".dataTables_filter"));a.find(".dataTables_filter").html(a.find(".dataTables_filter").find("input").attr("Placeholder","Search").clone(!0));a.find(".save-table-data").on("click",function(){"hidden"==b(this).next(".DTTT_container").css("visibility")?b(this).next(".DTTT_container").css("visibility","visible"):b(this).next(".DTTT_container").css("visibility","hidden")});a.find(".search-table-data").on("click",function(){b(this).next(".dataTables_filter").toggle(); -b(this).next(".dataTables_filter").find("input").focus()});a.css({"min-height":a.height()})}});b.fn.dataTableExt.sErrMode="throw"})})(window.CountlyHelpers=window.CountlyHelpers||{},jQuery);$.expr[":"].contains=$.expr.createPseudo(function(a){return function(b){return 0<=$(b).text().toUpperCase().indexOf(a.toUpperCase())}}); -function fillKeyEvents(a){if(!a.length)return!0;$("#key-events").html("");for(var b=0;b\t\t\t\t\t\t\t\t\t
    "+a[b][c].code+"
    \t\t\t\t\t
    "+a[b][c].desc+"
    \t\t\t\t\t\t\t")} -window.DashboardView=countlyView.extend({selectedView:"#draw-total-sessions",initialize:function(){this.template=Handlebars.compile($("#dashboard-template").html())},beforeRender:function(){return $.when(countlySession.initialize(),countlyLocation.initialize(),countlyDevice.initialize(),countlyCarrier.initialize(),countlyDeviceDetails.initialize()).then(function(){})},afterRender:function(){countlyLocation.drawGeoChart({height:290})},dateChanged:function(){this.renderCommon(!1,!0);countlyLocation.drawGeoChart({height:290}); -switch(this.selectedView){case "#draw-total-users":_.defer(function(){sessionDP=countlySession.getUserDPActive();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")});break;case "#draw-new-users":_.defer(function(){sessionDP=countlySession.getUserDPNew();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")});break;case "#draw-total-sessions":_.defer(function(){sessionDP=countlySession.getSessionDPTotal();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")}); -break;case "#draw-time-spent":_.defer(function(){sessionDP=countlySession.getDurationDPAvg();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")});break;case "#draw-total-time-spent":_.defer(function(){sessionDP=countlySession.getDurationDP();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")});break;case "#draw-avg-events-served":_.defer(function(){sessionDP=countlySession.getEventsDPAvg();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")})}},pageScript:function(){$("#total-user-estimate-ind").on("click", -function(){CountlyHelpers.alert($("#total-user-estimate-exp").html(),"black")});$(".widget-content .inner").click(function(){$(".big-numbers").removeClass("active");$(".big-numbers .select").removeClass("selected");$(this).parent(".big-numbers").addClass("active");$(this).find(".select").addClass("selected")});$(".bar-inner").on({mouseenter:function(){var a=$(this).parent().next();a.text($(this).data("item"));a.css({color:$(this).css("background-color")})},mouseleave:function(){var a=$(this).parent().next(); -a.text(a.data("item"));a.css({color:$(this).parent().find(".bar-inner:first-child").css("background-color")})}});var a=this;$(".big-numbers .inner").click(function(){var b=$(this).find(".select").attr("id");if(a.selectedView=="#"+b)return!0;a.selectedView="#"+b;var c;switch(b){case "draw-total-users":_.defer(function(){sessionDP=countlySession.getUserDPActive();c=countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");fillKeyEvents(c)});break;case "draw-new-users":_.defer(function(){sessionDP= -countlySession.getUserDPNew();c=countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");fillKeyEvents(c)});break;case "draw-total-sessions":_.defer(function(){sessionDP=countlySession.getSessionDPTotal();c=countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");fillKeyEvents(c)});break;case "draw-time-spent":_.defer(function(){sessionDP=countlySession.getDurationDPAvg();c=countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");fillKeyEvents(c)});break;case "draw-total-time-spent":_.defer(function(){sessionDP= -countlySession.getDurationDP();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")});break;case "draw-avg-events-served":_.defer(function(){sessionDP=countlySession.getEventsDPAvg();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")})}});app.localize()},renderCommon:function(a,b){var c=countlySession.getSessionData(),f=countlyLocation.getLocationData({maxCountries:7}),e=countlySession.getSessionDPTotal();c["country-data"]=f;c["page-title"]=countlyCommon.getDateRange(); -c.usage=[{title:jQuery.i18n.map["common.total-sessions"],data:c.usage["total-sessions"],id:"draw-total-sessions",help:"dashboard.total-sessions"},{title:jQuery.i18n.map["common.total-users"],data:c.usage["total-users"],id:"draw-total-users",help:"dashboard.total-users"},{title:jQuery.i18n.map["common.new-users"],data:c.usage["new-users"],id:"draw-new-users",help:"dashboard.new-users"},{title:jQuery.i18n.map["dashboard.time-spent"],data:c.usage["total-duration"],id:"draw-total-time-spent",help:"dashboard.total-time-spent"}, -{title:jQuery.i18n.map["dashboard.avg-time-spent"],data:c.usage["avg-duration-per-session"],id:"draw-time-spent",help:"dashboard.avg-time-spent2"},{title:jQuery.i18n.map["dashboard.avg-reqs-received"],data:c.usage["avg-events"],id:"draw-avg-events-served",help:"dashboard.avg-reqs-received"}];c.bars=[{title:jQuery.i18n.map["common.bar.top-platform"],data:countlyDeviceDetails.getPlatformBars(),help:"dashboard.top-platforms"},{title:jQuery.i18n.map["common.bar.top-resolution"],data:countlyDeviceDetails.getResolutionBars(), -help:"dashboard.top-resolutions"},{title:jQuery.i18n.map["common.bar.top-carrier"],data:countlyCarrier.getCarrierBars(),help:"dashboard.top-carriers"},{title:jQuery.i18n.map["common.bar.top-users"],data:countlySession.getTopUserBars(),help:"dashboard.top-users"}];this.templateData=c;a||($(this.el).html(this.template(this.templateData)),$(this.selectedView).parents(".big-numbers").addClass("active"),this.pageScript(),b||(c=countlyCommon.drawTimeGraph(e.chartDP,"#dashboard-graph"),fillKeyEvents(c)))}, -restart:function(){this.refresh(!0)},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container"));$(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary"));$(".widget-header .title").replaceWith(newPage.find(".widget-header .title"));$(a.selectedView).parents(".big-numbers").addClass("active"); -switch(a.selectedView){case "#draw-total-users":sessionDP=countlySession.getUserDPActive();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");break;case "#draw-new-users":sessionDP=countlySession.getUserDPNew();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");break;case "#draw-total-sessions":sessionDP=countlySession.getSessionDPTotal();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");break;case "#draw-time-spent":sessionDP=countlySession.getDurationDPAvg(); -countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");break;case "#draw-total-time-spent":sessionDP=countlySession.getDurationDP();countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph");break;case "#draw-avg-events-served":sessionDP=countlySession.getEventsDPAvg(),countlyCommon.drawTimeGraph(sessionDP.chartDP,"#dashboard-graph")}$(".usparkline").peity("bar",{width:"100%",height:"30",colour:"#6BB96E",strokeColour:"#6BB96E",strokeWidth:2});$(".dsparkline").peity("bar",{width:"100%", -height:"30",colour:"#C94C4C",strokeColour:"#C94C4C",strokeWidth:2});0==newPage.find("#map-list-right").length&&$("#map-list-right").remove();$("#map-list-right").length?$("#map-list-right").replaceWith(newPage.find("#map-list-right")):$(".widget.map-list").prepend(newPage.find("#map-list-right"));a.pageScript()})},destroy:function(){}}); -window.SessionView=countlyView.extend({beforeRender:function(){return $.when(countlySession.initialize()).then(function(){})},renderCommon:function(a){var b=countlySession.getSessionData(),c=countlySession.getSessionDP();this.templateData={"page-title":jQuery.i18n.map["sessions.title"],"logo-class":"sessions","big-numbers":{count:3,items:[{title:jQuery.i18n.map["common.total-sessions"],total:b.usage["total-sessions"].total,trend:b.usage["total-sessions"].trend,help:"sessions.total-sessions"},{title:jQuery.i18n.map["common.new-sessions"], -total:b.usage["new-users"].total,trend:b.usage["new-users"].trend,help:"sessions.new-sessions"},{title:jQuery.i18n.map["common.unique-sessions"],total:b.usage["total-users"].total,trend:b.usage["total-users"].trend,help:"sessions.unique-sessions"}]}};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawTimeGraph(c.chartDP,"#dashboard-graph"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:c.chartData,aoColumns:[{mData:"date",sType:"customDate",sTitle:jQuery.i18n.map["common.date"]}, +(function(a,b){function d(){var a={cols:[],rows:[]};e=new google.visualization.GeoChart(document.getElementById(h));a.cols=[{id:"country",label:jQuery.i18n.map["countries.table.country"],type:"string"},{id:"total",label:jQuery.i18n.map["common.total"],type:"number"}];a.rows=_.map(f,function(c){c.country=g[c.country]||"Unknown";return"European Union"==c.country||"Unknown"==c.country?{c:[{v:""},{v:c.value}]}:{c:[{v:c.country},{v:c.value}]}});c=new google.visualization.DataTable(a);i.region="world"; +i.resolution="countries";i.displayMode="region";e.draw(c,i)}var e,c,h="geo-chart",i={displayMode:"region",colorAxis:{minValue:0,colors:["#D7F1D8","#6BB96E"]},resolution:"countries",toolTip:{textStyle:{color:"#FF0000"},showColorCode:!1},legend:"none",backgroundColor:"transparent",datalessRegionColor:"#FFF"},f=[],g={};b.get("localization/countries/en/country.json",function(c){g=c});a.drawGeoChart=function(c,a){c&&(c.chartElementId&&(h=c.chartElementId),c.height&&(i.height=c.height,i.width=556*c.height/ +347));f=a;google.visualization?d():google.load("visualization","1",{packages:["geochart"],callback:d})}})(window.countlyMapHelper=window.countlyMapHelper||{},jQuery);(function(a,b,d){var e={},c={},h="",i="",f=[],g=[],j={},l=0,k=!1,p=null;a.initialize=function(d){if(!d&&k&&p==countlyCommon.getPeriodForAjax()&&l==countlyCommon.ACTIVE_APP_KEY)return a.refresh();p=countlyCommon.getPeriodForAjax();if(countlyCommon.DEBUG)return e={2012:{}},!0;l=countlyCommon.ACTIVE_APP_KEY;k=!0;return b.when(b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"get_events",period:p},dataType:"jsonp", +success:function(b){c=b;!h&&a.getEvents()[0]&&(h=a.getEvents()[0].key)}}),b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"events",event:h,segmentation:i,period:p},dataType:"jsonp",success:function(c){e=c;j=e.meta||{};f=j.segments||[];f.sort();g=j[i]?j[i]:[]}})).then(function(){return!0})};a.refresh=function(){return countlyCommon.DEBUG?(e={2012:{}},!0):b.when(b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r, +data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"get_events"},dataType:"jsonp",success:function(b){c=b;!h&&a.getEvents()[0]&&(h=a.getEvents()[0].key)}}),b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"events",action:"refresh",event:h,segmentation:i},dataType:"jsonp",success:function(c){countlyCommon.extendDbObj(e,c);for(var a in e.meta)j[a]=countlyCommon.union(j[a],e.meta[a]); +(f=j.segments)&&f.sort();g=j[i]?j[i]:[]}})).then(function(){return!0})};a.reset=function(){e={};c={};i=h="";f=[];g=[];j={};l=0;k=!1};a.refreshEvents=function(){if(countlyCommon.DEBUG)return c={},!0;b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"get_events"},dataType:"jsonp",success:function(b){c=b;!h&&a.getEvents()[0]&&(h=a.getEvents()[0].key)}})};a.setActiveEvent=function(c,d){e={};i="";f=[];g=[];j={};h= +c;b.when(a.initialize(!0)).then(d)};a.setActiveSegmentation=function(c,h){e={};i=c;b.when(a.initialize(!0)).then(h)};a.getActiveSegmentation=function(){return i?i:jQuery.i18n.map["events.no-segmentation"]};a.isSegmentedView=function(){return i?!0:!1};a.getEventData=function(){var b={},b=c?c.map?c.map:{}:{},k=b[h]&&b[h].count?b[h].count:jQuery.i18n.map["events.table.count"],l=b[h]&&b[h].sum?b[h].sum:jQuery.i18n.map["events.table.sum"];if(i){var b={chartData:{},chartDP:{dp:[],ticks:[]}},j=countlyCommon.extractTwoLevelData(e, +g,a.clearEventsObject,[{name:"curr_segment",func:function(c){return c.replace(/:/g,".").replace(/\[CLY\]/g,"")}},{name:"c"},{name:"s"}]);b.chartData=j.chartData;var j=_.pluck(b.chartData,"curr_segment").slice(0,15),f=_.pluck(b.chartData,"c"),p=_.without(_.pluck(b.chartData,"s"),!1,null,"",d,NaN),u=[{data:[],color:countlyCommon.GRAPH_COLORS[0]}];0==_.reduce(p,function(c,a){return c+a},0)&&(p=[]);p.length&&(u[u.length]={data:[],color:countlyCommon.GRAPH_COLORS[1]},u[1].data[0]=[-1,null],u[1].data[j.length+ +1]=[j.length,null]);u[0].data[0]=[-1,null];u[0].data[j.length+1]=[j.length,null];b.chartDP.ticks.push([-1,""]);b.chartDP.ticks.push([j.length,""]);for(var t=0;tx&&(q=x);j>y&&(j=y);k>b&&(k=b);for(r=0;rx&&(v=x);l>y&&(l=y);k>b&&(k=b);for(r=0;r"+b.chartData[j].percent+"%";return b};a.getSessionDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject, +[{data:[],label:jQuery.i18n.map["common.table.total-sessions"]},{data:[],label:jQuery.i18n.map["common.table.new-sessions"]},{data:[],label:jQuery.i18n.map["common.table.unique-sessions"]}],[{name:"t"},{name:"n"},{name:"u"}])};a.getSessionDPTotal=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-sessions"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.total-sessions"],color:"#333933"}],[{name:"pt", +func:function(c){return c.t},period:"previous"},{name:"t"}])};a.getUserDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"]},{data:[],label:jQuery.i18n.map["common.table.new-users"]},{data:[],label:jQuery.i18n.map["common.table.returning-users"]}],[{name:"u"},{name:"n"},{name:"returning",func:function(c){return c.u-c.n}}])};a.getUserDPActive=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[], +label:jQuery.i18n.map["common.table.total-users"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.total-users"],color:"#333933"}],[{name:"pt",func:function(c){return c.u},period:"previous"},{name:"t",func:function(c){return c.u}}])};a.getUserDPNew=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.new-users"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.table.new-users"],color:"#333933"}], +[{name:"pn",func:function(c){return c.n},period:"previous"},{name:"n"}])};a.getMsgUserDPActive=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"],color:countlyCommon.GRAPH_COLORS[0]},{data:[],label:jQuery.i18n.map["common.table.messaging-users"],color:countlyCommon.GRAPH_COLORS[1]}],[{name:"u"},{name:"m"}])};a.getDurationDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.time-spent"], +color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.time-spent"],color:"#333933"}],[{name:"previous_t",func:function(c){return(c.d/60).toFixed(1)},period:"previous"},{name:"t",func:function(c){return(c.d/60).toFixed(1)}}])};a.getDurationDPAvg=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.average-time"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.average-time"],color:"#333933"}], +[{name:"previous_average",func:function(c){return 0==c.t?0:(c.d/c.t/60).toFixed(1)},period:"previous"},{name:"average",func:function(c){return 0==c.t?0:(c.d/c.t/60).toFixed(1)}}])};a.getEventsDP=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.reqs-received"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.reqs-received"],color:"#333933"}],[{name:"pe",func:function(c){return c.e},period:"previous"},{name:"e"}])}; +a.getEventsDPAvg=function(){return countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.graph.avg-reqs-received"],color:"#DDDDDD",mode:"ghost"},{data:[],label:jQuery.i18n.map["common.graph.avg-reqs-received"],color:"#333933"}],[{name:"previous_average",func:function(c){return 0==c.u?0:(c.e/c.u).toFixed(1)},period:"previous"},{name:"average",func:function(c){return 0==c.u?0:(c.e/c.u).toFixed(1)}}])};a.clearSessionObject=function(c){c?(c.t||(c.t=0),c.n||(c.n= +0),c.u||(c.u=0),c.d||(c.d=0),c.e||(c.e=0),c.p||(c.p=0),c.m||(c.m=0)):c={t:0,n:0,u:0,d:0,e:0,p:0,m:0};return c};a.explainDurationRange=function(c){var a=jQuery.i18n.map["common.seconds"],b=jQuery.i18n.map["common.minutes"];return["0-10 "+a,"11-30 "+a,"31-60 "+a,"1-3 "+b,"3-10 "+b,"10-30 "+b,"30-60 "+b,"> 1 "+jQuery.i18n.map["common.hour"]][c]};a.getDurationIndex=function(c){var a=jQuery.i18n.map["common.seconds"],b=jQuery.i18n.map["common.minutes"];return["0-10 "+a,"11-30 "+a,"31-60 "+a,"1-3 "+b,"3-10 "+ +b,"10-30 "+b,"30-60 "+b,"> 1 "+jQuery.i18n.map["common.hour"]].indexOf(c)};a.getTopUserBars=function(){var c=[],b=0,d=3,g=0,j=countlyCommon.extractChartData(e,a.clearSessionObject,[{data:[],label:jQuery.i18n.map["common.table.total-users"]}],[{name:"t",func:function(c){return c.u}}]),j=_.sortBy(_.reject(j.chartData,function(c){return 0==c.t}),function(c){return-c.t});3>j.length&&(d=j.length);for(var l=0;lb.maxCountries&&(e.chartData= +e.chartData.splice(0,b.maxCountries));return e.chartData});a.clearLocationObject=function(c){c?(c.t||(c.t=0),c.n||(c.n=0),c.u||(c.u=0)):c={t:0,n:0,u:0};return c}})(window.countlyCity=window.countlyCity||{},jQuery);(function(a,b){function d(){var e={cols:[],rows:[]};i=new google.visualization.GeoChart(document.getElementById(g));var d=countlyCommon.extractTwoLevelData(c,h,a.clearLocationObject,[{name:"country",func:function(c){return a.getCountryName(c)}},{name:"t"}]);e.cols=[{id:"country",label:jQuery.i18n.map["countries.table.country"],type:"string"},{id:"total",label:jQuery.i18n.map["common.total"],type:"number"}];e.rows=_.map(d.chartData,function(c){return"European Union"==c.country||"Unknown"==c.country? +{c:[{v:""},{v:c.t}]}:{c:[{v:c.country},{v:c.t}]}});f=new google.visualization.DataTable(e);j.region="world";j.resolution="countries";j.displayMode="region";!1!==countlyCommon.CITY_DATA&&300b.maxCountries&&(e.chartData=e.chartData.splice(0,b.maxCountries));for(b=0;b"+e.chartData[b].country; +return e.chartData};a.clearLocationObject=function(c){c?(c.t||(c.t=0),c.n||(c.n=0),c.u||(c.u=0)):c={t:0,n:0,u:0};return c};a.getCountryName=function(c){return(c=l[c.toUpperCase()])?c:"Unknown"};a.changeLanguage=function(){return b.get("localization/countries/"+countlyCommon.BROWSER_LANG_SHORT+"/country.json",function(c){l=c})}})(window.countlyLocation=window.countlyLocation||{},jQuery);(function(a,b){function d(){c.meta?(h=c.meta["l-ranges"]?c.meta["l-ranges"]:[],i=c.meta["f-ranges"]?c.meta["f-ranges"]:[]):(h=[],i=[])}var e={},c={},h=[],i=[],f=0,g=!1,j=null;a.initialize=function(){if(g&&j==countlyCommon.getPeriodForAjax()&&f==countlyCommon.ACTIVE_APP_KEY)return a.refresh();j=countlyCommon.getPeriodForAjax();if(countlyCommon.DEBUG)return!0;f=countlyCommon.ACTIVE_APP_KEY;g=!0;return b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID, +method:"users",period:j},dataType:"jsonp",success:function(a){c=a;d();countlySession.initialize();countlyLocation.initialize()}})};a.refresh=function(){return countlyCommon.DEBUG?!0:f!=countlyCommon.ACTIVE_APP_KEY?(f=countlyCommon.ACTIVE_APP_KEY,a.initialize()):b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"users",action:"refresh"},dataType:"jsonp",success:function(a){countlyCommon.extendDbObj(c,a);c.meta&& +(h=countlyCommon.union(h,c.meta["l-ranges"]),i=countlyCommon.union(i,c.meta["f-ranges"]));countlySession.refresh(a);countlyLocation.refresh(a)}})};a.reset=function(){c={};d()};a.getFrequencyData=function(){var b={chartData:{},chartDP:{dp:[],ticks:[]}};b.chartData=countlyCommon.extractRangeData(c,"f",i,a.explainFrequencyRange);var e=_.pluck(b.chartData,"f"),d=_.pluck(b.chartData,"t"),h=[{data:[]}];h[0].data[0]=[-1,null];h[0].data[e.length+1]=[e.length,null];b.chartDP.ticks.push([-1,""]);b.chartDP.ticks.push([e.length, +""]);for(var g=0;g"+b.chartData[g].percent+"%";return b};a.getLoyaltyData=function(){var b={chartData:{},chartDP:{dp:[],ticks:[]}};b.chartData=countlyCommon.extractRangeData(c,"l",h,a.explainLoyaltyRange);var e=_.pluck(b.chartData,"l"),d=_.pluck(b.chartData,"t"),g=[{data:[]}];g[0].data[0]= +[-1,null];g[0].data[e.length+1]=[e.length,null];b.chartDP.ticks.push([-1,""]);b.chartDP.ticks.push([e.length,""]);for(var j=0;j"+b.chartData[j].percent+"%";return b};a.getLoyaltyDP=function(){e=countlyCommon.periodObj;for(var a=[{data:[],label:jQuery.i18n.map["user-loyalty.loyalty"]}], +b=[],d,g=0;g 500".split(";")[c]};a.getLoyaltyIndex=function(c){return"1;2;3-5;6-9;10-19;20-49;50-99;100-499;> 500".split(";").indexOf(c)};a.isInitialized=function(){return g};a.getDbObj=function(){return c}})(window.countlyUser=window.countlyUser||{},jQuery);(function(a,b){function d(){h=c.meta?c.meta.devices?c.meta.devices:[]:[]}var e={},c={},h=[],i=0,f=!1,g=null;a.initialize=function(){if(f&&g==countlyCommon.getPeriodForAjax()&&i==countlyCommon.ACTIVE_APP_KEY)return a.refresh();g=countlyCommon.getPeriodForAjax();if(countlyCommon.DEBUG)return c={2012:{}},!0;i=countlyCommon.ACTIVE_APP_KEY;f=!0;return b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"devices",period:g}, +dataType:"jsonp",success:function(a){c=a;d()}})};a.refresh=function(){e=countlyCommon.periodObj;return countlyCommon.DEBUG?(c={2012:{}},!0):i!=countlyCommon.ACTIVE_APP_KEY?(i=countlyCommon.ACTIVE_APP_KEY,a.initialize()):b.ajax({type:"GET",url:countlyCommon.API_PARTS.data.r,data:{api_key:countlyGlobal.member.api_key,app_id:countlyCommon.ACTIVE_APP_ID,method:"devices",action:"refresh"},dataType:"jsonp",success:function(a){countlyCommon.extendDbObj(c,a);c.meta&&(h=countlyCommon.union(h,c.meta.devices))}})}; +a.reset=function(){c={};d()};a.getDeviceData=function(){var b=countlyCommon.extractTwoLevelData(c,h,a.clearDeviceObject,[{name:"device",func:function(c){return a.getDeviceFullName(c)}},{name:"t"},{name:"u"},{name:"n"}]),e=_.pluck(b.chartData,"device"),d=_.pluck(b.chartData,"u"),g=_.pluck(b.chartData,"n"),i=[],f=[];_.reduce(d,function(c,a){return c+a},0);for(var q=0;q"+c.split("x")[0]+""}},{name:"height",func:function(c){return""+c.split("x")[1]+""}},{name:"t"},{name:"u"},{name:"n"}]),b=_.pluck(c.chartData,"resolution"), +d=_.pluck(c.chartData,"u"),g=_.pluck(c.chartData,"n"),i=[],j=[];_.reduce(d,function(c,a){return c+a},0);for(var f=0;fd.all[e].trend?"d":"u";d.all.avgduration.total=0==d.all.sessions.total?0:d.all.duration.total/ +d.all.sessions.total;a=d.all.duration.total.toFixed(1)+" "+jQuery.i18n.map["common.minute.abrv"];142560<=d.all.duration.total?a=(d.all.duration.total/525600).toFixed(1)+" "+jQuery.i18n.map["common.year.abrv"]:1440<=d.all.duration.total?a=(d.all.duration.total/1440).toFixed(1)+" "+jQuery.i18n.map["common.day.abrv"]:60<=d.all.duration.total&&(a=(d.all.duration.total/60).toFixed(1)+" "+jQuery.i18n.map["common.hour.abrv"]);d.all.duration.total=a;a=d.all.avgduration.total.toFixed(1)+" "+jQuery.i18n.map["common.minute.abrv"]; +142560<=d.all.avgduration.total?a=(d.all.avgduration.total/525600).toFixed(1)+" "+jQuery.i18n.map["common.year.abrv"]:1440<=d.all.avgduration.total?a=(d.all.avgduration.total/1440).toFixed(1)+" "+jQuery.i18n.map["common.day.abrv"]:60<=d.all.avgduration.total&&(a=(d.all.avgduration.total/60).toFixed(1)+" "+jQuery.i18n.map["common.hour.abrv"]);d.all.avgduration.total=a})};a.reset=function(){e={}};a.getData=function(){var c=[],a;for(a in d)c.push(d[a]);return c};a.getSessionData=function(){return c}; +a.setApp=function(c){i=c;countlyCommon.setActiveApp(i)};var f=function(a){countlyCommon.setActiveApp(a);return b.when(countlyUser.initialize()).done(function(){var b=countlySession.getSessionData();e[a]||(h[a]=b,c[a]={"#draw-total-users":countlySession.getUserDPActive().chartDP[1],"#draw-new-users":countlySession.getUserDPNew().chartDP[1],"#draw-total-sessions":countlySession.getSessionDPTotal().chartDP[1],"#draw-time-spent":countlySession.getDurationDPAvg().chartDP[1],"#draw-total-time-spent":countlySession.getDurationDP().chartDP[1], +"#draw-avg-events-served":countlySession.getEventsDPAvg().chartDP[1]},d[a]={_id:a,name:countlyGlobal.apps[a].name,sessions:b.usage["total-sessions"],users:b.usage["total-users"],newusers:b.usage["new-users"],duration:b.usage["total-duration"],avgduration:b.usage["avg-duration-per-session"]},e[a]=!0)})},g=function(c){if("NA"==c||"\u221e"==c)return 0;var c=c.slice(0,-1),a=1;"K"==c.slice(-1)?(c=c.slice(0,-1),a=1E3):"M"==c.slice(-1)&&(c=c.slice(0,-1),a=1E6);return parseFloat(c)*a}})(window.countlyAllApps= +window.countlyAllApps||{},jQuery);var countlyView=Backbone.View.extend({template:null,templateData:{},el:$("#content"),initialize:function(){this.template=Handlebars.compile($("#template-analytics-common").html())},dateChanged:function(){"/"==Backbone.history.fragment?this.refresh(!0):this.refresh()},appChanged:function(){countlyEvent.reset();countlyFunnel.reset();var a=this;$.when(countlyEvent.initialize()).then(function(){a.render()})},beforeRender:function(){return!0},afterRender:function(){},render:function(){$("#content-top").html(""); +this.el.html('
    ');if(countlyCommon.ACTIVE_APP_ID){var a=this;$.when(this.beforeRender(),initializeOnce()).then(function(){a.renderCommon();a.afterRender();app.pageScript()})}else this.renderCommon(),this.afterRender(),app.pageScript();return this},renderCommon:function(){},refresh:function(){return!0},restart:function(){this.refresh()},destroy:function(){}}),initializeOnce=_.once(function(){return $.when(countlyEvent.initialize()).then(function(){})}),Template=function(){this.cached= +{}},T=new Template; +$.extend(Template.prototype,{render:function(a,b){T.isCached(a)?b(T.cached[a]):$.get(T.urlFor(a),function(d){T.store(a,d);T.render(a,b)})},renderSync:function(a,b){T.isCached(a)||T.fetch(a);T.render(a,b)},prefetch:function(a){$.get(T.urlFor(a),function(b){T.store(a,b)})},fetch:function(a){if(!T.isCached(a)){var b=$.ajax({url:T.urlFor(a),async:!1}).responseText;T.store(a,b)}},isCached:function(a){return!!T.cached[a]},store:function(a,b){T.cached[a]=Handlebars.compile(b)},urlFor:function(a){return a+".html"}}); +(function(a,b){function d(a){b("body").append(a);var c=a.outerHeight()-2,d=a.outerWidth();a.css({height:c,"margin-top":Math.floor(-c/2),width:d,"margin-left":Math.floor(-d/2)});b("#overlay").fadeIn();a.fadeIn()}a.parseAndShowMsg=function(a){if(!a||!a.length)return!0;_.isArray(a)&&(a=a[0]);var c="info",b="",b=a.split("|");1");d(c)};a.alert=function(a,c){var h=b("#cly-alert").clone();h.removeAttr("id");h.find(".message").html(a);h.addClass(c);d(h)};a.confirm=function(a,c,h,i){var f=b("#cly-confirm").clone();f.removeAttr("id"); +f.find(".message").text(a);i&&2==i.length&&(f.find("#dialog-cancel").text(i[0]),f.find("#dialog-continue").text(i[1]));f.addClass(c);d(f);f.find("#dialog-cancel").on("click",function(){h(!1)});f.find("#dialog-continue").on("click",function(){h(!0)})};a.loading=function(a){var c=b("#cly-loading").clone();c.removeAttr("id");c.find(".message").html(a);c.addClass("cly-loading");d(c);return c};a.setUpDateSelectors=function(a){b("#month").text(moment().year());b("#day").text(moment().format("MMM"));b("#yesterday").text(moment().subtract("days", +1).format("Do"));b("#date-selector").find(">.button").click(function(){if(b(this).hasClass("selected"))return!0;a.dateFromSelected=null;a.dateToSelected=null;b(".date-selector").removeClass("selected").removeClass("active");b(this).addClass("selected");var c=b(this).attr("id");if(countlyCommon.getPeriod()==c)return!0;countlyCommon.setPeriod(c);a.dateChanged(c);b("#"+c).addClass("active")});b("#date-selector").find(">.button").each(function(){countlyCommon.getPeriod()==b(this).attr("id")&&b(this).addClass("active").addClass("selected")})}; +a.initializeSelect=function(a){a=a||b("#content-container");a.off("click",".cly-select").on("click",".cly-select",function(c){if(b(this).hasClass("disabled"))return!0;b(this).removeClass("req");var a=b(this).find(".select-items"),e=a.find(".item").length;if(!a.length)return!1;b(".cly-select").find(".search").remove();a.is(":visible")?b(this).removeClass("active"):(b(".cly-select").removeClass("active"),b(".select-items").hide(),b(this).addClass("active"),10
    ").insertBefore(b(this).find(".select-items"))); +b(this).hasClass("centered")&&(a=b(this).find(".select-items").height(),b(this).find(".select-items").css("margin-top",-(a/2).toFixed(0)-(b(this).height()/2).toFixed(0)+"px"));b(this).find(".select-items").is(":visible")?b(this).find(".select-items").hide():(b(this).find(".select-items").show(),b(this).find(".select-items>div").addClass("scroll-list"),b(this).find(".scroll-list").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0}));b(this).find(".search input").focus(); +b("#date-picker").hide();c.stopPropagation()});a.off("click",".select-items .item").on("click",".select-items .item",function(){var c=b(this).parents(".cly-select").find(".text");c.text(b(this).text());c.data("value",b(this).data("value"))});a.off("click",".cly-select .search").on("click",".cly-select .search",function(c){c.stopPropagation()});a.off("keyup",".cly-select .search input").on("keyup",".cly-select .search input",function(){b(this).val()?(b(this).parents(".cly-select").find(".item:not(:contains('"+ +b(this).val()+"'))").addClass("hidden"),b(this).parents(".cly-select").find(".item:contains('"+b(this).val()+"')").removeClass("hidden")):b(this).parents(".cly-select").find(".item").removeClass("hidden")});a.off("mouseenter").on("mouseenter",".cly-select .item",function(){var c=b(this);this.offsetWidth'+(c||jQuery.i18n.map["push.no-message"])+""}};a.initializeTextSelect=function(){function a(c,b){c.removeClass("req");if(!c.find(".select-items").length)return!1;c.find(".select-items").is(":visible")&&!b?c.find(".select-items").hide():(c.find(".select-items").show(),c.find(".select-items>div").addClass("scroll-list"),c.find(".scroll-list").slimScroll({height:"100%", +start:"top",wheelStep:10,position:"right",disableFadeOut:!0}))}b("#content-container").on("click",".cly-text-select",function(c){if(b(this).hasClass("disabled"))return!0;a(b(this));b("#date-picker").hide();c.stopPropagation()});b("#content-container").on("click",".select-items .item",function(){var c=b(this).parents(".cly-text-select").find(".text");c.text(b(this).text());c.data("value",b(this).data("value"));c.val(b(this).text())});b("#content-container").on("keyup",".cly-text-select input",function(){a(b(this).parents(".cly-text-select"), +!0);b(this).data("value",b(this).val());b(this).val()?(b(this).parents(".cly-text-select").find(".item:not(:contains('"+b(this).val()+"'))").addClass("hidden"),b(this).parents(".cly-text-select").find(".item:contains('"+b(this).val()+"')").removeClass("hidden")):b(this).parents(".cly-text-select").find(".item").removeClass("hidden")});b(window).click(function(){b(".select-items").hide()})};a.initializeHugeDropdown=function(){var a;b("#content-container").on("mouseenter",".cly-huge-dropdown-activator", +function(){clearInterval(a);var c=b(this).next(".cly-huge-dropdown");c.trigger("huge-dropdown-init");c.find(".scroll").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0});c.find(".button-container .title").text(b(this).text());c.fadeIn("slow")});b("#content-container").on("mouseleave",".cly-huge-dropdown",function(){var c=b(this);a=setTimeout(function(){c.fadeOut("fast")},500)});b("#content-container").on("mouseenter",".cly-huge-dropdown",function(){clearInterval(a)}); +b("#content-container").on("close",".cly-huge-dropdown",function(){b(this).fadeOut("fast")})};a.revealDialog=d;a.changeDialogHeight=function(a,c,d){var i=c||a.attr("data-height")||a.height()+15,f=a.width(),g=b("#sidebar").height()-40;a.attr("data-height",c);if(i>g)a[d?"animate":"css"]({height:g,"margin-top":Math.floor(-g/2),width:f,"margin-left":Math.floor(-f/2),"overflow-y":"auto"});else a[d?"animate":"css"]({height:i,"margin-top":Math.floor(-i/2),width:f,"margin-left":Math.floor(-f/2)})};a.removeDialog= +function(a){a.remove();b("#overlay").fadeOut()};b(document).ready(function(){b("#overlay").click(function(){var a=b(".dialog:visible:not(.cly-loading)");a.length&&(a.fadeOut().remove(),b(this).hide())});b("#dialog-ok, #dialog-cancel, #dialog-continue").live("click",function(){b(this).parents(".dialog:visible").fadeOut().remove();b(".dialog:visible").length||b("#overlay").hide()});b(document).keyup(function(a){27==a.keyCode&&(b(".dialog:visible").animate({top:0,opacity:0},{duration:1E3,easing:"easeOutQuart", +complete:function(){b(this).remove()}}),b("#overlay").hide())})})})(window.CountlyHelpers=window.CountlyHelpers||{},jQuery);$.expr[":"].contains=$.expr.createPseudo(function(a){return function(b){return 0<=$(b).text().toUpperCase().indexOf(a.toUpperCase())}}); +window.DashboardView=countlyView.extend({selectedView:"#draw-total-sessions",onlineUsersGauge:null,newUsersGauge:null,initialize:function(){this.template=Handlebars.compile($("#dashboard-template").html())},beforeRender:function(){return $.when(countlyUser.initialize(),countlyCarrier.initialize(),countlyDeviceDetails.initialize()).then(function(){})},afterRender:function(){countlyLocation.drawGeoChart({height:290})},pageScript:function(){$("#total-user-estimate-ind").on("click",function(){CountlyHelpers.alert($("#total-user-estimate-exp").html(), +"black")});$(".widget-content .inner").click(function(){$(".big-numbers").removeClass("active");$(".big-numbers .select").removeClass("selected");$(this).parent(".big-numbers").addClass("active");$(this).find(".select").addClass("selected")});$(".bar-inner").on({mouseenter:function(){var a=$(this).parent().next();a.text($(this).data("item"));a.css({color:$(this).css("background-color")})},mouseleave:function(){var a=$(this).parent().next();a.text(a.data("item"));a.css({color:$(this).parent().find(".bar-inner:first-child").css("background-color")})}}); +var a=this;$(".big-numbers .inner").click(function(){var b=$(this).find(".select").attr("id");if(a.selectedView=="#"+b)return!0;a.selectedView="#"+b;a.drawGraph()});app.localize()},drawGraph:function(){var a={};switch(this.selectedView){case "#draw-total-users":a=countlySession.getUserDPActive();break;case "#draw-new-users":a=countlySession.getUserDPNew();break;case "#draw-total-sessions":a=countlySession.getSessionDPTotal();break;case "#draw-time-spent":a=countlySession.getDurationDPAvg();break; +case "#draw-total-time-spent":a=countlySession.getDurationDP();break;case "#draw-avg-events-served":a=countlySession.getEventsDPAvg()}_.defer(function(){countlyCommon.drawTimeGraph(a.chartDP,"#dashboard-graph")})},renderCommon:function(a,b){var d=countlySession.getSessionData(),e=countlyLocation.getLocationData({maxCountries:7});countlySession.getSessionDPTotal();d["country-data"]=e;d["page-title"]=countlyCommon.getDateRange();d.usage=[{title:jQuery.i18n.map["common.total-sessions"],data:d.usage["total-sessions"], +id:"draw-total-sessions",help:"dashboard.total-sessions"},{title:jQuery.i18n.map["common.total-users"],data:d.usage["total-users"],id:"draw-total-users",help:"dashboard.total-users"},{title:jQuery.i18n.map["common.new-users"],data:d.usage["new-users"],id:"draw-new-users",help:"dashboard.new-users"},{title:jQuery.i18n.map["dashboard.time-spent"],data:d.usage["total-duration"],id:"draw-total-time-spent",help:"dashboard.total-time-spent"},{title:jQuery.i18n.map["dashboard.avg-time-spent"],data:d.usage["avg-duration-per-session"], +id:"draw-time-spent",help:"dashboard.avg-time-spent2"},{title:jQuery.i18n.map["dashboard.avg-reqs-received"],data:d.usage["avg-events"],id:"draw-avg-events-served",help:"dashboard.avg-reqs-received"}];d.bars=[{title:jQuery.i18n.map["common.bar.top-platform"],data:countlyDeviceDetails.getPlatformBars(),help:"dashboard.top-platforms"},{title:jQuery.i18n.map["common.bar.top-resolution"],data:countlyDeviceDetails.getResolutionBars(),help:"dashboard.top-resolutions"},{title:jQuery.i18n.map["common.bar.top-carrier"], +data:countlyCarrier.getCarrierBars(),help:"dashboard.top-carriers"},{title:jQuery.i18n.map["common.bar.top-users"],data:countlySession.getTopUserBars(),help:"dashboard.top-users"}];this.templateData=d;a||($(this.el).html(this.template(this.templateData)),$(this.selectedView).parents(".big-numbers").addClass("active"),this.pageScript(),b||this.drawGraph())},restart:function(){this.refresh(!0)},refresh:function(a){var b=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=b)return!1; +b.renderCommon(!0);var d=$("
    "+b.template(b.templateData)+"
    ");$(".rev-container").replaceWith(d.find(".rev-container"));$(".dashboard-summary").replaceWith(d.find(".dashboard-summary"));$(".widget-header .title").replaceWith(d.find(".widget-header .title"));$("#big-numbers-container").find(".big-numbers").each(function(b,c){var h=$(d.find("#big-numbers-container .big-numbers")[b]);if(a)$(c).find(".number").replaceWith(h.find(".number"));else{var i=$(c).find(".number .value"),f=parseFloat(i.text())|| +0,g=i.text().replace(f,""),j=parseFloat(h.find(".number .value").text()),l=h.find(".number .value").text().replace(j,"");j!=f&&(j"+a.template(a.templateData)+"");$(a.el).find("#big-numbers-container").html(newPage.find("#big-numbers-container").html());var b=countlySession.getSessionDP();countlyCommon.drawTimeGraph(b.chartDP,"#dashboard-graph");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); -window.UserView=countlyView.extend({beforeRender:function(){return $.when(countlySession.initialize()).then(function(){})},renderCommon:function(a){var b=countlyUser.getLoyaltyData(),c=countlySession.getSessionData(),f=countlySession.getDurationData(),e=countlySession.getUserDP();c["chart-data"]=e.chartData;c["loyalty-data"]=b;c["duration-data"]=f;this.templateData={"page-title":jQuery.i18n.map["users.title"],"logo-class":"users","big-numbers":{count:3,items:[{title:jQuery.i18n.map["common.total-users"], -total:c.usage["total-users"].total,trend:c.usage["total-users"].trend,help:"users.total-users"},{title:jQuery.i18n.map["common.new-users"],total:c.usage["new-users"].total,trend:c.usage["new-users"].trend,help:"users.new-users"},{title:jQuery.i18n.map["common.returning-users"],total:c.usage["returning-users"].total,trend:c.usage["returning-users"].trend,help:"users.returning-users"}]}};a||($(this.el).html(this.template(this.templateData)),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults, -{aaData:e.chartData,aoColumns:[{mData:"date",sType:"customDate",sTitle:jQuery.i18n.map["common.date"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]},{mData:"returning",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.returning-users"]}]})), -$(".d-table").stickyTableHeaders(),countlyCommon.drawTimeGraph(e.chartDP,"#dashboard-graph"))},refresh:function(){var a=this;$.when(countlySession.refresh()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container"));var b=countlySession.getUserDP();countlyCommon.drawTimeGraph(b.chartDP,"#dashboard-graph");CountlyHelpers.refreshTable(a.dtable,b.chartData); -app.localize()})}}); -window.LoyaltyView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){var b=countlyUser.getLoyaltyData();countlySession.getSessionData();countlySession.getUserDP();this.templateData={"page-title":jQuery.i18n.map["user-loyalty.title"],"logo-class":"loyalty","chart-helper":"loyalty.chart","table-helper":"loyalty.table"};a||($(this.el).html(this.template(this.templateData)),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults, -{aaData:b.chartData,aoColumns:[{mData:"l",sType:"loyalty",sTitle:jQuery.i18n.map["user-loyalty.table.session-count"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders(),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"))},refresh:function(){var a=countlyUser.getLoyaltyData(),b=this;$.when(countlyUser.refresh()).then(function(){if(app.activeView!= -b)return!1;b.renderCommon(!0);newPage=$("
    "+b.template(b.templateData)+"
    ");countlyUser.getLoyaltyData();countlyCommon.drawGraph(a.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(b.dtable,a.chartData);app.localize()})}}); -window.CountriesView=countlyView.extend({cityView:store.get("countly_location_city")?store.get("countly_active_app"):!1,initialize:function(){this.template=Handlebars.compile($("#template-analytics-countries").html())},beforeRender:function(){return $.when(countlySession.initialize(),countlyLocation.initialize(),countlyCity.initialize()).then(function(){})},drawTable:function(){var a=this.cityView?jQuery.i18n.map["countries.table.city"]:jQuery.i18n.map["countries.table.country"],b,c="country_flag"; -this.cityView?(b=countlyCity.getLocationData(),c="city"):b=countlyLocation.getLocationData();var f=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID];f&&f.country&&$("#toggle-map").text(countlyLocation.getCountryName(f.country));this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b,aoColumns:[{mData:c,sTitle:a},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num", -mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]}));$(".d-table").stickyTableHeaders()},dateChanged:function(){this.renderCommon()},renderCommon:function(a){var b=countlySession.getSessionData();this.templateData={"page-title":jQuery.i18n.map["countries.title"],"logo-class":"countries","big-numbers":{count:3, -items:[{title:jQuery.i18n.map["common.total-sessions"],total:b.usage["total-sessions"].total,trend:b.usage["total-sessions"].trend,help:"countries.total-sessions"},{title:jQuery.i18n.map["common.total-users"],total:b.usage["total-users"].total,trend:b.usage["total-users"].trend,help:"countries.total-users"},{title:jQuery.i18n.map["common.new-users"],total:b.usage["new-users"].total,trend:b.usage["new-users"].trend,help:"countries.new-users"}]},"chart-helper":"countries.chart","table-helper":"countries.table"}; -var c=this;$(document).bind("selectMapCountry",function(){c.cityView=!0;store.set("countly_location_city",!0);$("#toggle-map").addClass("active");countlyCity.drawGeoChart({height:450});c.refresh(!0)});a||($(this.el).html(this.template(this.templateData)),(a=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID])&&a.country&&$("#toggle-map").text(countlyLocation.getCountryName(a.country)),this.drawTable(),this.cityView?(countlyCity.drawGeoChart({height:450}),$("#toggle-map").addClass("active")):countlyLocation.drawGeoChart({height:450}), -!1===countlyCommon.CITY_DATA&&($("#toggle-map").hide(),store.set("countly_location_city",!1)),$("#toggle-map").on("click",function(){$(this).hasClass("active")?(c.cityView=!1,countlyLocation.drawGeoChart({height:450}),$(this).removeClass("active"),c.refresh(!0),store.set("countly_location_city",!1)):(c.cityView=!0,countlyCity.drawGeoChart({height:450}),$(this).addClass("active"),c.refresh(!0),store.set("countly_location_city",!0))}))},refresh:function(a){var b=this;$.when(this.beforeRender()).then(function(){if(app.activeView!= -b)return!1;b.renderCommon(!0);newPage=$("
    "+b.template(b.templateData)+"
    ");$(b.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container"));if(a)b.drawTable();else{var c;b.cityView?(c=countlyCity.getLocationData(),countlyCity.refreshGeoChart()):(c=countlyLocation.getLocationData(),countlyLocation.refreshGeoChart());CountlyHelpers.refreshTable(b.dtable,c)}app.localize()})}}); -window.FrequencyView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){countlyUser.getLoyaltyData();countlySession.getSessionData();countlySession.getDurationData();countlySession.getUserDP();var b=countlyUser.getFrequencyData();this.templateData={"page-title":jQuery.i18n.map["session-frequency.title"],"logo-class":"frequency","chart-helper":"frequency.chart","table-helper":"frequency.table"};a||($(this.el).html(this.template(this.templateData)), -this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"f",sType:"frequency",sTitle:jQuery.i18n.map["session-frequency.table.time-after"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders(),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph", -"bar"))},refresh:function(){var a=this;$.when(countlyUser.refresh()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlyUser.getFrequencyData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); +this;$.when(countlyUser.initialize()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find("#big-numbers-container").html(newPage.find("#big-numbers-container").html());var b=countlySession.getSessionDP();countlyCommon.drawTimeGraph(b.chartDP,"#dashboard-graph");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); +window.UserView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){var b=countlySession.getSessionData(),d=countlySession.getUserDP();this.templateData={"page-title":jQuery.i18n.map["users.title"],"logo-class":"users","big-numbers":{count:3,items:[{title:jQuery.i18n.map["common.total-users"],total:b.usage["total-users"].total,trend:b.usage["total-users"].trend,help:"users.total-users"},{title:jQuery.i18n.map["common.new-users"], +total:b.usage["new-users"].total,trend:b.usage["new-users"].trend,help:"users.new-users"},{title:jQuery.i18n.map["common.returning-users"],total:b.usage["returning-users"].total,trend:b.usage["returning-users"].trend,help:"users.returning-users"}]}};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawTimeGraph(d.chartDP,"#dashboard-graph"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:d.chartData,aoColumns:[{mData:"date",sType:"customDate",sTitle:jQuery.i18n.map["common.date"]}, +{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]},{mData:"returning",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.returning-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a= +this;$.when(countlyUser.initialize()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container"));var b=countlySession.getUserDP();countlyCommon.drawTimeGraph(b.chartDP,"#dashboard-graph");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); +window.AllAppsView=countlyView.extend({selectedView:"#draw-total-sessions",selectedApps:{all:!0},selectedCount:0,initialize:function(){this.template=Handlebars.compile($("#template-allapps").html())},beforeRender:function(){return $.when(countlyAllApps.initialize()).then(function(){})},pageScript:function(){$(".widget-content .inner").click(function(){$(".big-numbers").removeClass("active");$(".big-numbers .select").removeClass("selected");$(this).parent(".big-numbers").addClass("active");$(this).find(".select").addClass("selected")}); +var a=this;$(".big-numbers .inner").click(function(){var b=$(this).find(".select").attr("id");if(a.selectedView=="#"+b)return!0;a.selectedView="#"+b;a.drawGraph()});app.localize()},drawGraph:function(){var a=[],b=countlyAllApps.getSessionData(),d,e,c=0,h;for(h in this.selectedApps)try{d=b[h][this.selectedView],e=countlyCommon.GRAPH_COLORS[c],"all"==h?a.push({data:d.data,label:d.label+" for All Apps",color:e}):a.push({data:d.data,label:d.label+" for "+countlyGlobal.apps[h].name,color:e}),$("#"+h+" .color").css("background-color", +e),c++}catch(i){}_.defer(function(){countlyCommon.drawTimeGraph(a,"#dashboard-graph")})},renderCommon:function(a){$("#sidebar-app-select").find(".text").text(jQuery.i18n.map["allapps.title"]);$("#sidebar-app-select").find(".logo").css("background-image","url('"+countlyGlobal.cdn+"images/favicon.png')");$("#sidebar-menu > .item").addClass("hide");$("#management-menu").removeClass("hide");$("#allapps-menu").removeClass("hide").css("display","block");var b=countlyAllApps.getData();this.templateData= +{"page-title":jQuery.i18n.map["allapps.title"],"logo-class":"platforms",usage:[{title:jQuery.i18n.map["common.total-sessions"],data:0,id:"draw-total-sessions",help:"dashboard.total-sessions"},{title:jQuery.i18n.map["common.total-users"],data:0,id:"draw-total-users",help:"dashboard.total-users"},{title:jQuery.i18n.map["common.new-users"],data:0,id:"draw-new-users",help:"dashboard.new-users"},{title:jQuery.i18n.map["dashboard.time-spent"],data:0,id:"draw-total-time-spent",help:"dashboard.total-time-spent"}, +{title:jQuery.i18n.map["dashboard.avg-time-spent"],data:0,id:"draw-time-spent",help:"dashboard.avg-time-spent2"},{title:jQuery.i18n.map["dashboard.avg-reqs-received"],data:0,id:"draw-avg-events-served",help:"dashboard.avg-reqs-received"}]};var d=this;a||($(this.el).html(this.template(this.templateData)),$(this.selectedView).parents(".big-numbers").addClass("active"),this.pageScript(),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b,fnRowCallback:function(a,c){$(a).attr("id", +c._id)},aoColumns:[{mData:function(a){return d.selectedApps[a._id]?"":""},sWidth:"10px",bSortable:!1},{mData:function(a,c){return"display"==c?("all"==a._id?" ":" ")+a.name+"
    ":a.name},sType:"string",sTitle:jQuery.i18n.map["allapps.app-name"]}, +{mData:function(a,c){return"display"==c?"
    "+a.sessions.total:a.sessions.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-sessions"]},{mData:function(a,c){return"display"==c?"
    "+a.users.total:a.users.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-users"]}, +{mData:function(a,c){return"display"==c?"
    "+a.newusers.total:a.newusers.total},sType:"string",sTitle:jQuery.i18n.map["allapps.new-users"]},{mData:function(a,c){return"display"==c?"
    "+a.duration.total:a.duration.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-duration"]}, +{mData:function(a,c){return"display"==c?"
    "+a.avgduration.total:a.avgduration.total},sType:"string",sTitle:jQuery.i18n.map["allapps.average-duration"]}]})),this.drawGraph(),$(".dataTable-bottom").append("
    Maximum number of applications to be compared (10)
    "),$(".d-table").stickyTableHeaders(), +$(".allapps tbody").on("click","tr",function(a){var c=$(a.target).closest("td"),a=$(this);if(a.children().first().is(c)){if(d.selectedApps[a.attr("id")])a.find(".check").removeClass("icon-check").addClass("icon-unchecked"),a.find(".color").css("background-color","transparent"),delete d.selectedApps[a.attr("id")],"all"!=a.attr("id")&&d.selectedCount--,0==d.selectedCount&&($("#empty-graph").show(),$(".big-numbers").removeClass("active"),$(".big-numbers .select").removeClass("selected"));else if(10> +d.selectedCount||"all"==a.attr("id"))0==d.selectedCount&&($("#empty-graph").hide(),$(d.selectedView).parents(".big-numbers").addClass("active")),"all"==a.attr("id")?($(".check.icon-check").removeClass("icon-check").addClass("icon-unchecked"),$(".d-table").find(".color").css("background-color","transparent"),d.selectedApps={},d.selectedCount=0):(d.selectedApps.all&&($(".d-table #all .check.icon-check").removeClass("icon-check").addClass("icon-unchecked"),$(".d-table #all").find(".color").css("background-color", +"transparent"),delete d.selectedApps.all),d.selectedCount++),a.find(".check").removeClass("icon-unchecked").addClass("icon-check"),d.selectedApps[a.attr("id")]=!0;d.drawGraph()}else c=d.dtable.fnGetData(this),countlyAllApps.setApp(a.attr("id")),$("#sidebar-app-select").find(".logo").css("background-image","url('"+countlyGlobal.cdn+"appimages/"+a.attr("id")+".png')"),$("#sidebar-app-select").find(".text").text(c.name),$("#sidebar-menu > .item").removeClass("hide"),$("#allapps-menu").css("display", +"none"),window.location.hash="#/"}))},refresh:function(){var a=this;$.when(countlyAllApps.initialize()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlyAllApps.getData();CountlyHelpers.refreshTable(a.dtable,b);a.drawGraph();app.localize()})}}); +window.LoyaltyView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){var b=countlyUser.getLoyaltyData();this.templateData={"page-title":jQuery.i18n.map["user-loyalty.title"],"logo-class":"loyalty","chart-helper":"loyalty.chart","table-helper":"loyalty.table"};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, +$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"l",sType:"loyalty",sTitle:jQuery.i18n.map["user-loyalty.table.session-count"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlyUser.initialize()).then(function(){if(app.activeView!=a)return!1; +var b=countlyUser.getLoyaltyData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); +window.CountriesView=countlyView.extend({cityView:store.get("countly_location_city")?store.get("countly_active_app"):!1,initialize:function(){this.template=Handlebars.compile($("#template-analytics-countries").html())},beforeRender:function(){return $.when(countlyUser.initialize(),countlyCity.initialize()).then(function(){})},drawTable:function(){var a=this.cityView?jQuery.i18n.map["countries.table.city"]:jQuery.i18n.map["countries.table.country"],b,d="country_flag";this.cityView?(b=countlyCity.getLocationData(), +d="city"):b=countlyLocation.getLocationData();var e=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID];e&&e.country&&$("#toggle-map").text(countlyLocation.getCountryName(e.country));this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b,aoColumns:[{mData:d,sTitle:a},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, +sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]}));$(".d-table").stickyTableHeaders()},renderCommon:function(a){var b=countlySession.getSessionData();this.templateData={"page-title":jQuery.i18n.map["countries.title"],"logo-class":"countries","big-numbers":{count:3,items:[{title:jQuery.i18n.map["common.total-sessions"],total:b.usage["total-sessions"].total, +trend:b.usage["total-sessions"].trend,help:"countries.total-sessions"},{title:jQuery.i18n.map["common.total-users"],total:b.usage["total-users"].total,trend:b.usage["total-users"].trend,help:"countries.total-users"},{title:jQuery.i18n.map["common.new-users"],total:b.usage["new-users"].total,trend:b.usage["new-users"].trend,help:"countries.new-users"}]},"chart-helper":"countries.chart","table-helper":"countries.table"};var d=this;$(document).bind("selectMapCountry",function(){d.cityView=!0;store.set("countly_location_city", +!0);$("#toggle-map").addClass("active");countlyCity.drawGeoChart({height:450});d.refresh(!0)});a||($(this.el).html(this.template(this.templateData)),this.cityView?(countlyCity.drawGeoChart({height:450}),$("#toggle-map").addClass("active")):countlyLocation.drawGeoChart({height:450}),this.drawTable(),!1===countlyCommon.CITY_DATA&&($("#toggle-map").hide(),store.set("countly_location_city",!1)),$("#toggle-map").on("click",function(){$(this).hasClass("active")?(d.cityView=!1,countlyLocation.drawGeoChart({height:450}), +$(this).removeClass("active"),d.refresh(!0),store.set("countly_location_city",!1)):(d.cityView=!0,countlyCity.drawGeoChart({height:450}),$(this).addClass("active"),d.refresh(!0),store.set("countly_location_city",!0))}))},refresh:function(a){var b=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=b)return!1;b.renderCommon(!0);newPage=$("
    "+b.template(b.templateData)+"
    ");$(b.el).find("#big-numbers-container").replaceWith(newPage.find("#big-numbers-container"));if(a)b.drawTable(); +else{var d;b.cityView?(d=countlyCity.getLocationData(),countlyCity.refreshGeoChart()):(d=countlyLocation.getLocationData(),countlyLocation.refreshGeoChart());CountlyHelpers.refreshTable(b.dtable,d)}app.localize()})}}); +window.FrequencyView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){var b=countlyUser.getFrequencyData();this.templateData={"page-title":jQuery.i18n.map["session-frequency.title"],"logo-class":"frequency","chart-helper":"frequency.chart","table-helper":"frequency.table"};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, +$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"f",sType:"frequency",sTitle:jQuery.i18n.map["session-frequency.table.time-after"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlyUser.initialize()).then(function(){if(app.activeView!= +a)return!1;var b=countlyUser.getFrequencyData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); window.DeviceView=countlyView.extend({beforeRender:function(){return $.when(countlyDevice.initialize(),countlyDeviceDetails.initialize()).then(function(){})},pageScript:function(){$(".bar-inner").on({mouseenter:function(){var a=$(this).parent().next();a.text($(this).data("item"));a.css({color:$(this).css("background-color")})},mouseleave:function(){var a=$(this).parent().next();a.text(a.data("item"));a.css({color:$(this).parent().find(".bar-inner:first-child").css("background-color")})}});app.localize()}, renderCommon:function(a){var b=countlyDevice.getDeviceData();this.templateData={"page-title":jQuery.i18n.map["devices.title"],"logo-class":"devices","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["common.total-users"],right:jQuery.i18n.map["common.new-users"]},bars:[{title:jQuery.i18n.map["common.bar.top-platform"],data:countlyDeviceDetails.getPlatformBars(),help:"dashboard.top-platforms"},{title:jQuery.i18n.map["common.bar.top-platform-version"],data:countlyDeviceDetails.getOSVersionBars(), help:"devices.platform-versions2"},{title:jQuery.i18n.map["common.bar.top-resolution"],data:countlyDeviceDetails.getResolutionBars(),help:"dashboard.top-resolutions"}],"chart-helper":"devices.chart","table-helper":""};a||($(this.el).html(this.template(this.templateData)),this.pageScript(),countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData, aoColumns:[{mData:"device",sTitle:jQuery.i18n.map["devices.table.device"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})), $(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary"));var b=countlyDevice.getDeviceData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,b.chartData); a.pageScript()})}}); -window.PlatformView=countlyView.extend({activePlatform:null,beforeRender:function(){return $.when(countlyDevice.initialize(),countlyDeviceDetails.initialize()).then(function(){})},pageScript:function(){var a=this;a.activePlatform?$(".graph-segment[data-name='"+a.activePlatform+"']").addClass("active"):$(".graph-segment:first-child").addClass("active");$(".graph-segment").on("click",function(){a.activePlatform=$(this).data("name");$(".graph-segment").removeClass("active");$(this).addClass("active");a.refresh()}); -app.localize()},renderCommon:function(a){var b=countlyDeviceDetails.getOSVersionData(this.activePlatform),c=countlyDeviceDetails.getPlatformData();this.templateData={"page-title":jQuery.i18n.map["platforms.title"],"logo-class":"platforms","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["platforms.pie-left"],right:jQuery.i18n.map["platforms.pie-right"]},"graph-segmentation":b.os,"chart-helper":"platform-versions.chart","table-helper":"","two-tables":!0};a||($(this.el).html(this.template(this.templateData)), -this.pageScript(),countlyCommon.drawGraph(c.chartDP,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph2","pie"),this.dtable=$("#dataTableOne").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:c.chartData,aoColumns:[{mData:"os_",sTitle:jQuery.i18n.map["platforms.table.platform"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, +window.PlatformView=countlyView.extend({activePlatform:null,beforeRender:function(){return $.when(countlyDeviceDetails.initialize()).then(function(){})},pageScript:function(){var a=this;a.activePlatform?$(".graph-segment[data-name='"+a.activePlatform+"']").addClass("active"):$(".graph-segment:first-child").addClass("active");$(".graph-segment").on("click",function(){a.activePlatform=$(this).data("name");$(".graph-segment").removeClass("active");$(this).addClass("active");a.refresh()});app.localize()}, +renderCommon:function(a){var b=countlyDeviceDetails.getOSVersionData(this.activePlatform),d=countlyDeviceDetails.getPlatformData();this.templateData={"page-title":jQuery.i18n.map["platforms.title"],"logo-class":"platforms","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["platforms.pie-left"],right:jQuery.i18n.map["platforms.pie-right"]},"graph-segmentation":b.os,"chart-helper":"platform-versions.chart","table-helper":"","two-tables":!0};a||($(this.el).html(this.template(this.templateData)), +this.pageScript(),countlyCommon.drawGraph(d.chartDP,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph2","pie"),this.dtable=$("#dataTableOne").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:d.chartData,aoColumns:[{mData:"os_",sTitle:jQuery.i18n.map["platforms.table.platform"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),this.dtableTwo=$("#dataTableTwo").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"os_version",sTitle:jQuery.i18n.map["platforms.table.platform-version"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]}, {mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$("#dataTableTwo").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);var b=countlyDeviceDetails.getOSVersionData(a.activePlatform), -c=countlyDeviceDetails.getPlatformData();newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary"));$(a.el).find(".graph-segment-container").replaceWith(newPage.find(".graph-segment-container"));countlyCommon.drawGraph(countlyDeviceDetails.getPlatformData().chartDP,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDP,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,c.chartData);CountlyHelpers.refreshTable(a.dtableTwo, -b.chartData);a.pageScript()})}}); -window.AppVersionView=countlyView.extend({beforeRender:function(){return $.when(countlyAppVersion.initialize()).then(function(){})},renderCommon:function(a){var b=countlyAppVersion.getAppVersionData();this.templateData={"page-title":jQuery.i18n.map["app-versions.title"],"logo-class":"app-versions","chart-helper":"app-versions.chart","table-helper":""};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, +d=countlyDeviceDetails.getPlatformData(),e=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find(".dashboard-summary").replaceWith(e.find(".dashboard-summary"));$(a.el).find(".graph-segment-container").replaceWith(e.find(".graph-segment-container"));countlyCommon.drawGraph(d.chartDP,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDP,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,d.chartData);CountlyHelpers.refreshTable(a.dtableTwo,b.chartData);a.pageScript()})}}); +window.AppVersionView=countlyView.extend({beforeRender:function(){return $.when(countlyDeviceDetails.initialize()).then(function(){})},renderCommon:function(a){var b=countlyAppVersion.getAppVersionData();this.templateData={"page-title":jQuery.i18n.map["app-versions.title"],"logo-class":"app-versions","chart-helper":"app-versions.chart","table-helper":""};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, $.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"app_version",sTitle:jQuery.i18n.map["app-versions.table.app-version"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, -sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlyAppVersion.getAppVersionData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); +sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;var b=countlyAppVersion.getAppVersionData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); window.CarrierView=countlyView.extend({beforeRender:function(){return $.when(countlyCarrier.initialize()).then(function(){})},renderCommon:function(a){var b=countlyCarrier.getCarrierData();this.templateData={"page-title":jQuery.i18n.map["carriers.title"],"logo-class":"carriers","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["common.total-users"],right:jQuery.i18n.map["common.new-users"]},"chart-helper":"carriers.chart","table-helper":""};a||($(this.el).html(this.template(this.templateData)), countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"carrier",sTitle:jQuery.i18n.map["carriers.table.carrier"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, -sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlyCarrier.getCarrierData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph", -"pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); +sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;var b=countlyCarrier.getCarrierData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"); +CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); +window.LanguageView=countlyView.extend({beforeRender:function(){return $.when(countlyLanguage.initialize()).then(function(){})},renderCommon:function(a){var b=countlyLanguage.getLanguageData();this.templateData={"page-title":jQuery.i18n.map["languages.title"],"logo-class":"languages","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["common.total-users"],right:jQuery.i18n.map["common.new-users"]},"chart-helper":"languages.chart","table-helper":""};b.chartData.forEach(function(a){a.language in +countlyGlobal.languages&&(a.language=countlyGlobal.languages[a.language].englishName)});a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"language",sTitle:jQuery.i18n.map["languages.table.language"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, +sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(this.beforeRender()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0); +newPage=$("
    "+a.template(a.templateData)+"
    ");newPage.find(".sortable").tablesorter({sortList:a.sortList});$(a.el).find(".sortable tbody").replaceWith(newPage.find(".sortable tbody"));var b=countlyLanguage.getLanguageData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); window.ResolutionView=countlyView.extend({beforeRender:function(){return $.when(countlyDeviceDetails.initialize()).then(function(){})},renderCommon:function(a){var b=countlyDeviceDetails.getResolutionData();this.templateData={"page-title":jQuery.i18n.map["resolutions.title"],"logo-class":"resolutions","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["common.total-users"],right:jQuery.i18n.map["common.new-users"]},"chart-helper":"resolutions.chart"};a||($(this.el).html(this.template(this.templateData)), countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"resolution",sTitle:jQuery.i18n.map["resolutions.table.resolution"]},{mData:"width",sTitle:jQuery.i18n.map["resolutions.table.width"]},{mData:"height",sTitle:jQuery.i18n.map["resolutions.table.height"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)}, -sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlyDeviceDetails.refresh()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0); +sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlyDeviceDetails.initialize()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0); newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary"));var b=countlyDeviceDetails.getResolutionData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); -window.DurationView=countlyView.extend({beforeRender:function(){return $.when(countlySession.initialize()).then(function(){})},renderCommon:function(a){var b=countlySession.getDurationData();this.templateData={"page-title":jQuery.i18n.map["session-duration.title"],"logo-class":"durations","chart-helper":"durations.chart","table-helper":"durations.table"};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, -$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"ds",sType:"session-duration",sTitle:jQuery.i18n.map["session-duration.table.duration"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlySession.refresh()).then(function(){if(app.activeView!= -a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlySession.getDurationData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData);app.localize()})}}); -window.ManageAppsView=countlyView.extend({initialize:function(){this.template=Handlebars.compile($("#template-management-applications").html())},renderCommon:function(){function a(a){if(jQuery.isEmptyObject(countlyGlobal.apps))return e(),$("#no-app-warning").show(),!1;if(jQuery.isEmptyObject(countlyGlobal.admin_apps))return e(),!1;$("#app-container-new").remove();$("#add-new-app").hide();f();$("#view-app").show();countlyGlobal.admin_apps[a]?$("#delete-app").show():$("#delete-app").hide();$("#new-install-overlay").is(":visible")&& -($("#no-app-warning").hide(),$("#first-app-success").show(),$("#new-install-overlay").fadeOut(),countlyCommon.setActiveApp(a),$("#sidebar-app-select").find(".logo").css("background-image","url('/appimages/"+a+".png')"),$("#sidebar-app-select").find(".text").text(countlyGlobal.apps[a].name));$("#app-edit-id").val(a);$("#view-app").find(".widget-header .title").text(countlyGlobal.apps[a].name);$("#app-edit-name").find(".read").text(countlyGlobal.apps[a].name);$("#app-edit-name").find(".edit input").val(countlyGlobal.apps[a].name); -$("#view-app-key").text(countlyGlobal.apps[a].key);$("#view-app-id").text(a);$("#app-edit-category").find(".cly-select .text").text(d[countlyGlobal.apps[a].category]);$("#app-edit-category").find(".cly-select .text").data("value",countlyGlobal.apps[a].category);$("#app-edit-timezone").find(".cly-select .text").data("value",countlyGlobal.apps[a].timezone);$("#app-edit-category").find(".read").text(d[countlyGlobal.apps[a].category]);$("#app-edit-image").find(".read .logo").css({"background-image":'url("/appimages/'+ -a+'.png")'});for(var c=h[countlyGlobal.apps[a].country],g=0;g
    "+h[g].n+"");if(b&&c&&d){f=h[b];if(1==f.z.length)for(var t in f.z[0])$(a+" #selected").show(),$(a+" #selected").text(t),$(a+" #app-timezone").val(f.z[0][t]),$(a+" #app-country").val(b),$(a+" #country-select .text").html("
    "+f.n);else{$(a+" #timezone-select").find(".text").text(t);g=f.z;for(var u=0;u"+t+"");$(a+" #app-timezone").val(d);$(a+" #app-country").val(b);$(a+" #country-select .text").html("
    "+f.n);$(a+" #timezone-select .text").text(c);$(a+" #timezone-select").show()}$(a+" .select-items .item").click(function(){var a= -$(this).parents(".cly-select").find(".text");a.html($(this).html());a.data("value",$(this).data("value"))});$(a+" #timezone-items .item").click(function(){$(a+" #app-timezone").val($(this).data("value"))})}$(a+" #country-items .item").click(function(){$(a+" #selected").text("");$(a+" #timezone-select").hide();e.html("");var b=$(this).data("value");if(1==h[b].z.length)for(var c in h[b].z[0])$(a+" #selected").show(),$(a+" #selected").text(c),$(a+" #app-timezone").val(h[b].z[0][c]),$(a+" #app-country").val(b); -else{for(var d="",f=0;f"+c+"");$(a+" #timezone-select").show();$(a+" #app-timezone").val(d);$(a+" .select-items .item").click(function(){var a=$(this).parents(".cly-select").find(".text");a.html($(this).html());a.data("value",$(this).data("value"))});$(a+" #timezone-items .item").click(function(){$(a+ -" #app-timezone").val($(this).data("value"))})}})}function c(){$("#edit-app").removeClass("active");$(".edit").hide();$(".read").show();$(".table-edit").hide();$(".required").hide()}function f(){$("#app-add-name").val("");$("#app-add-category").text(jQuery.i18n.map["management-applications.category.tip"]);$("#app-add-category").data("value","");$("#app-add-timezone #selected").text("");$("#app-add-timezone #selected").hide();$("#app-add-timezone .text").html(jQuery.i18n.map["management-applications.time-zone.tip"]); -$("#app-add-timezone .text").data("value","");$("#app-add-timezone #app-timezone").val("");$("#app-add-timezone #app-country").val("");$("#app-add-timezone #timezone-select").hide();$(".required").hide()}function e(){if($("#app-container-new").is(":visible"))return!1;$(".app-container").removeClass("active");$("#first-app-success").hide();c();var a=$("#manage-new-app>div").clone();a.attr("id","app-container-new");a.addClass("active");jQuery.isEmptyObject(countlyGlobal.apps)?$("#cancel-app-add").hide(): -$("#cancel-app-add").show();$("#app-management-bar .scrollable").append(a);$("#add-new-app").show();$("#view-app").hide();var a=jstz.determine().name(),d;for(d in h)for(var f=0;f").addClass("required").text("*"); -d||$("#app-edit-name .edit input").after(f.clone());if($(".required").length)return $(".required").fadeIn(),!1;var e=$("#add-edit-image-form").find("#app_image").val().split(".").pop().toLowerCase();if(e&&-1==$.inArray(e,["gif","png","jpg","jpeg"]))return CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red"),!1;$(this).addClass("disabled");$.ajax({type:"GET",url:countlyCommon.API_PARTS.apps.w+"/update",data:{args:JSON.stringify({app_id:b,name:d,category:$("#app-edit-category .cly-select .text").data("value")+ -"",timezone:$("#app-edit-timezone #app-timezone").val(),country:$("#app-edit-timezone #app-country").val()}),api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(f){for(var g in f)countlyGlobal.apps[b][g]=f[g],countlyGlobal.admin_apps[b][g]=f[g];if(!e)return $("#save-app-edit").removeClass("disabled"),a(b),c(),$(".app-container").filter(function(){return $(this).data("id")&&$(this).data("id")==b}).find(".name").text(d),!0;$("#add-edit-image-form").find("#app_image_id").val(b);$("#add-edit-image-form").ajaxSubmit({resetForm:!0, -beforeSubmit:function(a){a.push({name:"_csrf",value:countlyGlobal.csrf_token})},success:function(f){$("#save-app-edit").removeClass("disabled");var e=$(".app-container").filter(function(){return $(this).data("id")&&$(this).data("id")==b});f?(e.find(".logo").css({"background-image":"url("+f+")"}),$("#sidebar-app-select .logo").css("background-image",$("#sidebar-app-select .logo").css("background-image"))):CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red");a(b);c();e.find(".name").text(d)}})}})}); -$("#cancel-app-edit").click(function(){c();var b=$("#app-edit-id").val();a(b)});$(".app-container:not(#app-container-new)").live("click",function(){var b=$(this).data("id");c();$(".app-container").removeClass("active");$(this).addClass("active");a(b)});$("#add-app-button").click(function(){e()});$("#cancel-app-add").click(function(){$("#app-container-new").remove();$("#add-new-app").hide();$("#view-app").show();$(".new-app-name").text(jQuery.i18n.map["management-applications.my-new-app"]);f()});$("#app-add-name").keyup(function(){var a= -$(this).val();$("#app-container-new .name").text(a);$(".new-app-name").text(a)});$("#save-app-add").click(function(){if($(this).hasClass("disabled"))return!1;var b=$("#app-add-name").val(),c=$("#app-add-category").data("value")+"",d=$("#app-add-timezone #app-timezone").val(),f=$("#app-add-timezone #app-country").val();$(".required").fadeOut().remove();var e=$("").addClass("required").text("*");b||$("#app-add-name").after(e.clone());c||$("#app-add-category").parents(".cly-select").after(e.clone()); -d||$("#app-add-timezone #app-timezone").after(e.clone());if($(".required").length)return $(".required").fadeIn(),!1;var g=$("#add-app-image-form").find("#app_image").val().split(".").pop().toLowerCase();if(g&&-1==$.inArray(g,["gif","png","jpg","jpeg"]))return CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red"),!1;$(this).addClass("disabled");$.ajax({type:"GET",url:countlyCommon.API_PARTS.apps.w+"/create",data:{args:JSON.stringify({name:b,category:c,timezone:d,country:f}), -api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(b){var c=$("#sidebar-new-app>div").clone(),d={_id:b._id,name:b.name,key:b.key,category:b.category,timezone:b.timezone,country:b.country};countlyGlobal.apps[b._id]=d;countlyGlobal.admin_apps[b._id]=d;var f=$("#app-container-new");f.data("id",b._id);f.data("key",b.key);f.removeAttr("id");if(!g)return $("#save-app-add").removeClass("disabled"),c.find(".name").text(b.name),c.data("id",b._id),c.data("key",b.key),$("#app-nav .apps-scrollable").append(c), -a(b._id),!0;$("#add-app-image-form").find("#app_image_id").val(b._id);$("#add-app-image-form").ajaxSubmit({resetForm:!0,beforeSubmit:function(a){a.push({name:"_csrf",value:countlyGlobal.csrf_token})},success:function(d){$("#save-app-add").removeClass("disabled");d?(f.find(".logo").css({"background-image":"url("+d+")"}),c.find(".logo").css({"background-image":"url("+d+")"})):CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red");c.find(".name").text(b.name);c.data("id",b._id); -c.data("key",b.key);$("#app-nav .apps-scrollable").append(c);a(b._id)}})}})})}});window.ManageUsersView=countlyView.extend({template:null,initialize:function(){var a=this;T.render("templates/users",function(b){a.template=b})},renderCommon:function(){var a=this;$.ajax({url:countlyCommon.API_PARTS.users.r+"/all",data:{api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(b){$("#content").html(a.template({users:b,apps:countlyGlobal.apps}))}})}}); -window.ManageExportView=countlyView.extend({initialize:function(){this.template=Handlebars.compile($("#template-management-export").html())},pageScript:function(){$("#export-select-all").on("click",function(){$("#export-checkbox-container .checkbox").addClass("checked");$(this).hide();$("#export-deselect-all").show()});$("#export-deselect-all").on("click",function(){$("#export-checkbox-container .checkbox").removeClass("checked");$(this).hide();$("#export-select-all").show()});$("#export-checkbox-container .checkbox").on("click", -function(){var a=1;$(this).hasClass("checked")&&(a=-1);var b=$("#export-checkbox-container .checkbox").length,a=$("#export-checkbox-container .checkbox.checked").length+a;b==a?($("#export-deselect-all").show(),$("#export-select-all").hide()):($("#export-select-all").show(),$("#export-deselect-all").hide())})},renderCommon:function(){$(this.el).html(this.template({events:countlyEvent.getEventsWithSegmentations(),app_name:app.activeAppName,exports:[]}));this.pageScript()},appChanged:function(){this.renderCommon()}}); -window.EventsView=countlyView.extend({showOnGraph:2,beforeRender:function(){return $.when(countlyEvent.initialize()).then(function(){})},initialize:function(){this.template=Handlebars.compile($("#template-events").html())},pageScript:function(){var a=this;$(".event-container").on("click",function(){var b=$(this).data("key");a.showOnGraph=2;$(".event-container").removeClass("active");$(this).addClass("active");countlyEvent.setActiveEvent(b,function(){a.refresh(!0)})});$(".segmentation-option").on("click", -function(){var b=$(this).data("value");countlyEvent.setActiveSegmentation(b);a.refresh(!1,!0)});$(".big-numbers").on("click",function(){if(2==$(".big-numbers.selected").length)a.showOnGraph=1-$(this).index();else if(1==$(".big-numbers.selected").length){if($(this).hasClass("selected"))return!0;a.showOnGraph=2}$(this).toggleClass("selected");a.drawGraph(countlyEvent.getEventData())});countlyGlobal.admin_apps[countlyCommon.ACTIVE_APP_ID]&&$("#edit-events-button").show()},drawGraph:function(a){2!=this.showOnGraph? -($(".big-numbers").removeClass("selected"),$(".big-numbers").eq(this.showOnGraph).addClass("selected"),2==a.dataLevel?a.chartDP.dp=a.chartDP.dp.slice(this.showOnGraph,this.showOnGraph+1):a.chartDP=a.chartDP.slice(this.showOnGraph,this.showOnGraph+1)):$(".big-numbers").addClass("selected");2==a.dataLevel?countlyCommon.drawGraph(a.chartDP,"#dashboard-graph","bar",{series:{stack:null}}):countlyCommon.drawTimeGraph(a.chartDP,"#dashboard-graph")},drawTable:function(a){this.dtable&&this.dtable.fnDestroy&& -this.dtable.fnDestroy(!0);$("#event-main").append('
    ');var b=[];countlyEvent.isSegmentedView()?b.push({mData:"curr_segment",sTitle:jQuery.i18n.map["events.table.segmentation"]}):b.push({mData:"date",sType:"customDate",sTitle:jQuery.i18n.map["common.date"]});b.push({mData:"c",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:a.tableColumns[1]});a.tableColumns[2]&&b.push({mData:"s",sType:"formatted-num", -mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:a.tableColumns[2]});this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:a.chartData,aoColumns:b}));$(".d-table").stickyTableHeaders()},getColumnCount:function(){return $(".dataTable").find("thead th").length},renderCommon:function(a){var b=countlyEvent.getEventData(),c=countlyEvent.getEventSummary();this.templateData={"page-title":b.eventName.toUpperCase(),"logo-class":"events",events:countlyEvent.getEvents(), -"event-map":countlyEvent.getEventMap(),segmentations:countlyEvent.getEventSegmentations(),"active-segmentation":countlyEvent.getActiveSegmentation(),"big-numbers":c,"chart-data":{columnCount:b.tableColumns.length,columns:b.tableColumns,rows:b.chartData}};if(0==countlyEvent.getEvents().length)return window.location="dashboard#/",CountlyHelpers.alert(jQuery.i18n.map["events.no-event"],"black"),!0;a||($(this.el).html(this.template(this.templateData)),this.drawGraph(b),this.drawTable(b),this.pageScript(), -$("#edit-events-button").on("click",function(){CountlyHelpers.popup("#edit-event-container","events");$(".dialog #edit-event-table-container").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0});$(".dialog .events-table").sortable({items:"tr",revert:!0,handle:"td:first-child",helper:function(a,b){b.children().each(function(){$(this).width($(this).width())});b.addClass("moving");return b},cursor:"move",containment:"parent",tolerance:"pointer",placeholder:"event-row-placeholder", -stop:function(a,b){b.item.removeClass("moving")}});$(".dialog #events-save").on("click",function(){var a={},b=[];$(".dialog .events-table tbody tr").each(function(){var b=$(this);eventKey=b.find(".event-key").text();b.find(".event-name").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].name=b.find(".event-name").val());b.find(".event-count").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].count=b.find(".event-count").val());b.find(".event-sum").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].sum= -b.find(".event-sum").val())});$(".dialog .events-table").find(".event-key").each(function(){$(this).text()&&b.push($(this).text())});$.ajax({type:"POST",url:"/events/map/edit",data:{app_id:countlyCommon.ACTIVE_APP_ID,event_map:a,event_order:b,_csrf:countlyGlobal.csrf_token},success:function(){self.refresh()}})});$(".delete-event").on("click",function(){var a=$(this).data("event-key");a&&CountlyHelpers.confirm(jQuery.i18n.prop("events.delete-confirm",a),"red",function(b){b&&$.ajax({type:"POST",url:"/events/delete", -data:{event_key:a,app_id:countlyCommon.ACTIVE_APP_ID,_csrf:countlyGlobal.csrf_token},success:function(){countlyEvent.reset();self.render()}})})})}))},refresh:function(a,b){var c=this;$.when(countlyEvent.initialize(a)).then(function(){if(app.activeView!=c)return!1;c.renderCommon(!0);newPage=$("
    "+c.template(c.templateData)+"
    ");$(c.el).find("#event-nav .scrollable").html(function(){return newPage.find("#event-nav .scrollable").html()});b||($("#event-update-area .cly-select").length&&!a?($(c.el).find("#event-update-area .select-items").html(function(){return newPage.find("#event-update-area .select-items").html()}), -$(".select-items .item").click(function(){var a=$(this).parents(".cly-select").find(".text");a.text($(this).text());a.data("value",$(this).data("value"))})):$(c.el).find("#event-update-area").replaceWith(newPage.find("#event-update-area")));$(c.el).find(".widget-footer").html(newPage.find(".widget-footer").html());$(c.el).find("#edit-event-container").replaceWith(newPage.find("#edit-event-container"));var f=countlyEvent.getEventData();c.drawGraph(f);c.pageScript();a||b?c.drawTable(f):c.getColumnCount()!= -f.tableColumns.length?c.drawTable(f):CountlyHelpers.refreshTable(c.dtable,f.chartData);app.localize()})}}); window.DensityView=countlyView.extend({beforeRender:function(){return $.when(countlyDeviceDetails.initialize()).then(function(){})},renderCommon:function(a){var b=countlyDeviceDetails.getDensityData();this.templateData={"page-title":jQuery.i18n.map["density.title"],"logo-class":"densities","graph-type-double-pie":!0,"pie-titles":{left:jQuery.i18n.map["common.total-users"],right:jQuery.i18n.map["common.new-users"]},"chart-helper":"resolutions.chart"};a||($(this.el).html(this.template(this.templateData)), this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"densities",sType:"session-duration",sTitle:jQuery.i18n.map["density.table.density"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-sessions"]},{mData:"u",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.total-users"]},{mData:"n",sType:"formatted-num", mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.table.new-users"]}]})),$(".d-table").stickyTableHeaders(),countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie"),countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie"))},refresh:function(){var a=this;$.when(countlyDeviceDetails.refresh()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find(".dashboard-summary").replaceWith(newPage.find(".dashboard-summary")); var b=countlyDeviceDetails.getDensityData();countlyCommon.drawGraph(b.chartDPTotal,"#dashboard-graph","pie");countlyCommon.drawGraph(b.chartDPNew,"#dashboard-graph2","pie");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); -window.EnterpriseView=countlyView.extend({initialize:function(){this.template=Handlebars.compile($("#template-enterprise").html())},pageScript:function(){var a={drill:"Game changer for data analytics",funnels:"Track completion rates step by step",retention:"See how engaging your application is",revenue:"Calculate your customer's lifetime value",scalability:"Tens of millions of users? No problem",support:"Enterprise support and SLA","raw-data":"Your data, your rules"};$("#enterprise-sections").find(".app-container").on("click", -function(){var b=$(this).data("section");$(".enterprise-content").hide();$(".enterprise-content."+b).show();$("#enterprise-sections").find(".app-container").removeClass("active");$(this).addClass("active");$(".widget-header .title").text(a[b]||"")})},renderCommon:function(){$(this.el).html(this.template(this.templateData));this.pageScript()}}); -window.AllAppsView=countlyView.extend({selectedView:"#draw-total-sessions",selectedApps:{all:!0},selectedCount:0,initialize:function(){this.template=Handlebars.compile($("#template-allapps").html())},beforeRender:function(){return $.when(countlyAllApps.initialize()).then(function(){})},pageScript:function(){$(".widget-content .inner").click(function(){$(".big-numbers").removeClass("active");$(".big-numbers .select").removeClass("selected");$(this).parent(".big-numbers").addClass("active");$(this).find(".select").addClass("selected")}); -var a=this;$(".big-numbers .inner").click(function(){var b=$(this).find(".select").attr("id");if(a.selectedView=="#"+b)return!0;a.selectedView="#"+b;a.drawGraph()});app.localize()},drawGraph:function(){var a=[],b=countlyAllApps.getSessionData(),c,f,e=0,d;for(d in this.selectedApps)try{c=b[d][this.selectedView],f=countlyCommon.GRAPH_COLORS[e],"all"==d?a.push({data:c.data,label:c.label+" for All Apps",color:f}):a.push({data:c.data,label:c.label+" for "+countlyGlobal.apps[d].name,color:f}),$("#"+d+" .color").css("background-color", -f),e++}catch(h){}_.defer(function(){countlyCommon.drawTimeGraph(a,"#dashboard-graph")})},renderCommon:function(a){$("#sidebar-app-select").find(".text").text(jQuery.i18n.map["allapps.title"]);$("#sidebar-app-select").find(".logo").css("background-image","url('/images/favicon.png')");$("#sidebar-menu > .item").addClass("hide");$("#management-menu").removeClass("hide");$("#enterprise-menu").removeClass("hide");$("#allapps-menu").removeClass("hide").css("display","block");var b=countlyAllApps.getData(); -this.templateData={"page-title":jQuery.i18n.map["allapps.title"],"logo-class":"platforms",usage:[{title:jQuery.i18n.map["common.total-sessions"],data:0,id:"draw-total-sessions",help:"dashboard.total-sessions"},{title:jQuery.i18n.map["common.total-users"],data:0,id:"draw-total-users",help:"dashboard.total-users"},{title:jQuery.i18n.map["common.new-users"],data:0,id:"draw-new-users",help:"dashboard.new-users"},{title:jQuery.i18n.map["dashboard.time-spent"],data:0,id:"draw-total-time-spent",help:"dashboard.total-time-spent"}, -{title:jQuery.i18n.map["dashboard.avg-time-spent"],data:0,id:"draw-time-spent",help:"dashboard.avg-time-spent2"},{title:jQuery.i18n.map["dashboard.avg-reqs-received"],data:0,id:"draw-avg-events-served",help:"dashboard.avg-reqs-received"}]};var c=this;a||($(this.el).html(this.template(this.templateData)),$(this.selectedView).parents(".big-numbers").addClass("active"),this.pageScript(),this.dtable=$(".d-table").dataTable($.extend({},$.fn.dataTable.defaults,{aaData:b,fnRowCallback:function(a,b){$(a).attr("id", -b._id)},aoColumns:[{mData:function(a){return c.selectedApps[a._id]?"":""},sWidth:"10px",bSortable:!1},{mData:function(a,b){return"display"==b?("all"==a._id?" ":" ")+a.name+"
    ":a.name},sType:"string",sTitle:jQuery.i18n.map["allapps.app-name"]},{mData:function(a, -b){return"display"==b?"
    "+a.sessions.total:a.sessions.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-sessions"]},{mData:function(a,b){return"display"==b?"
    "+a.users.total:a.users.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-users"]},{mData:function(a,b){return"display"== -b?"
    "+a.newusers.total:a.newusers.total},sType:"string",sTitle:jQuery.i18n.map["allapps.new-users"]},{mData:function(a,b){return"display"==b?"
    "+a.duration.total:a.duration.total},sType:"string",sTitle:jQuery.i18n.map["allapps.total-duration"]},{mData:function(a,b){return"display"==b?"
    "+a.avgduration.total:a.avgduration.total},sType:"string",sTitle:jQuery.i18n.map["allapps.average-duration"]}]})),this.drawGraph(),$(".dataTable-bottom").append("
    Maximum number of applications to be compared (10)
    "),$(".d-table").stickyTableHeaders(),$(".allapps tbody").on("click","tr",function(a){var b=$(a.target).closest("td"),a=$(this);if(a.children().first().is(b)){if(c.selectedApps[a.attr("id")])a.find(".check").removeClass("icon-check").addClass("icon-unchecked"), -a.find(".color").css("background-color","transparent"),delete c.selectedApps[a.attr("id")],"all"!=a.attr("id")&&c.selectedCount--,0==c.selectedCount&&($("#empty-graph").show(),$(".big-numbers").removeClass("active"),$(".big-numbers .select").removeClass("selected"));else if(10>c.selectedCount||"all"==a.attr("id"))0==c.selectedCount&&($("#empty-graph").hide(),$(c.selectedView).parents(".big-numbers").addClass("active")),"all"==a.attr("id")?($(".check.icon-check").removeClass("icon-check").addClass("icon-unchecked"), -$(".d-table").find(".color").css("background-color","transparent"),c.selectedApps={},c.selectedCount=0):(c.selectedApps.all&&($(".d-table #all .check.icon-check").removeClass("icon-check").addClass("icon-unchecked"),$(".d-table #all").find(".color").css("background-color","transparent"),delete c.selectedApps.all),c.selectedCount++),a.find(".check").removeClass("icon-unchecked").addClass("icon-check"),c.selectedApps[a.attr("id")]=!0;c.drawGraph()}else b=c.dtable.fnGetData(this),countlyAllApps.setApp(a.attr("id")), -$("#sidebar-app-select").find(".logo").css("background-image","url('/appimages/"+a.attr("id")+".png')"),$("#sidebar-app-select").find(".text").text(b.name),$("#sidebar-menu > .item").removeClass("hide"),$("#allapps-menu").css("display","none"),window.location.hash="#/"}))},refresh:function(){var a=this;$.when(countlyAllApps.initialize()).then(function(){if(app.activeView!=a)return!1;a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");var b=countlyAllApps.getData();CountlyHelpers.refreshTable(a.dtable, -b);a.drawGraph();app.localize()})}}); -var AppRouter=Backbone.Router.extend({routes:{"/":"dashboard","/analytics/sessions":"sessions","/analytics/countries":"countries","/analytics/users":"users","/analytics/loyalty":"loyalty","/analytics/devices":"devices","/analytics/platforms":"platforms","/analytics/versions":"versions","/analytics/carriers":"carriers","/analytics/frequency":"frequency","/analytics/events":"events","/analytics/resolutions":"resolutions","/analytics/density":"density","/analytics/durations":"durations","/all":"allapps", -"/manage/apps":"manageApps","/manage/users":"manageUsers","/enterprise":"enterprise","*path":"main"},activeView:null,dateToSelected:null,dateFromSelected:null,activeAppName:"",activeAppKey:"",main:function(){this.navigate("/",!0)},dashboard:function(){this.renderWhenReady(this.dashboardView)},sessions:function(){this.renderWhenReady(this.sessionView)},countries:function(){this.renderWhenReady(this.countriesView)},devices:function(){this.renderWhenReady(this.deviceView)},platforms:function(){this.renderWhenReady(this.platformView)}, -versions:function(){this.renderWhenReady(this.appVersionView)},users:function(){this.renderWhenReady(this.userView)},loyalty:function(){this.renderWhenReady(this.loyaltyView)},frequency:function(){this.renderWhenReady(this.frequencyView)},carriers:function(){this.renderWhenReady(this.carrierView)},manageApps:function(){this.renderWhenReady(this.manageAppsView)},manageUsers:function(){this.renderWhenReady(this.manageUsersView)},events:function(){this.renderWhenReady(this.eventsView)},resolutions:function(){this.renderWhenReady(this.resolutionsView)}, -density:function(){this.renderWhenReady(this.densityView)},durations:function(){this.renderWhenReady(this.durationsView)},enterprise:function(){this.renderWhenReady(this.enterpriseView)},allapps:function(){this.renderWhenReady(this.allAppsView)},refreshActiveView:function(){},renderWhenReady:function(a){this.activeView&&this.activeView.destroy();this.activeView=a;clearInterval(this.refreshActiveView);if(_.isEmpty(countlyGlobal.apps))return"/manage/apps"!=Backbone.history.fragment?this.navigate("/manage/apps", -!0):a.render(),!1;a.render();var b=this;this.refreshActiveView=setInterval(function(){b.activeView.refresh()},countlyCommon.DASHBOARD_REFRESH_MS)},initialize:function(){this.dashboardView=new DashboardView;this.sessionView=new SessionView;this.countriesView=new CountriesView;this.userView=new UserView;this.loyaltyView=new LoyaltyView;this.deviceView=new DeviceView;this.platformView=new PlatformView;this.appVersionView=new AppVersionView;this.frequencyView=new FrequencyView;this.carrierView=new CarrierView; -this.manageAppsView=new ManageAppsView;this.manageUsersView=new ManageUsersView;this.eventsView=new EventsView;this.resolutionsView=new ResolutionView;this.densityView=new DensityView;this.durationsView=new DurationView;this.enterpriseView=new EnterpriseView;this.allAppsView=new AllAppsView;Handlebars.registerPartial("date-selector",$("#template-date-selector").html());Handlebars.registerPartial("timezones",$("#template-timezones").html());Handlebars.registerPartial("app-categories",$("#template-app-categories").html()); -Handlebars.registerHelper("eachOfObject",function(a,b){var e="",d;for(d in a)e+=b.fn({property:d,value:a[d]});return e});Handlebars.registerHelper("eachOfObjectValue",function(a,b){var e="",d;for(d in a)e+=b.fn(a[d]);return e});Handlebars.registerHelper("eachOfArray",function(a,b){for(var e="",d=0;d .item").removeClass("hide");$("#allapps-menu").css("display","none");"#/all"==window.location.hash.toString()&&(window.location.hash="/");if(a.activeAppKey==b)return j.removeClass("active"),$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),!1;a.activeAppName=e;a.activeAppKey=b;$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack",complete:function(){countlyCommon.setActiveApp(c);j.find(".text").text(e); -j.find(".logo").css("background-image",f);j.removeClass("active");a.activeView.appChanged()}})});$("#sidebar-events").click(function(a){$.when(countlyEvent.refreshEvents()).then(function(){0==countlyEvent.getEvents().length&&(CountlyHelpers.alert(jQuery.i18n.map["events.no-event"],"black"),a.stopImmediatePropagation(),a.preventDefault())})});$("#sidebar-menu>.item").click(function(){var a=$(this).next();a.find(".item");var b=$(this).hasClass("active");b||$(".sidebar-submenu").not(a).slideUp();a.hasClass("sidebar-submenu")&& -!b?a.slideToggle():($("#sidebar-menu>.item").removeClass("active"),$(this).addClass("active"),201==$("#app-nav").offset().left&&($("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),$("#sidebar-app-select").removeClass("active")));$(this).attr("href")&&$("#sidebar-app-select").removeClass("disabled")});$(".sidebar-submenu .item").click(function(){if($(this).hasClass("disabled"))return!0;"#/manage/apps"==$(this).attr("href")?($("#sidebar-app-select").addClass("disabled"),$("#sidebar-app-select").removeClass("active")): -$("#sidebar-app-select").removeClass("disabled");201==$("#app-nav").offset().left&&($("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),$("#sidebar-app-select").removeClass("active"));$(".sidebar-submenu .item").removeClass("active");$(this).addClass("active");$(this).parent().prev(".item").addClass("active")});$("#sidebar-app-select").click(function(){if($(this).hasClass("disabled"))return!0;$(this).hasClass("active")?$(this).removeClass("active"):$(this).addClass("active");$("#app-nav").show(); -201==$("#app-nav").offset().left?$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}):$("#app-nav").animate({left:"201px"},{duration:500,easing:"easeOutBack"})});$("#sidebar-bottom-container .reveal-menu").click(function(){$("#language-menu").hide();$("#sidebar-bottom-container .menu").toggle()});$("#sidebar-bottom-container .reveal-language-menu").click(function(){$("#sidebar-bottom-container .menu").hide();$("#language-menu").toggle()});$("#sidebar-bottom-container .item").click(function(){$("#sidebar-bottom-container .menu").hide(); -$("#language-menu").hide()});$("#language-menu .item").click(function(){var b=$(this).data("language-code"),c=b.toUpperCase();store.set("countly_lang",b);$(".reveal-language-menu").text(c);countlyCommon.BROWSER_LANG_SHORT=b;countlyCommon.BROWSER_LANG=b;try{moment.lang(countlyCommon.BROWSER_LANG_SHORT)}catch(e){moment.lang("en")}$("#date-to").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$("#date-from").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]); -jQuery.i18n.properties({name:"help",cache:!0,language:countlyCommon.BROWSER_LANG_SHORT,path:"/localization/help/",mode:"map",callback:function(){countlyCommon.HELP_MAP=jQuery.i18n.map;jQuery.i18n.map={};jQuery.i18n.properties({name:"dashboard",cache:!0,language:countlyCommon.BROWSER_LANG_SHORT,path:"/localization/dashboard/",mode:"map",callback:function(){$.when(countlyLocation.changeLanguage()).then(function(){a.activeView.render();a.pageScript()})}})}})});$("#account-settings").click(function(){CountlyHelpers.popup("#edit-account-details"); -$(".dialog #username").val($("#menu-username").text());$(".dialog #api-key").val($("#user-api-key").val())});$("#save-account-details:not(.disabled)").live("click",function(){var a=$(".dialog #username").val(),b=$(".dialog #old_pwd").val(),c=$(".dialog #new_pwd").val(),e=$(".dialog #re_new_pwd").val();if(c!=e)return $(".dialog #settings-save-result").addClass("red").text(jQuery.i18n.map["user-settings.password-match"]),!0;$(this).addClass("disabled");$.ajax({type:"POST",url:"/user/settings",data:{username:a, -old_pwd:b,new_pwd:c,_csrf:countlyGlobal.csrf_token},success:function(b){var c=$(".dialog #settings-save-result");"username-exists"==b?c.removeClass("green").addClass("red").text(jQuery.i18n.map["management-users.username.exists"]):b?(c.removeClass("red").addClass("green").text(jQuery.i18n.map["user-settings.success"]),$(".dialog #old_pwd").val(""),$(".dialog #new_pwd").val(""),$(".dialog #re_new_pwd").val(""),$("#menu-username").text(a)):c.removeClass("green").addClass("red").text(jQuery.i18n.map["user-settings.alert"]); -$(".dialog #save-account-details").removeClass("disabled")}})});$(".apps-scrollable").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0});var e=_.once(function(){CountlyHelpers.alert(countlyCommon.HELP_MAP["help-mode-welcome"],"black")});$(".help-toggle, #help-toggle").click(function(b){$(".help-zone-vb").tipsy({gravity:$.fn.tipsy.autoNS,trigger:"manual",title:function(){return $(this).data("help")?$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow",opacity:1, -html:!0});$(".help-zone-vs").tipsy({gravity:$.fn.tipsy.autoNS,trigger:"manual",title:function(){return $(this).data("help")?$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow narrow",opacity:1,html:!0});$("#help-toggle").toggleClass("active");$("#help-toggle").hasClass("active")?(e(),$.idleTimer("destroy"),clearInterval(a.refreshActiveView),$(".help-zone-vs, .help-zone-vb").hover(function(){$(this).tipsy("show")},function(){$(this).tipsy("hide")})):(a.refreshActiveView=setInterval(function(){a.activeView.refresh()}, -countlyCommon.DASHBOARD_REFRESH_MS),$.idleTimer(countlyCommon.DASHBOARD_IDLE_MS),$(".help-zone-vs, .help-zone-vb").unbind("mouseenter mouseleave"));b.stopPropagation()});$("#user-logout").click(function(){store.remove("countly_active_app");store.remove("countly_date");store.remove("countly_location_city")});$(".beta-button").click(function(){CountlyHelpers.alert("This feature is currently in beta so the data you see in this view might change or disappear into thin air.

    If you find any bugs or have suggestions please let us know!

    Captain Obvious: You can use the message box that appears when you click the question mark on the bottom right corner of this page.", -"black")})});if(_.isEmpty(countlyGlobal.apps))$("#new-install-overlay").show();else if(countlyCommon.ACTIVE_APP_ID)$("#sidebar-app-select").find(".logo").css("background-image","url('/appimages/"+countlyCommon.ACTIVE_APP_ID+".png')"),$("#sidebar-app-select .text").text(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].name),a.activeAppName=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].name;else for(var b in countlyGlobal.apps){countlyCommon.setActiveApp(b);a.activeAppName=countlyGlobal.apps[b].name; -break}$.idleTimer(countlyCommon.DASHBOARD_IDLE_MS);$(document).bind("idle.idleTimer",function(){clearInterval(a.refreshActiveView)});$(document).bind("active.idleTimer",function(){a.activeView.restart();a.refreshActiveView=setInterval(function(){a.activeView.refresh()},countlyCommon.DASHBOARD_REFRESH_MS)})},localize:function(){var a={onlyFirstUpper:function(a){return a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()},upper:function(a){return a.toUpperCase()}};$("[data-help-localize]").each(function(){var a= -$(this);void 0!=a.data("help-localize")&&a.data("help",countlyCommon.HELP_MAP[a.data("help-localize")])});$("[data-localize]").each(function(){var b=$(this),c=b.data("localize").split("!"),f="",f=2==c.length?a[c[0]]?a[c[0]](jQuery.i18n.map[c[1]]):jQuery.i18n.prop(c[0],jQuery.i18n.map[c[1]]):jQuery.i18n.map[b.data("localize")];b.is("input[type=text]")||b.is("input[type=password]")?b.attr("placeholder",f):b.is("input[type=button]")||b.is("input[type=submit]")?b.attr("value",f):b.text(f)})},pageScript:function(){$("#month").text(moment().year()); -$("#day").text(moment().format("MMM"));$("#yesterday").text(moment().subtract("days",1).format("Do"));var a=this;$(document).ready(function(){a.localize();$("#help-toggle").hasClass("active")&&($(".help-zone-vb").tipsy({gravity:$.fn.tipsy.autoNS,trigger:"manual",title:function(){return $(this).data("help")?$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow",opacity:1,html:!0}),$(".help-zone-vs").tipsy({gravity:$.fn.tipsy.autoNS,trigger:"manual",title:function(){return $(this).data("help")? -$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow narrow",opacity:1,html:!0}),$.idleTimer("destroy"),clearInterval(a.refreshActiveView),$(".help-zone-vs, .help-zone-vb").hover(function(){$(this).tipsy("show")},function(){$(this).tipsy("hide")}));$("#sidebar-menu").find("a").removeClass("active");var b=$("#sidebar-menu").find("a[href='#"+Backbone.history.fragment+"']");b.addClass("active");var c=b.parent(".sidebar-submenu");c.prev(".item").addClass("active");b.not(":visible")&&c.slideDown(); -b=countlyCommon.getPeriod();"[object Array]"!==Object.prototype.toString.call(b)&&$("#"+b).addClass("active");$(".usparkline").peity("bar",{width:"100%",height:"30",colour:"#6BB96E",strokeColour:"#6BB96E",strokeWidth:2});$(".dsparkline").peity("bar",{width:"100%",height:"30",colour:"#C94C4C",strokeColour:"#C94C4C",strokeWidth:2});$("#date-selector").find(">.button").click(function(){if($(this).hasClass("selected"))return!0;a.dateFromSelected=null;a.dateToSelected=null;$(".date-selector").removeClass("selected").removeClass("active"); -$(this).addClass("selected");var b=$(this).attr("id");if(countlyCommon.getPeriod()==b)return!0;countlyCommon.setPeriod(b);a.activeView.dateChanged();$("#"+b).addClass("active");a.pageScript()});$(window).click(function(){$("#date-picker").hide();$(".cly-select").removeClass("active")});$("#date-picker").click(function(a){a.stopPropagation()});$("#date-picker-button").click(function(b){$("#date-picker").toggle();a.dateToSelected?f.datepicker("setDate",moment(a.dateToSelected).toDate()):(a.dateToSelected= -moment().toDate().getTime(),f.datepicker("setDate",moment().toDate()));e.datepicker("option","maxDate",moment(a.dateToSelected).toDate());a.dateFromSelected?e.datepicker("setDate",moment(a.dateFromSelected).toDate()):(extendDate=moment(f.datepicker("getDate")).subtract("days",30).toDate(),e.datepicker("setDate",extendDate),a.dateFromSelected=moment(f.datepicker("getDate")).subtract("days",30).toDate().getTime());f.datepicker("option","minDate",moment(a.dateFromSelected).toDate());b.stopPropagation()}); -var f=$("#date-to").datepicker({numberOfMonths:1,showOtherMonths:!0,maxDate:moment().toDate(),onSelect:function(b){var c=$(this).data("datepicker"),b=$.datepicker.parseDate(c.settings.dateFormat||$.datepicker._defaults.dateFormat,b,c.settings),c=new Date(b.getTime());c.getTime()a.dateToSelected&&(a.dateToSelected=c.getTime());f.datepicker("option","minDate",c);a.dateFromSelected=b.getTime()}});$.datepicker.setDefaults($.datepicker.regional[""]);$("#date-to").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$("#date-from").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]); -$("#date-submit").click(function(){if(!a.dateFromSelected&&!a.dateToSelected)return!1;countlyCommon.setPeriod([a.dateFromSelected,a.dateToSelected]);a.activeView.dateChanged();a.pageScript();$(".date-selector").removeClass("selected").removeClass("active")});$(".scrollable").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0});$(".widget-header").noisy({intensity:0.9,size:50,opacity:0.04,monochrome:!0});$(".checkbox").on("click",function(){$(this).toggleClass("checked")})})}}), -app=new AppRouter;Backbone.history.start(); +window.DurationView=countlyView.extend({beforeRender:function(){return $.when(countlyUser.initialize()).then(function(){})},renderCommon:function(a){var b=countlySession.getDurationData();this.templateData={"page-title":jQuery.i18n.map["session-duration.title"],"logo-class":"durations","chart-helper":"durations.chart","table-helper":"durations.table"};a||($(this.el).html(this.template(this.templateData)),countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar"),this.dtable=$(".d-table").dataTable($.extend({}, +$.fn.dataTable.defaults,{aaData:b.chartData,aoColumns:[{mData:"ds",sType:"session-duration",sTitle:jQuery.i18n.map["session-duration.table.duration"]},{mData:"t",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:jQuery.i18n.map["common.number-of-users"]},{mData:"percent",sType:"percent",sTitle:jQuery.i18n.map["common.percent"]}]})),$(".d-table").stickyTableHeaders())},refresh:function(){var a=this;$.when(countlyUser.initialize()).then(function(){if(app.activeView!= +a)return!1;var b=countlySession.getDurationData();countlyCommon.drawGraph(b.chartDP,"#dashboard-graph","bar");CountlyHelpers.refreshTable(a.dtable,b.chartData)})}}); +window.ManageAppsView=countlyView.extend({initialize:function(){this.template=Handlebars.compile($("#template-management-applications").html())},renderCommon:function(){function a(a){if(jQuery.isEmptyObject(countlyGlobal.apps))return c(),$("#no-app-warning").show(),!1;if(jQuery.isEmptyObject(countlyGlobal.admin_apps))return c(),!1;$("#app-container-new").remove();$("#add-new-app").hide();e();$("#view-app").show();countlyGlobal.admin_apps[a]?$("#delete-app").show():$("#delete-app").hide();$("#new-install-overlay").is(":visible")&& +($("#no-app-warning").hide(),$("#first-app-success").show(),$("#new-install-overlay").fadeOut(),countlyCommon.setActiveApp(a),$("#sidebar-app-select").find(".logo").css("background-image","url('"+countlyGlobal.cdn+"appimages/"+a+".png')"),$("#sidebar-app-select").find(".text").text(countlyGlobal.apps[a].name));$("#app-edit-id").val(a);$("#view-app").find(".widget-header .title").text(countlyGlobal.apps[a].name);$("#app-edit-name").find(".read").text(countlyGlobal.apps[a].name);$("#app-edit-name").find(".edit input").val(countlyGlobal.apps[a].name); +$("#view-app-key").text(countlyGlobal.apps[a].key);$("#view-app-id").text(a);$("#app-edit-category").find(".cly-select .text").text(h[countlyGlobal.apps[a].category]);$("#app-edit-category").find(".cly-select .text").data("value",countlyGlobal.apps[a].category);$("#app-edit-timezone").find(".cly-select .text").data("value",countlyGlobal.apps[a].timezone);$("#app-edit-category").find(".read").text(h[countlyGlobal.apps[a].category]);$("#app-edit-image").find(".read .logo").css({"background-image":'url("'+ +countlyGlobal.cdn+"appimages/"+a+'.png")'});for(var d=i[countlyGlobal.apps[a].country],f=0;f
    "+i[f].n+"");if(c&&b&&d){e=i[c];if(1==e.z.length)for(var q in e.z[0])$(a+" #selected").show(),$(a+" #selected").text(q),$(a+" #app-timezone").val(e.z[0][q]),$(a+" #app-country").val(c), +$(a+" #country-select .text").html("
    "+e.n);else{$(a+" #timezone-select").find(".text").text(q);f=e.z;for(var v=0;v"+q+"");$(a+" #app-timezone").val(d);$(a+" #app-country").val(c);$(a+" #country-select .text").html("
    "+e.n);$(a+" #timezone-select .text").text(b);$(a+" #timezone-select").show()}$(a+" .select-items .item").click(function(){var a=$(this).parents(".cly-select").find(".text");a.html($(this).html());a.data("value",$(this).data("value"))});$(a+" #timezone-items .item").click(function(){$(a+" #app-timezone").val($(this).data("value"))})}$(a+" #country-items .item").click(function(){$(a+" #selected").text("");$(a+" #timezone-select").hide();h.html("");var c=$(this).data("value");if(1==i[c].z.length)for(var b in i[c].z[0])$(a+ +" #selected").show(),$(a+" #selected").text(b),$(a+" #app-timezone").val(i[c].z[0][b]),$(a+" #app-country").val(c);else{for(var d="",e=0;e"+b+"");$(a+" #timezone-select").show();$(a+" #app-timezone").val(d);$(a+" .select-items .item").click(function(){var a=$(this).parents(".cly-select").find(".text"); +a.html($(this).html());a.data("value",$(this).data("value"))});$(a+" #timezone-items .item").click(function(){$(a+" #app-timezone").val($(this).data("value"))})}})}function d(){$("#edit-app").removeClass("active");$(".edit").hide();$(".read").show();$(".table-edit").hide();$(".required").hide()}function e(){$("#app-add-name").val("");$("#app-add-category").text(jQuery.i18n.map["management-applications.category.tip"]);$("#app-add-category").data("value","");$("#app-add-timezone #selected").text(""); +$("#app-add-timezone #selected").hide();$("#app-add-timezone .text").html(jQuery.i18n.map["management-applications.time-zone.tip"]);$("#app-add-timezone .text").data("value","");$("#app-add-timezone #app-timezone").val("");$("#app-add-timezone #app-country").val("");$("#app-add-timezone #timezone-select").hide();$(".required").hide()}function c(){if($("#app-container-new").is(":visible"))return!1;$(".app-container").removeClass("active");$("#first-app-success").hide();d();var a=$("#manage-new-app>div").clone(); +a.attr("id","app-container-new");a.addClass("active");jQuery.isEmptyObject(countlyGlobal.apps)?$("#cancel-app-add").hide():$("#cancel-app-add").show();$("#app-management-bar .scrollable").append(a);$("#add-new-app").show();$("#view-app").hide();var a=jstz.determine().name(),c;for(c in i)for(var e=0;e").addClass("required").text("*");b||$("#app-edit-name .edit input").after(e.clone());if($(".required").length)return $(".required").fadeIn(),!1;var h=$("#add-edit-image-form").find("#app_image").val().split(".").pop().toLowerCase();if(h&&-1==$.inArray(h,["gif","png","jpg","jpeg"]))return CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red"),!1;$(this).addClass("disabled");$.ajax({type:"GET",url:countlyCommon.API_PARTS.apps.w+ +"/update",data:{args:JSON.stringify({app_id:c,name:b,category:$("#app-edit-category .cly-select .text").data("value")+"",timezone:$("#app-edit-timezone #app-timezone").val(),country:$("#app-edit-timezone #app-country").val()}),api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(e){for(var f in e)countlyGlobal.apps[c][f]=e[f],countlyGlobal.admin_apps[c][f]=e[f];if(!h)return $("#save-app-edit").removeClass("disabled"),a(c),d(),$(".app-container").filter(function(){return $(this).data("id")&& +$(this).data("id")==c}).find(".name").text(b),-1!==$("#sidebar-app-select .logo").attr("style").indexOf(c)&&$("#sidebar-app-select .text").text(b),!0;$("#add-edit-image-form").find("#app_image_id").val(c);$("#add-edit-image-form").ajaxSubmit({resetForm:!0,beforeSubmit:function(a){a.push({name:"_csrf",value:countlyGlobal.csrf_token})},success:function(e){$("#save-app-edit").removeClass("disabled");var h=$(".app-container").filter(function(){return $(this).data("id")&&$(this).data("id")==c});e?(h.find(".logo").css({"background-image":"url("+ +e+"?v"+(new Date).getTime()+")"}),$("#sidebar-app-select .logo").css("background-image",$("#sidebar-app-select .logo").css("background-image").replace(")","")+"?v"+(new Date).getTime()+")")):CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red");a(c);d();h.find(".name").text(b)}})}})});$("#cancel-app-edit").click(function(){d();var c=$("#app-edit-id").val();a(c)});$(".app-container:not(#app-container-new)").live("click",function(){var c=$(this).data("id");d();$(".app-container").removeClass("active"); +$(this).addClass("active");a(c)});$("#add-app-button").click(function(){c()});$("#cancel-app-add").click(function(){$("#app-container-new").remove();$("#add-new-app").hide();$("#view-app").show();$(".new-app-name").text(jQuery.i18n.map["management-applications.my-new-app"]);e()});$("#app-add-name").keyup(function(){var a=$(this).val();$("#app-container-new .name").text(a);$(".new-app-name").text(a)});$("#save-app-add").click(function(){if($(this).hasClass("disabled"))return!1;var c=$("#app-add-name").val(), +b=$("#app-add-category").data("value")+"",d=$("#app-add-timezone #app-timezone").val(),e=$("#app-add-timezone #app-country").val();$(".required").fadeOut().remove();var h=$("").addClass("required").text("*");c||$("#app-add-name").after(h.clone());b||$("#app-add-category").parents(".cly-select").after(h.clone());d||$("#app-add-timezone #app-timezone").after(h.clone());if($(".required").length)return $(".required").fadeIn(),!1;var f=$("#add-app-image-form").find("#app_image").val().split(".").pop().toLowerCase(); +if(f&&-1==$.inArray(f,["gif","png","jpg","jpeg"]))return CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red"),!1;$(this).addClass("disabled");$.ajax({type:"GET",url:countlyCommon.API_PARTS.apps.w+"/create",data:{args:JSON.stringify({name:c,category:b,timezone:d,country:e}),api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(c){var b=$("#sidebar-new-app>div").clone(),d={_id:c._id,name:c.name,key:c.key,category:c.category,timezone:c.timezone,country:c.country}; +countlyGlobal.apps[c._id]=d;countlyGlobal.admin_apps[c._id]=d;var e=$("#app-container-new");e.data("id",c._id);e.data("key",c.key);e.removeAttr("id");if(!f)return $("#save-app-add").removeClass("disabled"),b.find(".name").text(c.name),b.data("id",c._id),b.data("key",c.key),$("#app-nav .apps-scrollable").append(b),a(c._id),!0;$("#add-app-image-form").find("#app_image_id").val(c._id);$("#add-app-image-form").ajaxSubmit({resetForm:!0,beforeSubmit:function(a){a.push({name:"_csrf",value:countlyGlobal.csrf_token})}, +success:function(d){$("#save-app-add").removeClass("disabled");d?(e.find(".logo").css({"background-image":"url("+d+")"}),b.find(".logo").css({"background-image":"url("+d+")"})):CountlyHelpers.alert(jQuery.i18n.map["management-applications.icon-error"],"red");b.find(".name").text(c.name);b.data("id",c._id);b.data("key",c.key);$("#app-nav .apps-scrollable").append(b);a(c._id)}})}})})}}); +window.ManageUsersView=countlyView.extend({template:null,initialize:function(){var a=this;T.render("templates/users",function(b){a.template=b})},renderCommon:function(){var a=this;$.ajax({url:countlyCommon.API_PARTS.users.r+"/all",data:{api_key:countlyGlobal.member.api_key},dataType:"jsonp",success:function(b){$("#content").html(a.template({users:b,apps:countlyGlobal.apps}))}})}}); +window.EventsView=countlyView.extend({showOnGraph:2,beforeRender:function(){},initialize:function(){this.template=Handlebars.compile($("#template-events").html())},pageScript:function(){$(".event-container").unbind("click");$(".segmentation-option").unbind("click");$(".big-numbers").unbind("click");var a=this;$(".event-container").on("click",function(){var b=$(this).data("key");a.showOnGraph=2;$(".event-container").removeClass("active");$(this).addClass("active");countlyEvent.setActiveEvent(b,function(){a.refresh(!0)})}); +$(".segmentation-option").on("click",function(){var b=$(this).data("value");countlyEvent.setActiveSegmentation(b,function(){a.renderCommon(!0);newPage=$("
    "+a.template(a.templateData)+"
    ");$(a.el).find("#event-nav .scrollable").html(function(){return newPage.find("#event-nav .scrollable").html()});$(a.el).find(".widget-footer").html(newPage.find(".widget-footer").html());$(a.el).find("#edit-event-container").replaceWith(newPage.find("#edit-event-container"));var b=countlyEvent.getEventData(); +a.drawGraph(b);a.pageScript();a.drawTable(b);app.localize()})});$(".big-numbers").on("click",function(){if(2==$(".big-numbers.selected").length)a.showOnGraph=1-$(this).index();else if(1==$(".big-numbers.selected").length){if($(this).hasClass("selected"))return!0;a.showOnGraph=2}$(this).toggleClass("selected");a.drawGraph(countlyEvent.getEventData())});countlyGlobal.admin_apps[countlyCommon.ACTIVE_APP_ID]&&$("#edit-events-button").show()},drawGraph:function(a){2!=this.showOnGraph?($(".big-numbers").removeClass("selected"), +$(".big-numbers").eq(this.showOnGraph).addClass("selected"),2==a.dataLevel?a.chartDP.dp=a.chartDP.dp.slice(this.showOnGraph,this.showOnGraph+1):a.chartDP=a.chartDP.slice(this.showOnGraph,this.showOnGraph+1)):$(".big-numbers").addClass("selected");2==a.dataLevel?countlyCommon.drawGraph(a.chartDP,"#dashboard-graph","bar",{series:{stack:null}}):countlyCommon.drawTimeGraph(a.chartDP,"#dashboard-graph")},drawTable:function(a){this.dtable&&this.dtable.fnDestroy&&this.dtable.fnDestroy(!0);$("#event-main").append('
    '); +var b=[];countlyEvent.isSegmentedView()?b.push({mData:"curr_segment",sTitle:jQuery.i18n.map["events.table.segmentation"]}):b.push({mData:"date",sType:"customDate",sTitle:jQuery.i18n.map["common.date"]});b.push({mData:"c",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:a.tableColumns[1]});a.tableColumns[2]&&b.push({mData:"s",sType:"formatted-num",mRender:function(a){return countlyCommon.formatNumber(a)},sTitle:a.tableColumns[2]});this.dtable=$(".d-table").dataTable($.extend({}, +$.fn.dataTable.defaults,{aaData:a.chartData,aoColumns:b}));$(".d-table").stickyTableHeaders()},getColumnCount:function(){return $(".dataTable").find("thead th").length},renderCommon:function(a){var b=countlyEvent.getEventData(),d=countlyEvent.getEventSummary(),e=this;this.templateData={"page-title":b.eventName.toUpperCase(),"logo-class":"events",events:countlyEvent.getEvents(),"event-map":countlyEvent.getEventMap(),segmentations:countlyEvent.getEventSegmentations(),"active-segmentation":countlyEvent.getActiveSegmentation(), +"big-numbers":d,"chart-data":{columnCount:b.tableColumns.length,columns:b.tableColumns,rows:b.chartData}};if(0==countlyEvent.getEvents().length)return window.location="dashboard#/",CountlyHelpers.alert(jQuery.i18n.map["events.no-event"],"black"),!0;a||($(this.el).html(this.template(this.templateData)),this.drawGraph(b),this.drawTable(b),this.pageScript(),$("#edit-events-button").on("click",function(){CountlyHelpers.popup("#edit-event-container","events");$(".dialog #edit-event-table-container").slimScroll({height:"100%", +start:"top",wheelStep:10,position:"right",disableFadeOut:!0});$(".dialog .events-table").sortable({items:"tr",revert:!0,handle:"td:first-child",helper:function(a,b){b.children().each(function(){$(this).width($(this).width())});b.addClass("moving");return b},cursor:"move",containment:"parent",tolerance:"pointer",placeholder:"event-row-placeholder",stop:function(a,b){b.item.removeClass("moving")}});$(".dialog #events-save").on("click",function(){var a={},b=[];$(".dialog .events-table tbody tr").each(function(){var b= +$(this);eventKey=b.find(".event-key").text();b.find(".event-name").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].name=b.find(".event-name").val());b.find(".event-count").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].count=b.find(".event-count").val());b.find(".event-sum").val()&&(a[eventKey]||(a[eventKey]={}),a[eventKey].sum=b.find(".event-sum").val())});$(".dialog .events-table").find(".event-key").each(function(){$(this).text()&&b.push($(this).text())});$.ajax({type:"POST",url:countlyGlobal.path+ +"/events/map/edit",data:{app_id:countlyCommon.ACTIVE_APP_ID,event_map:a,event_order:b,_csrf:countlyGlobal.csrf_token},success:function(){e.refresh()}})});$(".delete-event").on("click",function(){var a=$(this).data("event-key");a&&CountlyHelpers.confirm(jQuery.i18n.prop("events.delete-confirm",a),"red",function(b){b&&$.ajax({type:"POST",url:countlyGlobal.path+"/events/delete",data:{event_key:a,app_id:countlyCommon.ACTIVE_APP_ID,_csrf:countlyGlobal.csrf_token},success:function(){countlyEvent.reset(); +$.when(countlyEvent.initialize(!0)).then(function(){e.render()})}})})})}))},refresh:function(a,b){var d=this;$.when(countlyEvent.initialize(a)).then(function(){if(app.activeView!=d)return!1;d.renderCommon(!0);newPage=$("
    "+d.template(d.templateData)+"
    ");$(d.el).find("#event-nav .scrollable").html(function(){return newPage.find("#event-nav .scrollable").html()});b||($("#event-update-area .cly-select").length&&!a?($(d.el).find("#event-update-area .select-items").html(function(){return newPage.find("#event-update-area .select-items").html()}), +$("#event-update-area .select-items>div").addClass("scroll-list"),$("#event-update-area .select-items").find(".scroll-list").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0}),$(".select-items .item").click(function(){var a=$(this).parents(".cly-select").find(".text");a.text($(this).text());a.data("value",$(this).data("value"))})):$(d.el).find("#event-update-area").replaceWith(newPage.find("#event-update-area")));$(d.el).find(".widget-footer").html(newPage.find(".widget-footer").html()); +$(d.el).find("#edit-event-container").replaceWith(newPage.find("#edit-event-container"));var e=countlyEvent.getEventData();d.drawGraph(e);d.pageScript();a||b?d.drawTable(e):d.getColumnCount()!=e.tableColumns.length?d.drawTable(e):CountlyHelpers.refreshTable(d.dtable,e.chartData);app.localize()})}}); +var AppRouter=Backbone.Router.extend({routes:{"/":"dashboard","/analytics/sessions":"sessions","/analytics/countries":"countries","/analytics/users":"users","/analytics/loyalty":"loyalty","/analytics/devices":"devices","/analytics/platforms":"platforms","/analytics/versions":"versions","/analytics/carriers":"carriers","/analytics/frequency":"frequency","/analytics/events":"events","/analytics/resolutions":"resolutions","/analytics/density":"density","/analytics/durations":"durations","/analytics/languages":"languages", +"/all":"allapps","/manage/apps":"manageApps","/manage/users":"manageUsers","*path":"main"},activeView:null,dateToSelected:null,dateFromSelected:null,activeAppName:"",activeAppKey:"",main:function(){this.navigate("/",!0)},dashboard:function(){this.renderWhenReady(this.dashboardView)},sessions:function(){this.renderWhenReady(this.sessionView)},countries:function(){this.renderWhenReady(this.countriesView)},languages:function(){this.renderWhenReady(this.languagesView)},devices:function(){this.renderWhenReady(this.deviceView)}, +platforms:function(){this.renderWhenReady(this.platformView)},versions:function(){this.renderWhenReady(this.appVersionView)},users:function(){this.renderWhenReady(this.userView)},allapps:function(){this.renderWhenReady(this.allAppsView)},loyalty:function(){this.renderWhenReady(this.loyaltyView)},frequency:function(){this.renderWhenReady(this.frequencyView)},carriers:function(){this.renderWhenReady(this.carrierView)},manageApps:function(){this.renderWhenReady(this.manageAppsView)},manageUsers:function(){this.renderWhenReady(this.manageUsersView)}, +events:function(){this.renderWhenReady(this.eventsView)},resolutions:function(){this.renderWhenReady(this.resolutionsView)},density:function(){this.renderWhenReady(this.densityView)},durations:function(){this.renderWhenReady(this.durationsView)},refreshActiveView:function(){},renderWhenReady:function(a){this.activeView&&this.activeView.destroy();this.activeView=a;clearInterval(this.refreshActiveView);if(_.isEmpty(countlyGlobal.apps))return"/manage/apps"!=Backbone.history.fragment?this.navigate("/manage/apps", +!0):a.render(),!1;a.render();var b=this;this.refreshActiveView=setInterval(function(){b.activeView.refresh();if(b.refreshScripts[Backbone.history.fragment])for(var a=0,e=b.refreshScripts[Backbone.history.fragment].length;a<]/g,"")}this.pageScripts={};this.refreshScripts={};this.dashboardView=new DashboardView;this.sessionView=new SessionView;this.countriesView=new CountriesView;this.languagesView=new LanguageView;this.userView=new UserView;this.allAppsView=new AllAppsView;this.loyaltyView=new LoyaltyView;this.deviceView= +new DeviceView;this.platformView=new PlatformView;this.appVersionView=new AppVersionView;this.frequencyView=new FrequencyView;this.carrierView=new CarrierView;this.manageAppsView=new ManageAppsView;this.manageUsersView=new ManageUsersView;this.eventsView=new EventsView;this.resolutionsView=new ResolutionView;this.densityView=new DensityView;this.durationsView=new DurationView;Handlebars.registerPartial("date-selector",$("#template-date-selector").html());Handlebars.registerPartial("timezones",$("#template-timezones").html()); +Handlebars.registerPartial("app-categories",$("#template-app-categories").html());Handlebars.registerHelper("eachOfObject",function(a,b){var d="",e;for(e in a)d+=b.fn({property:e,value:a[e]});return d});Handlebars.registerHelper("eachOfObjectValue",function(a,b){var d="",e;for(e in a)d+=b.fn(a[e]);return d});Handlebars.registerHelper("eachOfArray",function(a,b){for(var d="",e=0;e .item").removeClass("hide");$("#allapps-menu").css("display","none");"#/all"==window.location.hash.toString()&&(window.location.hash="/");if(d.activeAppKey==a)return h.removeClass("active"),$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),!1;d.activeAppName=b;d.activeAppKey=a;$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack",complete:function(){countlyCommon.setActiveApp(c); +h.find(".text").text(b);h.find(".logo").css("background-image",e);h.removeClass("active");d.activeView.appChanged()}})});$("#sidebar-events").click(function(a){$.when(countlyEvent.refreshEvents()).then(function(){0==countlyEvent.getEvents().length&&(CountlyHelpers.alert(jQuery.i18n.map["events.no-event"],"black"),a.stopImmediatePropagation(),a.preventDefault())})});$("#sidebar-menu").on("click",".item",function(){var a=$(this).next(),c=$(this).hasClass("active");c&&$(".sidebar-submenu").not(a).slideUp(); +a.hasClass("sidebar-submenu")&&!c?a.slideToggle():($("#sidebar-menu>.item").removeClass("active"),$(this).addClass("active"),201==$("#app-nav").offset().left&&($("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),$("#sidebar-app-select").removeClass("active")))});$(".sidebar-submenu").on("click",".item",function(){if($(this).hasClass("disabled"))return!0;201==$("#app-nav").offset().left&&($("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}),$("#sidebar-app-select").removeClass("active")); +$(".sidebar-submenu .item").removeClass("active");$(this).addClass("active");$(this).parent().prev(".item").addClass("active")});$("#sidebar-app-select").click(function(){if($(this).hasClass("disabled"))return!0;$(this).hasClass("active")?$(this).removeClass("active"):$(this).addClass("active");$("#app-nav").show();201==$("#app-nav").offset().left?$("#app-nav").animate({left:"31px"},{duration:500,easing:"easeInBack"}):$("#app-nav").animate({left:"201px"},{duration:500,easing:"easeOutBack"})});$("#sidebar-bottom-container .reveal-menu").click(function(){$("#language-menu").hide(); +$("#sidebar-bottom-container .menu").toggle()});$("#sidebar-bottom-container .reveal-language-menu").click(function(){$("#sidebar-bottom-container .menu").hide();$("#language-menu").toggle()});$("#sidebar-bottom-container .item").click(function(){$("#sidebar-bottom-container .menu").hide();$("#language-menu").hide()});$("#language-menu .item").click(function(){var a=$(this).data("language-code"),c=a.toUpperCase();store.set("countly_lang",a);$(".reveal-language-menu").text(c);countlyCommon.BROWSER_LANG_SHORT= +a;countlyCommon.BROWSER_LANG=a;try{moment.lang(countlyCommon.BROWSER_LANG_SHORT)}catch(b){moment.lang("en")}$("#date-to").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$("#date-from").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);jQuery.i18n.properties({name:"help",cache:!0,language:countlyCommon.BROWSER_LANG_SHORT,path:[countlyGlobal.cdn+"localization/help/"],mode:"map",callback:function(){countlyCommon.HELP_MAP=jQuery.i18n.map;jQuery.i18n.map={}; +var a=["dashboard"],c=[countlyGlobal.cdn+"localization/dashboard/"];if(countlyGlobal.plugins)for(var b=0,e=countlyGlobal.plugins.length;b
    If you find any bugs or have suggestions please let us know!

    Captain Obvious: You can use the message box that appears when you click the question mark on the bottom right corner of this page.", +"black")});$("#content").on("click","#graph-note",function(){function a(){var c=$(".note-date:visible").val(),b=$(".note-date:visible").data("datepicker"),c=$.datepicker.parseDate(b.settings.dateFormat||$.datepicker._defaults.dateFormat,c,b.settings);$(".selected-date:visible").text(moment(c).format("D MMM YYYY")+", "+$(".time-picker:visible span.selected").text())}function c(a,b){var d=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes;"create"==b?d?d[a.date_id]?countlyCommon.arrayAddUniq(d[a.date_id], +a.note):d[a.date_id]=[a.note]:(d={},d[a.date_id]=[a.note],countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes=d):"delete"==b&&d&&d[a.date_id]&&(d[a.date_id]=_.without(d[a.date_id],a.note))}CountlyHelpers.popup("#graph-note-popup");$(".note-date:visible").datepicker({numberOfMonths:1,showOtherMonths:!0,onSelect:function(){a()}});$.datepicker.setDefaults($.datepicker.regional[""]);$(".note-date:visible").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$(".note-popup:visible .time-picker, .note-popup:visible .note-list").slimScroll({height:"100%", +start:"top",wheelStep:10,position:"right",disableFadeOut:!0});$(".note-popup:visible .time-picker span").on("click",function(){$(".note-popup:visible .time-picker span").removeClass("selected");$(this).addClass("selected");a()});$(".note-popup:visible .manage-notes-button").on("click",function(){$(".note-popup:visible .note-create").hide();$(".note-popup:visible .note-manage").show();$(".note-popup:visible .create-note-button").show();$(this).hide();$(".note-popup:visible .create-note").hide()}); +$(".note-popup:visible .create-note-button").on("click",function(){$(".note-popup:visible .note-create").show();$(".note-popup:visible .note-manage").hide();$(".note-popup:visible .manage-notes-button").show();$(this).hide();$(".note-popup:visible .create-note").show()});a();if(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID]&&countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes)for(var b=_.sortBy(_.keys(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes),function(a){return-parseInt(a)}),d=0;d< +b.length;d++)for(var e=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].notes[b[d]],h=0;h
    '+moment(b[d],"YYYYMMDDHH").format("D MMM YYYY, HH:mm")+'
    '+e[h]+'
    ');$(".note-popup:visible .note").length||$(".note-popup:visible .manage-notes-button").hide();$(".note-popup:visible .note-content").textcounter({max:50, +countDown:!0,countDownText:"remaining "});$(".note-popup:visible .note .delete-note").on("click",function(){var a=$(this).siblings(".date").data("dateid"),b=$(this).siblings(".content").text();$(this).parents(".note").fadeOut().remove();$.ajax({type:"POST",url:countlyGlobal.path+"/graphnotes/delete",data:{app_id:countlyCommon.ACTIVE_APP_ID,date_id:a,note:b,_csrf:countlyGlobal.csrf_token},success:function(d){if(!1==d)return!1;c({date_id:a,note:b},"delete");app.activeView.refresh()}});$(".note-popup:visible .note").length|| +($(".note-popup:visible .create-note-button").trigger("click"),$(".note-popup:visible .manage-notes-button").hide())});$(".note-popup:visible .create-note").on("click",function(){if($(this).hasClass("disabled"))return!0;$(this).addClass("disabled");var a=$(".note-date:visible").val(),b=$(".note-date:visible").data("datepicker"),a=$.datepicker.parseDate(b.settings.dateFormat||$.datepicker._defaults.dateFormat,a,b.settings),d=moment(moment(a).format("D MMM YYYY")+", "+$(".time-picker:visible span.selected").text(), +"D MMM YYYY, HH:mm").format("YYYYMMDDHH"),a=$(".note-popup:visible .note-content").val();if(a.length)$(".note-popup:visible .note-content").removeClass("required-border");else return $(".note-popup:visible .note-content").addClass("required-border"),$(this).removeClass("disabled"),!0;$.ajax({type:"POST",url:countlyGlobal.path+"/graphnotes/create",data:{app_id:countlyCommon.ACTIVE_APP_ID,date_id:d,note:a,_csrf:countlyGlobal.csrf_token},success:function(a){if(!1==a)return!1;c({date_id:d,note:a},"create"); +app.activeView.refresh()}});$("#overlay").trigger("click")})})});if(_.isEmpty(countlyGlobal.apps))$("#new-install-overlay").show();else if(countlyCommon.ACTIVE_APP_ID)$("#sidebar-app-select").find(".logo").css("background-image","url('"+countlyGlobal.cdn+"appimages/"+countlyCommon.ACTIVE_APP_ID+".png')"),$("#sidebar-app-select .text").text(countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].name),d.activeAppName=countlyGlobal.apps[countlyCommon.ACTIVE_APP_ID].name;else for(var e in countlyGlobal.apps){countlyCommon.setActiveApp(e); +d.activeAppName=countlyGlobal.apps[e].name;break}$.idleTimer(countlyCommon.DASHBOARD_IDLE_MS);$(document).bind("idle.idleTimer",function(){clearInterval(d.refreshActiveView)});$(document).bind("active.idleTimer",function(){d.activeView.restart();d.refreshActiveView=setInterval(function(){d.activeView.refresh()},countlyCommon.DASHBOARD_REFRESH_MS)});$.fn.dataTableExt.oPagination.four_button={fnInit:function(a,b,d){nFirst=document.createElement("span");nPrevious=document.createElement("span");nNext= +document.createElement("span");nLast=document.createElement("span");nFirst.innerHTML="";nPrevious.innerHTML="";nNext.innerHTML="";nLast.innerHTML="";nFirst.className="paginate_button first";nPrevious.className="paginate_button previous";nNext.className="paginate_button next";nLast.className="paginate_button last";b.appendChild(nFirst);b.appendChild(nPrevious); +b.appendChild(nNext);b.appendChild(nLast);$(nFirst).click(function(){a.oApi._fnPageChange(a,"first");d(a)});$(nPrevious).click(function(){a.oApi._fnPageChange(a,"previous");d(a)});$(nNext).click(function(){a.oApi._fnPageChange(a,"next");d(a)});$(nLast).click(function(){a.oApi._fnPageChange(a,"last");d(a)});$(nFirst).bind("selectstart",function(){return!1});$(nPrevious).bind("selectstart",function(){return!1});$(nNext).bind("selectstart",function(){return!1});$(nLast).bind("selectstart",function(){return!1})}, +fnUpdate:function(a){if(a.aanFeatures.p)for(var b=a.aanFeatures.p,d=0,e=b.length;db?1:0};jQuery.fn.dataTableExt.oSort["customDate-desc"]=function(c,b){c=a(c);b=a(b);return cb?-1:0};jQuery.fn.dataTableExt.oSort["dateRange-asc"]=function(a,d){a=b(a);d=b(d);return ad?1:0};jQuery.fn.dataTableExt.oSort["dateRange-desc"]=function(a,d){a=b(a);d=b(d);return ad?-1:0};jQuery.fn.dataTableExt.oSort["percent-asc"]=function(a,b){a=parseFloat($("").html(a).text().replace("%",""));b=parseFloat($("").html(b).text().replace("%",""));return ab?1:0};jQuery.fn.dataTableExt.oSort["percent-desc"]=function(a,b){a=parseFloat($("").html(a).text().replace("%",""));b=parseFloat($("").html(b).text().replace("%",""));return ab?-1: +0};jQuery.fn.dataTableExt.oSort["formatted-num-asc"]=function(a,b){var d=[],d=[],a=a.replace(/[^\d\-\.\/]/g,""),b=b.replace(/[^\d\-\.\/]/g,"");0<=a.indexOf("/")&&(d=a.split("/"),a=parseInt(d[0],10)/parseInt(d[1],10));0<=b.indexOf("/")&&(d=b.split("/"),b=parseInt(d[0],10)/parseInt(d[1],10));return a-b};jQuery.fn.dataTableExt.oSort["formatted-num-desc"]=function(a,b){var d=[],d=[],a=a.replace(/[^\d\-\.\/]/g,""),b=b.replace(/[^\d\-\.\/]/g,"");0<=a.indexOf("/")&&(d=a.split("/"),a=parseInt(d[0],10)/parseInt(d[1], +10));0<=b.indexOf("/")&&(d=b.split("/"),b=parseInt(d[0],10)/parseInt(d[1],10));return b-a};jQuery.fn.dataTableExt.oSort["loyalty-asc"]=function(a,b){a=countlyUser.getLoyaltyIndex(a);b=countlyUser.getLoyaltyIndex(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["loyalty-desc"]=function(a,b){a=countlyUser.getLoyaltyIndex(a);b=countlyUser.getLoyaltyIndex(b);return ab?-1:0};jQuery.fn.dataTableExt.oSort["frequency-asc"]=function(a,b){a=countlyUser.getFrequencyIndex(a);b=countlyUser.getFrequencyIndex(b); +return ab?1:0};jQuery.fn.dataTableExt.oSort["frequency-desc"]=function(a,b){a=countlyUser.getFrequencyIndex(a);b=countlyUser.getFrequencyIndex(b);return ab?-1:0};jQuery.fn.dataTableExt.oSort["session-duration-asc"]=function(a,b){a=countlySession.getDurationIndex(a);b=countlySession.getDurationIndex(b);return ab?1:0};jQuery.fn.dataTableExt.oSort["session-duration-desc"]=function(a,b){a=countlySession.getDurationIndex(a);b=countlySession.getDurationIndex(b);return ab?-1: +0};$.extend($.fn.dataTable.defaults,{sDom:'<"dataTable-top"fpT>t<"dataTable-bottom"i>',bAutoWidth:!1,sPaginationType:"four_button",iDisplayLength:50,bDestroy:!0,bDeferRender:!0,oTableTools:{sSwfPath:countlyGlobal.cdn+"javascripts/dom/dataTables/swf/copy_csv_xls.swf",aButtons:[{sExtends:"csv",sButtonText:"Save to CSV",fnClick:function(a,b,d){for(var a=$(a).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns,b=this.fnGetTableData(b).split(/\r\n|\r|\n/g).join('","').split('","'), +e="",g=0;g=a.length){var j=g%a.length;"formatted-num"==a[j].sType?b[g]=b[g].replace(/,/g,""):"percent"==a[j].sType&&(b[g]=b[g].replace("%",""))}e=0==(g+1)%a.length?e+('"'+b[g]+'"\r\n'):e+('"'+b[g]+'", ')}this.fnSetText(d,e)}},{sExtends:"xls",sButtonText:"Save for Excel",fnClick:function(a,b,d){for(var a=$(a).parents(".dataTables_wrapper").find(".dataTable").dataTable().fnSettings().aoColumns,b=this.fnGetTableData(b).split(/\r\n|\r|\n/g).join("\t").split("\t"), +e="",g=0;g=a.length){var j=g%a.length;"formatted-num"==a[j].sType?b[g]=parseFloat(b[g].replace(/,/g,"")).toLocaleString():"percent"==a[j].sType?b[g]=parseFloat(b[g].replace("%","")).toLocaleString():"numeric"==a[j].sType&&(b[g]=parseFloat(b[g]).toLocaleString())}e=0==(g+1)%a.length?e+(b[g]+"\r\n"):e+(b[g]+"\t")}this.fnSetText(d,e)}}]},fnInitComplete:function(a){a=$("#"+a.sTableId+"_wrapper");$("
    ").insertBefore(a.find(".DTTT_container")); +$("
    ").insertBefore(a.find(".dataTables_filter"));a.find(".dataTables_filter").html(a.find(".dataTables_filter").find("input").attr("Placeholder","Search").clone(!0));a.find(".save-table-data").on("click",function(){"hidden"==$(this).next(".DTTT_container").css("visibility")?$(this).next(".DTTT_container").css("visibility","visible"):$(this).next(".DTTT_container").css("visibility","hidden")});a.find(".search-table-data").on("click",function(){$(this).next(".dataTables_filter").toggle(); +$(this).next(".dataTables_filter").find("input").focus()});a.css({"min-height":a.height()})}});$.fn.dataTableExt.sErrMode="throw"},localize:function(){var a={onlyFirstUpper:function(a){return a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()},upper:function(a){return a.toUpperCase()}};$("[data-help-localize]").each(function(){var a=$(this);void 0!=a.data("help-localize")&&a.data("help",countlyCommon.HELP_MAP[a.data("help-localize")])});$("[data-localize]").each(function(){var b=$(this),d=b.data("localize").split("!"), +e="",e=2==d.length?a[d[0]]?a[d[0]](jQuery.i18n.map[d[1]]):jQuery.i18n.prop(d[0],jQuery.i18n.map[d[1]]):jQuery.i18n.map[b.data("localize")];b.is("input[type=text]")||b.is("input[type=password]")||b.is("textarea")?b.attr("placeholder",e):b.is("input[type=button]")||b.is("input[type=submit]")?b.attr("value",e):b.text(e)})},addPageScript:function(a,b){this.pageScripts[a]||(this.pageScripts[a]=[]);this.pageScripts[a].push(b)},addRefreshScript:function(a,b){this.refreshScripts[a]||(this.refreshScripts[a]= +[]);this.refreshScripts[a].push(b)},pageScript:function(){$("#month").text(moment().year());$("#day").text(moment().format("MMM"));$("#yesterday").text(moment().subtract("days",1).format("Do"));var a=this;$(document).ready(function(){a.localize();$("#help-toggle").hasClass("active")&&($(".help-zone-vb").tipsy({gravity:$.fn.tipsy.autoNS,trigger:"manual",title:function(){return $(this).data("help")?$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow",opacity:1,html:!0}),$(".help-zone-vs").tipsy({gravity:$.fn.tipsy.autoNS, +trigger:"manual",title:function(){return $(this).data("help")?$(this).data("help"):""},fade:!0,offset:5,cssClass:"yellow narrow",opacity:1,html:!0}),$.idleTimer("destroy"),clearInterval(a.refreshActiveView),$(".help-zone-vs, .help-zone-vb").hover(function(){$(this).tipsy("show")},function(){$(this).tipsy("hide")}));$("#sidebar-menu").find("a").removeClass("active");var b=$("#sidebar-menu").find("a[href='#"+Backbone.history.fragment+"']");b.addClass("active");var d=b.parent(".sidebar-submenu");d.prev(".item").addClass("active"); +b.not(":visible")&&d.slideDown();$(".sidebar-submenu").not(d).slideUp();b=countlyCommon.getPeriod();"[object Array]"!==Object.prototype.toString.call(b)&&$("#"+b).addClass("active");$(".usparkline").peity("bar",{width:"100%",height:"30",colour:"#6BB96E",strokeColour:"#6BB96E",strokeWidth:2});$(".dsparkline").peity("bar",{width:"100%",height:"30",colour:"#C94C4C",strokeColour:"#C94C4C",strokeWidth:2});CountlyHelpers.setUpDateSelectors(a.activeView);$(window).click(function(){$("#date-picker").hide(); +$(".cly-select").removeClass("active")});$("#date-picker").click(function(a){a.stopPropagation()});$("#date-picker-button").click(function(b){$("#date-picker").toggle();a.dateToSelected?e.datepicker("setDate",moment(a.dateToSelected).toDate()):(a.dateToSelected=moment().toDate().getTime(),e.datepicker("setDate",moment().toDate()));c.datepicker("option","maxDate",moment(a.dateToSelected).toDate());a.dateFromSelected?c.datepicker("setDate",moment(a.dateFromSelected).toDate()):(extendDate=moment(e.datepicker("getDate")).subtract("days", +30).toDate(),c.datepicker("setDate",extendDate),a.dateFromSelected=moment(e.datepicker("getDate")).subtract("days",30).toDate().getTime());e.datepicker("option","minDate",moment(a.dateFromSelected).toDate());b.stopPropagation()});var e=$("#date-to").datepicker({numberOfMonths:1,showOtherMonths:!0,maxDate:moment().toDate(),onSelect:function(b){var d=$(this).data("datepicker"),b=$.datepicker.parseDate(d.settings.dateFormat||$.datepicker._defaults.dateFormat,b,d.settings),d=new Date(b.getTime());d.getTime()< +a.dateFromSelected&&(a.dateFromSelected=d.getTime());c.datepicker("option","maxDate",d);a.dateToSelected=b.getTime()}}),c=$("#date-from").datepicker({numberOfMonths:1,showOtherMonths:!0,maxDate:moment().subtract("days",1).toDate(),onSelect:function(b){var c=$(this).data("datepicker"),b=$.datepicker.parseDate(c.settings.dateFormat||$.datepicker._defaults.dateFormat,b,c.settings),c=new Date(b.getTime());c.getTime()>a.dateToSelected&&(a.dateToSelected=c.getTime());e.datepicker("option","minDate",c); +a.dateFromSelected=b.getTime()}});$.datepicker.setDefaults($.datepicker.regional[""]);$("#date-to").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$("#date-from").datepicker("option",$.datepicker.regional[countlyCommon.BROWSER_LANG]);$("#date-submit").click(function(){if(!a.dateFromSelected&&!a.dateToSelected)return!1;countlyCommon.setPeriod([a.dateFromSelected,a.dateToSelected]);a.activeView.dateChanged();$(".date-selector").removeClass("selected").removeClass("active")}); +$(".scrollable").slimScroll({height:"100%",start:"top",wheelStep:10,position:"right",disableFadeOut:!0});$(".widget-header").noisy({intensity:0.9,size:50,opacity:0.04,monochrome:!0});$(".checkbox").on("click",function(){$(this).toggleClass("checked")});$(".resource-link").on("click",function(){$(this).data("link")&&CountlyHelpers.openResource($(this).data("link"))});"/manage/apps"==Backbone.history.fragment||"/manage/account"==Backbone.history.fragment||"/manage/users"==Backbone.history.fragment? +($("#sidebar-app-select").addClass("disabled"),$("#sidebar-app-select").removeClass("active")):$("#sidebar-app-select").removeClass("disabled");if(a.pageScripts[Backbone.history.fragment]){b=0;for(d=a.pageScripts[Backbone.history.fragment].length;ba.length)return Math.max.apply(Math,a);if(!e&&h.isEmpty(a))return-Infinity;var f={computed:-Infinity};return u(a,function(a,h,d){h=e?e.call(b,a,h,d):a;h>=f.computed&&(f={value:a,computed:h})}),f.value};h.min=function(a,e,b){if(!e&&h.isArray(a)&&a[0]===+a[0]&&65535>a.length)return Math.min.apply(Math,a);if(!e&&h.isEmpty(a))return Infinity;var f={computed:Infinity}; -return u(a,function(a,h,d){h=e?e.call(b,a,h,d):a;hh||void 0===b)return 1;if(b>>1;b.call(f,a[g])b?Math.max(0, -d+b):b}if(n&&a.indexOf===n)return a.indexOf(e,b);for(;f=arguments.length&&(e=a||0,a=0);for(var b=arguments[2]||1,h=Math.max(Math.ceil((e-a)/b),0),f=0,d=Array(h);f=a?e():function(){if(1>--a)return e.apply(this,arguments)}}; -h.keys=q||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var e=[],b;for(b in a)h.has(a,b)&&(e[e.length]=b);return e};h.values=function(a){var e=[],b;for(b in a)h.has(a,b)&&e.push(a[b]);return e};h.pairs=function(a){var e=[],b;for(b in a)h.has(a,b)&&e.push([b,a[b]]);return e};h.invert=function(a){var e={},b;for(b in a)h.has(a,b)&&(e[a[b]]=b);return e};h.functions=h.methods=function(a){var e=[],b;for(b in a)h.isFunction(a[b])&&e.push(b);return e.sort()};h.extend=function(a){return u(b.call(arguments, -1),function(e){for(var b in e)a[b]=e[b]}),a};h.pick=function(a){var e={},h=d.apply(j,b.call(arguments,1));return u(h,function(b){b in a&&(e[b]=a[b])}),e};h.omit=function(a){var e={},f=d.apply(j,b.call(arguments,1)),c;for(c in a)h.contains(f,c)||(e[c]=a[c]);return e};h.defaults=function(a){return u(b.call(arguments,1),function(e){for(var b in e)null==a[b]&&(a[b]=e[b])}),a};h.clone=function(a){return h.isObject(a)?h.isArray(a)?a.slice():h.extend({},a):a};h.tap=function(a,e){return e(a),a};var F=function(a, -e,b,f){if(a===e)return 0!==a||1/a==1/e;if(null==a||null==e)return a===e;a instanceof h&&(a=a._wrapped);e instanceof h&&(e=e._wrapped);var d=s.call(a);if(d!=s.call(e))return!1;switch(d){case "[object String]":return a==String(e);case "[object Number]":return a!=+a?e!=+e:0==a?1/a==1/e:a==+e;case "[object Date]":case "[object Boolean]":return+a==+e;case "[object RegExp]":return a.source==e.source&&a.global==e.global&&a.multiline==e.multiline&&a.ignoreCase==e.ignoreCase}if("object"!=typeof a||"object"!= -typeof e)return!1;for(var c=b.length;c--;)if(b[c]==a)return f[c]==e;b.push(a);f.push(e);var c=0,g=!0;if("[object Array]"==d){if(c=a.length,g=c==e.length)for(;c--&&(g=F(a[c],e[c],b,f)););}else{var d=a.constructor,m=e.constructor;if(d!==m&&(!h.isFunction(d)||!(d instanceof d&&h.isFunction(m)&&m instanceof m)))return!1;for(var q in a)if(h.has(a,q)&&(c++,!(g=h.has(e,q)&&F(a[q],e[q],b,f))))break;if(g){for(q in e)if(h.has(e,q)&&!c--)break;g=!c}}return b.pop(),f.pop(),g};h.isEqual=function(a,e){return F(a, -e,[],[])};h.isEmpty=function(a){if(null==a)return!0;if(h.isArray(a)||h.isString(a))return 0===a.length;for(var e in a)if(h.has(a,e))return!1;return!0};h.isElement=function(a){return!!a&&1===a.nodeType};h.isArray=l||function(a){return"[object Array]"==s.call(a)};h.isObject=function(a){return a===Object(a)};u("Arguments Function String Number Date RegExp".split(" "),function(a){h["is"+a]=function(e){return s.call(e)=="[object "+a+"]"}});h.isArguments(arguments)||(h.isArguments=function(a){return!!a&& -!!h.has(a,"callee")});"function"!=typeof/./&&(h.isFunction=function(a){return"function"==typeof a});h.isFinite=function(a){return h.isNumber(a)&&isFinite(a)};h.isNaN=function(a){return h.isNumber(a)&&a!=+a};h.isBoolean=function(a){return!0===a||!1===a||"[object Boolean]"==s.call(a)};h.isNull=function(a){return null===a};h.isUndefined=function(a){return void 0===a};h.has=function(a,e){return f.call(a,e)};h.noConflict=function(){return a._=g,this};h.identity=function(a){return a};h.times=function(a, -e,b){for(var h=0;h":">",'"':""","'":"'","/":"/"}};D.unescape=h.invert(D.escape);var H={escape:RegExp("["+h.keys(D.escape).join("")+"]","g"),unescape:RegExp("("+h.keys(D.unescape).join("|")+")","g")};h.each(["escape","unescape"],function(a){h[a]=function(e){return null==e?"":(""+e).replace(H[a],function(e){return D[a][e]})}});h.result=function(a, -e){if(null==a)return null;var b=a[e];return h.isFunction(b)?b.call(a):b};h.mixin=function(a){u(h.functions(a),function(e){var b=h[e]=a[e];h.prototype[e]=function(){var a=[this._wrapped];k.apply(a,arguments);a=b.apply(h,a);return this._chain?h(a).chain():a}})};var I=0;h.uniqueId=function(a){var e=I++;return a?a+e:e};h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var B=/(.)^/,N={"'":"'","\\":"\\","\r":"r","\n":"n","\t":"t","\u2028":"u2028","\u2029":"u2029"}, -O=/\\|'|\r|\n|\t|\u2028|\u2029/g;h.template=function(a,e,b){var b=h.defaults({},b,h.templateSettings),f=RegExp([(b.escape||B).source,(b.interpolate||B).source,(b.evaluate||B).source].join("|")+"|$","g"),d=0,c="__p+='";a.replace(f,function(e,b,h,f,g){c+=a.slice(d,g).replace(O,function(a){return"\\"+N[a]});c+=b?"'+\n((__t=("+b+"))==null?'':_.escape(__t))+\n'":h?"'+\n((__t=("+h+"))==null?'':__t)+\n'":f?"';\n"+f+"\n__p+='":"";d=g+e.length});c+="';\n";b.variable||(c="with(obj||{}){\n"+c+"}\n");c="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+ -c+"return __p;\n";try{var g=new Function(b.variable||"obj","_",c)}catch(m){throw m.source=c,m;}if(e)return g(e,h);e=function(a){return g.call(this,a,h)};return e.source="function("+(b.variable||"obj")+"){\n"+c+"}",e};h.chain=function(a){return h(a).chain()};h.mixin(h);u("pop push reverse shift sort splice unshift".split(" "),function(a){var e=j[a];h.prototype[a]=function(){var b=this._wrapped;return e.apply(b,arguments),("shift"==a||"splice"==a)&&0===b.length&&delete b[0],this._chain?h(b).chain(): -b}});u(["concat","join","slice"],function(a){var e=j[a];h.prototype[a]=function(){var a=e.apply(this._wrapped,arguments);return this._chain?h(a).chain():a}});h.extend(h.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);(function(){function a(a,g){return[].slice.call((g||document).querySelectorAll(a))}if(window.addEventListener){var g=window.StyleFix={link:function(a){try{if("stylesheet"!==a.rel||a.hasAttribute("data-noprefix"))return}catch(j){return}var l=a.href||a.getAttribute("data-href"),k=l.replace(/[^\/]+$/,""),b=a.parentNode,d=new XMLHttpRequest,s;d.onreadystatechange=function(){4===d.readyState&&s()};s=function(){var f=d.responseText;if(f&&a.parentNode&&(!d.status||400>d.status||600c.length)return Math.max.apply(Math,c);if(!a&&h.isEmpty(c))return-Infinity;var g={computed:-Infinity};return A(c,function(c,h,j){h=a?a.call(e,c,h,j):c;h>=g.computed&&(g={value:c,computed:h})}),g.value};h.min=function(c,a,e){if(!a&&h.isArray(c)&&c[0]===+c[0]&&65535>c.length)return Math.min.apply(Math,c);if(!a&&h.isEmpty(c))return Infinity;var g={computed:Infinity}; +return A(c,function(c,h,j){h=a?a.call(e,c,h,j):c;hh||void 0===e)return 1;if(e>>1;e.call(g,c[p])e?Math.max(0, +j+e):e}if(n&&c.indexOf===n)return c.indexOf(a,e);for(;g=arguments.length&&(a=c||0,c=0);for(var e=arguments[2]||1,h=Math.max(Math.ceil((a-c)/e),0),g=0,j=Array(h);g=c?a():function(){if(1>--c)return a.apply(this,arguments)}}; +h.keys=e||function(c){if(c!==Object(c))throw new TypeError("Invalid object");var a=[],e;for(e in c)h.has(c,e)&&(a[a.length]=e);return a};h.values=function(c){var a=[],e;for(e in c)h.has(c,e)&&a.push(c[e]);return a};h.pairs=function(c){var a=[],e;for(e in c)h.has(c,e)&&a.push([e,c[e]]);return a};h.invert=function(c){var a={},e;for(e in c)h.has(c,e)&&(a[c[e]]=e);return a};h.functions=h.methods=function(c){var a=[],e;for(e in c)h.isFunction(c[e])&&a.push(e);return a.sort()};h.extend=function(c){return A(g.call(arguments, +1),function(a){for(var e in a)c[e]=a[e]}),c};h.pick=function(c){var a={},e=f.apply(b,g.call(arguments,1));return A(e,function(e){e in c&&(a[e]=c[e])}),a};h.omit=function(c){var a={},e=f.apply(b,g.call(arguments,1)),j;for(j in c)h.contains(e,j)||(a[j]=c[j]);return a};h.defaults=function(c){return A(g.call(arguments,1),function(a){for(var e in a)null==c[e]&&(c[e]=a[e])}),c};h.clone=function(c){return h.isObject(c)?h.isArray(c)?c.slice():h.extend({},c):c};h.tap=function(c,a){return a(c),c};var H=function(c, +a,e,g){if(c===a)return 0!==c||1/c==1/a;if(null==c||null==a)return c===a;c instanceof h&&(c=c._wrapped);a instanceof h&&(a=a._wrapped);var j=q.call(c);if(j!=q.call(a))return!1;switch(j){case "[object String]":return c==String(a);case "[object Number]":return c!=+c?a!=+a:0==c?1/c==1/a:c==+a;case "[object Date]":case "[object Boolean]":return+c==+a;case "[object RegExp]":return c.source==a.source&&c.global==a.global&&c.multiline==a.multiline&&c.ignoreCase==a.ignoreCase}if("object"!=typeof c||"object"!= +typeof a)return!1;for(var f=e.length;f--;)if(e[f]==c)return g[f]==a;e.push(c);g.push(a);var f=0,p=!0;if("[object Array]"==j){if(f=c.length,p=f==a.length)for(;f--&&(p=H(c[f],a[f],e,g)););}else{var j=c.constructor,r=a.constructor;if(j!==r&&(!h.isFunction(j)||!(j instanceof j&&h.isFunction(r)&&r instanceof r)))return!1;for(var b in c)if(h.has(c,b)&&(f++,!(p=h.has(a,b)&&H(c[b],a[b],e,g))))break;if(p){for(b in a)if(h.has(a,b)&&!f--)break;p=!f}}return e.pop(),g.pop(),p};h.isEqual=function(c,a){return H(c, +a,[],[])};h.isEmpty=function(c){if(null==c)return!0;if(h.isArray(c)||h.isString(c))return 0===c.length;for(var a in c)if(h.has(c,a))return!1;return!0};h.isElement=function(c){return!!c&&1===c.nodeType};h.isArray=m||function(c){return"[object Array]"==q.call(c)};h.isObject=function(c){return c===Object(c)};A("Arguments Function String Number Date RegExp".split(" "),function(c){h["is"+c]=function(a){return q.call(a)=="[object "+c+"]"}});h.isArguments(arguments)||(h.isArguments=function(c){return!!c&& +!!h.has(c,"callee")});"function"!=typeof/./&&(h.isFunction=function(c){return"function"==typeof c});h.isFinite=function(c){return h.isNumber(c)&&isFinite(c)};h.isNaN=function(c){return h.isNumber(c)&&c!=+c};h.isBoolean=function(c){return!0===c||!1===c||"[object Boolean]"==q.call(c)};h.isNull=function(c){return null===c};h.isUndefined=function(c){return void 0===c};h.has=function(c,a){return s.call(c,a)};h.noConflict=function(){return a._=d,this};h.identity=function(c){return c};h.times=function(c, +a,e){for(var h=0;h":">",'"':""","'":"'","/":"/"}};F.unescape=h.invert(F.escape);var I={escape:RegExp("["+h.keys(F.escape).join("")+"]","g"),unescape:RegExp("("+h.keys(F.unescape).join("|")+")","g")};h.each(["escape","unescape"],function(c){h[c]=function(a){return null==a?"":(""+a).replace(I[c],function(a){return F[c][a]})}});h.result=function(c, +a){if(null==c)return null;var e=c[a];return h.isFunction(e)?e.call(c):e};h.mixin=function(c){A(h.functions(c),function(a){var e=h[a]=c[a];h.prototype[a]=function(){var c=[this._wrapped];l.apply(c,arguments);c=e.apply(h,c);return this._chain?h(c).chain():c}})};var J=0;h.uniqueId=function(c){var a=J++;return c?c+a:a};h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var G=/(.)^/,K={"'":"'","\\":"\\","\r":"r","\n":"n","\t":"t","\u2028":"u2028","\u2029":"u2029"}, +D=/\\|'|\r|\n|\t|\u2028|\u2029/g;h.template=function(c,a,e){var e=h.defaults({},e,h.templateSettings),g=RegExp([(e.escape||G).source,(e.interpolate||G).source,(e.evaluate||G).source].join("|")+"|$","g"),j=0,f="__p+='";c.replace(g,function(a,e,h,g,p){f+=c.slice(j,p).replace(D,function(c){return"\\"+K[c]});f+=e?"'+\n((__t=("+e+"))==null?'':_.escape(__t))+\n'":h?"'+\n((__t=("+h+"))==null?'':__t)+\n'":g?"';\n"+g+"\n__p+='":"";j=p+a.length});f+="';\n";e.variable||(f="with(obj||{}){\n"+f+"}\n");f="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+ +f+"return __p;\n";try{var p=new Function(e.variable||"obj","_",f)}catch(r){throw r.source=f,r;}if(a)return p(a,h);a=function(c){return p.call(this,c,h)};return a.source="function("+(e.variable||"obj")+"){\n"+f+"}",a};h.chain=function(c){return h(c).chain()};h.mixin(h);A("pop push reverse shift sort splice unshift".split(" "),function(c){var a=b[c];h.prototype[c]=function(){var e=this._wrapped;return a.apply(e,arguments),("shift"==c||"splice"==c)&&0===e.length&&delete e[0],this._chain?h(e).chain(): +e}});A(["concat","join","slice"],function(c){var a=b[c];h.prototype[c]=function(){var c=a.apply(this._wrapped,arguments);return this._chain?h(c).chain():c}});h.extend(h.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);(function(){function a(a,b){return[].slice.call((b||document).querySelectorAll(a))}if(window.addEventListener){var d=window.StyleFix={link:function(a){try{if("stylesheet"!==a.rel||a.hasAttribute("data-noprefix"))return}catch(b){return}var m=a.href||a.getAttribute("data-href"),l=m.replace(/[^\/]+$/,""),g=a.parentNode,f=new XMLHttpRequest,q;f.onreadystatechange=function(){4===f.readyState&&q()};q=function(){var b=f.responseText;if(b&&a.parentNode&&(!f.status||400>f.status||600a?Math.ceil(a):Math.floor(a)}function k(a,e){for(var b=a+"";b.lengthf;f++)e[f]=null==e[f]?2===f?1:0:e[f];return e[7]=b,h=new a(0),b?(h.setUTCFullYear(e[0],e[1],e[2]),h.setUTCHours(e[3],e[4],e[5],e[6])):(h.setFullYear(e[0],e[1],e[2]),h.setHours(e[3],e[4],e[5],e[6])),h._a=e,h}function z(a,e){var b,f,d=[];!e&&G&&(e=require("./lang/"+a));for(b=0;bb;b++)f=h([2E3,b]),d[b]=RegExp("^"+(e.months[b]||e.months(f,""))+"|^"+(e.monthsShort[b]|| -e.monthsShort(f,"")).replace(".",""),"i");return e.monthsParse=e.monthsParse||d,x[a]=e,e}function y(a){return(a="string"==typeof a&&a||a&&a._lang||null)?x[a]||z(a):h}function m(a){return J[a]?"'+("+J[a]+")+'":a.replace(I,"").replace(/\\?'/g,"\\'")}function t(a){return y().longDateFormat[a]||a}function w(a,e){for(var b=y(a);H.test(e);)e=e.replace(H,t);if(!P[e]){var f=P,h=e,d;d="var a,b;return '"+e.replace(D,m)+"';";d=new Function("t","v","o","p","m",d);f[h]=d}return P[e](a,function(f,h){return b[f].call? -b[f](a,e):b[f][h]},b.ordinal,k,b.meridiem)}function r(a){switch(a){case "DDDD":return T;case "YYYY":return U;case "S":case "SS":case "SSS":case "DDD":return O;case "MMM":case "MMMM":case "dd":case "ddd":case "dddd":case "a":case "A":return V;case "Z":case "ZZ":return K;case "T":return W;case "MM":case "DD":case "YY":case "HH":case "hh":case "mm":case "ss":case "M":case "D":case "d":case "H":case "h":case "m":case "s":return N;default:return RegExp(a.replace("\\",""))}}function p(a,e){var b=[0,0,1, -0,0,0,0],h={tzh:0,tzm:0},d=e.match(D),c,g;for(c=0;cj;j++)if(y().monthsParse[j].test(g)){m[1]=j;break}break;case "D":case "DD":case "DDD":case "DDDD":null!=g&&(m[2]=~~g);break;case "YY":g=~~g;m[0]=g+(70b[3]&&(b[3]+=12),!1===h.isPm&&12===b[3]&&(b[3]=0),b[3]+=h.tzh,b[4]+=h.tzm,f(b,h.isUTC)}function n(a,e,b,f,h){h=h.relativeTime[a];return"function"==typeof h?h(e||1,!!b,a,f):h.replace(/%d/i,e||1)}function e(a, -e){h.fn[a]=function(a){var b=this._isUTC?"UTC":"";return null!=a?(this._d["set"+b+e](a),this):this._d["get"+b+e]()}}function q(a){h.duration.fn[a]=function(){return this._data[a]}}function A(a,e){h.duration.fn["as"+a]=function(){return+this/e}}for(var h,u=Math.round,v,x={},E="en",G="undefined"!=typeof module&&module.exports,C="months monthsShort weekdays weekdaysShort weekdaysMin longDateFormat calendar relativeTime ordinal meridiem".split(" "),F=/^\/?Date\((\-?\d+)/i,D=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?)/g, -H=/(LT|LL?L?L?)/g,I=/(^\[)|(\\)|\]$/g,B=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,N=/\d\d?/,O=/\d{1,3}/,T=/\d{3}/,U=/\d{1,4}/,V=/[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i,K=/Z|[\+\-]\d\d:?\d\d/i,W=/T/i,X=/^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,Q=[["HH:mm:ss.S",/T\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/T\d\d:\d\d:\d\d/],["HH:mm",/T\d\d:\d\d/],["HH",/T\d\d/]],Y=/([\+\-]|\d\d)/gi,L="Month Date Hours Minutes Seconds Milliseconds".split(" "), -M={Milliseconds:1,Seconds:1E3,Minutes:6E4,Hours:36E5,Days:864E5,Months:2592E6,Years:31536E6},P={},J={M:"(a=t.month()+1)",MMM:'v("monthsShort",t.month())',MMMM:'v("months",t.month())',D:"(a=t.date())",DDD:"(a=new Date(t.year(),t.month(),t.date()),b=new Date(t.year(),0,1),a=~~(((a-b)/864e5)+1.5))",d:"(a=t.day())",dd:'v("weekdaysMin",t.day())',ddd:'v("weekdaysShort",t.day())',dddd:'v("weekdays",t.day())',w:"(a=new Date(t.year(),t.month(),t.date()-t.day()+5),b=new Date(a.getFullYear(),0,4),a=~~((a-b)/864e5/7+1.5))", -YY:"p(t.year()%100,2)",YYYY:"p(t.year(),4)",a:"m(t.hours(),t.minutes(),!0)",A:"m(t.hours(),t.minutes(),!1)",H:"t.hours()",h:"t.hours()%12||12",m:"t.minutes()",s:"t.seconds()",S:"~~(t.milliseconds()/100)",SS:"p(~~(t.milliseconds()/10),2)",SSS:"p(t.milliseconds(),3)",Z:'((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(a/60),2)+":"+p(~~a%60,2)',ZZ:'((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(10*a/6),4)'},R=["DDD","w","M","D","d"],S="MDHhmsw".split("");R.length;)v=R.pop(),J[v+"o"]=J[v]+"+o(a)";for(;S.length;)v=S.pop(), -J[v+v]="p("+J[v]+",2)";J.DDDD="p("+J.DDD+",3)";h=function(e,b){if(null===e||""===e)return null;var m;if(h.isMoment(e))m=new c(new a(+e._d),e._isUTC,e._lang);else{if(b)if(d(b)){var q=e.match(B)||[],j,y=99,z,A;for(z=0;zq;q++)if(Q[q][1].exec(e)){m+= -Q[q][0];break}m=K.exec(e)?p(e,m+" Z"):p(e,m)}else m=new a(e);else m=new a(e);m=new c(m)}return m};h.utc=function(a,e){return d(a)?new c(f(a,!0),!0):("string"==typeof a&&!K.exec(a)&&(a+=" +0000",e&&(e+=" Z")),h(a,e).utc())};h.unix=function(a){return h(1E3*a)};h.duration=function(a,e){var b=h.isDuration(a),f="number"==typeof a,d=b?a._data:f?{}:a,c;return f&&(e?d[e]=a:d.milliseconds=a),c=new j(d),b&&(c._lang=a._lang),c};h.humanizeDuration=function(a,e,b){return h.duration(a,!0===e?null:e).humanize(!0=== -e?!0:b)};h.version="1.7.0";h.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";h.lang=function(a,e){var b;if(!a)return E;(e||!x[a])&&z(a,e);if(x[a]){for(b=0;ba?b:-1>a?e.lastWeek:0>a?e.lastDay:1>a?e.sameDay:2>a?e.nextDay:7>a?e.nextWeek:b;return this.format("function"==typeof a?a.apply(this):a)},isLeapYear:function(){var a=this.year();return 0===a%4&&0!==a%100||0===a%400},isDST:function(){return this.zone()d&&["s",d]||1===c&&["m"]||45>c&&["mm",c]||1===g&&["h"]||22>g&&["hh",g]||1===m&&["d"]||25>=m&&["dd",m]||45>=m&&["M"]||345>m&&["MM",u(m/30)]||1===q&&["y"]||["yy",q];f=(d[2]=f,d[3]=0=e?b.past:b.future).replace(/%s/i,f)),f},lang:h.fn.lang};for(v in M)M.hasOwnProperty(v)&&(A(v,M[v]),q(v.toLowerCase()));A("Weeks",6048E5);G&&(module.exports=h);"undefined"==typeof ender&&(this.moment=h);"function"==typeof define&&define.amd&&define("moment",[],function(){return h})}).call(this, +(function(a){function d(a,c,e,g,h){a=k[a];a.length&&(a=RegExp(c+"("+a.join("|")+")"+e,"gi"),h=h.replace(a,g));return h}if(window.StyleFix&&window.getComputedStyle){var k=window.PrefixFree={prefixCSS:function(a,c){var e=k.prefix;-1c?Math.ceil(c):Math.floor(c)}function l(c,a){for(var e=c+"";e.lengthh;h++)c[h]=null==c[h]?2===h?1:0:c[h];return c[7]=e,g=new a(0),e?(g.setUTCFullYear(c[0],c[1],c[2]),g.setUTCHours(c[3],c[4],c[5],c[6])):(g.setFullYear(c[0],c[1],c[2]),g.setHours(c[3],c[4],c[5],c[6])),g._a=c,g}function v(c,a){var e,g,j=[];!a&&z&&(a=require("./lang/"+c));for(e=0;ee;e++)g=h([2E3,e]),j[e]=RegExp("^"+(a.months[e]||a.months(g,""))+"|^"+(a.monthsShort[e]|| +a.monthsShort(g,"")).replace(".",""),"i");return a.monthsParse=a.monthsParse||j,C[c]=a,a}function j(c){return(c="string"==typeof c&&c||c&&c._lang||null)?C[c]||v(c):h}function r(c){return L[c]?"'+("+L[c]+")+'":c.replace(J,"").replace(/\\?'/g,"\\'")}function u(c){return j().longDateFormat[c]||c}function t(c,a){for(var e=j(c);I.test(a);)a=a.replace(I,u);if(!P[a]){var h=P,g=a,f;f="var a,b;return '"+a.replace(F,r)+"';";f=new Function("t","v","o","p","m",f);h[g]=f}return P[a](c,function(h,g){return e[h].call? +e[h](c,a):e[h][g]},e.ordinal,l,e.meridiem)}function x(c){switch(c){case "DDDD":return T;case "YYYY":return U;case "S":case "SS":case "SSS":case "DDD":return D;case "MMM":case "MMMM":case "dd":case "ddd":case "dddd":case "a":case "A":return V;case "Z":case "ZZ":return M;case "T":return W;case "MM":case "DD":case "YY":case "HH":case "hh":case "mm":case "ss":case "M":case "D":case "d":case "H":case "h":case "m":case "s":return K;default:return RegExp(c.replace("\\",""))}}function w(c,a){var e=[0,0,1, +0,0,0,0],h={tzh:0,tzm:0},g=a.match(F),f,p;for(f=0;fd;d++)if(j().monthsParse[d].test(p)){r[1]=d;break}break;case "D":case "DD":case "DDD":case "DDDD":null!=p&&(r[2]=~~p);break;case "YY":p=~~p;r[0]=p+(70e[3]&&(e[3]+=12),!1===h.isPm&&12===e[3]&&(e[3]=0),e[3]+=h.tzh,e[4]+=h.tzm,s(e,h.isUTC)}function n(c,a,e,h,g){g=g.relativeTime[c];return"function"==typeof g?g(a||1,!!e,c,h):g.replace(/%d/i,a||1)}function c(c, +a){h.fn[c]=function(c){var e=this._isUTC?"UTC":"";return null!=c?(this._d["set"+e+a](c),this):this._d["get"+e+a]()}}function e(c){h.duration.fn[c]=function(){return this._data[c]}}function p(c,a){h.duration.fn["as"+c]=function(){return+this/a}}for(var h,A=Math.round,B,C={},y="en",z="undefined"!=typeof module&&module.exports,E="months monthsShort weekdays weekdaysShort weekdaysMin longDateFormat calendar relativeTime ordinal meridiem".split(" "),H=/^\/?Date\((\-?\d+)/i,F=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?)/g, +I=/(LT|LL?L?L?)/g,J=/(^\[)|(\\)|\]$/g,G=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,K=/\d\d?/,D=/\d{1,3}/,T=/\d{3}/,U=/\d{1,4}/,V=/[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i,M=/Z|[\+\-]\d\d:?\d\d/i,W=/T/i,X=/^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,Q=[["HH:mm:ss.S",/T\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/T\d\d:\d\d:\d\d/],["HH:mm",/T\d\d:\d\d/],["HH",/T\d\d/]],Y=/([\+\-]|\d\d)/gi,N="Month Date Hours Minutes Seconds Milliseconds".split(" "), +O={Milliseconds:1,Seconds:1E3,Minutes:6E4,Hours:36E5,Days:864E5,Months:2592E6,Years:31536E6},P={},L={M:"(a=t.month()+1)",MMM:'v("monthsShort",t.month())',MMMM:'v("months",t.month())',D:"(a=t.date())",DDD:"(a=new Date(t.year(),t.month(),t.date()),b=new Date(t.year(),0,1),a=~~(((a-b)/864e5)+1.5))",d:"(a=t.day())",dd:'v("weekdaysMin",t.day())',ddd:'v("weekdaysShort",t.day())',dddd:'v("weekdays",t.day())',w:"(a=new Date(t.year(),t.month(),t.date()-t.day()+5),b=new Date(a.getFullYear(),0,4),a=~~((a-b)/864e5/7+1.5))", +YY:"p(t.year()%100,2)",YYYY:"p(t.year(),4)",a:"m(t.hours(),t.minutes(),!0)",A:"m(t.hours(),t.minutes(),!1)",H:"t.hours()",h:"t.hours()%12||12",m:"t.minutes()",s:"t.seconds()",S:"~~(t.milliseconds()/100)",SS:"p(~~(t.milliseconds()/10),2)",SSS:"p(t.milliseconds(),3)",Z:'((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(a/60),2)+":"+p(~~a%60,2)',ZZ:'((a=-t.zone())<0?((a=-a),"-"):"+")+p(~~(10*a/6),4)'},R=["DDD","w","M","D","d"],S="MDHhmsw".split("");R.length;)B=R.pop(),L[B+"o"]=L[B]+"+o(a)";for(;S.length;)B=S.pop(), +L[B+B]="p("+L[B]+",2)";L.DDDD="p("+L.DDD+",3)";h=function(c,e){if(null===c||""===c)return null;var g;if(h.isMoment(c))g=new k(new a(+c._d),c._isUTC,c._lang);else{if(e)if(f(e)){var j=c.match(G)||[],p,r=99,b,u;for(b=0;bj;j++)if(Q[j][1].exec(c)){g+= +Q[j][0];break}g=M.exec(c)?w(c,g+" Z"):w(c,g)}else g=new a(c);else g=new a(c);g=new k(g)}return g};h.utc=function(c,a){return f(c)?new k(s(c,!0),!0):("string"==typeof c&&!M.exec(c)&&(c+=" +0000",a&&(a+=" Z")),h(c,a).utc())};h.unix=function(c){return h(1E3*c)};h.duration=function(c,a){var e=h.isDuration(c),g="number"==typeof c,j=e?c._data:g?{}:c,f;return g&&(a?j[a]=c:j.milliseconds=c),f=new b(j),e&&(f._lang=c._lang),f};h.humanizeDuration=function(c,a,e){return h.duration(c,!0===a?null:a).humanize(!0=== +a?!0:e)};h.version="1.7.0";h.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";h.lang=function(c,a){var e;if(!c)return y;(a||!C[c])&&v(c,a);if(C[c]){for(e=0;ec?e:-1>c?a.lastWeek:0>c?a.lastDay:1>c?a.sameDay:2>c?a.nextDay:7>c?a.nextWeek:e;return this.format("function"==typeof c?c.apply(this):c)},isLeapYear:function(){var c=this.year();return 0===c%4&&0!==c%100||0===c%400},isDST:function(){return this.zone()j&&["s",j]||1===f&&["m"]||45>f&&["mm",f]||1===p&&["h"]||22>p&&["hh",p]||1===r&&["d"]||25>=r&&["dd",r]||45>=r&&["M"]||345>r&&["MM",A(r/30)]||1===b&&["y"]||["yy",b];g=(j[2]=g,j[3]=0=a?e.past:e.future).replace(/%s/i,g)),g},lang:h.fn.lang};for(B in O)O.hasOwnProperty(B)&&(p(B,O[B]),e(B.toLowerCase()));p("Weeks",6048E5);z&&(module.exports=h);"undefined"==typeof ender&&(this.moment=h);"function"==typeof define&&define.amd&&define("moment",[],function(){return h})}).call(this, Date);"undefined"!==typeof require&&(moment=require("moment")); -(function(a){var g=function(b){var b=a([b]),d=b.day();0===d&&(d=7);4d&&(b-=1,d=a([b,11, -31,0,0]).isocalendar()[1]);0===c&&(c=7);return[b,d,c,f]};a.fromIsocalendar=function(a){return g(a[0]).add({weeks:a[1]-1,days:a[2]-1,minutes:a[3]})};for(var l=0,k=c.length;lf&&(g-=1,f=a([g,11, +31,0,0]).isocalendar()[1]);0===b&&(b=7);return[g,f,b,k]};a.fromIsocalendar=function(a){return d(a[0]).add({weeks:a[1]-1,days:a[2]-1,minutes:a[3]})};for(var m=0,l=k.length;ma?d?c[a]:g[a]:a)+" "+j,j}var g="nolla yksi kaksi kolme nelj\u00e4 viisi kuusi seitsem\u00e4n kahdeksan yhdeks\u00e4n".split(" "),c=["nolla","yhden","kahden","kolmen","nelj\u00e4n","viiden","kuuden",g[7],g[8],g[9]],j={months:"tammikuu helmikuu maaliskuu huhtikuu toukokuu kes\u00e4kuu hein\u00e4kuu elokuu syyskuu lokakuu marraskuu joulukuu".split(" "),monthsShort:"tam hel maa huh tou kes hei elo syy lok mar jou".split(" "),weekdays:"sunnuntai maanantai tiistai keskiviikko torstai perjantai lauantai".split(" "), +(function(){function a(a,b,g,f){b="";switch(g){case "s":return f?"muutaman sekunnin":"muutama sekunti";case "m":return f?"minuutin":"minuutti";case "mm":b=f?"minuutin":"minuuttia";break;case "h":return f?"tunnin":"tunti";case "hh":b=f?"tunnin":"tuntia";break;case "d":return f?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4";case "dd":b=f?"p\u00e4iv\u00e4n":"p\u00e4iv\u00e4\u00e4";break;case "M":return f?"kuukauden":"kuukausi";case "MM":b=f?"kuukauden":"kuukautta";break;case "y":return f?"vuoden":"vuosi";case "yy":b= +f?"vuoden":"vuotta"}return b=(10>a?f?k[a]:d[a]:a)+" "+b,b}var d="nolla yksi kaksi kolme nelj\u00e4 viisi kuusi seitsem\u00e4n kahdeksan yhdeks\u00e4n".split(" "),k=["nolla","yhden","kahden","kolmen","nelj\u00e4n","viiden","kuuden",d[7],d[8],d[9]],b={months:"tammikuu helmikuu maaliskuu huhtikuu toukokuu kes\u00e4kuu hein\u00e4kuu elokuu syyskuu lokakuu marraskuu joulukuu".split(" "),monthsShort:"tam hel maa huh tou kes hei elo syy lok mar jou".split(" "),weekdays:"sunnuntai maanantai tiistai keskiviikko torstai perjantai lauantai".split(" "), weekdaysShort:"su ma ti ke to pe la".split(" "),weekdaysMin:"su ma ti ke to pe la".split(" "),longDateFormat:{LT:"HH.mm",L:"DD.MM.YYYY",LL:"Do MMMMt\\a YYYY",LLL:"Do MMMMt\\a YYYY, klo LT",LLLL:"dddd, Do MMMMt\\a YYYY, klo LT"},calendar:{sameDay:"[t\u00e4n\u00e4\u00e4n] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s p\u00e4\u00e4st\u00e4",past:"%s sitten",s:a,m:a,mm:a,h:a,hh:a, -d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=j);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("fi",j)})(); +d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=b);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("fi",b)})(); (function(){var a={months:"janvier f\u00e9vrier mars avril mai juin juillet ao\u00fbt septembre octobre novembre d\u00e9cembre".split(" "),monthsShort:"janv. f\u00e9vr. mars avr. mai juin juil. ao\u00fbt sept. oct. nov. d\u00e9c.".split(" "),weekdays:"dimanche lundi mardi mercredi jeudi vendredi samedi".split(" "),weekdaysShort:"dim. lun. mar. mer. jeu. ven. sam.".split(" "),weekdaysMin:"Di Lu Ma Me Je Ve Sa".split(" "),longDateFormat:{LT:"HH:mm",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT", LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui \u00e0] LT",nextDay:"[Demain \u00e0] LT",nextWeek:"dddd [\u00e0] LT",lastDay:"[Hier \u00e0] LT",lastWeek:"dddd [dernier \u00e0] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"une ann\u00e9e",yy:"%d ann\u00e9es"},ordinal:function(a){return 1===a?"er":"\u00e8me"}};"undefined"!=typeof module&& module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("fr-ca",a)})(); @@ -103,14 +103,14 @@ module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this (function(){var a={months:"Xaneiro Febreiro Marzo Abril Maio Xu\u00f1o Xullo Agosto Setembro Octubro Novembro Decembro".split(" "),monthsShort:"Xan. Feb. Mar. Abr. Mai. Xu\u00f1. Xul. Ago. Set. Out. Nov. Dec.".split(" "),weekdays:"Domingo Luns Martes M\u00e9rcores Xoves Venres S\u00e1bado".split(" "),weekdaysShort:"Dom. Lun. Mar. M\u00e9r. Xov. Ven. S\u00e1b.".split(" "),weekdaysMin:"Do Lu Ma M\u00e9 Xo Ve S\u00e1".split(" "),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT", LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"\u00e1s":"a")+"] LT"},nextDay:function(){return"[ma\u00f1\u00e1 "+(1!==this.hours()?"\u00e1s":"a")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"\u00e1s":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"\u00e1":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"\u00e1s":"a")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fai %s",s:"uns segundo", m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un d\u00eda",dd:"%d d\u00edas",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinal:function(){return"\u00ba"}};"undefined"!=typeof module&&module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("gl",a)})(); -(function(){function a(a,c,g,b){switch(g){case "s":return b||c?"n\u00e9h\u00e1ny m\u00e1sodperc":"n\u00e9h\u00e1ny m\u00e1sodperce";case "m":a="egy";case "mm":return a+(b||c?" perc":" perce");case "h":a="egy";case "hh":return a+(b||c?" \u00f3ra":" \u00f3r\u00e1ja");case "d":a="egy";case "dd":return a+(b||c?" nap":" napja");case "M":a="egy";case "MM":return a+(b||c?" h\u00f3nap":" h\u00f3napja");case "y":a="egy";case "yy":return a+(b||c?" \u00e9v":" \u00e9ve")}return""}function g(a){var c="";switch(this.day()){case 0:c= -"vas\u00e1rnap";break;case 1:c="h\u00e9tf\u0151n";break;case 2:c="kedden";break;case 3:c="szerd\u00e1n";break;case 4:c="cs\u00fct\u00f6rt\u00f6k\u00f6n";break;case 5:c="p\u00e9nteken";break;case 6:c="szombaton"}return(a?"":"m\u00falt ")+"["+c+"] LT[-kor]"}var c={months:"janu\u00e1r febru\u00e1r m\u00e1rcius \u00e1prilis m\u00e1jus j\u00fanius j\u00falius augusztus szeptember okt\u00f3ber november december".split(" "),monthsShort:"jan feb m\u00e1rc \u00e1pr m\u00e1j j\u00fan j\u00fal aug szept okt nov dec".split(" "), -weekdays:"vas\u00e1rnap h\u00e9tf\u0151 kedd szerda cs\u00fct\u00f6rt\u00f6k p\u00e9ntek szombat".split(" "),weekdaysShort:"v h k sze cs p szo".split(" "),longDateFormat:{LT:"H:mm",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return g.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return g.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\u00falva",past:"%s", -s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=c);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("hu",c)})(); -(function(){var a=function(a){return 11==a%100?!0:1==a%10?!1:!0},g=function(c,g,l,k){var b=c+" ";switch(l){case "s":return g||k?"nokkrar sek\u00fandur":"nokkrum sek\u00fandum";case "m":return g?"m\u00edn\u00fata":"m\u00edn\u00fatu";case "mm":return a(c)?b+(g||k?"m\u00edn\u00fatur":"m\u00edn\u00fatum"):g?b+"m\u00edn\u00fata":b+"m\u00edn\u00fatu";case "hh":return a(c)?b+(g||k?"klukkustundir":"klukkustundum"):b+"klukkustund";case "d":return g?"dagur":k?"dag":"degi";case "dd":return a(c)?g?b+"dagar": -b+(k?"daga":"d\u00f6gum"):g?b+"dagur":b+(k?"dag":"degi");case "M":return g?"m\u00e1nu\u00f0ur":k?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i";case "MM":return a(c)?g?b+"m\u00e1nu\u00f0ir":b+(k?"m\u00e1nu\u00f0i":"m\u00e1nu\u00f0um"):g?b+"m\u00e1nu\u00f0ur":b+(k?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i");case "y":return g||k?"\u00e1r":"\u00e1ri";case "yy":return a(c)?b+(g||k?"\u00e1r":"\u00e1rum"):b+(g||k?"\u00e1r":"\u00e1ri")}},g={months:"jan\u00faar febr\u00faar mars apr\u00edl ma\u00ed j\u00fan\u00ed j\u00fal\u00ed \u00e1g\u00fast september okt\u00f3ber n\u00f3vember desember".split(" "), +(function(){function a(a,d,k,g){switch(k){case "s":return g||d?"n\u00e9h\u00e1ny m\u00e1sodperc":"n\u00e9h\u00e1ny m\u00e1sodperce";case "m":a="egy";case "mm":return a+(g||d?" perc":" perce");case "h":a="egy";case "hh":return a+(g||d?" \u00f3ra":" \u00f3r\u00e1ja");case "d":a="egy";case "dd":return a+(g||d?" nap":" napja");case "M":a="egy";case "MM":return a+(g||d?" h\u00f3nap":" h\u00f3napja");case "y":a="egy";case "yy":return a+(g||d?" \u00e9v":" \u00e9ve")}return""}function d(a){var d="";switch(this.day()){case 0:d= +"vas\u00e1rnap";break;case 1:d="h\u00e9tf\u0151n";break;case 2:d="kedden";break;case 3:d="szerd\u00e1n";break;case 4:d="cs\u00fct\u00f6rt\u00f6k\u00f6n";break;case 5:d="p\u00e9nteken";break;case 6:d="szombaton"}return(a?"":"m\u00falt ")+"["+d+"] LT[-kor]"}var k={months:"janu\u00e1r febru\u00e1r m\u00e1rcius \u00e1prilis m\u00e1jus j\u00fanius j\u00falius augusztus szeptember okt\u00f3ber november december".split(" "),monthsShort:"jan feb m\u00e1rc \u00e1pr m\u00e1j j\u00fan j\u00fal aug szept okt nov dec".split(" "), +weekdays:"vas\u00e1rnap h\u00e9tf\u0151 kedd szerda cs\u00fct\u00f6rt\u00f6k p\u00e9ntek szombat".split(" "),weekdaysShort:"v h k sze cs p szo".split(" "),longDateFormat:{LT:"H:mm",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return d.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return d.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s m\u00falva",past:"%s", +s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=k);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("hu",k)})(); +(function(){var a=function(a){return 11==a%100?!0:1==a%10?!1:!0},d=function(d,b,m,l){var g=d+" ";switch(m){case "s":return b||l?"nokkrar sek\u00fandur":"nokkrum sek\u00fandum";case "m":return b?"m\u00edn\u00fata":"m\u00edn\u00fatu";case "mm":return a(d)?g+(b||l?"m\u00edn\u00fatur":"m\u00edn\u00fatum"):b?g+"m\u00edn\u00fata":g+"m\u00edn\u00fatu";case "hh":return a(d)?g+(b||l?"klukkustundir":"klukkustundum"):g+"klukkustund";case "d":return b?"dagur":l?"dag":"degi";case "dd":return a(d)?b?g+"dagar": +g+(l?"daga":"d\u00f6gum"):b?g+"dagur":g+(l?"dag":"degi");case "M":return b?"m\u00e1nu\u00f0ur":l?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i";case "MM":return a(d)?b?g+"m\u00e1nu\u00f0ir":g+(l?"m\u00e1nu\u00f0i":"m\u00e1nu\u00f0um"):b?g+"m\u00e1nu\u00f0ur":g+(l?"m\u00e1nu\u00f0":"m\u00e1nu\u00f0i");case "y":return b||l?"\u00e1r":"\u00e1ri";case "yy":return a(d)?g+(b||l?"\u00e1r":"\u00e1rum"):g+(b||l?"\u00e1r":"\u00e1ri")}},d={months:"jan\u00faar febr\u00faar mars apr\u00edl ma\u00ed j\u00fan\u00ed j\u00fal\u00ed \u00e1g\u00fast september okt\u00f3ber n\u00f3vember desember".split(" "), monthsShort:"jan feb mar apr ma\u00ed j\u00fan j\u00fal \u00e1g\u00fa sep okt n\u00f3v des".split(" "),weekdays:"sunnudagur m\u00e1nudagur \u00feri\u00f0judagur mi\u00f0vikudagur fimmtudagur f\u00f6studagur laugardagur".split(" "),weekdaysShort:"sun m\u00e1n \u00feri mi\u00f0 fim f\u00f6s lau".split(" "),weekdaysMin:"Su M\u00e1 \u00der Mi Fi F\u00f6 La".split(" "),longDateFormat:{LT:"H:mm",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY kl. LT",LLLL:"dddd, D. MMMM YYYY kl. LT"},calendar:{sameDay:"[\u00ed dag kl.] LT", -nextDay:"[\u00e1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\u00ed g\u00e6r kl.] LT",lastWeek:"[s\u00ed\u00f0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\u00ed\u00f0an",s:g,m:g,mm:g,h:"klukkustund",hh:g,d:g,dd:g,M:g,MM:g,y:g,yy:g},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=g);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("is",g)})(); +nextDay:"[\u00e1 morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[\u00ed g\u00e6r kl.] LT",lastWeek:"[s\u00ed\u00f0asta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s s\u00ed\u00f0an",s:d,m:d,mm:d,h:"klukkustund",hh:d,d:d,dd:d,M:d,MM:d,y:d,yy:d},ordinal:function(){return"."}};"undefined"!=typeof module&&module.exports&&(module.exports=d);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("is",d)})(); (function(){var a={months:"Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settebre Ottobre Novembre Dicembre".split(" "),monthsShort:"Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic".split(" "),weekdays:"Domenica Luned\u00ec Marted\u00ec Mercoled\u00ec Gioved\u00ec Venerd\u00ec Sabato".split(" "),weekdaysShort:"Dom Lun Mar Mer Gio Ven Sab".split(" "),weekdaysMin:"D L Ma Me G V S".split(" "),longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"}, calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:"[lo scorso] dddd [alle] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s fa",s:"secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinal:function(){return"\u00ba"}};"undefined"!=typeof module&&module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&& this.moment.lang("it",a)})(); @@ -132,133 +132,133 @@ calendar:{sameDay:"[I dag klokken] LT",nextDay:"[I morgen klokken] LT",nextWeek: (function(){var a={months:"januari februari maart april mei juni juli augustus september oktober november december".split(" "),monthsShort:"jan feb mrt apr mei jun jul aug sep okt nov dec".split(" "),weekdays:"zondag maandag dinsdag woensdag donderdag vrijdag zaterdag".split(" "),weekdaysShort:"zo. ma. di. wo. do. vr. za.".split(" "),weekdaysMin:"Zo Ma Di Wo Do Vr Za".split(" "),longDateFormat:{LT:"HH:mm",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Vandaag om] LT", nextDay:"[Morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"\u00e9\u00e9n minuut",mm:"%d minuten",h:"\u00e9\u00e9n uur",hh:"%d uur",d:"\u00e9\u00e9n dag",dd:"%d dagen",M:"\u00e9\u00e9n maand",MM:"%d maanden",y:"\u00e9\u00e9n jaar",yy:"%d jaar"},ordinal:function(a){return 1===a||8===a||20<=a?"ste":"de"}};"undefined"!=typeof module&&module.exports&&(module.exports= a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("nl",a)})(); -(function(){var a=function(a){return 5>a%10&&1a%10&&1=a%10&&0===a%10%1&&(12>a%100||14=a%10&&0===a%10%1||11<=a%100&&14>=a%100&&0===a%100%1},function(){return!0}],g=function(c,g,l){var k={mm:"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442_\u043c\u0438\u043d\u0443\u0442\u044b",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432_\u0447\u0430\u0441\u0430", -dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439_\u0434\u043d\u044f",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432_\u043c\u0435\u0441\u044f\u0446\u0430",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442_\u0433\u043e\u0434\u0430"};if("m"===l)g=g?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443";else{g=c+" ";a:{for(var c=+c,l=k[l].split("_"),k=Math.min(a.length,l.length), -b=-1;++b=a%10&&0===a%10%1&&(12>a%100||14=a%10&&0===a%10%1||11<=a%100&&14>=a%100&&0===a%100%1},function(){return!0}],d=function(d,b,m){var l={mm:"\u043c\u0438\u043d\u0443\u0442\u0430_\u043c\u0438\u043d\u0443\u0442\u044b_\u043c\u0438\u043d\u0443\u0442_\u043c\u0438\u043d\u0443\u0442\u044b",hh:"\u0447\u0430\u0441_\u0447\u0430\u0441\u0430_\u0447\u0430\u0441\u043e\u0432_\u0447\u0430\u0441\u0430", +dd:"\u0434\u0435\u043d\u044c_\u0434\u043d\u044f_\u0434\u043d\u0435\u0439_\u0434\u043d\u044f",MM:"\u043c\u0435\u0441\u044f\u0446_\u043c\u0435\u0441\u044f\u0446\u0430_\u043c\u0435\u0441\u044f\u0446\u0435\u0432_\u043c\u0435\u0441\u044f\u0446\u0430",yy:"\u0433\u043e\u0434_\u0433\u043e\u0434\u0430_\u043b\u0435\u0442_\u0433\u043e\u0434\u0430"};if("m"===m)b=b?"\u043c\u0438\u043d\u0443\u0442\u0430":"\u043c\u0438\u043d\u0443\u0442\u0443";else{b=d+" ";a:{for(var d=+d,m=l[m].split("_"),l=Math.min(a.length,m.length), +g=-1;++ga?"\u65e9\u4e0a":11>a&&30>c?"\u4e0a\u5348":13>a&&30>c?"\u4e2d\u5348":18>a?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"}, +weekdaysMin:"\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".split(""),longDateFormat:{LT:"Ah\u70b9mm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,k){return 9>a?"\u65e9\u4e0a":11>a&&30>k?"\u4e0a\u5348":13>a&&30>k?"\u4e2d\u5348":18>a?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"}, relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",m:"1\u5206\u949f",mm:"%d\u5206\u949f",h:"1\u5c0f\u65f6",hh:"%d\u5c0f\u65f6",d:"1\u5929",dd:"%d\u5929",M:"1\u4e2a\u6708",MM:"%d\u4e2a\u6708",y:"1\u5e74",yy:"%d\u5e74"},ordinal:function(){return""}};"undefined"!=typeof module&&module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("zh",a)})(); (function(){var a={months:"\u4e00\u6708 \u4e8c\u6708 \u4e09\u6708 \u56db\u6708 \u4e94\u6708 \u516d\u6708 \u4e03\u6708 \u516b\u6708 \u4e5d\u6708 \u5341\u6708 \u5341\u4e00\u6708 \u5341\u4e8c\u6708".split(" "),monthsShort:"1\u6708 2\u6708 3\u6708 4\u6708 5\u6708 6\u6708 7\u6708 8\u6708 9\u6708 10\u6708 11\u6708 12\u6708".split(" "),weekdays:"\u661f\u671f\u65e5 \u661f\u671f\u4e00 \u661f\u671f\u4e8c \u661f\u671f\u4e09 \u661f\u671f\u56db \u661f\u671f\u4e94 \u661f\u671f\u516d".split(" "),weekdaysShort:"\u9031\u65e5 \u9031\u4e00 \u9031\u4e8c \u9031\u4e09 \u9031\u56db \u9031\u4e94 \u9031\u516d".split(" "), -weekdaysMin:"\u65e5\u4e00\u4e8c\u4e09\u56db\u4e94\u516d".split(""),longDateFormat:{LT:"Ah\u9edemm",L:"YYYY\u5e74MMMD\u65e5",LL:"YYYY\u5e74MMMD\u65e5",LLL:"YYYY\u5e74MMMD\u65e5LT",LLLL:"YYYY\u5e74MMMD\u65e5ddddLT"},meridiem:function(a,c){return 9>a?"\u65e9\u4e0a":11>a&&30>c?"\u4e0a\u5348":13>a&&30>c?"\u4e2d\u5348":18>a?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"}, -relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",m:"\u4e00\u5206\u9418",mm:"%d\u5206\u9418",h:"\u4e00\u5c0f\u6642",hh:"%d\u5c0f\u6642",d:"\u4e00\u5929",dd:"%d\u5929",M:"\u4e00\u500b\u6708",MM:"%d\u500b\u6708",y:"\u4e00\u5e74",yy:"%d\u5e74"},ordinal:function(){return""}};"undefined"!=typeof module&&module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("zh-tw",a)})();var Handlebars={VERSION:"1.0.beta.6",helpers:{},partials:{},registerHelper:function(a,g,c){c&&(g.not=c);this.helpers[a]=g},registerPartial:function(a,g){this.partials[a]=g}};Handlebars.registerHelper("helperMissing",function(a){if(2!==arguments.length)throw Error("Could not find property '"+a+"'");});var toString=Object.prototype.toString,functionType="[object Function]"; -Handlebars.registerHelper("blockHelperMissing",function(a,g){var c=g.inverse||function(){},j=g.fn,l="",k=toString.call(a);k===functionType&&(a=a.call(this));if(!0===a)return j(this);if(!1===a||null==a)return c(this);if("[object Array]"===k){if(0a?"\u65e9\u4e0a":11>a&&30>k?"\u4e0a\u5348":13>a&&30>k?"\u4e2d\u5348":18>a?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"}, +relativeTime:{future:"%s\u5167",past:"%s\u524d",s:"\u5e7e\u79d2",m:"\u4e00\u5206\u9418",mm:"%d\u5206\u9418",h:"\u4e00\u5c0f\u6642",hh:"%d\u5c0f\u6642",d:"\u4e00\u5929",dd:"%d\u5929",M:"\u4e00\u500b\u6708",MM:"%d\u500b\u6708",y:"\u4e00\u5e74",yy:"%d\u5e74"},ordinal:function(){return""}};"undefined"!=typeof module&&module.exports&&(module.exports=a);"undefined"!=typeof window&&this.moment&&this.moment.lang&&this.moment.lang("zh-tw",a)})();var Handlebars={VERSION:"1.0.beta.6",helpers:{},partials:{},registerHelper:function(a,d,k){k&&(d.not=k);this.helpers[a]=d},registerPartial:function(a,d){this.partials[a]=d}};Handlebars.registerHelper("helperMissing",function(a){if(2!==arguments.length)throw Error("Could not find property '"+a+"'");});var toString=Object.prototype.toString,functionType="[object Function]"; +Handlebars.registerHelper("blockHelperMissing",function(a,d){var k=d.inverse||function(){},b=d.fn,m="",l=toString.call(a);l===functionType&&(a=a.call(this));if(!0===a)return b(this);if(!1===a||null==a)return k(this);if("[object Array]"===l){if(0a.length&&(a+=this._input.substr(0,20-a.length));return(a.substr(0,20)+(20/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/, +d=Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+d+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,d;this._more||(this.match=this.yytext="");for(var k=this._currentRules(),b=0;b/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/, /^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/],conditions:{mu:{rules:[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],inclusive:!1},emu:{rules:[2],inclusive:!1},INITIAL:{rules:[0,1,26],inclusive:!0}}}}}(); "undefined"!==typeof require&&"undefined"!==typeof exports&&(exports.parser=handlebars,exports.parse=function(){return handlebars.parse.apply(handlebars,arguments)},exports.main=function(a){if(!a[1])throw Error("Usage: "+a[0]+" FILE");a="undefined"!==typeof process?require("fs").readFileSync(require("path").join(process.cwd(),a[1]),"utf8"):require("file").path(require("file").cwd()).join(a[1]).read({charset:"utf-8"});return exports.parser.parse(a)},"undefined"!==typeof module&&require.main===module&& -exports.main("undefined"!==typeof process?process.argv.slice(1):require("system").args));Handlebars.Parser=handlebars;Handlebars.parse=function(a){Handlebars.Parser.yy=Handlebars.AST;return Handlebars.Parser.parse(a)};Handlebars.print=function(a){return(new Handlebars.PrintVisitor).accept(a)};Handlebars.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(){}};Handlebars.log=function(a,g){Handlebars.logger.log(a,g)}; -(function(){Handlebars.AST={};Handlebars.AST.ProgramNode=function(a,c){this.type="program";this.statements=a;c&&(this.inverse=new Handlebars.AST.ProgramNode(c))};Handlebars.AST.MustacheNode=function(a,c,j){this.type="mustache";this.id=a[0];this.params=a.slice(1);this.hash=c;this.escaped=!j};Handlebars.AST.PartialNode=function(a,c){this.type="partial";this.id=a;this.context=c};var a=function(a,c){if(a.original!==c.original)throw new Handlebars.Exception(a.original+" doesn't match "+c.original);};Handlebars.AST.BlockNode= -function(g,c,j){a(g.id,j);this.type="block";this.mustache=g;this.program=c};Handlebars.AST.InverseNode=function(g,c,j){a(g.id,j);this.type="inverse";this.mustache=g;this.program=c};Handlebars.AST.ContentNode=function(a){this.type="content";this.string=a};Handlebars.AST.HashNode=function(a){this.type="hash";this.pairs=a};Handlebars.AST.IdNode=function(a){this.type="ID";this.original=a.join(".");for(var c=[],j=0,l=0,k=a.length;l":">",'"':""","'":"'","`":"`"},g=/&(?!\w+;)|[<>"'`]/g,c=/[&<>"'`]/,j=function(c){return a[c]||"&"};Handlebars.Utils={escapeExpression:function(a){return a instanceof Handlebars.SafeString?a.toString():null==a||!1===a?"":!c.test(a)?a:a.replace(g,j)},isEmpty:function(a){return"undefined"===typeof a?!0:null===a?!0:!1===a?!0:"[object Array]"===Object.prototype.toString.call(a)&&0===a.length?!0:!1}}})();Handlebars.Compiler=function(){}; +exports.main("undefined"!==typeof process?process.argv.slice(1):require("system").args));Handlebars.Parser=handlebars;Handlebars.parse=function(a){Handlebars.Parser.yy=Handlebars.AST;return Handlebars.Parser.parse(a)};Handlebars.print=function(a){return(new Handlebars.PrintVisitor).accept(a)};Handlebars.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(){}};Handlebars.log=function(a,d){Handlebars.logger.log(a,d)}; +(function(){Handlebars.AST={};Handlebars.AST.ProgramNode=function(a,k){this.type="program";this.statements=a;k&&(this.inverse=new Handlebars.AST.ProgramNode(k))};Handlebars.AST.MustacheNode=function(a,k,b){this.type="mustache";this.id=a[0];this.params=a.slice(1);this.hash=k;this.escaped=!b};Handlebars.AST.PartialNode=function(a,k){this.type="partial";this.id=a;this.context=k};var a=function(a,k){if(a.original!==k.original)throw new Handlebars.Exception(a.original+" doesn't match "+k.original);};Handlebars.AST.BlockNode= +function(d,k,b){a(d.id,b);this.type="block";this.mustache=d;this.program=k};Handlebars.AST.InverseNode=function(d,k,b){a(d.id,b);this.type="inverse";this.mustache=d;this.program=k};Handlebars.AST.ContentNode=function(a){this.type="content";this.string=a};Handlebars.AST.HashNode=function(a){this.type="hash";this.pairs=a};Handlebars.AST.IdNode=function(a){this.type="ID";this.original=a.join(".");for(var k=[],b=0,m=0,l=a.length;m":">",'"':""","'":"'","`":"`"},d=/&(?!\w+;)|[<>"'`]/g,k=/[&<>"'`]/,b=function(b){return a[b]||"&"};Handlebars.Utils={escapeExpression:function(a){return a instanceof Handlebars.SafeString?a.toString():null==a||!1===a?"":!k.test(a)?a:a.replace(d,b)},isEmpty:function(a){return"undefined"===typeof a?!0:null===a?!0:!1===a?!0:"[object Array]"===Object.prototype.toString.call(a)&&0===a.length?!0:!1}}})();Handlebars.Compiler=function(){}; Handlebars.JavaScriptCompiler=function(){}; -(function(a,g){a.OPCODE_MAP={appendContent:1,getContext:2,lookupWithHelpers:3,lookup:4,append:5,invokeMustache:6,appendEscaped:7,pushString:8,truthyOrFallback:9,functionOrFallback:10,invokeProgram:11,invokePartial:12,push:13,assignToHash:15,pushStringParam:16};a.MULTI_PARAM_OPCODES={appendContent:1,getContext:1,lookupWithHelpers:2,lookup:1,invokeMustache:3,pushString:1,truthyOrFallback:1,functionOrFallback:1,invokeProgram:3,invokePartial:1,push:1,assignToHash:1,pushStringParam:1};a.DISASSEMBLE_MAP= -{};for(var c in a.OPCODE_MAP)a.DISASSEMBLE_MAP[a.OPCODE_MAP[c]]=c;a.multiParamSize=function(b){return a.MULTI_PARAM_OPCODES[a.DISASSEMBLE_MAP[b]]};a.prototype={compiler:a,disassemble:function(){for(var b=this.opcodes,d,c=[],f,g=0,j=b.length;gdepth||this.addDepth(depth-1);return d},block:function(a){var d=a.mustache,c=this.setupStackForMustache(d),f=this.compileProgram(a.program);a.program.inverse&&(a=this.compileProgram(a.program.inverse),this.declare("inverse",a));this.opcode("invokeProgram", -f,c.length,!!d.hash);this.declare("inverse",null);this.opcode("append")},inverse:function(a){var d=this.setupStackForMustache(a.mustache),c=this.compileProgram(a.program);this.declare("inverse",c);this.opcode("invokeProgram",null,d.length,!!a.mustache.hash);this.declare("inverse",null);this.opcode("append")},hash:function(a){var a=a.pairs,d,c;this.opcode("push","{}");for(var f=0,g=a.length;fthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot);return"stack"+this.stackSlot},popStack:function(){return"stack"+this.stackSlot--},topStack:function(){return"stack"+this.stackSlot},quotedString:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"'}};c="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield".split(" "); -for(var j=g.RESERVED_WORDS={},l=0,k=c.length;l/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},has:function(a){return null!=this.attributes[a]},set:function(a,f){f||(f={});if(!a)return this;a.attributes&&(a=a.attributes);var b=this.attributes,h=this._escapedAttributes;if(!f.silent&&this.validate&&!this._performValidation(a,f))return!1;this.idAttribute in a&&(this.id=a[this.idAttribute]); -var d=this._changing;this._changing=!0;for(var c in a){var g=a[c];j.isEqual(b[c],g)||(b[c]=g,delete h[c],this._changed=!0,f.silent||this.trigger("change:"+c,this,g,f))}!d&&!f.silent&&this._changed&&this.change(f);this._changing=!1;return this},unset:function(a,f){if(!(a in this.attributes))return this;f||(f={});var b={};b[a]=void 0;if(!f.silent&&this.validate&&!this._performValidation(b,f))return!1;delete this.attributes[a];delete this._escapedAttributes[a];a==this.idAttribute&&delete this.id;this._changed= -!0;f.silent||(this.trigger("change:"+a,this,void 0,f),this.change(f));return this},clear:function(a){a||(a={});var f,b=this.attributes,h={};for(f in b)h[f]=void 0;if(!a.silent&&this.validate&&!this._performValidation(h,a))return!1;this.attributes={};this._escapedAttributes={};this._changed=!0;if(!a.silent){for(f in b)this.trigger("change:"+f,this,void 0,a);this.change(a)}return this},fetch:function(a){a||(a={});var f=this,b=a.success;a.success=function(h,d,c){if(!f.set(f.parse(h,c),a))return!1;b&& -b(f,h)};a.error=n(a.error,f,a);return(this.sync||c.sync).call(this,"read",this,a)},save:function(a,f){f||(f={});if(a&&!this.set(a,f))return!1;var b=this,h=f.success;f.success=function(a,e,d){if(!b.set(b.parse(a,d),f))return!1;h&&h(b,a,d)};f.error=n(f.error,b,f);var d=this.isNew()?"create":"update";return(this.sync||c.sync).call(this,d,this,f)},destroy:function(a){a||(a={});if(this.isNew())return this.trigger("destroy",this,this.collection,a);var f=this,b=a.success;a.success=function(h){f.trigger("destroy", -f,f.collection,a);b&&b(f,h)};a.error=n(a.error,f,a);return(this.sync||c.sync).call(this,"delete",this,a)},url:function(){var a=r(this.collection)||this.urlRoot||p();return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return null==this.id},change:function(a){this.trigger("change",this,a);this._previousAttributes=j.clone(this.attributes);this._changed=!1},hasChanged:function(a){return a? -this._previousAttributes[a]!=this.attributes[a]:this._changed},changedAttributes:function(a){a||(a=this.attributes);var f=this._previousAttributes,b=!1,h;for(h in a)j.isEqual(f[h],a[h])||(b=b||{},b[h]=a[h]);return b},previous:function(a){return!a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return j.clone(this._previousAttributes)},_performValidation:function(a,f){var b=this.validate(a);return b?(f.error?f.error(this,b,f):this.trigger("error",this,b,f), -!1):!0}});c.Collection=function(a,f){f||(f={});f.comparator&&(this.comparator=f.comparator);j.bindAll(this,"_onModelEvent","_removeReference");this._reset();a&&this.reset(a,{silent:!0});this.initialize.apply(this,arguments)};j.extend(c.Collection.prototype,c.Events,{model:c.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,f){if(j.isArray(a))for(var b=0,h=a.length;b=b))this.iframe=l('